diff --git a/package-lock.json b/package-lock.json index c7d1b31..b6f3be1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,8 +13,8 @@ "@types/mkdirp": "^1.0.0", "@types/node": "^13.9.8", "axios": "^0.21.1", - "axios-extensions": "^3.1.3", "date-fns": "^2.27.0", + "delay": "^5.0.0", "dotenv": "^10.0.0", "imghash": "^0.0.9", "ioredis": "^4.28.1", @@ -38,7 +38,7 @@ "jest": "^25.1.0", "jest-cli": "^25.1.0", "moleculer-repl": "^0.6.2", - "threetwo-ui-typings": "^1.0.11", + "threetwo-ui-typings": "^1.0.13", "ts-jest": "^25.3.0", "ts-node": "^8.8.1" }, @@ -1549,11 +1549,6 @@ "integrity": "sha512-/BHF5HAx3em7/KkzVKm3LrsD6HZAXuXO1AJZQ3cRRBZj4oHZDviWPYu0aEplAqDFNHZPW6d3G7KN+ONcCCC7pw==", "dev": true }, - "node_modules/@types/lru-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-QjCOmf5kYwekcsfEKhcEHMK8/SvgnneuSDXFERBuC/DPca2KJIO/gpChTsVb35BoWLBpEAJWz1GFVEArSdtKtw==" - }, "node_modules/@types/mkdirp": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-1.0.2.tgz", @@ -2041,33 +2036,6 @@ "follow-redirects": "^1.14.0" } }, - "node_modules/axios-extensions": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/axios-extensions/-/axios-extensions-3.1.3.tgz", - "integrity": "sha512-/OB9OcJLNOIx9pdW4m4/hFRvNo12wlX5BaprIzqpMaLR02I88Mr98/wW4QN9rhx0/yg9rM7i6Af/RpV4MyxXjA==", - "dependencies": { - "@types/lru-cache": "^4.1.1", - "lru-cache": "^5.1.1", - "tslib": "^1.9.0", - "util": "^0.11.1" - }, - "peerDependencies": { - "axios": "*" - } - }, - "node_modules/axios-extensions/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/axios-extensions/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, "node_modules/babel-jest": { "version": "25.5.1", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", @@ -3137,6 +3105,17 @@ "node": ">=0.10.0" } }, + "node_modules/delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -10864,9 +10843,9 @@ "dev": true }, "node_modules/threetwo-ui-typings": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/threetwo-ui-typings/-/threetwo-ui-typings-1.0.11.tgz", - "integrity": "sha512-jRI1rUttoJDqsKFUPd4MM56NErftl2NSEo8MkeqllOtVf38Wy+wVvAT+OW6AoSguA5cLxSpOiA25c31FWjOvOw==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/threetwo-ui-typings/-/threetwo-ui-typings-1.0.13.tgz", + "integrity": "sha512-AQiY8/hbp+TobBoehNTEoNco97AoiKYQjAANSFDR3pSD5jFn5qjLlKntvqdNF9Fg5tcS0ReYe0AjsvKshKpixQ==", "dev": true, "dependencies": { "typescript": "^4.3.2" @@ -11136,7 +11115,8 @@ "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, "node_modules/tsutils": { "version": "3.21.0", @@ -11365,25 +11345,12 @@ "node": ">=0.10.0" } }, - "node_modules/util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dependencies": { - "inherits": "2.0.3" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, - "node_modules/util/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, "node_modules/uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", @@ -13083,11 +13050,6 @@ "integrity": "sha512-/BHF5HAx3em7/KkzVKm3LrsD6HZAXuXO1AJZQ3cRRBZj4oHZDviWPYu0aEplAqDFNHZPW6d3G7KN+ONcCCC7pw==", "dev": true }, - "@types/lru-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-QjCOmf5kYwekcsfEKhcEHMK8/SvgnneuSDXFERBuC/DPca2KJIO/gpChTsVb35BoWLBpEAJWz1GFVEArSdtKtw==" - }, "@types/mkdirp": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-1.0.2.tgz", @@ -13435,32 +13397,6 @@ "follow-redirects": "^1.14.0" } }, - "axios-extensions": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/axios-extensions/-/axios-extensions-3.1.3.tgz", - "integrity": "sha512-/OB9OcJLNOIx9pdW4m4/hFRvNo12wlX5BaprIzqpMaLR02I88Mr98/wW4QN9rhx0/yg9rM7i6Af/RpV4MyxXjA==", - "requires": { - "@types/lru-cache": "^4.1.1", - "lru-cache": "^5.1.1", - "tslib": "^1.9.0", - "util": "^0.11.1" - }, - "dependencies": { - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "requires": { - "yallist": "^3.0.2" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } - } - }, "babel-jest": { "version": "25.5.1", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", @@ -14314,6 +14250,11 @@ "isobject": "^3.0.1" } }, + "delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==" + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -20221,9 +20162,9 @@ "dev": true }, "threetwo-ui-typings": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/threetwo-ui-typings/-/threetwo-ui-typings-1.0.11.tgz", - "integrity": "sha512-jRI1rUttoJDqsKFUPd4MM56NErftl2NSEo8MkeqllOtVf38Wy+wVvAT+OW6AoSguA5cLxSpOiA25c31FWjOvOw==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/threetwo-ui-typings/-/threetwo-ui-typings-1.0.13.tgz", + "integrity": "sha512-AQiY8/hbp+TobBoehNTEoNco97AoiKYQjAANSFDR3pSD5jFn5qjLlKntvqdNF9Fg5tcS0ReYe0AjsvKshKpixQ==", "dev": true, "requires": { "typescript": "^4.3.2" @@ -20438,7 +20379,8 @@ "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, "tsutils": { "version": "3.21.0", @@ -20617,21 +20559,6 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - } - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index a0dff49..d7784a5 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "jest": "^25.1.0", "jest-cli": "^25.1.0", "moleculer-repl": "^0.6.2", - "threetwo-ui-typings": "^1.0.11", + "threetwo-ui-typings": "^1.0.13", "ts-jest": "^25.3.0", "ts-node": "^8.8.1" }, @@ -40,8 +40,8 @@ "@types/mkdirp": "^1.0.0", "@types/node": "^13.9.8", "axios": "^0.21.1", - "axios-extensions": "^3.1.3", "date-fns": "^2.27.0", + "delay": "^5.0.0", "dotenv": "^10.0.0", "imghash": "^0.0.9", "ioredis": "^4.28.1", diff --git a/services/comicvine.service.ts b/services/comicvine.service.ts index ba2da3f..dd1af13 100644 --- a/services/comicvine.service.ts +++ b/services/comicvine.service.ts @@ -2,6 +2,7 @@ import { Service, ServiceBroker, Context } from "moleculer"; import axios from "axios"; +import delay from "delay"; import { isNil, isUndefined } from "lodash"; import { matchScorer, rankVolumes } from "../utils/searchmatchscorer.utils"; @@ -63,6 +64,43 @@ export default class ComicVineService extends Service { return data; }, }, + getIssuesForSeries: { + rest: "POST /getIssuesForSeries", + params: {}, + handler: async ( + ctx: Context<{ comicObjectID: string }> + ) => { + // 1. Query mongo to get the comic document by its _id + const comicBookDetails: any = await this.broker.call( + "library.getComicBookById", + { id: ctx.params.comicObjectID } + ); + + // 2. Query CV and get metadata for them + const issuesPromises = await comicBookDetails.sourcedMetadata.comicvine.volumeInformation.issues.map( + async (issue: any, idx: any) => { + await delay(1000); + const metadata: any = await axios.request({ + url: `${issue.api_detail_url}?api_key=${process.env.COMICVINE_API_KEY}`, + params: { + resources: "issues", + limit: "100", + format: "json", + }, + headers: { + "User-Agent": "ThreeTwo", + }, + }); + const issueMetadata = metadata.data.results; + + // 3. Just return the issues + return issueMetadata; + } + ); + + return Promise.all(issuesPromises); + }, + }, volumeBasedSearch: { rest: "POST /volumeBasedSearch", params: {}, @@ -84,13 +122,13 @@ export default class ComicVineService extends Service { resources: string; scorerConfiguration?: { searchParams: { - searchTerms: { name: string; subtitle?: string; number: string; year: string; }; - }; + + }; rawFileDetails: object; }> @@ -98,7 +136,6 @@ export default class ComicVineService extends Service { console.log( "Searching against: ", ctx.params.scorerConfiguration.searchParams - .searchTerms ); const results: any = []; const volumes = await this.fetchVolumesFromCV( @@ -128,20 +165,18 @@ export default class ComicVineService extends Service { let coverDateFilter = ""; if ( !isNil( - ctx.params.scorerConfiguration.searchParams - .searchTerms.year + ctx.params.scorerConfiguration.searchParams.year ) ) { const issueYear = parseInt( - ctx.params.scorerConfiguration.searchParams - .searchTerms.year, + ctx.params.scorerConfiguration.searchParams.year, 10 ); coverDateFilter = `cover_date:${ issueYear - 1 }-01-01|${issueYear + 1}-12-31`; } - const filterString = `issue_number:${ctx.params.scorerConfiguration.searchParams.searchTerms.number},${volumeIdString},${coverDateFilter}`; + const filterString = `issue_number:${ctx.params.scorerConfiguration.searchParams.number},${volumeIdString},${coverDateFilter}`; console.log(filterString); const issueMatches = await axios({ diff --git a/utils/searchmatchscorer.utils.ts b/utils/searchmatchscorer.utils.ts index 1076d97..ac64013 100644 --- a/utils/searchmatchscorer.utils.ts +++ b/utils/searchmatchscorer.utils.ts @@ -90,11 +90,11 @@ export const rankVolumes = (volumes: any, scorerConfiguration: any) => { // 1. If the detected year of the issue falls in the range (end_year >= {detected year for issue} >= start_year ) // 2. If there is a strong string comparison between the volume name and the issue name ?? const issueNumber = parseInt( - scorerConfiguration.searchParams.searchTerms.number, + scorerConfiguration.searchParams.number, 10 ); const issueYear = parseISO( - scorerConfiguration.searchParams.searchTerms.year + scorerConfiguration.searchParams.year ); const foo = volumes.map((volume: any, idx: number) => { let volumeMatchScore = 0; @@ -108,14 +108,14 @@ export const rankVolumes = (volumes: any, scorerConfiguration: any) => { ? parseInt(volume.last_issue.issue_number, 10) : null; let issueNameMatchScore = stringSimilarity.compareTwoStrings( - scorerConfiguration.searchParams.searchTerms.name, + scorerConfiguration.searchParams.name, volume.name ); // 1. If there is a subtitle in the candidate volume's name, add it to the issueNameMatchScore // If not, move on. let subtitleMatchScore = 0; - if(!isNil(scorerConfiguration.searchParams.searchTerms.subtitle)) { - subtitleMatchScore = stringSimilarity.compareTwoStrings(scorerConfiguration.searchParams.searchTerms.subtitle, volume.name); + if(!isNil(scorerConfiguration.searchParams.subtitle)) { + subtitleMatchScore = stringSimilarity.compareTwoStrings(scorerConfiguration.searchParams.subtitle, volume.name); if(subtitleMatchScore > 0.1) { issueNameMatchScore += subtitleMatchScore; }