Skip to content

Commit ee19791

Browse files
committed
Added support for giant bomb api and modified the readme
Added a note about mobygames per #164
1 parent 265bf10 commit ee19791

File tree

4 files changed

+131
-2
lines changed

4 files changed

+131
-2
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ Now you select the result you want and the plugin will cast it's magic and creat
119119
| [Wikipedia](https://en.wikipedia.org/wiki/Main_Page) | The Wikipedia API allows access to all Wikipedia articles. | wiki articles | No | None | No |
120120
| [Steam](https://store.steampowered.com/) | The Steam API offers information on all steam games. | games | No | 10000 per day | No |
121121
| [Open Library](https://openlibrary.org) | The OpenLibrary API offers metadata for books | books | No | Cover access is rate-limited when not using CoverID or OLID by max 100 requests/IP every 5 minutes. This plugin uses OLID so there shouldn't be a rate limit. | No |
122-
| [Moby Games](https://www.mobygames.com) | The Moby Games API offers metadata for games for all platforms | games | Yes, by making an account [here](https://www.mobygames.com/user/register/) | API requests are limited to 360 per hour (one every ten seconds). In addition, requests should be made no more frequently than one per second. | No |
122+
| [Moby Games](https://www.mobygames.com) | The Moby Games API offers metadata for games for all platforms | games | Yes, by making an account [here](https://www.mobygames.com/user/register/). NOTE: As of September 2024 the API key is no longer free so consider using Giant Bomb or steam instead | API requests are limited to 360 per hour (one every ten seconds). In addition, requests should be made no more frequently than one per second. | No |
123+
| [Giant Bomb](https://www.giantbomb.com) | The Giant Bomb API offers metadata for games for all platforms | games | Yes, by making an account [here](https://www.giantbomb.com/login-signup/) | API requests are limited to 200 requests per resource, per hour. In addition, they implement velocity detection to prevent malicious use. If too many requests are made per second, you may receive temporary blocks to resources. | No |
123124
124125
#### Notes
125126
@@ -156,6 +157,9 @@ Now you select the result you want and the plugin will cast it's magic and creat
156157
- [Moby Games](https://www.mobygames.com)
157158
- you can find this ID in the URL
158159
- e.g. for "Bioshock 2" the URL looks like this `https://www.mobygames.com/game/45089/bioshock-2/` so the ID is `45089`
160+
- [Giant Bomb](https://www.giantbomb.com)
161+
- you can find this ID in the URL
162+
- e.g. for "Dota 2" the URL looks like this `https://www.giantbomb.com/dota-2/3030-32887/` so the ID is `3030-32887`
159163
160164
### Problems, unexpected behavior or improvement suggestions?
161165

src/api/apis/GiantBombAPI.ts

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import { APIModel } from '../APIModel';
2+
import { MediaTypeModel } from '../../models/MediaTypeModel';
3+
import MediaDbPlugin from '../../main';
4+
import { GameModel } from '../../models/GameModel';
5+
import { requestUrl } from 'obsidian';
6+
import { MediaType } from '../../utils/MediaType';
7+
8+
export class GiantBombAPI extends APIModel {
9+
plugin: MediaDbPlugin;
10+
apiDateFormat: string = 'YYYY-MM-DD';
11+
12+
constructor(plugin: MediaDbPlugin) {
13+
super();
14+
15+
this.plugin = plugin;
16+
this.apiName = 'GiantBombAPI';
17+
this.apiDescription = 'A free API for games.';
18+
this.apiUrl = 'https://www.giantbomb.com/api';
19+
this.types = [MediaType.Game];
20+
}
21+
async searchByTitle(title: string): Promise<MediaTypeModel[]> {
22+
console.log(`MDB | api "${this.apiName}" queried by Title`);
23+
24+
if (!this.plugin.settings.GiantBombKey) {
25+
throw Error(`MDB | API key for ${this.apiName} missing.`);
26+
}
27+
28+
const searchUrl = `${this.apiUrl}/games?api_key=${this.plugin.settings.GiantBombKey}&filter=name:${encodeURIComponent(title)}&format=json`;
29+
const fetchData = await requestUrl({
30+
url: searchUrl,
31+
});
32+
33+
// console.debug(fetchData);
34+
35+
if (fetchData.status === 401) {
36+
throw Error(`MDB | Authentication for ${this.apiName} failed. Check the API key.`);
37+
}
38+
if (fetchData.status === 429) {
39+
throw Error(`MDB | Too many requests for ${this.apiName}, you've exceeded your API quota.`);
40+
}
41+
if (fetchData.status !== 200) {
42+
throw Error(`MDB | Received status code ${fetchData.status} from ${this.apiName}.`);
43+
}
44+
45+
const data = await fetchData.json;
46+
// console.debug(data);
47+
const ret: MediaTypeModel[] = [];
48+
for (const result of data.results) {
49+
ret.push(
50+
new GameModel({
51+
type: MediaType.Game,
52+
title: result.name,
53+
englishTitle: result.name,
54+
year: new Date(result.original_release_date).getFullYear().toString(),
55+
dataSource: this.apiName,
56+
id: result.guid,
57+
} as GameModel),
58+
);
59+
}
60+
61+
return ret;
62+
}
63+
64+
async getById(id: string): Promise<MediaTypeModel> {
65+
console.log(`MDB | api "${this.apiName}" queried by ID`);
66+
67+
if (!this.plugin.settings.GiantBombKey) {
68+
throw Error(`MDB | API key for ${this.apiName} missing.`);
69+
}
70+
71+
const searchUrl = `${this.apiUrl}/game/${encodeURIComponent(id)}/?api_key=${this.plugin.settings.GiantBombKey}&format=json`;
72+
const fetchData = await requestUrl({
73+
url: searchUrl,
74+
});
75+
console.debug(fetchData);
76+
77+
if (fetchData.status !== 200) {
78+
throw Error(`MDB | Received status code ${fetchData.status} from ${this.apiName}.`);
79+
}
80+
81+
const data = await fetchData.json;
82+
// console.debug(data);
83+
const result = data.results;
84+
85+
return new GameModel({
86+
type: MediaType.Game,
87+
title: result.name,
88+
englishTitle: result.name,
89+
year: new Date(result.original_release_date).getFullYear().toString(),
90+
dataSource: this.apiName,
91+
url: result.site_detail_url,
92+
id: result.guid,
93+
developers: result.developers?.map((x: any) => x.name) ?? [],
94+
publishers: result.publishers?.map((x: any) => x.name) ?? [],
95+
genres: result.genres?.map((x: any) => x.name) ?? [],
96+
onlineRating: 0,
97+
image: result.image?.super_url ?? '',
98+
99+
released: true,
100+
releaseDate: result.original_release_date ?? 'unknown',
101+
102+
userData: {
103+
played: false,
104+
105+
personalRating: 0,
106+
},
107+
} as GameModel);
108+
}
109+
}

src/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { SteamAPI } from './api/apis/SteamAPI';
2121
import { BoardGameGeekAPI } from './api/apis/BoardGameGeekAPI';
2222
import { OpenLibraryAPI } from './api/apis/OpenLibraryAPI';
2323
import { MobyGamesAPI } from './api/apis/MobyGamesAPI';
24+
import { GiantBombAPI } from './api/apis/GiantBombAPI';
2425
import { PropertyMapper } from './settings/PropertyMapper';
2526
import { MediaDbFolderImportModal } from './modals/MediaDbFolderImportModal';
2627
import { PropertyMapping, PropertyMappingModel } from './settings/PropertyMapping';
@@ -58,6 +59,7 @@ export default class MediaDbPlugin extends Plugin {
5859
this.apiManager.registerAPI(new BoardGameGeekAPI(this));
5960
this.apiManager.registerAPI(new OpenLibraryAPI(this));
6061
this.apiManager.registerAPI(new MobyGamesAPI(this));
62+
this.apiManager.registerAPI(new GiantBombAPI(this));
6163
// this.apiManager.registerAPI(new LocGovAPI(this)); // TODO: parse data
6264

6365
this.mediaTypeManager = new MediaTypeManager();

src/settings/Settings.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { fragWithHTML } from '../utils/Utils';
1212
export interface MediaDbPluginSettings {
1313
OMDbKey: string;
1414
MobyGamesKey: string;
15+
GiantBombKey: string;
1516
sfwFilter: boolean;
1617
templates: boolean;
1718
customDateFormat: string;
@@ -78,6 +79,7 @@ export interface MediaDbPluginSettings {
7879
const DEFAULT_SETTINGS: MediaDbPluginSettings = {
7980
OMDbKey: '',
8081
MobyGamesKey: '',
82+
GiantBombKey: '',
8183
sfwFilter: true,
8284
templates: true,
8385
customDateFormat: 'L',
@@ -191,7 +193,7 @@ export class MediaDbSettingTab extends PluginSettingTab {
191193
});
192194
});
193195

194-
new Setting(containerEl)
196+
new Setting(containerEl)
195197
.setName('Moby Games key')
196198
.setDesc('API key for "www.mobygames.com".')
197199
.addText(cb => {
@@ -203,6 +205,18 @@ export class MediaDbSettingTab extends PluginSettingTab {
203205
});
204206
});
205207

208+
new Setting(containerEl)
209+
.setName('Giant Bomb Key')
210+
.setDesc('API key for "www.giantbomb.com".')
211+
.addText(cb => {
212+
cb.setPlaceholder('API key')
213+
.setValue(this.plugin.settings.GiantBombKey)
214+
.onChange(data => {
215+
this.plugin.settings.GiantBombKey = data;
216+
void this.plugin.saveSettings();
217+
});
218+
});
219+
206220
new Setting(containerEl)
207221
.setName('SFW filter')
208222
.setDesc('Only shows SFW results for APIs that offer filtering.')

0 commit comments

Comments
 (0)