From e75bb5b476446a227ec11f9246c86d8175080763 Mon Sep 17 00:00:00 2001 From: ltctceplrm <14954927+ltctceplrm@users.noreply.github.com> Date: Sat, 27 Jan 2024 00:46:11 +0100 Subject: [PATCH] Added support for Moby Games API --- src/api/apis/MobyGamesAPI.ts | 103 +++++++++++++++++++++++++++++++++++ src/main.ts | 2 + src/settings/Settings.ts | 14 +++++ 3 files changed, 119 insertions(+) create mode 100644 src/api/apis/MobyGamesAPI.ts diff --git a/src/api/apis/MobyGamesAPI.ts b/src/api/apis/MobyGamesAPI.ts new file mode 100644 index 0000000..8e43638 --- /dev/null +++ b/src/api/apis/MobyGamesAPI.ts @@ -0,0 +1,103 @@ +import { APIModel } from '../APIModel'; +import { MediaTypeModel } from '../../models/MediaTypeModel'; +import MediaDbPlugin from '../../main'; +import { GameModel } from '../../models/GameModel'; +import { requestUrl } from 'obsidian'; +import { MediaType } from '../../utils/MediaType'; + +export class MobyGamesAPI extends APIModel { + plugin: MediaDbPlugin; + + constructor(plugin: MediaDbPlugin) { + super(); + + this.plugin = plugin; + this.apiName = 'MobyGamesAPI'; + this.apiDescription = 'A free API for games.'; + this.apiUrl = 'https://api.mobygames.com/v1'; + this.types = [MediaType.Game]; + } + async searchByTitle(title: string): Promise { + console.log(`MDB | api "${this.apiName}" queried by Title`); + + const searchUrl = `${this.apiUrl}/games?title=${encodeURIComponent(title)}&api_key=${this.plugin.settings.MobyGamesKey}`; + const fetchData = await requestUrl({ + url: searchUrl, + }); + + console.debug(fetchData); + + if (fetchData.status === 401) { + throw Error(`MDB | Authentication for ${this.apiName} failed. Check the API key.`); + } + if (fetchData.status === 429) { + throw Error(`MDB | Too many requests for ${this.apiName}, you've exceeded your API quota.`); + } + if (fetchData.status !== 200) { + throw Error(`MDB | Received status code ${fetchData.status} from an API.`); + } + + const data = await fetchData.json; + console.debug(data); + const ret: MediaTypeModel[] = []; + for (const result of data.games) { + ret.push( + new GameModel({ + type: MediaType.Game, + title: result.title, + englishTitle: result.title, + year: result.platforms[0].first_release_date ?? '', + dataSource: this.apiName, + id: result.game_id, + + } as GameModel), + ); + } + + return ret; + } + + async getById(id: string): Promise { + console.log(`MDB | api "${this.apiName}" queried by ID`); + + const searchUrl = `${this.apiUrl}/games?id=${encodeURIComponent(id)}&api_key=${this.plugin.settings.MobyGamesKey}`; + const fetchData = await requestUrl({ + url: searchUrl, + }); + console.debug(fetchData); + + if (fetchData.status !== 200) { + throw Error(`MDB | Received status code ${fetchData.status} from an API.`); + } + + const data = await fetchData.json; + console.debug(data); + const result = data.games[0]; + + const model = new GameModel({ + type: MediaType.Game, + title: result.title, + englishTitle: result.title, + year: result.platforms[0].first_release_date, + dataSource: this.apiName, + url: `https://www.mobygames.com/game/${result.game_id}`, + id: result.game_id, + developers: result['developers'], + publishers: result['publishers'], + genres: result.genres?.map((x: any) => x.genre_name) ?? [], + onlineRating: result.moby_score, + image: result.sample_cover.image ?? '', + + released: true, + releaseDate: result.platforms[0].first_release_date ?? 'unknown', + + userData: { + played: false, + + personalRating: 0, + }, + } as GameModel); + + return model; + } +} diff --git a/src/main.ts b/src/main.ts index fc7ee25..653e107 100644 --- a/src/main.ts +++ b/src/main.ts @@ -20,6 +20,7 @@ import { MEDIA_TYPES, MediaTypeManager } from './utils/MediaTypeManager'; import { SteamAPI } from './api/apis/SteamAPI'; import { BoardGameGeekAPI } from './api/apis/BoardGameGeekAPI'; import { OpenLibraryAPI } from './api/apis/OpenLibraryAPI'; +import { MobyGamesAPI } from './api/apis/MobyGamesAPI'; import { PropertyMapper } from './settings/PropertyMapper'; import { YAMLConverter } from './utils/YAMLConverter'; import { MediaDbFolderImportModal } from './modals/MediaDbFolderImportModal'; @@ -48,6 +49,7 @@ export default class MediaDbPlugin extends Plugin { this.apiManager.registerAPI(new SteamAPI(this)); this.apiManager.registerAPI(new BoardGameGeekAPI(this)); this.apiManager.registerAPI(new OpenLibraryAPI(this)); + this.apiManager.registerAPI(new MobyGamesAPI(this)); // this.apiManager.registerAPI(new LocGovAPI(this)); // TODO: parse data this.mediaTypeManager = new MediaTypeManager(); diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index c65078d..9b089f2 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -11,6 +11,7 @@ import { fragWithHTML } from '../utils/Utils'; export interface MediaDbPluginSettings { OMDbKey: string; + MobyGamesKey: string; sfwFilter: boolean; useCustomYamlStringifier: boolean; templates: boolean; @@ -60,6 +61,7 @@ export interface MediaDbPluginSettings { const DEFAULT_SETTINGS: MediaDbPluginSettings = { OMDbKey: '', + MobyGamesKey: '', sfwFilter: true, useCustomYamlStringifier: true, templates: true, @@ -160,6 +162,18 @@ export class MediaDbSettingTab extends PluginSettingTab { }); }); + new Setting(containerEl) + .setName('Moby Games key') + .setDesc('API key for "www.mobygames.com".') + .addText(cb => { + cb.setPlaceholder('API key') + .setValue(this.plugin.settings.MobyGamesKey) + .onChange(data => { + this.plugin.settings.MobyGamesKey = data; + this.plugin.saveSettings(); + }); + }); + new Setting(containerEl) .setName('SFW filter') .setDesc('Only shows SFW results for APIs that offer filtering.')