153 lines
5.0 KiB
TypeScript
153 lines
5.0 KiB
TypeScript
"use strict";
|
|
import { Context, Service, ServiceBroker, ServiceSchema, Errors } from "moleculer";
|
|
import io from "socket.io-client";
|
|
|
|
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",
|
|
{},
|
|
);
|
|
|
|
// 2a. Get the list of hubs from AirDC++
|
|
const data: any = await this.broker.call("settings.getSettings", {
|
|
settingsKey: "directConnect",
|
|
});
|
|
const { hubs } = data?.client;
|
|
console.log("HUBZZZZZ", hubs);
|
|
// Iterate through the list of wanted comics
|
|
wantedComics.forEach(async (comic: any) => {
|
|
let issuesToSearch: any = [];
|
|
if (comic.wanted.markEntireVolumeAsWanted) {
|
|
// 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 = {
|
|
issues: comic.wanted.issues,
|
|
volumeName: comic.wanted.volume?.name,
|
|
};
|
|
}
|
|
for (const issue of issuesToSearch.issues) {
|
|
// 2. construct the search queries
|
|
|
|
// 2b. for AirDC++ search, with the volume name, issueId and cover_date
|
|
const { year } = this.parseStringDate(issue.coverDate);
|
|
|
|
const dcppSearchQuery = {
|
|
query: {
|
|
pattern: `${issuesToSearch.volumeName.replace(/#/g, "")} ${
|
|
issue.issueNumber
|
|
} ${year}`,
|
|
extensions: ["cbz", "cbr", "cb7"],
|
|
},
|
|
hub_urls: hubs.map((hub: any) => hub.value),
|
|
priority: 5,
|
|
};
|
|
// Perform the AirDC++ search
|
|
const dcppResults = await this.broker.call("socket.search", {
|
|
query: dcppSearchQuery,
|
|
config: {
|
|
hostname: "localhost:5600",
|
|
protocol: "http",
|
|
username: "user",
|
|
password: "pass",
|
|
},
|
|
namespace: "/automated",
|
|
});
|
|
this.socketIOInstance.on("searchResultUpdated", (data: any) => {
|
|
console.log("Hyaar we go", data);
|
|
});
|
|
// const dcppResults = await ctx.call("airdcpp.search", {
|
|
// dcppSearchQuery,
|
|
// });
|
|
|
|
// 2b. for Prowlarr search, with the volume name, issueId and cover_date
|
|
const prowlarrQuery = {
|
|
port: "9696",
|
|
apiKey: "c4f42e265fb044dc81f7e88bd41c3367",
|
|
offset: 0,
|
|
categories: [7030],
|
|
query: `${issuesToSearch.volumeName} ${issue.issueNumber} ${year}`,
|
|
host: "localhost",
|
|
limit: 100,
|
|
type: "search",
|
|
indexerIds: [2],
|
|
};
|
|
|
|
// Perform the Prowlarr search
|
|
const prowlarrResults = await this.broker.call("prowlarr.search", {
|
|
prowlarrQuery,
|
|
});
|
|
|
|
// Process results here or after the loop
|
|
console.log("DCPP Results: ", dcppResults);
|
|
console.log("Prowlarr Results: ", prowlarrResults);
|
|
}
|
|
});
|
|
},
|
|
},
|
|
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: {
|
|
parseStringDate: (dateString: string) => {
|
|
const date = new Date(dateString);
|
|
|
|
// Get the year, month, and day
|
|
const year = date.getFullYear(); // 2022
|
|
const month = date.getMonth() + 1; // December is 11 in Date object (0-indexed), so add 1 to make it human-readable
|
|
const day = date.getDate(); // 1
|
|
return { year, month, day };
|
|
},
|
|
},
|
|
async started() {
|
|
this.socketIOInstance = io("ws://localhost:3001/automated", {
|
|
transports: ["websocket"],
|
|
withCredentials: true,
|
|
});
|
|
this.socketIOInstance.on("connect", (data: any) => {
|
|
console.log("connected", data);
|
|
});
|
|
|
|
this.socketIOInstance.on("searchResultAdded", (data: any) => {
|
|
console.log("Received searchResultUpdated event:", data);
|
|
});
|
|
},
|
|
});
|
|
}
|
|
}
|