parent
e48963487b
commit
f5b9020dc8
16 changed files with 225 additions and 64 deletions
|
|
@ -1,10 +1,11 @@
|
|||
import { MediaTypeModel } from '../models/MediaTypeModel';
|
||||
import { MediaType } from '../utils/MediaType';
|
||||
|
||||
export abstract class APIModel {
|
||||
apiName: string;
|
||||
apiUrl: string;
|
||||
apiDescription: string;
|
||||
types: string[];
|
||||
types: MediaType[];
|
||||
|
||||
/**
|
||||
* This function should query the api and return a list of matches. The matches should be caped at 20.
|
||||
|
|
@ -15,12 +16,11 @@ export abstract class APIModel {
|
|||
|
||||
abstract getById(id: string): Promise<MediaTypeModel>;
|
||||
|
||||
hasType(type: string): boolean {
|
||||
hasType(type: MediaType): boolean {
|
||||
return this.types.contains(type);
|
||||
}
|
||||
|
||||
// for future use (https://github.com/mProjectsCode/obsidian-media-db-plugin/issues/5)
|
||||
hasTypeOverlap(types: string[]): boolean {
|
||||
hasTypeOverlap(types: MediaType[]): boolean {
|
||||
for (const type of types) {
|
||||
if (this.hasType(type)) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ import { APIModel } from '../APIModel';
|
|||
import { MediaTypeModel } from '../../models/MediaTypeModel';
|
||||
import MediaDbPlugin from '../../main';
|
||||
import { BoardGameModel } from 'src/models/BoardGameModel';
|
||||
import { debugLog } from '../../utils/Utils';
|
||||
import { requestUrl } from 'obsidian';
|
||||
import { MediaType } from '../../utils/MediaType';
|
||||
|
||||
export class BoardGameGeekAPI extends APIModel {
|
||||
plugin: MediaDbPlugin;
|
||||
|
|
@ -15,7 +15,7 @@ export class BoardGameGeekAPI extends APIModel {
|
|||
this.apiName = 'BoardGameGeekAPI';
|
||||
this.apiDescription = 'A free API for BoardGameGeek things.';
|
||||
this.apiUrl = 'https://api.geekdo.com/xmlapi';
|
||||
this.types = ['boardgames'];
|
||||
this.types = [MediaType.BoardGame];
|
||||
}
|
||||
|
||||
async searchByTitle(title: string): Promise<MediaTypeModel[]> {
|
||||
|
|
@ -33,13 +33,13 @@ export class BoardGameGeekAPI extends APIModel {
|
|||
const data = fetchData.text;
|
||||
const response = new window.DOMParser().parseFromString(data, 'text/xml');
|
||||
|
||||
debugLog(response);
|
||||
console.debug(response);
|
||||
|
||||
let ret: MediaTypeModel[] = [];
|
||||
|
||||
for (const boardgame of Array.from(response.querySelectorAll('boardgame'))) {
|
||||
const id = boardgame.attributes.getNamedItem('objectid')!.value;
|
||||
const title = boardgame.querySelector('name')!.textContent!;
|
||||
const title = boardgame.querySelector('name[primary=true]')?.textContent ?? boardgame.querySelector('name')!.textContent!;
|
||||
const year = boardgame.querySelector('yearpublished')?.textContent ?? '';
|
||||
|
||||
ret.push(
|
||||
|
|
@ -70,17 +70,22 @@ export class BoardGameGeekAPI extends APIModel {
|
|||
|
||||
const data = fetchData.text;
|
||||
const response = new window.DOMParser().parseFromString(data, 'text/xml');
|
||||
debugLog(response);
|
||||
console.debug(response);
|
||||
|
||||
const boardgame = response.querySelector('boardgame')!;
|
||||
const title = boardgame.querySelector('name')!.textContent!;
|
||||
const title = boardgame.querySelector('name[primary=true]')!.textContent!;
|
||||
const year = boardgame.querySelector('yearpublished')?.textContent ?? '';
|
||||
const image = boardgame.querySelector('image')?.textContent ?? undefined;
|
||||
const onlineRating = Number.parseFloat(boardgame.querySelector('statistics ratings average')?.textContent ?? '');
|
||||
const onlineRating = Number.parseFloat(boardgame.querySelector('statistics ratings average')?.textContent ?? '0');
|
||||
const genres = Array.from(boardgame.querySelectorAll('boardgamecategory')).map(n => n!.textContent!);
|
||||
const complexityRating = Number.parseFloat(boardgame.querySelector('averageweight')?.textContent ?? '0');
|
||||
const minPlayers = Number.parseFloat(boardgame.querySelector('minplayers')?.textContent ?? '0');
|
||||
const maxPlayers = Number.parseFloat(boardgame.querySelector('maxplayers')?.textContent ?? '0');
|
||||
const playtime = (boardgame.querySelector('playingtime')?.textContent ?? 'unknown') + ' minutes';
|
||||
const publishers = Array.from(boardgame.querySelectorAll('boardgamepublisher')).map(n => n!.textContent!);
|
||||
|
||||
const model = new BoardGameModel({
|
||||
title,
|
||||
title: title,
|
||||
englishTitle: title,
|
||||
year: year === '0' ? '' : year,
|
||||
dataSource: this.apiName,
|
||||
|
|
@ -89,7 +94,13 @@ export class BoardGameGeekAPI extends APIModel {
|
|||
|
||||
genres: genres,
|
||||
onlineRating: onlineRating,
|
||||
complexityRating: complexityRating,
|
||||
minPlayers: minPlayers,
|
||||
maxPlayers: maxPlayers,
|
||||
playtime: playtime,
|
||||
publishers: publishers,
|
||||
image: image,
|
||||
|
||||
released: true,
|
||||
|
||||
userData: {
|
||||
|
|
|
|||
|
|
@ -25,14 +25,14 @@ export class LocGovAPI extends APIModel {
|
|||
|
||||
const searchUrl = `https://www.loc.gov/search/?q=${encodeURIComponent(title)}&fo=json&c=20`;
|
||||
const fetchData = await fetch(searchUrl);
|
||||
debugLog(fetchData);
|
||||
console.debug(fetchData);
|
||||
|
||||
if (fetchData.status !== 200) {
|
||||
throw Error(`MDB | Received status code ${fetchData.status} from an API.`);
|
||||
}
|
||||
|
||||
const data = await fetchData.json();
|
||||
debugLog(data);
|
||||
console.debug(data);
|
||||
let ret: MediaTypeModel[] = [];
|
||||
|
||||
throw new Error('MDB | Under construction, API implementation not finished');
|
||||
|
|
@ -50,7 +50,7 @@ export class LocGovAPI extends APIModel {
|
|||
}
|
||||
|
||||
const data = await fetchData.json();
|
||||
debugLog(data);
|
||||
console.debug(data);
|
||||
const result = data.data;
|
||||
|
||||
const type = this.typeMappings.get(result.type.toLowerCase());
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { MediaTypeModel } from '../../models/MediaTypeModel';
|
|||
import { MovieModel } from '../../models/MovieModel';
|
||||
import MediaDbPlugin from '../../main';
|
||||
import { SeriesModel } from '../../models/SeriesModel';
|
||||
import { debugLog } from '../../utils/Utils';
|
||||
import { MediaType } from '../../utils/MediaType';
|
||||
|
||||
export class MALAPI extends APIModel {
|
||||
plugin: MediaDbPlugin;
|
||||
|
|
@ -16,7 +16,7 @@ export class MALAPI extends APIModel {
|
|||
this.apiName = 'MALAPI';
|
||||
this.apiDescription = 'A free API for Anime. Some results may take a long time to load.';
|
||||
this.apiUrl = 'https://jikan.moe/';
|
||||
this.types = ['movie', 'series', 'anime'];
|
||||
this.types = [MediaType.Movie, MediaType.Series];
|
||||
this.typeMappings = new Map<string, string>();
|
||||
this.typeMappings.set('movie', 'movie');
|
||||
this.typeMappings.set('special', 'special');
|
||||
|
|
@ -30,13 +30,13 @@ export class MALAPI extends APIModel {
|
|||
const searchUrl = `https://api.jikan.moe/v4/anime?q=${encodeURIComponent(title)}&limit=20${this.plugin.settings.sfwFilter ? '&sfw' : ''}`;
|
||||
|
||||
const fetchData = await fetch(searchUrl);
|
||||
debugLog(fetchData);
|
||||
console.debug(fetchData);
|
||||
if (fetchData.status !== 200) {
|
||||
throw Error(`MDB | Received status code ${fetchData.status} from an API.`);
|
||||
}
|
||||
const data = await fetchData.json();
|
||||
|
||||
debugLog(data);
|
||||
console.debug(data);
|
||||
|
||||
let ret: MediaTypeModel[] = [];
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ export class MALAPI extends APIModel {
|
|||
async getById(id: string): Promise<MediaTypeModel> {
|
||||
console.log(`MDB | api "${this.apiName}" queried by ID`);
|
||||
|
||||
const searchUrl = `https://api.jikan.moe/v4/anime/${encodeURIComponent(id)}`;
|
||||
const searchUrl = `https://api.jikan.moe/v4/anime/${encodeURIComponent(id)}/full`;
|
||||
const fetchData = await fetch(searchUrl);
|
||||
|
||||
if (fetchData.status !== 200) {
|
||||
|
|
@ -93,7 +93,7 @@ export class MALAPI extends APIModel {
|
|||
}
|
||||
|
||||
const data = await fetchData.json();
|
||||
debugLog(data);
|
||||
console.debug(data);
|
||||
const result = data.data;
|
||||
|
||||
const type = this.typeMappings.get(result.type?.toLowerCase());
|
||||
|
|
@ -111,10 +111,12 @@ export class MALAPI extends APIModel {
|
|||
producer: result.studios?.map((x: any) => x.name).join(', ') ?? 'unknown',
|
||||
duration: result.duration ?? 'unknown',
|
||||
onlineRating: result.score ?? 0,
|
||||
actors: [],
|
||||
image: result.images?.jpg?.image_url ?? '',
|
||||
|
||||
released: true,
|
||||
premiere: new Date(result.aired?.from).toLocaleDateString() ?? 'unknown',
|
||||
streamingServices: result.streaming?.map((x: any) => x.name) ?? [],
|
||||
|
||||
userData: {
|
||||
watched: false,
|
||||
|
|
@ -140,10 +142,12 @@ export class MALAPI extends APIModel {
|
|||
producer: result.studios?.map((x: any) => x.name).join(', ') ?? 'unknown',
|
||||
duration: result.duration ?? 'unknown',
|
||||
onlineRating: result.score ?? 0,
|
||||
actors: [],
|
||||
image: result.images?.jpg?.image_url ?? '',
|
||||
|
||||
released: true,
|
||||
premiere: new Date(result.aired?.from).toLocaleDateString() ?? 'unknown',
|
||||
streamingServices: result.streaming?.map((x: any) => x.name) ?? [],
|
||||
|
||||
userData: {
|
||||
watched: false,
|
||||
|
|
@ -168,6 +172,7 @@ export class MALAPI extends APIModel {
|
|||
episodes: result.episodes,
|
||||
duration: result.duration ?? 'unknown',
|
||||
onlineRating: result.score ?? 0,
|
||||
streamingServices: result.streaming?.map((x: any) => x.name) ?? [],
|
||||
image: result.images?.jpg?.image_url ?? '',
|
||||
|
||||
released: true,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ import { MediaTypeModel } from '../../models/MediaTypeModel';
|
|||
import MediaDbPlugin from '../../main';
|
||||
import { requestUrl } from 'obsidian';
|
||||
import { MusicReleaseModel } from '../../models/MusicReleaseModel';
|
||||
import { contactEmail, debugLog, mediaDbVersion, pluginName } from '../../utils/Utils';
|
||||
import { contactEmail, mediaDbVersion, pluginName } from '../../utils/Utils';
|
||||
import { MediaType } from '../../utils/MediaType';
|
||||
|
||||
export class MusicBrainzAPI extends APIModel {
|
||||
plugin: MediaDbPlugin;
|
||||
|
|
@ -15,7 +16,7 @@ export class MusicBrainzAPI extends APIModel {
|
|||
this.apiName = 'MusicBrainz API';
|
||||
this.apiDescription = 'Free API for music albums.';
|
||||
this.apiUrl = 'https://musicbrainz.org/';
|
||||
this.types = ['music'];
|
||||
this.types = [MediaType.MusicRelease];
|
||||
}
|
||||
|
||||
async searchByTitle(title: string): Promise<MediaTypeModel[]> {
|
||||
|
|
@ -30,14 +31,14 @@ export class MusicBrainzAPI extends APIModel {
|
|||
},
|
||||
});
|
||||
|
||||
debugLog(fetchData);
|
||||
console.debug(fetchData);
|
||||
|
||||
if (fetchData.status !== 200) {
|
||||
throw Error(`MDB | Received status code ${fetchData.status} from an API.`);
|
||||
}
|
||||
|
||||
const data = await fetchData.json;
|
||||
debugLog(data);
|
||||
console.debug(data);
|
||||
let ret: MediaTypeModel[] = [];
|
||||
|
||||
for (const result of data['release-groups']) {
|
||||
|
|
@ -76,7 +77,7 @@ export class MusicBrainzAPI extends APIModel {
|
|||
}
|
||||
|
||||
const data = await fetchData.json;
|
||||
debugLog(data);
|
||||
console.debug(data);
|
||||
const result = data;
|
||||
|
||||
const model = new MusicReleaseModel({
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { MovieModel } from '../../models/MovieModel';
|
|||
import MediaDbPlugin from '../../main';
|
||||
import { SeriesModel } from '../../models/SeriesModel';
|
||||
import { GameModel } from '../../models/GameModel';
|
||||
import { debugLog } from '../../utils/Utils';
|
||||
import { MediaType } from '../../utils/MediaType';
|
||||
|
||||
export class OMDbAPI extends APIModel {
|
||||
plugin: MediaDbPlugin;
|
||||
|
|
@ -17,7 +17,7 @@ export class OMDbAPI extends APIModel {
|
|||
this.apiName = 'OMDbAPI';
|
||||
this.apiDescription = 'A free API for Movies, Series and Games.';
|
||||
this.apiUrl = 'http://www.omdbapi.com/';
|
||||
this.types = ['movie', 'series'];
|
||||
this.types = [MediaType.Movie, MediaType.Series, MediaType.Game];
|
||||
this.typeMappings = new Map<string, string>();
|
||||
this.typeMappings.set('movie', 'movie');
|
||||
this.typeMappings.set('series', 'series');
|
||||
|
|
@ -46,7 +46,7 @@ export class OMDbAPI extends APIModel {
|
|||
return [];
|
||||
}
|
||||
|
||||
debugLog(data.Search);
|
||||
console.debug(data.Search);
|
||||
|
||||
let ret: MediaTypeModel[] = [];
|
||||
|
||||
|
|
@ -108,7 +108,7 @@ export class OMDbAPI extends APIModel {
|
|||
}
|
||||
|
||||
const result = await fetchData.json();
|
||||
debugLog(result);
|
||||
console.debug(result);
|
||||
|
||||
if (result.Response === 'False') {
|
||||
throw Error(`MDB | Received error from ${this.apiName}: ${result.Error}`);
|
||||
|
|
@ -133,9 +133,11 @@ export class OMDbAPI extends APIModel {
|
|||
producer: result.Director ?? 'unknown',
|
||||
duration: result.Runtime ?? 'unknown',
|
||||
onlineRating: Number.parseFloat(result.imdbRating ?? 0),
|
||||
actors: result.Actors?.split(', ') ?? [],
|
||||
image: result.Poster ?? '',
|
||||
|
||||
released: true,
|
||||
streamingServices: [],
|
||||
premiere: new Date(result.Released).toLocaleDateString() ?? 'unknown',
|
||||
|
||||
userData: {
|
||||
|
|
@ -161,9 +163,11 @@ export class OMDbAPI extends APIModel {
|
|||
episodes: 0,
|
||||
duration: result.Runtime ?? 'unknown',
|
||||
onlineRating: Number.parseFloat(result.imdbRating ?? 0),
|
||||
actors: result.Actors?.split(', ') ?? [],
|
||||
image: result.Poster ?? '',
|
||||
|
||||
released: true,
|
||||
streamingServices: [],
|
||||
airing: false,
|
||||
airedFrom: new Date(result.Released).toLocaleDateString() ?? 'unknown',
|
||||
airedTo: 'unknown',
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import { APIModel } from '../APIModel';
|
|||
import { MediaTypeModel } from '../../models/MediaTypeModel';
|
||||
import MediaDbPlugin from '../../main';
|
||||
import { GameModel } from '../../models/GameModel';
|
||||
import { debugLog } from '../../utils/Utils';
|
||||
import { requestUrl } from 'obsidian';
|
||||
import { MediaType } from '../../utils/MediaType';
|
||||
|
||||
|
|
@ -17,7 +16,7 @@ export class SteamAPI extends APIModel {
|
|||
this.apiName = 'SteamAPI';
|
||||
this.apiDescription = 'A free API for all Steam games.';
|
||||
this.apiUrl = 'http://www.steampowered.com/';
|
||||
this.types = ['games'];
|
||||
this.types = [MediaType.Game];
|
||||
this.typeMappings = new Map<string, string>();
|
||||
this.typeMappings.set('game', 'game');
|
||||
}
|
||||
|
|
@ -36,7 +35,7 @@ export class SteamAPI extends APIModel {
|
|||
|
||||
const data = await fetchData.json;
|
||||
|
||||
debugLog(data);
|
||||
console.debug(data);
|
||||
|
||||
let filteredData = [];
|
||||
|
||||
|
|
@ -79,7 +78,7 @@ export class SteamAPI extends APIModel {
|
|||
throw Error(`MDB | Received status code ${fetchData.status} from an API.`);
|
||||
}
|
||||
|
||||
debugLog(await fetchData.json);
|
||||
console.debug(await fetchData.json);
|
||||
|
||||
let result: any;
|
||||
for (const [key, value] of Object.entries(await fetchData.json)) {
|
||||
|
|
@ -94,7 +93,7 @@ export class SteamAPI extends APIModel {
|
|||
throw Error(`MDB | API returned invalid data.`);
|
||||
}
|
||||
|
||||
debugLog(result);
|
||||
console.debug(result);
|
||||
|
||||
const model = new GameModel({
|
||||
type: MediaType.Game,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { APIModel } from '../APIModel';
|
|||
import { MediaTypeModel } from '../../models/MediaTypeModel';
|
||||
import MediaDbPlugin from '../../main';
|
||||
import { WikiModel } from '../../models/WikiModel';
|
||||
import { debugLog } from '../../utils/Utils';
|
||||
import { MediaType } from '../../utils/MediaType';
|
||||
|
||||
export class WikipediaAPI extends APIModel {
|
||||
plugin: MediaDbPlugin;
|
||||
|
|
@ -14,7 +14,7 @@ export class WikipediaAPI extends APIModel {
|
|||
this.apiName = 'Wikipedia API';
|
||||
this.apiDescription = 'The API behind Wikipedia';
|
||||
this.apiUrl = 'https://www.wikipedia.com';
|
||||
this.types = ['wiki'];
|
||||
this.types = [MediaType.Wiki];
|
||||
}
|
||||
|
||||
async searchByTitle(title: string): Promise<MediaTypeModel[]> {
|
||||
|
|
@ -22,14 +22,14 @@ export class WikipediaAPI extends APIModel {
|
|||
|
||||
const searchUrl = `https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=${encodeURIComponent(title)}&srlimit=20&utf8=&format=json&origin=*`;
|
||||
const fetchData = await fetch(searchUrl);
|
||||
debugLog(fetchData);
|
||||
console.debug(fetchData);
|
||||
|
||||
if (fetchData.status !== 200) {
|
||||
throw Error(`MDB | Received status code ${fetchData.status} from an API.`);
|
||||
}
|
||||
|
||||
const data = await fetchData.json();
|
||||
debugLog(data);
|
||||
console.debug(data);
|
||||
let ret: MediaTypeModel[] = [];
|
||||
|
||||
for (const result of data.query.search) {
|
||||
|
|
@ -59,7 +59,7 @@ export class WikipediaAPI extends APIModel {
|
|||
}
|
||||
|
||||
const data = await fetchData.json();
|
||||
debugLog(data);
|
||||
console.debug(data);
|
||||
const result: any = Object.entries(data?.query?.pages)[0][1];
|
||||
|
||||
const model = new WikiModel({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue