import { Notice , Plugin , addIcon } from 'obsidian' ; import * as AnkiConnect from './src/anki' ; import { PluginSettings , ParsedSettings } from './src/interfaces/settings-interface' ; import { SettingsTab } from './src/settings' ; import { ANKI_ICON } from './src/constants' ; import { settingToData } from './src/setting-to-data' ; import { FileManager } from './src/files-manager' ; export default class MyPlugin extends Plugin { settings : PluginSettings ; note_types : Array < string > ; fields_dict : Record < string , string [ ] > ; added_media : string [ ] ; file_hashes : Record < string , string > ; async getDefaultSettings ( ) { let settings = { CUSTOM_REGEXPS : { } , FILE_LINK_FIELDS : { } , CONTEXT_FIELDS : { } , FOLDER_DECKS : { } , FOLDER_TAGS : { } , Syntax : { "Begin Note" : "START" , "End Note" : "END" , "Begin Inline Note" : "STARTI" , "End Inline Note" : "ENDI" , "Target Deck Line" : "TARGET DECK" , "File Tags Line" : "FILE TAGS" , "Delete Note Line" : "DELETE" , "Frozen Fields Line" : "FROZEN" } , Defaults : { "Tag" : "Obsidian_to_Anki" , "Deck" : "Default" , "Scheduling Interval" : 0 , "Add File Link" : false , "Add Context" : false , "CurlyCloze" : false , "CurlyCloze - Highlights to Clozes" : false , "ID Comments" : true , "Add Obsidian Tags" : false , } } ; this . note_types = await AnkiConnect . invoke ( 'modelNames' ) as Array < string > ; this . fields_dict = await this . generateFieldsDict ( ) ; for ( let note_type of this . note_types ) { settings [ "CUSTOM_REGEXPS" ] [ note_type ] = "" ; const field_names = await AnkiConnect . invoke ( 'modelFieldNames' , { modelName : note_type } ) as string [ ] ; this . fields_dict [ note_type ] = field_names ; settings [ "FILE_LINK_FIELDS" ] [ note_type ] = field_names [ 0 ] ; } return settings ; } async generateFieldsDict ( ) { let fields_dict = { } ; for ( let note_type of this . note_types ) { const field_names = await AnkiConnect . invoke ( 'modelFieldNames' , { modelName : note_type } ) as string [ ] ; fields_dict [ note_type ] = field_names ; } return fields_dict ; } async saveDefault ( ) { const default_sets = await this . getDefaultSettings ( ) ; this . saveData ( { settings : default_sets , "Added Media" : [ ] , "File Hashes" : { } , fields_dict : { } } ) ; } async loadSettings ( ) { let current_data = await this . loadData ( ) ; if ( current_data == null || Object . keys ( current_data ) . length != 4 ) { new Notice ( "Need to connect to Anki generate default settings..." ) ; const default_sets = await this . getDefaultSettings ( ) ; this . saveData ( { settings : default_sets , "Added Media" : [ ] , "File Hashes" : { } , fields_dict : { } } ) ; new Notice ( "Default settings successfully generated!" ) ; return default_sets ; } else { return current_data . settings ; } } async loadAddedMedia ( ) { let current_data = await this . loadData ( ) ; if ( current_data == null ) { await this . saveDefault ( ) ; return [ ] ; } else { return current_data [ "Added Media" ] ; } } async loadFileHashes ( ) { let current_data = await this . loadData ( ) ; if ( current_data == null ) { await this . saveDefault ( ) ; return { } ; } else { return current_data [ "File Hashes" ] ; } } async loadFieldsDict ( ) { let current_data = await this . loadData ( ) ; if ( current_data == null ) { await this . saveDefault ( ) ; const fields_dict = await this . generateFieldsDict ( ) ; return fields_dict ; } return current_data . fields_dict ; } async saveAllData ( ) { this . saveData ( { settings : this . settings , "Added Media" : this . added_media , "File Hashes" : this . file_hashes , fields_dict : this . fields_dict } ) ; } regenerateSettingsRegexps ( ) { let regexp_section = this . settings [ "CUSTOM_REGEXPS" ] ; for ( let note_type of this . note_types ) { this . settings [ "CUSTOM_REGEXPS" ] [ note_type ] = regexp_section . hasOwnProperty ( note_type ) ? regexp_section [ note_type ] : "" ; } for ( let note_type of Object . keys ( this . settings [ "CUSTOM_REGEXPS" ] ) ) { if ( ! this . note_types . includes ( note_type ) ) { delete this . settings [ "CUSTOM_REGEXPS" ] [ note_type ] ; } } } async scanVault ( ) { new Notice ( 'Scanning vault, check console for details...' ) ; console . info ( "Checking connection to Anki..." ) ; try { await AnkiConnect . invoke ( 'modelNames' ) ; } catch ( e ) { new Notice ( "Error, couldn't connect to Anki! Check console for error message." ) ; return ; } new Notice ( "Successfully connected to Anki! This could take a few minutes - please don't close Anki until the plugin is finished" ) ; const data = await settingToData ( this . app , this . settings , this . fields_dict ) ; const manager = new FileManager ( this . app , data , this . app . vault . getMarkdownFiles ( ) , this . file_hashes , this . added_media ) ; await manager . initialiseFiles ( ) ; await manager . requests_1 ( ) ; this . added_media = Array . from ( manager . added_media_set ) ; const hashes = manager . getHashes ( ) ; for ( let key in hashes ) { this . file_hashes [ key ] = hashes [ key ] ; } new Notice ( "All done! Saving file hashes and added media now..." ) ; this . saveAllData ( ) ; } async onload ( ) { console . log ( 'loading Obsidian_to_Anki...' ) ; addIcon ( 'anki' , ANKI_ICON ) ; try { this . settings = await this . loadSettings ( ) ; } catch ( e ) { new Notice ( "Couldn't connect to Anki! Check console for error message." ) ; return ; } this . note_types = Object . keys ( this . settings [ "CUSTOM_REGEXPS" ] ) ; this . fields_dict = await this . loadFieldsDict ( ) ; if ( Object . keys ( this . fields_dict ) . length == 0 ) { new Notice ( 'Need to connect to Anki to generate fields dictionary...' ) ; try { this . fields_dict = await this . generateFieldsDict ( ) ; new Notice ( "Fields dictionary successfully generated!" ) ; } catch ( e ) { new Notice ( "Couldn't connect to Anki! Check console for error message." ) ; return ; } } this . added_media = await this . loadAddedMedia ( ) ; this . file_hashes = await this . loadFileHashes ( ) ; this . addSettingTab ( new SettingsTab ( this . app , this ) ) ; this . addRibbonIcon ( 'anki' , 'Obsidian_to_Anki - Scan Vault' , async ( ) => { await this . scanVault ( ) ; } ) ; this . addCommand ( { id : 'anki-scan-vault' , name : 'Scan Vault' , callback : async ( ) => { await this . scanVault ( ) ; } } ) ; } async onunload ( ) { console . log ( "Saving settings for Obsidian_to_Anki..." ) ; this . saveAllData ( ) ; console . log ( 'unloading Obsidian_to_Anki...' ) ; } }