➕ Added an AutoDownloadService
This commit is contained in:
95
package-lock.json
generated
95
package-lock.json
generated
@@ -21,6 +21,7 @@
|
|||||||
"@types/parse-torrent": "^5.8.7",
|
"@types/parse-torrent": "^5.8.7",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.44.0",
|
"@typescript-eslint/eslint-plugin": "^5.44.0",
|
||||||
"@typescript-eslint/parser": "^5.44.0",
|
"@typescript-eslint/parser": "^5.44.0",
|
||||||
|
"airdcpp-apisocket": "^2.4.4",
|
||||||
"axios": "^1.5.0",
|
"axios": "^1.5.0",
|
||||||
"concurrently": "^7.6.0",
|
"concurrently": "^7.6.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
@@ -36,7 +37,8 @@
|
|||||||
"qbittorrent-api-v2": "^1.2.2",
|
"qbittorrent-api-v2": "^1.2.2",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"typescript": "^4.9.3"
|
"typescript": "^4.9.3",
|
||||||
|
"ws": "^8.16.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16.x.x"
|
"node": ">= 16.x.x"
|
||||||
@@ -1759,6 +1761,19 @@
|
|||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/airdcpp-apisocket": {
|
||||||
|
"version": "2.4.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/airdcpp-apisocket/-/airdcpp-apisocket-2.4.4.tgz",
|
||||||
|
"integrity": "sha512-Xn0kWSVdLJwPpOoHcdI2wzzfzZW2jTpuyZR2wCNs2UIlZhO+FTwMf3QQfNCt5gYTOld9LaiCEulxFuXDA8qrLA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"chalk": "^4.1.2",
|
||||||
|
"events": "^3.3.0",
|
||||||
|
"invariant": "^2.2.4",
|
||||||
|
"is-in-browser": "^2.0.0",
|
||||||
|
"promise": "^8.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ajv": {
|
"node_modules/ajv": {
|
||||||
"version": "6.12.6",
|
"version": "6.12.6",
|
||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||||
@@ -2061,6 +2076,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/asap": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||||
|
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/astral-regex": {
|
"node_modules/astral-regex": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
|
||||||
@@ -3694,6 +3715,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz",
|
"resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz",
|
||||||
"integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg=="
|
"integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/events": {
|
||||||
|
"version": "3.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
||||||
|
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/execa": {
|
"node_modules/execa": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
|
||||||
@@ -3881,9 +3911,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/follow-redirects": {
|
"node_modules/follow-redirects": {
|
||||||
"version": "1.15.5",
|
"version": "1.15.6",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
|
||||||
"integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==",
|
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -4387,6 +4417,15 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/invariant": {
|
||||||
|
"version": "2.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||||
|
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"loose-envify": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ioredis": {
|
"node_modules/ioredis": {
|
||||||
"version": "5.3.2",
|
"version": "5.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.3.2.tgz",
|
||||||
@@ -4544,6 +4583,12 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-in-browser": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-/NUv5pqj+krUJalhGpj0lyy+x7vrD9jt1PlAfkoIDEXqE+xZgFJ4FU8e9m99WuHbCqsBZVf+nzvAjNso+SO80A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/is-interactive": {
|
"node_modules/is-interactive": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
|
||||||
@@ -5521,6 +5566,18 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/loose-envify": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"loose-envify": "cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lru-cache": {
|
"node_modules/lru-cache": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||||
@@ -6485,6 +6542,15 @@
|
|||||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/promise": {
|
||||||
|
"version": "8.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz",
|
||||||
|
"integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"asap": "~2.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/prompts": {
|
"node_modules/prompts": {
|
||||||
"version": "2.4.2",
|
"version": "2.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
|
||||||
@@ -7960,6 +8026,27 @@
|
|||||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ws": {
|
||||||
|
"version": "8.16.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
|
||||||
|
"integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": ">=5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/y18n": {
|
"node_modules/y18n": {
|
||||||
"version": "5.0.8",
|
"version": "5.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||||
|
|||||||
68
services/autodownload.service.ts
Normal file
68
services/autodownload.service.ts
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
"use strict";
|
||||||
|
import { Context, Service, ServiceBroker, ServiceSchema, Errors } from "moleculer";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
export default class AutoDownloadService extends Service {
|
||||||
|
// @ts-ignore
|
||||||
|
public constructor(
|
||||||
|
public broker: ServiceBroker,
|
||||||
|
schema: ServiceSchema<{}> = { name: "autodownload" },
|
||||||
|
) {
|
||||||
|
super(broker);
|
||||||
|
this.parseServiceSchema({
|
||||||
|
name: "autodownload",
|
||||||
|
mixins: [],
|
||||||
|
hooks: {},
|
||||||
|
actions: {
|
||||||
|
searchWantedComics: {
|
||||||
|
rest: "POST /searchWantedComics",
|
||||||
|
handler: async (ctx: Context<{}>) => {
|
||||||
|
// 1.iterate through the wanted comic objects, and:
|
||||||
|
// 1a. Orchestrate all issues from ComicVine if the entire volume is wanted
|
||||||
|
// 1b. Just the issues in "wanted.issues[]"
|
||||||
|
const wantedComics: any = await this.broker.call(
|
||||||
|
"library.getComicsMarkedAsWanted",
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Iterate through the list of wanted comics
|
||||||
|
for (const comic of wantedComics) {
|
||||||
|
let issuesToSearch: any = [];
|
||||||
|
|
||||||
|
if (comic.wanted.markEntireVolumeAsWanted) {
|
||||||
|
// 1a. Fetch all issues from ComicVine if the entire volume is wanted
|
||||||
|
issuesToSearch = await this.broker.call(
|
||||||
|
"comicvine.getIssuesForVolume",
|
||||||
|
{
|
||||||
|
volumeId: comic.wanted.volume.id,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else if (comic.wanted.issues && comic.wanted.issues.length > 0) {
|
||||||
|
// 1b. Just the issues in "wanted.issues[]"
|
||||||
|
issuesToSearch = comic.wanted.issues;
|
||||||
|
}
|
||||||
|
for (const issue of issuesToSearch) {
|
||||||
|
// construct the search queries
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
determineDownloadChannel: {
|
||||||
|
rest: "POST /determineDownloadChannel",
|
||||||
|
handler: async (ctx: Context<{}>) => {
|
||||||
|
// 1. Parse the incoming search query
|
||||||
|
// to make sure that it is well-formed
|
||||||
|
// At the very least, it should have name, year, number
|
||||||
|
// 2. Choose between download mediums based on user-preference?
|
||||||
|
// possible choices are: DC++, Torrent
|
||||||
|
// 3. Perform the search on those media with the aforementioned search query
|
||||||
|
// 4. Choose a subset of relevant search results,
|
||||||
|
// and score them
|
||||||
|
// 5. Download the highest-scoring, relevant result
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -65,6 +65,7 @@ export default class ProwlarrService extends Service {
|
|||||||
offset: number;
|
offset: number;
|
||||||
}>,
|
}>,
|
||||||
) => {
|
) => {
|
||||||
|
console.log(JSON.stringify(ctx.params, null, 2));
|
||||||
const {
|
const {
|
||||||
indexerIds,
|
indexerIds,
|
||||||
categories,
|
categories,
|
||||||
@@ -76,15 +77,16 @@ export default class ProwlarrService extends Service {
|
|||||||
limit,
|
limit,
|
||||||
offset,
|
offset,
|
||||||
} = ctx.params;
|
} = ctx.params;
|
||||||
|
const indexer = indexerIds[0] ? indexerIds.length === 1 : indexerIds;
|
||||||
|
const category = categories[0] ? categories.length === 1 : categories;
|
||||||
const result = await axios({
|
const result = await axios({
|
||||||
url: `http://${host}:${port}/api/v1/search`,
|
url: `http://${host}:${port}/api/v1/search`,
|
||||||
method: "GET",
|
method: "GET",
|
||||||
params: {
|
params: {
|
||||||
query,
|
query,
|
||||||
type,
|
type,
|
||||||
indexerIds,
|
indexer,
|
||||||
categories,
|
category,
|
||||||
limit,
|
limit,
|
||||||
offset,
|
offset,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -86,7 +86,6 @@ export default class QBittorrentService extends Service {
|
|||||||
getClientInfo: {
|
getClientInfo: {
|
||||||
rest: "GET /getClientInfo",
|
rest: "GET /getClientInfo",
|
||||||
handler: async (ctx: Context<{}>) => {
|
handler: async (ctx: Context<{}>) => {
|
||||||
console.log(this.meta.app);
|
|
||||||
await this.broker.call("qbittorrent.loginWithStoredCredentials", {});
|
await this.broker.call("qbittorrent.loginWithStoredCredentials", {});
|
||||||
return {
|
return {
|
||||||
buildInfo: await this.meta.app.buildInfo(),
|
buildInfo: await this.meta.app.buildInfo(),
|
||||||
@@ -212,6 +211,20 @@ export default class QBittorrentService extends Service {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
determineDownloadApps: {
|
||||||
|
rest: "",
|
||||||
|
handler: async () => {
|
||||||
|
// 1. Parse the incoming search query
|
||||||
|
// to make sure that it is well-formed
|
||||||
|
// At the very least, it should have name, year, number
|
||||||
|
// 2. Choose between download mediums based on user-preference?
|
||||||
|
// possible choices are: DC++, Torrent
|
||||||
|
// 3. Perform the search on those media with the aforementioned search query
|
||||||
|
// 4. Choose a subset of relevant search results,
|
||||||
|
// and score them
|
||||||
|
// 5. Download the highest-scoring, relevant result
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {},
|
methods: {},
|
||||||
async started() {
|
async started() {
|
||||||
|
|||||||
Reference in New Issue
Block a user