94list-laravel-tampermonkey

对接 94list-laravel 的油猴脚本

目前為 2024-03-19 提交的版本,檢視 最新版本

// ==UserScript==
// @name              94list-laravel-tampermonkey
// @namespace         https://github.com/huankong233/94list-laravel-tampermonkey
// @version           0.0.1
// @author            huan_kong
// @description       对接 94list-laravel 的油猴脚本
// @license           MIT
// @homepage          https://github.com/huankong233/94list-laravel-tampermonkey
// @supportURL        https://github.com/huankong233/94list-laravel-tampermonkey
// @icon              https://huankong.top/favicon.ico
// @match             *://pan.baidu.com/disk/*
// @match             *://yun.baidu.com/disk/*
// @connect           localhost
// @connect           127.0.0.1
// @connect           *
// @require           https://registry.npmmirror.com/jquery/3.7.1/files/dist/jquery.min.js
// @require           https://registry.npmmirror.com/sweetalert2/11.10.6/files/dist/sweetalert2.all.min.js
// @grant             GM_xmlhttpRequest
// @grant             GM_addStyle
// @grant             GM_setClipboard
// @grant             GM_registerMenuCommand
// ==/UserScript==

$(async function () {
  GM_addStyle(
    `input{outline-style:none;border:1px solid #c0c4cc;border-radius:5px;width:100%;height:100%;padding:0;padding:10px 15px;box-sizing:border-box}.hk table{width:100%;border-collapse:collapse;margin:25px 0;font-size:.9em;font-family:'Segoe UI',Tahoma,Geneva,Verdana,sans-serif;min-width:400px;box-shadow:0 0 20px rgba(0,0,0,0.15)}.hk thead tr{background-color:#009879;color:#fff;text-align:center;}.hk .line{line-height:60px}.hk th,.hk td{padding:12px 15px;width:138px;height:85px;overflow:overlay;display:inline-block;}.hk tbody tr{border-bottom:1px solid #ddd}.hk tbody tr:nth-of-type(even){background-color:#f3f3f3}.hk td{height:100px;}.hk td.line{line-height:75px;}`
  )

  GM_registerMenuCommand('⚙️ 设置', () => {
    Swal.fire({
      title: '⚙️ 设置',
      html: `<div>
        <p>94list-laravel-site-url</p>
        <input type="text" id="siteUrl" value=${
          localStorage.getItem('94list-laravel-site-url') ?? ''
        }>
        <p>94list-laravel-site-password</p>
        <input type="text" id="sitePassword" value=${
          localStorage.getItem('94list-laravel-site-password') ?? ''
        }>
        <p>94list-laravel-site-aria2-host</p>
        <input type="text" id="siteAriaHost" value=${
          localStorage.getItem('94list-laravel-site-aria2-host') ?? ''
        }>
        <p>94list-laravel-site-aria2-secret</p>
        <input type="text" id="siteAriaSecret" value=${
          localStorage.getItem('94list-laravel-site-aria2-secret') ?? ''
        }>
      </div>`,
      icon: 'info',
      showConfirmButton: true
    }).then(() => {
      localStorage.setItem('94list-laravel-site-url', document.querySelector('#siteUrl').value)
      localStorage.setItem(
        '94list-laravel-site-password',
        document.querySelector('#sitePassword').value
      )
      localStorage.setItem(
        '94list-laravel-site-aria2-host',
        document.querySelector('#siteAriaHost').value
      )
      localStorage.setItem(
        '94list-laravel-site-aria2-secret',
        document.querySelector('#siteAriaSecret').value
      )
      location.reload()
    })
  })

  function setLocalStorage(key, url) {
    localStorage.setItem(key, url)
    location.reload()
  }

  const request = params => {
    return new Promise((resolve, reject) =>
      GM_xmlhttpRequest({
        ...params,
        onload: res => (res.status === 200 ? resolve(res) : reject(res)),
        onerror: err => reject(err)
      })
    )
  }

  const siteUrl = localStorage.getItem('94list-laravel-site-url')
  const password = localStorage.getItem('94list-laravel-site-password')

  if (!siteUrl | (siteUrl === 'null')) {
    await Swal.fire({
      title: '请先设置 94list-laravel-site-url',
      html: `<input type="text" id="siteUrl">`
    })
    setLocalStorage('94list-laravel-site-url', document.querySelector('#siteUrl').value)
  }

  const serevrConfig = await request({
    method: 'POST',
    url: siteUrl + '/api/user/getConfig',
    responseType: 'json'
  })
    .then(res => res.response.data)
    .catch(_ => {
      Swal.fire({
        icon: 'error',
        title: '系统提示',
        text: '请求服务器失败!'
      }).then(_ => setLocalStorage('94list-laravel-site-url', null))
    })

  if (serevrConfig.havePassword && !password | (password === 'null')) {
    await Swal.fire({
      title: '请先设置 94list-laravel-site-password',
      html: `<input type="text" id="sitePassword">`
    })
    setLocalStorage('94list-laravel-site-password', document.querySelector('#sitePassword').value)
  }

  $('.wp-s-agile-tool-bar__header.is-header-tool').prepend(
    '<div class="wp-s-agile-tool-bar__h-group"><button style="margin-right:10px;" id="94listDownBtn" class="u-button nd-file-list-toolbar-action-item is-need-left-sep u-button--primary u-button--default u-button--small is-has-icon  u-button--danger"><i class="iconfont icon-download"></i><span>94list-laravel</span></button></div>'
  )

  const match = /"bdstoken":"(\w+)"/.exec($('html').html())
  if (match === null) {
    Swal.fire({
      icon: 'error',
      title: '系统提示',
      text: '未知错误!'
    }).then(_ => location.reload())
  }
  const bdstoken = match[1]

  const getSelectedList = function () {
    if (document.location.href.indexOf('.baidu.com/disk/home') > 0) {
      return require('system-core:context/context.js').instanceForSystem.list.getSelected()
    }
    if (document.location.href.indexOf('.baidu.com/disk/main') > 0) {
      let mainList = document.querySelector('.nd-main-list')
      if (!mainList) mainList = document.querySelector('.nd-new-main-list')
      return mainList.__vue__.selectedList
    }
  }

  $('#94listDownBtn').on('click', async function () {
    if ($('tr.selected img[src*="ceH8M5EZYnGhnBKRceGqmaZXPPw2xbO+1x"]').length > 0) {
      Swal.fire({
        icon: 'error',
        title: '系统提示',
        text: '不支持文件夹解析'
      })
      return
    }
    const selectedIds = getSelectedList().map(v => v.fs_id)
    if (selectedIds.length === 0) {
      Swal.fire({
        title: '系统提示',
        text: '请选择需要下载的文件',
        icon: 'error'
      })
      return
    }
    function getRangeCode(len = 6) {
      const orgStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
      let returnStr = ''
      for (let i = 0; i < len; i++) {
        returnStr += orgStr.charAt(Math.floor(Math.random() * orgStr.length))
      }
      return returnStr
    }
    Swal.fire({
      title: false,
      text: '服务器请求中',
      showCloseButton: false,
      showCancelButton: false,
      showConfirmButton: false,
      didOpen: () => Swal.showLoading()
    })
    const pwd = getRangeCode(4)
    const shareLink = await $.ajax({
      method: 'post',
      url: `https://pan.baidu.com/share/set?channel=chunlei&bdstoken=${bdstoken}period=1&pwd=${pwd}&eflag_disable=true&channel_list=%5B%5D&schannel=4&fid_list=[${selectedIds}]`
    })
    if (shareLink.show_msg) {
      Swal.fire({
        title: '系统提示',
        text: shareLink.show_msg,
        icon: 'error'
      })
      return
    }
    const url = shareLink.link
    const shareFileList = await request({
      method: 'post',
      url: siteUrl + '/api/user/getFileList',
      headers: {
        'Content-Type': 'application/json'
      },
      data: JSON.stringify({
        dir: '/',
        url,
        pwd,
        password
      }),
      responseType: 'json'
    }).catch(err => {
      Swal.fire({
        icon: 'error',
        title: '系统提示',
        text: err.response.message
      }).then(_ =>
        err.response.message == '密码不匹配'
          ? setLocalStorage('94list-laravel-site-password', null)
          : location.reload()
      )
    })
    const shareSign = await request({
      method: 'post',
      url: siteUrl + '/api/user/getSign',
      headers: {
        'Content-Type': 'application/json'
      },
      data: JSON.stringify({
        uk: shareFileList.response.data.uk,
        shareid: shareFileList.response.data.shareid,
        password
      }),
      responseType: 'json'
    }).catch(err => {
      Swal.fire({
        icon: 'error',
        title: '系统提示',
        text: err.response.message
      }).then(_ =>
        err.response.message == '密码不匹配'
          ? setLocalStorage('94list-laravel-site-password', null)
          : location.reload()
      )
    })
    const downLinks = await request({
      method: 'post',
      url: siteUrl + '/api/user/downloadFiles',
      headers: {
        'Content-Type': 'application/json'
      },
      data: JSON.stringify({
        fs_ids: selectedIds,
        timestamp: shareSign.response.data.timestamp,
        uk: shareFileList.response.data.uk,
        sign: shareSign.response.data.sign,
        randsk: shareFileList.response.data.randsk,
        shareid: shareFileList.response.data.shareid,
        password
      }),
      responseType: 'json'
    }).catch(err => {
      Swal.fire({
        icon: 'error',
        title: '系统提示',
        text: err.response.message
      }).then(_ =>
        err.response.message == '密码不匹配'
          ? setLocalStorage('94list-laravel-site-password', null)
          : location.reload()
      )
    })
    Swal.close()

    Swal.fire({
      html: `<h3>当前下载UA: ${serevrConfig.userAgent}</h3><div class="hk"><table><thead><tr><th class="line">文件名</th><th class="line">地址</th><th class="line">操作</th></tr></thead><tbody></tbody></table></div>`
    })

    downLinks.response.data.forEach(link => {
      $('.swal2-html-container .hk table tbody').append(`
      <tr>
          <td class="line">${link.server_filename}</td>
          <td>${link.dlink}</td>
          <td><button class="aria" data-dlink="${link.dlink}" data-filename="${link.server_filename}">发送到Aria2</button><button class="idm" data-dlink="${link.dlink}" data-filename="${link.server_filename}">尝试调用IDM</button><button class="copy" data-dlink="${link.dlink}">复制链接</button></td>
      </tr>`)
    })

    $('.hk button.aria').on('click', async function () {
      let aria2Host = localStorage.getItem('94list-laravel-site-aria2-host')
      if (!aria2Host || aria2Host === 'null') {
        await Swal.fire({
          title: '请先设置 94list-laravel-site-aria2-host',
          html: `<input type="text" id="siteAriaHost">`
        })

        aria2Host = document.querySelector('#siteAriaHost').value
        localStorage.setItem('94list-laravel-site-aria2-host', aria2Host)
      }

      let aria2Secret = localStorage.getItem('94list-laravel-site-aria2-secret')

      await request({
        method: 'post',
        url: aria2Host,
        headers: {
          'Content-Type': 'application/json'
        },
        data: JSON.stringify({
          jsonrpc: '2.0',
          id: '94list-laravel-tampermonkey',
          method: 'aria2.addUri',
          params: [
            `token:${aria2Secret}`,
            [$(this).data('dlink')],
            {
              out: $(this).data('filename'),
              header: [`User-Agent: ${serevrConfig.userAgent}`]
            }
          ]
        })
      })
    })

    $('.hk button.idm').on('click', async function () {
      const blob = await request({
        method: 'get',
        url: $(this).data('dlink'),
        responseType: 'blob',
        headers: { 'User-Agent': serevrConfig.userAgent }
      })
      const url = URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = url
      a.download = $(this).data('filename')
      a.click()
      URL.revokeObjectURL(url)
    })

    $('.hk button.copy').on('click', function () {
      GM_setClipboard($(this).data('dlink'), 'dlink')
    })
  })
})

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址