Merge branch 'release'

This commit is contained in:
mProjectsCode 2022-09-22 13:21:08 +02:00
commit a6250cbff7
10 changed files with 175 additions and 101 deletions

View file

@ -9,13 +9,13 @@ export class APIManager {
this.apis = []; this.apis = [];
} }
async query(query: string, apisToQuery: any): Promise<MediaTypeModel[]> { async query(query: string, apisToQuery: string[]): Promise<MediaTypeModel[]> {
debugLog(`MDB | api manager queried with "${query}"`); debugLog(`MDB | api manager queried with "${query}"`);
let res: MediaTypeModel[] = []; let res: MediaTypeModel[] = [];
for (const api of this.apis) { for (const api of this.apis) {
if (Object.keys(apisToQuery).contains(api.apiName) && apisToQuery[api.apiName]) { if (apisToQuery.contains(api.apiName)) {
const apiRes = await api.searchByTitle(query); const apiRes = await api.searchByTitle(query);
res = res.concat(apiRes); res = res.concat(apiRes);
} }
@ -28,9 +28,9 @@ export class APIManager {
return await this.queryDetailedInfoById(item.id, item.dataSource); return await this.queryDetailedInfoById(item.id, item.dataSource);
} }
async queryDetailedInfoById(id: string, dataSource: string): Promise<MediaTypeModel> { async queryDetailedInfoById(id: string, apiName: string): Promise<MediaTypeModel> {
for (const api of this.apis) { for (const api of this.apis) {
if (api.apiName === dataSource) { if (api.apiName === apiName) {
return api.getById(id); return api.getById(id);
} }
} }

View file

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

View file

@ -58,7 +58,7 @@ export class WikipediaAPI extends APIModel {
const data = await fetchData.json(); const data = await fetchData.json();
debugLog(data); debugLog(data);
const result = Object.entries(data?.query?.pages)[0][1]; const result: any = Object.entries(data?.query?.pages)[0][1];
const model = new WikiModel({ const model = new WikiModel({
type: 'wiki', type: 'wiki',

View file

@ -23,12 +23,31 @@ export default class MediaDbPlugin extends Plugin {
mediaTypeManager: MediaTypeManager; mediaTypeManager: MediaTypeManager;
modelPropertyMapper: ModelPropertyMapper; modelPropertyMapper: ModelPropertyMapper;
frontMatterRexExpPattern: string = '^(---)\\n[\\s\\S]*?\\n---';
async onload() { async onload() {
await this.loadSettings(); await this.loadSettings();
// register the settings tab
this.addSettingTab(new MediaDbSettingTab(this.app, this));
this.apiManager = new APIManager();
// register APIs
this.apiManager.registerAPI(new OMDbAPI(this));
this.apiManager.registerAPI(new MALAPI(this));
this.apiManager.registerAPI(new WikipediaAPI(this));
this.apiManager.registerAPI(new MusicBrainzAPI(this));
this.apiManager.registerAPI(new SteamAPI(this));
this.apiManager.registerAPI(new BoardGameGeekAPI(this));
// this.apiManager.registerAPI(new LocGovAPI(this)); // TODO: parse data
this.mediaTypeManager = new MediaTypeManager(this.settings);
this.modelPropertyMapper = new ModelPropertyMapper(this.settings);
// add icon to the left ribbon // add icon to the left ribbon
const ribbonIconEl = this.addRibbonIcon('database', 'Add new Media DB entry', (evt: MouseEvent) => const ribbonIconEl = this.addRibbonIcon('database', 'Add new Media DB entry', (evt: MouseEvent) =>
this.createMediaDbNotes(this.openMediaDbAdvancedSearchModal.bind(this)), this.createEntryWithAdvancedSearchModal(),
); );
ribbonIconEl.addClass('obsidian-media-db-plugin-ribbon-class'); ribbonIconEl.addClass('obsidian-media-db-plugin-ribbon-class');
@ -46,13 +65,13 @@ export default class MediaDbPlugin extends Plugin {
this.addCommand({ this.addCommand({
id: 'open-media-db-search-modal', id: 'open-media-db-search-modal',
name: 'Add new Media DB entry', name: 'Add new Media DB entry',
callback: () => this.createMediaDbNotes(this.openMediaDbAdvancedSearchModal.bind(this)), callback: () => this.createEntryWithAdvancedSearchModal(),
}); });
// register command to open id search modal // register command to open id search modal
this.addCommand({ this.addCommand({
id: 'open-media-db-id-search-modal', id: 'open-media-db-id-search-modal',
name: 'Add new Media DB entry by id', name: 'Add new Media DB entry by id',
callback: () => this.createMediaDbNotes(this.openMediaDbIdSearchModal.bind(this)), callback: () => this.createEntryWithIdSearchModal(),
}); });
// register command to update the open note // register command to update the open note
this.addCommand({ this.addCommand({
@ -68,42 +87,65 @@ export default class MediaDbPlugin extends Plugin {
return true; return true;
}, },
}); });
// register the settings tab
this.addSettingTab(new MediaDbSettingTab(this.app, this));
this.apiManager = new APIManager();
// register APIs
this.apiManager.registerAPI(new OMDbAPI(this));
this.apiManager.registerAPI(new MALAPI(this));
this.apiManager.registerAPI(new WikipediaAPI(this));
this.apiManager.registerAPI(new MusicBrainzAPI(this));
this.apiManager.registerAPI(new SteamAPI(this));
this.apiManager.registerAPI(new BoardGameGeekAPI(this));
// this.apiManager.registerAPI(new LocGovAPI(this)); // TODO: parse data
this.mediaTypeManager = new MediaTypeManager(this.settings);
this.modelPropertyMapper = new ModelPropertyMapper(this.settings);
} }
async createMediaDbNotes(modal: () => Promise<MediaTypeModel[]>, attachFile?: TFile): Promise<void> { async createEntryWithSearchModal() {
let models: MediaTypeModel[] = [];
}
async createEntryWithAdvancedSearchModal() {
let results: MediaTypeModel[] = [];
try { try {
models = await modal(); const {query, apis} = await this.openMediaDbAdvancedSearchModal();
new Notice('MediaDB Searching...');
const apiSearchResults = await this.apiManager.query(query, apis);
const selectResults = await this.openMediaDbSelectModal(apiSearchResults, false);
results = await this.queryDetails(selectResults);
} catch (e) { } catch (e) {
console.warn(e); console.warn(e);
new Notice(e.toString()); new Notice(e.toString());
} }
debugLog(results);
await this.createMediaDbNotes(results);
}
async createEntryWithIdSearchModal() {
let result: MediaTypeModel = undefined;
try {
const {query, api} = await this.openMediaDbIdSearchModal();
new Notice('MediaDB Searching...');
result = await this.apiManager.queryDetailedInfoById(query, api);
} catch (e) {
console.warn(e);
new Notice(e.toString());
}
debugLog(result);
await this.createMediaDbNoteFromModel(result);
}
async createMediaDbNotes(models: MediaTypeModel[], attachFile?: TFile): Promise<void> {
for (const model of models) {
await this.createMediaDbNoteFromModel(model, attachFile);
}
}
async queryDetails(models: MediaTypeModel[]): Promise<MediaTypeModel[]> {
let detailModels: MediaTypeModel[] = [];
for (const model of models) { for (const model of models) {
try { try {
await this.createMediaDbNoteFromModel(await this.apiManager.queryDetailedInfo(model), attachFile); detailModels.push(await this.apiManager.queryDetailedInfo(model));
} catch (e) { } catch (e) {
console.warn(e); console.warn(e);
new Notice(e.toString()); new Notice(e.toString());
} }
} }
return detailModels;
} }
async createMediaDbNoteFromModel(mediaTypeModel: MediaTypeModel, attachFile?: TFile): Promise<void> { async createMediaDbNoteFromModel(mediaTypeModel: MediaTypeModel, attachFile?: TFile): Promise<void> {
@ -187,23 +229,33 @@ export default class MediaDbPlugin extends Plugin {
return metadata; return metadata;
} }
/**
* Creates a note in the vault.
*
* @param fileName
* @param fileContent
* @param openFile
*/
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`;
// find and possibly create the folder set in settings
const folder = this.app.vault.getAbstractFileByPath(this.settings.folder); const folder = this.app.vault.getAbstractFileByPath(this.settings.folder);
if (!folder) { if (!folder) {
await this.app.vault.createFolder(this.settings.folder.replace(/\/$/, '')); await this.app.vault.createFolder(this.settings.folder.replace(/\/$/, ''));
} }
// find and delete file with the same name
const file = this.app.vault.getAbstractFileByPath(filePath); const file = this.app.vault.getAbstractFileByPath(filePath);
if (file) { if (file) {
await this.app.vault.delete(file); await this.app.vault.delete(file);
} }
// create the file
const targetFile = await this.app.vault.create(filePath, fileContent); const targetFile = await this.app.vault.create(filePath, fileContent);
// open file // open newly crated file
if (openFile) { if (openFile) {
const activeLeaf = this.app.workspace.getUnpinnedLeaf(); const activeLeaf = this.app.workspace.getUnpinnedLeaf();
if (!activeLeaf) { if (!activeLeaf) {
@ -214,6 +266,10 @@ export default class MediaDbPlugin extends Plugin {
} }
} }
/**
* Update the active note by querying the API again.
* Tries to read the type, id and dataSource of the active note. If successful it will query the api, delete the old note and create a new one.
*/
async updateActiveNote() { async updateActiveNote() {
const activeFile: TFile = this.app.workspace.getActiveFile(); const activeFile: TFile = this.app.workspace.getActiveFile();
if (!activeFile) { if (!activeFile) {
@ -249,18 +305,12 @@ export default class MediaDbPlugin extends Plugin {
const erroredFiles: { filePath: string, error: string }[] = []; const erroredFiles: { filePath: string, error: string }[] = [];
let canceled: boolean = false; let canceled: boolean = false;
const {selectedAPI, titleFieldName, appendContent} = await new Promise((resolve, reject) => { const {selectedAPI, titleFieldName, appendContent} = await new Promise<{selectedAPI: string, titleFieldName: string, appendContent: boolean}>((resolve, reject) => {
new MediaDbFolderImportModal(this.app, this, ((selectedAPI, titleFieldName, appendContent) => { new MediaDbFolderImportModal(this.app, this, ((selectedAPI: string, titleFieldName: string, appendContent: boolean) => {
resolve({selectedAPI, titleFieldName, appendContent}); resolve({selectedAPI, titleFieldName, appendContent});
})).open(); })).open();
}); });
const selectedAPIs = {};
for (const api of this.apiManager.apis) {
// @ts-ignore
selectedAPIs[api.apiName] = api.apiName === selectedAPI;
}
for (const child of folder.children) { for (const child of folder.children) {
if (child instanceof TFile) { if (child instanceof TFile) {
const file = child as TFile; const file = child as TFile;
@ -279,7 +329,7 @@ export default class MediaDbPlugin extends Plugin {
let results: MediaTypeModel[] = []; let results: MediaTypeModel[] = [];
try { try {
results = await this.apiManager.query(title, selectedAPIs); results = await this.apiManager.query(title, [selectedAPI]);
} catch (e) { } catch (e) {
erroredFiles.push({filePath: file.path, error: e.toString()}); erroredFiles.push({filePath: file.path, error: e.toString()});
continue; continue;
@ -292,7 +342,7 @@ export default class MediaDbPlugin extends Plugin {
let selectedResults: MediaTypeModel[] = []; let selectedResults: MediaTypeModel[] = [];
try { try {
selectedResults = await new Promise((resolve, reject) => { selectedResults = await new Promise((resolve, reject) => {
const searchResultModal = new MediaDbSearchResultModal(this.app, this, results, true, (err, res) => { const searchResultModal = new MediaDbSearchResultModal(this.app, this, results, true, (res, err) => {
if (err) { if (err) {
return reject(err); return reject(err);
} }
@ -325,11 +375,17 @@ export default class MediaDbPlugin extends Plugin {
continue; continue;
} }
await this.createMediaDbNotes(async () => selectedResults, appendContent ? file : null); const detailedResults = await this.queryDetails(selectedResults);
await this.createMediaDbNotes(detailedResults, appendContent ? file : null);
} }
} }
if (erroredFiles.length > 0) { if (erroredFiles.length > 0) {
await this.createErroredFilesReport(erroredFiles);
}
}
async createErroredFilesReport(erroredFiles: { filePath: string, error: string }[]): Promise<void> {
const title = `bulk import error report ${dateTimeToString(new Date())}`; const title = `bulk import error report ${dateTimeToString(new Date())}`;
const filePath = `${this.settings.folder.replace(/\/$/, '')}/${title}.md`; const filePath = `${this.settings.folder.replace(/\/$/, '')}/${title}.md`;
@ -339,33 +395,40 @@ export default class MediaDbPlugin extends Plugin {
const targetFile = await this.app.vault.create(filePath, fileContent); const targetFile = await this.app.vault.create(filePath, fileContent);
} }
}
async openMediaDbAdvancedSearchModal(): Promise<MediaTypeModel[]> { async openMediaDbAdvancedSearchModal(): Promise<{ query: string, apis: string[] }> {
return new Promise(((resolve, reject) => { return await new Promise((resolve, reject) => {
new MediaDbAdvancedSearchModal(this.app, this, (err, results) => { new MediaDbAdvancedSearchModal(this.app, this, (res, err) => {
if (err) { if (err) {
return reject(err); return reject(err);
} }
new MediaDbSearchResultModal(this.app, this, results, false, (err2, res) => { resolve(res)
if (err2) {
return reject(err2);
}
resolve(res);
}, () => resolve([])).open();
}).open(); }).open();
})); });
} }
async openMediaDbIdSearchModal(): Promise<MediaTypeModel> { async openMediaDbIdSearchModal(): Promise<{ query: string, api: string }> {
return new Promise(((resolve, reject) => { return await new Promise((resolve, reject) => {
new MediaDbIdSearchModal(this.app, this, (err, res) => { new MediaDbIdSearchModal(this.app, this, (res, err) => {
if (err) {
return reject(err);
}
resolve(res)
}).open();
});
}
async openMediaDbSelectModal(resultsToDisplay: MediaTypeModel[], skipButton: boolean = false): Promise<MediaTypeModel[]> {
return await new Promise((resolve, reject) => {
new MediaDbSearchResultModal(this.app, this, resultsToDisplay, skipButton, (res, err) => {
if (err) { if (err) {
return reject(err); return reject(err);
} }
resolve(res); resolve(res);
}, () => {
resolve([])
}).open(); }).open();
})); });
} }
async loadSettings() { async loadSettings() {

View file

@ -8,16 +8,16 @@ export class MediaDbAdvancedSearchModal extends Modal {
isBusy: boolean; isBusy: boolean;
plugin: MediaDbPlugin; plugin: MediaDbPlugin;
searchBtn: ButtonComponent; searchBtn: ButtonComponent;
selectedApis: any; selectedApis: {name: string, selected: boolean}[];
onSubmit: (err: Error, result?: MediaTypeModel[]) => void; onSubmit: (res: {query: string, apis: string[]}, err?: Error) => void;
constructor(app: App, plugin: MediaDbPlugin, onSubmit?: (err: Error, result?: MediaTypeModel[]) => void) { constructor(app: App, plugin: MediaDbPlugin, onSubmit?: (res: {query: string, apis: string[]}, err?: Error) => void) {
super(app); super(app);
this.plugin = plugin; this.plugin = plugin;
this.onSubmit = onSubmit; this.onSubmit = onSubmit;
this.selectedApis = []; this.selectedApis = [];
for (const api of this.plugin.apiManager.apis) { for (const api of this.plugin.apiManager.apis) {
this.selectedApis[api.apiName] = false; this.selectedApis.push({name: api.apiName, selected: false});
} }
} }
@ -36,14 +36,9 @@ export class MediaDbAdvancedSearchModal extends Modal {
return; return;
} }
let selectedAPICount = 0; const apis: string[] = this.selectedApis.filter(x => x.selected).map(x => x.name);
for (const api in this.selectedApis) {
if (this.selectedApis[api]) {
selectedAPICount += 1;
}
}
if (selectedAPICount === 0) { if (apis.length === 0) {
new Notice('MDB | No API selected'); new Notice('MDB | No API selected');
return; return;
} }
@ -54,12 +49,9 @@ export class MediaDbAdvancedSearchModal extends Modal {
this.searchBtn.setDisabled(false); this.searchBtn.setDisabled(false);
this.searchBtn.setButtonText('Searching...'); this.searchBtn.setButtonText('Searching...');
console.log(`MDB | query started with title ${this.query}`); this.onSubmit({query: this.query, apis: apis});
const res = await this.plugin.apiManager.query(this.query, this.selectedApis);
this.onSubmit(null, res);
} catch (e) { } catch (e) {
this.onSubmit(e); this.onSubmit(null, e);
} finally { } finally {
this.close(); this.close();
} }
@ -96,9 +88,9 @@ export class MediaDbAdvancedSearchModal extends Modal {
const apiToggleComponent = new ToggleComponent(apiToggleComponentWrapper); const apiToggleComponent = new ToggleComponent(apiToggleComponentWrapper);
apiToggleComponent.setTooltip(api.apiName); apiToggleComponent.setTooltip(api.apiName);
apiToggleComponent.setValue(this.selectedApis[api.apiName]); apiToggleComponent.setValue(this.selectedApis.find(x => x.name === api.apiName).selected);
apiToggleComponent.onChange((value) => { apiToggleComponent.onChange((value) => {
this.selectedApis[api.apiName] = value; this.selectedApis.find(x => x.name === api.apiName).selected = value;
}); });
apiToggleComponentWrapper.appendChild(apiToggleComponent.toggleEl); apiToggleComponentWrapper.appendChild(apiToggleComponent.toggleEl);
} }

View file

@ -9,9 +9,9 @@ export class MediaDbIdSearchModal extends Modal {
plugin: MediaDbPlugin; plugin: MediaDbPlugin;
searchBtn: ButtonComponent; searchBtn: ButtonComponent;
selectedApi: string; selectedApi: string;
onSubmit: (err: Error, result?: MediaTypeModel) => void; onSubmit: (res: {query: string, api: string}, err?: Error) => void;
constructor(app: App, plugin: MediaDbPlugin, onSubmit?: (err: Error, result?: MediaTypeModel) => void) { constructor(app: App, plugin: MediaDbPlugin, onSubmit?: (res: {query: string, api: string}, err?: Error) => void) {
super(app); super(app);
this.plugin = plugin; this.plugin = plugin;
this.onSubmit = onSubmit; this.onSubmit = onSubmit;
@ -44,16 +44,9 @@ export class MediaDbIdSearchModal extends Modal {
this.searchBtn.setDisabled(false); this.searchBtn.setDisabled(false);
this.searchBtn.setButtonText('Searching...'); this.searchBtn.setButtonText('Searching...');
console.log(`MDB | query started with id ${this.query}`); this.onSubmit({query: this.query, api: this.selectedApi});
const api = this.plugin.apiManager.getApiByName(this.selectedApi);
if (!api) {
this.onSubmit(new Error('the selected api does not exist'));
}
const res = await api.getById(this.query);
this.onSubmit(null, res);
} catch (e) { } catch (e) {
this.onSubmit(e); this.onSubmit(null, e);
} finally { } finally {
this.close(); this.close();
} }

View file

@ -6,13 +6,13 @@ import {SelectModal} from './SelectModal';
export class MediaDbSearchResultModal extends SelectModal<MediaTypeModel> { export class MediaDbSearchResultModal extends SelectModal<MediaTypeModel> {
plugin: MediaDbPlugin; plugin: MediaDbPlugin;
heading: string; heading: string;
onSubmit: (error: Error, result: MediaTypeModel[]) => void; onSubmit: (res: MediaTypeModel[], err?: Error) => void;
onCancel: () => void; onCancel: () => void;
onSkip: () => void; onSkip: () => void;
sendCallback: boolean; sendCallback: boolean;
constructor(app: App, plugin: MediaDbPlugin, elements: MediaTypeModel[], skipButton: boolean, onSubmit: (error: Error, result: MediaTypeModel[]) => void, onCancel: () => void, onSkip?: () => void) { constructor(app: App, plugin: MediaDbPlugin, elements: MediaTypeModel[], skipButton: boolean, onSubmit: (res: MediaTypeModel[], err?: Error) => void, onCancel: () => void, onSkip?: () => void) {
super(app, elements); super(app, elements);
this.plugin = plugin; this.plugin = plugin;
this.onSubmit = onSubmit; this.onSubmit = onSubmit;
@ -35,7 +35,7 @@ export class MediaDbSearchResultModal extends SelectModal<MediaTypeModel> {
// Perform action on the selected suggestion. // Perform action on the selected suggestion.
submit() { submit() {
this.onSubmit(null, this.selectModalElements.filter(x => x.isActive()).map(x => x.value)); this.onSubmit(this.selectModalElements.filter(x => x.isActive()).map(x => x.value));
this.sendCallback = true; this.sendCallback = true;
this.close(); this.close();
} }

View file

@ -19,17 +19,25 @@ export class ModelPropertyMapper {
this.conversionRulesMap.set(MediaType.BoardGame, settings.boardgamePropertyConversionRules); this.conversionRulesMap.set(MediaType.BoardGame, settings.boardgamePropertyConversionRules);
} }
/**
* Converts an object using the conversion rules for its type.
* Returns an unaltered object if object.type is null or undefined or if there are no conversion rules for the type.
*
* @param obj
*/
convertObject(obj: object): object { convertObject(obj: object): object {
if (!obj.hasOwnProperty('type')) { if (!obj.hasOwnProperty('type')) {
return obj; return obj;
} }
// @ts-ignore // @ts-ignore
// get conversion rules from settings corresponding to the object type
const conversionRulesString: string = this.conversionRulesMap.get(obj['type']); const conversionRulesString: string = this.conversionRulesMap.get(obj['type']);
if (!conversionRulesString) { if (!conversionRulesString) {
return obj; return obj;
} }
// parse the conversion rules
const conversionRules: ModelPropertyConversionRule[] = []; const conversionRules: ModelPropertyConversionRule[] = [];
for (const conversionRuleString of conversionRulesString.split('\n')) { for (const conversionRuleString of conversionRulesString.split('\n')) {
if (conversionRuleString) { if (conversionRuleString) {
@ -39,8 +47,8 @@ export class ModelPropertyMapper {
const newObj: object = {}; const newObj: object = {};
for (const [key, value] of Object.entries(obj)) { for (const [key, value] of Object.entries(obj)) {
// property 'type' can not be remapped
if (key === 'type') { if (key === 'type') {
// @ts-ignore // @ts-ignore
newObj[key] = value; newObj[key] = value;
@ -51,10 +59,13 @@ export class ModelPropertyMapper {
for (const conversionRule of conversionRules) { for (const conversionRule of conversionRules) {
if (conversionRule.property === key) { if (conversionRule.property === key) {
hasConversionRule = true; hasConversionRule = true;
// if the conversion rule maps to 'x', then that means it should be ignored
if (conversionRule.newProperty.toLowerCase() !== 'x') {
// @ts-ignore // @ts-ignore
newObj[conversionRule.newProperty] = value; newObj[conversionRule.newProperty] = value;
} }
} }
}
if (!hasConversionRule) { if (!hasConversionRule) {
// @ts-ignore // @ts-ignore
newObj[key] = value; newObj[key] = value;
@ -64,18 +75,26 @@ export class ModelPropertyMapper {
return newObj; return newObj;
} }
/**
* Converts an object back using the conversion rules for its type.
* Returns an unaltered object if object.type is null or undefined or if there are no conversion rules for the type.
*
* @param obj
*/
convertObjectBack(obj: object): object { convertObjectBack(obj: object): object {
if (!obj.hasOwnProperty('type')) { if (!obj.hasOwnProperty('type')) {
return obj; return obj;
} }
// @ts-ignore // @ts-ignore
// get conversion rules from settings corresponding to the object type
const conversionRulesString: string = this.conversionRulesMap.get(obj['type']); const conversionRulesString: string = this.conversionRulesMap.get(obj['type']);
if (!conversionRulesString) { if (!conversionRulesString) {
return obj; return obj;
} }
const conversionRules: ModelPropertyConversionRule[] = []; const conversionRules: ModelPropertyConversionRule[] = [];
// parse the conversion rules
for (const conversionRuleString of conversionRulesString.split('\n')) { for (const conversionRuleString of conversionRulesString.split('\n')) {
if (conversionRuleString) { if (conversionRuleString) {
conversionRules.push(new ModelPropertyConversionRule(conversionRuleString)); conversionRules.push(new ModelPropertyConversionRule(conversionRuleString));
@ -85,6 +104,7 @@ export class ModelPropertyMapper {
const originalObj: object = {}; const originalObj: object = {};
for (const [key, value] of Object.entries(obj)) { for (const [key, value] of Object.entries(obj)) {
// property 'type' can not be remapped
if (key === 'type') { if (key === 'type') {
// @ts-ignore // @ts-ignore
originalObj[key] = value; originalObj[key] = value;

View file

@ -58,6 +58,12 @@ export class MediaTypeManager {
return replaceTags(template, mediaTypeModel); return replaceTags(template, mediaTypeModel);
} }
/**
* Takes an object and a MediaType and turns the object into an instance of a MediaTypeModel corresponding to the MediaType passed in.
*
* @param obj
* @param mediaType
*/
createMediaTypeModelFromMediaType(obj: any, mediaType: MediaType): MediaTypeModel { createMediaTypeModelFromMediaType(obj: any, mediaType: MediaType): MediaTypeModel {
if (mediaType === MediaType.Movie) { if (mediaType === MediaType.Movie) {
return new MovieModel(obj); return new MovieModel(obj);

View file

@ -5,7 +5,7 @@ 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.2'; export const mediaDbVersion: string = '0.3.2';
export const debug: boolean = false; export const debug: boolean = true;
export function wrapAround(value: number, size: number): number { export function wrapAround(value: number, size: number): number {
return ((value % size) + size) % size; return ((value % size) + size) % size;