From 3befc82b8771e05dd4732dd50a4fb4b7dae00509 Mon Sep 17 00:00:00 2001 From: ltctceplrm <14954927+ltctceplrm@users.noreply.github.com> Date: Tue, 11 Feb 2025 15:45:20 +0100 Subject: [PATCH 01/11] Added comic book support - Created a new model for comic books - Added comic vine support --- src/api/apis/ComicVineAPI.ts | 97 +++++++++++++++++++++++++++++++++++ src/main.ts | 2 + src/models/ComicBookModel.ts | 67 ++++++++++++++++++++++++ src/utils/MediaType.ts | 1 + src/utils/MediaTypeManager.ts | 7 +++ 5 files changed, 174 insertions(+) create mode 100644 src/api/apis/ComicVineAPI.ts create mode 100644 src/models/ComicBookModel.ts diff --git a/src/api/apis/ComicVineAPI.ts b/src/api/apis/ComicVineAPI.ts new file mode 100644 index 0000000..02cfffc --- /dev/null +++ b/src/api/apis/ComicVineAPI.ts @@ -0,0 +1,97 @@ +import { requestUrl } from 'obsidian'; +import { ComicBookModel } from 'src/models/ComicBookModel'; +import type MediaDbPlugin from '../../main'; +import type { MediaTypeModel } from '../../models/MediaTypeModel'; +import { MediaType } from '../../utils/MediaType'; +import { APIModel } from '../APIModel'; + +export class ComicVineAPI extends APIModel { + plugin: MediaDbPlugin; + + constructor(plugin: MediaDbPlugin) { + super(); + + this.plugin = plugin; + this.apiName = 'ComicVineAPI'; + this.apiDescription = 'A free API for comic books.'; + this.apiUrl = 'https://comicvine.gamespot.com/api'; + this.types = [MediaType.ComicBook]; + } + + async searchByTitle(title: string): Promise { + console.log(`MDB | api "${this.apiName}" queried by Title`); + + const searchUrl = `${this.apiUrl}/search/?api_key=${this.plugin.settings.ComicVineKey}&format=json&resources=volume&query=${encodeURIComponent(title)}`; + const fetchData = await requestUrl({ + url: searchUrl, + }); + // console.debug(fetchData); + if (fetchData.status !== 200) { + throw Error(`MDB | Received status code ${fetchData.status} from ${this.apiName}.`); + } + + const data = await fetchData.json; + // console.debug(data); + const ret: MediaTypeModel[] = []; + for (const result of data.results) { + ret.push( + new ComicBookModel({ + title: result.name, + englishTitle: result.name, + year: result.start_year, + dataSource: this.apiName, + id: result.id, + publisher: result.publisher.name ?? 'unknown', + }), + ); + } + + return ret; + } + + async getById(id: string): Promise { + console.log(`MDB | api "${this.apiName}" queried by ID`); + + const searchUrl = `${this.apiUrl}/volume/4050-${encodeURIComponent(id)}/?api_key=${this.plugin.settings.ComicVineKey}&format=json`; + const fetchData = await requestUrl({ + url: searchUrl, + }); + + console.debug(fetchData); + + if (fetchData.status !== 200) { + throw Error(`MDB | Received status code ${fetchData.status} from ${this.apiName}.`); + } + + const data = await fetchData.json; + // console.debug(data); + const result = data.results; + + return new ComicBookModel({ + type: MediaType.ComicBook, + title: result.name, + plot: result.deck, + year: result.start_year ?? '', + dataSource: this.apiName, + url: result.site_detail_url, + id: result.id, + + creators: result.people?.map((x: any) => x.name) ?? [], + issues: result.count_of_issues, + onlineRating: result.score ?? 0, + image: result.image?.original_url ?? '', + + released: true, + publisher: result.publisher.name ?? '', + publishedFrom: result.start_year ?? 'unknown', + publishedTo: 'unknown', + status: result.status, + + userData: { + read: false, + lastRead: '', + personalRating: 0, + }, + }); + } +} diff --git a/src/main.ts b/src/main.ts index 625a1ed..a6b5b2f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -11,6 +11,7 @@ import { OMDbAPI } from './api/apis/OMDbAPI'; import { OpenLibraryAPI } from './api/apis/OpenLibraryAPI'; import { SteamAPI } from './api/apis/SteamAPI'; import { WikipediaAPI } from './api/apis/WikipediaAPI'; +import { ComicVineAPI } from './api/apis/ComicVineAPI'; import { MediaDbFolderImportModal } from './modals/MediaDbFolderImportModal'; import type { MediaTypeModel } from './models/MediaTypeModel'; import { PropertyMapper } from './settings/PropertyMapper'; @@ -53,6 +54,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 ComicVineAPI(this)); this.apiManager.registerAPI(new MobyGamesAPI(this)); this.apiManager.registerAPI(new GiantBombAPI(this)); // this.apiManager.registerAPI(new LocGovAPI(this)); // TODO: parse data diff --git a/src/models/ComicBookModel.ts b/src/models/ComicBookModel.ts new file mode 100644 index 0000000..a3990df --- /dev/null +++ b/src/models/ComicBookModel.ts @@ -0,0 +1,67 @@ +import { MediaType } from '../utils/MediaType'; +import type { ModelToData } from '../utils/Utils'; +import { mediaDbTag, migrateObject } from '../utils/Utils'; +import { MediaTypeModel } from './MediaTypeModel'; + +export type ComicBookData = ModelToData; + +export class ComicBookModel extends MediaTypeModel { + creators: string[]; + publisher: string; + plot: string; + issues: number; + image: string; + onlineRating: number; + status: string; + released: boolean; + publishedFrom: string; + publishedTo: string; + + userData: { + read: boolean; + lastRead: string; + personalRating: number; + }; + + constructor(obj: ComicBookData) { + super(); + + this.creators = []; + this.publisher = ''; + this.plot = ''; + this.issues = 0; + this.image = ''; + this.onlineRating = 0; + + this.released = false; + this.status = ''; + this.publishedFrom = ''; + this.publishedTo = ''; + + this.userData = { + read: false, + lastRead: '', + personalRating: 0, + }; + + migrateObject(this, obj, this); + + if (!obj.hasOwnProperty('userData')) { + migrateObject(this.userData, obj, this.userData); + } + + this.type = this.getMediaType(); + } + + getTags(): string[] { + return [mediaDbTag, 'comicbook']; + } + + getMediaType(): MediaType { + return MediaType.ComicBook; + } + + getSummary(): string { + return this.englishTitle + ' (' + this.year + ') - ' + this.publisher; + } +} diff --git a/src/utils/MediaType.ts b/src/utils/MediaType.ts index dd39945..8844e11 100644 --- a/src/utils/MediaType.ts +++ b/src/utils/MediaType.ts @@ -7,4 +7,5 @@ export enum MediaType { Wiki = 'wiki', BoardGame = 'boardgame', Book = 'book', + ComicBook = 'comicBook', } diff --git a/src/utils/MediaTypeManager.ts b/src/utils/MediaTypeManager.ts index 531da63..8eee245 100644 --- a/src/utils/MediaTypeManager.ts +++ b/src/utils/MediaTypeManager.ts @@ -4,6 +4,7 @@ import { BoardGameModel } from '../models/BoardGameModel'; import { BookModel } from '../models/BookModel'; import { GameModel } from '../models/GameModel'; import { MangaModel } from '../models/MangaModel'; +import { ComicBookModel } from '../models/ComicBookModel'; import type { MediaTypeModel } from '../models/MediaTypeModel'; import { MovieModel } from '../models/MovieModel'; import { MusicReleaseModel } from '../models/MusicReleaseModel'; @@ -22,6 +23,7 @@ export const MEDIA_TYPES: MediaType[] = [ MediaType.MusicRelease, MediaType.BoardGame, MediaType.Book, + MediaType.ComicBook, ]; export class MediaTypeManager { @@ -45,6 +47,7 @@ export class MediaTypeManager { this.mediaFileNameTemplateMap.set(MediaType.MusicRelease, settings.musicReleaseFileNameTemplate); this.mediaFileNameTemplateMap.set(MediaType.BoardGame, settings.boardgameFileNameTemplate); this.mediaFileNameTemplateMap.set(MediaType.Book, settings.bookFileNameTemplate); + this.mediaFileNameTemplateMap.set(MediaType.ComicBook, settings.bookFileNameTemplate); this.mediaTemplateMap = new Map(); this.mediaTemplateMap.set(MediaType.Movie, settings.movieTemplate); @@ -55,6 +58,7 @@ export class MediaTypeManager { this.mediaTemplateMap.set(MediaType.MusicRelease, settings.musicReleaseTemplate); this.mediaTemplateMap.set(MediaType.BoardGame, settings.boardgameTemplate); this.mediaTemplateMap.set(MediaType.Book, settings.bookTemplate); + this.mediaTemplateMap.set(MediaType.ComicBook, settings.bookTemplate); } updateFolders(settings: MediaDbPluginSettings): void { @@ -67,6 +71,7 @@ export class MediaTypeManager { this.mediaFolderMap.set(MediaType.MusicRelease, settings.musicReleaseFolder); this.mediaFolderMap.set(MediaType.BoardGame, settings.boardgameFolder); this.mediaFolderMap.set(MediaType.Book, settings.bookFolder); + this.mediaFolderMap.set(MediaType.ComicBook, settings.bookFolder); } getFileName(mediaTypeModel: MediaTypeModel): string { @@ -144,6 +149,8 @@ export class MediaTypeManager { return new BoardGameModel(obj); } else if (mediaType === MediaType.Book) { return new BookModel(obj); + } else if (mediaType === MediaType.ComicBook) { + return new ComicBookModel(obj); } throw new Error(`Unknown media type: ${mediaType}`); From c80af49f9db823acdd130a29fdf2b3e6026e7b82 Mon Sep 17 00:00:00 2001 From: ltctceplrm <14954927+ltctceplrm@users.noreply.github.com> Date: Tue, 11 Feb 2025 15:49:35 +0100 Subject: [PATCH 02/11] Modified settings.ts to support comics --- src/settings/Settings.ts | 68 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index f30b153..ec9e27f 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -14,6 +14,7 @@ export interface MediaDbPluginSettings { OMDbKey: string; MobyGamesKey: string; GiantBombKey: string; + ComicVineKey: string; sfwFilter: boolean; templates: boolean; customDateFormat: string; @@ -46,6 +47,7 @@ export interface MediaDbPluginSettings { musicReleaseTemplate: string; boardgameTemplate: string; bookTemplate: string; + comicbookTemplate: string; movieFileNameTemplate: string; seriesFileNameTemplate: string; @@ -55,6 +57,7 @@ export interface MediaDbPluginSettings { musicReleaseFileNameTemplate: string; boardgameFileNameTemplate: string; bookFileNameTemplate: string; + comicbookFileNameTemplate: string; moviePropertyConversionRules: string; seriesPropertyConversionRules: string; @@ -64,6 +67,7 @@ export interface MediaDbPluginSettings { musicReleasePropertyConversionRules: string; boardgamePropertyConversionRules: string; bookPropertyConversionRules: string; + comicbookPropertyConversionRules: string; movieFolder: string; seriesFolder: string; @@ -73,6 +77,7 @@ export interface MediaDbPluginSettings { musicReleaseFolder: string; boardgameFolder: string; bookFolder: string; + comicbookFolder: string; propertyMappingModels: PropertyMappingModel[]; } @@ -81,6 +86,7 @@ const DEFAULT_SETTINGS: MediaDbPluginSettings = { OMDbKey: '', MobyGamesKey: '', GiantBombKey: '', + ComicVineKey: '', sfwFilter: true, templates: true, customDateFormat: 'L', @@ -112,6 +118,7 @@ const DEFAULT_SETTINGS: MediaDbPluginSettings = { musicReleaseTemplate: '', boardgameTemplate: '', bookTemplate: '', + comicbookTemplate: '', movieFileNameTemplate: '{{ title }} ({{ year }})', seriesFileNameTemplate: '{{ title }} ({{ year }})', @@ -121,6 +128,7 @@ const DEFAULT_SETTINGS: MediaDbPluginSettings = { musicReleaseFileNameTemplate: '{{ title }} (by {{ ENUM:artists }} - {{ year }})', boardgameFileNameTemplate: '{{ title }} ({{ year }})', bookFileNameTemplate: '{{ title }} ({{ year }})', + comicbookFileNameTemplate: '{{ title }} ({{ year }})', moviePropertyConversionRules: '', seriesPropertyConversionRules: '', @@ -130,6 +138,7 @@ const DEFAULT_SETTINGS: MediaDbPluginSettings = { musicReleasePropertyConversionRules: '', boardgamePropertyConversionRules: '', bookPropertyConversionRules: '', + comicbookPropertyConversionRules: '', movieFolder: 'Media DB/movies', seriesFolder: 'Media DB/series', @@ -139,6 +148,7 @@ const DEFAULT_SETTINGS: MediaDbPluginSettings = { musicReleaseFolder: 'Media DB/music', boardgameFolder: 'Media DB/boardgames', bookFolder: 'Media DB/books', + comicbookFolder: 'Media DB/comicbooks', propertyMappingModels: [], }; @@ -217,6 +227,17 @@ export class MediaDbSettingTab extends PluginSettingTab { void this.plugin.saveSettings(); }); }); + new Setting(containerEl) + .setName('Comic Vine Key') + .setDesc('API key for "www.comicvine.gamespot.com".') + .addText(cb => { + cb.setPlaceholder('API key') + .setValue(this.plugin.settings.ComicVineKey) + .onChange(data => { + this.plugin.settings.ComicVineKey = data; + void this.plugin.saveSettings(); + }); + }); new Setting(containerEl) .setName('SFW filter') @@ -364,7 +385,15 @@ export class MediaDbSettingTab extends PluginSettingTab { // void this.plugin.saveSettings(); // }); // }); - + // new Setting(containerEl) + // .setName('Giantbomb API') + // .setDesc('Use Giantbomb API for games.') + // .addToggle(cb => { + // cb.setValue(this.plugin.settings.apiToggle.GiantBombAPI.game).onChange(data => { + // this.plugin.settings.apiToggle.GiantBombAPI.game = data; + // void this.plugin.saveSettings(); + // }); + // }); new Setting(containerEl).setName('New file location').setHeading(); // region new file location new Setting(containerEl) @@ -469,6 +498,18 @@ export class MediaDbSettingTab extends PluginSettingTab { void this.plugin.saveSettings(); }); }); + new Setting(containerEl) + .setName('Comic Book folder') + .setDesc('Where newly imported comic books should be placed.') + .addSearch(cb => { + new FolderSuggest(this.app, cb.inputEl); + cb.setPlaceholder(DEFAULT_SETTINGS.comicbookFolder) + .setValue(this.plugin.settings.comicbookFolder) + .onChange(data => { + this.plugin.settings.comicbookFolder = data; + void this.plugin.saveSettings(); + }); + }); // endregion new Setting(containerEl).setName('Template settings').setHeading(); @@ -576,6 +617,19 @@ export class MediaDbSettingTab extends PluginSettingTab { void this.plugin.saveSettings(); }); }); + + new Setting(containerEl) + .setName('Comic Book template') + .setDesc('Template file to be used when creating a new note for a comic book.') + .addSearch(cb => { + new FileSuggest(this.app, cb.inputEl); + cb.setPlaceholder('Example: comicbookTemplate.md') + .setValue(this.plugin.settings.comicbookTemplate) + .onChange(data => { + this.plugin.settings.comicbookTemplate = data; + void this.plugin.saveSettings(); + }); + }); // endregion new Setting(containerEl).setName('File name settings').setHeading(); @@ -675,6 +729,18 @@ export class MediaDbSettingTab extends PluginSettingTab { void this.plugin.saveSettings(); }); }); + + new Setting(containerEl) + .setName('Comic Book file name template') + .setDesc('Template for the file name used when creating a new note for a book.') + .addText(cb => { + cb.setPlaceholder(`Example: ${DEFAULT_SETTINGS.comicbookFileNameTemplate}`) + .setValue(this.plugin.settings.comicbookFileNameTemplate) + .onChange(data => { + this.plugin.settings.comicbookFileNameTemplate = data; + void this.plugin.saveSettings(); + }); + }); // endregion // region Property Mappings From 646d0f8cd9bfb65a9f28f2043fa2307ada2e9979 Mon Sep 17 00:00:00 2001 From: ltctceplrm <14954927+ltctceplrm@users.noreply.github.com> Date: Tue, 11 Feb 2025 17:48:24 +0100 Subject: [PATCH 03/11] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index e0b04d8..eb6da3b 100644 --- a/README.md +++ b/README.md @@ -108,9 +108,12 @@ Now you select the result you want and the plugin will cast it's magic and creat - music releases - wiki articles - books +- manga +- comic ### Currently supported APIs: + | 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, manga, manwha, novels | No | 60 per minute and 3 per second | Yes | @@ -121,6 +124,7 @@ Now you select the result you want and the plugin will cast it's magic and creat | [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 | | [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 | | [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 | +| Comic Vine | The Comic Vine API offers metadata for comic books | comicbooks | Yes, by making an account [here](https://comicvine.gamespot.com/login-signup/) and going to the [api section](https://comicvine.gamespot.com/api/) of the site | 200 requests per resource, per hour. There is also a velocity detection to prevent malicious use. If too many requests are made per second, you may receive temporary blocks to resources. | No #### Notes @@ -160,6 +164,10 @@ Now you select the result you want and the plugin will cast it's magic and creat - [Giant Bomb](https://www.giantbomb.com) - you can find this ID in the URL - e.g. for "Dota 2" the URL looks like this `https://www.giantbomb.com/dota-2/3030-32887/` so the ID is `3030-32887` +- [Comic Vine](https://www.comicvine.gamespot.com) + - you can find this ID in the URL + - e.g. for "Boule & Bill" the URL looks like this `https://comicvine.gamespot.com/boule-bill/4050-70187/` so the ID is `4050-70187` + - Please note that only volumes can be added, not separate issues. ### Problems, unexpected behavior or improvement suggestions? From f3e0b32bb8ac84390660730351b7502f2074f6ea Mon Sep 17 00:00:00 2001 From: ltctceplrm <14954927+ltctceplrm@users.noreply.github.com> Date: Tue, 11 Feb 2025 17:48:54 +0100 Subject: [PATCH 04/11] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eb6da3b..5ad2f49 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ Now you select the result you want and the plugin will cast it's magic and creat - wiki articles - books - manga -- comic +- comics ### Currently supported APIs: From 4eee3704e8e302cb679f60549307071345ed3058 Mon Sep 17 00:00:00 2001 From: ltctceplrm <14954927+ltctceplrm@users.noreply.github.com> Date: Tue, 11 Feb 2025 19:20:55 +0100 Subject: [PATCH 05/11] Renamed publisher to publishers and added array Also added publisher/serialization support for MALAPI MAnga --- src/api/apis/ComicVineAPI.ts | 4 ++-- src/api/apis/MALAPIManga.ts | 1 + src/models/ComicBookModel.ts | 4 ++-- src/models/MangaModel.ts | 2 ++ 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/api/apis/ComicVineAPI.ts b/src/api/apis/ComicVineAPI.ts index 02cfffc..591d6d8 100644 --- a/src/api/apis/ComicVineAPI.ts +++ b/src/api/apis/ComicVineAPI.ts @@ -41,7 +41,7 @@ export class ComicVineAPI extends APIModel { year: result.start_year, dataSource: this.apiName, id: result.id, - publisher: result.publisher.name ?? 'unknown', + publishers: result.publisher.name ?? [], }), ); } @@ -82,7 +82,7 @@ export class ComicVineAPI extends APIModel { image: result.image?.original_url ?? '', released: true, - publisher: result.publisher.name ?? '', + publishers: result.publisher.map((x: any) => x.name) ?? [], publishedFrom: result.start_year ?? 'unknown', publishedTo: 'unknown', status: result.status, diff --git a/src/api/apis/MALAPIManga.ts b/src/api/apis/MALAPIManga.ts index 770c273..95040e6 100644 --- a/src/api/apis/MALAPIManga.ts +++ b/src/api/apis/MALAPIManga.ts @@ -114,6 +114,7 @@ export class MALAPIManga extends APIModel { image: result.images?.jpg?.image_url ?? '', released: true, + publishers: result.serializations?.map((x: any) => x.name) ?? [], publishedFrom: new Date(result.published?.from).toLocaleDateString() ?? 'unknown', publishedTo: new Date(result.published?.to).toLocaleDateString() ?? 'unknown', status: result.status, diff --git a/src/models/ComicBookModel.ts b/src/models/ComicBookModel.ts index a3990df..cd8f941 100644 --- a/src/models/ComicBookModel.ts +++ b/src/models/ComicBookModel.ts @@ -7,7 +7,7 @@ export type ComicBookData = ModelToData; export class ComicBookModel extends MediaTypeModel { creators: string[]; - publisher: string; + publishers: string[]; plot: string; issues: number; image: string; @@ -27,7 +27,7 @@ export class ComicBookModel extends MediaTypeModel { super(); this.creators = []; - this.publisher = ''; + this.publishers = []; this.plot = ''; this.issues = 0; this.image = ''; diff --git a/src/models/MangaModel.ts b/src/models/MangaModel.ts index b89e963..55efae6 100644 --- a/src/models/MangaModel.ts +++ b/src/models/MangaModel.ts @@ -17,6 +17,7 @@ export class MangaModel extends MediaTypeModel { released: boolean; status: string; + publishers: string[]; publishedFrom: string; publishedTo: string; @@ -40,6 +41,7 @@ export class MangaModel extends MediaTypeModel { this.released = false; this.status = ''; + this.publishers = []; this.publishedFrom = ''; this.publishedTo = ''; From 01b56c9be5ffaa787850d50f9c39de6faa95fd2c Mon Sep 17 00:00:00 2001 From: ltctceplrm <14954927+ltctceplrm@users.noreply.github.com> Date: Tue, 11 Feb 2025 19:42:28 +0100 Subject: [PATCH 06/11] Changed publishers mapping for comic books the publisher field on comic vine isn't an array --- src/api/apis/ComicVineAPI.ts | 2 +- src/models/ComicBookModel.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/apis/ComicVineAPI.ts b/src/api/apis/ComicVineAPI.ts index 591d6d8..51815c2 100644 --- a/src/api/apis/ComicVineAPI.ts +++ b/src/api/apis/ComicVineAPI.ts @@ -82,7 +82,7 @@ export class ComicVineAPI extends APIModel { image: result.image?.original_url ?? '', released: true, - publishers: result.publisher.map((x: any) => x.name) ?? [], + publishers: result.publisher.name ?? [], publishedFrom: result.start_year ?? 'unknown', publishedTo: 'unknown', status: result.status, diff --git a/src/models/ComicBookModel.ts b/src/models/ComicBookModel.ts index cd8f941..27c66bf 100644 --- a/src/models/ComicBookModel.ts +++ b/src/models/ComicBookModel.ts @@ -62,6 +62,6 @@ export class ComicBookModel extends MediaTypeModel { } getSummary(): string { - return this.englishTitle + ' (' + this.year + ') - ' + this.publisher; + return this.englishTitle + ' (' + this.year + ') - ' + this.publishers; } } From a07e549ea4e86c3d8374e1d98046f9ab8861b1f4 Mon Sep 17 00:00:00 2001 From: ltctceplrm <14954927+ltctceplrm@users.noreply.github.com> Date: Tue, 11 Feb 2025 21:51:08 +0100 Subject: [PATCH 07/11] Merged comic book models with manga models into comicmanga model Updated both MALAPI Manga and ComicVine API to be more consistent with eachother. --- src/api/apis/ComicVineAPI.ts | 18 +++++---- src/api/apis/MALAPIManga.ts | 16 ++++---- src/main.ts | 24 ++++++----- src/models/ComicMangaModel.ts | 74 ++++++++++++++++++++++++++++++++++ src/settings/PropertyMapper.ts | 7 +++- src/settings/Settings.ts | 58 ++++---------------------- src/utils/MediaType.ts | 3 +- src/utils/MediaTypeManager.ts | 21 ++++------ 8 files changed, 128 insertions(+), 93 deletions(-) create mode 100644 src/models/ComicMangaModel.ts diff --git a/src/api/apis/ComicVineAPI.ts b/src/api/apis/ComicVineAPI.ts index 51815c2..c45da4e 100644 --- a/src/api/apis/ComicVineAPI.ts +++ b/src/api/apis/ComicVineAPI.ts @@ -1,5 +1,5 @@ import { requestUrl } from 'obsidian'; -import { ComicBookModel } from 'src/models/ComicBookModel'; +import { ComicMangaModel } from 'src/models/ComicMangaModel'; import type MediaDbPlugin from '../../main'; import type { MediaTypeModel } from '../../models/MediaTypeModel'; import { MediaType } from '../../utils/MediaType'; @@ -15,7 +15,7 @@ export class ComicVineAPI extends APIModel { this.apiName = 'ComicVineAPI'; this.apiDescription = 'A free API for comic books.'; this.apiUrl = 'https://comicvine.gamespot.com/api'; - this.types = [MediaType.ComicBook]; + this.types = [MediaType.ComicManga]; } async searchByTitle(title: string): Promise { @@ -35,7 +35,7 @@ export class ComicVineAPI extends APIModel { const ret: MediaTypeModel[] = []; for (const result of data.results) { ret.push( - new ComicBookModel({ + new ComicMangaModel({ title: result.name, englishTitle: result.name, year: result.start_year, @@ -67,18 +67,20 @@ export class ComicVineAPI extends APIModel { // console.debug(data); const result = data.results; - return new ComicBookModel({ - type: MediaType.ComicBook, + return new ComicMangaModel({ + type: MediaType.ComicManga, title: result.name, + englishTitle: result.name, + alternateTitles: result.aliases, plot: result.deck, year: result.start_year ?? '', dataSource: this.apiName, url: result.site_detail_url, id: result.id, - creators: result.people?.map((x: any) => x.name) ?? [], - issues: result.count_of_issues, - onlineRating: result.score ?? 0, + + authors: result.people?.map((x: any) => x.name) ?? [], + chapters: result.count_of_issues, image: result.image?.original_url ?? '', released: true, diff --git a/src/api/apis/MALAPIManga.ts b/src/api/apis/MALAPIManga.ts index 95040e6..bd99476 100644 --- a/src/api/apis/MALAPIManga.ts +++ b/src/api/apis/MALAPIManga.ts @@ -1,5 +1,5 @@ import type MediaDbPlugin from '../../main'; -import { MangaModel } from '../../models/MangaModel'; +import { ComicMangaModel } from '../../models/ComicMangaModel'; import type { MediaTypeModel } from '../../models/MediaTypeModel'; import { MediaType } from '../../utils/MediaType'; import { APIModel } from '../APIModel'; @@ -15,7 +15,7 @@ export class MALAPIManga extends APIModel { this.apiName = 'MALAPI Manga'; this.apiDescription = 'A free API for Manga. Some results may take a long time to load.'; this.apiUrl = 'https://jikan.moe/'; - this.types = [MediaType.Manga]; + this.types = [MediaType.ComicManga]; this.typeMappings = new Map(); this.typeMappings.set('manga', 'manga'); this.typeMappings.set('manhwa', 'manhwa'); @@ -45,7 +45,7 @@ export class MALAPIManga extends APIModel { for (const result of data.data) { const type = this.typeMappings.get(result.type?.toLowerCase()); ret.push( - new MangaModel({ + new ComicMangaModel({ subType: type, title: result.title, plot: result.synopsis, @@ -69,8 +69,8 @@ export class MALAPIManga extends APIModel { status: result.status, userData: { - watched: false, - lastWatched: '', + read: false, + lastRead: '', personalRating: 0, }, }), @@ -95,7 +95,7 @@ export class MALAPIManga extends APIModel { const result = data.data; const type = this.typeMappings.get(result.type?.toLowerCase()); - return new MangaModel({ + return new ComicMangaModel({ subType: type, title: result.title, englishTitle: result.title_english ?? result.title, @@ -120,8 +120,8 @@ export class MALAPIManga extends APIModel { status: result.status, userData: { - watched: false, - lastWatched: '', + read: false, + lastRead: '', personalRating: 0, }, }); diff --git a/src/main.ts b/src/main.ts index a6b5b2f..f7e4f5f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -12,6 +12,7 @@ import { OpenLibraryAPI } from './api/apis/OpenLibraryAPI'; import { SteamAPI } from './api/apis/SteamAPI'; import { WikipediaAPI } from './api/apis/WikipediaAPI'; import { ComicVineAPI } from './api/apis/ComicVineAPI'; +import { VNDBAPI } from './api/apis/VNDBAPI'; import { MediaDbFolderImportModal } from './modals/MediaDbFolderImportModal'; import type { MediaTypeModel } from './models/MediaTypeModel'; import { PropertyMapper } from './settings/PropertyMapper'; @@ -57,6 +58,7 @@ export default class MediaDbPlugin extends Plugin { this.apiManager.registerAPI(new ComicVineAPI(this)); this.apiManager.registerAPI(new MobyGamesAPI(this)); this.apiManager.registerAPI(new GiantBombAPI(this)); + this.apiManager.registerAPI(new VNDBAPI(this)); // this.apiManager.registerAPI(new LocGovAPI(this)); // TODO: parse data this.mediaTypeManager = new MediaTypeManager(); @@ -540,35 +542,37 @@ export default class MediaDbPlugin extends Plugin { if (!activeFile) { throw new Error('MDB | there is no active note'); } - + let metadata = this.getMetadataFromFileCache(activeFile); metadata = this.modelPropertyMapper.convertObjectBack(metadata); - + console.debug(`MDB | read metadata`, metadata); - + if (!metadata?.type || !metadata?.dataSource || !metadata?.id) { throw new Error('MDB | active note is not a Media DB entry or is missing metadata'); } - + const validOldMetadata: MediaTypeModelObj = metadata as unknown as MediaTypeModelObj; - + console.debug(`MDB | validOldMetadata`, validOldMetadata); + const oldMediaTypeModel = this.mediaTypeManager.createMediaTypeModelFromMediaType(validOldMetadata, validOldMetadata.type); - // console.debug(oldMediaTypeModel); - + console.debug(`MDB | oldMediaTypeModel created`, oldMediaTypeModel); + let newMediaTypeModel = await this.apiManager.queryDetailedInfoById(validOldMetadata.id, validOldMetadata.dataSource); if (!newMediaTypeModel) { return; } - + newMediaTypeModel = Object.assign(oldMediaTypeModel, newMediaTypeModel.getWithOutUserData()); - // console.debug(newMediaTypeModel); - + console.debug(`MDB | newMediaTypeModel after merge`, newMediaTypeModel); + if (onlyMetadata) { await this.createMediaDbNoteFromModel(newMediaTypeModel, { attachFile: activeFile, folder: activeFile.parent ?? undefined, openNote: true }); } else { await this.createMediaDbNoteFromModel(newMediaTypeModel, { attachTemplate: true, folder: activeFile.parent ?? undefined, openNote: true }); } } + async createEntriesFromFolder(folder: TFolder): Promise { const erroredFiles: { filePath: string; error: string }[] = []; diff --git a/src/models/ComicMangaModel.ts b/src/models/ComicMangaModel.ts new file mode 100644 index 0000000..21bd282 --- /dev/null +++ b/src/models/ComicMangaModel.ts @@ -0,0 +1,74 @@ +import { MediaType } from '../utils/MediaType'; +import type { ModelToData } from '../utils/Utils'; +import { mediaDbTag, migrateObject } from '../utils/Utils'; +import { MediaTypeModel } from './MediaTypeModel'; + +export type ComicMangaData = ModelToData; + +export class ComicMangaModel extends MediaTypeModel { + plot: string; + alternateTitles: string[]; + genres: string[]; + authors: string[]; + chapters: number; + volumes: number; + onlineRating: number; + image: string; + + released: boolean; + status: string; + publishers: string[]; + publishedFrom: string; + publishedTo: string; + + userData: { + read: boolean; + lastRead: string; + personalRating: number; + }; + + constructor(obj: ComicMangaData) { + super(); + + this.plot = ''; + this.alternateTitles = []; + this.genres = []; + this.authors = []; + this.chapters = 0; + this.volumes = 0; + this.onlineRating = 0; + this.image = ''; + + this.released = false; + this.status = ''; + this.publishers = []; + this.publishedFrom = ''; + this.publishedTo = ''; + + this.userData = { + read: false, + lastRead: '', + personalRating: 0, + }; + + migrateObject(this, obj, this); + + if (!obj.hasOwnProperty('userData')) { + migrateObject(this.userData, obj, this.userData); + } + + this.type = this.getMediaType(); + } + + getTags(): string[] { + return [mediaDbTag, 'manga', 'light-novel', 'comicbook']; + } + + getMediaType(): MediaType { + return MediaType.ComicManga; + } + + getSummary(): string { + return this.title + ' (' + this.year + ')'; + } +} \ No newline at end of file diff --git a/src/settings/PropertyMapper.ts b/src/settings/PropertyMapper.ts index b5644dc..53ad049 100644 --- a/src/settings/PropertyMapper.ts +++ b/src/settings/PropertyMapper.ts @@ -62,7 +62,12 @@ export class PropertyMapper { return obj; } - if (MEDIA_TYPES.contains(obj.type as any)) { + + if (obj.type === "manga") { + obj.type = "comicManga"; + console.debug(`MDB | updated metadata type`, obj.type); + } + if (MEDIA_TYPES.contains(obj.type as any)) { return obj; } diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index ec9e27f..b02994e 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -47,7 +47,6 @@ export interface MediaDbPluginSettings { musicReleaseTemplate: string; boardgameTemplate: string; bookTemplate: string; - comicbookTemplate: string; movieFileNameTemplate: string; seriesFileNameTemplate: string; @@ -57,7 +56,6 @@ export interface MediaDbPluginSettings { musicReleaseFileNameTemplate: string; boardgameFileNameTemplate: string; bookFileNameTemplate: string; - comicbookFileNameTemplate: string; moviePropertyConversionRules: string; seriesPropertyConversionRules: string; @@ -67,7 +65,6 @@ export interface MediaDbPluginSettings { musicReleasePropertyConversionRules: string; boardgamePropertyConversionRules: string; bookPropertyConversionRules: string; - comicbookPropertyConversionRules: string; movieFolder: string; seriesFolder: string; @@ -77,7 +74,6 @@ export interface MediaDbPluginSettings { musicReleaseFolder: string; boardgameFolder: string; bookFolder: string; - comicbookFolder: string; propertyMappingModels: PropertyMappingModel[]; } @@ -118,7 +114,6 @@ const DEFAULT_SETTINGS: MediaDbPluginSettings = { musicReleaseTemplate: '', boardgameTemplate: '', bookTemplate: '', - comicbookTemplate: '', movieFileNameTemplate: '{{ title }} ({{ year }})', seriesFileNameTemplate: '{{ title }} ({{ year }})', @@ -128,7 +123,6 @@ const DEFAULT_SETTINGS: MediaDbPluginSettings = { musicReleaseFileNameTemplate: '{{ title }} (by {{ ENUM:artists }} - {{ year }})', boardgameFileNameTemplate: '{{ title }} ({{ year }})', bookFileNameTemplate: '{{ title }} ({{ year }})', - comicbookFileNameTemplate: '{{ title }} ({{ year }})', moviePropertyConversionRules: '', seriesPropertyConversionRules: '', @@ -138,17 +132,15 @@ const DEFAULT_SETTINGS: MediaDbPluginSettings = { musicReleasePropertyConversionRules: '', boardgamePropertyConversionRules: '', bookPropertyConversionRules: '', - comicbookPropertyConversionRules: '', movieFolder: 'Media DB/movies', seriesFolder: 'Media DB/series', - mangaFolder: 'Media DB/manga', + mangaFolder: 'Media DB/comics', gameFolder: 'Media DB/games', wikiFolder: 'Media DB/wiki', musicReleaseFolder: 'Media DB/music', boardgameFolder: 'Media DB/boardgames', bookFolder: 'Media DB/books', - comicbookFolder: 'Media DB/comicbooks', propertyMappingModels: [], }; @@ -423,8 +415,8 @@ export class MediaDbSettingTab extends PluginSettingTab { }); new Setting(containerEl) - .setName('Manga folder') - .setDesc('Where newly imported manga should be placed.') + .setName('Comic and manga folder') + .setDesc('Where newly imported comics and manga should be placed.') .addSearch(cb => { new FolderSuggest(this.app, cb.inputEl); cb.setPlaceholder(DEFAULT_SETTINGS.mangaFolder) @@ -498,18 +490,7 @@ export class MediaDbSettingTab extends PluginSettingTab { void this.plugin.saveSettings(); }); }); - new Setting(containerEl) - .setName('Comic Book folder') - .setDesc('Where newly imported comic books should be placed.') - .addSearch(cb => { - new FolderSuggest(this.app, cb.inputEl); - cb.setPlaceholder(DEFAULT_SETTINGS.comicbookFolder) - .setValue(this.plugin.settings.comicbookFolder) - .onChange(data => { - this.plugin.settings.comicbookFolder = data; - void this.plugin.saveSettings(); - }); - }); + // endregion new Setting(containerEl).setName('Template settings').setHeading(); @@ -541,8 +522,8 @@ export class MediaDbSettingTab extends PluginSettingTab { }); new Setting(containerEl) - .setName('Manga template') - .setDesc('Template file to be used when creating a new note for a manga.') + .setName('Manga and Comics template') + .setDesc('Template file to be used when creating a new note for a manga or a comic.') .addSearch(cb => { new FileSuggest(this.app, cb.inputEl); cb.setPlaceholder('Example: mangaTemplate.md') @@ -618,18 +599,6 @@ export class MediaDbSettingTab extends PluginSettingTab { }); }); - new Setting(containerEl) - .setName('Comic Book template') - .setDesc('Template file to be used when creating a new note for a comic book.') - .addSearch(cb => { - new FileSuggest(this.app, cb.inputEl); - cb.setPlaceholder('Example: comicbookTemplate.md') - .setValue(this.plugin.settings.comicbookTemplate) - .onChange(data => { - this.plugin.settings.comicbookTemplate = data; - void this.plugin.saveSettings(); - }); - }); // endregion new Setting(containerEl).setName('File name settings').setHeading(); @@ -659,8 +628,8 @@ export class MediaDbSettingTab extends PluginSettingTab { }); new Setting(containerEl) - .setName('Manga file name template') - .setDesc('Template for the file name used when creating a new note for a manga.') + .setName('Manga and comic file name template') + .setDesc('Template for the file name used when creating a new note for a manga or comic.') .addText(cb => { cb.setPlaceholder(`Example: ${DEFAULT_SETTINGS.mangaFileNameTemplate}`) .setValue(this.plugin.settings.mangaFileNameTemplate) @@ -730,17 +699,6 @@ export class MediaDbSettingTab extends PluginSettingTab { }); }); - new Setting(containerEl) - .setName('Comic Book file name template') - .setDesc('Template for the file name used when creating a new note for a book.') - .addText(cb => { - cb.setPlaceholder(`Example: ${DEFAULT_SETTINGS.comicbookFileNameTemplate}`) - .setValue(this.plugin.settings.comicbookFileNameTemplate) - .onChange(data => { - this.plugin.settings.comicbookFileNameTemplate = data; - void this.plugin.saveSettings(); - }); - }); // endregion // region Property Mappings diff --git a/src/utils/MediaType.ts b/src/utils/MediaType.ts index 8844e11..02d1c2c 100644 --- a/src/utils/MediaType.ts +++ b/src/utils/MediaType.ts @@ -1,11 +1,10 @@ export enum MediaType { Movie = 'movie', Series = 'series', - Manga = 'manga', + ComicManga = 'comicManga', Game = 'game', MusicRelease = 'musicRelease', Wiki = 'wiki', BoardGame = 'boardgame', Book = 'book', - ComicBook = 'comicBook', } diff --git a/src/utils/MediaTypeManager.ts b/src/utils/MediaTypeManager.ts index 8eee245..ec4a5ae 100644 --- a/src/utils/MediaTypeManager.ts +++ b/src/utils/MediaTypeManager.ts @@ -3,8 +3,7 @@ import { TFolder } from 'obsidian'; import { BoardGameModel } from '../models/BoardGameModel'; import { BookModel } from '../models/BookModel'; import { GameModel } from '../models/GameModel'; -import { MangaModel } from '../models/MangaModel'; -import { ComicBookModel } from '../models/ComicBookModel'; +import { ComicMangaModel } from '../models/ComicMangaModel'; import type { MediaTypeModel } from '../models/MediaTypeModel'; import { MovieModel } from '../models/MovieModel'; import { MusicReleaseModel } from '../models/MusicReleaseModel'; @@ -17,13 +16,12 @@ import { replaceTags } from './Utils'; export const MEDIA_TYPES: MediaType[] = [ MediaType.Movie, MediaType.Series, - MediaType.Manga, + MediaType.ComicManga, MediaType.Game, MediaType.Wiki, MediaType.MusicRelease, MediaType.BoardGame, MediaType.Book, - MediaType.ComicBook, ]; export class MediaTypeManager { @@ -41,37 +39,34 @@ export class MediaTypeManager { this.mediaFileNameTemplateMap = new Map(); this.mediaFileNameTemplateMap.set(MediaType.Movie, settings.movieFileNameTemplate); this.mediaFileNameTemplateMap.set(MediaType.Series, settings.seriesFileNameTemplate); - this.mediaFileNameTemplateMap.set(MediaType.Manga, settings.mangaFileNameTemplate); + this.mediaFileNameTemplateMap.set(MediaType.ComicManga, settings.mangaFileNameTemplate); this.mediaFileNameTemplateMap.set(MediaType.Game, settings.gameFileNameTemplate); this.mediaFileNameTemplateMap.set(MediaType.Wiki, settings.wikiFileNameTemplate); this.mediaFileNameTemplateMap.set(MediaType.MusicRelease, settings.musicReleaseFileNameTemplate); this.mediaFileNameTemplateMap.set(MediaType.BoardGame, settings.boardgameFileNameTemplate); this.mediaFileNameTemplateMap.set(MediaType.Book, settings.bookFileNameTemplate); - this.mediaFileNameTemplateMap.set(MediaType.ComicBook, settings.bookFileNameTemplate); this.mediaTemplateMap = new Map(); this.mediaTemplateMap.set(MediaType.Movie, settings.movieTemplate); this.mediaTemplateMap.set(MediaType.Series, settings.seriesTemplate); - this.mediaTemplateMap.set(MediaType.Manga, settings.mangaTemplate); + this.mediaTemplateMap.set(MediaType.ComicManga, settings.mangaTemplate); this.mediaTemplateMap.set(MediaType.Game, settings.gameTemplate); this.mediaTemplateMap.set(MediaType.Wiki, settings.wikiTemplate); this.mediaTemplateMap.set(MediaType.MusicRelease, settings.musicReleaseTemplate); this.mediaTemplateMap.set(MediaType.BoardGame, settings.boardgameTemplate); this.mediaTemplateMap.set(MediaType.Book, settings.bookTemplate); - this.mediaTemplateMap.set(MediaType.ComicBook, settings.bookTemplate); } updateFolders(settings: MediaDbPluginSettings): void { this.mediaFolderMap = new Map(); this.mediaFolderMap.set(MediaType.Movie, settings.movieFolder); this.mediaFolderMap.set(MediaType.Series, settings.seriesFolder); - this.mediaFolderMap.set(MediaType.Manga, settings.mangaFolder); + this.mediaFolderMap.set(MediaType.ComicManga, settings.mangaFolder); this.mediaFolderMap.set(MediaType.Game, settings.gameFolder); this.mediaFolderMap.set(MediaType.Wiki, settings.wikiFolder); this.mediaFolderMap.set(MediaType.MusicRelease, settings.musicReleaseFolder); this.mediaFolderMap.set(MediaType.BoardGame, settings.boardgameFolder); this.mediaFolderMap.set(MediaType.Book, settings.bookFolder); - this.mediaFolderMap.set(MediaType.ComicBook, settings.bookFolder); } getFileName(mediaTypeModel: MediaTypeModel): string { @@ -137,8 +132,8 @@ export class MediaTypeManager { return new MovieModel(obj); } else if (mediaType === MediaType.Series) { return new SeriesModel(obj); - } else if (mediaType === MediaType.Manga) { - return new MangaModel(obj); + } else if (mediaType === MediaType.ComicManga) { + return new ComicMangaModel(obj); } else if (mediaType === MediaType.Game) { return new GameModel(obj); } else if (mediaType === MediaType.Wiki) { @@ -149,8 +144,6 @@ export class MediaTypeManager { return new BoardGameModel(obj); } else if (mediaType === MediaType.Book) { return new BookModel(obj); - } else if (mediaType === MediaType.ComicBook) { - return new ComicBookModel(obj); } throw new Error(`Unknown media type: ${mediaType}`); From 0d4bf113be82f5aef9359a86434d3d8c5e217206 Mon Sep 17 00:00:00 2001 From: ltctceplrm <14954927+ltctceplrm@users.noreply.github.com> Date: Tue, 11 Feb 2025 21:52:50 +0100 Subject: [PATCH 08/11] Deleted old comic and manga models --- src/models/ComicBookModel.ts | 67 -------------------------------- src/models/MangaModel.ts | 74 ------------------------------------ 2 files changed, 141 deletions(-) delete mode 100644 src/models/ComicBookModel.ts delete mode 100644 src/models/MangaModel.ts diff --git a/src/models/ComicBookModel.ts b/src/models/ComicBookModel.ts deleted file mode 100644 index 27c66bf..0000000 --- a/src/models/ComicBookModel.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { MediaType } from '../utils/MediaType'; -import type { ModelToData } from '../utils/Utils'; -import { mediaDbTag, migrateObject } from '../utils/Utils'; -import { MediaTypeModel } from './MediaTypeModel'; - -export type ComicBookData = ModelToData; - -export class ComicBookModel extends MediaTypeModel { - creators: string[]; - publishers: string[]; - plot: string; - issues: number; - image: string; - onlineRating: number; - status: string; - released: boolean; - publishedFrom: string; - publishedTo: string; - - userData: { - read: boolean; - lastRead: string; - personalRating: number; - }; - - constructor(obj: ComicBookData) { - super(); - - this.creators = []; - this.publishers = []; - this.plot = ''; - this.issues = 0; - this.image = ''; - this.onlineRating = 0; - - this.released = false; - this.status = ''; - this.publishedFrom = ''; - this.publishedTo = ''; - - this.userData = { - read: false, - lastRead: '', - personalRating: 0, - }; - - migrateObject(this, obj, this); - - if (!obj.hasOwnProperty('userData')) { - migrateObject(this.userData, obj, this.userData); - } - - this.type = this.getMediaType(); - } - - getTags(): string[] { - return [mediaDbTag, 'comicbook']; - } - - getMediaType(): MediaType { - return MediaType.ComicBook; - } - - getSummary(): string { - return this.englishTitle + ' (' + this.year + ') - ' + this.publishers; - } -} diff --git a/src/models/MangaModel.ts b/src/models/MangaModel.ts deleted file mode 100644 index 55efae6..0000000 --- a/src/models/MangaModel.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { MediaType } from '../utils/MediaType'; -import type { ModelToData } from '../utils/Utils'; -import { mediaDbTag, migrateObject } from '../utils/Utils'; -import { MediaTypeModel } from './MediaTypeModel'; - -export type MangaData = ModelToData; - -export class MangaModel extends MediaTypeModel { - plot: string; - alternateTitles: string[]; - genres: string[]; - authors: string[]; - chapters: number; - volumes: number; - onlineRating: number; - image: string; - - released: boolean; - status: string; - publishers: string[]; - publishedFrom: string; - publishedTo: string; - - userData: { - watched: boolean; - lastWatched: string; - personalRating: number; - }; - - constructor(obj: MangaData) { - super(); - - this.plot = ''; - this.alternateTitles = []; - this.genres = []; - this.authors = []; - this.chapters = 0; - this.volumes = 0; - this.onlineRating = 0; - this.image = ''; - - this.released = false; - this.status = ''; - this.publishers = []; - this.publishedFrom = ''; - this.publishedTo = ''; - - this.userData = { - watched: false, - lastWatched: '', - personalRating: 0, - }; - - migrateObject(this, obj, this); - - if (!obj.hasOwnProperty('userData')) { - migrateObject(this.userData, obj, this.userData); - } - - this.type = this.getMediaType(); - } - - getTags(): string[] { - return [mediaDbTag, 'manga', 'light-novel']; - } - - getMediaType(): MediaType { - return MediaType.Manga; - } - - getSummary(): string { - return this.title + ' (' + this.year + ')'; - } -} From d89d8be1893867b308c65f5e88f724bd83a6cc7a Mon Sep 17 00:00:00 2001 From: ltctceplrm <14954927+ltctceplrm@users.noreply.github.com> Date: Tue, 11 Feb 2025 22:05:57 +0100 Subject: [PATCH 09/11] Fixed bug when publisher field was null --- src/api/apis/ComicVineAPI.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/api/apis/ComicVineAPI.ts b/src/api/apis/ComicVineAPI.ts index c45da4e..6cfad99 100644 --- a/src/api/apis/ComicVineAPI.ts +++ b/src/api/apis/ComicVineAPI.ts @@ -40,8 +40,8 @@ export class ComicVineAPI extends APIModel { englishTitle: result.name, year: result.start_year, dataSource: this.apiName, - id: result.id, - publishers: result.publisher.name ?? [], + id: `4050-${result.id}`, + publishers: result.publisher?.name ?? [], }), ); } @@ -52,7 +52,7 @@ export class ComicVineAPI extends APIModel { async getById(id: string): Promise { console.log(`MDB | api "${this.apiName}" queried by ID`); - const searchUrl = `${this.apiUrl}/volume/4050-${encodeURIComponent(id)}/?api_key=${this.plugin.settings.ComicVineKey}&format=json`; + const searchUrl = `${this.apiUrl}/volume/${encodeURIComponent(id)}/?api_key=${this.plugin.settings.ComicVineKey}&format=json`; const fetchData = await requestUrl({ url: searchUrl, }); @@ -76,7 +76,7 @@ export class ComicVineAPI extends APIModel { year: result.start_year ?? '', dataSource: this.apiName, url: result.site_detail_url, - id: result.id, + id: `4050-${result.id}`, authors: result.people?.map((x: any) => x.name) ?? [], @@ -84,7 +84,7 @@ export class ComicVineAPI extends APIModel { image: result.image?.original_url ?? '', released: true, - publishers: result.publisher.name ?? [], + publishers: result.publisher?.name ?? [], publishedFrom: result.start_year ?? 'unknown', publishedTo: 'unknown', status: result.status, From 540a772e6d59fb9c515810600a0045902c9bac99 Mon Sep 17 00:00:00 2001 From: ltctceplrm <14954927+ltctceplrm@users.noreply.github.com> Date: Wed, 12 Feb 2025 00:31:57 +0100 Subject: [PATCH 10/11] Ran prettier and commented out VNDBAPI that I forgot to remove Just in case I forget: ` bun prettier . --write` --- src/api/apis/ComicVineAPI.ts | 45 +++++++++++++++++----------------- src/main.ts | 21 ++++++++-------- src/models/ComicMangaModel.ts | 2 +- src/settings/PropertyMapper.ts | 7 +++--- src/settings/Settings.ts | 2 +- 5 files changed, 37 insertions(+), 40 deletions(-) diff --git a/src/api/apis/ComicVineAPI.ts b/src/api/apis/ComicVineAPI.ts index 6cfad99..86c9bf8 100644 --- a/src/api/apis/ComicVineAPI.ts +++ b/src/api/apis/ComicVineAPI.ts @@ -56,7 +56,7 @@ export class ComicVineAPI extends APIModel { const fetchData = await requestUrl({ url: searchUrl, }); - + console.debug(fetchData); if (fetchData.status !== 200) { @@ -68,31 +68,30 @@ export class ComicVineAPI extends APIModel { const result = data.results; return new ComicMangaModel({ - type: MediaType.ComicManga, - title: result.name, - englishTitle: result.name, - alternateTitles: result.aliases, - plot: result.deck, - year: result.start_year ?? '', - dataSource: this.apiName, - url: result.site_detail_url, - id: `4050-${result.id}`, + type: MediaType.ComicManga, + title: result.name, + englishTitle: result.name, + alternateTitles: result.aliases, + plot: result.deck, + year: result.start_year ?? '', + dataSource: this.apiName, + url: result.site_detail_url, + id: `4050-${result.id}`, + authors: result.people?.map((x: any) => x.name) ?? [], + chapters: result.count_of_issues, + image: result.image?.original_url ?? '', - authors: result.people?.map((x: any) => x.name) ?? [], - chapters: result.count_of_issues, - image: result.image?.original_url ?? '', + released: true, + publishers: result.publisher?.name ?? [], + publishedFrom: result.start_year ?? 'unknown', + publishedTo: 'unknown', + status: result.status, - released: true, - publishers: result.publisher?.name ?? [], - publishedFrom: result.start_year ?? 'unknown', - publishedTo: 'unknown', - status: result.status, - - userData: { - read: false, - lastRead: '', - personalRating: 0, + userData: { + read: false, + lastRead: '', + personalRating: 0, }, }); } diff --git a/src/main.ts b/src/main.ts index f7e4f5f..7cdf43a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -12,7 +12,7 @@ import { OpenLibraryAPI } from './api/apis/OpenLibraryAPI'; import { SteamAPI } from './api/apis/SteamAPI'; import { WikipediaAPI } from './api/apis/WikipediaAPI'; import { ComicVineAPI } from './api/apis/ComicVineAPI'; -import { VNDBAPI } from './api/apis/VNDBAPI'; +//import { VNDBAPI } from './api/apis/VNDBAPI'; import { MediaDbFolderImportModal } from './modals/MediaDbFolderImportModal'; import type { MediaTypeModel } from './models/MediaTypeModel'; import { PropertyMapper } from './settings/PropertyMapper'; @@ -58,7 +58,7 @@ export default class MediaDbPlugin extends Plugin { this.apiManager.registerAPI(new ComicVineAPI(this)); this.apiManager.registerAPI(new MobyGamesAPI(this)); this.apiManager.registerAPI(new GiantBombAPI(this)); - this.apiManager.registerAPI(new VNDBAPI(this)); + //this.apiManager.registerAPI(new VNDBAPI(this)); // this.apiManager.registerAPI(new LocGovAPI(this)); // TODO: parse data this.mediaTypeManager = new MediaTypeManager(); @@ -542,37 +542,36 @@ export default class MediaDbPlugin extends Plugin { if (!activeFile) { throw new Error('MDB | there is no active note'); } - + let metadata = this.getMetadataFromFileCache(activeFile); metadata = this.modelPropertyMapper.convertObjectBack(metadata); - + console.debug(`MDB | read metadata`, metadata); - + if (!metadata?.type || !metadata?.dataSource || !metadata?.id) { throw new Error('MDB | active note is not a Media DB entry or is missing metadata'); } - + const validOldMetadata: MediaTypeModelObj = metadata as unknown as MediaTypeModelObj; console.debug(`MDB | validOldMetadata`, validOldMetadata); - + const oldMediaTypeModel = this.mediaTypeManager.createMediaTypeModelFromMediaType(validOldMetadata, validOldMetadata.type); console.debug(`MDB | oldMediaTypeModel created`, oldMediaTypeModel); - + let newMediaTypeModel = await this.apiManager.queryDetailedInfoById(validOldMetadata.id, validOldMetadata.dataSource); if (!newMediaTypeModel) { return; } - + newMediaTypeModel = Object.assign(oldMediaTypeModel, newMediaTypeModel.getWithOutUserData()); console.debug(`MDB | newMediaTypeModel after merge`, newMediaTypeModel); - + if (onlyMetadata) { await this.createMediaDbNoteFromModel(newMediaTypeModel, { attachFile: activeFile, folder: activeFile.parent ?? undefined, openNote: true }); } else { await this.createMediaDbNoteFromModel(newMediaTypeModel, { attachTemplate: true, folder: activeFile.parent ?? undefined, openNote: true }); } } - async createEntriesFromFolder(folder: TFolder): Promise { const erroredFiles: { filePath: string; error: string }[] = []; diff --git a/src/models/ComicMangaModel.ts b/src/models/ComicMangaModel.ts index 21bd282..5677d72 100644 --- a/src/models/ComicMangaModel.ts +++ b/src/models/ComicMangaModel.ts @@ -71,4 +71,4 @@ export class ComicMangaModel extends MediaTypeModel { getSummary(): string { return this.title + ' (' + this.year + ')'; } -} \ No newline at end of file +} diff --git a/src/settings/PropertyMapper.ts b/src/settings/PropertyMapper.ts index 53ad049..e3be2c5 100644 --- a/src/settings/PropertyMapper.ts +++ b/src/settings/PropertyMapper.ts @@ -62,12 +62,11 @@ export class PropertyMapper { return obj; } - - if (obj.type === "manga") { - obj.type = "comicManga"; + if (obj.type === 'manga') { + obj.type = 'comicManga'; console.debug(`MDB | updated metadata type`, obj.type); } - if (MEDIA_TYPES.contains(obj.type as any)) { + if (MEDIA_TYPES.contains(obj.type as any)) { return obj; } diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index b02994e..f880a35 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -219,7 +219,7 @@ export class MediaDbSettingTab extends PluginSettingTab { void this.plugin.saveSettings(); }); }); - new Setting(containerEl) + new Setting(containerEl) .setName('Comic Vine Key') .setDesc('API key for "www.comicvine.gamespot.com".') .addText(cb => { From 0a4c308b5e0ec19d967a46187803ffd9598dd437 Mon Sep 17 00:00:00 2001 From: ltctceplrm <14954927+ltctceplrm@users.noreply.github.com> Date: Wed, 19 Feb 2025 15:27:48 +0100 Subject: [PATCH 11/11] Removed commented lines --- src/main.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main.ts b/src/main.ts index 7cdf43a..bdb02bb 100644 --- a/src/main.ts +++ b/src/main.ts @@ -12,7 +12,6 @@ import { OpenLibraryAPI } from './api/apis/OpenLibraryAPI'; import { SteamAPI } from './api/apis/SteamAPI'; import { WikipediaAPI } from './api/apis/WikipediaAPI'; import { ComicVineAPI } from './api/apis/ComicVineAPI'; -//import { VNDBAPI } from './api/apis/VNDBAPI'; import { MediaDbFolderImportModal } from './modals/MediaDbFolderImportModal'; import type { MediaTypeModel } from './models/MediaTypeModel'; import { PropertyMapper } from './settings/PropertyMapper'; @@ -58,7 +57,6 @@ export default class MediaDbPlugin extends Plugin { this.apiManager.registerAPI(new ComicVineAPI(this)); this.apiManager.registerAPI(new MobyGamesAPI(this)); this.apiManager.registerAPI(new GiantBombAPI(this)); - //this.apiManager.registerAPI(new VNDBAPI(this)); // this.apiManager.registerAPI(new LocGovAPI(this)); // TODO: parse data this.mediaTypeManager = new MediaTypeManager();