Skip to content

Commit 7ae5167

Browse files
Merge pull request #47 from mProjectsCode/master
changes for release 0.3.2
2 parents 2c3fe62 + 5e693ab commit 7ae5167

18 files changed

+230
-5
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,15 @@ Now you select the result you want and the plugin will cast it's magic and creat
130130
You are more than welcome to open an issue on [GitHub](https://github.com/mProjectsCode/obsidian-media-db-plugin/issues).
131131

132132
### Changelog
133+
134+
#### 0.3.2
135+
- Added Board Game Geek API (documentation pending)
136+
- More information in the search results
137+
- various fixes
138+
139+
#### 0.3.1
140+
- various fixes
141+
133142
#### 0.3.0
134143
- Added bulk import. Import a folder of media notes as Media DB entries (thanks to [PaperOrb](https://github.com/PaperOrb) on GitHub for their input and for helping me test this feature)
135144
- Added a custom result select modal that allows you to select multiple results at once

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"id": "obsidian-media-db-plugin",
33
"name": "Media DB Plugin",
4-
"version": "0.3.1",
4+
"version": "0.3.2",
55
"minAppVersion": "0.14.0",
66
"description": "A plugin that can query multiple APIs for movies, series, anime, games, music and wiki articles, and import them into your vault.",
77
"author": "Moritz Jung",

src/api/apis/BoardGameGeekAPI.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import {APIModel} from '../APIModel';
2+
import {MediaTypeModel} from '../../models/MediaTypeModel';
3+
import MediaDbPlugin from '../../main';
4+
import {BoardGameModel} from 'src/models/BoardGameModel';
5+
import {debugLog} from '../../utils/Utils';
6+
import {requestUrl} from 'obsidian';
7+
import {MediaType} from '../../utils/MediaType';
8+
9+
export class BoardGameGeekAPI extends APIModel {
10+
plugin: MediaDbPlugin;
11+
12+
constructor(plugin: MediaDbPlugin) {
13+
super();
14+
15+
this.plugin = plugin;
16+
this.apiName = 'BoardGameGeekAPI';
17+
this.apiDescription = 'A free API for BoardGameGeek things.';
18+
this.apiUrl = 'https://api.geekdo.com/xmlapi';
19+
this.types = ['boardgames'];
20+
}
21+
22+
async searchByTitle(title: string): Promise<MediaTypeModel[]> {
23+
console.log(`MDB | api "${this.apiName}" queried by Title`);
24+
25+
const searchUrl = `${this.apiUrl}/search?search=${encodeURIComponent(title)}`;
26+
const fetchData = await requestUrl({
27+
url: searchUrl,
28+
});
29+
30+
if (fetchData.status !== 200) {
31+
throw Error(`MDB | Received status code ${fetchData.status} from an API.`);
32+
}
33+
34+
const data = fetchData.text;
35+
const response = new window.DOMParser().parseFromString(data, "text/xml")
36+
37+
debugLog(response);
38+
39+
let ret: MediaTypeModel[] = [];
40+
41+
for (const boardgame of Array.from(response.querySelectorAll("boardgame"))) {
42+
const id = boardgame.attributes.getNamedItem("objectid")!.value;
43+
const title = boardgame.querySelector("name")!.textContent!;
44+
const year = boardgame.querySelector("yearpublished")?.textContent ?? "";
45+
46+
ret.push(new BoardGameModel({
47+
dataSource: this.apiName,
48+
id,
49+
title,
50+
englishTitle: title,
51+
year,
52+
} as BoardGameModel));
53+
}
54+
55+
return ret;
56+
}
57+
58+
async getById(id: string): Promise<MediaTypeModel> {
59+
console.log(`MDB | api "${this.apiName}" queried by ID`);
60+
61+
const searchUrl = `${this.apiUrl}/boardgame/${encodeURIComponent(id)}?stats=1`;
62+
const fetchData = await requestUrl({
63+
url: searchUrl,
64+
});
65+
66+
if (fetchData.status !== 200) {
67+
throw Error(`MDB | Received status code ${fetchData.status} from an API.`);
68+
}
69+
70+
const data = fetchData.text;
71+
const response = new window.DOMParser().parseFromString(data, "text/xml")
72+
debugLog(response);
73+
74+
const boardgame = response.querySelector("boardgame")!;
75+
const title = boardgame.querySelector("name")!.textContent!;
76+
const year = boardgame.querySelector("yearpublished")?.textContent ?? "";
77+
const image = boardgame.querySelector("image")?.textContent ?? undefined;
78+
const onlineRating = Number.parseFloat(boardgame.querySelector("statistics ratings average")?.textContent ?? "");
79+
const genres = Array.from(boardgame.querySelectorAll("boardgamecategory")).map(n => n!.textContent!);
80+
81+
const model = new BoardGameModel({
82+
type: MediaType.BoardGame,
83+
title,
84+
englishTitle: title,
85+
year: year === "0" ? "" : year,
86+
dataSource: this.apiName,
87+
url: `https://boardgamegeek.com/boardgame/${id}`,
88+
id,
89+
90+
genres,
91+
onlineRating,
92+
image,
93+
released: true,
94+
95+
userData: {
96+
played: false,
97+
personalRating: 0,
98+
},
99+
} as BoardGameModel);
100+
101+
return model;
102+
103+
}
104+
}

src/api/apis/SteamAPI.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export class SteamAPI extends APIModel {
100100
englishTitle: result.name,
101101
year: (new Date(result.release_date.date)).getFullYear().toString(),
102102
dataSource: this.apiName,
103-
url: `https://store.steampowered.com/app/${result.id}`,
103+
url: `https://store.steampowered.com/app/${result.steam_appid}`,
104104
id: result.steam_appid,
105105

106106
genres: result.genres?.map((x: any) => x.description) ?? [],

src/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {WikipediaAPI} from './api/apis/WikipediaAPI';
1212
import {MusicBrainzAPI} from './api/apis/MusicBrainzAPI';
1313
import {MediaTypeManager} from './utils/MediaTypeManager';
1414
import {SteamAPI} from './api/apis/SteamAPI';
15+
import {BoardGameGeekAPI} from './api/apis/BoardGameGeekAPI';
1516
import {ModelPropertyMapper} from './settings/ModelPropertyMapper';
1617
import {YAMLConverter} from './utils/YAMLConverter';
1718
import {MediaDbFolderImportModal} from './modals/MediaDbFolderImportModal';
@@ -79,6 +80,7 @@ export default class MediaDbPlugin extends Plugin {
7980
this.apiManager.registerAPI(new WikipediaAPI(this));
8081
this.apiManager.registerAPI(new MusicBrainzAPI(this));
8182
this.apiManager.registerAPI(new SteamAPI(this));
83+
this.apiManager.registerAPI(new BoardGameGeekAPI(this));
8284
// this.apiManager.registerAPI(new LocGovAPI(this)); // TODO: parse data
8385

8486
this.mediaTypeManager = new MediaTypeManager(this.settings);

src/modals/MediaDbSearchResultModal.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class MediaDbSearchResultModal extends SelectModal<MediaTypeModel> {
2929
// Renders each suggestion item.
3030
renderElement(item: MediaTypeModel, el: HTMLElement) {
3131
el.createEl('div', {text: this.plugin.mediaTypeManager.getFileName(item)});
32-
el.createEl('small', {text: `${item.englishTitle}\n`});
32+
el.createEl('small', {text: `${item.getSummary()}\n`});
3333
el.createEl('small', {text: `${item.type.toUpperCase() + (item.subType ? ` (${item.subType})` : '')} from ${item.dataSource}`});
3434
}
3535

src/models/BoardGameModel.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import {MediaTypeModel} from './MediaTypeModel';
2+
import {mediaDbTag} from '../utils/Utils';
3+
import {MediaType} from '../utils/MediaType';
4+
5+
6+
export class BoardGameModel extends MediaTypeModel {
7+
genres: string[];
8+
onlineRating: number;
9+
image?: string;
10+
11+
released: boolean;
12+
13+
userData: {
14+
played: boolean;
15+
personalRating: number;
16+
};
17+
18+
19+
constructor(obj: any = {}) {
20+
super();
21+
22+
Object.assign(this, obj);
23+
24+
this.type = this.getMediaType();
25+
}
26+
27+
getTags(): string[] {
28+
return [mediaDbTag, 'boardgame'];
29+
}
30+
31+
getMediaType(): MediaType {
32+
return MediaType.BoardGame;
33+
}
34+
35+
getSummary(): string {
36+
return this.englishTitle + ' (' + this.year + ')';
37+
}
38+
39+
}

src/models/GameModel.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,8 @@ export class GameModel extends MediaTypeModel {
4242
return MediaType.Game;
4343
}
4444

45+
getSummary(): string {
46+
return this.englishTitle + ' (' + this.year + ')';
47+
}
48+
4549
}

src/models/MediaTypeModel.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ export abstract class MediaTypeModel {
1414

1515
abstract getMediaType(): MediaType;
1616

17+
//a string that contains enough info to disambiguate from similar media
18+
abstract getSummary(): string;
19+
1720
abstract getTags(): string[];
1821

1922
toMetaDataObject(): object {

src/models/MovieModel.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,7 @@ export class MovieModel extends MediaTypeModel {
4444
return MediaType.Movie;
4545
}
4646

47+
getSummary(): string {
48+
return this.englishTitle + ' (' + this.year + ')';
49+
}
4750
}

0 commit comments

Comments
 (0)