| | |
| | | import xlsx from "node-xlsx"; |
| | | import * as fs from 'fs'; |
| | | import * as path from 'path'; |
| | | import * as qbtApi from 'qbittorrent-api-v2'; |
| | | const ignoreFolderMap = {}; |
| | | const downloadedFileMap = new Map(); |
| | | const fileMap = {}; |
| | | |
| | | async function sleep(ms) { |
| | | return new Promise((resolve) => { |
| | | setTimeout(resolve, ms); |
| | | }); |
| | | } |
| | | function loadIgnoreFolderMap() { |
| | | fs.readFileSync('ignore-folder.txt', 'utf8').replace(/\r/g, '').split('\n').forEach((line) => { |
| | | ignoreFolderMap[line.trim()] = true; |
| | | }); |
| | | } |
| | | function loadFileMap() { |
| | | const workSheets = xlsx.parse("libgen-撞库图书.xlsx"); |
| | | const sheet = workSheets[0]; |
| | | for (const row of sheet.data) { |
| | | const [id, file] = row; |
| | | const folderName = (Math.floor(parseInt(id) / 1000) * 1000).toFixed(0); |
| | | if (!fileMap[folderName]) { |
| | | fileMap[folderName] = {}; |
| | | } |
| | | fileMap[folderName][file] = true; |
| | | const ids = fs.readFileSync('8月1和2书单-nofiction.txt', 'utf8').replace(/\r/g, '').split('\n'); |
| | | for (const id of ids) { |
| | | const md5 = id.split('.')[0]; |
| | | fileMap[md5] = id; |
| | | } |
| | | } |
| | | |
| | | function loadDownloadedFileMap() { |
| | | const files = fs.readFileSync('8月1和2书单-nofiction-downloaded.txt', 'utf-8').replace(/\r/g, '').split('\n'); |
| | | for (const file of files) { |
| | | downloadedFileMap.set(file.split('.')[0], file); |
| | | } |
| | | } |
| | | |
| | | function copyFiles() { |
| | | const ws = fs.createWriteStream('8月1和2书单-nofiction-downloaded.txt', { flags: 'a', encoding: 'utf8' }); |
| | | const fileMap = new Map(); |
| | | fs.readFileSync('8月1和2书单-nofiction.txt', "utf8").replace(/\r/g, '').split("\n").forEach(id => fileMap.set(id.split('.')[0], id)); |
| | | const dir = 'C:\\Users\\lyg\\Downloads\\down'; |
| | | const dst = "D:\\test111"; |
| | | fs.readdirSync(dir).filter(folder => fs.statSync(path.join(dir, folder)).isDirectory()).forEach(folder => { |
| | | fs.readdirSync(path.join(dir, folder)).forEach(fileId => { |
| | | if (fileMap.has(fileId)) { |
| | | try { |
| | | fs.copyFileSync(path.join(dir, folder, fileId), path.join(dst, fileMap.get(fileId))); |
| | | fs.unlinkSync(path.join(dir, folder, fileId)); |
| | | ws.write(fileMap.get(fileId) + "\n"); |
| | | } catch (e) { } |
| | | } |
| | | }); |
| | | }); |
| | | ws.close(); |
| | | } |
| | | |
| | | async function main() { |
| | | // loadIgnoreFolderMap(); |
| | | loadFileMap(); |
| | | |
| | | copyFiles(); |
| | | await sleep(2000); |
| | | loadDownloadedFileMap(); |
| | | const qbt = await qbtApi.connect('http://localhost:8081', 'admin', 'adminadmin'); |
| | | |
| | | const ignoreTors = []; |
| | | const tors = []; |
| | | const torrents = await qbt.torrents(); |
| | | for (const torrent of torrents) { |
| | | if (torrent.state === 'pausedUP') { continue; } |
| | | // if (torrent.state === 'pausedUP') { continue; } |
| | | const contents = await qbt.files(torrent.hash); |
| | | const torName = torrent.name; |
| | | const files = fileMap[torName]; |
| | | if (!files) { |
| | | continue; |
| | | } |
| | | tors.push(torrent.hash); |
| | | const fileIds = []; |
| | | const ignoreFileIds = []; |
| | | for (const content of contents) { |
| | | const contentName = content.name.split("/")[1]; |
| | | if (!files[contentName]) { |
| | | if (!fileMap[contentName] || ignoreFolderMap[torrent.name] || downloadedFileMap.has(contentName)) { |
| | | ignoreFileIds.push(content.index); |
| | | } else { |
| | | fileIds.push(content.index); |
| | | } |
| | | } |
| | | if (ignoreFileIds.length) { |
| | | let retry = true; |
| | | while (retry) { |
| | | await sleep(100); |
| | | await qbt.setFilePriority(torrent.hash, ignoreFileIds.join('|'), "0").then(() => retry = false).catch(() => { }); |
| | | } |
| | | } |
| | | if (fileIds.length) { |
| | | await qbt.setFilePriority(torrent.hash, fileIds.join('|'), "0"); |
| | | let retry = true; |
| | | while (retry) { |
| | | await sleep(100); |
| | | await qbt.setFilePriority(torrent.hash, fileIds.join('|'), "1").then(() => retry = false).catch(() => { }); |
| | | } |
| | | } else { |
| | | ignoreTors.push(torrent.hash); |
| | | } |
| | | } |
| | | if (ignoreTors.length) { |
| | | await qbt.pauseTorrents(ignoreTors.join('|')); |
| | | } |
| | | if (tors.length) { |
| | | await qbt.resumeTorrents(tors.join('|')); |
| | | } |
| | | |
| | | setTimeout(() => { |
| | | |
| | | }, 1000 * 60 ** 60 * 5); |
| | | } |
| | | |
| | | main(); |
| | | main(); |
| | | |
| | | function fixFileName(){ |
| | | loadFileMap(); |
| | | const dir = ''; |
| | | fs.readdirSync(dir).forEach(file => { |
| | | if (fileMap[file]) { |
| | | const filename = fileMap[file]; |
| | | fs.renameSync(path.join(dir, file), path.join(dir, filename)); |
| | | } |
| | | }); |
| | | } |