From d7c23d84e43e7d0c8fad01772c29d7f46366f9db Mon Sep 17 00:00:00 2001 From: qubist-pixel-ux Date: Fri, 12 Jul 2024 02:02:18 +0530 Subject: [PATCH 1/7] Add My Drama List API --- src/api/apis/MyDramaListAPI.ts | 155 +++++++++++++++++++++++++++++++++ src/main.ts | 2 + 2 files changed, 157 insertions(+) create mode 100644 src/api/apis/MyDramaListAPI.ts diff --git a/src/api/apis/MyDramaListAPI.ts b/src/api/apis/MyDramaListAPI.ts new file mode 100644 index 0000000..4d98c50 --- /dev/null +++ b/src/api/apis/MyDramaListAPI.ts @@ -0,0 +1,155 @@ +import MediaDbPlugin from 'src/main'; +import { APIModel } from '../APIModel'; +import { MediaType } from 'src/utils/MediaType'; +import { MediaTypeModel } from 'src/models/MediaTypeModel'; +import { MovieModel } from 'src/models/MovieModel'; +import { SeriesModel } from 'src/models/SeriesModel'; + +export class MyDramaListAPI extends APIModel { + plugin: MediaDbPlugin; + apiDateFormat: string = 'DD MMM YYYY'; + + constructor(plugin: MediaDbPlugin) { + super(); + + this.plugin = plugin; + this.apiName = 'MyDramaListAPI'; + this.apiDescription = 'A free API for Asian Movies and Dramas'; + this.apiUrl = 'https://kuryana.vercel.app/'; + this.types = [MediaType.Movie, MediaType.Series]; + } + + async searchByTitle(title: string): Promise { + console.log(`MDB | api "${this.apiName}" queried by Title`); + + const searchUrl = `https://kuryana.vercel.app/search/q/${encodeURIComponent(title)}`; + const fetchData = await fetch(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.dramas) { + const type = result.type.toLowerCase(); + if (type.contains('movie')) { + ret.push( + new MovieModel({ + type: result.type, + title: result.title, + englishTitle: result.title, + year: result.year, + dataSource: this.apiName, + id: result.slug, + } as MovieModel), + ); + } else if (type.contains('series') || type.contains('show') || type.contains('drama')) { + ret.push( + new SeriesModel({ + type: result.type, + title: result.title, + englishTitle: result.title, + year: result.year, + dataSource: this.apiName, + id: result.slug, + } as SeriesModel), + ); + } else { + console.debug(`MDB | api "${this.apiName}" unsupported Type "${result.type}"`); + } + } + return ret; + } + + async getById(id: string): Promise { + console.log(`MDB | api "${this.apiName}" queried by ID`); + + const searchUrl = `https://kuryana.vercel.app/id/${encodeURIComponent(id)}`; + const fetchData = await fetch(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); + + if (data.error) { + throw Error(`MDB | Received error from ${this.apiName}: ${data.title} ${data.info}`); + } + + const result = data.data; + const type = result.details.type.toLowerCase(); + if (type.contains('movie')) { + return new MovieModel({ + type: result.details.type, + title: result.title, + englishTitle: result.title, + year: result.details.release_date?.split(',')[1]?.trim(), + dataSource: 'My Drama List', + url: `https://mydramalist.com/${id}`, + id: id, + + plot: result.synopsis ?? '', + genres: result.others.genres ?? [], + director: result.others.director ? [result.others.director] : [], + writer: [], + studio: result.details.original_network ? [result.details.original_network] : [], + duration: result.details.duration ?? 'unknown', + onlineRating: Number.parseFloat(result.rating ?? 0), + actors: result.casts.map((cast: any) => cast.name) ?? [], + image: result.poster ?? '', + + released: true, + streamingServices: [], + premiere: this.plugin.dateFormatter.format(result.details.release_date, this.apiDateFormat) ?? 'unknown', + + userData: { + watched: false, + lastWatched: '', + personalRating: 0, + }, + } as MovieModel); + } else if (type.contains('series') || type.contains('show') || type.contains('drama')) { + return new SeriesModel({ + type: result.details.type, + title: result.title, + englishTitle: result.title, + year: result.details.aired?.split(',')[1]?.split('-')[0]?.trim(), + dataSource: 'My Drama List', + url: `https://mydramalist.com/${id}`, + id: id, + + plot: result.synopsis ?? '', + genres: result.others.genres ?? [], + writer: [], + studio: [result.details.original_network], + episodes: result.details.episodes ?? 0, + duration: result.details.duration ?? 'unknown', + onlineRating: Number.parseFloat(result.rating ?? 0), + actors: result.casts.map((cast: any) => cast.name) ?? [], + image: result.poster ?? '', + + released: true, + streamingServices: [], + airing: false, + airedFrom: this.plugin.dateFormatter.format(result.details.aired?.split('-')[0]?.trim(), this.apiDateFormat) ?? 'unknown', + airedTo: this.plugin.dateFormatter.format(result.details.aired?.split('-')[1]?.trim(), this.apiDateFormat) ?? 'unknown', + + userData: { + watched: false, + lastWatched: '', + personalRating: 0, + }, + } as SeriesModel); + } else { + console.debug(`MDB | api "${this.apiName}" unsupported Type "${result.details.type}"`); + } + + return; + } +} diff --git a/src/main.ts b/src/main.ts index 678505a..805db9f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -27,6 +27,7 @@ import { PropertyMapping, PropertyMappingModel } from './settings/PropertyMappin import { ModalHelper, ModalResultCode, SearchModalOptions } from './utils/ModalHelper'; import { DateFormatter } from './utils/DateFormatter'; import { MediaType } from 'src/utils/MediaType'; +import { MyDramaListAPI } from './api/apis/MyDramaListAPI'; export type Metadata = Record; @@ -58,6 +59,7 @@ export default class MediaDbPlugin extends Plugin { this.apiManager.registerAPI(new BoardGameGeekAPI(this)); this.apiManager.registerAPI(new OpenLibraryAPI(this)); this.apiManager.registerAPI(new MobyGamesAPI(this)); + this.apiManager.registerAPI(new MyDramaListAPI(this)); // this.apiManager.registerAPI(new LocGovAPI(this)); // TODO: parse data this.mediaTypeManager = new MediaTypeManager(); From f5c5f94dcb3daf24f001c878324344cc42c8ff6a Mon Sep 17 00:00:00 2001 From: qubist-pixel-ux Date: Fri, 12 Jul 2024 10:52:11 +0530 Subject: [PATCH 2/7] MyDramaList API : Use dataview's duration datatype for runtime --- src/api/apis/MyDramaListAPI.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/apis/MyDramaListAPI.ts b/src/api/apis/MyDramaListAPI.ts index 4d98c50..d8b8a28 100644 --- a/src/api/apis/MyDramaListAPI.ts +++ b/src/api/apis/MyDramaListAPI.ts @@ -99,7 +99,7 @@ export class MyDramaListAPI extends APIModel { director: result.others.director ? [result.others.director] : [], writer: [], studio: result.details.original_network ? [result.details.original_network] : [], - duration: result.details.duration ?? 'unknown', + duration: result.details.duration?.replace(/[. ]/g, '') ?? '0hr0min', onlineRating: Number.parseFloat(result.rating ?? 0), actors: result.casts.map((cast: any) => cast.name) ?? [], image: result.poster ?? '', @@ -129,7 +129,7 @@ export class MyDramaListAPI extends APIModel { writer: [], studio: [result.details.original_network], episodes: result.details.episodes ?? 0, - duration: result.details.duration ?? 'unknown', + duration: result.details.duration.duration?.replace(/[. ]/g, '') ?? '0hr0min', onlineRating: Number.parseFloat(result.rating ?? 0), actors: result.casts.map((cast: any) => cast.name) ?? [], image: result.poster ?? '', From 736d2eaf7b9ebe5c6deb7f9ee191ac7d3f5aaaf5 Mon Sep 17 00:00:00 2001 From: qubist-pixel-ux Date: Wed, 17 Jul 2024 15:08:46 +0530 Subject: [PATCH 3/7] Additional fields for Movie and Series Model --- src/models/MovieModel.ts | 20 ++++++++++++++++++++ src/models/SeriesModel.ts | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/models/MovieModel.ts b/src/models/MovieModel.ts index a4db8a7..5607f84 100644 --- a/src/models/MovieModel.ts +++ b/src/models/MovieModel.ts @@ -3,15 +3,25 @@ import { mediaDbTag, migrateObject } from '../utils/Utils'; import { MediaType } from '../utils/MediaType'; export class MovieModel extends MediaTypeModel { + nativeTitle: string; + aliases: string[]; plot: string; genres: string[]; + mediaTags: string[]; + relatedContent: string[]; director: string[]; writer: string[]; studio: string[]; duration: string; onlineRating: number; + votes: number; + ranked: number; + popularity: number; + watchers: number; actors: string[]; image: string; + country: string; + content_rating: string; released: boolean; streamingServices: string[]; @@ -26,15 +36,25 @@ export class MovieModel extends MediaTypeModel { constructor(obj: any = {}) { super(); + this.nativeTitle = undefined; + this.aliases = undefined; this.plot = undefined; this.genres = undefined; + this.mediaTags = undefined; + this.relatedContent = undefined; this.director = undefined; this.writer = undefined; this.studio = undefined; this.duration = undefined; this.onlineRating = undefined; + this.votes = undefined; + this.ranked = undefined; + this.popularity = undefined; + this.watchers = undefined; this.actors = undefined; this.image = undefined; + this.country = undefined; + this.content_rating = undefined; this.released = undefined; this.streamingServices = undefined; diff --git a/src/models/SeriesModel.ts b/src/models/SeriesModel.ts index edc222e..a931f6b 100644 --- a/src/models/SeriesModel.ts +++ b/src/models/SeriesModel.ts @@ -6,19 +6,30 @@ export class SeriesModel extends MediaTypeModel { type: string; subType: string; title: string; + nativeTitle: string; englishTitle: string; + aliases: string[]; year: string; dataSource: string; url: string; id: string; + country: string; + content_rating: string; plot: string; genres: string[]; + mediaTags: string[]; + relatedContent: string[]; + director: string[]; writer: string[]; studio: string[]; episodes: number; duration: string; onlineRating: number; + votes: number; + ranked: number; + popularity: number; + watchers: number; actors: string[]; image: string; @@ -37,15 +48,26 @@ export class SeriesModel extends MediaTypeModel { constructor(obj: any = {}) { super(); + this.nativeTitle = undefined; + this.aliases = undefined; this.plot = undefined; this.genres = undefined; + this.mediaTags = undefined; + this.relatedContent = undefined; + this.director = undefined; this.writer = undefined; this.studio = undefined; this.episodes = undefined; this.duration = undefined; this.onlineRating = undefined; + this.votes = undefined; + this.ranked = undefined; + this.popularity = undefined; + this.watchers = undefined; this.actors = undefined; this.image = undefined; + this.country = undefined; + this.content_rating = undefined; this.released = undefined; this.streamingServices = undefined; From de3103802c99e3aac8243c0b8dc8396f0eaf9e1d Mon Sep 17 00:00:00 2001 From: qubist-pixel-ux Date: Wed, 17 Jul 2024 15:09:11 +0530 Subject: [PATCH 4/7] MyDramaList API : Handle additional data --- src/api/apis/MyDramaListAPI.ts | 43 +++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/src/api/apis/MyDramaListAPI.ts b/src/api/apis/MyDramaListAPI.ts index d8b8a28..90c5a0c 100644 --- a/src/api/apis/MyDramaListAPI.ts +++ b/src/api/apis/MyDramaListAPI.ts @@ -89,24 +89,34 @@ export class MyDramaListAPI extends APIModel { type: result.details.type, title: result.title, englishTitle: result.title, - year: result.details.release_date?.split(',')[1]?.trim(), + nativeTitle: result?.others?.native_title ?? '', + aliases: result?.others?.also_known_as ?? [], + year: result.details?.release_date?.split(',')[1]?.trim(), dataSource: 'My Drama List', url: `https://mydramalist.com/${id}`, id: id, + country: result?.details?.country ?? '', + content_rating: result?.details?.content_rating ?? '', plot: result.synopsis ?? '', genres: result.others.genres ?? [], - director: result.others.director ? [result.others.director] : [], - writer: [], + mediaTags: result?.others?.tags ? result.others.tags.map((tag: string) => tag.replace(' (Vote or add tags)', '')) : [], + relatedContent: result.others.related_content ?? '', + director: result.others.director ? result.others.director : [], + writer: result.others.screenwriter ?? [], studio: result.details.original_network ? [result.details.original_network] : [], - duration: result.details.duration?.replace(/[. ]/g, '') ?? '0hr0min', - onlineRating: Number.parseFloat(result.rating ?? 0), + duration: result.details.duration?.replace(/[. ]/g, '') ?? '', + onlineRating: result.rating ? Number.parseFloat(result.rating) : '', + votes: Number.parseInt(result.details.score.split('(')[1].split(' ')[2].replace(',', '')) ?? '', + ranked: Number.parseInt(result.details.ranked.replace('#', '')) ?? '', + popularity: Number.parseInt(result.details.popularity.replace('#', '')) ?? '', + watchers: result.details.watchers ? Number.parseInt(result.details.watchers) : '', actors: result.casts.map((cast: any) => cast.name) ?? [], image: result.poster ?? '', released: true, streamingServices: [], - premiere: this.plugin.dateFormatter.format(result.details.release_date, this.apiDateFormat) ?? 'unknown', + premiere: this.plugin.dateFormatter.format(result.details.release_date, this.apiDateFormat) ?? '', userData: { watched: false, @@ -118,27 +128,38 @@ export class MyDramaListAPI extends APIModel { return new SeriesModel({ type: result.details.type, title: result.title, + nativeTitle: result?.others?.native_title ?? '', + aliases: result?.others?.also_known_as ?? [], englishTitle: result.title, year: result.details.aired?.split(',')[1]?.split('-')[0]?.trim(), dataSource: 'My Drama List', url: `https://mydramalist.com/${id}`, id: id, + country: result?.details?.country ?? '', + content_rating: result?.details?.content_rating ?? '', plot: result.synopsis ?? '', genres: result.others.genres ?? [], - writer: [], + mediaTags: result?.others?.tags ? result.others.tags.map((tag: string) => tag.replace(' (Vote or add tags)', '')) : [], + relatedContent: result.others.related_content ?? '', + director: result.others.director ? result.others.director : [], + writer: result.others.screenwriter ?? [], studio: [result.details.original_network], episodes: result.details.episodes ?? 0, - duration: result.details.duration.duration?.replace(/[. ]/g, '') ?? '0hr0min', - onlineRating: Number.parseFloat(result.rating ?? 0), + duration: result.details.duration?.replace(/[. ]/g, '') ?? '', + onlineRating: result.rating ? Number.parseFloat(result.rating) : '', actors: result.casts.map((cast: any) => cast.name) ?? [], + votes: Number.parseInt(result.details.score.split('(')[1].split(' ')[2].replace(',', '')) ?? '', + ranked: Number.parseInt(result.details.ranked.replace('#', '')) ?? '', + popularity: Number.parseInt(result.details.popularity.replace('#', '')) ?? '', + watchers: result.details.watchers ? Number.parseInt(result.details.watchers) : '', image: result.poster ?? '', released: true, streamingServices: [], airing: false, - airedFrom: this.plugin.dateFormatter.format(result.details.aired?.split('-')[0]?.trim(), this.apiDateFormat) ?? 'unknown', - airedTo: this.plugin.dateFormatter.format(result.details.aired?.split('-')[1]?.trim(), this.apiDateFormat) ?? 'unknown', + airedFrom: this.plugin.dateFormatter.format(result.details.aired?.split('-')[0]?.trim(), this.apiDateFormat) ?? '', + airedTo: this.plugin.dateFormatter.format(result.details.aired?.split('-')[1]?.trim(), this.apiDateFormat) ?? '', userData: { watched: false, From 91714d92a447e5731aaafd8c3e7d77a376094a31 Mon Sep 17 00:00:00 2001 From: qubist-pixel-ux Date: Wed, 17 Jul 2024 15:50:55 +0530 Subject: [PATCH 5/7] MyDramaList API : Handle "Special" Type --- src/api/apis/MyDramaListAPI.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/api/apis/MyDramaListAPI.ts b/src/api/apis/MyDramaListAPI.ts index 90c5a0c..cbde592 100644 --- a/src/api/apis/MyDramaListAPI.ts +++ b/src/api/apis/MyDramaListAPI.ts @@ -30,7 +30,7 @@ export class MyDramaListAPI extends APIModel { } const data = await fetchData.json(); - console.debug(data); + //console.debug(data); const ret: MediaTypeModel[] = []; for (const result of data.results.dramas) { @@ -46,7 +46,7 @@ export class MyDramaListAPI extends APIModel { id: result.slug, } as MovieModel), ); - } else if (type.contains('series') || type.contains('show') || type.contains('drama')) { + } else if (type.contains('series') || type.contains('show') || type.contains('drama') || type.contains('special')) { ret.push( new SeriesModel({ type: result.type, @@ -124,7 +124,7 @@ export class MyDramaListAPI extends APIModel { personalRating: 0, }, } as MovieModel); - } else if (type.contains('series') || type.contains('show') || type.contains('drama')) { + } else if (type.contains('series') || type.contains('show') || type.contains('drama') || type.contains('special')) { return new SeriesModel({ type: result.details.type, title: result.title, From 2c3c177583ad85e358ea7ca2f4b5306ebaea48ae Mon Sep 17 00:00:00 2001 From: qubist-pixel-ux Date: Wed, 17 Jul 2024 16:28:35 +0530 Subject: [PATCH 6/7] MyDramaList : Add subtype --- src/api/apis/MyDramaListAPI.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/api/apis/MyDramaListAPI.ts b/src/api/apis/MyDramaListAPI.ts index cbde592..e5e8a42 100644 --- a/src/api/apis/MyDramaListAPI.ts +++ b/src/api/apis/MyDramaListAPI.ts @@ -38,7 +38,8 @@ export class MyDramaListAPI extends APIModel { if (type.contains('movie')) { ret.push( new MovieModel({ - type: result.type, + type: 'Movie', + subType: result.type, title: result.title, englishTitle: result.title, year: result.year, @@ -49,7 +50,8 @@ export class MyDramaListAPI extends APIModel { } else if (type.contains('series') || type.contains('show') || type.contains('drama') || type.contains('special')) { ret.push( new SeriesModel({ - type: result.type, + type: 'Series', + subType: result.type, title: result.title, englishTitle: result.title, year: result.year, @@ -86,7 +88,8 @@ export class MyDramaListAPI extends APIModel { const type = result.details.type.toLowerCase(); if (type.contains('movie')) { return new MovieModel({ - type: result.details.type, + type: 'Movie', + subType: result.details.type, title: result.title, englishTitle: result.title, nativeTitle: result?.others?.native_title ?? '', @@ -126,7 +129,8 @@ export class MyDramaListAPI extends APIModel { } as MovieModel); } else if (type.contains('series') || type.contains('show') || type.contains('drama') || type.contains('special')) { return new SeriesModel({ - type: result.details.type, + type: 'Series', + subType: result.details.type, title: result.title, nativeTitle: result?.others?.native_title ?? '', aliases: result?.others?.also_known_as ?? [], From 64382b3172c2cf40c7544102212f60464373f7d8 Mon Sep 17 00:00:00 2001 From: qubist-pixel-ux Date: Wed, 17 Jul 2024 16:46:59 +0530 Subject: [PATCH 7/7] ReadMe : Add MyDramaList --- README.md | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 37138fc..276138d 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ ## Obsidian Media DB Plugin -A plugin that can query multiple APIs for movies, series, anime, manga, games, music and wiki articles, and import them into your vault. +A plugin that can query multiple APIs for movies, series, asian dramas, anime, manga, games, music and wiki articles, and import them into your vault. ### Features #### Search by Title -Search a movie, series, anime, game, music release or wiki article by its name across multiple APIs. +Search a movie, series, asian dramas, anime, game, music release or wiki article by its name across multiple APIs. #### Search by ID @@ -104,6 +104,7 @@ Now you select the result you want and the plugin will cast it's magic and creat - movies (including specials) - series (including OVAs) +- Asian Dramas and Movies (including specials) - games - music releases - wiki articles @@ -111,23 +112,29 @@ Now you select the result you want and the plugin will cast it's magic and creat ### 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 | -| [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 | -| [Steam](https://store.steampowered.com/) | The Steam API offers information on all steam games. | games | No | 10000 per day | No | -| [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/) | 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 | +| 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 | +| [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 | +| [MyDramaList](https://mydramalist.com/) | MyDramaList offers metadata for Asian Dramas, movies, specials, etc. [Unofficial API](https://github.com/tbdsux/kuryana) is being used. | series, movies, specials | No | No | 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 | +| [Steam](https://store.steampowered.com/) | The Steam API offers information on all steam games. | games | No | 10000 per day | No | +| [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/) | 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 | #### 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" +- [MyDramaList](https://mydramalist.com/) + - [Unofficial API](https://github.com/tbdsux/kuryana/) is being used + - Ratelimit is unknown + #### Search by ID - [Jikan](https://jikan.moe/) @@ -142,6 +149,9 @@ 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 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` +- [MyDramaList](https://mydramalist.com/) + - Id is in the URL + - e.g. for "The Roundup" the URL looks like this `https://mydramalist.com/29612-the-outlaws-2/` so the ID is `29612-the-outlaws-2` - [MusicBrainz](https://musicbrainz.org/) - the id of a release is not easily accessible, you are better off just searching by title - [Wikipedia](https://en.wikipedia.org/wiki/Main_Page)