liyugang
3 天以前 8c24730e9a52dc2c8933e8d41d2f9651de48a231
src/qbt-task-creator.mjs
@@ -1,45 +1,119 @@
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));
    }
  });
}