Skip to content

Commit

Permalink
feature: 下载文件夹,使用 JSON RPC 时保留文件夹结构
Browse files Browse the repository at this point in the history
  • Loading branch information
Yingyya committed Aug 7, 2024
1 parent f81419c commit c0cf656
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 26 deletions.
126 changes: 103 additions & 23 deletions src/pages/Parsed.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import InputText from 'primevue/inputtext';
import Button from 'primevue/button';
import Divider from 'primevue/divider';
import ButtonGroup from 'primevue/buttongroup';
import {onBeforeUnmount, onMounted, ref} from 'vue';
import {nextTick, onBeforeUnmount, onMounted, ref} from 'vue';
import {storeToRefs} from 'pinia';
import {useCacheStore, useUserStore} from '@/store';
import {useMessage} from '@/hooks/useMessage';
Expand All @@ -25,6 +25,7 @@ import {testJsonrpc} from '@/utils/test-jsonrpc';
import {stringIsEmpty} from '@/utils/string-is-empty';
import {actionTwo} from '@/utils/show-driver';
import delay from '@/utils/delay';
import {getJsonRpcConfig} from '@/utils/get-jsonrpc-config';
const route = useRoute();
const router = useRouter();
Expand All @@ -36,8 +37,8 @@ const filesRef = ref<TreeFileInfo[] | undefined>(undefined);
const diskRoot = ref<string | undefined>(undefined);
const message = useMessage();
const treeLoading = ref(false);
const selectedFilesOrigin = ref([]);
const selectedFiles = ref<TreeFileInfo[]>([]);
const selectedFilesOrigin = ref<Record<string | number, any>>({});
const selectedFiles = ref<(TreeFileInfo & TreeNode)[]>([]);
const starting = ref(false);
const shareInfo = ref<ShareInfo>({seckey: '', share_id: '', uk: ''});
const worker = useWorker();
Expand All @@ -50,6 +51,7 @@ const downloadType = ref<{
}>({
code: ''
});
const rndDir = ref('');
const progress = ref(0);
const results: ParsedFile[] = [];
Expand All @@ -67,6 +69,7 @@ onMounted(async () => {
const {data: response} = await getFileList(requestId, undefined);
const {data} = response;
const files = data.list;
rndDir.value = files[0].filename;
const {root, tree} = dealFileList(files);
shareInfo.value = data.shareinfo;
diskRoot.value = root;
Expand Down Expand Up @@ -97,24 +100,54 @@ const onNodeExpand = async (node: TreeNode) => {
node.loading = false;
}
};
// 过滤选择文件夹 (只选择文件)
const onNodeSelect = (node: TreeNode & TreeFileInfo) => {
if (!node.leaf) return;
const found = selectedFiles.value.find(v => v.fs_id === node.fs_id);
if (!found) {
selectedFiles.value.push(node);
const selectFile = (node: TreeNode & TreeFileInfo) => {
if (!node.leaf && node.children === undefined) {
nextTick(() => {
delete selectedFilesOrigin.value[node.key];
});
return;
}
if (node.children && !node.leaf) {
node.children.forEach((child => selectFile(child as typeof node)));
} else {
const found = selectedFiles.value.find(v => v.fs_id === node.fs_id);
if (!found) {
selectedFiles.value.push(node);
}
}
};
const onNodeUnSelect = (node: TreeNode) => {
if (!node.leaf) return;
const found = selectedFiles.value.findIndex(v => v.fs_id === node.fs_id);
if (found !== -1) {
selectedFiles.value.splice(found, 1);
const unSelectFile = (node: TreeNode & TreeFileInfo) => {
if (node.children) {
node.children.forEach((child => unSelectFile(child as typeof node)));
} else {
const found = selectedFiles.value.findIndex(v => v.fs_id === node.fs_id);
if (found !== -1) {
selectedFiles.value.splice(found, 1);
}
}
};
const onNodeSelect = (node: TreeNode & TreeFileInfo) => {
if (!node.leaf && node.children === undefined) {
message.warn('请先加载该文件夹下的所有文件!');
nextTick(() => {
delete selectedFilesOrigin.value[node.key];
});
return;
}
selectFile(node);
};
const onNodeUnSelect = (node: TreeNode & TreeFileInfo) => {
if (!node.leaf) {
node?.children?.forEach(child => unSelectFile(child as typeof node));
return;
}
unSelectFile(node);
};
const dialogStore = useCacheStore();
const start = () => {
if (stringIsEmpty(downloadType.value.code)) {
Expand All @@ -127,9 +160,18 @@ const start = () => {
starting.value = true;
dialogStore.interceptUnload = true;
const body: WorkerRequestBody[] = [];
for (let file of selectedFiles.value) {
body.push({fs_id: file.fs_id, reqId: requestId, surl, pwd, ...shareInfo.value});
}
const add = (file: TreeFileInfo & TreeNode) => {
if (file.children) {
file.children.forEach(child => {
add(child as typeof file);
});
} else {
body.push({fs_id: file.fs_id, reqId: requestId, surl, pwd, ...shareInfo.value});
}
};
selectedFiles.value.forEach(file => {
add(file);
});
worker.addTask(body);
};
Expand All @@ -154,13 +196,19 @@ const onWorkerMessage = async (m: WorkerResponse) => {
}
if (m.type === 'progress') {
const max = m.max || 1;
const n = m.n || 0
const n = m.n || 0;
progress.value = Math.round(n / max * 100);
return;
}
if (m.type === 'success') {
if (downloadType.value.code === 'jsonrpc') {
sendToRPC(m!!.body!!.dlink, m!!.body!!.filename);
const file = selectedFiles.value.find(f => f.fs_id === m!!.body!!.filefsid);
if (file === undefined) {
message.warn(`${m!!.body!!.filename} 下载失败,请刷新页面后重试!`);
return;
}
const rootDir = file.path.replace(new RegExp(`/${rndDir.value}.*`, 'g'), '');
sendToRPC(m!!.body!!.dlink, m!!.body!!.filename, file.path.replace(new RegExp(`^${rootDir}`), '').replace(m!!.body!!.filename, ''));
return;
}
// Web
Expand All @@ -184,6 +232,17 @@ const testConnectionRPC = () => {
});
};
const getRPConfig = async () => {
getJsonRpcConfig().then(rpcConfig => {
if (rpcConfig.dir) {
rpcRef.value.basedir = rpcConfig.dir;
message.success('获取成功!');
} else {
message.warn('获取失败!');
}
});
};
onBeforeUnmount(() => {
worker.setCallback(undefined);
});
Expand All @@ -206,7 +265,7 @@ worker.setCallback(onWorkerMessage);
<BlockUI :blocked="blocked">
<ProgressBar v-if="blocked || treeLoading" mode="indeterminate"
style="height: 6px"></ProgressBar>
<Tree class="mt-4" loadingMode="icon" :value="filesRef" selection-mode="multiple"
<Tree class="mt-4" loadingMode="icon" :value="filesRef" selection-mode="checkbox"
@node-expand="onNodeExpand" :loading="treeLoading" @nodeSelect="onNodeSelect"
@nodeUnselect="onNodeUnSelect"
v-model:selectionKeys="selectedFilesOrigin"/>
Expand Down Expand Up @@ -236,7 +295,8 @@ worker.setCallback(onWorkerMessage);
</li>
</ul>
</Fieldset>
<Fieldset legend="下载配置" class="mt-4 mb-4 p-fluid" toggleable :disabled="blocked" id="driver-step-select-download-type">
<Fieldset legend="下载配置" class="mt-4 mb-4 p-fluid" toggleable :disabled="blocked"
id="driver-step-select-download-type">
<div class="formgrid grid">
<div class="field col">
<label for="type">下载方式</label>
Expand Down Expand Up @@ -280,14 +340,34 @@ worker.setCallback(onWorkerMessage);
@click="testConnectionRPC"></Button>
</div>
</div>
<div class="formgrid grid">
<div class="field col">
<label for="basedir">下载目录(最好不要留空)</label>
<InputText type="text" placeholder="" v-model="rpcRef.basedir"/>
</div>
<div class="field col">
<Button label="获取配置" style="margin-top: 25px;" id="driver-step-test-json-rpc"
@click="getRPConfig"></Button>
</div>
</div>
<Divider></Divider>
<p>下载目录为在操作系统中目录,而不是网盘目录,如果留空可能会现在在操作系统的根目录,如果不知道当前配置的下载目录,可以点击【获取配置】来自动获取。<br>
<strong>例如:</strong><br>
下载目录是:D:/下载<br>
选择的文件夹是:/视频/a.mp4<br>
那么下载地址是:D:/下载/视频/a.mp4<br>
<strong>保存的文件夹和您分享出的文件的根目录有关,和您网盘的存储路径无关。</strong>
</p>
</template>
</Fieldset>
<Fieldset legend="准备下载">
<ProgressBar :mode="starting && progress === 0 ? 'indeterminate' : 'determinate'" v-if="starting"
<ProgressBar :mode="starting && progress === 0 ? 'indeterminate' : 'determinate'"
v-if="starting"
:value="progress"></ProgressBar>
<Divider/>
<ButtonGroup>
<Button label="开始" icon="pi pi-check" :disabled="selectedFiles.length === 0" id="driver-step-done"
<Button label="开始" icon="pi pi-check" :disabled="selectedFiles.length === 0"
id="driver-step-done"
@click="start"/>
<Button label="取消" icon="pi pi-times" :disabled="!starting" @click="stop"/>
</ButtonGroup>
Expand Down
3 changes: 2 additions & 1 deletion src/store/modules/user-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export const useUserStore = defineStore('user-store', {
rpc: {
host: 'localhost',
port: '6800',
token: ''
token: '',
basedir: ''
}
};
},
Expand Down
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export type RPCConfig = {
host: string;
port: string;
token: string;
basedir: string;
};

export type FileListResult = {
Expand Down Expand Up @@ -59,6 +60,7 @@ export type ParsedFileResult = {
dlink: string;
ua: string;
use_cache: boolean;
filefsid: string;
};

export type Notice = {
Expand Down
19 changes: 19 additions & 0 deletions src/utils/get-jsonrpc-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import axios from 'axios';
import {useUserStore} from '@/store';

export async function getJsonRpcConfig(): Promise<Record<string, string>> {
const user = useUserStore();
try {
const {data} = await axios.post(`http://${user.rpc.host}:${user.rpc.port}/jsonrpc`, {
jsonrpc: '2.0',
id: 'F4Pan',
method: 'aria2.getGlobalOption',
params: []
}, {
timeout: 1000 * 5
});
return data.result;
} catch {
return {};
}
}
6 changes: 4 additions & 2 deletions src/utils/send-to-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import axios from 'axios';
import {useSystemConfigStore, useUserStore} from '@/store';
import {useMessage} from '@/hooks/useMessage';

export function sendToRPC(url: string, filename: string) {
export function sendToRPC(url: string, filename: string, dir?: string) {
const user = useUserStore();
const system = useSystemConfigStore();
const message = useMessage();
const basedir = user.rpc.basedir.replace(/\/$/, '');
axios.post(`http://${user.rpc.host}:${user.rpc.port}/jsonrpc`, {
jsonrpc: '2.0',
id: 'F4Pan',
Expand All @@ -15,7 +16,8 @@ export function sendToRPC(url: string, filename: string) {
[url],
{
out: filename,
header: [`User-Agent: ${system.parse_ua}`]
header: [`User-Agent: ${system.parse_ua}`],
dir: `${basedir}/${dir}`,
}
]
}).then(() => {
Expand Down

0 comments on commit c0cf656

Please sign in to comment.