Skip to content

Commit 38d28e1

Browse files
committed
Testing openlibrary support
1 parent 5054b0f commit 38d28e1

File tree

6 files changed

+203
-6
lines changed

6 files changed

+203
-6
lines changed

src/api/apis/OpenLibraryAPI.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { APIModel } from '../APIModel';
2+
import { MediaTypeModel } from '../../models/MediaTypeModel';
3+
import MediaDbPlugin from '../../main';
4+
import { BookModel } from 'src/models/BookModel';
5+
import { requestUrl } from 'obsidian';
6+
import { MediaType } from '../../utils/MediaType';
7+
8+
export class OpenLibraryAPI extends APIModel {
9+
plugin: MediaDbPlugin;
10+
11+
constructor(plugin: MediaDbPlugin) {
12+
super();
13+
14+
this.plugin = plugin;
15+
this.apiName = 'OpenLibraryAPI';
16+
this.apiDescription = 'A free API for books';
17+
this.apiUrl = 'https://openlibrary.org/';
18+
this.types = [MediaType.Book];
19+
}
20+
21+
async searchByTitle(title: string): Promise<MediaTypeModel[]> {
22+
console.log(`MDB | api "${this.apiName}" queried by Title`);
23+
24+
const searchUrl = `https://openlibrary.org/search.json?title=${encodeURIComponent(title)}&limit=20}`;
25+
26+
const fetchData = await fetch(searchUrl);
27+
console.debug(fetchData);
28+
if (fetchData.status !== 200) {
29+
throw Error(`MDB | Received status code ${fetchData.status} from an API.`);
30+
}
31+
const data = await fetchData.json();
32+
33+
console.debug(data);
34+
35+
const ret: MediaTypeModel[] = [];
36+
37+
for (const result of data.docs) {
38+
ret.push(
39+
new BookModel({
40+
subType: '',
41+
title: result.title,
42+
englishTitle: result.title_english ?? result.title,
43+
year: result.year ?? result.aired?.prop?.from?.year ?? '',
44+
dataSource: this.apiName,
45+
id: result.mal_id,
46+
} as BookModel)
47+
);
48+
}
49+
50+
return ret;
51+
}
52+
53+
async getById(id: string): Promise<MediaTypeModel> {
54+
console.log(`MDB | api "${this.apiName}" queried by ID`);
55+
56+
const searchUrl = `https://openlibrary.org/isbn/${encodeURIComponent(id)}.json`;
57+
const fetchData = await fetch(searchUrl);
58+
59+
if (fetchData.status !== 200) {
60+
throw Error(`MDB | Received status code ${fetchData.status} from an API.`);
61+
}
62+
63+
const data = await fetchData.json();
64+
console.debug(data);
65+
const result = data.data;
66+
67+
const model = new BookModel({
68+
subType: '',
69+
title: result.title,
70+
year: new Date(result.publish_date.date).getFullYear().toString(),
71+
dataSource: this.apiName,
72+
url: `https://openlibrary.org` + result.key,
73+
id: result.isbn_10,
74+
75+
author: result.authors.key ?? 'unknown',
76+
pages: result.number_of_pages ?? 'unknown',
77+
image: `https://covers.openlibrary.org/b/isbn/` + result.isbn_10 + `-L.jpg` ?? '',
78+
79+
released: true,
80+
81+
userData: {
82+
read: false,
83+
lastRead: '',
84+
personalRating: 0,
85+
},
86+
} as BookModel);
87+
88+
return;
89+
}
90+
}

