it works and stuff.

todo improve search quality
improve metadata matching quality
This commit is contained in:
Alexandra
2025-05-24 06:39:00 -06:00
parent bb743933bd
commit 4367b5cdb7
13 changed files with 148 additions and 68 deletions

View File

@@ -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"]
]

View File

@@ -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);
}

View File

@@ -23,7 +23,7 @@ export default function (sequelize) {
type: DataTypes.STRING
},
releasedate: {
type: DataTypes.DATE
type: DataTypes.DATEONLY
},
genre: {
type: DataTypes.STRING

View File

@@ -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",

View File

@@ -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 {