Meta data field customization #19

This commit is contained in:
mProjectsCode 2022-06-07 10:38:51 +02:00
parent b4e40d2daa
commit 78ee146b71
8 changed files with 247 additions and 11 deletions

View file

@ -81,7 +81,10 @@ export class SteamAPI extends APIModel {
let result;
for (const [key, value] of Object.entries(await fetchData.json)) {
if (key == id) {
// console.log(typeof key, key)
// console.log(typeof id, id)
// after some testing I found out that id is somehow a number despite that it's defined as string...
if (key === String(id)) {
result = value.data;
}
}

View file

@ -12,11 +12,14 @@ import {WikipediaAPI} from './api/apis/WikipediaAPI';
import {MusicBrainzAPI} from './api/apis/MusicBrainzAPI';
import {MediaTypeManager} from './utils/MediaTypeManager';
import {SteamAPI} from './api/apis/SteamAPI';
import {ModelPropertyMapper} from './settings/ModelPropertyMapper';
import {YAMLConverter} from './utils/YAMLConverter';
export default class MediaDbPlugin extends Plugin {
settings: MediaDbPluginSettings;
apiManager: APIManager;
mediaTypeManager: MediaTypeManager;
modelPropertyMapper: ModelPropertyMapper;
async onload() {
await this.loadSettings();
@ -68,6 +71,7 @@ export default class MediaDbPlugin extends Plugin {
// this.apiManager.registerAPI(new LocGovAPI(this)); // TODO: parse data
this.mediaTypeManager = new MediaTypeManager(this.settings);
this.modelPropertyMapper = new ModelPropertyMapper(this.settings);
}
async createMediaDbNote(modal: () => Promise<MediaTypeModel>): Promise<void> {
@ -87,7 +91,7 @@ export default class MediaDbPlugin extends Plugin {
console.log('MDB | Creating new note...');
// console.log(mediaTypeModel);
let fileContent = `---\n${mediaTypeModel.toMetaData()}---\n`;
let fileContent = `---\n${YAMLConverter.toYaml(this.modelPropertyMapper.convertObject(mediaTypeModel.toMetaDataObject()))}---\n`;
if (this.settings.templates) {
fileContent += await this.mediaTypeManager.getContent(mediaTypeModel, this.app);
@ -144,13 +148,17 @@ export default class MediaDbPlugin extends Plugin {
throw new Error('MDB | there is no active note');
}
let metadata: FrontMatterCache = this.app.metadataCache.getFileCache(activeFile).frontmatter;
let metadata: any = this.app.metadataCache.getFileCache(activeFile).frontmatter;
delete metadata.position; // remove unnecessary data from the FrontMatterCache
metadata = this.modelPropertyMapper.convertObjectBack(metadata);
console.log(metadata)
if (!metadata?.type || !metadata?.dataSource || !metadata?.id) {
throw new Error('MDB | active note is not a Media DB entry or is missing metadata');
}
delete metadata.position; // remove unnecessary data from the FrontMatterCache
let oldMediaTypeModel = this.mediaTypeManager.createMediaTypeModelFromMediaType(metadata, metadata.type);
let newMediaTypeModel = await this.apiManager.queryDetailedInfoById(metadata.id, metadata.dataSource);
@ -171,6 +179,8 @@ export default class MediaDbPlugin extends Plugin {
async saveSettings() {
this.mediaTypeManager.updateTemplates(this.settings);
this.modelPropertyMapper.updateConversionRules(this.settings);
await this.saveData(this.settings);
}
}

View file

@ -17,8 +17,8 @@ export abstract class MediaTypeModel {
abstract getTags(): string[];
toMetaData(): string {
return YAMLConverter.toYaml({...this.getWithOutUserData(), ...this.userData, tags: '#' + this.getTags().join('/')});
toMetaDataObject(): object {
return {...this.getWithOutUserData(), ...this.userData, tags: '#' + this.getTags().join('/')};
}
getWithOutUserData(): object {

View file

@ -16,6 +16,7 @@ export class WikiModel extends MediaTypeModel {
wikiUrl: string;
lastUpdated: string;
length: number;
article: string;
userData: {};
@ -35,4 +36,11 @@ export class WikiModel extends MediaTypeModel {
return MediaType.Wiki;
}
override getWithOutUserData(): object {
const copy = JSON.parse(JSON.stringify(this));
delete copy.userData;
delete copy.article;
return copy;
}
}

View file

@ -0,0 +1,27 @@
import {containsOnlyLettersAndUnderscores} from '../utils/Utils';
export class ModelPropertyConversionRule {
property: string;
newProperty: string;
constructor(conversionRule: string) {
const conversionRuleParts = conversionRule.split('->');
if (conversionRuleParts.length !== 2) {
throw Error(`Conversion rule "${conversionRule}" may only have exactly one "->"`);
}
let property = conversionRuleParts[0].trim();
let newProperty = conversionRuleParts[1].trim();
if (!property || !containsOnlyLettersAndUnderscores(property)) {
throw Error(`Error in conversion rule "${conversionRule}": property may not be empty and only contain letters and underscores.`);
}
if (!newProperty || !containsOnlyLettersAndUnderscores(newProperty)) {
throw Error(`Error in conversion rule "${conversionRule}": new property may not be empty and only contain letters and underscores.`);
}
this.property = property;
this.newProperty = newProperty;
}
}

View file

@ -0,0 +1,109 @@
import {MediaType} from '../utils/MediaType';
import {MediaDbPluginSettings} from './Settings';
import {ModelPropertyConversionRule} from './ModelPropertyConversionRule';
export class ModelPropertyMapper {
conversionRulesMap: Map<MediaType, string>;
constructor(settings: MediaDbPluginSettings) {
this.updateConversionRules(settings);
}
updateConversionRules(settings: MediaDbPluginSettings) {
this.conversionRulesMap = new Map<MediaType, string>();
this.conversionRulesMap.set(MediaType.Movie, settings.moviePropertyConversionRules);
this.conversionRulesMap.set(MediaType.Series, settings.seriesPropertyConversionRules);
this.conversionRulesMap.set(MediaType.Game, settings.gamePropertyConversionRules);
this.conversionRulesMap.set(MediaType.Wiki, settings.wikiPropertyConversionRules);
this.conversionRulesMap.set(MediaType.MusicRelease, settings.musicReleasePropertyConversionRules);
}
convertObject(obj: object): object {
if (!obj.hasOwnProperty('type')) {
return obj;
}
// @ts-ignore
const conversionRulesString: string = this.conversionRulesMap.get(obj['type']);
if (!conversionRulesString) {
return obj;
}
const conversionRules: ModelPropertyConversionRule[] = []
for (const conversionRuleString of conversionRulesString.split('\n')) {
if (conversionRuleString) {
conversionRules.push(new ModelPropertyConversionRule(conversionRuleString));
}
}
const newObj: object = {};
for (const [key, value] of Object.entries(obj)) {
if (key === 'type') {
// @ts-ignore
newObj[key] = value;
continue;
}
let hasConversionRule = false;
for (const conversionRule of conversionRules) {
if (conversionRule.property === key) {
hasConversionRule = true;
// @ts-ignore
newObj[conversionRule.newProperty] = value;
}
}
if (!hasConversionRule) {
// @ts-ignore
newObj[key] = value;
}
}
return newObj;
}
convertObjectBack(obj: object): object {
if (!obj.hasOwnProperty('type')) {
return obj;
}
// @ts-ignore
const conversionRulesString: string = this.conversionRulesMap.get(obj['type']);
if (!conversionRulesString) {
return obj;
}
const conversionRules: ModelPropertyConversionRule[] = []
for (const conversionRuleString of conversionRulesString.split('\n')) {
if (conversionRuleString) {
conversionRules.push(new ModelPropertyConversionRule(conversionRuleString));
}
}
const originalObj: object = {};
for (const [key, value] of Object.entries(obj)) {
if (key === 'type') {
// @ts-ignore
originalObj[key] = value;
continue;
}
let hasConversionRule = false;
for (const conversionRule of conversionRules) {
if (conversionRule.newProperty === key) {
hasConversionRule = true;
// @ts-ignore
originalObj[conversionRule.property] = value;
}
}
if (!hasConversionRule) {
// @ts-ignore
originalObj[key] = value;
}
}
return originalObj;
}
}

View file

@ -22,6 +22,12 @@ export interface MediaDbPluginSettings {
wikiFileNameTemplate: string,
musicReleaseFileNameTemplate: string,
moviePropertyConversionRules: string,
seriesPropertyConversionRules: string,
gamePropertyConversionRules: string,
wikiPropertyConversionRules: string,
musicReleasePropertyConversionRules: string,
templates: boolean,
}
@ -42,6 +48,12 @@ export const DEFAULT_SETTINGS: MediaDbPluginSettings = {
wikiFileNameTemplate: '{{ title }}',
musicReleaseFileNameTemplate: '{{ title }} (by {{ ENUM:artists }} - {{ year }})',
moviePropertyConversionRules: '',
seriesPropertyConversionRules: '',
gamePropertyConversionRules: '',
wikiPropertyConversionRules: '',
musicReleasePropertyConversionRules: '',
templates: true,
};
@ -181,7 +193,7 @@ export class MediaDbSettingTab extends PluginSettingTab {
new Setting(containerEl)
.setName('Movie file name template')
.setDesc('Template for the file name used when creating a new note for a movie.')
.addSearch(cb => {
.addText(cb => {
cb.setPlaceholder(`Example: ${DEFAULT_SETTINGS.movieFileNameTemplate}`)
.setValue(this.plugin.settings.movieFileNameTemplate)
.onChange(data => {
@ -193,7 +205,7 @@ export class MediaDbSettingTab extends PluginSettingTab {
new Setting(containerEl)
.setName('Series file name template')
.setDesc('Template for the file name used when creating a new note for a series.')
.addSearch(cb => {
.addText(cb => {
cb.setPlaceholder(`Example: ${DEFAULT_SETTINGS.seriesFileNameTemplate}`)
.setValue(this.plugin.settings.seriesFileNameTemplate)
.onChange(data => {
@ -205,7 +217,7 @@ export class MediaDbSettingTab extends PluginSettingTab {
new Setting(containerEl)
.setName('Game file name template')
.setDesc('Template for the file name used when creating a new note for a game.')
.addSearch(cb => {
.addText(cb => {
cb.setPlaceholder(`Example: ${DEFAULT_SETTINGS.gameFileNameTemplate}`)
.setValue(this.plugin.settings.gameFileNameTemplate)
.onChange(data => {
@ -217,7 +229,7 @@ export class MediaDbSettingTab extends PluginSettingTab {
new Setting(containerEl)
.setName('Wiki file name template')
.setDesc('Template for the file name used when creating a new note for a wiki entry.')
.addSearch(cb => {
.addText(cb => {
cb.setPlaceholder(`Example: ${DEFAULT_SETTINGS.wikiFileNameTemplate}`)
.setValue(this.plugin.settings.wikiFileNameTemplate)
.onChange(data => {
@ -229,7 +241,7 @@ export class MediaDbSettingTab extends PluginSettingTab {
new Setting(containerEl)
.setName('Music Release file name template')
.setDesc('Template for the file name used when creating a new note for a music release.')
.addSearch(cb => {
.addText(cb => {
cb.setPlaceholder(`Example: ${DEFAULT_SETTINGS.musicReleaseFileNameTemplate}`)
.setValue(this.plugin.settings.musicReleaseFileNameTemplate)
.onChange(data => {
@ -239,6 +251,69 @@ export class MediaDbSettingTab extends PluginSettingTab {
});
// endregion
containerEl.createEl('h3', {text: 'Property Mappings'});
// region Property Mappings
new Setting(containerEl)
.setName('Movie model property mappings')
.setDesc('Mappings for the property names of a movie.')
.addTextArea(cb => {
cb.setPlaceholder(`Example: \ntitle -> name\nyear -> releaseYear`)
.setValue(this.plugin.settings.moviePropertyConversionRules)
.onChange(data => {
this.plugin.settings.moviePropertyConversionRules = data;
this.plugin.saveSettings();
});
});
new Setting(containerEl)
.setName('Series model property mappings')
.setDesc('Mappings for the property names of a series.')
.addTextArea(cb => {
cb.setPlaceholder(`Example: \ntitle -> name\nyear -> releaseYear`)
.setValue(this.plugin.settings.seriesPropertyConversionRules)
.onChange(data => {
this.plugin.settings.seriesPropertyConversionRules = data;
this.plugin.saveSettings();
});
});
new Setting(containerEl)
.setName('Game model property mappings')
.setDesc('Mappings for the property names of a game.')
.addTextArea(cb => {
cb.setPlaceholder(`Example: \ntitle -> name\nyear -> releaseYear`)
.setValue(this.plugin.settings.gamePropertyConversionRules)
.onChange(data => {
this.plugin.settings.gamePropertyConversionRules = data;
this.plugin.saveSettings();
});
});
new Setting(containerEl)
.setName('Wiki model property mappings')
.setDesc('Mappings for the property names of a wiki entry.')
.addTextArea(cb => {
cb.setPlaceholder(`Example: \ntitle -> name\nyear -> releaseYear`)
.setValue(this.plugin.settings.wikiPropertyConversionRules)
.onChange(data => {
this.plugin.settings.wikiPropertyConversionRules = data;
this.plugin.saveSettings();
});
});
new Setting(containerEl)
.setName('Music Release model property mappings')
.setDesc('Mappings for the property names of a music release.')
.addTextArea(cb => {
cb.setPlaceholder(`Example: \ntitle -> name\nyear -> releaseYear`)
.setValue(this.plugin.settings.musicReleasePropertyConversionRules)
.onChange(data => {
this.plugin.settings.musicReleasePropertyConversionRules = data;
this.plugin.saveSettings();
});
});
// endregion
}
}

View file

@ -17,6 +17,10 @@ export function debugLog(o: any): void {
}
}
export function containsOnlyLettersAndUnderscores(str: string): boolean {
return /^[a-zA-Z_]+$/.test(str);
}
export function replaceIllegalFileNameCharactersInString(string: string): string {
return string.replace(/[\\,#%&{}/*<>$"@.?]*/g, '').replace(/:+/g, ' -');
}