Skip to content

Commit a10f9ec

Browse files
committed
Allow batch / folder import by id as well as title
1 parent 9fa7348 commit a10f9ec

File tree

2 files changed

+90
-48
lines changed

2 files changed

+90
-48
lines changed

src/main.ts

Lines changed: 69 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -621,9 +621,14 @@ export default class MediaDbPlugin extends Plugin {
621621
const erroredFiles: { filePath: string; error: string }[] = [];
622622
let canceled: boolean = false;
623623

624-
const { selectedAPI, titleFieldName, appendContent } = await new Promise<{ selectedAPI: string; titleFieldName: string; appendContent: boolean }>(resolve => {
625-
new MediaDbFolderImportModal(this.app, this, (selectedAPI: string, titleFieldName: string, appendContent: boolean) => {
626-
resolve({ selectedAPI, titleFieldName, appendContent });
624+
const { selectedAPI, titleFieldName, idFieldName, appendContent } = await new Promise<{
625+
selectedAPI: string;
626+
titleFieldName: string;
627+
idFieldName: string;
628+
appendContent: boolean;
629+
}>(resolve => {
630+
new MediaDbFolderImportModal(this.app, this, (selectedAPI: string, titleFieldName: string, idFieldName: string, appendContent: boolean) => {
631+
resolve({ selectedAPI, titleFieldName, idFieldName, appendContent });
627632
}).open();
628633
});
629634

@@ -637,54 +642,75 @@ export default class MediaDbPlugin extends Plugin {
637642

638643
const metadata = this.getMetadataFromFileCache(file);
639644

640-
const title = metadata[titleFieldName];
641-
if (!title || typeof title !== 'string') {
642-
erroredFiles.push({ filePath: file.path, error: `metadata field '${titleFieldName}' not found, empty, or not a string` });
643-
continue;
644-
}
645+
// Querying by ID takes priority, doesn't require user to select from multiple matches
646+
const id = metadata[idFieldName];
647+
if (id && typeof id === 'string') {
648+
try {
649+
const model = await this.apiManager.queryDetailedInfoById(id, selectedAPI);
650+
if (model) {
651+
await this.createMediaDbNotes([model], appendContent ? file : undefined);
652+
} else {
653+
erroredFiles.push({ filePath: file.path, error: `Failed to query API with id: ${id}` });
654+
}
655+
} catch (e) {
656+
erroredFiles.push({ filePath: file.path, error: `${e}` });
657+
continue;
658+
}
659+
} else {
660+
// Query API with title instead, requires user to select best match
661+
const title = metadata[titleFieldName];
662+
if (!title || typeof title !== 'string') {
663+
erroredFiles.push({ filePath: file.path, error: `metadata field '${titleFieldName}' not found, empty, or not a string` });
664+
continue;
665+
}
645666

646-
let results: MediaTypeModel[] = [];
647-
try {
648-
results = await this.apiManager.query(title, [selectedAPI]);
649-
} catch (e) {
650-
erroredFiles.push({ filePath: file.path, error: `${e}` });
651-
continue;
652-
}
653-
if (!results || results.length === 0) {
654-
erroredFiles.push({ filePath: file.path, error: `no search results` });
655-
continue;
656-
}
667+
let results: MediaTypeModel[] = [];
668+
try {
669+
results = await this.apiManager.query(title, [selectedAPI]);
670+
} catch (e) {
671+
erroredFiles.push({ filePath: file.path, error: `${e}` });
672+
continue;
673+
}
674+
if (!results || results.length === 0) {
675+
erroredFiles.push({ filePath: file.path, error: `no search results` });
676+
continue;
677+
}
657678

658-
const { selectModalResult, selectModal } = await this.modalHelper.createSelectModal({ elements: results, skipButton: true, modalTitle: `Results for '${title}'` });
679+
const { selectModalResult, selectModal } = await this.modalHelper.createSelectModal({
680+
elements: results,
681+
skipButton: true,
682+
modalTitle: `Results for '${title}'`,
683+
});
659684

660-
if (selectModalResult.code === ModalResultCode.ERROR) {
661-
erroredFiles.push({ filePath: file.path, error: selectModalResult.error.message });
662-
selectModal.close();
663-
continue;
664-
}
685+
if (selectModalResult.code === ModalResultCode.ERROR) {
686+
erroredFiles.push({ filePath: file.path, error: selectModalResult.error.message });
687+
selectModal.close();
688+
continue;
689+
}
665690

666-
if (selectModalResult.code === ModalResultCode.CLOSE) {
667-
erroredFiles.push({ filePath: file.path, error: 'user canceled' });
668-
selectModal.close();
669-
canceled = true;
670-
continue;
671-
}
691+
if (selectModalResult.code === ModalResultCode.CLOSE) {
692+
erroredFiles.push({ filePath: file.path, error: 'user canceled' });
693+
selectModal.close();
694+
canceled = true;
695+
continue;
696+
}
672697

673-
if (selectModalResult.code === ModalResultCode.SKIP) {
674-
erroredFiles.push({ filePath: file.path, error: 'user skipped' });
675-
selectModal.close();
676-
continue;
677-
}
698+
if (selectModalResult.code === ModalResultCode.SKIP) {
699+
erroredFiles.push({ filePath: file.path, error: 'user skipped' });
700+
selectModal.close();
701+
continue;
702+
}
678703

679-
if (selectModalResult.data.selected.length === 0) {
680-
erroredFiles.push({ filePath: file.path, error: `no search results selected` });
681-
continue;
682-
}
704+
if (selectModalResult.data.selected.length === 0) {
705+
erroredFiles.push({ filePath: file.path, error: `no search results selected` });
706+
continue;
707+
}
683708

684-
const detailedResults = await this.queryDetails(selectModalResult.data.selected);
685-
await this.createMediaDbNotes(detailedResults, appendContent ? file : undefined);
709+
const detailedResults = await this.queryDetails(selectModalResult.data.selected);
710+
await this.createMediaDbNotes(detailedResults, appendContent ? file : undefined);
686711

687-
selectModal.close();
712+
selectModal.close();
713+
}
688714
}
689715
}
690716

src/modals/MediaDbFolderImportModal.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,25 @@ import type MediaDbPlugin from '../main';
44

55
export class MediaDbFolderImportModal extends Modal {
66
plugin: MediaDbPlugin;
7-
onSubmit: (selectedAPI: string, titleFieldName: string, appendContent: boolean) => void;
7+
onSubmit: (selectedAPI: string, titleFieldName: string, idFieldName: string, appendContent: boolean) => void;
88
selectedApi: string;
99
searchBtn?: ButtonComponent;
1010
titleFieldName: string;
11+
idFieldName: string;
1112
appendContent: boolean;
1213

13-
constructor(app: App, plugin: MediaDbPlugin, onSubmit: (selectedAPI: string, titleFieldName: string, appendContent: boolean) => void) {
14+
constructor(app: App, plugin: MediaDbPlugin, onSubmit: (selectedAPI: string, titleFieldName: string, idFieldName: string, appendContent: boolean) => void) {
1415
super(app);
1516
this.plugin = plugin;
1617
this.onSubmit = onSubmit;
1718
this.selectedApi = plugin.apiManager.apis[0].apiName;
1819
this.titleFieldName = '';
20+
this.idFieldName = '';
1921
this.appendContent = false;
2022
}
2123

2224
submit(): void {
23-
this.onSubmit(this.selectedApi, this.titleFieldName, this.appendContent);
25+
this.onSubmit(this.selectedApi, this.titleFieldName, this.idFieldName, this.appendContent);
2426
this.close();
2527
}
2628

@@ -43,7 +45,7 @@ export class MediaDbFolderImportModal extends Modal {
4345
apiSelectorWrapper.appendChild(apiSelectorComponent.selectEl);
4446

4547
contentEl.createDiv({ cls: 'media-db-plugin-spacer' });
46-
contentEl.createEl('h3', { text: 'Append note content to Media DB entry.' });
48+
contentEl.createEl('h3', { text: 'Append note content to Media DB entry?' });
4749

4850
const appendContentToggleElementWrapper = contentEl.createEl('div', { cls: 'media-db-plugin-list-wrapper' });
4951
const appendContentToggleTextWrapper = appendContentToggleElementWrapper.createEl('div', { cls: 'media-db-plugin-list-text-wrapper' });
@@ -60,7 +62,7 @@ export class MediaDbFolderImportModal extends Modal {
6062
appendContentToggleComponentWrapper.appendChild(appendContentToggle.toggleEl);
6163

6264
contentEl.createDiv({ cls: 'media-db-plugin-spacer' });
63-
contentEl.createEl('h3', { text: 'The name of the metadata field that should be used as the title to query.' });
65+
contentEl.createEl('h3', { text: "Name of 'title' metadata field to use in API query." });
6466

6567
const placeholder = 'title';
6668
const titleFieldNameComponent = new TextComponent(contentEl);
@@ -74,6 +76,20 @@ export class MediaDbFolderImportModal extends Modal {
7476
});
7577
contentEl.appendChild(titleFieldNameComponent.inputEl);
7678

79+
contentEl.createDiv({ cls: 'media-db-plugin-spacer' });
80+
contentEl.createEl('h3', { text: "Name of 'id' metadata field to use in API query (if present, will be used instead of title)." });
81+
82+
const idFieldNameComponent = new TextComponent(contentEl);
83+
idFieldNameComponent.inputEl.style.width = '100%';
84+
idFieldNameComponent.setPlaceholder('id');
85+
idFieldNameComponent.onChange(value => (this.idFieldName = value));
86+
idFieldNameComponent.inputEl.addEventListener('keydown', ke => {
87+
if (ke.key === 'Enter') {
88+
this.submit();
89+
}
90+
});
91+
contentEl.appendChild(idFieldNameComponent.inputEl);
92+
7793
contentEl.createDiv({ cls: 'media-db-plugin-spacer' });
7894

7995
new Setting(contentEl)

0 commit comments

Comments
 (0)