🤼‍♀️ ES-powered issue detection feature

This commit is contained in:
2022-02-01 23:20:20 -08:00
parent ec2f5e0f09
commit 28483f81e4
4 changed files with 87 additions and 64 deletions

14
package-lock.json generated
View File

@@ -46,7 +46,7 @@
"node-unrar-js": "^1.0.2", "node-unrar-js": "^1.0.2",
"sharp": "^0.28.3", "sharp": "^0.28.3",
"socket.io": "^4.4.0", "socket.io": "^4.4.0",
"threetwo-ui-typings": "^1.0.11", "threetwo-ui-typings": "^1.0.12",
"through2": "^4.0.2", "through2": "^4.0.2",
"unrar": "^0.2.0", "unrar": "^0.2.0",
"xml2js": "^0.4.23" "xml2js": "^0.4.23"
@@ -11247,9 +11247,9 @@
"dev": true "dev": true
}, },
"node_modules/threetwo-ui-typings": { "node_modules/threetwo-ui-typings": {
"version": "1.0.11", "version": "1.0.12",
"resolved": "https://registry.npmjs.org/threetwo-ui-typings/-/threetwo-ui-typings-1.0.11.tgz", "resolved": "https://registry.npmjs.org/threetwo-ui-typings/-/threetwo-ui-typings-1.0.12.tgz",
"integrity": "sha512-jRI1rUttoJDqsKFUPd4MM56NErftl2NSEo8MkeqllOtVf38Wy+wVvAT+OW6AoSguA5cLxSpOiA25c31FWjOvOw==", "integrity": "sha512-lKADNpD2Oa3Wmf6tdZhaPSNfIFa0KtstsZLE0yalTjqKmtQZM7Ct2OnlCkH7aonDuVn+jgcRMwkcP9krCqa2fw==",
"dependencies": { "dependencies": {
"typescript": "^4.3.2" "typescript": "^4.3.2"
} }
@@ -20540,9 +20540,9 @@
"dev": true "dev": true
}, },
"threetwo-ui-typings": { "threetwo-ui-typings": {
"version": "1.0.11", "version": "1.0.12",
"resolved": "https://registry.npmjs.org/threetwo-ui-typings/-/threetwo-ui-typings-1.0.11.tgz", "resolved": "https://registry.npmjs.org/threetwo-ui-typings/-/threetwo-ui-typings-1.0.12.tgz",
"integrity": "sha512-jRI1rUttoJDqsKFUPd4MM56NErftl2NSEo8MkeqllOtVf38Wy+wVvAT+OW6AoSguA5cLxSpOiA25c31FWjOvOw==", "integrity": "sha512-lKADNpD2Oa3Wmf6tdZhaPSNfIFa0KtstsZLE0yalTjqKmtQZM7Ct2OnlCkH7aonDuVn+jgcRMwkcP9krCqa2fw==",
"requires": { "requires": {
"typescript": "^4.3.2" "typescript": "^4.3.2"
}, },

View File

@@ -95,10 +95,10 @@ export default class ApiService extends Service {
console.log("Client connected via websocket!"); console.log("Client connected via websocket!");
client.on("action", async (action) => { client.on("action", async (action) => {
console.log("ACCCCCTION", action);
switch (action.type) { switch (action.type) {
case "LS_IMPORT": case "LS_IMPORT":
// 1. Send task to queue // 1. Send task to queue
console.log(`Recieved ${action.type} event.`)
await this.broker.call( await this.broker.call(
"import.newImport", "import.newImport",
action.data, action.data,

View File

@@ -31,8 +31,6 @@ SOFTWARE.
* Initial: 2022/01/28 Rishi Ghan * Initial: 2022/01/28 Rishi Ghan
*/ */
"use strict"; "use strict";
import { isNil, isUndefined, map } from "lodash"; import { isNil, isUndefined, map } from "lodash";
import { import {
@@ -395,7 +393,7 @@ export default class ImportService extends Service {
{ {
$group: { $group: {
_id: "$sourcedMetadata.comicvine.volume.id", _id: "$sourcedMetadata.comicvine.volume.id",
comicObjectId : { $first: "$_id" }, comicObjectId: { $first: "$_id" },
volumeURI: { volumeURI: {
$last: "$sourcedMetadata.comicvine.volume.api_detail_url", $last: "$sourcedMetadata.comicvine.volume.api_detail_url",
}, },
@@ -416,17 +414,21 @@ export default class ImportService extends Service {
volumesMetadata = map(volumes, async (volume) => { volumesMetadata = map(volumes, async (volume) => {
console.log(volume); console.log(volume);
if (!isNil(volume.volumeURI)) { if (!isNil(volume.volumeURI)) {
const volumeMetadata = await ctx.call("comicvine.getVolumes", { const volumeMetadata = await ctx.call(
volumeURI: volume.volumeURI, "comicvine.getVolumes",
data: { {
format: "json", volumeURI: volume.volumeURI,
fieldList: data: {
"id,name,deck,api_detail_url", format: "json",
limit: "1", fieldList:
offset: "0", "id,name,deck,api_detail_url",
}, limit: "1",
}); offset: "0",
volumeMetadata["comicObjectId"] = volume.comicObjectId; },
}
);
volumeMetadata["comicObjectId"] =
volume.comicObjectId;
return volumeMetadata; return volumeMetadata;
} }
}); });
@@ -434,21 +436,23 @@ export default class ImportService extends Service {
return Promise.all(volumesMetadata); return Promise.all(volumesMetadata);
}, },
}, },
getIssuesForSeries: { findIssuesForSeriesInLibrary: {
rest: "POST /getIssuesForSeries", rest: "POST /findIssuesForSeriesInLibrary",
params: {}, params: {},
handler: async (ctx:Context<{ comicObjectID: string }>) => { handler: async (
// 1. Query mongo to get issues for a given volume ctx: Context<{ comicObjectID: string }>
) => {
// 1. Query mongo to get the comic document by its _id
const comicBookDetails: any = await this.broker.call( const comicBookDetails: any = await this.broker.call(
"import.getComicBookById", "import.getComicBookById",
{ id: ctx.params.comicObjectID } { id: ctx.params.comicObjectID }
); );
// 2. Query CV and get metadata for them // 2. Query CV and get metadata for them
comicBookDetails.sourcedMetadata.comicvine.volumeInformation.issues.map( const foo =
async (issue: any, idx: any) => { await comicBookDetails.sourcedMetadata.comicvine.volumeInformation.issues.map(
const issueMetadata: any = async (issue: any, idx: any) => {
await axios.request({ const metadata: any = await axios.request({
url: `${issue.api_detail_url}?api_key=${process.env.COMICVINE_API_KEY}`, url: `${issue.api_detail_url}?api_key=${process.env.COMICVINE_API_KEY}`,
params: { params: {
resources: "issues", resources: "issues",
@@ -459,29 +463,34 @@ export default class ImportService extends Service {
"User-Agent": "ThreeTwo", "User-Agent": "ThreeTwo",
}, },
}); });
const metadata = const issueMetadata = metadata.data.results;
issueMetadata.data.results;
// 2a. Query Mongo with Elastic to see if a match exists for a given issue's name, and issue number
if (
!isUndefined(metadata.volume.name) &&
!isUndefined(metadata.issue_number)
) {
console.log("asdasd", metadata.volume.name);
await ctx.broker.call("libraryqueue.issuesForSeries", { queryObject: {
issueName:
metadata.volume
.name,
issueNumber:
metadata.issue_number,
}});
}
return issueMetadata.data.results; // 2a. Enqueue the Elasticsearch job
} if (
); !isUndefined(issueMetadata.volume.name) &&
} !isUndefined(issueMetadata.issue_number)
) {
await ctx.broker.call(
"libraryqueue.issuesForSeries",
{
queryObject: {
issueId: issue.id,
issueName:
issueMetadata.volume
.name,
issueNumber:
issueMetadata.issue_number,
issueMetadata,
},
}
);
}
// 3. Just return the issues
return issueMetadata;
}
);
return Promise.all(foo);
},
}, },
flushDB: { flushDB: {
rest: "POST /flushDB", rest: "POST /flushDB",

View File

@@ -33,7 +33,7 @@ SOFTWARE.
"use strict"; "use strict";
import { isNil, isUndefined } from "lodash"; import { extend, isNil, isUndefined } from "lodash";
import { import {
Context, Context,
Service, Service,
@@ -101,20 +101,30 @@ export default class LibraryQueueService extends Service {
async process(job: SandboxedJob) { async process(job: SandboxedJob) {
try { try {
console.log( console.log(
"reached the issuematchinlibrary queue" "Job recieved to find issue matches in library."
); );
console.log(job.data);
const matchesInLibrary = await this.broker.call( const matchesInLibrary = await this.broker.call(
"search.searchComic", "search.searchComic",
{ {
queryObject: job.data.queryObject, queryObject: job.data.queryObject,
} }
); );
console.log( if (
`Matches in Library: ${matchesInLibrary}` !isNil(matchesInLibrary) &&
); !isUndefined(matchesInLibrary)
) {
console.log("Matches found in library:");
return Promise.all(matchesInLibrary); const foo = extend(
{ issue: job.data.queryObject.issueMetadata },
{ matches: matchesInLibrary }
);
return foo;
} else {
console.log(
"No match was found for this issue in the library."
);
}
} catch (error) { } catch (error) {
throw error; throw error;
} }
@@ -139,10 +149,14 @@ export default class LibraryQueueService extends Service {
rest: "POST /findIssuesForSeries", rest: "POST /findIssuesForSeries",
params: {}, params: {},
handler: async ( handler: async (
ctx: Context<{ queryObject: { ctx: Context<{
issueName: string, queryObject: {
issueNumber: string, issueName: string;
} }> issueNumber: string;
issueId: string;
issueMetadata: object;
};
}>
) => { ) => {
return await this.createJob( return await this.createJob(
"issue.findMatchesInLibrary", "issue.findMatchesInLibrary",
@@ -197,7 +211,7 @@ export default class LibraryQueueService extends Service {
"completed", "completed",
async (job, res) => { async (job, res) => {
client.emit("action", { client.emit("action", {
type: "LS_COVER_EXTRACTED", type: "CV_ISSUES_FOR_VOLUME_IN_LIBRARY_SUCCESS",
result: res, result: res,
}); });
console.info( console.info(