Skip to content

Commit 6a0d192

Browse files
committed
Some main.ts refactoring
1 parent 7ae5167 commit 6a0d192

8 files changed

+167
-93
lines changed

src/api/APIManager.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ export class APIManager {
99
this.apis = [];
1010
}
1111

12-
async query(query: string, apisToQuery: any): Promise<MediaTypeModel[]> {
12+
async query(query: string, apisToQuery: string[]): Promise<MediaTypeModel[]> {
1313
debugLog(`MDB | api manager queried with "${query}"`);
1414

1515
let res: MediaTypeModel[] = [];
1616

1717
for (const api of this.apis) {
18-
if (Object.keys(apisToQuery).contains(api.apiName) && apisToQuery[api.apiName]) {
18+
if (apisToQuery.contains(api.apiName)) {
1919
const apiRes = await api.searchByTitle(query);
2020
res = res.concat(apiRes);
2121
}
@@ -28,9 +28,9 @@ export class APIManager {
2828
return await this.queryDetailedInfoById(item.id, item.dataSource);
2929
}
3030

31-
async queryDetailedInfoById(id: string, dataSource: string): Promise<MediaTypeModel> {
31+
async queryDetailedInfoById(id: string, apiName: string): Promise<MediaTypeModel> {
3232
for (const api of this.apis) {
33-
if (api.apiName === dataSource) {
33+
if (api.apiName === apiName) {
3434
return api.getById(id);
3535
}
3636
}

src/main.ts

Lines changed: 116 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,31 @@ export default class MediaDbPlugin extends Plugin {
2323
mediaTypeManager: MediaTypeManager;
2424
modelPropertyMapper: ModelPropertyMapper;
2525

26+
frontMatterRexExpPattern: string = '^(---)\\n[\\s\\S]*?\\n---';
27+
2628
async onload() {
2729
await this.loadSettings();
30+
// register the settings tab
31+
this.addSettingTab(new MediaDbSettingTab(this.app, this));
32+
33+
34+
this.apiManager = new APIManager();
35+
// register APIs
36+
this.apiManager.registerAPI(new OMDbAPI(this));
37+
this.apiManager.registerAPI(new MALAPI(this));
38+
this.apiManager.registerAPI(new WikipediaAPI(this));
39+
this.apiManager.registerAPI(new MusicBrainzAPI(this));
40+
this.apiManager.registerAPI(new SteamAPI(this));
41+
this.apiManager.registerAPI(new BoardGameGeekAPI(this));
42+
// this.apiManager.registerAPI(new LocGovAPI(this)); // TODO: parse data
43+
44+
this.mediaTypeManager = new MediaTypeManager(this.settings);
45+
this.modelPropertyMapper = new ModelPropertyMapper(this.settings);
46+
2847

2948
// add icon to the left ribbon
3049
const ribbonIconEl = this.addRibbonIcon('database', 'Add new Media DB entry', (evt: MouseEvent) =>
31-
this.createMediaDbNotes(this.openMediaDbAdvancedSearchModal.bind(this)),
50+
this.createEntryWithAdvancedSearchModal(),
3251
);
3352
ribbonIconEl.addClass('obsidian-media-db-plugin-ribbon-class');
3453

@@ -46,13 +65,13 @@ export default class MediaDbPlugin extends Plugin {
4665
this.addCommand({
4766
id: 'open-media-db-search-modal',
4867
name: 'Add new Media DB entry',
49-
callback: () => this.createMediaDbNotes(this.openMediaDbAdvancedSearchModal.bind(this)),
68+
callback: () => this.createEntryWithAdvancedSearchModal(),
5069
});
5170
// register command to open id search modal
5271
this.addCommand({
5372
id: 'open-media-db-id-search-modal',
5473
name: 'Add new Media DB entry by id',
55-
callback: () => this.createMediaDbNotes(this.openMediaDbIdSearchModal.bind(this)),
74+
callback: () => this.createEntryWithIdSearchModal(),
5675
});
5776
// register command to update the open note
5877
this.addCommand({
@@ -68,42 +87,65 @@ export default class MediaDbPlugin extends Plugin {
6887
return true;
6988
},
7089
});
90+
}
7191

72-
// register the settings tab
73-
this.addSettingTab(new MediaDbSettingTab(this.app, this));
92+
async createEntryWithSearchModal() {
7493

94+
}
7595

76-
this.apiManager = new APIManager();
77-
// register APIs
78-
this.apiManager.registerAPI(new OMDbAPI(this));
79-
this.apiManager.registerAPI(new MALAPI(this));
80-
this.apiManager.registerAPI(new WikipediaAPI(this));
81-
this.apiManager.registerAPI(new MusicBrainzAPI(this));
82-
this.apiManager.registerAPI(new SteamAPI(this));
83-
this.apiManager.registerAPI(new BoardGameGeekAPI(this));
84-
// this.apiManager.registerAPI(new LocGovAPI(this)); // TODO: parse data
96+
async createEntryWithAdvancedSearchModal() {
97+
let results: MediaTypeModel[] = [];
98+
try {
99+
const {query, apis} = await this.openMediaDbAdvancedSearchModal();
85100

86-
this.mediaTypeManager = new MediaTypeManager(this.settings);
87-
this.modelPropertyMapper = new ModelPropertyMapper(this.settings);
101+
new Notice('MediaDB Searching...');
102+
103+
const apiSearchResults = await this.apiManager.query(query, apis);
104+
const selectResults = await this.openMediaDbSelectModal(apiSearchResults, false);
105+
results = await this.queryDetails(selectResults);
106+
} catch (e) {
107+
console.warn(e);
108+
new Notice(e.toString());
109+
}
110+
111+
debugLog(results);
112+
await this.createMediaDbNotes(results);
88113
}
89114

90-
async createMediaDbNotes(modal: () => Promise<MediaTypeModel[]>, attachFile?: TFile): Promise<void> {
91-
let models: MediaTypeModel[] = [];
115+
async createEntryWithIdSearchModal() {
116+
let result: MediaTypeModel = undefined;
92117
try {
93-
models = await modal();
118+
const {query, api} = await this.openMediaDbIdSearchModal();
119+
120+
new Notice('MediaDB Searching...');
121+
122+
result = await this.apiManager.queryDetailedInfoById(query, api);
94123
} catch (e) {
95124
console.warn(e);
96125
new Notice(e.toString());
97126
}
98127

128+
debugLog(result);
129+
await this.createMediaDbNoteFromModel(result);
130+
}
131+
132+
async createMediaDbNotes(models: MediaTypeModel[], attachFile?: TFile): Promise<void> {
133+
for (const model of models) {
134+
await this.createMediaDbNoteFromModel(model, attachFile);
135+
}
136+
}
137+
138+
async queryDetails(models: MediaTypeModel[]): Promise<MediaTypeModel[]> {
139+
let detailModels: MediaTypeModel[] = [];
99140
for (const model of models) {
100141
try {
101-
await this.createMediaDbNoteFromModel(await this.apiManager.queryDetailedInfo(model), attachFile);
142+
detailModels.push(await this.apiManager.queryDetailedInfo(model));
102143
} catch (e) {
103144
console.warn(e);
104145
new Notice(e.toString());
105146
}
106147
}
148+
return detailModels;
107149
}
108150

109151
async createMediaDbNoteFromModel(mediaTypeModel: MediaTypeModel, attachFile?: TFile): Promise<void> {
@@ -187,23 +229,33 @@ export default class MediaDbPlugin extends Plugin {
187229
return metadata;
188230
}
189231

232+
/**
233+
* Creates a note in the vault.
234+
*
235+
* @param fileName
236+
* @param fileContent
237+
* @param openFile
238+
*/
190239
async createNote(fileName: string, fileContent: string, openFile: boolean = false) {
191240
fileName = replaceIllegalFileNameCharactersInString(fileName);
192241
const filePath = `${this.settings.folder.replace(/\/$/, '')}/${fileName}.md`;
193242

243+
// find and possibly create the folder set in settings
194244
const folder = this.app.vault.getAbstractFileByPath(this.settings.folder);
195245
if (!folder) {
196246
await this.app.vault.createFolder(this.settings.folder.replace(/\/$/, ''));
197247
}
198248

249+
// find and delete file with the same name
199250
const file = this.app.vault.getAbstractFileByPath(filePath);
200251
if (file) {
201252
await this.app.vault.delete(file);
202253
}
203254

255+
// create the file
204256
const targetFile = await this.app.vault.create(filePath, fileContent);
205257

206-
// open file
258+
// open newly crated file
207259
if (openFile) {
208260
const activeLeaf = this.app.workspace.getUnpinnedLeaf();
209261
if (!activeLeaf) {
@@ -214,6 +266,10 @@ export default class MediaDbPlugin extends Plugin {
214266
}
215267
}
216268

269+
/**
270+
* Update the active note by querying the API again.
271+
* 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.
272+
*/
217273
async updateActiveNote() {
218274
const activeFile: TFile = this.app.workspace.getActiveFile();
219275
if (!activeFile) {
@@ -249,18 +305,12 @@ export default class MediaDbPlugin extends Plugin {
249305
const erroredFiles: { filePath: string, error: string }[] = [];
250306
let canceled: boolean = false;
251307

252-
const {selectedAPI, titleFieldName, appendContent} = await new Promise((resolve, reject) => {
253-
new MediaDbFolderImportModal(this.app, this, ((selectedAPI, titleFieldName, appendContent) => {
308+
const {selectedAPI, titleFieldName, appendContent} = await new Promise<{selectedAPI: string, titleFieldName: string, appendContent: boolean}>((resolve, reject) => {
309+
new MediaDbFolderImportModal(this.app, this, ((selectedAPI: string, titleFieldName: string, appendContent: boolean) => {
254310
resolve({selectedAPI, titleFieldName, appendContent});
255311
})).open();
256312
});
257313

258-
const selectedAPIs = {};
259-
for (const api of this.apiManager.apis) {
260-
// @ts-ignore
261-
selectedAPIs[api.apiName] = api.apiName === selectedAPI;
262-
}
263-
264314
for (const child of folder.children) {
265315
if (child instanceof TFile) {
266316
const file = child as TFile;
@@ -279,7 +329,7 @@ export default class MediaDbPlugin extends Plugin {
279329

280330
let results: MediaTypeModel[] = [];
281331
try {
282-
results = await this.apiManager.query(title, selectedAPIs);
332+
results = await this.apiManager.query(title, [selectedAPI]);
283333
} catch (e) {
284334
erroredFiles.push({filePath: file.path, error: e.toString()});
285335
continue;
@@ -292,7 +342,7 @@ export default class MediaDbPlugin extends Plugin {
292342
let selectedResults: MediaTypeModel[] = [];
293343
try {
294344
selectedResults = await new Promise((resolve, reject) => {
295-
const searchResultModal = new MediaDbSearchResultModal(this.app, this, results, true, (err, res) => {
345+
const searchResultModal = new MediaDbSearchResultModal(this.app, this, results, true, (res, err) => {
296346
if (err) {
297347
return reject(err);
298348
}
@@ -325,47 +375,60 @@ export default class MediaDbPlugin extends Plugin {
325375
continue;
326376
}
327377

328-
await this.createMediaDbNotes(async () => selectedResults, appendContent ? file : null);
378+
const detailedResults = await this.queryDetails(selectedResults);
379+
await this.createMediaDbNotes(detailedResults, appendContent ? file : null);
329380
}
330381
}
331382

332383
if (erroredFiles.length > 0) {
333-
const title = `bulk import error report ${dateTimeToString(new Date())}`;
334-
const filePath = `${this.settings.folder.replace(/\/$/, '')}/${title}.md`;
384+
await this.createErroredFilesReport(erroredFiles);
385+
}
386+
}
335387

336-
const table = [['file', 'error']].concat(erroredFiles.map(x => [x.filePath, x.error]));
337-
// console.log(table)
338-
let fileContent = `# ${title}\n\n${markdownTable(table)}`;
388+
async createErroredFilesReport(erroredFiles: { filePath: string, error: string }[]): Promise<void> {
389+
const title = `bulk import error report ${dateTimeToString(new Date())}`;
390+
const filePath = `${this.settings.folder.replace(/\/$/, '')}/${title}.md`;
339391

340-
const targetFile = await this.app.vault.create(filePath, fileContent);
341-
}
392+
const table = [['file', 'error']].concat(erroredFiles.map(x => [x.filePath, x.error]));
393+
// console.log(table)
394+
let fileContent = `# ${title}\n\n${markdownTable(table)}`;
395+
396+
const targetFile = await this.app.vault.create(filePath, fileContent);
342397
}
343398

344-
async openMediaDbAdvancedSearchModal(): Promise<MediaTypeModel[]> {
345-
return new Promise(((resolve, reject) => {
346-
new MediaDbAdvancedSearchModal(this.app, this, (err, results) => {
399+
async openMediaDbAdvancedSearchModal(): Promise<{ query: string, apis: string[] }> {
400+
return await new Promise((resolve, reject) => {
401+
new MediaDbAdvancedSearchModal(this.app, this, (res, err) => {
347402
if (err) {
348403
return reject(err);
349404
}
350-
new MediaDbSearchResultModal(this.app, this, results, false, (err2, res) => {
351-
if (err2) {
352-
return reject(err2);
353-
}
354-
resolve(res);
355-
}, () => resolve([])).open();
405+
resolve(res)
356406
}).open();
357-
}));
407+
});
408+
}
409+
410+
async openMediaDbIdSearchModal(): Promise<{ query: string, api: string }> {
411+
return await new Promise((resolve, reject) => {
412+
new MediaDbIdSearchModal(this.app, this, (res, err) => {
413+
if (err) {
414+
return reject(err);
415+
}
416+
resolve(res)
417+
}).open();
418+
});
358419
}
359420

360-
async openMediaDbIdSearchModal(): Promise<MediaTypeModel> {
361-
return new Promise(((resolve, reject) => {
362-
new MediaDbIdSearchModal(this.app, this, (err, res) => {
421+
async openMediaDbSelectModal(resultsToDisplay: MediaTypeModel[], skipButton: boolean = false): Promise<MediaTypeModel[]> {
422+
return await new Promise((resolve, reject) => {
423+
new MediaDbSearchResultModal(this.app, this, resultsToDisplay, skipButton, (res, err) => {
363424
if (err) {
364425
return reject(err);
365426
}
366427
resolve(res);
428+
}, () => {
429+
resolve([])
367430
}).open();
368-
}));
431+
});
369432
}
370433

371434
async loadSettings() {

src/modals/MediaDbAdvancedSearchModal.ts

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ export class MediaDbAdvancedSearchModal extends Modal {
88
isBusy: boolean;
99
plugin: MediaDbPlugin;
1010
searchBtn: ButtonComponent;
11-
selectedApis: any;
12-
onSubmit: (err: Error, result?: MediaTypeModel[]) => void;
11+
selectedApis: {name: string, selected: boolean}[];
12+
onSubmit: (res: {query: string, apis: string[]}, err?: Error) => void;
1313

14-
constructor(app: App, plugin: MediaDbPlugin, onSubmit?: (err: Error, result?: MediaTypeModel[]) => void) {
14+
constructor(app: App, plugin: MediaDbPlugin, onSubmit?: (res: {query: string, apis: string[]}, err?: Error) => void) {
1515
super(app);
1616
this.plugin = plugin;
1717
this.onSubmit = onSubmit;
1818
this.selectedApis = [];
1919
for (const api of this.plugin.apiManager.apis) {
20-
this.selectedApis[api.apiName] = false;
20+
this.selectedApis.push({name: api.apiName, selected: false});
2121
}
2222
}
2323

@@ -36,14 +36,9 @@ export class MediaDbAdvancedSearchModal extends Modal {
3636
return;
3737
}
3838

39-
let selectedAPICount = 0;
40-
for (const api in this.selectedApis) {
41-
if (this.selectedApis[api]) {
42-
selectedAPICount += 1;
43-
}
44-
}
39+
const apis: string[] = this.selectedApis.filter(x => x.selected).map(x => x.name);
4540

46-
if (selectedAPICount === 0) {
41+
if (apis.length === 0) {
4742
new Notice('MDB | No API selected');
4843
return;
4944
}
@@ -54,12 +49,9 @@ export class MediaDbAdvancedSearchModal extends Modal {
5449
this.searchBtn.setDisabled(false);
5550
this.searchBtn.setButtonText('Searching...');
5651

57-
console.log(`MDB | query started with title ${this.query}`);
58-
59-
const res = await this.plugin.apiManager.query(this.query, this.selectedApis);
60-
this.onSubmit(null, res);
52+
this.onSubmit({query: this.query, apis: apis});
6153
} catch (e) {
62-
this.onSubmit(e);
54+
this.onSubmit(null, e);
6355
} finally {
6456
this.close();
6557
}
@@ -96,9 +88,9 @@ export class MediaDbAdvancedSearchModal extends Modal {
9688

9789
const apiToggleComponent = new ToggleComponent(apiToggleComponentWrapper);
9890
apiToggleComponent.setTooltip(api.apiName);
99-
apiToggleComponent.setValue(this.selectedApis[api.apiName]);
91+
apiToggleComponent.setValue(this.selectedApis.find(x => x.name === api.apiName).selected);
10092
apiToggleComponent.onChange((value) => {
101-
this.selectedApis[api.apiName] = value;
93+
this.selectedApis.find(x => x.name === api.apiName).selected = value;
10294
});
10395
apiToggleComponentWrapper.appendChild(apiToggleComponent.toggleEl);
10496
}

0 commit comments

Comments
 (0)