Merge branch 'master' into release

This commit is contained in:
mProjectsCode 2022-07-02 13:14:41 +02:00
commit 317b43016b
10 changed files with 144 additions and 45 deletions

View file

@ -1,7 +1,7 @@
{ {
"id": "obsidian-media-db-plugin", "id": "obsidian-media-db-plugin",
"name": "Media DB Plugin", "name": "Media DB Plugin",
"version": "0.3.0", "version": "0.3.1",
"minAppVersion": "0.14.0", "minAppVersion": "0.14.0",
"description": "A plugin that can query multiple APIs for movies, series, anime, games, music and wiki articles, and import them into your vault.", "description": "A plugin that can query multiple APIs for movies, series, anime, games, music and wiki articles, and import them into your vault.",
"author": "Moritz Jung", "author": "Moritz Jung",

View file

@ -1,6 +1,6 @@
{ {
"name": "obsidian-media-db-plugin", "name": "obsidian-media-db-plugin",
"version": "0.3.0", "version": "0.3.1",
"description": "A plugin that can query multiple APIs for movies, series, anime, games, music and wiki articles, and import them into your vault.", "description": "A plugin that can query multiple APIs for movies, series, anime, games, music and wiki articles, and import them into your vault.",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {

View file

@ -41,13 +41,20 @@ export class MALAPI extends APIModel {
let ret: MediaTypeModel[] = []; let ret: MediaTypeModel[] = [];
for (const result of data.data) { for (const result of data.data) {
const type = this.typeMappings.get(result.type.toLowerCase()); const type = this.typeMappings.get(result.type?.toLowerCase());
if (type === undefined) { if (type === undefined) {
continue; ret.push(new MovieModel({
subType: '',
title: result.title,
englishTitle: result.title_english ?? result.title,
year: result.year ?? result.aired?.prop?.from?.year ?? '',
dataSource: this.apiName,
id: result.mal_id,
} as MovieModel));
} }
if (type === 'movie' || type === 'special') { if (type === 'movie' || type === 'special') {
ret.push(new MovieModel({ ret.push(new MovieModel({
type: type, subType: type,
title: result.title, title: result.title,
englishTitle: result.title_english ?? result.title, englishTitle: result.title_english ?? result.title,
year: result.year ?? result.aired?.prop?.from?.year ?? '', year: result.year ?? result.aired?.prop?.from?.year ?? '',
@ -56,7 +63,7 @@ export class MALAPI extends APIModel {
} as MovieModel)); } as MovieModel));
} else if (type === 'series' || type === 'ova') { } else if (type === 'series' || type === 'ova') {
ret.push(new SeriesModel({ ret.push(new SeriesModel({
type: type, subType: type,
title: result.title, title: result.title,
englishTitle: result.title_english ?? result.title, englishTitle: result.title_english ?? result.title,
year: result.year ?? result.aired?.prop?.from?.year ?? '', year: result.year ?? result.aired?.prop?.from?.year ?? '',
@ -83,14 +90,39 @@ export class MALAPI extends APIModel {
debugLog(data); debugLog(data);
const result = data.data; const result = data.data;
const type = this.typeMappings.get(result.type.toLowerCase()); const type = this.typeMappings.get(result.type?.toLowerCase());
if (type === undefined) { if (type === undefined) {
throw Error(`${result.type.toLowerCase()} is an unsupported type.`); const model = new MovieModel({
subType: '',
title: result.title,
englishTitle: result.title_english ?? result.title,
year: result.year ?? result.aired?.prop?.from?.year ?? '',
dataSource: this.apiName,
url: result.url,
id: result.mal_id,
genres: result.genres?.map((x: any) => x.name) ?? [],
producer: result.studios?.map((x: any) => x.name).join(', ') ?? 'unknown',
duration: result.duration ?? 'unknown',
onlineRating: result.score ?? 0,
image: result.images?.jpg?.image_url ?? '',
released: true,
premiere: (new Date(result.aired?.from)).toLocaleDateString() ?? 'unknown',
userData: {
watched: false,
lastWatched: '',
personalRating: 0,
},
} as MovieModel);
return model;
} }
if (type === 'movie' || type === 'special') { if (type === 'movie' || type === 'special') {
const model = new MovieModel({ const model = new MovieModel({
type: type, subType: type,
title: result.title, title: result.title,
englishTitle: result.title_english ?? result.title, englishTitle: result.title_english ?? result.title,
year: result.year ?? result.aired?.prop?.from?.year ?? '', year: result.year ?? result.aired?.prop?.from?.year ?? '',
@ -117,7 +149,7 @@ export class MALAPI extends APIModel {
return model; return model;
} else if (type === 'series' || type === 'ova') { } else if (type === 'series' || type === 'ova') {
const model = new SeriesModel({ const model = new SeriesModel({
type: type, subType: type,
title: result.title, title: result.title,
englishTitle: result.title_english ?? result.title, englishTitle: result.title_english ?? result.title,
year: result.year ?? result.aired?.prop?.from?.year ?? '', year: result.year ?? result.aired?.prop?.from?.year ?? '',

View file

@ -1,4 +1,4 @@
import {Notice, Plugin, TFile, TFolder} from 'obsidian'; import {Notice, parseYaml, Plugin, stringifyYaml, TFile, TFolder} from 'obsidian';
import {DEFAULT_SETTINGS, MediaDbPluginSettings, MediaDbSettingTab} from './settings/Settings'; import {DEFAULT_SETTINGS, MediaDbPluginSettings, MediaDbSettingTab} from './settings/Settings';
import {APIManager} from './api/APIManager'; import {APIManager} from './api/APIManager';
import {MediaTypeModel} from './models/MediaTypeModel'; import {MediaTypeModel} from './models/MediaTypeModel';
@ -109,33 +109,13 @@ export default class MediaDbPlugin extends Plugin {
console.log('MDB | Creating new note...'); console.log('MDB | Creating new note...');
// console.log(mediaTypeModel); // console.log(mediaTypeModel);
let metadata = this.modelPropertyMapper.convertObject(mediaTypeModel.toMetaDataObject()); let fileMetadata = this.modelPropertyMapper.convertObject(mediaTypeModel.toMetaDataObject());
if (attachFile) { let fileContent = '';
let attachFileMetadata: any = this.app.metadataCache.getFileCache(attachFile).frontmatter;
if (attachFileMetadata) {
attachFileMetadata = JSON.parse(JSON.stringify(attachFileMetadata)); // deep copy
delete attachFileMetadata.position;
} else {
attachFileMetadata = {};
}
metadata = Object.assign(attachFileMetadata, metadata); ({fileMetadata, fileContent} = await this.attachFile(fileMetadata, fileContent, attachFile));
} ({fileMetadata, fileContent} = await this.attachTemplate(fileMetadata, fileContent, await this.mediaTypeManager.getTemplate(mediaTypeModel, this.app)));
debugLog(metadata); fileContent = `---\n${this.settings.useCustomYamlStringifier ? YAMLConverter.toYaml(fileMetadata) : stringifyYaml(fileMetadata)}---\n` + fileContent;
let fileContent = `---\n${YAMLConverter.toYaml(metadata)}---\n`;
if (this.settings.templates) {
fileContent += await this.mediaTypeManager.getContent(mediaTypeModel, this.app);
}
if (attachFile) {
let attachFileContent: string = await this.app.vault.read(attachFile);
const regExp = new RegExp('^(---)\\n[\\s\\S]*\\n---');
attachFileContent = attachFileContent.replace(regExp, '');
fileContent += '\n\n' + attachFileContent;
}
await this.createNote(this.mediaTypeManager.getFileName(mediaTypeModel), fileContent); await this.createNote(this.mediaTypeManager.getFileName(mediaTypeModel), fileContent);
} catch (e) { } catch (e) {
@ -144,6 +124,67 @@ export default class MediaDbPlugin extends Plugin {
} }
} }
async attachFile(fileMetadata: any, fileContent: string, fileToAttach?: TFile): Promise<{ fileMetadata: any, fileContent: string }> {
if (!fileToAttach) {
return {fileMetadata: fileMetadata, fileContent: fileContent};
}
let attachFileMetadata: any = this.app.metadataCache.getFileCache(fileToAttach).frontmatter;
if (attachFileMetadata) {
attachFileMetadata = JSON.parse(JSON.stringify(attachFileMetadata)); // deep copy
delete attachFileMetadata.position;
} else {
attachFileMetadata = {};
}
fileMetadata = Object.assign(attachFileMetadata, fileMetadata);
let attachFileContent: string = await this.app.vault.read(fileToAttach);
const regExp = new RegExp('^(---)\\n[\\s\\S]*\\n---');
attachFileContent = attachFileContent.replace(regExp, '');
fileContent += '\n' + attachFileContent;
return {fileMetadata: fileMetadata, fileContent: fileContent};
}
async attachTemplate(fileMetadata: any, fileContent: string, template: string): Promise<{ fileMetadata: any, fileContent: string }> {
if (!template) {
return {fileMetadata: fileMetadata, fileContent: fileContent};
}
let templateMetadata: any = this.getMetaDataFromFileContent(template);
fileMetadata = Object.assign(templateMetadata, fileMetadata);
const regExp = new RegExp('^(---)\\n[\\s\\S]*\\n---');
const attachFileContent = template.replace(regExp, '');
fileContent += '\n' + attachFileContent;
return {fileMetadata: fileMetadata, fileContent: fileContent};
}
getMetaDataFromFileContent(fileContent: string): any {
let metadata: any;
const regExp = new RegExp('^(---)\\n[\\s\\S]*\\n---');
const frontMatterRegExpResult = regExp.exec(fileContent);
if (!frontMatterRegExpResult) {
return {};
}
let frontMatter = frontMatterRegExpResult[0];
if (!frontMatter) {
return {};
}
frontMatter = frontMatter.substring(4);
frontMatter = frontMatter.substring(0, frontMatter.length - 3);
metadata = parseYaml(frontMatter);
if (!metadata) {
metadata = {};
}
return metadata;
}
async createNote(fileName: string, fileContent: string, openFile: boolean = false) { async createNote(fileName: string, fileContent: string, openFile: boolean = false) {
fileName = replaceIllegalFileNameCharactersInString(fileName); fileName = replaceIllegalFileNameCharactersInString(fileName);
const filePath = `${this.settings.folder.replace(/\/$/, '')}/${fileName}.md`; const filePath = `${this.settings.folder.replace(/\/$/, '')}/${fileName}.md`;

View file

@ -46,7 +46,7 @@ export class MediaDbFolderImportModal extends Modal {
const appendContentToggleElementWrapper = contentEl.createEl('div', {cls: 'media-db-plugin-list-wrapper'}); const appendContentToggleElementWrapper = contentEl.createEl('div', {cls: 'media-db-plugin-list-wrapper'});
const appendContentToggleTextWrapper = appendContentToggleElementWrapper.createEl('div', {cls: 'media-db-plugin-list-text-wrapper'}); const appendContentToggleTextWrapper = appendContentToggleElementWrapper.createEl('div', {cls: 'media-db-plugin-list-text-wrapper'});
appendContentToggleTextWrapper.createEl('span', { appendContentToggleTextWrapper.createEl('span', {
text: 'If this is enabled, the plugin will override meta data fields with the same name.', text: 'If this is enabled, the plugin will override metadata fields with the same name.',
cls: 'media-db-plugin-list-text', cls: 'media-db-plugin-list-text',
}); });
@ -59,7 +59,7 @@ export class MediaDbFolderImportModal extends Modal {
contentEl.createDiv({cls: 'media-db-plugin-spacer'}); contentEl.createDiv({cls: 'media-db-plugin-spacer'});
contentEl.createEl('h3', {text: 'The name of the mata data field that should be used as the title to query'}); contentEl.createEl('h3', {text: 'The name of the metadata field that should be used as the title to query.'});
const placeholder = 'title'; const placeholder = 'title';
const titleFieldNameComponent = new TextComponent(contentEl); const titleFieldNameComponent = new TextComponent(contentEl);

View file

@ -72,11 +72,13 @@ export abstract class SelectModal<T> extends Modal {
contentEl.createEl('h2', {text: this.title}); contentEl.createEl('h2', {text: this.title});
contentEl.createEl('p', {text: this.description}); contentEl.createEl('p', {text: this.description});
contentEl.addClass('media-db-plugin-select-modal');
const elementWrapper = contentEl.createDiv({cls: 'media-db-plugin-select-wrapper'}); const elementWrapper = contentEl.createDiv({cls: 'media-db-plugin-select-wrapper'});
let i = 0; let i = 0;
for (const element of this.elements) { for (const element of this.elements) {
const selectModalElement = new SelectModalElement(element, contentEl, i, this, false); const selectModalElement = new SelectModalElement(element, elementWrapper, i, this, false);
this.selectModalElements.push(selectModalElement); this.selectModalElements.push(selectModalElement);
@ -85,6 +87,8 @@ export abstract class SelectModal<T> extends Modal {
i += 1; i += 1;
} }
this.selectModalElements.first()?.element.scrollIntoView();
const bottomSetting = new Setting(contentEl); const bottomSetting = new Setting(contentEl);
bottomSetting.addButton(btn => btn.setButtonText('Cancel').onClick(() => this.close())); bottomSetting.addButton(btn => btn.setButtonText('Cancel').onClick(() => this.close()));
if (this.skipButton) { if (this.skipButton) {

View file

@ -7,8 +7,11 @@ import {FileSuggest} from './suggesters/FileSuggest';
export interface MediaDbPluginSettings { export interface MediaDbPluginSettings {
folder: string, folder: string,
sfwFilter: boolean,
OMDbKey: string, OMDbKey: string,
sfwFilter: boolean,
useCustomYamlStringifier: boolean;
templates: boolean,
movieTemplate: string, movieTemplate: string,
seriesTemplate: string, seriesTemplate: string,
@ -28,13 +31,14 @@ export interface MediaDbPluginSettings {
wikiPropertyConversionRules: string, wikiPropertyConversionRules: string,
musicReleasePropertyConversionRules: string, musicReleasePropertyConversionRules: string,
templates: boolean,
} }
export const DEFAULT_SETTINGS: MediaDbPluginSettings = { export const DEFAULT_SETTINGS: MediaDbPluginSettings = {
folder: 'Media DB', folder: 'Media DB',
sfwFilter: true,
OMDbKey: '', OMDbKey: '',
sfwFilter: true,
useCustomYamlStringifier: true,
templates: true,
movieTemplate: '', movieTemplate: '',
seriesTemplate: '', seriesTemplate: '',
@ -54,7 +58,7 @@ export const DEFAULT_SETTINGS: MediaDbPluginSettings = {
wikiPropertyConversionRules: '', wikiPropertyConversionRules: '',
musicReleasePropertyConversionRules: '', musicReleasePropertyConversionRules: '',
templates: true,
}; };
export class MediaDbSettingTab extends PluginSettingTab { export class MediaDbSettingTab extends PluginSettingTab {
@ -108,6 +112,17 @@ export class MediaDbSettingTab extends PluginSettingTab {
}); });
}); });
new Setting(containerEl)
.setName('YAML formatter')
.setDesc('Add optional quotation marks around strings in the metadata block.')
.addToggle(cb => {
cb.setValue(this.plugin.settings.useCustomYamlStringifier)
.onChange(data => {
this.plugin.settings.useCustomYamlStringifier = data;
this.plugin.saveSettings();
});
});
new Setting(containerEl) new Setting(containerEl)
.setName('Resolve {{ tags }} in templates') .setName('Resolve {{ tags }} in templates')
.setDesc('Whether to resolve {{ tags }} in templates. The spaces inside the curly braces are important.') .setDesc('Whether to resolve {{ tags }} in templates. The spaces inside the curly braces are important.')

View file

@ -37,7 +37,7 @@ export class MediaTypeManager {
return replaceTags(this.mediaFileNameTemplateMap.get(mediaTypeModel.getMediaType()), mediaTypeModel); return replaceTags(this.mediaFileNameTemplateMap.get(mediaTypeModel.getMediaType()), mediaTypeModel);
} }
async getContent(mediaTypeModel: MediaTypeModel, app: App) { async getTemplate(mediaTypeModel: MediaTypeModel, app: App) {
const templateFileName = this.mediaTemplateMap.get(mediaTypeModel.getMediaType()); const templateFileName = this.mediaTemplateMap.get(mediaTypeModel.getMediaType());
if (!templateFileName) { if (!templateFileName) {

View file

@ -4,7 +4,7 @@ import {MediaTypeModel} from '../models/MediaTypeModel';
export const pluginName: string = 'obsidian-media-db-plugin'; export const pluginName: string = 'obsidian-media-db-plugin';
export const contactEmail: string = 'm.projects.code@gmail.com'; export const contactEmail: string = 'm.projects.code@gmail.com';
export const mediaDbTag: string = 'mediaDB'; export const mediaDbTag: string = 'mediaDB';
export const mediaDbVersion: string = '0.3.0'; export const mediaDbVersion: string = '0.3.1';
export const debug: boolean = false; export const debug: boolean = false;
export function wrapAround(value: number, size: number): number { export function wrapAround(value: number, size: number): number {

View file

@ -22,8 +22,15 @@ small.media-db-plugin-list-text{
color: var(--text-muted); color: var(--text-muted);
} }
.media-db-plugin-select-modal {
display: flex;
flex-direction: column;
}
.media-db-plugin-select-wrapper { .media-db-plugin-select-wrapper {
margin: 5px; margin: 5px;
flex: 1;
overflow-y: auto;
} }
.media-db-plugin-select-element { .media-db-plugin-select-element {