From 5375d74481726b94c457e1828d48814c40a591d7 Mon Sep 17 00:00:00 2001 From: David Brownman Date: Thu, 29 Aug 2024 20:52:13 -0700 Subject: [PATCH] load search key lazily mostly a copy of https://github.com/ckatzorke/howlongtobeat/pull/64, plus a typescript upgrade --- dist/main/hltbsearch.d.ts | 36 ++++- dist/main/hltbsearch.js | 140 ++++++++++++------ dist/main/hltbsearch.js.map | 2 +- dist/main/howlongtobeat.js | 4 +- dist/main/howlongtobeat.js.map | 2 +- dist/test/howlongtobeat.integration.test.js | 65 ++++---- .../howlongtobeat.integration.test.js.map | 2 +- package-lock.json | 52 ++++--- package.json | 4 +- src/main/hltbsearch.ts | 74 ++++++++- src/test/howlongtobeat.integration.test.ts | 100 +++++++------ 11 files changed, 329 insertions(+), 152 deletions(-) diff --git a/dist/main/hltbsearch.d.ts b/dist/main/hltbsearch.d.ts index b0536f6..33b2210 100644 --- a/dist/main/hltbsearch.d.ts +++ b/dist/main/hltbsearch.d.ts @@ -2,11 +2,43 @@ * Takes care about the http connection and response handling */ export declare class HltbSearch { + protected searchKey: string; static BASE_URL: string; static DETAIL_URL: string; static SEARCH_URL: string; static IMAGE_URL: string; - payload: any; + private static readonly SEARCH_KEY_PATTERN; + payload: { + searchType: string; + searchTerms: any[]; + searchPage: number; + size: number; + searchOptions: { + games: { + userId: number; + platform: string; + sortCategory: string; + rangeCategory: string; + rangeTime: { + min: number; + max: number; + }; + gameplay: { + perspective: string; + flow: string; + genre: string; + }; + modifier: string; + }; + users: { + sortCategory: string; + }; + filter: string; + sort: number; + randomizer: number; + }; + }; detailHtml(gameId: string, signal?: AbortSignal): Promise; - search(query: Array, signal?: AbortSignal): Promise; + search(query: Array, signal?: AbortSignal, retry?: boolean): Promise; + private getSearchKey; } diff --git a/dist/main/hltbsearch.js b/dist/main/hltbsearch.js index 03f547b..c1596b1 100644 --- a/dist/main/hltbsearch.js +++ b/dist/main/hltbsearch.js @@ -1,63 +1,70 @@ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); -const axios = require('axios'); -const UserAgent = require('user-agents'); +exports.HltbSearch = void 0; +const axios = require("axios"); +const UserAgent = require("user-agents"); +const cheerio = require("cheerio"); /** * Takes care about the http connection and response handling */ class HltbSearch { constructor() { this.payload = { - "searchType": "games", - "searchTerms": [], - "searchPage": 1, - "size": 20, - "searchOptions": { - "games": { - "userId": 0, - "platform": "", - "sortCategory": "popular", - "rangeCategory": "main", - "rangeTime": { - "min": 0, - "max": 0 + searchType: "games", + searchTerms: [], + searchPage: 1, + size: 20, + searchOptions: { + games: { + userId: 0, + platform: "", + sortCategory: "popular", + rangeCategory: "main", + rangeTime: { + min: 0, + max: 0, }, - "gameplay": { - "perspective": "", - "flow": "", - "genre": "" + gameplay: { + perspective: "", + flow: "", + genre: "", }, - "modifier": "" + modifier: "", }, - "users": { - "sortCategory": "postcount" + users: { + sortCategory: "postcount", }, - "filter": "", - "sort": 0, - "randomizer": 0 - } + filter: "", + sort: 0, + randomizer: 0, + }, }; } detailHtml(gameId, signal) { return __awaiter(this, void 0, void 0, function* () { try { - let result = yield axios.get(`${HltbSearch.DETAIL_URL}${gameId}`, { + let result = yield axios + .get(`${HltbSearch.DETAIL_URL}${gameId}`, { headers: { - 'User-Agent': new UserAgent().toString(), - 'origin': 'https://howlongtobeat.com', - 'referer': 'https://howlongtobeat.com' + "User-Agent": new UserAgent().toString(), + origin: "https://howlongtobeat.com", + referer: "https://howlongtobeat.com", }, timeout: 20000, signal, - }).catch(e => { throw e; }); + }) + .catch((e) => { + throw e; + }); return result.data; } catch (error) { @@ -72,18 +79,21 @@ class HltbSearch { } }); } - search(query, signal) { - return __awaiter(this, void 0, void 0, function* () { + search(query_1, signal_1) { + return __awaiter(this, arguments, void 0, function* (query, signal, retry = true) { // Use built-in javascript URLSearchParams as a drop-in replacement to create axios.post required data param let search = Object.assign({}, this.payload); search.searchTerms = query; try { - let result = yield axios.post(HltbSearch.SEARCH_URL, search, { + // only search scripts lazily + this.searchKey || (this.searchKey = yield this.getSearchKey()); + const searchUrlWithKey = HltbSearch.SEARCH_URL + this.searchKey; + let result = yield axios.post(searchUrlWithKey, search, { headers: { - 'content-type': 'application/json', - 'origin': 'https://howlongtobeat.com/', - 'referer': 'https://howlongtobeat.com/', - 'user-agent': new UserAgent() + "User-Agent": new UserAgent().toString(), + "content-type": "application/json", + origin: "https://howlongtobeat.com/", + referer: "https://howlongtobeat.com/", }, timeout: 20000, signal, @@ -95,6 +105,12 @@ class HltbSearch { if (error) { throw new Error(error); } + else if (error.response.status === 404 && retry) { + // key maybe stale + this.searchKey = null; + // don't retry on the second one, could be a real 404 + return this.search(query, signal, false); + } else if (error.response.status !== 200) { throw new Error(`Got non-200 status code from howlongtobeat.com [${error.response.status}] ${JSON.stringify(error.response)} @@ -103,12 +119,48 @@ class HltbSearch { } }); } + getSearchKey() { + return __awaiter(this, void 0, void 0, function* () { + const res = yield axios.get(HltbSearch.BASE_URL, { + headers: { + "User-Agent": new UserAgent().toString(), + origin: "https://howlongtobeat.com", + referer: "https://howlongtobeat.com", + }, + }); + const html = res.data; + const $ = cheerio.load(html); + const scripts = $("script[src]"); + for (const el of scripts) { + const src = $(el).attr("src"); + if (!src.includes("_app-")) { + continue; + } + const scriptUrl = HltbSearch.BASE_URL + src; + try { + const res = yield axios.get(scriptUrl, { + headers: { + "User-Agent": new UserAgent().toString(), + origin: "https://howlongtobeat.com", + referer: "https://howlongtobeat.com", + }, + }); + const scriptText = res.data; + const matches = [...scriptText.matchAll(HltbSearch.SEARCH_KEY_PATTERN)]; + return matches[0][1]; + } + catch (error) { + continue; + } + } + throw new Error("Could not find search key"); + }); + } } -HltbSearch.BASE_URL = 'https://howlongtobeat.com/'; +exports.HltbSearch = HltbSearch; +HltbSearch.BASE_URL = "https://howlongtobeat.com/"; HltbSearch.DETAIL_URL = `${HltbSearch.BASE_URL}game?id=`; -// this smells like they don't want people hitting this endpoint -// pulled from the network tab on 2024-08-01; it may change again -HltbSearch.SEARCH_URL = `${HltbSearch.BASE_URL}api/search/5683ebd079f1c360`; +HltbSearch.SEARCH_URL = `${HltbSearch.BASE_URL}api/search/`; HltbSearch.IMAGE_URL = `${HltbSearch.BASE_URL}games/`; -exports.HltbSearch = HltbSearch; +HltbSearch.SEARCH_KEY_PATTERN = /"\/api\/search\/".concat\("([a-zA-Z0-9]+)"\)/g; //# sourceMappingURL=hltbsearch.js.map \ No newline at end of file diff --git a/dist/main/hltbsearch.js.map b/dist/main/hltbsearch.js.map index 9071d66..59dc22d 100644 --- a/dist/main/hltbsearch.js.map +++ b/dist/main/hltbsearch.js.map @@ -1 +1 @@ -{"version":3,"file":"hltbsearch.js","sourceRoot":"","sources":["../../src/main/hltbsearch.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"hltbsearch.js","sourceRoot":"","sources":["../../src/main/hltbsearch.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/main/howlongtobeat.js b/dist/main/howlongtobeat.js index 412d040..2d019b7 100644 --- a/dist/main/howlongtobeat.js +++ b/dist/main/howlongtobeat.js @@ -1,13 +1,15 @@ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); +exports.HowLongToBeatParser = exports.HowLongToBeatEntry = exports.HowLongToBeatService = void 0; const cheerio = require('cheerio'); const levenshtein = require('fast-levenshtein'); const hltbsearch_1 = require("./hltbsearch"); diff --git a/dist/main/howlongtobeat.js.map b/dist/main/howlongtobeat.js.map index f815ff3..eba56b6 100644 --- a/dist/main/howlongtobeat.js.map +++ b/dist/main/howlongtobeat.js.map @@ -1 +1 @@ -{"version":3,"file":"howlongtobeat.js","sourceRoot":"","sources":["../../src/main/howlongtobeat.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"howlongtobeat.js","sourceRoot":"","sources":["../../src/main/howlongtobeat.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/test/howlongtobeat.integration.test.js b/dist/test/howlongtobeat.integration.test.js index 8f3e7f7..c5f9a09 100644 --- a/dist/test/howlongtobeat.integration.test.js +++ b/dist/test/howlongtobeat.integration.test.js @@ -3,77 +3,84 @@ Object.defineProperty(exports, "__esModule", { value: true }); const chai = require("chai"); const howlongtobeat_1 = require("../main/howlongtobeat"); const assert = chai.assert; -describe('Integration-Testing HowLongToBeatService', () => { - describe('Test for detail()', () => { - it('should load entry for 2224 (Dark Souls)', () => { - return new howlongtobeat_1.HowLongToBeatService().detail('2224').then((entry) => { +describe("Integration-Testing HowLongToBeatService", () => { + const HLTB = new howlongtobeat_1.HowLongToBeatService(); + describe("Test for detail()", () => { + it("should load entry for 2224 (Dark Souls)", () => { + return HLTB.detail("2224").then((entry) => { // console.log(entry); assert.isNotNull(entry); - assert.strictEqual(entry.id, '2224'); - assert.strictEqual(entry.name, 'Dark Souls'); - assert.strictEqual(entry.searchTerm, 'Dark Souls'); + assert.strictEqual(entry.id, "2224"); + assert.strictEqual(entry.name, "Dark Souls"); + assert.strictEqual(entry.searchTerm, "Dark Souls"); assert.isString(entry.imageUrl); assert.isArray(entry.platforms); assert.strictEqual(entry.platforms.length, 3); // backward compatible test assert.strictEqual(entry.playableOn.length, 3); - assert.isTrue(entry.description.includes('Live Through A Million Deaths & Earn Your Legacy.')); + assert.isTrue(entry.description.includes("Live Through A Million Deaths & Earn Your Legacy.")); assert.isTrue(entry.gameplayMain > 40); assert.isTrue(entry.gameplayCompletionist > 100); }); }); - it('should abort loading entry for 2224 (Dark Souls)', () => { + it("should abort loading entry for 2224 (Dark Souls)", () => { const abortController = new AbortController(); abortController.abort(); - return new howlongtobeat_1.HowLongToBeatService().detail('2224', abortController.signal).then(() => { + return HLTB.detail("2224", abortController.signal) + .then(() => { assert.fail(); - }).catch(e => { - assert.include(e.message.toLowerCase(), 'cancel'); + }) + .catch((e) => { + assert.include(e.message.toLowerCase(), "cancel"); }); }); - it('should fail to load entry for 123 (404)', () => { - return new howlongtobeat_1.HowLongToBeatService().detail('123').then(() => { + it("should fail to load entry for 123 (404)", () => { + return HLTB.detail("123") + .then(() => { assert.fail(); - }).catch(e => { + }) + .catch((e) => { assert.isOk(e.message); }); }); }); - describe('Test for search()', () => { - it('should have no search results when searching for dorks', () => { - return new howlongtobeat_1.HowLongToBeatService().search('dorks').then((result) => { + describe("Test for search()", () => { + it("should have no search results when searching for dorks", () => { + return HLTB.search("dorks").then((result) => { assert.isNotNull(result); assert.strictEqual(result.length, 0); }); }); - it('should have at least 3 search results when searching for dark souls III', () => { - return new howlongtobeat_1.HowLongToBeatService().search('dark souls III').then((result) => { + it("should have at least 3 search results when searching for dark souls III", () => { + return HLTB.search("dark souls III").then((result) => { assert.isNotNull(result); assert.isTrue(result.length >= 3); - assert.strictEqual(result[0].id, '26803'); - assert.strictEqual(result[0].name, 'Dark Souls III'); + assert.strictEqual(result[0].id, "26803"); + assert.strictEqual(result[0].name, "Dark Souls III"); assert.isTrue(result[0].gameplayMain > 30); assert.isTrue(result[0].gameplayCompletionist > 80); }); }); - it('should abort searching for dark souls III', () => { + it("should abort searching for dark souls III", () => { const abortController = new AbortController(); abortController.abort(); - return new howlongtobeat_1.HowLongToBeatService().search('dark souls III', abortController.signal).then(() => { + return HLTB.search("dark souls III", abortController.signal) + .then(() => { assert.fail(); - }).catch(e => { - assert.include(e.message.toLowerCase(), 'cancel'); + }) + .catch((e) => { + assert.include(e.message.toLowerCase(), "cancel"); }); }); - it('should have 1 search results with 100% similarity when searching for Persona 4: Golden', () => { - return new howlongtobeat_1.HowLongToBeatService().search('Persona 4 Golden').then((result) => { + it("should have 1 search results with 100% similarity when searching for Persona 4: Golden", () => { + return HLTB.search("Persona 4 Golden").then((result) => { assert.isNotNull(result); assert.strictEqual(result.length, 1); //assert.strictEqual(result[0].similarity, 1); }); }); it('Entries without any time settings (e.g. "Surge") should have a zero hour result', () => { - return new howlongtobeat_1.HowLongToBeatService().search('Surge').then((result) => { + return HLTB.search("Surge").then((result) => { // console.log(result); assert.isNotNull(result); assert.isTrue(result.length > 1); diff --git a/dist/test/howlongtobeat.integration.test.js.map b/dist/test/howlongtobeat.integration.test.js.map index b5de261..cca76d4 100644 --- a/dist/test/howlongtobeat.integration.test.js.map +++ b/dist/test/howlongtobeat.integration.test.js.map @@ -1 +1 @@ -{"version":3,"file":"howlongtobeat.integration.test.js","sourceRoot":"","sources":["../../src/test/howlongtobeat.integration.test.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"howlongtobeat.integration.test.js","sourceRoot":"","sources":["../../src/test/howlongtobeat.integration.test.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index be34fb3..619e623 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,14 +18,14 @@ "@types/chai": "^3.5.2", "@types/chai-as-promised": "^0.0.30", "@types/mocha": "^2.2.41", - "@types/node": "^7.0.14", + "@types/node": "^22.5.1", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", "codecov": "^3.7.1", "hoek": "^5.0.4", "mocha": "^10.0.0", "nyc": "^15.0.0", - "typescript": "^2.9.2" + "typescript": "^5.5.4" } }, "node_modules/@babel/code-frame": { @@ -245,10 +245,13 @@ "dev": true }, "node_modules/@types/node": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.39.tgz", - "integrity": "sha512-KQHAZeVsk4UIT9XaR6cn4WpHZzimK6UBD1UomQKfQQFmTlUHaNBzeuov+TM4+kigLO0IJt4I5OOsshcCyA9gSA==", - "dev": true + "version": "22.5.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.1.tgz", + "integrity": "sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==", + "dev": true, + "dependencies": { + "undici-types": "~6.19.2" + } }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", @@ -2533,16 +2536,16 @@ } }, "node_modules/typescript": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", - "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/underscore": { @@ -2558,6 +2561,12 @@ "underscore": "*" } }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true + }, "node_modules/urlgrey": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-0.4.4.tgz", @@ -2979,10 +2988,13 @@ "dev": true }, "@types/node": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.39.tgz", - "integrity": "sha512-KQHAZeVsk4UIT9XaR6cn4WpHZzimK6UBD1UomQKfQQFmTlUHaNBzeuov+TM4+kigLO0IJt4I5OOsshcCyA9gSA==", - "dev": true + "version": "22.5.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.1.tgz", + "integrity": "sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==", + "dev": true, + "requires": { + "undici-types": "~6.19.2" + } }, "@ungap/promise-all-settled": { "version": "1.1.2", @@ -4689,9 +4701,9 @@ } }, "typescript": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", - "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true }, "underscore": { @@ -4707,6 +4719,12 @@ "underscore": "*" } }, + "undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true + }, "urlgrey": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-0.4.4.tgz", diff --git a/package.json b/package.json index 0989125..c21bfa1 100644 --- a/package.json +++ b/package.json @@ -29,13 +29,13 @@ "@types/chai": "^3.5.2", "@types/chai-as-promised": "^0.0.30", "@types/mocha": "^2.2.41", - "@types/node": "^7.0.14", + "@types/node": "^22.5.1", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", "codecov": "^3.7.1", "hoek": "^5.0.4", "mocha": "^10.0.0", "nyc": "^15.0.0", - "typescript": "^2.9.2" + "typescript": "^5.5.4" } } diff --git a/src/main/hltbsearch.ts b/src/main/hltbsearch.ts index 36d1ec1..6ccf5fd 100644 --- a/src/main/hltbsearch.ts +++ b/src/main/hltbsearch.ts @@ -1,18 +1,22 @@ const axios: any = require("axios"); const UserAgent: any = require("user-agents"); +const cheerio: any = require("cheerio"); /** * Takes care about the http connection and response handling */ export class HltbSearch { + protected searchKey: string; + public static BASE_URL: string = "https://howlongtobeat.com/"; public static DETAIL_URL: string = `${HltbSearch.BASE_URL}game?id=`; - // this smells like they don't want people hitting this endpoint - // pulled from the network tab on 2024-08-01; it may change again - public static SEARCH_URL: string = `${HltbSearch.BASE_URL}api/search/5683ebd079f1c360`; + public static SEARCH_URL: string = `${HltbSearch.BASE_URL}api/search/`; public static IMAGE_URL: string = `${HltbSearch.BASE_URL}games/`; - payload: any = { + private static readonly SEARCH_KEY_PATTERN = + /"\/api\/search\/".concat\("([a-zA-Z0-9]+)"\)/g; + + payload = { searchType: "games", searchTerms: [], searchPage: 1, @@ -72,17 +76,25 @@ export class HltbSearch { } } - async search(query: Array, signal?: AbortSignal): Promise { + async search( + query: Array, + signal?: AbortSignal, + retry = true + ): Promise { // Use built-in javascript URLSearchParams as a drop-in replacement to create axios.post required data param let search = { ...this.payload }; search.searchTerms = query; try { - let result = await axios.post(HltbSearch.SEARCH_URL, search, { + // only search scripts lazily + this.searchKey ||= await this.getSearchKey(); + const searchUrlWithKey = HltbSearch.SEARCH_URL + this.searchKey; + + let result = await axios.post(searchUrlWithKey, search, { headers: { + "User-Agent": new UserAgent().toString(), "content-type": "application/json", origin: "https://howlongtobeat.com/", referer: "https://howlongtobeat.com/", - "user-agent": new UserAgent(), }, timeout: 20000, signal, @@ -92,6 +104,11 @@ export class HltbSearch { } catch (error) { if (error) { throw new Error(error); + } else if (error.response.status === 404 && retry) { + // key maybe stale + this.searchKey = null; + // don't retry on the second one, could be a real 404 + return this.search(query, signal, false); } else if (error.response.status !== 200) { throw new Error(`Got non-200 status code from howlongtobeat.com [${ error.response.status @@ -101,4 +118,47 @@ export class HltbSearch { } } } + + private async getSearchKey(): Promise { + const res = await axios.get(HltbSearch.BASE_URL, { + headers: { + "User-Agent": new UserAgent().toString(), + origin: "https://howlongtobeat.com", + referer: "https://howlongtobeat.com", + }, + }); + + const html = res.data; + const $ = cheerio.load(html); + + const scripts = $("script[src]"); + + for (const el of scripts) { + const src = $(el).attr("src") as string; + + if (!src.includes("_app-")) { + continue; + } + + const scriptUrl = HltbSearch.BASE_URL + src; + + try { + const res = await axios.get(scriptUrl, { + headers: { + "User-Agent": new UserAgent().toString(), + origin: "https://howlongtobeat.com", + referer: "https://howlongtobeat.com", + }, + }); + + const scriptText = res.data; + const matches = [...scriptText.matchAll(HltbSearch.SEARCH_KEY_PATTERN)]; + return matches[0][1]; + } catch (error) { + continue; + } + } + + throw new Error("Could not find search key"); + } } diff --git a/src/test/howlongtobeat.integration.test.ts b/src/test/howlongtobeat.integration.test.ts index 05fd873..5f20d9f 100644 --- a/src/test/howlongtobeat.integration.test.ts +++ b/src/test/howlongtobeat.integration.test.ts @@ -1,82 +1,90 @@ -import * as chai from 'chai'; +import * as chai from "chai"; -import { HowLongToBeatService } from '../main/howlongtobeat'; +import { HowLongToBeatService } from "../main/howlongtobeat"; const assert = chai.assert; -describe('Integration-Testing HowLongToBeatService', () => { - - describe('Test for detail()', () => { - - it('should load entry for 2224 (Dark Souls)', () => { - return new HowLongToBeatService().detail('2224').then((entry) => { +describe("Integration-Testing HowLongToBeatService", () => { + const HLTB = new HowLongToBeatService(); + describe("Test for detail()", () => { + it("should load entry for 2224 (Dark Souls)", () => { + return HLTB.detail("2224").then((entry) => { // console.log(entry); assert.isNotNull(entry); - assert.strictEqual(entry.id, '2224'); - assert.strictEqual(entry.name, 'Dark Souls'); - assert.strictEqual(entry.searchTerm, 'Dark Souls'); + assert.strictEqual(entry.id, "2224"); + assert.strictEqual(entry.name, "Dark Souls"); + assert.strictEqual(entry.searchTerm, "Dark Souls"); assert.isString(entry.imageUrl); assert.isArray(entry.platforms); assert.strictEqual(entry.platforms.length, 3); // backward compatible test assert.strictEqual(entry.playableOn.length, 3); - assert.isTrue(entry.description.includes('Live Through A Million Deaths & Earn Your Legacy.')) + assert.isTrue( + entry.description.includes( + "Live Through A Million Deaths & Earn Your Legacy." + ) + ); assert.isTrue(entry.gameplayMain > 40); assert.isTrue(entry.gameplayCompletionist > 100); }); }); - it('should abort loading entry for 2224 (Dark Souls)', () => { - const abortController = new AbortController() - abortController.abort() - return new HowLongToBeatService().detail('2224', abortController.signal).then(() => { - assert.fail() - }).catch(e => { - assert.include(e.message.toLowerCase(), 'cancel') - }) + it("should abort loading entry for 2224 (Dark Souls)", () => { + const abortController = new AbortController(); + abortController.abort(); + return HLTB.detail("2224", abortController.signal) + .then(() => { + assert.fail(); + }) + .catch((e) => { + assert.include(e.message.toLowerCase(), "cancel"); + }); }); - it('should fail to load entry for 123 (404)', () => { - return new HowLongToBeatService().detail('123').then(() => { - assert.fail() - }).catch(e => { - assert.isOk(e.message) - }); + it("should fail to load entry for 123 (404)", () => { + return HLTB.detail("123") + .then(() => { + assert.fail(); + }) + .catch((e) => { + assert.isOk(e.message); + }); }); }); - - describe('Test for search()', () => { - it('should have no search results when searching for dorks', () => { - return new HowLongToBeatService().search('dorks').then((result) => { + describe("Test for search()", () => { + it("should have no search results when searching for dorks", () => { + return HLTB.search("dorks").then((result) => { assert.isNotNull(result); assert.strictEqual(result.length, 0); }); }); - it('should have at least 3 search results when searching for dark souls III', () => { - return new HowLongToBeatService().search('dark souls III').then((result) => { + it("should have at least 3 search results when searching for dark souls III", () => { + return HLTB.search("dark souls III").then((result) => { assert.isNotNull(result); assert.isTrue(result.length >= 3); - assert.strictEqual(result[0].id, '26803'); - assert.strictEqual(result[0].name, 'Dark Souls III'); + assert.strictEqual(result[0].id, "26803"); + assert.strictEqual(result[0].name, "Dark Souls III"); assert.isTrue(result[0].gameplayMain > 30); assert.isTrue(result[0].gameplayCompletionist > 80); }); }); - it('should abort searching for dark souls III', () => { - const abortController = new AbortController() - abortController.abort() - return new HowLongToBeatService().search('dark souls III', abortController.signal).then(() => { - assert.fail() - }).catch(e => { - assert.include(e.message.toLowerCase(), 'cancel') - }) + it("should abort searching for dark souls III", () => { + const abortController = new AbortController(); + abortController.abort(); + return HLTB.search("dark souls III", abortController.signal) + .then(() => { + assert.fail(); + }) + .catch((e) => { + assert.include(e.message.toLowerCase(), "cancel"); + }); }); - it('should have 1 search results with 100% similarity when searching for Persona 4: Golden', () => { - return new HowLongToBeatService().search('Persona 4 Golden').then((result) => { + it("should have 1 search results with 100% similarity when searching for Persona 4: Golden", () => { + return HLTB.search("Persona 4 Golden").then((result) => { assert.isNotNull(result); assert.strictEqual(result.length, 1); //assert.strictEqual(result[0].similarity, 1); @@ -84,7 +92,7 @@ describe('Integration-Testing HowLongToBeatService', () => { }); it('Entries without any time settings (e.g. "Surge") should have a zero hour result', () => { - return new HowLongToBeatService().search('Surge').then((result) => { + return HLTB.search("Surge").then((result) => { // console.log(result); assert.isNotNull(result); assert.isTrue(result.length > 1); @@ -92,6 +100,4 @@ describe('Integration-Testing HowLongToBeatService', () => { }); }); }); - - });