mirror of
https://github.com/Drop-OSS/drop.git
synced 2025-11-10 12:32:09 +10:00
feat: rework developer/publisher system
This commit is contained in:
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- You are about to drop the `CompanyGameRelation` table. If the table is not empty, all the data it contains will be lost.
|
||||||
|
- You are about to drop the `Developer` table. If the table is not empty, all the data it contains will be lost.
|
||||||
|
- You are about to drop the `Publisher` table. If the table is not empty, all the data it contains will be lost.
|
||||||
|
- You are about to drop the `_DeveloperToGame` table. If the table is not empty, all the data it contains will be lost.
|
||||||
|
- You are about to drop the `_GameToPublisher` table. If the table is not empty, all the data it contains will be lost.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "CompanyGameRelation" DROP CONSTRAINT "CompanyGameRelation_companyId_fkey";
|
||||||
|
|
||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "CompanyGameRelation" DROP CONSTRAINT "CompanyGameRelation_gameId_fkey";
|
||||||
|
|
||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "_DeveloperToGame" DROP CONSTRAINT "_DeveloperToGame_A_fkey";
|
||||||
|
|
||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "_DeveloperToGame" DROP CONSTRAINT "_DeveloperToGame_B_fkey";
|
||||||
|
|
||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "_GameToPublisher" DROP CONSTRAINT "_GameToPublisher_A_fkey";
|
||||||
|
|
||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "_GameToPublisher" DROP CONSTRAINT "_GameToPublisher_B_fkey";
|
||||||
|
|
||||||
|
-- DropTable
|
||||||
|
DROP TABLE "CompanyGameRelation";
|
||||||
|
|
||||||
|
-- DropTable
|
||||||
|
DROP TABLE "Developer";
|
||||||
|
|
||||||
|
-- DropTable
|
||||||
|
DROP TABLE "Publisher";
|
||||||
|
|
||||||
|
-- DropTable
|
||||||
|
DROP TABLE "_DeveloperToGame";
|
||||||
|
|
||||||
|
-- DropTable
|
||||||
|
DROP TABLE "_GameToPublisher";
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "_developers" (
|
||||||
|
"A" TEXT NOT NULL,
|
||||||
|
"B" TEXT NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "_developers_AB_pkey" PRIMARY KEY ("A","B")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "_publishers" (
|
||||||
|
"A" TEXT NOT NULL,
|
||||||
|
"B" TEXT NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "_publishers_AB_pkey" PRIMARY KEY ("A","B")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "_developers_B_index" ON "_developers"("B");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "_publishers_B_index" ON "_publishers"("B");
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "_developers" ADD CONSTRAINT "_developers_A_fkey" FOREIGN KEY ("A") REFERENCES "Company"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "_developers" ADD CONSTRAINT "_developers_B_fkey" FOREIGN KEY ("B") REFERENCES "Game"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "_publishers" ADD CONSTRAINT "_publishers_A_fkey" FOREIGN KEY ("A") REFERENCES "Company"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "_publishers" ADD CONSTRAINT "_publishers_B_fkey" FOREIGN KEY ("B") REFERENCES "Game"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
@ -17,8 +17,6 @@ model Game {
|
|||||||
mName String // Name of game
|
mName String // Name of game
|
||||||
mShortDescription String // Short description
|
mShortDescription String // Short description
|
||||||
mDescription String // Supports markdown
|
mDescription String // Supports markdown
|
||||||
mDevelopers Developer[]
|
|
||||||
mPublishers Publisher[]
|
|
||||||
mReleased DateTime // When the game was released
|
mReleased DateTime // When the game was released
|
||||||
|
|
||||||
mReviewCount Int
|
mReviewCount Int
|
||||||
@ -33,10 +31,12 @@ model Game {
|
|||||||
versions GameVersion[]
|
versions GameVersion[]
|
||||||
libraryBasePath String @unique // Base dir for all the game versions
|
libraryBasePath String @unique // Base dir for all the game versions
|
||||||
|
|
||||||
collections CollectionEntry[]
|
collections CollectionEntry[]
|
||||||
saves SaveSlot[]
|
saves SaveSlot[]
|
||||||
screenshots Screenshot[]
|
screenshots Screenshot[]
|
||||||
companyRelations CompanyGameRelation[]
|
|
||||||
|
developers Company[] @relation(name: "developers")
|
||||||
|
publishers Company[] @relation(name: "publishers")
|
||||||
|
|
||||||
@@unique([metadataSource, metadataId], name: "metadataKey")
|
@@unique([metadataSource, metadataId], name: "metadataKey")
|
||||||
}
|
}
|
||||||
@ -117,62 +117,12 @@ model Company {
|
|||||||
mBannerObjectId String
|
mBannerObjectId String
|
||||||
mWebsite String
|
mWebsite String
|
||||||
|
|
||||||
gameRelations CompanyGameRelation[]
|
developed Game[] @relation(name: "developers")
|
||||||
|
published Game[] @relation(name: "publishers")
|
||||||
|
|
||||||
@@unique([metadataSource, metadataId], name: "metadataKey")
|
@@unique([metadataSource, metadataId], name: "metadataKey")
|
||||||
}
|
}
|
||||||
|
|
||||||
model CompanyGameRelation {
|
|
||||||
companyId String
|
|
||||||
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
|
|
||||||
gameId String
|
|
||||||
game Game @relation(fields: [gameId], references: [id], onDelete: Cascade)
|
|
||||||
|
|
||||||
// what the company did for the game
|
|
||||||
developer Boolean @default(false)
|
|
||||||
publisher Boolean @default(false)
|
|
||||||
|
|
||||||
@@unique([companyId, gameId], name: "companyGame")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Developer {
|
|
||||||
id String @id @default(uuid())
|
|
||||||
|
|
||||||
metadataSource MetadataSource
|
|
||||||
metadataId String
|
|
||||||
metadataOriginalQuery String
|
|
||||||
|
|
||||||
mName String
|
|
||||||
mShortDescription String
|
|
||||||
mDescription String
|
|
||||||
mLogo String
|
|
||||||
mBanner String
|
|
||||||
mWebsite String
|
|
||||||
|
|
||||||
games Game[]
|
|
||||||
|
|
||||||
@@unique([metadataSource, metadataId, metadataOriginalQuery], name: "metadataKey")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Publisher {
|
|
||||||
id String @id @default(uuid())
|
|
||||||
|
|
||||||
metadataSource MetadataSource
|
|
||||||
metadataId String
|
|
||||||
metadataOriginalQuery String
|
|
||||||
|
|
||||||
mName String
|
|
||||||
mShortDescription String
|
|
||||||
mDescription String
|
|
||||||
mLogo String
|
|
||||||
mBanner String
|
|
||||||
mWebsite String
|
|
||||||
|
|
||||||
games Game[]
|
|
||||||
|
|
||||||
@@unique([metadataSource, metadataId, metadataOriginalQuery], name: "metadataKey")
|
|
||||||
}
|
|
||||||
|
|
||||||
model ObjectHash {
|
model ObjectHash {
|
||||||
id String @id
|
id String @id
|
||||||
hash String
|
hash String
|
||||||
|
|||||||
@ -1,21 +0,0 @@
|
|||||||
import aclManager from "~/server/internal/acls";
|
|
||||||
import prisma from "~/server/internal/db/database";
|
|
||||||
|
|
||||||
export default defineEventHandler(async (h3) => {
|
|
||||||
const userId = await aclManager.getUserACL(h3, ["store:read"]);
|
|
||||||
if (!userId) throw createError({ statusCode: 403 });
|
|
||||||
|
|
||||||
const developers = await prisma.developer.findMany({
|
|
||||||
include: {
|
|
||||||
games: true,
|
|
||||||
},
|
|
||||||
orderBy: {
|
|
||||||
games: {
|
|
||||||
_count: "desc",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
take: 3,
|
|
||||||
});
|
|
||||||
|
|
||||||
return developers;
|
|
||||||
});
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
import aclManager from "~/server/internal/acls";
|
|
||||||
import prisma from "~/server/internal/db/database";
|
|
||||||
|
|
||||||
export default defineEventHandler(async (h3) => {
|
|
||||||
const userId = await aclManager.getUserACL(h3, ["store:read"]);
|
|
||||||
if (!userId) throw createError({ statusCode: 403 });
|
|
||||||
|
|
||||||
const publishers = await prisma.publisher.findMany({
|
|
||||||
include: {
|
|
||||||
games: true,
|
|
||||||
},
|
|
||||||
orderBy: {
|
|
||||||
games: {
|
|
||||||
_count: "desc",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
take: 4,
|
|
||||||
});
|
|
||||||
|
|
||||||
return publishers;
|
|
||||||
});
|
|
||||||
@ -12,13 +12,13 @@ export default defineEventHandler(async (h3) => {
|
|||||||
mShortDescription: true,
|
mShortDescription: true,
|
||||||
mCoverObjectId: true,
|
mCoverObjectId: true,
|
||||||
mBannerObjectId: true,
|
mBannerObjectId: true,
|
||||||
mDevelopers: {
|
developers: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
mName: true,
|
mName: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mPublishers: {
|
publishers: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
mName: true,
|
mName: true,
|
||||||
|
|||||||
@ -71,8 +71,6 @@ class LibraryManager {
|
|||||||
mName: true,
|
mName: true,
|
||||||
mShortDescription: true,
|
mShortDescription: true,
|
||||||
metadataSource: true,
|
metadataSource: true,
|
||||||
mDevelopers: true,
|
|
||||||
mPublishers: true,
|
|
||||||
mIconObjectId: true,
|
mIconObjectId: true,
|
||||||
libraryBasePath: true,
|
libraryBasePath: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import type { Developer, Publisher } from "~/prisma/client";
|
import type { Company } from "~/prisma/client";
|
||||||
import { MetadataSource } from "~/prisma/client";
|
import { MetadataSource } from "~/prisma/client";
|
||||||
import type { MetadataProvider } from ".";
|
import type { MetadataProvider } from ".";
|
||||||
import { MissingMetadataProviderConfig } from ".";
|
import { MissingMetadataProviderConfig } from ".";
|
||||||
@ -6,9 +6,8 @@ import type {
|
|||||||
GameMetadataSearchResult,
|
GameMetadataSearchResult,
|
||||||
_FetchGameMetadataParams,
|
_FetchGameMetadataParams,
|
||||||
GameMetadata,
|
GameMetadata,
|
||||||
_FetchPublisherMetadataParams,
|
_FetchCompanyMetadataParams,
|
||||||
CompanyMetadata,
|
CompanyMetadata,
|
||||||
_FetchDeveloperMetadataParams,
|
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import type { AxiosRequestConfig } from "axios";
|
import type { AxiosRequestConfig } from "axios";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
@ -168,7 +167,7 @@ export class GiantBombProvider implements MetadataProvider {
|
|||||||
? this.turndown.turndown(gameData.description)
|
? this.turndown.turndown(gameData.description)
|
||||||
: gameData.deck;
|
: gameData.deck;
|
||||||
|
|
||||||
const publishers: Publisher[] = [];
|
const publishers: Company[] = [];
|
||||||
if (gameData.publishers) {
|
if (gameData.publishers) {
|
||||||
for (const pub of gameData.publishers) {
|
for (const pub of gameData.publishers) {
|
||||||
const res = await publisher(pub.name);
|
const res = await publisher(pub.name);
|
||||||
@ -177,7 +176,7 @@ export class GiantBombProvider implements MetadataProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const developers: Developer[] = [];
|
const developers: Company[] = [];
|
||||||
if (gameData.developers) {
|
if (gameData.developers) {
|
||||||
for (const dev of gameData.developers) {
|
for (const dev of gameData.developers) {
|
||||||
const res = await developer(dev.name);
|
const res = await developer(dev.name);
|
||||||
@ -222,10 +221,10 @@ export class GiantBombProvider implements MetadataProvider {
|
|||||||
|
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
async fetchPublisher({
|
async fetchCompany({
|
||||||
query,
|
query,
|
||||||
createObject,
|
createObject,
|
||||||
}: _FetchPublisherMetadataParams): Promise<CompanyMetadata> {
|
}: _FetchCompanyMetadataParams): Promise<CompanyMetadata> {
|
||||||
const results = await this.request<Array<CompanySearchResult>>(
|
const results = await this.request<Array<CompanySearchResult>>(
|
||||||
"search",
|
"search",
|
||||||
"",
|
"",
|
||||||
@ -255,9 +254,4 @@ export class GiantBombProvider implements MetadataProvider {
|
|||||||
|
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
async fetchDeveloper(
|
|
||||||
params: _FetchDeveloperMetadataParams,
|
|
||||||
): Promise<CompanyMetadata> {
|
|
||||||
return await this.fetchPublisher(params);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import type { Developer, Publisher } from "~/prisma/client";
|
import type { Company } from "~/prisma/client";
|
||||||
import { MetadataSource } from "~/prisma/client";
|
import { MetadataSource } from "~/prisma/client";
|
||||||
import type { MetadataProvider } from ".";
|
import type { MetadataProvider } from ".";
|
||||||
import { MissingMetadataProviderConfig } from ".";
|
import { MissingMetadataProviderConfig } from ".";
|
||||||
@ -6,9 +6,8 @@ import type {
|
|||||||
GameMetadataSearchResult,
|
GameMetadataSearchResult,
|
||||||
_FetchGameMetadataParams,
|
_FetchGameMetadataParams,
|
||||||
GameMetadata,
|
GameMetadata,
|
||||||
_FetchPublisherMetadataParams,
|
_FetchCompanyMetadataParams,
|
||||||
CompanyMetadata,
|
CompanyMetadata,
|
||||||
_FetchDeveloperMetadataParams,
|
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import type { AxiosRequestConfig } from "axios";
|
import type { AxiosRequestConfig } from "axios";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
@ -312,8 +311,8 @@ export class IGDBProvider implements MetadataProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const publishers: Publisher[] = [];
|
const publishers: Company[] = [];
|
||||||
const developers: Developer[] = [];
|
const developers: Company[] = [];
|
||||||
for (const involvedCompany of response[i]?.involved_companies ?? []) {
|
for (const involvedCompany of response[i]?.involved_companies ?? []) {
|
||||||
// get details about the involved company
|
// get details about the involved company
|
||||||
const involved_company_response =
|
const involved_company_response =
|
||||||
@ -368,10 +367,10 @@ export class IGDBProvider implements MetadataProvider {
|
|||||||
|
|
||||||
throw new Error("No game found on igdb with that id");
|
throw new Error("No game found on igdb with that id");
|
||||||
}
|
}
|
||||||
async fetchPublisher({
|
async fetchCompany({
|
||||||
query,
|
query,
|
||||||
createObject,
|
createObject,
|
||||||
}: _FetchPublisherMetadataParams): Promise<CompanyMetadata> {
|
}: _FetchCompanyMetadataParams): Promise<CompanyMetadata> {
|
||||||
const response = await this.request<IGDBCompany>(
|
const response = await this.request<IGDBCompany>(
|
||||||
"companies",
|
"companies",
|
||||||
`where name = "${query}"; fields *; limit 1;`,
|
`where name = "${query}"; fields *; limit 1;`,
|
||||||
@ -407,9 +406,4 @@ export class IGDBProvider implements MetadataProvider {
|
|||||||
|
|
||||||
throw new Error(`igdb failed to find publisher/developer ${query}`);
|
throw new Error(`igdb failed to find publisher/developer ${query}`);
|
||||||
}
|
}
|
||||||
async fetchDeveloper(
|
|
||||||
params: _FetchDeveloperMetadataParams,
|
|
||||||
): Promise<CompanyMetadata> {
|
|
||||||
return await this.fetchPublisher(params);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
import type { Developer, Publisher } from "~/prisma/client";
|
|
||||||
import { MetadataSource } from "~/prisma/client";
|
import { MetadataSource } from "~/prisma/client";
|
||||||
import prisma from "../db/database";
|
import prisma from "../db/database";
|
||||||
import type {
|
import type {
|
||||||
_FetchDeveloperMetadataParams,
|
|
||||||
_FetchGameMetadataParams,
|
_FetchGameMetadataParams,
|
||||||
_FetchPublisherMetadataParams,
|
_FetchCompanyMetadataParams,
|
||||||
GameMetadata,
|
GameMetadata,
|
||||||
GameMetadataSearchResult,
|
GameMetadataSearchResult,
|
||||||
InternalGameMetadataResult,
|
InternalGameMetadataResult,
|
||||||
@ -35,11 +33,8 @@ export abstract class MetadataProvider {
|
|||||||
|
|
||||||
abstract search(query: string): Promise<GameMetadataSearchResult[]>;
|
abstract search(query: string): Promise<GameMetadataSearchResult[]>;
|
||||||
abstract fetchGame(params: _FetchGameMetadataParams): Promise<GameMetadata>;
|
abstract fetchGame(params: _FetchGameMetadataParams): Promise<GameMetadata>;
|
||||||
abstract fetchPublisher(
|
abstract fetchCompany(
|
||||||
params: _FetchPublisherMetadataParams,
|
params: _FetchCompanyMetadataParams,
|
||||||
): Promise<CompanyMetadata | undefined>;
|
|
||||||
abstract fetchDeveloper(
|
|
||||||
params: _FetchDeveloperMetadataParams,
|
|
||||||
): Promise<CompanyMetadata | undefined>;
|
): Promise<CompanyMetadata | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,14 +133,14 @@ export class MetadataHandler {
|
|||||||
["internal:read"],
|
["internal:read"],
|
||||||
);
|
);
|
||||||
|
|
||||||
let metadata;
|
let metadata: GameMetadata | undefined = undefined;
|
||||||
try {
|
try {
|
||||||
metadata = await provider.fetchGame({
|
metadata = await provider.fetchGame({
|
||||||
id: result.id,
|
id: result.id,
|
||||||
name: result.name,
|
name: result.name,
|
||||||
// wrap in anonymous functions to keep references to this
|
// wrap in anonymous functions to keep references to this
|
||||||
publisher: (name: string) => this.fetchPublisher(name),
|
publisher: (name: string) => this.fetchCompany(name),
|
||||||
developer: (name: string) => this.fetchDeveloper(name),
|
developer: (name: string) => this.fetchCompany(name),
|
||||||
createObject,
|
createObject,
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -171,77 +166,27 @@ export class MetadataHandler {
|
|||||||
mCoverObjectId: metadata.coverId,
|
mCoverObjectId: metadata.coverId,
|
||||||
mImageLibraryObjectIds: metadata.images,
|
mImageLibraryObjectIds: metadata.images,
|
||||||
|
|
||||||
|
publishers: {
|
||||||
|
connect: metadata.publishers,
|
||||||
|
},
|
||||||
|
developers: {
|
||||||
|
connect: metadata.developers,
|
||||||
|
},
|
||||||
|
|
||||||
libraryBasePath,
|
libraryBasePath,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
// relate companies to game
|
// relate companies to game
|
||||||
for (const pub of metadata.publishers) {
|
|
||||||
await prisma.companyGameRelation.upsert({
|
|
||||||
where: {
|
|
||||||
companyGame: {
|
|
||||||
gameId: game.id,
|
|
||||||
companyId: pub.id,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
create: {
|
|
||||||
gameId: game.id,
|
|
||||||
companyId: pub.id,
|
|
||||||
publisher: true,
|
|
||||||
},
|
|
||||||
update: {
|
|
||||||
publisher: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
for (const dev of metadata.developers) {
|
|
||||||
await prisma.companyGameRelation.upsert({
|
|
||||||
where: {
|
|
||||||
companyGame: {
|
|
||||||
gameId: game.id,
|
|
||||||
companyId: dev.id,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
create: {
|
|
||||||
gameId: game.id,
|
|
||||||
companyId: dev.id,
|
|
||||||
developer: true,
|
|
||||||
},
|
|
||||||
update: {
|
|
||||||
developer: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
await pullObjects();
|
await pullObjects();
|
||||||
|
|
||||||
return game;
|
return game;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchDeveloper(query: string) {
|
|
||||||
return (await this.fetchDeveloperPublisher(
|
|
||||||
query,
|
|
||||||
"fetchDeveloper",
|
|
||||||
"developer",
|
|
||||||
)) as Developer | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetchPublisher(query: string) {
|
|
||||||
return (await this.fetchDeveloperPublisher(
|
|
||||||
query,
|
|
||||||
"fetchPublisher",
|
|
||||||
"publisher",
|
|
||||||
)) as Publisher | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Careful with this function, it has no typechecking
|
// Careful with this function, it has no typechecking
|
||||||
// Type-checking this thing is impossible
|
// Type-checking this thing is impossible
|
||||||
private async fetchDeveloperPublisher(
|
private async fetchCompany(query: string) {
|
||||||
query: string,
|
const existing = await prisma.company.findFirst({
|
||||||
functionName: "fetchDeveloper" | "fetchPublisher",
|
|
||||||
type: "developer" | "publisher",
|
|
||||||
) {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
const existing = await (prisma as any)[type].findFirst({
|
|
||||||
where: {
|
where: {
|
||||||
metadataOriginalQuery: query,
|
metadataOriginalQuery: query,
|
||||||
},
|
},
|
||||||
@ -258,10 +203,10 @@ export class MetadataHandler {
|
|||||||
);
|
);
|
||||||
let result: CompanyMetadata | undefined;
|
let result: CompanyMetadata | undefined;
|
||||||
try {
|
try {
|
||||||
result = await provider[functionName]({ query, createObject });
|
result = await provider.fetchCompany({ query, createObject });
|
||||||
if (result === undefined) {
|
if (result === undefined) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`${provider.source()} failed to find a ${type} for "${query}`,
|
`${provider.source()} failed to find a company for "${query}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -273,15 +218,8 @@ export class MetadataHandler {
|
|||||||
// If we're successful
|
// If we're successful
|
||||||
await pullObjects();
|
await pullObjects();
|
||||||
|
|
||||||
// TODO: dedupe metadata in event that a company with same source and id appears
|
const object = await prisma.company.create({
|
||||||
const object = await prisma.company.upsert({
|
data: {
|
||||||
where: {
|
|
||||||
metadataKey: {
|
|
||||||
metadataId: result.id,
|
|
||||||
metadataSource: provider.source(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
create: {
|
|
||||||
metadataSource: provider.source(),
|
metadataSource: provider.source(),
|
||||||
metadataId: result.id,
|
metadataId: result.id,
|
||||||
metadataOriginalQuery: query,
|
metadataOriginalQuery: query,
|
||||||
@ -293,14 +231,6 @@ export class MetadataHandler {
|
|||||||
mBannerObjectId: result.banner,
|
mBannerObjectId: result.banner,
|
||||||
mWebsite: result.website,
|
mWebsite: result.website,
|
||||||
},
|
},
|
||||||
update: {
|
|
||||||
mName: result.name,
|
|
||||||
mShortDescription: result.shortDescription,
|
|
||||||
mDescription: result.description,
|
|
||||||
mLogoObjectId: result.logo,
|
|
||||||
mBannerObjectId: result.banner,
|
|
||||||
mWebsite: result.website,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
|
|||||||
@ -3,9 +3,8 @@ import type { MetadataProvider } from ".";
|
|||||||
import type {
|
import type {
|
||||||
_FetchGameMetadataParams,
|
_FetchGameMetadataParams,
|
||||||
GameMetadata,
|
GameMetadata,
|
||||||
_FetchPublisherMetadataParams,
|
_FetchCompanyMetadataParams,
|
||||||
CompanyMetadata,
|
CompanyMetadata,
|
||||||
_FetchDeveloperMetadataParams,
|
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import * as jdenticon from "jdenticon";
|
import * as jdenticon from "jdenticon";
|
||||||
|
|
||||||
@ -43,13 +42,8 @@ export class ManualMetadataProvider implements MetadataProvider {
|
|||||||
images: [iconId],
|
images: [iconId],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
async fetchPublisher(
|
async fetchCompany(
|
||||||
_params: _FetchPublisherMetadataParams,
|
_params: _FetchCompanyMetadataParams,
|
||||||
): Promise<CompanyMetadata> {
|
|
||||||
throw new Error("Method not implemented.");
|
|
||||||
}
|
|
||||||
async fetchDeveloper(
|
|
||||||
_params: _FetchDeveloperMetadataParams,
|
|
||||||
): Promise<CompanyMetadata> {
|
): Promise<CompanyMetadata> {
|
||||||
throw new Error("Method not implemented.");
|
throw new Error("Method not implemented.");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
import type { Developer, Publisher } from "~/prisma/client";
|
import type { Company } from "~/prisma/client";
|
||||||
import { MetadataSource } from "~/prisma/client";
|
import { MetadataSource } from "~/prisma/client";
|
||||||
import type { MetadataProvider } from ".";
|
import type { MetadataProvider } from ".";
|
||||||
import type {
|
import type {
|
||||||
GameMetadataSearchResult,
|
GameMetadataSearchResult,
|
||||||
_FetchGameMetadataParams,
|
_FetchGameMetadataParams,
|
||||||
GameMetadata,
|
GameMetadata,
|
||||||
_FetchPublisherMetadataParams,
|
_FetchCompanyMetadataParams,
|
||||||
CompanyMetadata,
|
CompanyMetadata,
|
||||||
_FetchDeveloperMetadataParams,
|
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import type { AxiosRequestConfig } from "axios";
|
import type { AxiosRequestConfig } from "axios";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
@ -179,7 +178,7 @@ export class PCGamingWikiProvider implements MetadataProvider {
|
|||||||
|
|
||||||
const game = res.data.cargoquery[0].title;
|
const game = res.data.cargoquery[0].title;
|
||||||
|
|
||||||
const publishers: Publisher[] = [];
|
const publishers: Company[] = [];
|
||||||
if (game.Publishers !== null) {
|
if (game.Publishers !== null) {
|
||||||
const pubListClean = this.parseCompanyStr(game.Publishers);
|
const pubListClean = this.parseCompanyStr(game.Publishers);
|
||||||
for (const pub of pubListClean) {
|
for (const pub of pubListClean) {
|
||||||
@ -189,7 +188,7 @@ export class PCGamingWikiProvider implements MetadataProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const developers: Developer[] = [];
|
const developers: Company[] = [];
|
||||||
if (game.Developers !== null) {
|
if (game.Developers !== null) {
|
||||||
const devListClean = this.parseCompanyStr(game.Developers);
|
const devListClean = this.parseCompanyStr(game.Developers);
|
||||||
for (const dev of devListClean) {
|
for (const dev of devListClean) {
|
||||||
@ -228,10 +227,10 @@ export class PCGamingWikiProvider implements MetadataProvider {
|
|||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchPublisher({
|
async fetchCompany({
|
||||||
query,
|
query,
|
||||||
createObject,
|
createObject,
|
||||||
}: _FetchPublisherMetadataParams): Promise<CompanyMetadata> {
|
}: _FetchCompanyMetadataParams): Promise<CompanyMetadata> {
|
||||||
const searchParams = new URLSearchParams({
|
const searchParams = new URLSearchParams({
|
||||||
action: "cargoquery",
|
action: "cargoquery",
|
||||||
tables: "Company",
|
tables: "Company",
|
||||||
@ -267,10 +266,4 @@ export class PCGamingWikiProvider implements MetadataProvider {
|
|||||||
|
|
||||||
throw new Error(`pcgamingwiki failed to find publisher/developer ${query}`);
|
throw new Error(`pcgamingwiki failed to find publisher/developer ${query}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchDeveloper(
|
|
||||||
params: _FetchDeveloperMetadataParams,
|
|
||||||
): Promise<CompanyMetadata> {
|
|
||||||
return await this.fetchPublisher(params);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
14
server/internal/metadata/types.d.ts
vendored
14
server/internal/metadata/types.d.ts
vendored
@ -1,4 +1,4 @@
|
|||||||
import type { Developer, Publisher } from "~/prisma/client";
|
import type { Company } from "~/prisma/client";
|
||||||
import type { TransactionDataType } from "../objects/transactional";
|
import type { TransactionDataType } from "../objects/transactional";
|
||||||
import type { ObjectReference } from "../objects/objectHandler";
|
import type { ObjectReference } from "../objects/objectHandler";
|
||||||
|
|
||||||
@ -27,8 +27,8 @@ export interface GameMetadata {
|
|||||||
|
|
||||||
// These are created using utility functions passed to the metadata loader
|
// These are created using utility functions passed to the metadata loader
|
||||||
// (that then call back into the metadata provider chain)
|
// (that then call back into the metadata provider chain)
|
||||||
publishers: Publisher[];
|
publishers: Company[];
|
||||||
developers: Developer[];
|
developers: Company[];
|
||||||
|
|
||||||
reviewCount: number;
|
reviewCount: number;
|
||||||
reviewRating: number;
|
reviewRating: number;
|
||||||
@ -55,15 +55,13 @@ export interface _FetchGameMetadataParams {
|
|||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
publisher: (query: string) => Promise<Publisher | undefined>;
|
publisher: (query: string) => Promise<Company | undefined>;
|
||||||
developer: (query: string) => Promise<Developer | undefined>;
|
developer: (query: string) => Promise<Company | undefined>;
|
||||||
|
|
||||||
createObject: (data: TransactionDataType) => ObjectReference;
|
createObject: (data: TransactionDataType) => ObjectReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface _FetchPublisherMetadataParams {
|
export interface _FetchCompanyMetadataParams {
|
||||||
query: string;
|
query: string;
|
||||||
createObject: (data: TransactionDataType) => ObjectReference;
|
createObject: (data: TransactionDataType) => ObjectReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type _FetchDeveloperMetadataParams = _FetchPublisherMetadataParams;
|
|
||||||
|
|||||||
Reference in New Issue
Block a user