diff --git a/models/comic.model.ts b/models/comic.model.ts index e5a5da9..0897268 100644 --- a/models/comic.model.ts +++ b/models/comic.model.ts @@ -54,6 +54,7 @@ const DirectConnectBundleSchema = mongoose.Schema({ name: String, size: String, type: {}, + _id: false, }); const wantedSchema = mongoose.Schema( { diff --git a/services/airdcpp.service.ts b/services/airdcpp.service.ts new file mode 100644 index 0000000..2776d5c --- /dev/null +++ b/services/airdcpp.service.ts @@ -0,0 +1,100 @@ +"use strict"; +import { + Context, + Service, + ServiceBroker, + ServiceSchema, + Errors, +} from "moleculer"; +import axios from "axios"; +import AirDCPPSocket from "../shared/airdcpp.socket"; + +export default class AirDCPPService extends Service { + // @ts-ignore + public constructor( + public broker: ServiceBroker, + schema: ServiceSchema<{}> = { name: "airdcpp" } + ) { + super(broker); + this.parseServiceSchema({ + name: "airdcpp", + mixins: [], + hooks: {}, + actions: { + initialize: { + rest: "POST /initialize", + handler: async ( + ctx: Context<{ + host: { + hostname: string; + port: string; + protocol: string; + username: string; + password: string; + }; + }> + ) => { + try { + const { + host: { + hostname, + protocol, + port, + username, + password, + }, + } = ctx.params; + const airDCPPSocket = new AirDCPPSocket({ + protocol, + hostname: `${hostname}:${port}`, + username, + password, + }); + return await airDCPPSocket.connect(); + } catch (err) { + console.error(err); + } + }, + }, + getHubs: { + rest: "POST /getHubs", + handler: async ( + ctx: Context<{ + host: { + hostname: string; + port: string; + protocol: string; + username: string; + password: string; + }; + }> + ) => { + console.log(ctx.params); + const { + host: { + hostname, + port, + protocol, + username, + password, + }, + } = ctx.params; + try { + const airDCPPSocket = new AirDCPPSocket({ + protocol, + hostname: `${hostname}:${port}`, + username, + password, + }); + await airDCPPSocket.connect(); + return await airDCPPSocket.get(`hubs`); + } catch (err) { + throw err; + } + }, + }, + }, + methods: {}, + }); + } +} diff --git a/services/library.service.ts b/services/library.service.ts index 1199cd7..e417ae1 100644 --- a/services/library.service.ts +++ b/services/library.service.ts @@ -280,93 +280,69 @@ export default class ImportService extends Service { console.log("Saving to Mongo..."); - let condition = {}; - if (wanted.volume && wanted.volume.id) { - condition["wanted.volume.id"] = - wanted.volume.id; - } + if ( + !wanted || + !wanted.volume || + !wanted.volume.id + ) { + console.log( + "No valid identifier for upsert. Attempting to create a new document with minimal data..." + ); + const newDocument = new Comic(payload); // Using the entire payload for the new document - if (Object.keys(condition).length === 0) { - console.log("No valid identifier for upsert."); + await newDocument.save(); return { - success: false, + success: true, message: - "No valid volume identifier provided.", + "New document created due to lack of valid identifiers.", + data: newDocument, }; } - // Check if the volume or issues already exist - const existingVolume = await Comic.findOne( - condition - ); - if (existingVolume) { - // Check for existing issues - let existingIssues = []; - if (wanted.issues && wanted.issues.length > 0) { - existingIssues = wanted.issues.filter( - (issue: any) => - existingVolume.wanted.issues.some( - (existing: any) => - existing.id === issue.id - ) - ); - } + let condition = { + "wanted.volume.id": wanted.volume.id, + }; - if (existingIssues.length > 0) { - return { - success: false, - message: `Issue(s) with ID(s) ${existingIssues - .map((i) => i.id) - .join(", ")} already exist.`, - }; - } - - return { - success: false, - message: - "Volume with this ID already exists.", - }; - } - - // Perform the upsert operation if no existing volume or issues were found - let update = { + let update: any = { + // Using 'any' to bypass strict type checks; alternatively, define a more accurate type $set: { + rawFileDetails: payload.rawFileDetails, + inferredMetadata: payload.inferredMetadata, + sourcedMetadata: payload.sourcedMetadata, + }, + $setOnInsert: { "wanted.source": payload.wanted.source, "wanted.markEntireVolumeWanted": payload.wanted.markEntireVolumeWanted, "wanted.volume": payload.wanted.volume, - "sourcedMetadata.comicvine": - payload.sourcedMetadata.comicvine, }, - $addToSet: {}, }; if (wanted.issues && wanted.issues.length > 0) { - update.$addToSet["wanted.issues"] = { - $each: wanted.issues, + update.$addToSet = { + "wanted.issues": { $each: wanted.issues }, }; } - const updatedDocument = - await Comic.findOneAndUpdate( - condition, - update, - { - upsert: true, - new: true, - setDefaultsOnInsert: true, - overwrite: false, - } - ); + const options = { + upsert: true, + new: true, + }; - console.log( - "Document upserted with new issues:", - updatedDocument + const result = await Comic.findOneAndUpdate( + condition, + update, + options ); + console.log( + "Operation completed. Document updated or inserted:", + result + ); + return { success: true, - message: "Document updated successfully.", - data: updatedDocument, + message: "Document successfully upserted.", + data: result, }; } catch (error) { console.log(error); @@ -377,6 +353,28 @@ export default class ImportService extends Service { } }, }, + getComicsMarkedAsWanted: { + rest: "GET /getComicsMarkedAsWanted", + handler: async (ctx: Context<{}>) => { + try { + // Query to find comics where 'markEntireVolumeAsWanted' is true or 'issues' array is not empty + const wantedComics = await Comic.find({ + wanted: { $exists: true }, + $or: [ + { "wanted.markEntireVolumeWanted": true }, + { "wanted.issues": { $not: { $size: 0 } } }, + ], + }); + + console.log(wantedComics); // Output the found comics + return wantedComics; + } catch (error) { + console.error("Error finding comics:", error); + throw error; + } + }, + }, + applyComicVineMetadata: { rest: "POST /applyComicVineMetadata", params: {}, diff --git a/services/settings.service.ts b/services/settings.service.ts index 361ca1f..c56fa4b 100644 --- a/services/settings.service.ts +++ b/services/settings.service.ts @@ -76,6 +76,7 @@ export default class SettingsService extends Service { }> ) { try { + console.log(ctx.params); let query = {}; const { settingsKey, settingsObjectId } = ctx.params; diff --git a/shared/airdcpp.socket.ts b/shared/airdcpp.socket.ts index 2f1a2c4..a3b0b0e 100644 --- a/shared/airdcpp.socket.ts +++ b/shared/airdcpp.socket.ts @@ -32,7 +32,8 @@ class AirDCPPSocket { this.socketInstance && typeof this.socketInstance.connect === "function" ) { - await this.socketInstance.connect(); + const sessionInformation = await this.socketInstance.connect(); + return sessionInformation; } }