clean up merged PRs

This commit is contained in:
Moritz Jung 2025-08-31 11:34:23 +02:00
parent 6699805001
commit 75166ec77c
5 changed files with 73 additions and 108 deletions

View file

@ -61,7 +61,7 @@ export class MobyGamesAPI extends APIModel {
year: new Date(result.platforms[0].first_release_date).getFullYear().toString(),
dataSource: this.apiName,
id: result.game_id,
} as GameModel),
}),
);
}

View file

@ -3,9 +3,8 @@ import type MediaDbPlugin from '../../main';
import type { MediaTypeModel } from '../../models/MediaTypeModel';
import { MusicReleaseModel } from '../../models/MusicReleaseModel';
import { MediaType } from '../../utils/MediaType';
import { contactEmail, extractTracksFromMedia, getLanguageName, mediaDbVersion, pluginName } from '../../utils/Utils';
import { contactEmail, getLanguageName, mediaDbVersion, pluginName } from '../../utils/Utils';
import { APIModel } from '../APIModel';
import { iso6392 } from 'iso-639-2';
// sadly no open api schema available
@ -26,6 +25,18 @@ interface Release {
status: string;
}
interface ArtistCredit {
name: string;
artist: {
tags: Tag[];
type: string;
id: string;
name: string;
'short-name': string;
country: string;
};
}
interface SearchResponse {
id: string;
'type-id': string;
@ -36,14 +47,7 @@ interface SearchResponse {
title: string;
'first-release-date': string;
'primary-type': string;
'artist-credit': {
name: string;
artist: {
id: string;
name: string;
'short-name': string;
};
}[];
'artist-credit': ArtistCredit[];
releases: Release[];
tags: Tag[];
}
@ -52,17 +56,7 @@ interface IdResponse {
id: string;
tags: Tag[];
'primary-type-id': string;
'artist-credit': {
name: string;
artist: {
tags: Tag[];
type: string;
id: string;
name: string;
'short-name': string;
country: string;
};
}[];
'artist-credit': ArtistCredit[];
title: string;
genres: Genre[];
'first-release-date': string;
@ -74,6 +68,27 @@ interface IdResponse {
};
}
interface MediaResponse {
media: {
'track-count': number;
tracks: {
'artist-credit': ArtistCredit[];
length: number | null;
number: string;
position: number;
title: string;
recording: {
length: number;
title: string;
};
}[];
}[];
'text-representation': {
language: string;
script: string;
};
}
export class MusicBrainzAPI extends APIModel {
plugin: MediaDbPlugin;
apiDateFormat: string = 'YYYY-MM-DD';
@ -173,9 +188,11 @@ export class MusicBrainzAPI extends APIModel {
throw Error(`MDB | Received status code ${releaseResponse.status} from ${this.apiName}.`);
}
const releaseData = await releaseResponse.json;
const releaseData = (await releaseResponse.json) as MediaResponse;
const tracks = extractTracksFromMedia(releaseData.media);
console.log(releaseData);
return new MusicReleaseModel({
type: 'musicRelease',
title: result.title,
@ -204,3 +221,32 @@ export class MusicBrainzAPI extends APIModel {
return this.plugin.settings.MusicBrainzAPI_disabledMediaTypes;
}
}
function extractTracksFromMedia(media: MediaResponse['media']): {
number: number;
title: string;
duration: string;
featuredArtists: string[];
}[] {
if (!media || media.length === 0 || !media[0].tracks) return [];
return media[0].tracks.map((track, index) => {
const title = track.title ?? track.recording?.title ?? 'Unknown Title';
const rawLength = track.length ?? track.recording?.length;
const duration = rawLength ? millisecondsToMinutes(rawLength) : 'unknown';
const featuredArtists = track['artist-credit']?.map(ac => ac.name) ?? [];
return {
number: index + 1,
title,
duration,
featuredArtists,
};
});
}
function millisecondsToMinutes(milliseconds: number): string {
const minutes = Math.floor(milliseconds / 60000);
const seconds = Math.floor((milliseconds % 60000) / 1000);
return `${minutes}:${seconds.toString().padStart(2, '0')}`;
}

View file

@ -1,5 +1,5 @@
import { MarkdownView, Notice, parseYaml, Plugin, stringifyYaml, TFile, TFolder } from 'obsidian';
import { requestUrl, normalizePath } from 'obsidian'; // Add requestUrl import
import { requestUrl, normalizePath } from 'obsidian';
import type { MediaType } from 'src/utils/MediaType';
import { APIManager } from './api/APIManager';
import { BoardGameGeekAPI } from './api/apis/BoardGameGeekAPI';
@ -59,7 +59,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 LocGovAPI(this)); // TODO: parse data
this.mediaTypeManager = new MediaTypeManager();
this.modelPropertyMapper = new PropertyMapper(this);
@ -157,12 +156,6 @@ export default class MediaDbPlugin extends Plugin {
});
}
/**
* first very simple approach
* TODO:
* - replace the detail query
* - maybe custom link syntax
*/
async createLinkWithSearchModal(): Promise<void> {
const apiSearchResults = await this.modalHelper.openAdvancedSearchModal({}, async advancedSearchModalData => {
return await this.apiManager.query(advancedSearchModalData.query, advancedSearchModalData.apis);
@ -381,18 +374,7 @@ export default class MediaDbPlugin extends Plugin {
* @param options
*/
async generateMediaDbNoteContents(mediaTypeModel: MediaTypeModel, options: CreateNoteOptions): Promise<string> {
const template = await this.mediaTypeManager.getTemplate(mediaTypeModel, this.app);
return this.generateContentWithDefaultFrontMatter(mediaTypeModel, options, template);
// if (this.settings.useDefaultFrontMatter || !template) {
// return this.generateContentWithDefaultFrontMatter(mediaTypeModel, options, template);
// } else {
// return this.generateContentWithCustomFrontMatter(mediaTypeModel, options, template);
// }
}
async generateContentWithDefaultFrontMatter(mediaTypeModel: MediaTypeModel, options: CreateNoteOptions, template?: string): Promise<string> {
let template = await this.mediaTypeManager.getTemplate(mediaTypeModel, this.app);
let fileMetadata: Record<string, unknown>;
if (this.settings.useDefaultFrontMatter) {
@ -421,48 +403,6 @@ export default class MediaDbPlugin extends Plugin {
return fileContent;
}
async generateContentWithCustomFrontMatter(mediaTypeModel: MediaTypeModel, options: CreateNoteOptions, template: string): Promise<string> {
const regExp = new RegExp(this.frontMatterRexExpPattern);
const frontMatter = this.getMetaDataFromFileContent(template);
let fileContent: string = template.replace(regExp, '');
// Updating a previous file
if (options.attachFile) {
const previousMetadata = this.app.metadataCache.getFileCache(options.attachFile)?.frontmatter ?? {};
// Use contents (below front matter) from previous file
fileContent = await this.app.vault.read(options.attachFile);
fileContent = fileContent.replace(regExp, '');
fileContent = fileContent.startsWith('\n') ? fileContent.substring(1) : fileContent;
// Update updated front matter with entries from the old front matter, if it isn't defined in the new front matter
Object.keys(previousMetadata).forEach(key => {
const value: unknown = previousMetadata[key];
if (!frontMatter[key] && value) {
frontMatter[key] = value;
}
});
}
// Ensure that id, type, and dataSource are defined
frontMatter.id ??= mediaTypeModel.id;
frontMatter.type ??= mediaTypeModel.type;
frontMatter.dataSource ??= mediaTypeModel.dataSource;
if (this.settings.enableTemplaterIntegration && hasTemplaterPlugin(this.app)) {
// Only support stringifyYaml for templater plugin
// Include the media variable in all templater commands by using a top level JavaScript execution command.
fileContent = `---\n<%* const media = ${JSON.stringify(mediaTypeModel)} %>\n${stringifyYaml(frontMatter)}---\n${fileContent}`;
} else {
fileContent = `---\n${stringifyYaml(frontMatter)}---\n${fileContent}`;
}
return fileContent;
}
async attachFile(fileMetadata: Metadata, fileContent: string, fileToAttach?: TFile): Promise<{ fileMetadata: Metadata; fileContent: string }> {
if (!fileToAttach) {
return { fileMetadata: fileMetadata, fileContent: fileContent };

View file

@ -1,6 +1,6 @@
import { MediaType } from '../utils/MediaType';
import type { ModelToData } from '../utils/Utils';
import { mediaDbTag, migrateObject, getLanguageName } from '../utils/Utils';
import { mediaDbTag, migrateObject } from '../utils/Utils';
import { MediaTypeModel } from './MediaTypeModel';
export type MusicReleaseData = ModelToData<MusicReleaseModel>;

View file

@ -1,7 +1,7 @@
import { iso6392 } from 'iso-639-2';
import type { TFile, TFolder, App } from 'obsidian';
import { requestUrl } from 'obsidian';
import type { MediaTypeModel } from '../models/MediaTypeModel';
import { iso6392 } from 'iso-639-2';
export const pluginName: string = 'obsidian-media-db-plugin';
export const contactEmail: string = 'm.projects.code@gmail.com';
@ -297,28 +297,7 @@ export async function obsidianFetch(input: Request): Promise<Response> {
text: async () => res.text,
} as Response;
}
export function extractTracksFromMedia(media: any[]): {
number: number;
title: string;
duration: string;
featuredArtists: string[];
}[] {
if (!media || media.length === 0 || !media[0].tracks) return [];
return media[0].tracks.map((track: any, index: number) => {
const title = track.title || track.recording?.title || 'Unknown Title';
const rawLength = track.length || track.recording?.length;
const duration = rawLength ? new Date(rawLength).toISOString().substr(14, 5) : 'unknown';
const featuredArtists = track['artist-credit']?.map((ac: { name: string }) => ac.name) ?? [];
return {
number: index + 1,
title,
duration,
featuredArtists,
};
});
}
export function getLanguageName(code: string): string | null {
const language = iso6392.find(lang => lang.iso6392B === code || lang.iso6392T === code);