Skip to content

Commit

Permalink
feat: support baidu pan
Browse files Browse the repository at this point in the history
  • Loading branch information
a1mersnow committed Jan 20, 2025
1 parent 2f4a79a commit 177cfd8
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- 👁️ 所见即所得
- 🎨 支持多个网盘平台
- 阿里云盘
- 百度网盘
- 夸克云盘
- 123云盘
- 移动云盘(新个人云)
Expand Down
1 change: 1 addition & 0 deletions components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ declare module 'vue' {
export interface GlobalComponents {
Button123: typeof import('./src/components/Button123.vue')['default']
ButtonAliyun: typeof import('./src/components/ButtonAliyun.vue')['default']
ButtonBaidu: typeof import('./src/components/ButtonBaidu.vue')['default']
ButtonCmcc: typeof import('./src/components/ButtonCmcc.vue')['default']
ButtonQuark: typeof import('./src/components/ButtonQuark.vue')['default']
ControlPanel: typeof import('./src/components/ControlPanel.vue')['default']
Expand Down
8 changes: 8 additions & 0 deletions src/components/ButtonBaidu.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<template>
<button
class="mr3 inline-block h8 flex items-center justify-center gap-x-1 ws-nowrap rd-full bg-#06a7ff px-4 py-2 text-white transition"
>
<i class="i-carbon:batch-job shrink-0 text-sm" />
<span class="text-sm font-bold">重命名</span>
</button>
</template>
171 changes: 171 additions & 0 deletions src/providers/baidu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
import type { Provider, Resource } from '~/types'
import ButtonComponent from '~/components/ButtonBaidu.vue'
import { getExtFromName } from '~/utils/tools'

function getDir() {
const u = getURL(location.href)
return u.searchParams.get('path') || '/'
}

async function getFileListOfCurrentDir(parentId = getDir()) {
const listApi = new URL('https://pan.baidu.com/api/list?clienttype=0&app_id=250528&web=1&order=name&desc=0&num=100')
listApi.searchParams.set('dir', parentId)
const result: Resource[] = []
let page = 1
let next = true

while (next) {
listApi.searchParams.set('page', String(page++))
const { list } = await get(listApi)
result.push(...list.map((x: any) => ({
drive_id: 'whocare',
file_id: String(x.fs_id),
name: x.server_filename,
parent_file_id: x.path,
file_extension: getExtFromName(x.server_filename),
mime_type: 'whocare',
type: x.isdir === 1 ? 'folder' : 'file',
})))
next = list.length === 100
}

return result
}

function setRequestHeader() {}

function post(api: URL | string, payload: Record<string, string>) {
return fetch(api, {
method: 'POST',
headers: {
'accept': 'application/json, text/plain, */*',
'Content-Type': 'application/x-www-form-urlencoded',
'x-requested-with': 'XMLHttpRequest',
},
credentials: 'include',
body: new URLSearchParams(payload).toString(),
}).then((res) => {
if (res.ok)
return res.json()
else
return Promise.reject(new Error('network error'))
})
}

function get(api: URL | string) {
return fetch(api, {
method: 'GET',
credentials: 'include',
}).then((res) => {
if (res.ok)
return res.json()
else
return Promise.reject(new Error('network error'))
})
}

interface RenameRecord {
id: string
path: string
newName: string
done: () => void
}

function createControledPromise() {
let _resolve: () => void
const promise = new Promise<void>((resolve) => {
_resolve = resolve
})
return {
promise,
done: () => {
_resolve()
},
}
}

let cache: RenameRecord[] = []
let timer: number | undefined
const BATCH_SIZE = 10
async function renameOne(resource: Resource, newName: string) {
const { promise, done } = createControledPromise()

cache.push({
id: resource.file_id,
path: resource.parent_file_id,
newName,
done,
})

if (timer) {
window.clearTimeout(timer)
timer = undefined
}

if (cache.length >= BATCH_SIZE) {
triggerRename(cache)
cache = []
}
else {
timer = window.setTimeout(() => {
triggerRename(cache)
cache = []
}, 100)
}
return promise
}

let bdstoken = ''
initToken()

async function triggerRename(list: RenameRecord[]) {
if (list.length === 0)
return
await post(`https://pan.baidu.com/api/filemanager?async=2&onnest=fail&opera=rename&bdstoken=${bdstoken}&clienttype=0&app_id=250528&web=1`, {
filelist: JSON.stringify(list.map(x => ({
id: +x.id,
path: x.path,
newname: x.newName,
}))),
})
list.forEach(x => x.done())
}

async function initToken() {
const { result } = await get('https://pan.baidu.com/api/gettemplatevariable?clienttype=0&app_id=250528&web=1&fields=[%22bdstoken%22]')
bdstoken = result.bdstoken
}

function getURL(url: string) {
const old = new URL(url)
const hash = old.hash
return new URL(old.origin + hash.replace(/^#/, ''))
}

function shouldShowEntry(url: string) {
const fresh = getURL(url)
return fresh.pathname === '/index' && fresh.searchParams.get('category') === 'all'
}

function getContainer() {
return {
el: document.querySelector('.wp-s-agile-tool-bar__header.is-header-tool'),
style: '',
front: true,
}
}

const provider: Provider = {
DRIVE_NAME: '百度网盘',
HOSTS: ['pan.baidu.com/disk'],
MAX_CONCURRENT: Infinity,
shouldShowEntry,
getContainer,
getApiDelay: () => 0,
renameOne,
setRequestHeader,
ButtonComponent,
getFileListOfCurrentDir,
}

export default provider

0 comments on commit 177cfd8

Please sign in to comment.