src/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { MusicBrainzAPI } from './api/apis/MusicBrainzAPI';
1010
import { MEDIA_TYPES, MediaTypeManager } from './utils/MediaTypeManager';
1111
import { SteamAPI } from './api/apis/SteamAPI';
1212
import { BoardGameGeekAPI } from './api/apis/BoardGameGeekAPI';
13+
import { OpenLibraryAPI } from './api/apis/OpenLibraryAPI';
1314
import { PropertyMapper } from './settings/PropertyMapper';
1415
import { YAMLConverter } from './utils/YAMLConverter';
1516
import { MediaDbFolderImportModal } from './modals/MediaDbFolderImportModal';
@@ -36,6 +37,7 @@ export default class MediaDbPlugin extends Plugin {
3637
this.apiManager.registerAPI(new MusicBrainzAPI(this));
3738
this.apiManager.registerAPI(new SteamAPI(this));
3839
this.apiManager.registerAPI(new BoardGameGeekAPI(this));
40+
this.apiManager.registerAPI(new OpenLibraryAPI(this));
3941
// this.apiManager.registerAPI(new LocGovAPI(this)); // TODO: parse data
4042

4143
this.mediaTypeManager = new MediaTypeManager();

src/models/BookModel.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { MediaTypeModel } from './MediaTypeModel';
2+
import { mediaDbTag, migrateObject } from '../utils/Utils';
3+
import { MediaType } from '../utils/MediaType';
4+
5+
export class BookModel extends MediaTypeModel {
6+
author: string;
7+
pages: string;
8+
image: string;
9+
10+
released: boolean;
11+
12+
userData: {
13+
read: boolean;
14+
lastRead: string;
15+
personalRating: number;
16+
};
17+
18+
constructor(obj: any = {}) {
19+
super();
20+
21+
this.author = undefined;
22+
this.pages = undefined;
23+
this.image = undefined;
24+
25+
this.released = undefined;
26+
27+
this.userData = {
28+
read: undefined,
29+
lastRead: undefined,
30+
personalRating: undefined,
31+
};
32+
33+
migrateObject(this, obj, this);
34+
35+
if (!obj.hasOwnProperty('userData')) {
36+
migrateObject(this.userData, obj, this.userData);
37+
}
38+
39+
this.type = this.getMediaType();
40+
}
41+
42+
getTags(): string[] {
43+
return [mediaDbTag, 'book'];
44+
}
45+
46+
getMediaType(): MediaType {
47+
return MediaType.Book;
48+
}
49+
50+
getSummary(): string {
51+
return this.englishTitle + ' (' + this.year + ')';
52+
}
53+
}

src/settings/Settings.ts

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,31 @@ export interface MediaDbPluginSettings {
2222
wikiTemplate: string;
2323
musicReleaseTemplate: string;
2424
boardgameTemplate: string;
25+
bookTemplate: string;
2526

2627
movieFileNameTemplate: string;
2728
seriesFileNameTemplate: string;
2829
gameFileNameTemplate: string;
2930
wikiFileNameTemplate: string;
3031
musicReleaseFileNameTemplate: string;
3132
boardgameFileNameTemplate: string;
33+
bookFileNameTemplate: string;
3234

3335
moviePropertyConversionRules: string;
3436
seriesPropertyConversionRules: string;
3537
gamePropertyConversionRules: string;
3638
wikiPropertyConversionRules: string;
3739
musicReleasePropertyConversionRules: string;
3840
boardgamePropertyConversionRules: string;
41+
bookPropertyConversionRules: string;
3942

4043
movieFolder: string;
4144
seriesFolder: string;
4245
gameFolder: string;
4346
wikiFolder: string;
4447
musicReleaseFolder: string;
4548
boardgameFolder: string;
49+
bookFolder: string;
4650

4751
propertyMappingModels: PropertyMappingModel[];
4852
}
@@ -60,27 +64,31 @@ const DEFAULT_SETTINGS: MediaDbPluginSettings = {
6064
wikiTemplate: '',
6165
musicReleaseTemplate: '',
6266
boardgameTemplate: '',
67+
bookTemplate: '',
6368

6469
movieFileNameTemplate: '{{ title }} ({{ year }})',
6570
seriesFileNameTemplate: '{{ title }} ({{ year }})',
6671
gameFileNameTemplate: '{{ title }} ({{ year }})',
6772
wikiFileNameTemplate: '{{ title }}',
6873
musicReleaseFileNameTemplate: '{{ title }} (by {{ ENUM:artists }} - {{ year }})',
6974
boardgameFileNameTemplate: '{{ title }} ({{ year }})',
75+
bookFileNameTemplate: '{{ title }} ({{ year }})',
7076

7177
moviePropertyConversionRules: '',
7278
seriesPropertyConversionRules: '',
7379
gamePropertyConversionRules: '',
7480
wikiPropertyConversionRules: '',
7581
musicReleasePropertyConversionRules: '',
7682
boardgamePropertyConversionRules: '',
83+
bookPropertyConversionRules: '',
7784

7885
movieFolder: 'Media DB/movies',
7986
seriesFolder: 'Media DB/series',
8087
gameFolder: 'Media DB/games',
8188
wikiFolder: 'Media DB/wiki',
8289
musicReleaseFolder: 'Media DB/music',
8390
boardgameFolder: 'Media DB/boardgames',
91+
bookFolder: 'Media DB/books',
8492

8593
propertyMappingModels: [],
8694
};
@@ -194,7 +202,7 @@ export class MediaDbSettingTab extends PluginSettingTab {
194202
// region new file location
195203
new Setting(containerEl)
196204
.setName('Movie Folder')
197-
.setDesc('Where newly imported movies should be places.')
205+
.setDesc('Where newly imported movies should be placed.')
198206
.addSearch(cb => {
199207
new FolderSuggest(this.app, cb.inputEl);
200208
cb.setPlaceholder(DEFAULT_SETTINGS.movieFolder)
@@ -207,7 +215,7 @@ export class MediaDbSettingTab extends PluginSettingTab {
207215

208216
new Setting(containerEl)
209217
.setName('Series Folder')
210-
.setDesc('Where newly imported series should be places.')
218+
.setDesc('Where newly imported series should be placed.')
211219
.addSearch(cb => {
212220
new FolderSuggest(this.app, cb.inputEl);
213221
cb.setPlaceholder(DEFAULT_SETTINGS.seriesFolder)
@@ -220,7 +228,7 @@ export class MediaDbSettingTab extends PluginSettingTab {
220228

221229
new Setting(containerEl)
222230
.setName('Game Folder')
223-
.setDesc('Where newly imported games should be places.')
231+
.setDesc('Where newly imported games should be placed.')
224232
.addSearch(cb => {
225233
new FolderSuggest(this.app, cb.inputEl);
226234
cb.setPlaceholder(DEFAULT_SETTINGS.gameFolder)
@@ -233,7 +241,7 @@ export class MediaDbSettingTab extends PluginSettingTab {
233241

234242
new Setting(containerEl)
235243
.setName('Wiki Folder')
236-
.setDesc('Where newly imported wiki articles should be places.')
244+
.setDesc('Where newly imported wiki articles should be placed.')
237245
.addSearch(cb => {
238246
new FolderSuggest(this.app, cb.inputEl);
239247
cb.setPlaceholder(DEFAULT_SETTINGS.wikiFolder)
@@ -246,7 +254,7 @@ export class MediaDbSettingTab extends PluginSettingTab {
246254

247255
new Setting(containerEl)
248256
.setName('Music Folder')
249-
.setDesc('Where newly imported music should be places.')
257+
.setDesc('Where newly imported music should be placed.')
250258
.addSearch(cb => {
251259
new FolderSuggest(this.app, cb.inputEl);
252260
cb.setPlaceholder(DEFAULT_SETTINGS.musicReleaseFolder)
@@ -269,6 +277,18 @@ export class MediaDbSettingTab extends PluginSettingTab {
269277
this.plugin.saveSettings();
270278
});
271279
});
280+
new Setting(containerEl)
281+
.setName('Book Folder')
282+
.setDesc('Where newly imported books should be placed.')
283+
.addSearch(cb => {
284+
new FolderSuggest(this.app, cb.inputEl);
285+
cb.setPlaceholder(DEFAULT_SETTINGS.bookFolder)
286+
.setValue(this.plugin.settings.bookFolder)
287+
.onChange(data => {
288+
this.plugin.settings.bookFolder = data;
289+
this.plugin.saveSettings();
290+
});
291+
});
272292
// endregion
273293

274294
containerEl.createEl('h3', { text: 'Template Settings' });
@@ -350,6 +370,19 @@ export class MediaDbSettingTab extends PluginSettingTab {
350370
this.plugin.saveSettings();
351371
});
352372
});
373+
374+
new Setting(containerEl)
375+
.setName('Book template')
376+
.setDesc('Template file to be used when creating a new note for a book.')
377+
.addSearch(cb => {
378+
new FileSuggest(this.app, cb.inputEl);
379+
cb.setPlaceholder('Example: bookTemplate.md')
380+
.setValue(this.plugin.settings.bookTemplate)
381+
.onChange(data => {
382+
this.plugin.settings.bookTemplate = data;
383+
this.plugin.saveSettings();
384+
});
385+
});
353386
// endregion
354387

355388
containerEl.createEl('h3', { text: 'File Name Settings' });
@@ -425,6 +458,18 @@ export class MediaDbSettingTab extends PluginSettingTab {
425458
this.plugin.saveSettings();
426459
});
427460
});
461+
462+
new Setting(containerEl)
463+
.setName('Book file name template')
464+
.setDesc('Template for the file name used when creating a new note for a book.')
465+
.addText(cb => {
466+
cb.setPlaceholder(`Example: ${DEFAULT_SETTINGS.bookFileNameTemplate}`)
467+
.setValue(this.plugin.settings.bookFileNameTemplate)
468+
.onChange(data => {
469+
this.plugin.settings.bookFileNameTemplate = data;
470+
this.plugin.saveSettings();
471+
});
472+
});
428473
// endregion
429474

430475
// region Property Mappings

src/utils/MediaType.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ export enum MediaType {
55
MusicRelease = 'musicRelease',
66
Wiki = 'wiki',
77
BoardGame = 'boardgame',
8+
Book = 'book',
89
}

src/utils/MediaTypeManager.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ import { GameModel } from '../models/GameModel';
99
import { WikiModel } from '../models/WikiModel';
1010
import { MusicReleaseModel } from '../models/MusicReleaseModel';
1111
import { BoardGameModel } from '../models/BoardGameModel';
12+
import { BookModel } from '../models/BookModel';
1213

13-
export const MEDIA_TYPES: MediaType[] = [MediaType.Movie, MediaType.Series, MediaType.Game, MediaType.Wiki, MediaType.MusicRelease, MediaType.BoardGame];
14+
export const MEDIA_TYPES: MediaType[] = [MediaType.Movie, MediaType.Series, MediaType.Game, MediaType.Wiki, MediaType.MusicRelease, MediaType.BoardGame, MediaType.Book];
1415

1516
export class MediaTypeManager {
1617
mediaFileNameTemplateMap: Map<MediaType, string>;
@@ -27,6 +28,7 @@ export class MediaTypeManager {
2728
this.mediaFileNameTemplateMap.set(MediaType.Wiki, settings.wikiFileNameTemplate);
2829
this.mediaFileNameTemplateMap.set(MediaType.MusicRelease, settings.musicReleaseFileNameTemplate);
2930
this.mediaFileNameTemplateMap.set(MediaType.BoardGame, settings.boardgameFileNameTemplate);
31+
this.mediaFileNameTemplateMap.set(MediaType.Book, settings.bookFileNameTemplate);
3032

3133
this.mediaTemplateMap = new Map<MediaType, string>();
3234
this.mediaTemplateMap.set(MediaType.Movie, settings.movieTemplate);
@@ -35,6 +37,7 @@ export class MediaTypeManager {
3537
this.mediaTemplateMap.set(MediaType.Wiki, settings.wikiTemplate);
3638
this.mediaTemplateMap.set(MediaType.MusicRelease, settings.musicReleaseTemplate);
3739
this.mediaTemplateMap.set(MediaType.BoardGame, settings.boardgameTemplate);
40+
this.mediaTemplateMap.set(MediaType.Book, settings.bookTemplate);
3841
}
3942

4043
updateFolders(settings: MediaDbPluginSettings): void {
@@ -45,6 +48,7 @@ export class MediaTypeManager {
4548
this.mediaFolderMap.set(MediaType.Wiki, settings.wikiFolder);
4649
this.mediaFolderMap.set(MediaType.MusicRelease, settings.musicReleaseFolder);
4750
this.mediaFolderMap.set(MediaType.BoardGame, settings.boardgameFolder);
51+
this.mediaFolderMap.set(MediaType.Book, settings.bookFolder);
4852
}
4953

5054
getFileName(mediaTypeModel: MediaTypeModel): string {
@@ -111,6 +115,8 @@ export class MediaTypeManager {
111115
return new MusicReleaseModel(obj);
112116
} else if (mediaType === MediaType.BoardGame) {
113117
return new BoardGameModel(obj);
118+
} else if (mediaType === MediaType.Book) {
119+
return new BookModel(obj);
114120
}
115121

116122
return undefined;

0 commit comments

Comments
 (0)