🔧 Added wiring for AirDC++ service
This commit is contained in:
@@ -54,6 +54,7 @@ const DirectConnectBundleSchema = mongoose.Schema({
|
|||||||
name: String,
|
name: String,
|
||||||
size: String,
|
size: String,
|
||||||
type: {},
|
type: {},
|
||||||
|
_id: false,
|
||||||
});
|
});
|
||||||
const wantedSchema = mongoose.Schema(
|
const wantedSchema = mongoose.Schema(
|
||||||
{
|
{
|
||||||
|
|||||||
100
services/airdcpp.service.ts
Normal file
100
services/airdcpp.service.ts
Normal file
@@ -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: {},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -280,93 +280,69 @@ export default class ImportService extends Service {
|
|||||||
|
|
||||||
console.log("Saving to Mongo...");
|
console.log("Saving to Mongo...");
|
||||||
|
|
||||||
let condition = {};
|
if (
|
||||||
if (wanted.volume && wanted.volume.id) {
|
!wanted ||
|
||||||
condition["wanted.volume.id"] =
|
!wanted.volume ||
|
||||||
wanted.volume.id;
|
!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) {
|
await newDocument.save();
|
||||||
console.log("No valid identifier for upsert.");
|
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: true,
|
||||||
message:
|
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
|
let condition = {
|
||||||
const existingVolume = await Comic.findOne(
|
"wanted.volume.id": wanted.volume.id,
|
||||||
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
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existingIssues.length > 0) {
|
let update: any = {
|
||||||
return {
|
// Using 'any' to bypass strict type checks; alternatively, define a more accurate type
|
||||||
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 = {
|
|
||||||
$set: {
|
$set: {
|
||||||
|
rawFileDetails: payload.rawFileDetails,
|
||||||
|
inferredMetadata: payload.inferredMetadata,
|
||||||
|
sourcedMetadata: payload.sourcedMetadata,
|
||||||
|
},
|
||||||
|
$setOnInsert: {
|
||||||
"wanted.source": payload.wanted.source,
|
"wanted.source": payload.wanted.source,
|
||||||
"wanted.markEntireVolumeWanted":
|
"wanted.markEntireVolumeWanted":
|
||||||
payload.wanted.markEntireVolumeWanted,
|
payload.wanted.markEntireVolumeWanted,
|
||||||
"wanted.volume": payload.wanted.volume,
|
"wanted.volume": payload.wanted.volume,
|
||||||
"sourcedMetadata.comicvine":
|
|
||||||
payload.sourcedMetadata.comicvine,
|
|
||||||
},
|
},
|
||||||
$addToSet: {},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (wanted.issues && wanted.issues.length > 0) {
|
if (wanted.issues && wanted.issues.length > 0) {
|
||||||
update.$addToSet["wanted.issues"] = {
|
update.$addToSet = {
|
||||||
$each: wanted.issues,
|
"wanted.issues": { $each: wanted.issues },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatedDocument =
|
const options = {
|
||||||
await Comic.findOneAndUpdate(
|
upsert: true,
|
||||||
condition,
|
new: true,
|
||||||
update,
|
};
|
||||||
{
|
|
||||||
upsert: true,
|
|
||||||
new: true,
|
|
||||||
setDefaultsOnInsert: true,
|
|
||||||
overwrite: false,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log(
|
const result = await Comic.findOneAndUpdate(
|
||||||
"Document upserted with new issues:",
|
condition,
|
||||||
updatedDocument
|
update,
|
||||||
|
options
|
||||||
);
|
);
|
||||||
|
console.log(
|
||||||
|
"Operation completed. Document updated or inserted:",
|
||||||
|
result
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
message: "Document updated successfully.",
|
message: "Document successfully upserted.",
|
||||||
data: updatedDocument,
|
data: result,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(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: {
|
applyComicVineMetadata: {
|
||||||
rest: "POST /applyComicVineMetadata",
|
rest: "POST /applyComicVineMetadata",
|
||||||
params: {},
|
params: {},
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ export default class SettingsService extends Service {
|
|||||||
}>
|
}>
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
console.log(ctx.params);
|
||||||
let query = {};
|
let query = {};
|
||||||
const { settingsKey, settingsObjectId } =
|
const { settingsKey, settingsObjectId } =
|
||||||
ctx.params;
|
ctx.params;
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ class AirDCPPSocket {
|
|||||||
this.socketInstance &&
|
this.socketInstance &&
|
||||||
typeof this.socketInstance.connect === "function"
|
typeof this.socketInstance.connect === "function"
|
||||||
) {
|
) {
|
||||||
await this.socketInstance.connect();
|
const sessionInformation = await this.socketInstance.connect();
|
||||||
|
return sessionInformation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user