From 4367b5cdb7b6b729acd5eee708f6e732a6ec4368 Mon Sep 17 00:00:00 2001 From: Alexandra Date: Sat, 24 May 2025 06:39:00 -0600 Subject: [PATCH] it works and stuff. todo improve search quality improve metadata matching quality --- lib/json/relatedkeywords/names.json | 5 ++- lib/metadatasearch.js | 63 ++++++++++++++++++++++++++--- lib/models/metadata.js | 2 +- lib/nonGameTerms.json | 7 +++- lib/services/elasticsearch.js | 6 ++- server.js | 9 +---- views/pages/results.ejs | 5 ++- views/partials/footer.ejs | 6 --- views/partials/head.ejs | 3 +- views/partials/result.ejs | 34 ++++++++++------ views/public/css/result.css | 42 +++++++++++++++++++ views/public/css/style.css | 28 ------------- views/public/js/utility.js | 6 +++ 13 files changed, 148 insertions(+), 68 deletions(-) create mode 100644 views/public/css/result.css create mode 100644 views/public/js/utility.js diff --git a/lib/json/relatedkeywords/names.json b/lib/json/relatedkeywords/names.json index 920ccf2..dfe4787 100644 --- a/lib/json/relatedkeywords/names.json +++ b/lib/json/relatedkeywords/names.json @@ -10,5 +10,8 @@ ["littleendian", "little endian"], ["pc88", "pc-88", "pc 88"], ["dvd", "digital video disc", "digital versatile disc"], - ["bros", "brothers", "bros."] + ["bros", "brothers", "bros."], + ["&", "and"], + ["+", "plus"], + [".hack", "dothack"] ] diff --git a/lib/metadatasearch.js b/lib/metadatasearch.js index c339f16..1b89565 100644 --- a/lib/metadatasearch.js +++ b/lib/metadatasearch.js @@ -18,6 +18,7 @@ import { } from "@phalcode/ts-igdb-client"; import { File, Metadata } from "./database.js"; import { Sequelize } from "sequelize"; +import debugPrint from "./debugprint.js"; export default class MetadataSearch { constructor() { @@ -88,11 +89,35 @@ export default class MetadataSearch { .alias(x) .pipe( fields(this.gameFields), - and( - ...this.buildAndClauses("name", "~", query[x].name), - where("game_type.type", "=", "Main Game"), - where("platforms.name", "~", query[x].platform) + or( + and( + ...this.buildAndClauses("name", "~", query[x].name), + where("game_type.type", "!=", "Mod"), + where("game_type.type", "!=", "DLC"), + ...this.buildPlatformClause("~", query[x].platform) + ), + and( + ...this.buildAndClauses( + "alternative_names.name", + "~", + query[x].name + ), + where("game_type.type", "!=", "Mod"), + where("game_type.type", "!=", "DLC"), + ...this.buildPlatformClause("~", query[x].platform) + ), + and( + ...this.buildAndClauses( + "game_localizations.name", + "~", + query[x].name + ), + where("game_type.type", "!=", "Mod"), + where("game_type.type", "!=", "DLC"), + ...this.buildPlatformClause("~", query[x].platform) + ) ), + sort("name", "asc"), limit(1) ) ); @@ -109,10 +134,24 @@ export default class MetadataSearch { return andClauses; } + buildPlatformClause(op, string) { + if (string == "Others") return []; + //special garbage because SOMEONE doesn't value consistency + string = string.replace("Nintendo Wii", "Wii"); + string = string.replace("Nintendo Game Boy", "Game Boy"); + string = string.replace("Sony PlayStation", "Playstation"); + string = string.replace("Microsoft Xbox", "Xbox"); + return [where("platforms.name", op, string, WhereFlags.CONTAINS)]; + } + normalizeName(filename) { if (!filename) return; return filename - .replace(/\.[A-z]{3,3}|\.|&|-|,|v[0-9]+\.[0-9]+|\[.*?\]|\(.*?\)/g, "") + .replace( + /\.[A-z]{3,3}|\.|&|-|\+|,|v[0-9]+\.[0-9]+|\[.*?\]|\(.*?\)|the|usa/gi, + "" + ) + .replace(/\s{2,}/g, " ") .trim(); } @@ -134,6 +173,7 @@ export default class MetadataSearch { } if (!gameQuery.length) return []; let gameMetas = await this.getMetadata(gameQuery); + debugPrint(JSON.stringify(gameMetas, null, 2)); if (!gameMetas.length) return []; for (let x in gameMetas) { if (gameMetas[x].result.length) { @@ -141,10 +181,21 @@ export default class MetadataSearch { gameMetas[x].result[0], games[gameQuery[x].id] ); + } else { + games[x].blockmetadata = true; + games[x].save(); } } let details = await Promise.all(games.map((game) => game.getDetails())); - return details.map((details) => details?.dataValues); + let combined = []; + //make sure the metadata gets included with the gamedata + for (let x in games) { + combined.push({ + file: games[x].dataValues, + metadata: details[x]?.dataValues, + }); + } + return combined; } catch (error) { console.error("Error getting metadata:", error); } diff --git a/lib/models/metadata.js b/lib/models/metadata.js index 19f9e9e..7cc42f4 100644 --- a/lib/models/metadata.js +++ b/lib/models/metadata.js @@ -23,7 +23,7 @@ export default function (sequelize) { type: DataTypes.STRING }, releasedate: { - type: DataTypes.DATE + type: DataTypes.DATEONLY }, genre: { type: DataTypes.STRING diff --git a/lib/nonGameTerms.json b/lib/nonGameTerms.json index 1259ee0..926b2a4 100644 --- a/lib/nonGameTerms.json +++ b/lib/nonGameTerms.json @@ -1,6 +1,7 @@ { "terms": [ "7z", + "action replay", "addon", "artwork", "audio", @@ -8,10 +9,13 @@ "box", "boxart", "cbr", + "chd", "cheat", "config", + "codebreaker", "cfg", "csv", + "datel", "debug", "dlc", "document", @@ -22,11 +26,9 @@ "figurine", "firmware", "guide", - "hack", "html", "ini", "installer", - "intro", "json", "jpg", "manual", @@ -49,6 +51,7 @@ "setup", "soundtrack", "sqlite", + "swf", "terms", "tool", "trainer", diff --git a/lib/services/elasticsearch.js b/lib/services/elasticsearch.js index 1f96701..a46f50e 100644 --- a/lib/services/elasticsearch.js +++ b/lib/services/elasticsearch.js @@ -179,13 +179,15 @@ export async function search(query, options) { // Build results with full PostgreSQL records let results = response.hits.hits.map((hit) => ({ - ...recordMap[hit._id]?.dataValues, + file:{ + ...recordMap[hit._id]?.dataValues, + }, score: hit._score, highlights: hit.highlight, })); //Filter out anything that couldn't be found in postgres - results = results.filter(result => result.filename) + results = results.filter(result => result.file.filename) const elapsed = timer.elapsedSeconds(); return { diff --git a/server.js b/server.js index 887bfed..c9b4401 100644 --- a/server.js +++ b/server.js @@ -206,16 +206,9 @@ app.get("/search", async function (req, res) { await QueryCount.update({ count: queryCount }, { where: { id: 1 } }); updateDefaults(); } - let resultOutput = []; - for (let x in results.items) { - resultOutput.push({ - file: results.items[x], - metadata: metas[x] || [], - }); - } let options = { query: query, - results: resultOutput, + results: metas?.length ? metas : results.items, count: results.count, elapsed: results.elapsed, pageNum: pageNum, diff --git a/views/pages/results.ejs b/views/pages/results.ejs index c14b3ea..83151ae 100644 --- a/views/pages/results.ejs +++ b/views/pages/results.ejs @@ -10,6 +10,7 @@ +
@@ -81,7 +82,9 @@
  • class="page-link previous" aria-controls="results" aria-disabled="true" aria-label="Previous" data-dt-idx="previous" tabindex="-1">‹
  • 1
  • <%- pageNum >= 5 ? ellipsesElem : '' %> - <% for(let x = pageRange.lower; x <= pageRange.upper; x++){ %> + <% for(let x = pageRange.lower; x <= pageRange.upper; x++){ + if(x == pageCount) break; + %>
  • <%= x %>
  • <% } %> <%- pageNum <= pageCount - 5 ? ellipsesElem : '' %> diff --git a/views/partials/footer.ejs b/views/partials/footer.ejs index c606278..4d7a7ce 100644 --- a/views/partials/footer.ejs +++ b/views/partials/footer.ejs @@ -9,12 +9,6 @@
    - \ No newline at end of file + + \ No newline at end of file diff --git a/views/partials/result.ejs b/views/partials/result.ejs index 552cebc..77a5677 100644 --- a/views/partials/result.ejs +++ b/views/partials/result.ejs @@ -4,16 +4,26 @@ const coverUrl = metadata.coverartid ? `/proxy-image?url=https://images.igdb.com/igdb/image/upload/t_cover_big/${metadata.coverartid}.webp` : "/public/images/coverart/nocoverart.png" %>
    -
    - -
    -
    -

    <%= metadata.title || file.filename %>

    -

    Released: <%= metadata.releasedate || file.date %> Region: <%= file.region %> Platform: <%= file.category %>

    -

    <%= metadata.description || "No description was found." %>

    - <% if(metadata.title) {%> -

    Filename: <%= file.filename %>

    - <% } %> -

    -

    +
    + +
    +
    +

    <%= metadata.title || file.filename %>

    +

    Released: <%= metadata.releasedate || file.date %> + Region: <%= file.region %> + Platform: <%= file.category %> + <% if(metadata.genre){ %> + Genres: <%= JSON.parse(metadata.genre).join(' / ') %> + <% } %> +

    +

    <%= metadata.description || "No description was found."//todo: localize %>

    + <% if(metadata.title) {%> +

    Filename: <%= file.filename %>

    + <% } %> +

    Release Group: <%= file.group %>

    +

    + More Info + Download + Play In Browser +

    \ No newline at end of file diff --git a/views/public/css/result.css b/views/public/css/result.css new file mode 100644 index 0000000..2788683 --- /dev/null +++ b/views/public/css/result.css @@ -0,0 +1,42 @@ +.coverart{ + object-fit: contain; + height: 200px; + width: 150px; +} +.description{ + white-space: normal; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} +.searchresult { + padding: 10px; +} +.searchresult div > p { + margin-bottom: 0.5rem; +} +.title { + font-weight: bold; + color: #f0a400; + margin-bottom: 0!important; +} +.title a { + font-weight: bold; + color: #f0a400; +} +.info { + font-size: 0.8em; +} +.file { + font-size: 0.8em; +} +.group { + font-size: 0.8em; +} +.infoitem{ + margin-right: 0; +} +.cover{ + margin-left: 1rem; +} \ No newline at end of file diff --git a/views/public/css/style.css b/views/public/css/style.css index 0795531..81167f4 100644 --- a/views/public/css/style.css +++ b/views/public/css/style.css @@ -184,31 +184,3 @@ thead > tr > th.dt-orderable span.dt-column-order.order-desc::before{ thead > tr > th.dt-orderable span.dt-column-order.order-asc::after{ opacity: 1; } -.coverart{ - object-fit: contain; - height: 200px; - width: 150px; -} -.description{ - white-space: normal; - display: -webkit-box; - -webkit-line-clamp: 4; - -webkit-box-orient: vertical; - overflow: hidden; -} -.searchresult { - padding: 10px; -} -.title { - font-weight: bold; - color: #f0a400; -} -.info { - font-size: 0.8em; -} -.file { - font-size: 0.8em; -} -.infoitem{ - margin-right: 1rem; -} \ No newline at end of file diff --git a/views/public/js/utility.js b/views/public/js/utility.js new file mode 100644 index 0000000..41f608a --- /dev/null +++ b/views/public/js/utility.js @@ -0,0 +1,6 @@ +function timeConverter(UNIX_timestamp){ + var timestamp = parseInt(UNIX_timestamp) + var date = new Date(timestamp); + var options = { hour12: false }; + return date.toLocaleString(options) + } \ No newline at end of file