From 80873784fcb9e6b52712caff124b20f85c1e8a4b Mon Sep 17 00:00:00 2001 From: wanxp <977741432@qq.com> Date: Sun, 20 Nov 2022 02:16:41 +0800 Subject: [PATCH] add function: sync personal movie/book/music info --- src/org/wanxp/constant/DoubanUserState.ts | 8 +++ .../wanxp/douban/component/DoubanSyncModal.ts | 64 ++++++++++++++++--- .../data/handler/DoubanAbstractLoadHandler.ts | 3 + .../wanxp/douban/data/model/HandleContext.ts | 3 +- .../wanxp/douban/model/GlobalStatusHolder.ts | 13 ++-- .../sync/model/GlobalSyncStatusHolder.ts | 6 +- src/org/wanxp/douban/sync/model/SyncConfig.ts | 1 + src/org/wanxp/lang/locale/en.ts | 4 +- src/org/wanxp/lang/locale/zh-cn.ts | 4 +- src/org/wanxp/main.ts | 28 +++++--- styles.css | 7 ++ 11 files changed, 112 insertions(+), 29 deletions(-) diff --git a/src/org/wanxp/constant/DoubanUserState.ts b/src/org/wanxp/constant/DoubanUserState.ts index aec5da6..7182dee 100644 --- a/src/org/wanxp/constant/DoubanUserState.ts +++ b/src/org/wanxp/constant/DoubanUserState.ts @@ -97,6 +97,14 @@ export const DoubanSubjectStateRecords_NOTE_SYNC: { [key :string]: string } = { [ALL]: i18nHelper.getMessage('500004'), } +// @ts-ignore +export const DoubanSubjectStateRecords_MUSIC_SYNC: { [key in DoubanSubjectState]: string } = { + // @ts-ignore + [ALL]: i18nHelper.getMessage('500004'), + [DoubanSubjectState.wish]: i18nHelper.getMessage('500402'), + [DoubanSubjectState.do]: i18nHelper.getMessage('500403'), + [DoubanSubjectState.collect]: i18nHelper.getMessage('500404'), +} diff --git a/src/org/wanxp/douban/component/DoubanSyncModal.ts b/src/org/wanxp/douban/component/DoubanSyncModal.ts index 8a31651..fa4b7bc 100644 --- a/src/org/wanxp/douban/component/DoubanSyncModal.ts +++ b/src/org/wanxp/douban/component/DoubanSyncModal.ts @@ -3,6 +3,7 @@ import { ButtonComponent, DropdownComponent, Modal, SearchComponent, Setting, + TextComponent, ToggleComponent } from "obsidian"; @@ -13,13 +14,15 @@ import {SyncType, SyncTypeRecords} from "../../constant/Constsant"; import { ALL, DoubanSubjectStateRecords_BOOK_SYNC, DoubanSubjectStateRecords_BROADCAST_SYNC, - DoubanSubjectStateRecords_MOVIE_SYNC, DoubanSubjectStateRecords_NOTE_SYNC + DoubanSubjectStateRecords_MOVIE_SYNC, DoubanSubjectStateRecords_MUSIC_SYNC, DoubanSubjectStateRecords_NOTE_SYNC } from "../../constant/DoubanUserState"; import {SyncConfig} from "../sync/model/SyncConfig"; import {clearInterval} from "timers"; import {statSync} from "fs"; import {CreateTemplateSelectParams} from "../setting/model/CreateTemplateSelectParams"; import {FolderSuggest} from "../setting/model/FolderSuggest"; +import SettingsManager from "../setting/SettingsManager"; +import {DEFAULT_SETTINGS} from "../../constant/DefaultSettings"; export class DoubanSyncModal extends Modal { plugin: DoubanPlugin; @@ -55,7 +58,6 @@ export class DoubanSyncModal extends Modal { const sliderDiv = contentEl.createEl('div'); sliderDiv.addClass('obsidian_douban_sync_slider'); - this.showProgress(sliderDiv); const controls = contentEl.createDiv("controls"); const syncButton = new ButtonComponent(controls) @@ -72,16 +74,22 @@ export class DoubanSyncModal extends Modal { }); cancelButton.setClass("obsidian_douban_search_button"); syncButton.setClass("obsidian_douban_search_button"); + this.showProgress(sliderDiv, syncButton); this.timer = setInterval(() => { - this.showProgress(sliderDiv); + this.showProgress(sliderDiv,syncButton); }, 1000); } - private showProgress(sliderDiv: HTMLDivElement) { + private showProgress(sliderDiv: HTMLDivElement, button:ButtonComponent) { const {syncStatus} = this.plugin.statusHolder; - if (!syncStatus) { + if (!this.plugin.statusHolder.syncStarted) { + sliderDiv.innerHTML = `

