🏗️ Added string-similarity lib
This commit is contained in:
72
package-lock.json
generated
72
package-lock.json
generated
@@ -13,7 +13,8 @@
|
|||||||
"kafkajs": "^2.2.4",
|
"kafkajs": "^2.2.4",
|
||||||
"moleculer": "^0.14.27",
|
"moleculer": "^0.14.27",
|
||||||
"moleculer-web": "^0.10.5",
|
"moleculer-web": "^0.10.5",
|
||||||
"parse-torrent": "^9.1.5"
|
"parse-torrent": "^9.1.5",
|
||||||
|
"string-similarity-alg": "^1.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@jest/globals": "^29.3.1",
|
"@jest/globals": "^29.3.1",
|
||||||
@@ -2356,12 +2357,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/braces": {
|
"node_modules/braces": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fill-range": "^7.0.1"
|
"fill-range": "^7.1.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
@@ -3025,39 +3026,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/engine.io-client": {
|
"node_modules/engine.io-client": {
|
||||||
"version": "6.5.3",
|
"version": "6.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.4.tgz",
|
||||||
"integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==",
|
"integrity": "sha512-GeZeeRjpD2qf49cZQ0Wvh/8NJNfeXkXXcoGh+F77oEAgo9gUHwT1fCRxSNU+YEEaysOJTnsFHmM5oAcPy4ntvQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@socket.io/component-emitter": "~3.1.0",
|
"@socket.io/component-emitter": "~3.1.0",
|
||||||
"debug": "~4.3.1",
|
"debug": "~4.3.1",
|
||||||
"engine.io-parser": "~5.2.1",
|
"engine.io-parser": "~5.2.1",
|
||||||
"ws": "~8.11.0",
|
"ws": "~8.17.1",
|
||||||
"xmlhttprequest-ssl": "~2.0.0"
|
"xmlhttprequest-ssl": "~2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/engine.io-client/node_modules/ws": {
|
|
||||||
"version": "8.11.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
|
|
||||||
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"bufferutil": "^4.0.1",
|
|
||||||
"utf-8-validate": "^5.0.2"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"bufferutil": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"utf-8-validate": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/engine.io-parser": {
|
"node_modules/engine.io-parser": {
|
||||||
"version": "5.2.2",
|
"version": "5.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz",
|
||||||
@@ -3892,9 +3872,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fill-range": {
|
"node_modules/fill-range": {
|
||||||
"version": "7.0.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"to-regex-range": "^5.0.1"
|
"to-regex-range": "^5.0.1"
|
||||||
@@ -7300,6 +7280,11 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/string-similarity-alg": {
|
||||||
|
"version": "1.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/string-similarity-alg/-/string-similarity-alg-1.3.2.tgz",
|
||||||
|
"integrity": "sha512-M+jTGEJmWLfIg2dawXOifzbkUs/tp8HbeSCXZpNII2oZvU5uexaBFx+NoUBWS3M6VQ2ezJJCMstU8L8gq6YqsQ=="
|
||||||
|
},
|
||||||
"node_modules/string-width": {
|
"node_modules/string-width": {
|
||||||
"version": "4.2.3",
|
"version": "4.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
@@ -8055,6 +8040,27 @@
|
|||||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ws": {
|
||||||
|
"version": "8.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||||
|
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": ">=5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/xmlhttprequest-ssl": {
|
"node_modules/xmlhttprequest-ssl": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
|
||||||
|
|||||||
@@ -51,9 +51,10 @@
|
|||||||
"@robertklep/qbittorrent": "^1.0.1",
|
"@robertklep/qbittorrent": "^1.0.1",
|
||||||
"ioredis": "^5.0.0",
|
"ioredis": "^5.0.0",
|
||||||
"kafkajs": "^2.2.4",
|
"kafkajs": "^2.2.4",
|
||||||
"moleculer": "^0.14.27",
|
"moleculer": "^0.14.34",
|
||||||
"moleculer-web": "^0.10.5",
|
"moleculer-web": "^0.10.7",
|
||||||
"parse-torrent": "^9.1.5"
|
"parse-torrent": "^9.1.5",
|
||||||
|
"string-similarity-alg": "^1.3.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16.x.x"
|
"node": ">= 16.x.x"
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { Service, ServiceBroker, ServiceSchema } from "moleculer";
|
|||||||
import { Kafka, EachMessagePayload, logLevel } from "kafkajs";
|
import { Kafka, EachMessagePayload, logLevel } from "kafkajs";
|
||||||
import io from "socket.io-client";
|
import io from "socket.io-client";
|
||||||
import { isUndefined } from "lodash";
|
import { isUndefined } from "lodash";
|
||||||
|
import stringSimilarity from "string-similarity-alg";
|
||||||
|
|
||||||
interface SearchResult {
|
interface SearchResult {
|
||||||
result: {
|
result: {
|
||||||
@@ -44,7 +45,26 @@ export default class ComicProcessorService extends Service {
|
|||||||
day: date.getDate(),
|
day: date.getDate(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
rankSearchResults: (results, query: string) => {},
|
rankSearchResults: async (results: Map<number, any[]>, query: string) => {
|
||||||
|
// Find the highest-ranked response based on similarity to the search string
|
||||||
|
let highestRankedResult = null;
|
||||||
|
let highestSimilarity = -1;
|
||||||
|
|
||||||
|
results.forEach((resultArray) => {
|
||||||
|
resultArray.forEach((result) => {
|
||||||
|
const similarity = stringSimilarity("jaro-winkler").compare(
|
||||||
|
result.name,
|
||||||
|
query,
|
||||||
|
);
|
||||||
|
if (similarity > highestSimilarity) {
|
||||||
|
highestSimilarity = similarity;
|
||||||
|
highestRankedResult = { ...result, similarity };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return highestRankedResult;
|
||||||
|
},
|
||||||
processJob: async (job: any) => {
|
processJob: async (job: any) => {
|
||||||
try {
|
try {
|
||||||
this.logger.info("Processing job:", JSON.stringify(job, null, 2));
|
this.logger.info("Processing job:", JSON.stringify(job, null, 2));
|
||||||
@@ -137,12 +157,17 @@ export default class ComicProcessorService extends Service {
|
|||||||
this.logger.error("Error processing job:", error);
|
this.logger.error("Error processing job:", error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
produceResultsToKafka: async (query: string) => {
|
produceResultsToKafka: async (query: string, result: any[]) => {
|
||||||
try {
|
try {
|
||||||
/*
|
/*
|
||||||
Match and rank
|
Match and rank
|
||||||
*/
|
*/
|
||||||
|
const result = await this.rankSearchResults(
|
||||||
|
this.airDCPPSearchResults,
|
||||||
|
query,
|
||||||
|
);
|
||||||
|
console.log("majori");
|
||||||
|
console.log(result);
|
||||||
/*
|
/*
|
||||||
Kafka messages need to be in a format that can be serialized to JSON, and a Map is not directly serializable in a way that retains its structure, hence why we use Object.fromEntries
|
Kafka messages need to be in a format that can be serialized to JSON, and a Map is not directly serializable in a way that retains its structure, hence why we use Object.fromEntries
|
||||||
*/
|
*/
|
||||||
@@ -150,9 +175,7 @@ export default class ComicProcessorService extends Service {
|
|||||||
topic: "comic-search-results",
|
topic: "comic-search-results",
|
||||||
messages: [
|
messages: [
|
||||||
{
|
{
|
||||||
value: JSON.stringify(
|
value: JSON.stringify(result),
|
||||||
Object.fromEntries(this.airDCPPSearchResults),
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@@ -165,7 +188,7 @@ export default class ComicProcessorService extends Service {
|
|||||||
args: [
|
args: [
|
||||||
{
|
{
|
||||||
query,
|
query,
|
||||||
results: Object.fromEntries(this.airDCPPSearchResults),
|
result,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@@ -265,6 +288,7 @@ export default class ComicProcessorService extends Service {
|
|||||||
this.logger.info(
|
this.logger.info(
|
||||||
`Search complete for query: "${data.searchInfo.query.pattern}"`,
|
`Search complete for query: "${data.searchInfo.query.pattern}"`,
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.produceResultsToKafka(data.searchInfo.query.pattern);
|
await this.produceResultsToKafka(data.searchInfo.query.pattern);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user