1- import { MarkdownView , Notice , parseYaml , Plugin , stringifyYaml , TFile , TFolder } from 'obsidian' ;
1+ import type { TFile } from 'obsidian' ;
2+ import { MarkdownView , Notice , parseYaml , Plugin , stringifyYaml , TFolder } from 'obsidian' ;
23import { requestUrl , normalizePath } from 'obsidian' ;
34import type { MediaType } from 'src/utils/MediaType' ;
45import { APIManager } from './api/APIManager' ;
@@ -14,19 +15,18 @@ import { OpenLibraryAPI } from './api/apis/OpenLibraryAPI';
1415import { SteamAPI } from './api/apis/SteamAPI' ;
1516import { WikipediaAPI } from './api/apis/WikipediaAPI' ;
1617import { ConfirmOverwriteModal } from './modals/ConfirmOverwriteModal' ;
17- import { MediaDbFolderImportModal } from './modals/MediaDbFolderImportModal' ;
1818import type { MediaTypeModel } from './models/MediaTypeModel' ;
1919import { PropertyMapper } from './settings/PropertyMapper' ;
2020import { PropertyMapping , PropertyMappingModel } from './settings/PropertyMapping' ;
2121import type { MediaDbPluginSettings } from './settings/Settings' ;
2222import { getDefaultSettings , MediaDbSettingTab } from './settings/Settings' ;
23+ import { BulkImportHelper } from './utils/BulkImportHelper' ;
2324import { DateFormatter } from './utils/DateFormatter' ;
2425import { MEDIA_TYPES , MediaTypeManager } from './utils/MediaTypeManager' ;
2526import type { SearchModalOptions } from './utils/ModalHelper' ;
26- import { ModalHelper , ModalResultCode } from './utils/ModalHelper' ;
27+ import { ModalHelper } from './utils/ModalHelper' ;
2728import type { CreateNoteOptions } from './utils/Utils' ;
28- import { dateTimeToString , markdownTable , replaceIllegalFileNameCharactersInString , unCamelCase , hasTemplaterPlugin , useTemplaterPluginInFile } from './utils/Utils' ;
29- import { BulkImportLookupMethod } from 'src/utils/BulkImportLookupMethod' ;
29+ import { replaceIllegalFileNameCharactersInString , unCamelCase , hasTemplaterPlugin , useTemplaterPluginInFile } from './utils/Utils' ;
3030
3131export type Metadata = Record < string , unknown > ;
3232
@@ -42,6 +42,7 @@ export default class MediaDbPlugin extends Plugin {
4242 mediaTypeManager ! : MediaTypeManager ;
4343 modelPropertyMapper ! : PropertyMapper ;
4444 modalHelper ! : ModalHelper ;
45+ bulkImportHelper ! : BulkImportHelper ;
4546 dateFormatter ! : DateFormatter ;
4647
4748 frontMatterRexExpPattern : string = '^(---)\\n[\\s\\S]*?\\n---' ;
@@ -64,6 +65,7 @@ export default class MediaDbPlugin extends Plugin {
6465 this . mediaTypeManager = new MediaTypeManager ( ) ;
6566 this . modelPropertyMapper = new PropertyMapper ( this ) ;
6667 this . modalHelper = new ModalHelper ( this ) ;
68+ this . bulkImportHelper = new BulkImportHelper ( this ) ;
6769 this . dateFormatter = new DateFormatter ( ) ;
6870
6971 await this . loadSettings ( ) ;
@@ -84,7 +86,7 @@ export default class MediaDbPlugin extends Plugin {
8486 menu . addItem ( item => {
8587 item . setTitle ( 'Import folder as Media DB entries' )
8688 . setIcon ( 'database' )
87- . onClick ( ( ) => this . createEntriesFromFolder ( file ) ) ;
89+ . onClick ( ( ) => this . bulkImportHelper . import ( file ) ) ;
8890 } ) ;
8991 }
9092 } ) ,
@@ -558,116 +560,6 @@ export default class MediaDbPlugin extends Plugin {
558560 }
559561 }
560562
561- async createEntriesFromFolder ( folder : TFolder ) : Promise < void > {
562- const erroredFiles : { filePath : string ; error : string } [ ] = [ ] ;
563- let canceled : boolean = false ;
564-
565- const { selectedAPI, lookupMethod, fieldName, appendContent } = await new Promise < {
566- selectedAPI : string ;
567- lookupMethod : string ;
568- fieldName : string ;
569- appendContent : boolean ;
570- } > ( resolve => {
571- new MediaDbFolderImportModal ( this . app , this , ( selectedAPI : string , lookupMethod : string , fieldName : string , appendContent : boolean ) => {
572- resolve ( { selectedAPI, lookupMethod, fieldName, appendContent } ) ;
573- } ) . open ( ) ;
574- } ) ;
575-
576- for ( const child of folder . children ) {
577- if ( child instanceof TFile ) {
578- const file : TFile = child ;
579- if ( canceled ) {
580- erroredFiles . push ( { filePath : file . path , error : 'user canceled' } ) ;
581- continue ;
582- }
583-
584- const metadata = this . getMetadataFromFileCache ( file ) ;
585- const lookupValue = metadata [ fieldName ] ;
586-
587- if ( ! lookupValue || typeof lookupValue !== 'string' ) {
588- erroredFiles . push ( { filePath : file . path , error : `metadata field '${ fieldName } ' not found, empty, or not a string` } ) ;
589- continue ;
590- } else if ( lookupMethod === BulkImportLookupMethod . ID ) {
591- try {
592- const model = await this . apiManager . queryDetailedInfoById ( lookupValue , selectedAPI ) ;
593- if ( model ) {
594- await this . createMediaDbNotes ( [ model ] , appendContent ? file : undefined ) ;
595- } else {
596- erroredFiles . push ( { filePath : file . path , error : `Failed to query API with id: ${ lookupValue } ` } ) ;
597- }
598- } catch ( e ) {
599- erroredFiles . push ( { filePath : file . path , error : `${ e } ` } ) ;
600- continue ;
601- }
602- } else if ( lookupMethod === BulkImportLookupMethod . TITLE ) {
603- let results : MediaTypeModel [ ] = [ ] ;
604- try {
605- results = await this . apiManager . query ( lookupValue , [ selectedAPI ] ) ;
606- } catch ( e ) {
607- erroredFiles . push ( { filePath : file . path , error : `${ e } ` } ) ;
608- continue ;
609- }
610- if ( ! results || results . length === 0 ) {
611- erroredFiles . push ( { filePath : file . path , error : `no search results` } ) ;
612- continue ;
613- }
614-
615- const { selectModalResult, selectModal } = await this . modalHelper . createSelectModal ( {
616- elements : results ,
617- skipButton : true ,
618- modalTitle : `Results for '${ lookupValue } '` ,
619- } ) ;
620-
621- if ( selectModalResult . code === ModalResultCode . ERROR ) {
622- erroredFiles . push ( { filePath : file . path , error : selectModalResult . error . message } ) ;
623- selectModal . close ( ) ;
624- continue ;
625- }
626-
627- if ( selectModalResult . code === ModalResultCode . CLOSE ) {
628- erroredFiles . push ( { filePath : file . path , error : 'user canceled' } ) ;
629- selectModal . close ( ) ;
630- canceled = true ;
631- continue ;
632- }
633-
634- if ( selectModalResult . code === ModalResultCode . SKIP ) {
635- erroredFiles . push ( { filePath : file . path , error : 'user skipped' } ) ;
636- selectModal . close ( ) ;
637- continue ;
638- }
639-
640- if ( selectModalResult . data . selected . length === 0 ) {
641- erroredFiles . push ( { filePath : file . path , error : `no search results selected` } ) ;
642- continue ;
643- }
644-
645- const detailedResults = await this . queryDetails ( selectModalResult . data . selected ) ;
646- await this . createMediaDbNotes ( detailedResults , appendContent ? file : undefined ) ;
647-
648- selectModal . close ( ) ;
649- } else {
650- erroredFiles . push ( { filePath : file . path , error : `invalid lookup type` } ) ;
651- continue ;
652- }
653- }
654- }
655-
656- if ( erroredFiles . length > 0 ) {
657- await this . createErroredFilesReport ( erroredFiles ) ;
658- }
659- }
660-
661- async createErroredFilesReport ( erroredFiles : { filePath : string ; error : string } [ ] ) : Promise < void > {
662- const title = `MDB - bulk import error report ${ dateTimeToString ( new Date ( ) ) } ` ;
663- const filePath = `${ title } .md` ;
664-
665- const table = [ [ 'file' , 'error' ] ] . concat ( erroredFiles . map ( x => [ x . filePath , x . error ] ) ) ;
666-
667- const fileContent = `# ${ title } \n\n${ markdownTable ( table ) } ` ;
668- await this . app . vault . create ( filePath , fileContent ) ;
669- }
670-
671563 async loadSettings ( ) : Promise < void > {
672564 // console.log(DEFAULT_SETTINGS);
673565 const diskSettings : MediaDbPluginSettings = ( await this . loadData ( ) ) as MediaDbPluginSettings ;
0 commit comments