+ + ${syncStatus.getHandle()}/${syncStatus.getTotal()}:${i18nHelper.getMessage('110036')} +

` + button.setDisabled(true); return; } sliderDiv.innerHTML = `

@@ -94,8 +102,11 @@ export class DoubanSyncModal extends Modal { clearInterval(this.timer) } contentEl.createEl("h3", {text: i18nHelper.getMessage('500001')}); - - let syncConfig:SyncConfig = {syncType: SyncType.movie, scope: ALL, force: false, outputFolder: this.plugin.settings.dataFilePath}; + const {settings} = this.plugin; + let syncConfig:SyncConfig = {syncType: SyncType.movie, scope: ALL, + force: false, + outputFolder: (settings.dataFilePath == '' || settings.dataFilePath == null) ? DEFAULT_SETTINGS.dataFilePath : settings.dataFilePath, + dataFileNamePath: (settings.dataFileNamePath == '' || settings.dataFileNamePath == null) ? DEFAULT_SETTINGS.dataFileNamePath : settings.dataFileNamePath}; this.showConfigPan(contentEl, syncConfig, false); const controls = contentEl.createDiv("controls"); @@ -157,6 +168,16 @@ export class DoubanSyncModal extends Modal { folderLabel.addClass('obsidian_douban_sync_config_text'); this.createFolderSetting(folderSelections, config, disable); + const fileName = contentEl.createDiv('fileName-item'); + let fileNameLabel = fileName.createEl('label'); + fileNameLabel.setText(i18nHelper.getMessage('110035')); + fileNameLabel.addClass('obsidian_douban_settings_text'); + fileNameLabel.addClass('obsidian_douban_sync_config_text'); + fileNameLabel.addClass('obsidian_douban_sync_config'); + this.constructOutiFleName(fileName, config, disable); + + fileName.addClass('obsidian_douban_sync_config'); + folderSelections.addClass('obsidian_douban_sync_config'); typeSelections.addClass('obsidian_douban_sync_config'); scopeSelections.addClass('obsidian_douban_sync_config'); forceSelections.addClass('obsidian_douban_sync_config'); @@ -188,6 +209,9 @@ export class DoubanSyncModal extends Modal { case SyncType.note: this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_NOTE_SYNC, config, disable); break; + case SyncType.music: + this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_MUSIC_SYNC, config, disable); + break; } } @@ -204,14 +228,16 @@ export class DoubanSyncModal extends Modal { } private createFolderSetting(contentEl:HTMLDivElement, config: SyncConfig, disable:boolean) { - let outputFolder = this.plugin.settings.dataFilePath; + const {settings} = this.plugin; + const placeHolder = (settings.dataFilePath == '' || settings.dataFilePath == null) ? DEFAULT_SETTINGS.dataFilePath : settings.dataFilePath; + let outputFolder = placeHolder; if (config.outputFolder) { outputFolder = config.outputFolder; } - const search = new SearchComponent(contentEl); + const search = new TextComponent(contentEl); new FolderSuggest(this.plugin.app, search.inputEl); search.setValue(outputFolder) - .setPlaceholder(i18nHelper.getMessage('121503')) + .setPlaceholder(placeHolder) .onChange(async (value:string) => { config.outputFolder = value; }) @@ -220,4 +246,22 @@ export class DoubanSyncModal extends Modal { } } + private constructOutiFleName(containerEl: HTMLElement, config: SyncConfig, disable:boolean) { + const {settings} = this.plugin; + const placeHolder =(settings.dataFileNamePath == '' || settings.dataFileNamePath == null) ? DEFAULT_SETTINGS.dataFileNamePath : settings.dataFileNamePath; + let dataFileNamePath = placeHolder; + if (config.dataFileNamePath) { + dataFileNamePath = config.dataFileNamePath; + } + const textComponent = new TextComponent(containerEl); + textComponent.setPlaceholder(placeHolder) + .setValue(dataFileNamePath) + .onChange(async (value) => { + config.dataFileNamePath = value; + }); + if (disable) { + textComponent.setDisabled(true); + } + } + } diff --git a/src/org/wanxp/douban/data/handler/DoubanAbstractLoadHandler.ts b/src/org/wanxp/douban/data/handler/DoubanAbstractLoadHandler.ts index f946953..7dc8bc7 100644 --- a/src/org/wanxp/douban/data/handler/DoubanAbstractLoadHandler.ts +++ b/src/org/wanxp/douban/data/handler/DoubanAbstractLoadHandler.ts @@ -68,6 +68,9 @@ export default abstract class DoubanAbstractLoadHandler } private getFileName(context: HandleContext): string { + if (context.dataFileNamePath) { + return context.dataFileNamePath; + } const {dataFileNamePath} = context.settings; return dataFileNamePath ? dataFileNamePath : DEFAULT_SETTINGS.dataFileNamePath; } diff --git a/src/org/wanxp/douban/data/model/HandleContext.ts b/src/org/wanxp/douban/data/model/HandleContext.ts index c1e5f12..22950f3 100644 --- a/src/org/wanxp/douban/data/model/HandleContext.ts +++ b/src/org/wanxp/douban/data/model/HandleContext.ts @@ -16,5 +16,6 @@ export default interface HandleContext { showAfterCreate?:boolean; syncStatusHolder?:SyncStatusHolder; action:string; - outputFolder:string; + outputFolder?:string; + dataFileNamePath?:string; } diff --git a/src/org/wanxp/douban/model/GlobalStatusHolder.ts b/src/org/wanxp/douban/model/GlobalStatusHolder.ts index ec99c06..b1f915d 100644 --- a/src/org/wanxp/douban/model/GlobalStatusHolder.ts +++ b/src/org/wanxp/douban/model/GlobalStatusHolder.ts @@ -7,27 +7,32 @@ import {DoubanSubjectState} from "../../constant/DoubanUserState"; export default class GlobalStatusHolder { public syncStatus:GlobalSyncStatusHolder; + public syncStarted:boolean; + public syncStartTime:number; public completeSync() { - this.syncStatus = null; + this.syncStarted = false; } public startSync(syncConfigOut: SyncConfig):boolean { - if (this.syncStatus) { + if (this.syncStarted) { const {syncConfig} = this.syncStatus; // @ts-ignore new Notice(i18nHelper.getMessage('110008'), SyncTypeRecords[syncConfig.syncType], DoubanSubjectState[syncConfig.scope]); return false; } this.syncStatus = new GlobalSyncStatusHolder(syncConfigOut); + this.syncStarted = true; + this.syncStartTime = new Date().getTime(); return true; } public stopSync() { - this.syncStatus = null; + this.syncStarted = false; + } public syncing() { - return this.syncStatus; + return this.syncStarted; } } diff --git a/src/org/wanxp/douban/sync/model/GlobalSyncStatusHolder.ts b/src/org/wanxp/douban/sync/model/GlobalSyncStatusHolder.ts index 257181b..7c59caf 100644 --- a/src/org/wanxp/douban/sync/model/GlobalSyncStatusHolder.ts +++ b/src/org/wanxp/douban/sync/model/GlobalSyncStatusHolder.ts @@ -5,13 +5,11 @@ export default class GlobalSyncStatusHolder { public syncConfig: SyncConfig; private total:number; private handle:number; - private startTime:number; constructor(syncConfig: SyncConfig) { this.syncConfig = syncConfig; - this.startTime = new Date().getTime(); - this.total = 0; - this.handle = 0; + this.total = 100; + this.handle = 1; } handled(num:number) { diff --git a/src/org/wanxp/douban/sync/model/SyncConfig.ts b/src/org/wanxp/douban/sync/model/SyncConfig.ts index 105d0ca..3de1c38 100644 --- a/src/org/wanxp/douban/sync/model/SyncConfig.ts +++ b/src/org/wanxp/douban/sync/model/SyncConfig.ts @@ -3,4 +3,5 @@ export interface SyncConfig { scope: string, force:boolean, outputFolder:string; + dataFileNamePath:string; } diff --git a/src/org/wanxp/lang/locale/en.ts b/src/org/wanxp/lang/locale/en.ts index b8c1a4e..0e5a24e 100644 --- a/src/org/wanxp/lang/locale/en.ts +++ b/src/org/wanxp/lang/locale/en.ts @@ -20,6 +20,8 @@ export default { '110032': `Scope:`, '110033': `Progress:`, '110034': `OutputFolder:`, + '110035': `FileName: (Tip:Support Variables And Path)`, + '110036': `Complete`, @@ -183,7 +185,7 @@ export default { '140207': `[OB-Douban]: [{0}/{1}] {2}`, '140208': `[OB-Douban]: [{0}/{1}] {2}`, - '140301': `Douban: Syncing...`, + '140301': `Douban: Syncing[{0}]...`, '140303': `Douban: User Info Expire, Please login again`, '140302': `Douban: Sync complete`, diff --git a/src/org/wanxp/lang/locale/zh-cn.ts b/src/org/wanxp/lang/locale/zh-cn.ts index 2c725a8..d8bcac7 100644 --- a/src/org/wanxp/lang/locale/zh-cn.ts +++ b/src/org/wanxp/lang/locale/zh-cn.ts @@ -20,6 +20,8 @@ export default { '110032': `范围:`, '110033': `进度:`, '110034': `输出文件夹:`, + '110035': `文档名: (提示:支持参数化以及多级路径, 可用参数见配置界面)`, + '110036': `完成`, '110201': `{0} 文件已经存在.`, @@ -189,7 +191,7 @@ export default { '140208': `[OB-Douban]: [{0}/{1}] {2}`, - '140301': `Douban: 开始同步...`, + '140301': `Douban: 开始同步[{0}]...`, '140302': `Douban: 同步完成`, '140303': `Douban: 用户信息已过期,请至插件中重新登录`, diff --git a/src/org/wanxp/main.ts b/src/org/wanxp/main.ts index 9ce96e6..ad883c9 100644 --- a/src/org/wanxp/main.ts +++ b/src/org/wanxp/main.ts @@ -8,7 +8,7 @@ import DoubanSubject from "./douban/data/model/DoubanSubject"; import Searcher from "./douban/data/search/Search"; import {i18nHelper} from './lang/helper'; import {log} from "src/org/wanxp/utils/Logutil"; -import {Action, BasicConst, SearchHandleMode} from "./constant/Constsant"; +import {Action, BasicConst, SearchHandleMode, SyncTypeRecords} from "./constant/Constsant"; import FileHandler from "./file/FileHandler"; import HandleContext from "./douban/data/model/HandleContext"; import HandleResult from "./douban/data/model/HandleResult"; @@ -83,24 +83,28 @@ export default class DoubanPlugin extends Plugin { async createFile(context: HandleContext, result: HandleResult) { let filePath = this.settings.dataFilePath; + if (context.outputFolder) { + filePath = context.outputFolder; + } filePath = filePath?filePath:DEFAULT_SETTINGS.dataFilePath; filePath = FileUtil.join(filePath, result.fileName); const {syncStatusHolder} = context; const {subject} = result; + const {content} = result; if (Action.Sync == context.action) { if (context.syncStatusHolder.syncConfig.force) { - const exists:boolean = await this.fileHandler.createOrReplaceNewNoteWithData(filePath, result.content, context.showAfterCreate); + const exists:boolean = await this.fileHandler.createOrReplaceNewNoteWithData(filePath, content, context.showAfterCreate); if (exists) { syncStatusHolder != null ? syncStatusHolder.replace(subject.id, subject.title):null; }else { syncStatusHolder != null ?syncStatusHolder.create(subject.id, subject.title):null; } }else { - await this.fileHandler.createNewNoteWithData(filePath, result.content, context.showAfterCreate); + await this.fileHandler.createNewNoteWithData(filePath, content, context.showAfterCreate); syncStatusHolder != null ?syncStatusHolder.create(subject.id, subject.title):null; } }else { - await this.fileHandler.createNewNoteWithData(filePath, result.content, context.showAfterCreate); + await this.fileHandler.createNewNoteWithData(filePath, content, context.showAfterCreate); syncStatusHolder != null ?syncStatusHolder.create(subject.id, subject.title):null; } } @@ -243,15 +247,23 @@ export default class DoubanPlugin extends Plugin { if (!result) { return; } - + if (syncConfig.dataFileNamePath) { + context.dataFileNamePath = syncConfig.dataFileNamePath; + } + if (syncConfig.outputFolder) { + context.outputFolder = syncConfig.outputFolder; + } context.syncStatusHolder = new SyncStatusHolder(syncConfig, this.statusHolder); - new Notice(i18nHelper.getMessage('140301')); - this.showStatus(i18nHelper.getMessage('140203', syncConfig.syncType)); + // @ts-ignore + new Notice(i18nHelper.getMessage('140301', SyncTypeRecords[syncConfig.syncType])); + + // @ts-ignore + this.showStatus(i18nHelper.getMessage('140203', SyncTypeRecords[syncConfig.syncType])); const syncHandler = new SyncHandler(this.app, this, syncConfig, context); await syncHandler.sync(); new Notice(i18nHelper.getMessage('140302')); } catch (e) { - log.error(i18nHelper.getMessage('140206').replace('{0}', e.message), e); + log.error(i18nHelper.getMessage('140206', e.message), e); } finally { context.plugin.statusHolder.completeSync(); this.clearStatusBarDelay(); diff --git a/styles.css b/styles.css index 6a9f901..4844131 100644 --- a/styles.css +++ b/styles.css @@ -50,6 +50,13 @@ .obsidian_douban_sync_config{ display: inline-block; + margin-left: 5px; + margin-bottom: 10px; + width: 90%; +} + +.obsidian_douban_sync_selections{ + width: 40px; }