From eb28e96769bb1b680a7d4e81751bfa0094f89362 Mon Sep 17 00:00:00 2001 From: Phantom Date: Fri, 21 Jul 2023 20:45:03 -0500 Subject: [PATCH 1/5] Added MAL Manga as a second Jikan API --- .gitignore | 3 + src/api/apis/MALAPIManga.ts | 199 ++++++++++++++++++++++++++++++++++ src/main.ts | 2 + src/models/MangaModel.ts | 77 +++++++++++++ src/settings/Settings.ts | 46 ++++++++ src/utils/MediaType.ts | 1 + src/utils/MediaTypeManager.ts | 8 +- 7 files changed, 335 insertions(+), 1 deletion(-) create mode 100644 src/api/apis/MALAPIManga.ts create mode 100644 src/models/MangaModel.ts diff --git a/.gitignore b/.gitignore index e09a007..79c0350 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,6 @@ data.json # Exclude macOS Finder (System Explorer) View States .DS_Store + +src/**/*.js +__mocks__/*.js \ No newline at end of file diff --git a/src/api/apis/MALAPIManga.ts b/src/api/apis/MALAPIManga.ts new file mode 100644 index 0000000..d44d727 --- /dev/null +++ b/src/api/apis/MALAPIManga.ts @@ -0,0 +1,199 @@ +import { APIModel } from '../APIModel'; +import { MediaTypeModel } from '../../models/MediaTypeModel'; +// import { MovieModel } from '../../models/MovieModel'; +import MediaDbPlugin from '../../main'; +import { MangaModel } from '../../models/MangaModel'; +import { MediaType } from '../../utils/MediaType'; + +export class MALAPIManga extends APIModel { + plugin: MediaDbPlugin; + typeMappings: Map; + + constructor(plugin: MediaDbPlugin) { + super(); + + this.plugin = plugin; + 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.typeMappings = new Map(); + this.typeMappings.set('manga', 'manga'); + this.typeMappings.set('light novel', 'lnovel'); + } + + async searchByTitle(title: string): Promise { + console.log(`MDB | api "${this.apiName}" queried by Title`); + + const searchUrl = `https://api.jikan.moe/v4/manga?q=${encodeURIComponent(title)}&limit=20${this.plugin.settings.sfwFilter ? '&sfw' : ''}`; + + const fetchData = await fetch(searchUrl); + console.debug(fetchData); + if (fetchData.status !== 200) { + throw Error(`MDB | Received status code ${fetchData.status} from an API.`); + } + const data = await fetchData.json(); + + console.debug(data); + + const ret: MediaTypeModel[] = []; + + for (const result of data.data) { + const type = this.typeMappings.get(result.type?.toLowerCase()); + if (type === undefined) { + ret.push( + new MangaModel({ + subType: type, + title: result.title, + synopsis: result.synopsis, + englishTitle: result.title_english ?? result.title, + alternateTitles: result.titles?.map((x: any) => x.title) ?? [], + year: result.year ?? result.published?.prop?.from?.year ?? '', + dataSource: this.apiName, + url: result.url, + id: result.mal_id, + + genres: result.genres?.map((x: any) => x.name) ?? [], + authors: result.authors?.map((x: any) => x.name) ?? [], + chapters: result.chapters, + volumes: result.volumes, + onlineRating: result.score ?? 0, + image: result.images?.jpg?.image_url ?? '', + + released: true, + publishedFrom: new Date(result.published?.from).toLocaleDateString() ?? 'unknown', + publishedTo: new Date(result.published?.to).toLocaleDateString() ?? 'unknown', + status: result.status, + + userData: { + watched: false, + lastWatched: '', + personalRating: 0, + }, + } as MangaModel) + ); + } + if (type === 'manga' || type === "lnovel") { + ret.push( + new MangaModel({ + subType: type, + title: result.title, + synopsis: result.synopsis, + englishTitle: result.title_english ?? result.title, + alternateTitles: result.titles?.map((x: any) => x.title) ?? [], + year: result.year ?? result.published?.prop?.from?.year ?? '', + dataSource: this.apiName, + url: result.url, + id: result.mal_id, + + genres: result.genres?.map((x: any) => x.name) ?? [], + authors: result.authors?.map((x: any) => x.name) ?? [], + chapters: result.chapters, + volumes: result.volumes, + onlineRating: result.score ?? 0, + image: result.images?.jpg?.image_url ?? '', + + released: true, + publishedFrom: new Date(result.published?.from).toLocaleDateString() ?? 'unknown', + publishedTo: new Date(result.published?.to).toLocaleDateString() ?? 'unknown', + status: result.status, + + userData: { + watched: false, + lastWatched: '', + personalRating: 0, + }, + } as MangaModel) + ); + } + } + + return ret; + } + + async getById(id: string): Promise { + console.log(`MDB | api "${this.apiName}" queried by ID`); + + const searchUrl = `https://api.jikan.moe/v4/manga/${encodeURIComponent(id)}/full`; + const fetchData = await fetch(searchUrl); + + if (fetchData.status !== 200) { + throw Error(`MDB | Received status code ${fetchData.status} from an API.`); + } + + const data = await fetchData.json(); + console.debug(data); + const result = data.data; + + const type = this.typeMappings.get(result.type?.toLowerCase()); + if (type === undefined) { + const model = new MangaModel({ + subType: type, + title: result.title, + synopsis: result.synopsis, + englishTitle: result.title_english ?? result.title, + alternateTitles: result.titles?.map((x: any) => x.title) ?? [], + year: result.year ?? result.published?.prop?.from?.year ?? '', + dataSource: this.apiName, + url: result.url, + id: result.mal_id, + + genres: result.genres?.map((x: any) => x.name) ?? [], + authors: result.authors?.map((x: any) => x.name) ?? [], + chapters: result.chapters, + volumes: result.volumes, + onlineRating: result.score ?? 0, + image: result.images?.jpg?.image_url ?? '', + + released: true, + publishedFrom: new Date(result.published?.from).toLocaleDateString() ?? 'unknown', + publishedTo: new Date(result.published?.to).toLocaleDateString() ?? 'unknown', + status: result.status, + + userData: { + watched: false, + lastWatched: '', + personalRating: 0, + }, + } as MangaModel); + + return model; + } + + if (type === 'manga' || type === 'lnovel') { + const model = new MangaModel({ + subType: type, + title: result.title, + synopsis: result.synopsis, + englishTitle: result.title_english ?? result.title, + alternateTitles: result.titles?.map((x: any) => x.title) ?? [], + year: result.year ?? result.published?.prop?.from?.year ?? '', + dataSource: this.apiName, + url: result.url, + id: result.mal_id, + + genres: result.genres?.map((x: any) => x.name) ?? [], + authors: result.authors?.map((x: any) => x.name) ?? [], + chapters: result.chapters, + volumes: result.volumes, + onlineRating: result.score ?? 0, + image: result.images?.jpg?.image_url ?? '', + + released: true, + publishedFrom: new Date(result.published?.from).toLocaleDateString() ?? 'unknown', + publishedTo: new Date(result.published?.to).toLocaleDateString() ?? 'unknown', + status: result.status, + + userData: { + watched: false, + lastWatched: '', + personalRating: 0, + }, + } as MangaModel); + + return model; + } + + return; + } +} diff --git a/src/main.ts b/src/main.ts index 76abff4..e863d3e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5,6 +5,7 @@ import { MediaTypeModel } from './models/MediaTypeModel'; import { CreateNoteOptions, dateTimeToString, markdownTable, replaceIllegalFileNameCharactersInString, unCamelCase } from './utils/Utils'; import { OMDbAPI } from './api/apis/OMDbAPI'; import { MALAPI } from './api/apis/MALAPI'; +import { MALAPIManga } from './api/apis/MALAPIManga'; import { WikipediaAPI } from './api/apis/WikipediaAPI'; import { MusicBrainzAPI } from './api/apis/MusicBrainzAPI'; import { MEDIA_TYPES, MediaTypeManager } from './utils/MediaTypeManager'; @@ -30,6 +31,7 @@ export default class MediaDbPlugin extends Plugin { // register APIs this.apiManager.registerAPI(new OMDbAPI(this)); this.apiManager.registerAPI(new MALAPI(this)); + this.apiManager.registerAPI(new MALAPIManga(this)); this.apiManager.registerAPI(new WikipediaAPI(this)); this.apiManager.registerAPI(new MusicBrainzAPI(this)); this.apiManager.registerAPI(new SteamAPI(this)); diff --git a/src/models/MangaModel.ts b/src/models/MangaModel.ts new file mode 100644 index 0000000..63c99ae --- /dev/null +++ b/src/models/MangaModel.ts @@ -0,0 +1,77 @@ +import { MediaTypeModel } from './MediaTypeModel'; +import { mediaDbTag, migrateObject } from '../utils/Utils'; +import { MediaType } from '../utils/MediaType'; + +export class MangaModel extends MediaTypeModel { + type: string; + subType: string; + title: string; + synopsis: string; + englishTitle: string; + alternateTitles: string[]; + year: string; + dataSource: string; + url: string; + id: string; + + genres: string[]; + authors: string[]; + chapters: number; + volumes: number; + onlineRating: number; + image: string; + + released: boolean; + status: string; + publishedFrom: string; + publishedTo: string; + + userData: { + watched: boolean; + lastWatched: string; + personalRating: number; + }; + + constructor(obj: any = {}) { + super(); + + this.genres = undefined; + this.authors = undefined; + this.alternateTitles = undefined; + this.chapters = undefined; + this.volumes = undefined; + this.onlineRating = undefined; + this.image = undefined; + + this.released = undefined; + this.status = undefined; + this.publishedFrom = undefined; + this.publishedTo = undefined; + + this.userData = { + watched: undefined, + lastWatched: undefined, + personalRating: undefined, + }; + + migrateObject(this, obj, this); + + if (!obj.hasOwnProperty('userData')) { + migrateObject(this.userData, obj, this.userData); + } + + this.type = this.getMediaType(); + } + + getTags(): string[] { + return [mediaDbTag, 'manga', 'lnovel']; + } + + getMediaType(): MediaType { + return MediaType.Manga; + } + + getSummary(): string { + return this.title + ' (' + this.year + ')'; + } +} diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 4c37060..c420084 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -16,6 +16,7 @@ export interface MediaDbPluginSettings { movieTemplate: string; seriesTemplate: string; + mangaTemplate: string; gameTemplate: string; wikiTemplate: string; musicReleaseTemplate: string; @@ -23,6 +24,7 @@ export interface MediaDbPluginSettings { movieFileNameTemplate: string; seriesFileNameTemplate: string; + mangaFileNameTemplate: string; gameFileNameTemplate: string; wikiFileNameTemplate: string; musicReleaseFileNameTemplate: string; @@ -30,6 +32,7 @@ export interface MediaDbPluginSettings { moviePropertyConversionRules: string; seriesPropertyConversionRules: string; + mangaPropertyConversionRules: string; gamePropertyConversionRules: string; wikiPropertyConversionRules: string; musicReleasePropertyConversionRules: string; @@ -37,6 +40,7 @@ export interface MediaDbPluginSettings { movieFolder: string; seriesFolder: string; + mangaFolder: string; gameFolder: string; wikiFolder: string; musicReleaseFolder: string; @@ -53,6 +57,7 @@ const DEFAULT_SETTINGS: MediaDbPluginSettings = { movieTemplate: '', seriesTemplate: '', + mangaTemplate: '', gameTemplate: '', wikiTemplate: '', musicReleaseTemplate: '', @@ -60,6 +65,7 @@ const DEFAULT_SETTINGS: MediaDbPluginSettings = { movieFileNameTemplate: '{{ title }} ({{ year }})', seriesFileNameTemplate: '{{ title }} ({{ year }})', + mangaFileNameTemplate: '{{ title }} ({{ year }})', gameFileNameTemplate: '{{ title }} ({{ year }})', wikiFileNameTemplate: '{{ title }}', musicReleaseFileNameTemplate: '{{ title }} (by {{ ENUM:artists }} - {{ year }})', @@ -67,6 +73,7 @@ const DEFAULT_SETTINGS: MediaDbPluginSettings = { moviePropertyConversionRules: '', seriesPropertyConversionRules: '', + mangaPropertyConversionRules: '', gamePropertyConversionRules: '', wikiPropertyConversionRules: '', musicReleasePropertyConversionRules: '', @@ -74,6 +81,7 @@ const DEFAULT_SETTINGS: MediaDbPluginSettings = { movieFolder: 'Media DB/movies', seriesFolder: 'Media DB/series', + mangaFolder: 'Media DB/manga', gameFolder: 'Media DB/games', wikiFolder: 'Media DB/wiki', musicReleaseFolder: 'Media DB/music', @@ -193,6 +201,19 @@ export class MediaDbSettingTab extends PluginSettingTab { }); }); + new Setting(containerEl) + .setName('Manga Folder') + .setDesc('Where newly imported manga should be placed.') + .addSearch(cb => { + new FolderSuggest(this.app, cb.inputEl); + cb.setPlaceholder(DEFAULT_SETTINGS.mangaFolder) + .setValue(this.plugin.settings.mangaFolder) + .onChange(data => { + this.plugin.settings.mangaFolder = data; + this.plugin.saveSettings(); + }); + }); + new Setting(containerEl) .setName('Game Folder') .setDesc('Where newly imported games should be places.') @@ -274,6 +295,19 @@ 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.') + .addSearch(cb => { + new FileSuggest(this.app, cb.inputEl); + cb.setPlaceholder('Example: mangaTemplate.md') + .setValue(this.plugin.settings.mangaTemplate) + .onChange(data => { + this.plugin.settings.mangaTemplate = data; + this.plugin.saveSettings(); + }); + }); + new Setting(containerEl) .setName('Game template') .setDesc('Template file to be used when creating a new note for a game.') @@ -353,6 +387,18 @@ 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.') + .addText(cb => { + cb.setPlaceholder(`Example: ${DEFAULT_SETTINGS.mangaFileNameTemplate}`) + .setValue(this.plugin.settings.mangaFileNameTemplate) + .onChange(data => { + this.plugin.settings.mangaFileNameTemplate = data; + this.plugin.saveSettings(); + }); + }); + new Setting(containerEl) .setName('Game file name template') .setDesc('Template for the file name used when creating a new note for a game.') diff --git a/src/utils/MediaType.ts b/src/utils/MediaType.ts index c36680c..4269f06 100644 --- a/src/utils/MediaType.ts +++ b/src/utils/MediaType.ts @@ -1,6 +1,7 @@ export enum MediaType { Movie = 'movie', Series = 'series', + Manga = 'manga', Game = 'game', MusicRelease = 'musicRelease', Wiki = 'wiki', diff --git a/src/utils/MediaTypeManager.ts b/src/utils/MediaTypeManager.ts index 58a07ef..f1bf872 100644 --- a/src/utils/MediaTypeManager.ts +++ b/src/utils/MediaTypeManager.ts @@ -5,12 +5,13 @@ import { replaceTags } from './Utils'; import { App, TAbstractFile, TFile, TFolder } from 'obsidian'; import { MovieModel } from '../models/MovieModel'; import { SeriesModel } from '../models/SeriesModel'; +import { MangaModel } from '../models/MangaModel'; import { GameModel } from '../models/GameModel'; import { WikiModel } from '../models/WikiModel'; import { MusicReleaseModel } from '../models/MusicReleaseModel'; import { BoardGameModel } from '../models/BoardGameModel'; -export const MEDIA_TYPES: MediaType[] = [MediaType.Movie, MediaType.Series, MediaType.Game, MediaType.Wiki, MediaType.MusicRelease, MediaType.BoardGame]; +export const MEDIA_TYPES: MediaType[] = [MediaType.Movie, MediaType.Series, MediaType.Manga, MediaType.Game, MediaType.Wiki, MediaType.MusicRelease, MediaType.BoardGame]; export class MediaTypeManager { mediaFileNameTemplateMap: Map; @@ -23,6 +24,7 @@ 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.Game, settings.gameFileNameTemplate); this.mediaFileNameTemplateMap.set(MediaType.Wiki, settings.wikiFileNameTemplate); this.mediaFileNameTemplateMap.set(MediaType.MusicRelease, settings.musicReleaseFileNameTemplate); @@ -31,6 +33,7 @@ export class MediaTypeManager { 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.Game, settings.gameTemplate); this.mediaTemplateMap.set(MediaType.Wiki, settings.wikiTemplate); this.mediaTemplateMap.set(MediaType.MusicRelease, settings.musicReleaseTemplate); @@ -41,6 +44,7 @@ export class MediaTypeManager { 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.Game, settings.gameFolder); this.mediaFolderMap.set(MediaType.Wiki, settings.wikiFolder); this.mediaFolderMap.set(MediaType.MusicRelease, settings.musicReleaseFolder); @@ -103,6 +107,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.Game) { return new GameModel(obj); } else if (mediaType === MediaType.Wiki) { From 93950947b80548cda3cb85ef42723294fdf4887f Mon Sep 17 00:00:00 2001 From: Phantom Date: Fri, 21 Jul 2023 20:53:12 -0500 Subject: [PATCH 2/5] Added remaining possible types, removed type ifs --- src/api/apis/MALAPIManga.ts | 80 +++---------------------------------- 1 file changed, 6 insertions(+), 74 deletions(-) diff --git a/src/api/apis/MALAPIManga.ts b/src/api/apis/MALAPIManga.ts index d44d727..8ef9e1f 100644 --- a/src/api/apis/MALAPIManga.ts +++ b/src/api/apis/MALAPIManga.ts @@ -19,7 +19,12 @@ export class MALAPIManga extends APIModel { this.types = [MediaType.Manga]; this.typeMappings = new Map(); this.typeMappings.set('manga', 'manga'); + this.typeMappings.set('manhwa', 'manhwa'); + this.typeMappings.set('doujinshi', 'doujin'); + this.typeMappings.set('one-shot', 'oneshot'); + this.typeMappings.set('manhua', 'manhua'); this.typeMappings.set('light novel', 'lnovel'); + this.typeMappings.set('novel', 'novel'); } async searchByTitle(title: string): Promise { @@ -40,7 +45,6 @@ export class MALAPIManga extends APIModel { for (const result of data.data) { const type = this.typeMappings.get(result.type?.toLowerCase()); - if (type === undefined) { ret.push( new MangaModel({ subType: type, @@ -71,41 +75,7 @@ export class MALAPIManga extends APIModel { personalRating: 0, }, } as MangaModel) - ); - } - if (type === 'manga' || type === "lnovel") { - ret.push( - new MangaModel({ - subType: type, - title: result.title, - synopsis: result.synopsis, - englishTitle: result.title_english ?? result.title, - alternateTitles: result.titles?.map((x: any) => x.title) ?? [], - year: result.year ?? result.published?.prop?.from?.year ?? '', - dataSource: this.apiName, - url: result.url, - id: result.mal_id, - - genres: result.genres?.map((x: any) => x.name) ?? [], - authors: result.authors?.map((x: any) => x.name) ?? [], - chapters: result.chapters, - volumes: result.volumes, - onlineRating: result.score ?? 0, - image: result.images?.jpg?.image_url ?? '', - - released: true, - publishedFrom: new Date(result.published?.from).toLocaleDateString() ?? 'unknown', - publishedTo: new Date(result.published?.to).toLocaleDateString() ?? 'unknown', - status: result.status, - - userData: { - watched: false, - lastWatched: '', - personalRating: 0, - }, - } as MangaModel) - ); - } + ) } return ret; @@ -126,7 +96,6 @@ export class MALAPIManga extends APIModel { const result = data.data; const type = this.typeMappings.get(result.type?.toLowerCase()); - if (type === undefined) { const model = new MangaModel({ subType: type, title: result.title, @@ -158,42 +127,5 @@ export class MALAPIManga extends APIModel { } as MangaModel); return model; - } - - if (type === 'manga' || type === 'lnovel') { - const model = new MangaModel({ - subType: type, - title: result.title, - synopsis: result.synopsis, - englishTitle: result.title_english ?? result.title, - alternateTitles: result.titles?.map((x: any) => x.title) ?? [], - year: result.year ?? result.published?.prop?.from?.year ?? '', - dataSource: this.apiName, - url: result.url, - id: result.mal_id, - - genres: result.genres?.map((x: any) => x.name) ?? [], - authors: result.authors?.map((x: any) => x.name) ?? [], - chapters: result.chapters, - volumes: result.volumes, - onlineRating: result.score ?? 0, - image: result.images?.jpg?.image_url ?? '', - - released: true, - publishedFrom: new Date(result.published?.from).toLocaleDateString() ?? 'unknown', - publishedTo: new Date(result.published?.to).toLocaleDateString() ?? 'unknown', - status: result.status, - - userData: { - watched: false, - lastWatched: '', - personalRating: 0, - }, - } as MangaModel); - - return model; - } - - return; } } From f6e96e7a9a5df1d7878c7009998a3381670e186c Mon Sep 17 00:00:00 2001 From: Phantom Date: Fri, 21 Jul 2023 21:16:54 -0500 Subject: [PATCH 3/5] renamed lnovel to light-novel --- src/api/apis/MALAPIManga.ts | 2 +- src/models/MangaModel.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/apis/MALAPIManga.ts b/src/api/apis/MALAPIManga.ts index 8ef9e1f..ab9a8d7 100644 --- a/src/api/apis/MALAPIManga.ts +++ b/src/api/apis/MALAPIManga.ts @@ -23,7 +23,7 @@ export class MALAPIManga extends APIModel { this.typeMappings.set('doujinshi', 'doujin'); this.typeMappings.set('one-shot', 'oneshot'); this.typeMappings.set('manhua', 'manhua'); - this.typeMappings.set('light novel', 'lnovel'); + this.typeMappings.set('light novel', 'light-novel'); this.typeMappings.set('novel', 'novel'); } diff --git a/src/models/MangaModel.ts b/src/models/MangaModel.ts index 63c99ae..c43f7be 100644 --- a/src/models/MangaModel.ts +++ b/src/models/MangaModel.ts @@ -64,7 +64,7 @@ export class MangaModel extends MediaTypeModel { } getTags(): string[] { - return [mediaDbTag, 'manga', 'lnovel']; + return [mediaDbTag, 'manga', 'light-novel']; } getMediaType(): MediaType { From 4cf7e26bdd4fb73648888a9dd3dd7dbcb59c1ccf Mon Sep 17 00:00:00 2001 From: Phantom Date: Wed, 27 Sep 2023 20:50:41 -0500 Subject: [PATCH 4/5] Removed unnecessary comment, fixed formatting --- src/api/apis/MALAPIManga.ts | 55 ++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/src/api/apis/MALAPIManga.ts b/src/api/apis/MALAPIManga.ts index ab9a8d7..45bc06d 100644 --- a/src/api/apis/MALAPIManga.ts +++ b/src/api/apis/MALAPIManga.ts @@ -1,6 +1,5 @@ import { APIModel } from '../APIModel'; import { MediaTypeModel } from '../../models/MediaTypeModel'; -// import { MovieModel } from '../../models/MovieModel'; import MediaDbPlugin from '../../main'; import { MangaModel } from '../../models/MangaModel'; import { MediaType } from '../../utils/MediaType'; @@ -96,36 +95,36 @@ export class MALAPIManga extends APIModel { const result = data.data; const type = this.typeMappings.get(result.type?.toLowerCase()); - const model = new MangaModel({ - subType: type, - title: result.title, - synopsis: result.synopsis, - englishTitle: result.title_english ?? result.title, - alternateTitles: result.titles?.map((x: any) => x.title) ?? [], - year: result.year ?? result.published?.prop?.from?.year ?? '', - dataSource: this.apiName, - url: result.url, - id: result.mal_id, + const model = new MangaModel({ + subType: type, + title: result.title, + synopsis: result.synopsis, + englishTitle: result.title_english ?? result.title, + alternateTitles: result.titles?.map((x: any) => x.title) ?? [], + year: result.year ?? result.published?.prop?.from?.year ?? '', + dataSource: this.apiName, + url: result.url, + id: result.mal_id, - genres: result.genres?.map((x: any) => x.name) ?? [], - authors: result.authors?.map((x: any) => x.name) ?? [], - chapters: result.chapters, - volumes: result.volumes, - onlineRating: result.score ?? 0, - image: result.images?.jpg?.image_url ?? '', + genres: result.genres?.map((x: any) => x.name) ?? [], + authors: result.authors?.map((x: any) => x.name) ?? [], + chapters: result.chapters, + volumes: result.volumes, + onlineRating: result.score ?? 0, + image: result.images?.jpg?.image_url ?? '', - released: true, - publishedFrom: new Date(result.published?.from).toLocaleDateString() ?? 'unknown', - publishedTo: new Date(result.published?.to).toLocaleDateString() ?? 'unknown', - status: result.status, + released: true, + publishedFrom: new Date(result.published?.from).toLocaleDateString() ?? 'unknown', + publishedTo: new Date(result.published?.to).toLocaleDateString() ?? 'unknown', + status: result.status, - userData: { - watched: false, - lastWatched: '', - personalRating: 0, - }, - } as MangaModel); + userData: { + watched: false, + lastWatched: '', + personalRating: 0, + }, + } as MangaModel); - return model; + return model; } } From ac8ee76f8115e6d56de797d616088c53751646e6 Mon Sep 17 00:00:00 2001 From: Phantom Date: Wed, 27 Sep 2023 21:01:45 -0500 Subject: [PATCH 5/5] Updated README --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bf1042e..d06dcf0 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, games, music and wiki articles, and import them into your vault. +A plugin that can query multiple APIs for movies, series, anime, manga, games, music and wiki articles, and import them into your vault. ### Features @@ -112,7 +112,7 @@ Now you select the result you want and the plugin will cast it's magic and creat | 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 | +| [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 | | [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 access to all Wikipedia articles. | wiki articles | No | None | No | @@ -131,6 +131,10 @@ Now you select the result you want and the plugin will cast it's magic and creat - 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` +- [Jikan Manga](https://jikan.moe/) + - the ID you need is the ID of the manga on [My Anime List](https://myanimelist.net) + - you can find this ID in the URL + - e.g. for "All You Need Is Kill" the URL looks like this `https://myanimelist.net/manga/62887/All_You_Need_Is_Kill` so the ID is `62887` - [OMDb](https://www.omdbapi.com/) - 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