obsidian-media-db-sync/src/api/apis/ComicVineAPI.ts
2026-04-06 17:05:45 +02:00

117 lines
3.2 KiB
TypeScript

/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access */
import { requestUrl } from 'obsidian';
import type MediaDbPlugin from '../../main';
import { ComicMangaModel } from '../../models/ComicMangaModel';
import type { MediaTypeModel } from '../../models/MediaTypeModel';
import { MediaType } from '../../utils/MediaType';
import { APIModel } from '../APIModel';
// sadly no open api schema available
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.ComicManga];
}
async searchByTitle(title: string): Promise<MediaTypeModel[]> {
console.log(`MDB | api "${this.apiName}" queried by Title`);
const key = this.plugin.app.secretStorage.getSecret(this.plugin.settings.ComicVineKeyId);
if (!key) {
throw new Error(`MDB | API key for ${this.apiName} missing.`);
}
const searchUrl = `${this.apiUrl}/search/?api_key=${key}&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 ComicMangaModel({
title: result.name,
englishTitle: result.name,
year: result.start_year,
dataSource: this.apiName,
id: `4050-${result.id}`,
publishers: result.publisher?.name,
}),
);
}
return ret;
}
async getById(id: string): Promise<MediaTypeModel> {
console.log(`MDB | api "${this.apiName}" queried by ID`);
const key = this.plugin.app.secretStorage.getSecret(this.plugin.settings.ComicVineKeyId);
if (!key) {
throw new Error(`MDB | API key for ${this.apiName} missing.`);
}
const searchUrl = `${this.apiUrl}/volume/${encodeURIComponent(id)}/?api_key=${key}&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;
const result = data.results;
const authors = result.people as
| {
name: string;
}[]
| undefined;
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}`,
authors: authors?.map(x => x.name),
chapters: result.count_of_issues,
image: result.image?.original_url,
released: true,
publishers: result.publisher?.name,
publishedFrom: result.start_year,
status: result.status,
userData: {
read: false,
lastRead: '',
personalRating: 0,
},
});
}
getDisabledMediaTypes(): MediaType[] {
return this.plugin.settings.ComicVineAPI_disabledMediaTypes;
}
}