From 7ba91c2a2f3592b389b8a4e77692bf75722b7aa8 Mon Sep 17 00:00:00 2001 From: mProjectsCode Date: Wed, 18 May 2022 20:05:45 +0200 Subject: [PATCH 1/5] wikipedia api #3 --- src/api/apis/LocGovAPI.ts | 145 +++++++++++++++++++++++++++++++++++ src/api/apis/WikipediaAPI.ts | 78 +++++++++++++++++++ src/main.ts | 3 + src/models/WikiModel.ts | 33 ++++++++ 4 files changed, 259 insertions(+) create mode 100644 src/api/apis/LocGovAPI.ts create mode 100644 src/api/apis/WikipediaAPI.ts create mode 100644 src/models/WikiModel.ts diff --git a/src/api/apis/LocGovAPI.ts b/src/api/apis/LocGovAPI.ts new file mode 100644 index 0000000..8e8fa42 --- /dev/null +++ b/src/api/apis/LocGovAPI.ts @@ -0,0 +1,145 @@ +import {APIModel} from '../APIModel'; +import {MediaTypeModel} from '../../models/MediaTypeModel'; +import MediaDbPlugin from '../../main'; + +export class LocGovAPI extends APIModel { + plugin: MediaDbPlugin; + typeMappings: Map; + + constructor(plugin: MediaDbPlugin) { + super(); + + this.plugin = plugin; + this.apiName = 'loc.gov API'; + this.apiDescription = 'A free API for the Library of Congress collections.'; + this.apiUrl = 'https://libraryofcongress.github.io/data-exploration/index.html'; + this.types = []; + this.typeMappings = new Map(); + // this.typeMappings.set('movie', 'movie'); + } + + async searchByTitle(title: string): Promise { + console.log(`MDB | api "${this.apiName}" queried`); + + const searchUrl = `https://www.loc.gov/search/?q=${title}&fo=json&c=20`; + + const fetchData = await fetch(searchUrl); + console.log(fetchData); + if (fetchData.status !== 200) { + throw Error(`Received status code ${fetchData.status} from an API.`); + } + const data = await fetchData.json(); + + console.log(data); + + let ret: MediaTypeModel[] = []; + + /* + for (const result of data.data) { + const type = this.typeMappings.get(result.type.toLowerCase()); + if (type === undefined) { + continue; + } + if (type === 'movie' || type === 'special') { + ret.push(new MovieModel({ + type: type, + title: result.title, + englishTitle: result.title_english ?? result.title, + year: result.year ?? result.aired?.prop?.from?.year ?? '', + dataSource: this.apiName, + id: result.mal_id, + } as MovieModel)); + } else if (type === 'series' || type === 'ova') { + ret.push(new SeriesModel({ + type: type, + title: result.title, + englishTitle: result.title_english ?? result.title, + year: result.year ?? result.aired?.prop?.from?.year ?? '', + dataSource: this.apiName, + id: result.mal_id, + } as SeriesModel)); + } + } + */ + + return ret; + } + + async getById(item: MediaTypeModel): Promise { + + const searchUrl = `https://www.loc.gov/item/{item.id}/?fo=json`; + + const fetchData = await fetch(searchUrl); + if (fetchData.status !== 200) { + throw Error(`Received status code ${fetchData.status} from an API.`); + } + + const data = await fetchData.json(); + console.log(data); + const result = data.data; + + const type = this.typeMappings.get(result.type.toLowerCase()); + if (type === undefined) { + throw Error(`${result.type.toLowerCase()} is an unsupported type.`); + } + + /* + if (type === 'movie' || type === 'special') { + const model = new MovieModel({ + type: type, + title: result.title, + englishTitle: result.title_english ?? result.title, + year: result.year ?? result.aired?.prop?.from?.year ?? '', + dataSource: this.apiName, + url: result.url, + id: result.mal_id, + + genres: result.genres?.map((x: any) => x.name) ?? [], + producer: result.studios?.map((x: any) => x.name).join(', ') ?? 'unknown', + duration: result.duration ?? 'unknown', + onlineRating: result.score ?? 0, + image: result.images?.jpg?.image_url ?? '', + + released: true, + premiere: (new Date(result.aired?.from)).toLocaleDateString() ?? 'unknown', + + watched: false, + lastWatched: '', + personalRating: 0, + } as MovieModel); + + return model; + } else if (type === 'series' || type === 'ova') { + const model = new SeriesModel({ + type: type, + title: result.title, + englishTitle: result.title_english ?? result.title, + year: result.year ?? result.aired?.prop?.from?.year ?? '', + dataSource: this.apiName, + url: result.url, + id: result.mal_id, + + genres: result.genres?.map((x: any) => x.name) ?? [], + studios: result.studios?.map((x: any) => x.name) ?? [], + episodes: result.episodes, + duration: result.duration ?? 'unknown', + onlineRating: result.score ?? 0, + image: result.images?.jpg?.image_url ?? '', + + released: true, + airedFrom: (new Date(result.aired?.from)).toLocaleDateString() ?? 'unknown', + airedTo: (new Date(result.aired?.to)).toLocaleDateString() ?? 'unknown', + airing: result.airing, + + watched: false, + lastWatched: '', + personalRating: 0, + } as SeriesModel); + + return model; + } + */ + + return; + } +} diff --git a/src/api/apis/WikipediaAPI.ts b/src/api/apis/WikipediaAPI.ts new file mode 100644 index 0000000..5e141e2 --- /dev/null +++ b/src/api/apis/WikipediaAPI.ts @@ -0,0 +1,78 @@ +import {APIModel} from '../APIModel'; +import {MediaTypeModel} from '../../models/MediaTypeModel'; +import MediaDbPlugin from '../../main'; +import {WikiModel} from '../../models/WikiModel'; + +export class WikipediaAPI extends APIModel { + plugin: MediaDbPlugin; + + constructor(plugin: MediaDbPlugin) { + super(); + + this.plugin = plugin; + this.apiName = 'Wikipedia API'; + this.apiDescription = 'The API behind Wikipedia'; + this.apiUrl = 'https://www.wikipedia.com'; + this.types = ['wiki']; + } + + async searchByTitle(title: string): Promise { + console.log(`MDB | api "${this.apiName}" queried`); + + const searchUrl = `https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=${title}&srlimit=20&utf8=&format=json&origin=*`; + + const fetchData = await fetch(searchUrl); + console.log(fetchData); + if (fetchData.status !== 200) { + throw Error(`Received status code ${fetchData.status} from an API.`); + } + const data = await fetchData.json(); + + console.log(data); + + let ret: MediaTypeModel[] = []; + + + for (const result of data.query.search) { + ret.push(new WikiModel({ + type: 'wiki', + title: result.title, + englishTitle: result.title, + year: '', + dataSource: this.apiName, + id: result.pageid, + } as WikiModel)); + } + + return ret; + } + + async getById(item: MediaTypeModel): Promise { + + const searchUrl = `https://en.wikipedia.org/w/api.php?action=query&prop=info&pageids=${item.id}&inprop=url&format=json&origin=*`; + + const fetchData = await fetch(searchUrl); + if (fetchData.status !== 200) { + throw Error(`Received status code ${fetchData.status} from an API.`); + } + + const data = await fetchData.json(); + console.log(data); + const result = Object.entries(data?.query?.pages)[0][1]; + + const model = new WikiModel({ + type: 'wiki', + title: result.title, + englishTitle: result.title, + year: '', + dataSource: this.apiName, + id: result.pageid, + + wikiUrl: result.fullurl, + lastUpdated: (new Date(result.touched)).toLocaleDateString() ?? 'unknown', + length: result.length, + } as WikiModel); + + return model; + } +} diff --git a/src/main.ts b/src/main.ts index 5cad2c0..880d086 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,6 +9,7 @@ import {MediaDbAdvancedSearchModal} from './modals/MediaDbAdvancedSearchModal'; import {MediaDbSearchResultModal} from './modals/MediaDbSearchResultModal'; import {MALAPI} from './api/apis/MALAPI'; import {MediaDbIdSearchModal} from './modals/MediaDbIdSearchModal'; +import {WikipediaAPI} from './api/apis/WikipediaAPI'; export default class MediaDbPlugin extends Plugin { settings: MediaDbPluginSettings; @@ -45,6 +46,8 @@ export default class MediaDbPlugin extends Plugin { this.apiManager.registerAPI(new TestAPI()); this.apiManager.registerAPI(new OMDbAPI(this)); this.apiManager.registerAPI(new MALAPI(this)); + this.apiManager.registerAPI(new WikipediaAPI(this)); + // this.apiManager.registerAPI(new LocGovAPI(this)); // TODO: parse data } async createMediaDbNote(modal: () => Promise): Promise { diff --git a/src/models/WikiModel.ts b/src/models/WikiModel.ts new file mode 100644 index 0000000..b97eac8 --- /dev/null +++ b/src/models/WikiModel.ts @@ -0,0 +1,33 @@ +import {MediaTypeModel} from './MediaTypeModel'; +import {stringifyYaml} from 'obsidian'; + + +export class WikiModel extends MediaTypeModel { + type: string; + title: string; + englishTitle: string; + year: string; + dataSource: string; + url: string; + id: string; + + wikiUrl: string; + lastUpdated: string; + length: number; + + + constructor(obj: any = {}) { + super(); + + Object.assign(this, obj); + } + + toMetaData(): string { + return stringifyYaml(this); + } + + getFileName(): string { + return this.title; + } + +} From 003c568099aa79edb97285331870c13c9b302fc6 Mon Sep 17 00:00:00 2001 From: mProjectsCode Date: Wed, 18 May 2022 22:10:56 +0200 Subject: [PATCH 2/5] Music releases --- src/api/apis/LocGovAPI.ts | 3 +- src/api/apis/MALAPI.ts | 2 +- src/api/apis/MusicBrainzAPI.ts | 98 ++++++++++++++++++++++++ src/api/apis/OMDbAPI.ts | 2 +- src/api/apis/TestAPI.ts | 26 ------- src/api/apis/WikipediaAPI.ts | 2 +- src/main.ts | 8 +- src/modals/MediaDbAdvancedSearchModal.ts | 2 +- src/models/MusicReleaseModel.ts | 35 +++++++++ src/models/SeriesModel.ts | 2 +- src/settings/Settings.ts | 30 ++++++++ src/utils/Utils.ts | 4 +- 12 files changed, 178 insertions(+), 36 deletions(-) create mode 100644 src/api/apis/MusicBrainzAPI.ts delete mode 100644 src/api/apis/TestAPI.ts create mode 100644 src/models/MusicReleaseModel.ts diff --git a/src/api/apis/LocGovAPI.ts b/src/api/apis/LocGovAPI.ts index 8e8fa42..9788bb4 100644 --- a/src/api/apis/LocGovAPI.ts +++ b/src/api/apis/LocGovAPI.ts @@ -2,6 +2,7 @@ import {APIModel} from '../APIModel'; import {MediaTypeModel} from '../../models/MediaTypeModel'; import MediaDbPlugin from '../../main'; +// WIP export class LocGovAPI extends APIModel { plugin: MediaDbPlugin; typeMappings: Map; @@ -21,7 +22,7 @@ export class LocGovAPI extends APIModel { async searchByTitle(title: string): Promise { console.log(`MDB | api "${this.apiName}" queried`); - const searchUrl = `https://www.loc.gov/search/?q=${title}&fo=json&c=20`; + const searchUrl = `https://www.loc.gov/search/?q=${encodeURIComponent(title)}&fo=json&c=20`; const fetchData = await fetch(searchUrl); console.log(fetchData); diff --git a/src/api/apis/MALAPI.ts b/src/api/apis/MALAPI.ts index 8057ab7..48cc850 100644 --- a/src/api/apis/MALAPI.ts +++ b/src/api/apis/MALAPI.ts @@ -26,7 +26,7 @@ export class MALAPI extends APIModel { async searchByTitle(title: string): Promise { console.log(`MDB | api "${this.apiName}" queried`); - const searchUrl = `https://api.jikan.moe/v4/anime?q=${title}&limit=20${this.plugin.settings.sfwFilter ? '&sfw' : ''}`; + const searchUrl = `https://api.jikan.moe/v4/anime?q=${encodeURIComponent(title)}&limit=20${this.plugin.settings.sfwFilter ? '&sfw' : ''}`; const fetchData = await fetch(searchUrl); console.log(fetchData); diff --git a/src/api/apis/MusicBrainzAPI.ts b/src/api/apis/MusicBrainzAPI.ts new file mode 100644 index 0000000..0cd899c --- /dev/null +++ b/src/api/apis/MusicBrainzAPI.ts @@ -0,0 +1,98 @@ +import {APIModel} from '../APIModel'; +import {MediaTypeModel} from '../../models/MediaTypeModel'; +import MediaDbPlugin from '../../main'; +import {requestUrl} from 'obsidian'; +import {MusicReleaseModel} from '../../models/MusicReleaseModel'; +// import {MusicBrainzApi} from 'musicbrainz-api'; + +// WIP +export class MusicBrainzAPI extends APIModel { + plugin: MediaDbPlugin; + + constructor(plugin: MediaDbPlugin) { + super(); + + this.plugin = plugin; + this.apiName = 'MusicBrainz API'; + this.apiDescription = 'Free API for music albums.'; + this.apiUrl = 'https://musicbrainz.org/'; + this.types = ['music']; + } + + async searchByTitle(title: string): Promise { + console.log(`MDB | api "${this.apiName}" queried`); + + const searchUrl = `https://musicbrainz.org/ws/2/release-group?query=${encodeURIComponent(title)}&limit=20&fmt=json`; + + const fetchData = await requestUrl({ + url: searchUrl, + headers: { + 'User-Agent': 'obsidian-media-db-plugin/0.1.7 ( m.projects.code@gmail.com )', + }, + }); + + console.log(fetchData); + + if (fetchData.status !== 200) { + throw Error(`Received status code ${fetchData.status} from an API.`); + } + const data = await fetchData.json; + + console.log(data); + + let ret: MediaTypeModel[] = []; + + for (const result of data['release-groups']) { + ret.push(new MusicReleaseModel({ + type: 'musicRelease', + title: result.title, + englishTitle: result.title, + year: (new Date(result['first-release-date'])).getFullYear().toString(), + dataSource: this.apiName, + url: '', + id: result.id, + + artists: result['artist-credit'].map((a: any) => a.name), + subType: result['primary-type'], + } as MusicReleaseModel)); + } + + return ret; + } + + async getById(item: MediaTypeModel): Promise { + console.log(`MDB | api "${this.apiName}" queried`); + + const searchUrl = `https://musicbrainz.org/ws/2/release-group/${encodeURIComponent(item.id)}?inc=releases+artists+tags+ratings+genres&fmt=json`; + + const fetchData = await requestUrl({ + url: searchUrl, + headers: { + 'User-Agent': 'MyAwesomeTagger/1.2.0 ( me@example.com )', + }, + }); + + const data = await fetchData.json; + + console.log(data); + + const result = data; + + const model = new MusicReleaseModel({ + type: 'musicRelease', + title: result.title, + englishTitle: result.title, + year: (new Date(result['first-release-date'])).getFullYear().toString(), + dataSource: this.apiName, + url: '', + id: result.id, + + artists: result['artist-credit'].map((a: any) => a.name), + genres: result.genres.map((g: any) => g.name), + subType: result['primary-type'], + rating: result.rating.value * 2, + } as MusicReleaseModel); + + return model; + } +} diff --git a/src/api/apis/OMDbAPI.ts b/src/api/apis/OMDbAPI.ts index e3531db..d5797f4 100644 --- a/src/api/apis/OMDbAPI.ts +++ b/src/api/apis/OMDbAPI.ts @@ -26,7 +26,7 @@ export class OMDbAPI extends APIModel { async searchByTitle(title: string): Promise { console.log(`MDB | api "${this.apiName}" queried`); - const searchUrl = `http://www.omdbapi.com/?s=${title}&apikey=${this.plugin.settings.OMDbKey}`; + const searchUrl = `http://www.omdbapi.com/?s=${encodeURIComponent(title)}&apikey=${this.plugin.settings.OMDbKey}`; const fetchData = await fetch(searchUrl); diff --git a/src/api/apis/TestAPI.ts b/src/api/apis/TestAPI.ts deleted file mode 100644 index cdba595..0000000 --- a/src/api/apis/TestAPI.ts +++ /dev/null @@ -1,26 +0,0 @@ -import {APIModel} from '../APIModel'; -import {MediaTypeModel} from '../../models/MediaTypeModel'; -import {MovieModel} from '../../models/MovieModel'; - -export class TestAPI extends APIModel { - constructor() { - super(); - this.apiName = 'testAPI'; - this.apiDescription = 'The test API used during development.'; - this.apiUrl = 'www.test.api'; - this.types = ['test']; - } - - async searchByTitle(title: string): Promise { - console.log(`MDB | api "${this.apiName}" queried`); - - return [ - new MovieModel({title: 'test_1', type: this.types[0], dataSource: this.apiName}), - new MovieModel({title: 'test_2', type: this.types[0], dataSource: this.apiName, producer: 'Max Musterman'}), - ]; - } - - async getById(item: MediaTypeModel): Promise { - return item; - } -} diff --git a/src/api/apis/WikipediaAPI.ts b/src/api/apis/WikipediaAPI.ts index 5e141e2..db17d40 100644 --- a/src/api/apis/WikipediaAPI.ts +++ b/src/api/apis/WikipediaAPI.ts @@ -19,7 +19,7 @@ export class WikipediaAPI extends APIModel { async searchByTitle(title: string): Promise { console.log(`MDB | api "${this.apiName}" queried`); - const searchUrl = `https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=${title}&srlimit=20&utf8=&format=json&origin=*`; + const searchUrl = `https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=${encodeURIComponent(title)}&srlimit=20&utf8=&format=json&origin=*`; const fetchData = await fetch(searchUrl); console.log(fetchData); diff --git a/src/main.ts b/src/main.ts index 880d086..0a8ab3a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,7 +1,6 @@ import {Notice, Plugin, TFile} from 'obsidian'; import {DEFAULT_SETTINGS, MediaDbPluginSettings, MediaDbSettingTab} from './settings/Settings'; import {APIManager} from './api/APIManager'; -import {TestAPI} from './api/apis/TestAPI'; import {MediaTypeModel} from './models/MediaTypeModel'; import {replaceIllegalFileNameCharactersInString, replaceTags} from './utils/Utils'; import {OMDbAPI} from './api/apis/OMDbAPI'; @@ -10,6 +9,7 @@ import {MediaDbSearchResultModal} from './modals/MediaDbSearchResultModal'; import {MALAPI} from './api/apis/MALAPI'; import {MediaDbIdSearchModal} from './modals/MediaDbIdSearchModal'; import {WikipediaAPI} from './api/apis/WikipediaAPI'; +import {MusicBrainzAPI} from './api/apis/MusicBrainzAPI'; export default class MediaDbPlugin extends Plugin { settings: MediaDbPluginSettings; @@ -43,10 +43,10 @@ export default class MediaDbPlugin extends Plugin { this.apiManager = new APIManager(); // register APIs - this.apiManager.registerAPI(new TestAPI()); this.apiManager.registerAPI(new OMDbAPI(this)); this.apiManager.registerAPI(new MALAPI(this)); this.apiManager.registerAPI(new WikipediaAPI(this)); + this.apiManager.registerAPI(new MusicBrainzAPI(this)); // this.apiManager.registerAPI(new LocGovAPI(this)); // TODO: parse data } @@ -71,6 +71,10 @@ export default class MediaDbPlugin extends Plugin { templateFile = this.app.vault.getFiles().filter((f: TFile) => f.name === this.settings.seriesTemplate).first(); } else if (data.type === 'game' && this.settings.gameTemplate) { templateFile = this.app.vault.getFiles().filter((f: TFile) => f.name === this.settings.gameTemplate).first(); + } else if (data.type === 'wiki' && this.settings.wikiTemplate) { + templateFile = this.app.vault.getFiles().filter((f: TFile) => f.name === this.settings.wikiTemplate).first(); + } else if (data.type === 'musicRelease' && this.settings.musicReleaseTemplate) { + templateFile = this.app.vault.getFiles().filter((f: TFile) => f.name === this.settings.musicReleaseTemplate).first(); } if (templateFile) { diff --git a/src/modals/MediaDbAdvancedSearchModal.ts b/src/modals/MediaDbAdvancedSearchModal.ts index 08da542..0664620 100644 --- a/src/modals/MediaDbAdvancedSearchModal.ts +++ b/src/modals/MediaDbAdvancedSearchModal.ts @@ -30,7 +30,7 @@ export class MediaDbAdvancedSearchModal extends Modal { console.log(this.selectedApis); - if (!this.query || this.query.length < 5) { + if (!this.query || this.query.length < 3) { new Notice('MDB: Query to short'); return; } diff --git a/src/models/MusicReleaseModel.ts b/src/models/MusicReleaseModel.ts new file mode 100644 index 0000000..46a2505 --- /dev/null +++ b/src/models/MusicReleaseModel.ts @@ -0,0 +1,35 @@ +import {MediaTypeModel} from './MediaTypeModel'; +import {stringifyYaml} from 'obsidian'; + + +export class MusicReleaseModel extends MediaTypeModel { + type: string; + title: string; + englishTitle: string; + year: string; + dataSource: string; + url: string; + id: string; + + genres: string[]; + artists: string[]; + subType: string; + rating: number; + + personalRating: number; + + constructor(obj: any = {}) { + super(); + + Object.assign(this, obj); + } + + toMetaData(): string { + return stringifyYaml(this); + } + + getFileName(): string { + return this.title + ' (' + this.artists.join(', ') + ' - ' + this.year + ' - ' + this.subType + ')'; + } + +} diff --git a/src/models/SeriesModel.ts b/src/models/SeriesModel.ts index d6ab109..7fc4a17 100644 --- a/src/models/SeriesModel.ts +++ b/src/models/SeriesModel.ts @@ -39,7 +39,7 @@ export class SeriesModel extends MediaTypeModel { } getFileName(): string { - return this.title; + return this.title + ' (' + this.year + ')'; } } diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 8b85f32..cc8a967 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -12,6 +12,8 @@ export interface MediaDbPluginSettings { movieTemplate: string, seriesTemplate: string, gameTemplate: string, + wikiTemplate: string, + musicReleaseTemplate: string, templates: boolean, } @@ -22,6 +24,8 @@ export const DEFAULT_SETTINGS: MediaDbPluginSettings = { movieTemplate: '', seriesTemplate: '', gameTemplate: '', + wikiTemplate: '', + musicReleaseTemplate: '', templates: true, }; @@ -103,6 +107,32 @@ export class MediaDbSettingTab extends PluginSettingTab { }); }); + new Setting(containerEl) + .setName('Wiki template') + .setDesc('Template file to be used when creating a new note for a wiki entry.') + .addSearch(cb => { + new FileSuggest(this.app, cb.inputEl); + cb.setPlaceholder('Example: wikiTemplate.md') + .setValue(this.plugin.settings.wikiTemplate) + .onChange(data => { + this.plugin.settings.wikiTemplate = data; + this.plugin.saveSettings(); + }); + }); + + new Setting(containerEl) + .setName('Music Release template') + .setDesc('Template file to be used when creating a new note for a music release.') + .addSearch(cb => { + new FileSuggest(this.app, cb.inputEl); + cb.setPlaceholder('Example: musicReleaseTemplate.md') + .setValue(this.plugin.settings.musicReleaseTemplate) + .onChange(data => { + this.plugin.settings.musicReleaseTemplate = data; + this.plugin.saveSettings(); + }); + }); + new Setting(containerEl) .setName('OMDb API key') .setDesc('API key for "www.omdbapi.com".') diff --git a/src/utils/Utils.ts b/src/utils/Utils.ts index aa385df..45b66c4 100644 --- a/src/utils/Utils.ts +++ b/src/utils/Utils.ts @@ -35,7 +35,7 @@ function replaceTag(match: string, mediaTypeModel: MediaTypeModel): string { let obj = traverseMetaData(path, mediaTypeModel); if (obj === undefined) { - return '{{ INVALID TEMPLATE TAG }}'; + return '{{ INVALID TEMPLATE TAG - object undefined }}'; } return obj; @@ -47,7 +47,7 @@ function replaceTag(match: string, mediaTypeModel: MediaTypeModel): string { let obj = traverseMetaData(path, mediaTypeModel); if (obj === undefined) { - return '{{ INVALID TEMPLATE TAG }}'; + return '{{ INVALID TEMPLATE TAG - object undefined }}'; } if (operator === 'LIST') { From 344c1ebf6c7e20696063ca73b4a6701e226ec7ea Mon Sep 17 00:00:00 2001 From: mProjectsCode Date: Wed, 18 May 2022 22:22:11 +0200 Subject: [PATCH 3/5] Tags --- src/api/apis/MusicBrainzAPI.ts | 5 +++-- src/models/GameModel.ts | 7 ++++++- src/models/MediaTypeModel.ts | 2 ++ src/models/MovieModel.ts | 7 ++++++- src/models/MusicReleaseModel.ts | 7 ++++++- src/models/SeriesModel.ts | 7 ++++++- src/models/WikiModel.ts | 7 ++++++- src/utils/Utils.ts | 4 ++++ 8 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/api/apis/MusicBrainzAPI.ts b/src/api/apis/MusicBrainzAPI.ts index 0cd899c..91f9d55 100644 --- a/src/api/apis/MusicBrainzAPI.ts +++ b/src/api/apis/MusicBrainzAPI.ts @@ -3,6 +3,7 @@ import {MediaTypeModel} from '../../models/MediaTypeModel'; import MediaDbPlugin from '../../main'; import {requestUrl} from 'obsidian'; import {MusicReleaseModel} from '../../models/MusicReleaseModel'; +import {contactEmail, pluginName} from '../../utils/Utils'; // import {MusicBrainzApi} from 'musicbrainz-api'; // WIP @@ -27,7 +28,7 @@ export class MusicBrainzAPI extends APIModel { const fetchData = await requestUrl({ url: searchUrl, headers: { - 'User-Agent': 'obsidian-media-db-plugin/0.1.7 ( m.projects.code@gmail.com )', + 'User-Agent': `${pluginName}/0.1.7 (${contactEmail})`, }, }); @@ -68,7 +69,7 @@ export class MusicBrainzAPI extends APIModel { const fetchData = await requestUrl({ url: searchUrl, headers: { - 'User-Agent': 'MyAwesomeTagger/1.2.0 ( me@example.com )', + 'User-Agent': `${pluginName}/0.1.7 (${contactEmail})`, }, }); diff --git a/src/models/GameModel.ts b/src/models/GameModel.ts index 7740bae..8a807ba 100644 --- a/src/models/GameModel.ts +++ b/src/models/GameModel.ts @@ -1,5 +1,6 @@ import {MediaTypeModel} from './MediaTypeModel'; import {stringifyYaml} from 'obsidian'; +import {mediaDbTag} from '../utils/Utils'; export class GameModel extends MediaTypeModel { @@ -29,11 +30,15 @@ export class GameModel extends MediaTypeModel { } toMetaData(): string { - return stringifyYaml(this); + return stringifyYaml({...this, tags: '#' + this.getTags().join('/')}); } getFileName(): string { return this.title + (this.year ? ` (${this.year})` : ''); } + getTags(): string[] { + return [mediaDbTag, 'game']; + } + } diff --git a/src/models/MediaTypeModel.ts b/src/models/MediaTypeModel.ts index 9f6c9f1..4963fb5 100644 --- a/src/models/MediaTypeModel.ts +++ b/src/models/MediaTypeModel.ts @@ -10,4 +10,6 @@ export abstract class MediaTypeModel { abstract toMetaData(): string; abstract getFileName(): string; + + abstract getTags(): string[]; } diff --git a/src/models/MovieModel.ts b/src/models/MovieModel.ts index 6b54613..e0ff845 100644 --- a/src/models/MovieModel.ts +++ b/src/models/MovieModel.ts @@ -1,5 +1,6 @@ import {MediaTypeModel} from './MediaTypeModel'; import {stringifyYaml} from 'obsidian'; +import {mediaDbTag} from '../utils/Utils'; export class MovieModel extends MediaTypeModel { @@ -32,11 +33,15 @@ export class MovieModel extends MediaTypeModel { } toMetaData(): string { - return stringifyYaml(this); + return stringifyYaml({...this, tags: '#' + this.getTags().join('/')}); } getFileName(): string { return this.title + (this.year ? ` (${this.year})` : ''); } + getTags(): string[] { + return [mediaDbTag, 'tv', 'movie']; + } + } diff --git a/src/models/MusicReleaseModel.ts b/src/models/MusicReleaseModel.ts index 46a2505..2561cf0 100644 --- a/src/models/MusicReleaseModel.ts +++ b/src/models/MusicReleaseModel.ts @@ -1,5 +1,6 @@ import {MediaTypeModel} from './MediaTypeModel'; import {stringifyYaml} from 'obsidian'; +import {mediaDbTag} from '../utils/Utils'; export class MusicReleaseModel extends MediaTypeModel { @@ -25,11 +26,15 @@ export class MusicReleaseModel extends MediaTypeModel { } toMetaData(): string { - return stringifyYaml(this); + return stringifyYaml({...this, tags: '#' + this.getTags().join('/')}); } getFileName(): string { return this.title + ' (' + this.artists.join(', ') + ' - ' + this.year + ' - ' + this.subType + ')'; } + getTags(): string[] { + return [mediaDbTag, 'music', 'album']; + } + } diff --git a/src/models/SeriesModel.ts b/src/models/SeriesModel.ts index 7fc4a17..205d51a 100644 --- a/src/models/SeriesModel.ts +++ b/src/models/SeriesModel.ts @@ -1,5 +1,6 @@ import {MediaTypeModel} from './MediaTypeModel'; import {stringifyYaml} from 'obsidian'; +import {mediaDbTag} from '../utils/Utils'; export class SeriesModel extends MediaTypeModel { @@ -35,11 +36,15 @@ export class SeriesModel extends MediaTypeModel { } toMetaData(): string { - return stringifyYaml(this); + return stringifyYaml({...this, tags: '#' + this.getTags().join('/')}); } getFileName(): string { return this.title + ' (' + this.year + ')'; } + getTags(): string[] { + return [mediaDbTag, 'tv', 'series']; + } + } diff --git a/src/models/WikiModel.ts b/src/models/WikiModel.ts index b97eac8..cf5dea5 100644 --- a/src/models/WikiModel.ts +++ b/src/models/WikiModel.ts @@ -1,5 +1,6 @@ import {MediaTypeModel} from './MediaTypeModel'; import {stringifyYaml} from 'obsidian'; +import {mediaDbTag} from '../utils/Utils'; export class WikiModel extends MediaTypeModel { @@ -23,11 +24,15 @@ export class WikiModel extends MediaTypeModel { } toMetaData(): string { - return stringifyYaml(this); + return stringifyYaml({...this, tags: '#' + this.getTags().join('/')}); } getFileName(): string { return this.title; } + getTags(): string[] { + return [mediaDbTag, 'wiki']; + } + } diff --git a/src/utils/Utils.ts b/src/utils/Utils.ts index 45b66c4..a9ee779 100644 --- a/src/utils/Utils.ts +++ b/src/utils/Utils.ts @@ -79,3 +79,7 @@ function traverseMetaData(path: Array, mediaTypeModel: MediaTypeModel): return o; } + +export const pluginName = 'obsidian-media-db-plugin'; +export const contactEmail = 'm.projects.code@gmail.com'; +export const mediaDbTag = 'mediaDB'; From a5d62ddc245d7528767753cbaf3b203b058e9082 Mon Sep 17 00:00:00 2001 From: mProjectsCode Date: Thu, 19 May 2022 10:38:11 +0200 Subject: [PATCH 4/5] changes for plugin submission review --- README.md | 93 +++++++++---------- manifest.json | 2 +- src/api/APIManager.ts | 14 +-- src/api/APIModel.ts | 1 + src/api/apis/LocGovAPI.ts | 111 +++-------------------- src/api/apis/MALAPI.ts | 16 ++-- src/api/apis/MusicBrainzAPI.ts | 28 +++--- src/api/apis/OMDbAPI.ts | 26 +++--- src/api/apis/WikipediaAPI.ts | 22 ++--- src/main.ts | 10 +- src/modals/MediaDbAdvancedSearchModal.ts | 12 +-- src/modals/MediaDbIdSearchModal.ts | 12 +-- src/utils/Utils.ts | 24 ++--- 13 files changed, 134 insertions(+), 237 deletions(-) diff --git a/README.md b/README.md index 033cbd8..0d0fd4b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## Obsidian Media DB Plugin -A plugin that can query multiple APIs for movies, series, anime and games, and import them into your vault. +A plugin that can query multiple APIs for movies, series, anime, games, music and wiki articles, and import them into your vault. ### Features #### Search by Title @@ -10,23 +10,23 @@ Search a movie, series, anime or game by its name across multiple APIs. Allows you to search by an ID that varies from API to API. Concrete info can be found in the description of the individual APIs. #### Templates -The plugin allows you to set a template note that gets added to the end of any note created by this plugin. -The plugin also offers simple "template tgs". E.g. if the template includes `{{ title }}`, it will be replaced by the title of the movie, show or game. +The plugin allows you to set a template note that gets added to the end of any note created by this plugin. +The plugin also offers simple "template tgs". E.g. if the template includes `{{ title }}`, it will be replaced by the title of the movie, show or game. Note that "template tags" are surrounded with two curly braces and that the spaces inside the curly braces are important. For arrays there are two special ways of displaying them. - using `{{ LIST:variable_name }}` will result in - ``` - - element 1 - - element 2 - - element 3 - - ... - ``` + ``` + - element 1 + - element 2 + - element 3 + - ... + ``` - using `{{ ENUM:variable_name }}` will result in - ``` - element 1, element 2, element 3, ... - ``` - + ``` + element 1, element 2, element 3, ... + ``` + I also published my own templates [here](https://github.com/mProjectsCode/obsidian-media-db-templates). @@ -34,48 +34,39 @@ I also published my own templates [here](https://github.com/mProjectsCode/obsidi - movies (including specials) - series (including OVAs) - games +- music releases +- wiki articles ### Currently supported APIs: -- [Jikan](https://jikan.moe/), an API that uses [My Anime List](https://myanimelist.net) - - supported formats - - series - - movies - - specials - - OVAs - - authentication - - no authentication or API key needed - - SFW filter support - - yes - - Search by ID - - the ID you need is the ID of the anime on [My Anime List](https://myanimelist.net) - - you can find this ID in the URL - - e.g. for "Beyond the Boundary" the URL looks like this `https://myanimelist.net/anime/18153/Kyoukai_no_Kanata` so the ID is `18153` - - notes - - sometimes the api is very slow, this is normal - - you need to use the title the anime has on [My Anime List](https://myanimelist.net), which is in most cases the japanese title - - e.g. instead of "Demon Slayer" you have to search "Kimetsu no Yaiba" - - the API is rate limited to - - 60 requests per minute - - 3 requests per second +| Name | Description | Supported formats | Authentification | Rate limiting | SFW filter support | +| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------ | ---------------------------------------------------------------------------- | ------------------------------ | ------------------ | +| [Jikan](https://jikan.moe/) | Jikan is an API that uses [My Anime List](https://myanimelist.net) and offers metadata for anime. | series, movies, specials, OVAs | No | 60 per minute and 3 per second | Yes | +| [OMDb](https://www.omdbapi.com/) | OMDb is an API that offers metadata for movie, series and games. | series, movies, games | Yes, you can get a free key here [here](https://www.omdbapi.com/apikey.aspx) | 1000 per day | No | +| [MusicBrainz](https://musicbrainz.org/) | MusicBrainz is an API that offers information about music releases. | music releases | No | 50 per second | No | +| [Wikipedia](https://en.wikipedia.org/wiki/Main_Page) | The Wikipedia API allows acces to all Wikipedia articles. | wiki articles | No | None | No | | | | | | | + +#### Notes +- [Jikan](https://jikan.moe/) + - sometimes the api is very slow, this is normal + - you need to use the title the anime has on [My Anime List](https://myanimelist.net), which is in most cases the japanese title + - e.g. instead of "Demon Slayer" you have to search "Kimetsu no Yaiba" + +#### Search by ID +- [Jikan](https://jikan.moe/) + - the ID you need is the ID of the anime on [My Anime List](https://myanimelist.net) + - you can find this ID in the URL + - e.g. for "Beyond the Boundary" the URL looks like this `https://myanimelist.net/anime/18153/Kyoukai_no_Kanata` so the ID is `18153` - [OMDb](https://www.omdbapi.com/) - - supported formats - - series - - movies - - games - - authentication - - an API key is needed - - you can get one [here](https://www.omdbapi.com/apikey.aspx) for free - - SFW filter support - - no, but I haven't encountered any NSFW content while developing this plugin - - Search by ID - - the ID you need is the ID of the movie or show on [IMDb](https://www.imdb.com) - - you can find this ID in the URL - - e.g. for "Rogue One" the URL looks like this `https://www.imdb.com/title/tt3748528/` so the ID is `tt3748528` - - notes - - the api is rate limited to 1000 requests a day - + - the ID you need is the ID of the movie or show on [IMDb](https://www.imdb.com) + - you can find this ID in the URL + - e.g. for "Rogue One" the URL looks like this `https://www.imdb.com/title/tt3748528/` so the ID is `tt3748528` +- [MusicBrainz](https://musicbrainz.org/) + - the id of a release is not easyly accessibe, you are better of just searching by title +- [Wikipedia](https://en.wikipedia.org/wiki/Main_Page) + - [here](https://en.wikipedia.org/wiki/Wikipedia:Finding_a_Wikidata_ID) is a guide to finding the Wikipedia ID for an article + ### Contributions -Thank you for wanting to contribute to this project. +Thank you for wanting to contribute to this project. Contributions are always welcome. If you have an idea, feel free to open a feature request under the issue tab or even create a pull request. diff --git a/manifest.json b/manifest.json index d860fef..24fc679 100644 --- a/manifest.json +++ b/manifest.json @@ -3,7 +3,7 @@ "name": "Media DB Plugin", "version": "0.1.7", "minAppVersion": "0.14.0", - "description": "A plugin that can query multiple APIs for movies, series, anime and games, and import them into your vault.", + "description": "A plugin that can query multiple APIs for movies, series, anime, games, music and wiki articles, and import them into your vault. ", "author": "Moritz Jung", "authorUrl": "https://mprojectscode.github.io/", "isDesktopOnly": false diff --git a/src/api/APIManager.ts b/src/api/APIManager.ts index 665e8a2..c20c677 100644 --- a/src/api/APIManager.ts +++ b/src/api/APIManager.ts @@ -1,5 +1,6 @@ import {APIModel} from './APIModel'; import {MediaTypeModel} from '../models/MediaTypeModel'; +import {debugLog} from '../utils/Utils'; export class APIManager { apis: APIModel[]; @@ -9,28 +10,17 @@ export class APIManager { } async query(query: string, apisToQuery: any): Promise { - console.log('MDB | api manager queried'); + debugLog(`MDB | api manager queried with "${query}"`); let res: MediaTypeModel[] = []; for (const api of this.apis) { if (Object.keys(apisToQuery).contains(api.apiName) && apisToQuery[api.apiName]) { const apiRes = await api.searchByTitle(query); - // console.log(apiRes); res = res.concat(apiRes); } } - /* - for (const api of this.apis) { - if (types.length === 0 || api.hasTypeOverlap(types)) { - const apiRes = await api.searchByTitle(query); - // console.log(apiRes); - res = res.concat(apiRes); - } - } - */ - return res; } diff --git a/src/api/APIModel.ts b/src/api/APIModel.ts index 4d042c8..0cbf5fa 100644 --- a/src/api/APIModel.ts +++ b/src/api/APIModel.ts @@ -19,6 +19,7 @@ export abstract class APIModel { return this.types.contains(type); } + // for future use (https://github.com/mProjectsCode/obsidian-media-db-plugin/issues/5) hasTypeOverlap(types: string[]): boolean { for (const type of types) { if (this.hasType(type)) { diff --git a/src/api/apis/LocGovAPI.ts b/src/api/apis/LocGovAPI.ts index 9788bb4..fd0b2d5 100644 --- a/src/api/apis/LocGovAPI.ts +++ b/src/api/apis/LocGovAPI.ts @@ -1,6 +1,7 @@ import {APIModel} from '../APIModel'; import {MediaTypeModel} from '../../models/MediaTypeModel'; import MediaDbPlugin from '../../main'; +import {debugLog} from '../../utils/Utils'; // WIP export class LocGovAPI extends APIModel { @@ -20,63 +21,36 @@ export class LocGovAPI extends APIModel { } async searchByTitle(title: string): Promise { - console.log(`MDB | api "${this.apiName}" queried`); + console.log(`MDB | api "${this.apiName}" queried by Title`); const searchUrl = `https://www.loc.gov/search/?q=${encodeURIComponent(title)}&fo=json&c=20`; - const fetchData = await fetch(searchUrl); - console.log(fetchData); + debugLog(fetchData); + if (fetchData.status !== 200) { - throw Error(`Received status code ${fetchData.status} from an API.`); + throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } - const data = await fetchData.json(); - - console.log(data); + const data = await fetchData.json(); + debugLog(data); let ret: MediaTypeModel[] = []; - /* - for (const result of data.data) { - const type = this.typeMappings.get(result.type.toLowerCase()); - if (type === undefined) { - continue; - } - if (type === 'movie' || type === 'special') { - ret.push(new MovieModel({ - type: type, - title: result.title, - englishTitle: result.title_english ?? result.title, - year: result.year ?? result.aired?.prop?.from?.year ?? '', - dataSource: this.apiName, - id: result.mal_id, - } as MovieModel)); - } else if (type === 'series' || type === 'ova') { - ret.push(new SeriesModel({ - type: type, - title: result.title, - englishTitle: result.title_english ?? result.title, - year: result.year ?? result.aired?.prop?.from?.year ?? '', - dataSource: this.apiName, - id: result.mal_id, - } as SeriesModel)); - } - } - */ + throw new Error('MDB | Under construction, API implementation not finished'); - return ret; + // return ret; } async getById(item: MediaTypeModel): Promise { + console.log(`MDB | api "${this.apiName}" queried by ID`); - const searchUrl = `https://www.loc.gov/item/{item.id}/?fo=json`; - + const searchUrl = `https://www.loc.gov/item/${item.id}/?fo=json`; const fetchData = await fetch(searchUrl); if (fetchData.status !== 200) { - throw Error(`Received status code ${fetchData.status} from an API.`); + throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } const data = await fetchData.json(); - console.log(data); + debugLog(data); const result = data.data; const type = this.typeMappings.get(result.type.toLowerCase()); @@ -84,63 +58,8 @@ export class LocGovAPI extends APIModel { throw Error(`${result.type.toLowerCase()} is an unsupported type.`); } - /* - if (type === 'movie' || type === 'special') { - const model = new MovieModel({ - type: type, - title: result.title, - englishTitle: result.title_english ?? result.title, - year: result.year ?? result.aired?.prop?.from?.year ?? '', - dataSource: this.apiName, - url: result.url, - id: result.mal_id, - - genres: result.genres?.map((x: any) => x.name) ?? [], - producer: result.studios?.map((x: any) => x.name).join(', ') ?? 'unknown', - duration: result.duration ?? 'unknown', - onlineRating: result.score ?? 0, - image: result.images?.jpg?.image_url ?? '', - - released: true, - premiere: (new Date(result.aired?.from)).toLocaleDateString() ?? 'unknown', - - watched: false, - lastWatched: '', - personalRating: 0, - } as MovieModel); - - return model; - } else if (type === 'series' || type === 'ova') { - const model = new SeriesModel({ - type: type, - title: result.title, - englishTitle: result.title_english ?? result.title, - year: result.year ?? result.aired?.prop?.from?.year ?? '', - dataSource: this.apiName, - url: result.url, - id: result.mal_id, - - genres: result.genres?.map((x: any) => x.name) ?? [], - studios: result.studios?.map((x: any) => x.name) ?? [], - episodes: result.episodes, - duration: result.duration ?? 'unknown', - onlineRating: result.score ?? 0, - image: result.images?.jpg?.image_url ?? '', - - released: true, - airedFrom: (new Date(result.aired?.from)).toLocaleDateString() ?? 'unknown', - airedTo: (new Date(result.aired?.to)).toLocaleDateString() ?? 'unknown', - airing: result.airing, - - watched: false, - lastWatched: '', - personalRating: 0, - } as SeriesModel); - - return model; - } - */ + throw new Error('MDB | Under construction, API implementation not finished'); - return; + // return; } } diff --git a/src/api/apis/MALAPI.ts b/src/api/apis/MALAPI.ts index 48cc850..67c5790 100644 --- a/src/api/apis/MALAPI.ts +++ b/src/api/apis/MALAPI.ts @@ -3,6 +3,7 @@ import {MediaTypeModel} from '../../models/MediaTypeModel'; import {MovieModel} from '../../models/MovieModel'; import MediaDbPlugin from '../../main'; import {SeriesModel} from '../../models/SeriesModel'; +import {debugLog} from '../../utils/Utils'; export class MALAPI extends APIModel { plugin: MediaDbPlugin; @@ -24,18 +25,18 @@ export class MALAPI extends APIModel { } async searchByTitle(title: string): Promise { - console.log(`MDB | api "${this.apiName}" queried`); + console.log(`MDB | api "${this.apiName}" queried by Title`); const searchUrl = `https://api.jikan.moe/v4/anime?q=${encodeURIComponent(title)}&limit=20${this.plugin.settings.sfwFilter ? '&sfw' : ''}`; const fetchData = await fetch(searchUrl); - console.log(fetchData); + debugLog(fetchData); if (fetchData.status !== 200) { - throw Error(`Received status code ${fetchData.status} from an API.`); + throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } const data = await fetchData.json(); - console.log(data); + debugLog(data); let ret: MediaTypeModel[] = []; @@ -69,16 +70,17 @@ export class MALAPI extends APIModel { } async getById(item: MediaTypeModel): Promise { + console.log(`MDB | api "${this.apiName}" queried by ID`); const searchUrl = `https://api.jikan.moe/v4/anime/${item.id}`; - const fetchData = await fetch(searchUrl); + if (fetchData.status !== 200) { - throw Error(`Received status code ${fetchData.status} from an API.`); + throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } const data = await fetchData.json(); - console.log(data); + debugLog(data); const result = data.data; const type = this.typeMappings.get(result.type.toLowerCase()); diff --git a/src/api/apis/MusicBrainzAPI.ts b/src/api/apis/MusicBrainzAPI.ts index 91f9d55..87ea855 100644 --- a/src/api/apis/MusicBrainzAPI.ts +++ b/src/api/apis/MusicBrainzAPI.ts @@ -3,10 +3,8 @@ import {MediaTypeModel} from '../../models/MediaTypeModel'; import MediaDbPlugin from '../../main'; import {requestUrl} from 'obsidian'; import {MusicReleaseModel} from '../../models/MusicReleaseModel'; -import {contactEmail, pluginName} from '../../utils/Utils'; -// import {MusicBrainzApi} from 'musicbrainz-api'; +import {contactEmail, debugLog, mediaDbVersion, pluginName} from '../../utils/Utils'; -// WIP export class MusicBrainzAPI extends APIModel { plugin: MediaDbPlugin; @@ -21,26 +19,25 @@ export class MusicBrainzAPI extends APIModel { } async searchByTitle(title: string): Promise { - console.log(`MDB | api "${this.apiName}" queried`); + console.log(`MDB | api "${this.apiName}" queried by Title`); const searchUrl = `https://musicbrainz.org/ws/2/release-group?query=${encodeURIComponent(title)}&limit=20&fmt=json`; const fetchData = await requestUrl({ url: searchUrl, headers: { - 'User-Agent': `${pluginName}/0.1.7 (${contactEmail})`, + 'User-Agent': `${pluginName}/${mediaDbVersion} (${contactEmail})`, }, }); - console.log(fetchData); + debugLog(fetchData); if (fetchData.status !== 200) { - throw Error(`Received status code ${fetchData.status} from an API.`); + throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } - const data = await fetchData.json; - - console.log(data); + const data = await fetchData.json; + debugLog(data); let ret: MediaTypeModel[] = []; for (const result of data['release-groups']) { @@ -62,10 +59,9 @@ export class MusicBrainzAPI extends APIModel { } async getById(item: MediaTypeModel): Promise { - console.log(`MDB | api "${this.apiName}" queried`); + console.log(`MDB | api "${this.apiName}" queried by ID`); const searchUrl = `https://musicbrainz.org/ws/2/release-group/${encodeURIComponent(item.id)}?inc=releases+artists+tags+ratings+genres&fmt=json`; - const fetchData = await requestUrl({ url: searchUrl, headers: { @@ -73,10 +69,12 @@ export class MusicBrainzAPI extends APIModel { }, }); - const data = await fetchData.json; - - console.log(data); + if (fetchData.status !== 200) { + throw Error(`MDB | Received status code ${fetchData.status} from an API.`); + } + const data = await fetchData.json; + debugLog(data); const result = data; const model = new MusicReleaseModel({ diff --git a/src/api/apis/OMDbAPI.ts b/src/api/apis/OMDbAPI.ts index d5797f4..4ae38f4 100644 --- a/src/api/apis/OMDbAPI.ts +++ b/src/api/apis/OMDbAPI.ts @@ -4,6 +4,7 @@ import {MovieModel} from '../../models/MovieModel'; import MediaDbPlugin from '../../main'; import {SeriesModel} from '../../models/SeriesModel'; import {GameModel} from '../../models/GameModel'; +import {debugLog} from '../../utils/Utils'; export class OMDbAPI extends APIModel { plugin: MediaDbPlugin; @@ -24,29 +25,28 @@ export class OMDbAPI extends APIModel { } async searchByTitle(title: string): Promise { - console.log(`MDB | api "${this.apiName}" queried`); + console.log(`MDB | api "${this.apiName}" queried by Title`); const searchUrl = `http://www.omdbapi.com/?s=${encodeURIComponent(title)}&apikey=${this.plugin.settings.OMDbKey}`; - const fetchData = await fetch(searchUrl); if (fetchData.status === 401) { - throw Error(`Authentication for ${this.apiName} failed. Check the API key.`); + throw Error(`MDB | Authentication for ${this.apiName} failed. Check the API key.`); } if (fetchData.status !== 200) { - throw Error(`Received status code ${fetchData.status} from an API.`); + throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } + const data = await fetchData.json(); if (data.Response === 'False') { - throw Error(`Received error from ${this.apiName}: ${data.Error}`); + throw Error(`MDB | Received error from ${this.apiName}: ${data.Error}`); } - if (!data.Search) { return []; } - console.log(data.Search); + debugLog(data.Search); let ret: MediaTypeModel[] = []; @@ -89,23 +89,23 @@ export class OMDbAPI extends APIModel { } async getById(item: MediaTypeModel): Promise { + console.log(`MDB | api "${this.apiName}" queried by ID`); const searchUrl = `http://www.omdbapi.com/?i=${item.id}&apikey=${this.plugin.settings.OMDbKey}`; - const fetchData = await fetch(searchUrl); + if (fetchData.status === 401) { - throw Error(`Authentication for ${this.apiName} failed. Check the API key.`); + throw Error(`MDB | Authentication for ${this.apiName} failed. Check the API key.`); } if (fetchData.status !== 200) { - throw Error(`Received status code ${fetchData.status} from an API.`); + throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } const result = await fetchData.json(); - - console.log(result); + debugLog(result); if (result.Response === 'False') { - throw Error(`Received error from ${this.apiName}: ${result.Error}`); + throw Error(`MDB | Received error from ${this.apiName}: ${result.Error}`); } const type = this.typeMappings.get(result.Type.toLowerCase()); diff --git a/src/api/apis/WikipediaAPI.ts b/src/api/apis/WikipediaAPI.ts index db17d40..1387b65 100644 --- a/src/api/apis/WikipediaAPI.ts +++ b/src/api/apis/WikipediaAPI.ts @@ -2,6 +2,7 @@ import {APIModel} from '../APIModel'; import {MediaTypeModel} from '../../models/MediaTypeModel'; import MediaDbPlugin from '../../main'; import {WikiModel} from '../../models/WikiModel'; +import {debugLog} from '../../utils/Utils'; export class WikipediaAPI extends APIModel { plugin: MediaDbPlugin; @@ -17,22 +18,20 @@ export class WikipediaAPI extends APIModel { } async searchByTitle(title: string): Promise { - console.log(`MDB | api "${this.apiName}" queried`); + console.log(`MDB | api "${this.apiName}" queried by Title`); const searchUrl = `https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=${encodeURIComponent(title)}&srlimit=20&utf8=&format=json&origin=*`; - const fetchData = await fetch(searchUrl); - console.log(fetchData); + debugLog(fetchData); + if (fetchData.status !== 200) { - throw Error(`Received status code ${fetchData.status} from an API.`); + throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } - const data = await fetchData.json(); - - console.log(data); + const data = await fetchData.json(); + debugLog(data); let ret: MediaTypeModel[] = []; - for (const result of data.query.search) { ret.push(new WikiModel({ type: 'wiki', @@ -48,16 +47,17 @@ export class WikipediaAPI extends APIModel { } async getById(item: MediaTypeModel): Promise { + console.log(`MDB | api "${this.apiName}" queried by ID`); const searchUrl = `https://en.wikipedia.org/w/api.php?action=query&prop=info&pageids=${item.id}&inprop=url&format=json&origin=*`; - const fetchData = await fetch(searchUrl); + if (fetchData.status !== 200) { - throw Error(`Received status code ${fetchData.status} from an API.`); + throw Error(`MDB | Received status code ${fetchData.status} from an API.`); } const data = await fetchData.json(); - console.log(data); + debugLog(data); const result = Object.entries(data?.query?.pages)[0][1]; const model = new WikiModel({ diff --git a/src/main.ts b/src/main.ts index 0a8ab3a..69c713b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -57,9 +57,7 @@ export default class MediaDbPlugin extends Plugin { data = await this.apiManager.queryDetailedInfo(data); - console.log(data); - - data.toMetaData(); + // console.log(data); let fileContent = `---\n${data.toMetaData()}---\n`; @@ -78,7 +76,7 @@ export default class MediaDbPlugin extends Plugin { } if (templateFile) { - let template = await this.app.vault.read(templateFile); + let template = await this.app.vault.cachedRead(templateFile); // console.log(template); if (this.settings.templates) { template = replaceTags(template, data); @@ -91,9 +89,9 @@ export default class MediaDbPlugin extends Plugin { const targetFile = await this.app.vault.create(filePath, fileContent); // open file - const activeLeaf = this.app.workspace.getLeaf(); + const activeLeaf = this.app.workspace.getUnpinnedLeaf(); if (!activeLeaf) { - console.warn('No active leaf'); + console.warn('MDB | no active leaf, not opening media db note'); return; } await activeLeaf.openFile(targetFile, {state: {mode: 'source'}}); diff --git a/src/modals/MediaDbAdvancedSearchModal.ts b/src/modals/MediaDbAdvancedSearchModal.ts index 0664620..1472f7d 100644 --- a/src/modals/MediaDbAdvancedSearchModal.ts +++ b/src/modals/MediaDbAdvancedSearchModal.ts @@ -1,6 +1,7 @@ import {App, ButtonComponent, Component, Modal, Notice, Setting, TextComponent, ToggleComponent} from 'obsidian'; import {MediaTypeModel} from '../models/MediaTypeModel'; import {APIManager} from '../api/APIManager'; +import {debugLog} from '../utils/Utils'; export class MediaDbAdvancedSearchModal extends Modal { query: string; @@ -28,10 +29,10 @@ export class MediaDbAdvancedSearchModal extends Modal { async search(): Promise { - console.log(this.selectedApis); + debugLog(this.selectedApis); if (!this.query || this.query.length < 3) { - new Notice('MDB: Query to short'); + new Notice('MDB | Query to short'); return; } @@ -43,7 +44,7 @@ export class MediaDbAdvancedSearchModal extends Modal { } if (selectedAPICount === 0) { - new Notice('MDB: No API selected'); + new Notice('MDB | No API selected'); return; } @@ -53,12 +54,9 @@ export class MediaDbAdvancedSearchModal extends Modal { this.searchBtn.setDisabled(false); this.searchBtn.setButtonText('Searching...'); - console.log('MDB | query started with ' + this.query); + console.log(`MDB | query started with title ${this.query}`); const res = await this.apiManager.query(this.query, this.selectedApis); - - // console.log(res) - this.onSubmit(null, res); } catch (e) { this.onSubmit(e); diff --git a/src/modals/MediaDbIdSearchModal.ts b/src/modals/MediaDbIdSearchModal.ts index bf7b5ce..0216746 100644 --- a/src/modals/MediaDbIdSearchModal.ts +++ b/src/modals/MediaDbIdSearchModal.ts @@ -1,6 +1,7 @@ import {App, ButtonComponent, DropdownComponent, Modal, Notice, Setting, TextComponent} from 'obsidian'; import {MediaTypeModel} from '../models/MediaTypeModel'; import {APIManager} from '../api/APIManager'; +import {debugLog} from '../utils/Utils'; export class MediaDbIdSearchModal extends Modal { query: string; @@ -25,15 +26,15 @@ export class MediaDbIdSearchModal extends Modal { async search(): Promise { - console.log(this.selectedApi); + debugLog(this.selectedApi); if (!this.query) { - new Notice('MDB: no Id entered'); + new Notice('MDB | no Id entered'); return; } if (!this.selectedApi) { - new Notice('MDB: No API selected'); + new Notice('MDB | No API selected'); return; } @@ -43,16 +44,13 @@ export class MediaDbIdSearchModal extends Modal { this.searchBtn.setDisabled(false); this.searchBtn.setButtonText('Searching...'); - console.log('MDB | query started with id ' + this.query); + console.log(`MDB | query started with id ${this.query}`); const api = this.apiManager.getApiByName(this.selectedApi); if (!api) { this.onSubmit(new Error('the selected api does not exist')); } const res = await api.getById({id: this.query} as MediaTypeModel); // TODO: fix jank - - // console.log(res) - this.onSubmit(null, res); } catch (e) { this.onSubmit(e); diff --git a/src/utils/Utils.ts b/src/utils/Utils.ts index a9ee779..c62eb17 100644 --- a/src/utils/Utils.ts +++ b/src/utils/Utils.ts @@ -1,18 +1,24 @@ import {MediaTypeModel} from '../models/MediaTypeModel'; + +export const pluginName: string = 'obsidian-media-db-plugin'; +export const contactEmail: string = 'm.projects.code@gmail.com'; +export const mediaDbTag: string = 'mediaDB'; +export const mediaDbVersion: string = '0.1.7'; +export const debug: boolean = false; + + export function wrapAround(value: number, size: number): number { return ((value % size) + size) % size; } -export function sleep(ms: number) { - return new Promise(resolve => setTimeout(resolve, ms)); -} - -export function getFileName(item: MediaTypeModel) { - return replaceIllegalFileNameCharactersInString(item.year ? `${item.title} (${item.year})` : `${item.title}`); +export function debugLog(o: any): void { + if (debug) { + console.log(o); + } } -export function replaceIllegalFileNameCharactersInString(string: string) { +export function replaceIllegalFileNameCharactersInString(string: string): string { return string.replace(/[\\,#%&{}/*<>$"@.?]*/g, '').replace(/:+/g, ' -'); } @@ -79,7 +85,3 @@ function traverseMetaData(path: Array, mediaTypeModel: MediaTypeModel): return o; } - -export const pluginName = 'obsidian-media-db-plugin'; -export const contactEmail = 'm.projects.code@gmail.com'; -export const mediaDbTag = 'mediaDB'; From 41ca7910902f9724e2d1d52d9f7145039d6390b2 Mon Sep 17 00:00:00 2001 From: mProjectsCode Date: Thu, 19 May 2022 10:38:44 +0200 Subject: [PATCH 5/5] bump version number --- manifest.json | 2 +- src/utils/Utils.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/manifest.json b/manifest.json index 24fc679..86d0d3f 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "obsidian-media-db-plugin", "name": "Media DB Plugin", - "version": "0.1.7", + "version": "0.1.8", "minAppVersion": "0.14.0", "description": "A plugin that can query multiple APIs for movies, series, anime, games, music and wiki articles, and import them into your vault. ", "author": "Moritz Jung", diff --git a/src/utils/Utils.ts b/src/utils/Utils.ts index c62eb17..12927db 100644 --- a/src/utils/Utils.ts +++ b/src/utils/Utils.ts @@ -4,7 +4,7 @@ import {MediaTypeModel} from '../models/MediaTypeModel'; export const pluginName: string = 'obsidian-media-db-plugin'; export const contactEmail: string = 'm.projects.code@gmail.com'; export const mediaDbTag: string = 'mediaDB'; -export const mediaDbVersion: string = '0.1.7'; +export const mediaDbVersion: string = '0.1.8'; export const debug: boolean = false;