From 0a39541b025d845b0840543b8ec1c07178263db0 Mon Sep 17 00:00:00 2001 From: wanxp <977741432@qq.com> Date: Sat, 19 Nov 2022 15:03:33 +0800 Subject: [PATCH] add function: sync user movie info --- main.ts | 53 +++++++- src/constant/Constsant.ts | 23 +++- src/constant/Douban.ts | 3 + src/constant/DoubanUserState.ts | 106 ++++++++++------ src/douban/component/DoubanLoginModel.ts | 2 +- src/douban/component/DoubanSearchModal.ts | 57 --------- src/douban/component/DoubanSyncModal.ts | 119 ++++++++++++++++++ .../data/handler/DoubanAbstractLoadHandler.ts | 38 +++--- src/douban/data/model/HandleContext.ts | 1 + src/douban/data/model/SubjectListItem.ts | 4 + .../sync/handler/DoubanAbstractSyncHandler.ts | 26 ++++ .../sync/handler/DoubanBookSyncHandler.ts | 19 +++ .../handler/DoubanBroadcastAbstractHandler.ts | 12 -- .../handler/DoubanBroadcastMovieHandler.ts | 16 --- .../handler/DoubanBroadcastSyncHandler.ts | 25 ++++ .../sync/handler/DoubanMovieSyncHandler.ts | 59 +++++++++ .../sync/handler/DoubanMusicSyncHandler.ts | 26 ++++ .../sync/handler/DoubanNoteSyncHandler.ts | 26 ++++ .../sync/handler/DoubanOtherSyncHandler.ts | 28 +++++ .../handler/DoubanPageBroadcastTransformer.ts | 32 ----- src/douban/sync/handler/DoubanSyncHandler.ts | 14 +++ src/douban/sync/handler/SyncHandler.ts | 58 +++++++++ .../handler/list/DoubanAbstractListHandler.ts | 87 +++++++++++++ .../sync/handler/list/DoubanListHandler.ts | 10 ++ .../list/DoubanMovieCollectListHandler.ts | 10 ++ .../handler/list/DoubanMovieDoListHandler.ts | 10 ++ .../handler/list/DoubanMovieListHandler.ts | 13 ++ .../list/DoubanMovieWishListHandler.ts | 10 ++ .../sync/model/DoubanBroadcastMoveSubject.ts | 4 +- .../sync/model/DoubanBroadcastSubject1.ts | 12 ++ ...oadcastSubject.ts => DoubanSyncSubject.ts} | 2 +- src/douban/sync/model/SyncConfig.ts | 5 + src/douban/user/UserComponent.ts | 4 + src/file/FileHandler.ts | 8 +- src/lang/locale/en.ts | 71 ++++++----- src/lang/locale/zh-cn.ts | 17 ++- src/utils/NumberUtil.ts | 12 ++ src/utils/TimeUtil.ts | 13 ++ 38 files changed, 817 insertions(+), 218 deletions(-) delete mode 100644 src/douban/component/DoubanSearchModal.ts create mode 100644 src/douban/component/DoubanSyncModal.ts create mode 100644 src/douban/data/model/SubjectListItem.ts create mode 100644 src/douban/sync/handler/DoubanAbstractSyncHandler.ts create mode 100644 src/douban/sync/handler/DoubanBookSyncHandler.ts delete mode 100644 src/douban/sync/handler/DoubanBroadcastAbstractHandler.ts delete mode 100644 src/douban/sync/handler/DoubanBroadcastMovieHandler.ts create mode 100644 src/douban/sync/handler/DoubanBroadcastSyncHandler.ts create mode 100644 src/douban/sync/handler/DoubanMovieSyncHandler.ts create mode 100644 src/douban/sync/handler/DoubanMusicSyncHandler.ts create mode 100644 src/douban/sync/handler/DoubanNoteSyncHandler.ts create mode 100644 src/douban/sync/handler/DoubanOtherSyncHandler.ts delete mode 100644 src/douban/sync/handler/DoubanPageBroadcastTransformer.ts create mode 100644 src/douban/sync/handler/DoubanSyncHandler.ts create mode 100644 src/douban/sync/handler/SyncHandler.ts create mode 100644 src/douban/sync/handler/list/DoubanAbstractListHandler.ts create mode 100644 src/douban/sync/handler/list/DoubanListHandler.ts create mode 100644 src/douban/sync/handler/list/DoubanMovieCollectListHandler.ts create mode 100644 src/douban/sync/handler/list/DoubanMovieDoListHandler.ts create mode 100644 src/douban/sync/handler/list/DoubanMovieListHandler.ts create mode 100644 src/douban/sync/handler/list/DoubanMovieWishListHandler.ts create mode 100644 src/douban/sync/model/DoubanBroadcastSubject1.ts rename src/douban/sync/model/{DoubanBroadcastSubject.ts => DoubanSyncSubject.ts} (78%) create mode 100644 src/douban/sync/model/SyncConfig.ts create mode 100644 src/utils/NumberUtil.ts create mode 100644 src/utils/TimeUtil.ts diff --git a/main.ts b/main.ts index 503647a..2c9de5e 100644 --- a/main.ts +++ b/main.ts @@ -1,4 +1,4 @@ -import {Editor, Plugin} from "obsidian"; +import {Editor, Notice, Plugin} from "obsidian"; import {DoubanFuzzySuggester} from "src/douban/data/search/DoubanSearchFuzzySuggestModal"; import {DoubanSearchChooseItemHandler} from "src/douban/data/handler/DoubanSearchChooseItemHandler"; @@ -18,6 +18,9 @@ import {DEFAULT_SETTINGS} from "./src/constant/DefaultSettings"; import UserComponent from "@App/user/UserComponent"; import SettingsManager from "@App/setting/SettingsManager"; import NetFileHandler from "./src/net/NetFileHandler"; +import {DoubanSyncModal} from "@App/component/DoubanSyncModal"; +import SyncHandler from "@App/sync/handler/SyncHandler"; +import {SyncConfig} from "@App/sync/model/SyncConfig"; export default class DoubanPlugin extends Plugin { public settings: DoubanPluginSetting; @@ -69,7 +72,7 @@ export default class DoubanPlugin extends Plugin { let filePath = this.settings.dataFilePath; filePath = filePath?filePath:DEFAULT_SETTINGS.dataFilePath; filePath = FileUtil.join(filePath, result.fileName); - this.fileHandler.createNewNoteWithData(filePath, result.content); + this.fileHandler.createNewNoteWithData(filePath, result.content, context.showAfterCreate); } async search(searchTerm: string, context: HandleContext) { @@ -103,6 +106,10 @@ export default class DoubanPlugin extends Plugin { new DoubanSearchModal(this.app, this, context).open(); } + async showSyncModal(context: HandleContext) { + new DoubanSyncModal(this.app, this, context).open(); + } + async onload() { await this.loadSettings(); if (this.settings.statusBar) { @@ -116,7 +123,8 @@ export default class DoubanPlugin extends Plugin { this.getDoubanTextForCreateNewNote({mode: SearchHandleMode.FOR_CREATE, settings: this.settings, userComponent: this.userComponent, - netFileHandler: this.netFileHandler}), + netFileHandler: this.netFileHandler, + showAfterCreate:true}), }); this.addCommand({ @@ -141,6 +149,16 @@ export default class DoubanPlugin extends Plugin { netFileHandler: this.netFileHandler}), }); + this.addCommand({ + id: "sync-douban-import-and-create-file", + name: i18nHelper.getMessage("110103"), + callback: () => + this.showSyncModal({mode: SearchHandleMode.FOR_CREATE, + settings: this.settings, + userComponent: this.userComponent, + netFileHandler: this.netFileHandler}), + }); + this.settingsManager = new SettingsManager(app, this); this.userComponent = new UserComponent(this.settingsManager); this.netFileHandler = new NetFileHandler(this.fileHandler); @@ -180,5 +198,34 @@ export default class DoubanPlugin extends Plugin { } setTimeout(() => this.doubanStatusBar.empty(), BasicConst.CLEAN_STATUS_BAR_DELAY) } + + async sync(syncConfig: SyncConfig, context: HandleContext) { + try { + const result:boolean = await this.checkLogin(context); + if (!result) { + return; + } + new Notice(i18nHelper.getMessage('140301')); + this.showStatus('140203', 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); + } finally { + this.clearStatusBarDelay(); + } + } + + private async checkLogin(context: HandleContext):Promise { + if (!context.userComponent.needLogin()) { + await context.userComponent.loginByCookie(); + } + if (!context.userComponent.isLogin()) { + new Notice(i18nHelper.getMessage('140303')); + return false; + } + return true; + } } diff --git a/src/constant/Constsant.ts b/src/constant/Constsant.ts index 7fba01b..6b0443a 100644 --- a/src/constant/Constsant.ts +++ b/src/constant/Constsant.ts @@ -6,6 +6,8 @@ import {i18nHelper} from "../lang/helper"; export const BasicConst = { YAML_FRONT_MATTER_SYMBOL: '---', CLEAN_STATUS_BAR_DELAY: 5000, + CLEAN_STATUS_BAR_DELAY_RANGE: 2000, + } /** @@ -72,10 +74,25 @@ export const PersonNameModeRecords: { [key in PersonNameMode]: string } = { } export enum SyncType { - MY_MOVIE= 'MY_MOVIE', - MY_BOOK= 'MY_BOOK', - BROADCAST= 'BROADCAST', + movie= 'movie', + book= 'book', + broadcast= 'broadcast', + note= 'note', + music= 'music', +} + +/** + * 同步模式选项 + */ +export const SyncTypeRecords: { [key in SyncType]: string } = { + [SyncType.movie]: i18nHelper.getMessage('504103'), + [SyncType.book]: i18nHelper.getMessage('504102'), + [SyncType.broadcast]: i18nHelper.getMessage('504104'), + [SyncType.note]: i18nHelper.getMessage('504105'), + [SyncType.music]: i18nHelper.getMessage('504105'), } +export const PAGE_SIZE:number = 15; + diff --git a/src/constant/Douban.ts b/src/constant/Douban.ts index d637f14..a2df574 100644 --- a/src/constant/Douban.ts +++ b/src/constant/Douban.ts @@ -7,3 +7,6 @@ export const doubanHeaders = { }; +export const doubanSubjectSyncListUrl = function(subjectType:string, userId:string, doType:string, start:number):string { + return `https://${subjectType}.douban.com/people/${userId}/${doType}?start=${start}&sort=time&rating=all&filter=all&mode=list`; +} diff --git a/src/constant/DoubanUserState.ts b/src/constant/DoubanUserState.ts index e78dd3d..aec5da6 100644 --- a/src/constant/DoubanUserState.ts +++ b/src/constant/DoubanUserState.ts @@ -2,68 +2,60 @@ import {i18nHelper} from "../lang/helper"; import {SupportType} from "./Constsant"; export enum DoubanSubjectState { - HAVE_NOT = 'HAVE_NOT', - WANTED = 'WANTED', - DOING = 'DOING', - DONE = 'DONE', - UNKNOWN = 'UNKNOWN', + not = 'not', + wish = 'wish', + do = 'do', + collect = 'collect', } export const DoubanSubjectStateRecords_ALL: { [key in DoubanSubjectState]: string } = { - [DoubanSubjectState.HAVE_NOT]: i18nHelper.getMessage('500101'), - [DoubanSubjectState.WANTED]: i18nHelper.getMessage('500102'), - [DoubanSubjectState.DOING]: i18nHelper.getMessage('500103'), - [DoubanSubjectState.DONE]: i18nHelper.getMessage('500104'), - [DoubanSubjectState.UNKNOWN]: i18nHelper.getMessage('500000'), + [DoubanSubjectState.not]: i18nHelper.getMessage('500101'), + [DoubanSubjectState.wish]: i18nHelper.getMessage('500102'), + [DoubanSubjectState.do]: i18nHelper.getMessage('500103'), + [DoubanSubjectState.collect]: i18nHelper.getMessage('500104'), } export const DoubanSubjectStateRecords_MOVIE: { [key in DoubanSubjectState]: string } = { - [DoubanSubjectState.HAVE_NOT]: i18nHelper.getMessage('500201'), - [DoubanSubjectState.WANTED]: i18nHelper.getMessage('500202'), - [DoubanSubjectState.DOING]: i18nHelper.getMessage('500203'), - [DoubanSubjectState.DONE]: i18nHelper.getMessage('500204'), - [DoubanSubjectState.UNKNOWN]: i18nHelper.getMessage('500000'), + [DoubanSubjectState.not]: i18nHelper.getMessage('500201'), + [DoubanSubjectState.wish]: i18nHelper.getMessage('500202'), + [DoubanSubjectState.do]: i18nHelper.getMessage('500203'), + [DoubanSubjectState.collect]: i18nHelper.getMessage('500204'), } export const DoubanSubjectStateRecords_BOOK: { [key in DoubanSubjectState]: string } = { - [DoubanSubjectState.HAVE_NOT]: i18nHelper.getMessage('500301'), - [DoubanSubjectState.WANTED]: i18nHelper.getMessage('500302'), - [DoubanSubjectState.DOING]: i18nHelper.getMessage('500303'), - [DoubanSubjectState.DONE]: i18nHelper.getMessage('500304'), - [DoubanSubjectState.UNKNOWN]: i18nHelper.getMessage('500000'), + [DoubanSubjectState.not]: i18nHelper.getMessage('500301'), + [DoubanSubjectState.wish]: i18nHelper.getMessage('500302'), + [DoubanSubjectState.do]: i18nHelper.getMessage('500303'), + [DoubanSubjectState.collect]: i18nHelper.getMessage('500304'), } export const DoubanSubjectStateRecords_MUSIC: { [key in DoubanSubjectState]: string } = { - [DoubanSubjectState.HAVE_NOT]: i18nHelper.getMessage('500401'), - [DoubanSubjectState.WANTED]: i18nHelper.getMessage('500402'), - [DoubanSubjectState.DOING]: i18nHelper.getMessage('500403'), - [DoubanSubjectState.DONE]: i18nHelper.getMessage('500404'), - [DoubanSubjectState.UNKNOWN]: i18nHelper.getMessage('500000'), + [DoubanSubjectState.not]: i18nHelper.getMessage('500401'), + [DoubanSubjectState.wish]: i18nHelper.getMessage('500402'), + [DoubanSubjectState.do]: i18nHelper.getMessage('500403'), + [DoubanSubjectState.collect]: i18nHelper.getMessage('500404'), } export const DoubanSubjectStateRecords_NOTE: { [key in DoubanSubjectState]: string } = { - [DoubanSubjectState.HAVE_NOT]: i18nHelper.getMessage('500501'), - [DoubanSubjectState.WANTED]: i18nHelper.getMessage('500502'), - [DoubanSubjectState.DOING]: i18nHelper.getMessage('500503'), - [DoubanSubjectState.DONE]: i18nHelper.getMessage('500504'), - [DoubanSubjectState.UNKNOWN]: i18nHelper.getMessage('500000'), + [DoubanSubjectState.not]: i18nHelper.getMessage('500501'), + [DoubanSubjectState.wish]: i18nHelper.getMessage('500502'), + [DoubanSubjectState.do]: i18nHelper.getMessage('500503'), + [DoubanSubjectState.collect]: i18nHelper.getMessage('500504'), } export const DoubanSubjectStateRecords_GAME: { [key in DoubanSubjectState]: string } = { - [DoubanSubjectState.HAVE_NOT]: i18nHelper.getMessage('500601'), - [DoubanSubjectState.WANTED]: i18nHelper.getMessage('500602'), - [DoubanSubjectState.DOING]: i18nHelper.getMessage('500603'), - [DoubanSubjectState.DONE]: i18nHelper.getMessage('500604'), - [DoubanSubjectState.UNKNOWN]: i18nHelper.getMessage('500000'), + [DoubanSubjectState.not]: i18nHelper.getMessage('500601'), + [DoubanSubjectState.wish]: i18nHelper.getMessage('500602'), + [DoubanSubjectState.do]: i18nHelper.getMessage('500603'), + [DoubanSubjectState.collect]: i18nHelper.getMessage('500604'), } export const DoubanSubjectStateRecords_TELEPLAY: { [key in DoubanSubjectState]: string } = { - [DoubanSubjectState.HAVE_NOT]: i18nHelper.getMessage('500701'), - [DoubanSubjectState.WANTED]: i18nHelper.getMessage('500702'), - [DoubanSubjectState.DOING]: i18nHelper.getMessage('500703'), - [DoubanSubjectState.DONE]: i18nHelper.getMessage('500704'), - [DoubanSubjectState.UNKNOWN]: i18nHelper.getMessage('500000'), + [DoubanSubjectState.not]: i18nHelper.getMessage('500701'), + [DoubanSubjectState.wish]: i18nHelper.getMessage('500702'), + [DoubanSubjectState.do]: i18nHelper.getMessage('500703'), + [DoubanSubjectState.collect]: i18nHelper.getMessage('500704'), } export const DoubanSubjectStateRecords: { [key in SupportType]: Record } = { @@ -76,3 +68,37 @@ export const DoubanSubjectStateRecords: { [key in SupportType]: Record { const cookies = details.requestHeaders['Cookie']; diff --git a/src/douban/component/DoubanSearchModal.ts b/src/douban/component/DoubanSearchModal.ts deleted file mode 100644 index 61d5b6f..0000000 --- a/src/douban/component/DoubanSearchModal.ts +++ /dev/null @@ -1,57 +0,0 @@ -import {App, DropdownComponent, Modal, TextComponent} from "obsidian"; - -import DoubanPlugin from "main"; -import {i18nHelper} from "src/lang/helper"; -import HandleContext from "@App/data/model/HandleContext"; - -export class DoubanSearchModal extends Modal { - searchTerm: string; - plugin: DoubanPlugin; - context: HandleContext - - constructor(app: App, plugin: DoubanPlugin, context: HandleContext) { - super(app); - this.plugin = plugin; - this.context = context; - } - - onOpen() { - let {contentEl} = this; - - contentEl.createEl("h3", {text: i18nHelper.getMessage('500001')}); - - const inputs = contentEl.createDiv("inputs"); - - // const syncTypeDropdown = new DropdownComponent(contentEl) - // .addOptions(); - - - - - const controls = contentEl.createDiv("controls"); - const searchButton = controls.createEl("button", { - text: i18nHelper.getMessage('110004'), - cls: "mod-cta", - attr: { - autofocus: true, - }, - }); - searchButton.addClass("obsidian_douban_search_button"); - - searchButton.addEventListener("click", this.close.bind(this)); - const cancelButton = controls.createEl("button", {text: i18nHelper.getMessage('110005')}); - cancelButton.addEventListener("click", this.close.bind(this)); - cancelButton.addClass("obsidian_douban_search_button"); - - } - - - async onClose() { - let {contentEl} = this; - contentEl.empty(); - if (this.searchTerm) { - await this.plugin.search(this.searchTerm, this.context); - } - } - -} diff --git a/src/douban/component/DoubanSyncModal.ts b/src/douban/component/DoubanSyncModal.ts new file mode 100644 index 0000000..f32c74b --- /dev/null +++ b/src/douban/component/DoubanSyncModal.ts @@ -0,0 +1,119 @@ +import { + App, + ButtonComponent, + DropdownComponent, + Modal, + SliderComponent, + TextComponent, + ToggleComponent +} from "obsidian"; + +import DoubanPlugin from "main"; +import {i18nHelper} from "src/lang/helper"; +import HandleContext from "@App/data/model/HandleContext"; +import {SyncType, SyncTypeRecords} from "../../constant/Constsant"; +import { + ALL, + DoubanSubjectStateRecords_BOOK_SYNC, DoubanSubjectStateRecords_BROADCAST_SYNC, + DoubanSubjectStateRecords_MOVIE_SYNC, DoubanSubjectStateRecords_NOTE_SYNC +} from "../../constant/DoubanUserState"; +import {SyncConfig} from "@App/sync/model/SyncConfig"; + +export class DoubanSyncModal extends Modal { + plugin: DoubanPlugin; + context: HandleContext + syncConfig: SyncConfig; + + constructor(app: App, plugin: DoubanPlugin, context: HandleContext) { + super(app); + this.plugin = plugin; + this.context = context; + } + + onOpen() { + let {contentEl} = this; + + contentEl.createEl("h3", {text: i18nHelper.getMessage('500001')}); + + + this.syncConfig = {syncType: 'movie', scope: 'collect', force: false}; + + const syncTypeDropdown = new DropdownComponent(contentEl); + const scopeSelections = contentEl.createDiv("scope-selection"); + + syncTypeDropdown.addOptions(SyncTypeRecords) + .setValue(SyncType.movie) + .onChange((value) => { + this.syncConfig.syncType = value; + this.openScopeDropdown(scopeSelections); + }); + + this.openScopeDropdown(scopeSelections); + + + + new ToggleComponent(contentEl) + .setTooltip(i18nHelper.getMessage('500110')) + .setValue(false) + .onChange((value) => { + this.syncConfig.force = value; + }); + + const controls = contentEl.createDiv("controls"); + // const syncButton = controls.createEl("button", { + // text: i18nHelper.getMessage('110007'), + // cls: "mod-cta", + // attr: { + // autofocus: true, + // }, + // }); + + const syncButton = new ButtonComponent(controls) + .setButtonText(i18nHelper.getMessage('110007')) + .onClick(async () => { + this.close(); + await this.plugin.sync(this.syncConfig, this.context); + }) + + const cancelButton = new ButtonComponent(controls) + .setButtonText(i18nHelper.getMessage('110005')) + .onClick(() => { + this.close(); + }); + cancelButton.setClass("obsidian_douban_search_button"); + syncButton.setClass("obsidian_douban_search_button"); + } + + + async onClose() { + let {contentEl} = this; + contentEl.empty(); + } + + private openScopeDropdown(contentEl:HTMLDivElement) { + switch (this.syncConfig.syncType) { + case SyncType.movie: + this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_MOVIE_SYNC); + break; + case SyncType.book: + this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_BOOK_SYNC); + break; + case SyncType.broadcast: + this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_BROADCAST_SYNC); + break; + case SyncType.note: + this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_NOTE_SYNC); + break; + } + } + + private showScopeDropdown(contentEl:HTMLDivElement, scopeSelections: Record) { + contentEl.empty(); + const syncScopeTypeDropdown = new DropdownComponent(contentEl) + .addOptions(scopeSelections) + .setValue(ALL) + .onChange((value) => { + this.syncConfig.scope = value; + }); + } +} diff --git a/src/douban/data/handler/DoubanAbstractLoadHandler.ts b/src/douban/data/handler/DoubanAbstractLoadHandler.ts index 1daa4c4..debc9b0 100644 --- a/src/douban/data/handler/DoubanAbstractLoadHandler.ts +++ b/src/douban/data/handler/DoubanAbstractLoadHandler.ts @@ -112,7 +112,7 @@ export default abstract class DoubanAbstractLoadHandler handleSpecialContent(value: any, textMode: TemplateTextMode = TemplateTextMode.NORMAL, context: HandleContext = null): string { let result; if (!value) { - return i18nHelper.getMessage('410101'); + return ''; } if (value instanceof Array) { result = this.handleContentArray(value, context, textMode); @@ -131,8 +131,8 @@ export default abstract class DoubanAbstractLoadHandler abstract support(extract: DoubanSubject): boolean; handle(url: string, context: HandleContext): void { - let headers = JSON.parse(this.doubanPlugin.settings.searchHeaders); - headers.Cookie = this.doubanPlugin.settings.loginCookiesContent; + let headers = JSON.parse(context.settings.searchHeaders); + headers.Cookie = context.settings.loginCookiesContent; const requestUrlParam: RequestUrlParam = { url: url, method: "GET", @@ -254,7 +254,7 @@ export default abstract class DoubanAbstractLoadHandler .replaceAll(DoubanUserParameter.MY_RATING, this.handleSpecialContent(userState.rate, textMode)) .replaceAll(DoubanUserParameter.MY_STATE, this.getUserStateName(userState.state)) .replaceAll(DoubanUserParameter.MY_COMMENT, this.handleSpecialContent(userState.comment, textMode)) - .replaceAll(DoubanUserParameter.MY_COLLECTION_DATE, moment(new Date()).format(context.settings.dateFormat)) + .replaceAll(DoubanUserParameter.MY_COLLECTION_DATE, moment(userState.collectionDate).format(context.settings.dateFormat)) } /** @@ -360,16 +360,16 @@ export default abstract class DoubanAbstractLoadHandler public static getUserState(stateWord:string):DoubanSubjectState { let state:DoubanSubjectState; if(!stateWord) { - return DoubanSubjectState.UNKNOWN; + return null; } if(stateWord.indexOf('想')>=0 ) { - state = DoubanSubjectState.WANTED; + state = DoubanSubjectState.wish; }else if(stateWord.indexOf('在')>=0) { - state = DoubanSubjectState.DOING; + state = DoubanSubjectState.do; }else if(stateWord.indexOf('过')>=0) { - state = DoubanSubjectState.DONE; + state = DoubanSubjectState.collect; }else { - state = DoubanSubjectState.HAVE_NOT; + state = DoubanSubjectState.not; } return state; @@ -377,20 +377,20 @@ export default abstract class DoubanAbstractLoadHandler private getUserStateName(state: DoubanSubjectState): string { if (!state) { - return DoubanSubjectStateRecords.ALL.UNKNOWN; + return ''; } let v = DoubanSubjectStateRecords[this.getSupportType()]; switch (state) { - case DoubanSubjectState.WANTED: - return v.WANTED; - case DoubanSubjectState.DOING: - return v.DOING; - case DoubanSubjectState.DONE: - return v.DONE; - case DoubanSubjectState.HAVE_NOT: - return v.HAVE_NOT; + case DoubanSubjectState.wish: + return v.wish; + case DoubanSubjectState.do: + return v.do; + case DoubanSubjectState.collect: + return v.collect; + case DoubanSubjectState.not: + return v.not; default: - return v.UNKNOWN; + return ''; } } diff --git a/src/douban/data/model/HandleContext.ts b/src/douban/data/model/HandleContext.ts index 4a446a8..38bc270 100644 --- a/src/douban/data/model/HandleContext.ts +++ b/src/douban/data/model/HandleContext.ts @@ -10,4 +10,5 @@ export default interface HandleContext { editor?:Editor; userComponent: UserComponent; netFileHandler: NetFileHandler; + showAfterCreate?:boolean; } diff --git a/src/douban/data/model/SubjectListItem.ts b/src/douban/data/model/SubjectListItem.ts new file mode 100644 index 0000000..797b990 --- /dev/null +++ b/src/douban/data/model/SubjectListItem.ts @@ -0,0 +1,4 @@ +export interface SubjectListItem { + id:string; + url:string; +} diff --git a/src/douban/sync/handler/DoubanAbstractSyncHandler.ts b/src/douban/sync/handler/DoubanAbstractSyncHandler.ts new file mode 100644 index 0000000..9ede30a --- /dev/null +++ b/src/douban/sync/handler/DoubanAbstractSyncHandler.ts @@ -0,0 +1,26 @@ +import {CheerioAPI} from "cheerio"; +import DoubanSyncSubject from "../model/DoubanSyncSubject"; +import DoubanPlugin from "../../../../main"; +import {SyncType} from "../../../constant/Constsant"; +import {DoubanSyncHandler} from "@App/sync/handler/DoubanSyncHandler"; +import { SyncConfig } from "../model/SyncConfig"; +import HandleContext from "@App/data/model/HandleContext"; + +export abstract class DoubanAbstractSyncHandler implements DoubanSyncHandler{ + + private plugin: DoubanPlugin; + + constructor(plugin: DoubanPlugin) { + this.plugin = plugin; + } + + support(t: string): boolean { + return this.getSyncType() == t; + } + + abstract sync(syncConfig: SyncConfig, context: HandleContext): Promise; + + abstract getSyncType(): SyncType; +} + + diff --git a/src/douban/sync/handler/DoubanBookSyncHandler.ts b/src/douban/sync/handler/DoubanBookSyncHandler.ts new file mode 100644 index 0000000..dbfd85b --- /dev/null +++ b/src/douban/sync/handler/DoubanBookSyncHandler.ts @@ -0,0 +1,19 @@ +import {CheerioAPI} from "cheerio"; +import {DoubanAbstractSyncHandler} from "./DoubanAbstractSyncHandler"; +import DoubanBroadcastMovieSubject from "../model/DoubanBroadcastMoveSubject"; +import DoubanPlugin from "../../../../main"; +import {SyncType} from "../../../constant/Constsant"; +import {SyncConfig} from "@App/sync/model/SyncConfig"; +import HandleContext from "@App/data/model/HandleContext"; + +//TODO will support in future version +export class DoubanBookSyncHandler extends DoubanAbstractSyncHandler { + getSyncType(): SyncType { + return SyncType.book; + } + + async sync(syncConfig: SyncConfig, context: HandleContext): Promise{ + return Promise.resolve(); + } + +} diff --git a/src/douban/sync/handler/DoubanBroadcastAbstractHandler.ts b/src/douban/sync/handler/DoubanBroadcastAbstractHandler.ts deleted file mode 100644 index 709f7ee..0000000 --- a/src/douban/sync/handler/DoubanBroadcastAbstractHandler.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {CheerioAPI} from "cheerio"; -import DoubanBroadcastSubject from "../model/DoubanBroadcastSubject"; - -export abstract class DoubanBroadcastAbstractHandler { - - abstract support(t: string): boolean; - - abstract transform(data: Element, source: CheerioAPI): T; - -} - - diff --git a/src/douban/sync/handler/DoubanBroadcastMovieHandler.ts b/src/douban/sync/handler/DoubanBroadcastMovieHandler.ts deleted file mode 100644 index 8634dc5..0000000 --- a/src/douban/sync/handler/DoubanBroadcastMovieHandler.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {CheerioAPI} from "cheerio"; -import {DoubanBroadcastAbstractHandler} from "./DoubanBroadcastAbstractHandler"; -import DoubanBroadcastMovieSubject from "../model/DoubanBroadcastMoveSubject"; - -//TODO will support in future version -export class DoubanBroadcastMovieHandler extends DoubanBroadcastAbstractHandler { - support(t: string): boolean { - throw new Error("Method not implemented."); - } - - transform(data: Element, source: CheerioAPI): DoubanBroadcastMovieSubject { - throw new Error("Method not implemented."); - } - - -} diff --git a/src/douban/sync/handler/DoubanBroadcastSyncHandler.ts b/src/douban/sync/handler/DoubanBroadcastSyncHandler.ts new file mode 100644 index 0000000..f9d9df1 --- /dev/null +++ b/src/douban/sync/handler/DoubanBroadcastSyncHandler.ts @@ -0,0 +1,25 @@ +import {CheerioAPI} from "cheerio"; +import {DoubanAbstractSyncHandler} from "./DoubanAbstractSyncHandler"; +import DoubanBroadcastMovieSubject from "../model/DoubanBroadcastMoveSubject"; +import DoubanPlugin from "../../../../main"; +import {SyncType} from "../../../constant/Constsant"; +import {SyncConfig} from "@App/sync/model/SyncConfig"; +import HandleContext from "@App/data/model/HandleContext"; + +//TODO will support in future version +export class DoubanBroadcastSyncHandler extends DoubanAbstractSyncHandler { + + getSyncType(): SyncType { + return SyncType.broadcast; + } + + support(t: string): boolean { + throw new Error("Method not implemented."); + } + + async sync(syncConfig: SyncConfig, context: HandleContext): Promise{ + return Promise.resolve(); + } + + +} diff --git a/src/douban/sync/handler/DoubanMovieSyncHandler.ts b/src/douban/sync/handler/DoubanMovieSyncHandler.ts new file mode 100644 index 0000000..4f8856a --- /dev/null +++ b/src/douban/sync/handler/DoubanMovieSyncHandler.ts @@ -0,0 +1,59 @@ +import {DoubanAbstractSyncHandler} from "./DoubanAbstractSyncHandler"; +import {SyncType} from "../../../constant/Constsant"; +import {SyncConfig} from "@App/sync/model/SyncConfig"; +import HandleContext from "@App/data/model/HandleContext"; +import DoubanSubjectLoadHandler from "@App/data/handler/DoubanSubjectLoadHandler"; +import DoubanMovieLoadHandler from "@App/data/handler/DoubanMovieLoadHandler"; +import DoubanMovieSubject from "@App/data/model/DoubanMovieSubject"; +import DoubanPlugin from "../../../../main"; +import {SubjectListItem} from "@App/data/model/SubjectListItem"; +import DoubanMovieCollectListHandler from "@App/sync/handler/list/DoubanMovieCollectListHandler"; +import {DoubanListHandler} from "@App/sync/handler/list/DoubanListHandler"; +import DoubanMovieWishListHandler from "./list/DoubanMovieWishListHandler"; +import DoubanMovieDoListHandler from "@App/sync/handler/list/DoubanMovieDoListHandler"; + +//TODO will support in future version +export class DoubanMovieSyncHandler extends DoubanAbstractSyncHandler { + + private doubanSubjectLoadHandler:DoubanSubjectLoadHandler; + private doubanListHandlers:DoubanListHandler[]; + + constructor(plugin:DoubanPlugin) { + super(plugin); + this.doubanSubjectLoadHandler = new DoubanMovieLoadHandler(plugin); + this.doubanListHandlers = [ + new DoubanMovieCollectListHandler(), + new DoubanMovieWishListHandler(), + new DoubanMovieDoListHandler(), + ] + } + + + + getSyncType(): SyncType { + return SyncType.movie; + } + + + + async sync(syncConfig: SyncConfig, context: HandleContext): Promise{ + Promise.resolve() + .then(() => this.getItems(syncConfig, context)) + .then(this.removeExists) + .then((items) => { + items.forEach(item => { + item.id + this.doubanSubjectLoadHandler.handle(item.url, context); + }) + }) + } + + + private async getItems(syncConfig:SyncConfig, context:HandleContext):Promise { + return this.doubanListHandlers.find((h) => h.support(syncConfig)).getAllPageList(context); + } + + private async removeExists(items:SubjectListItem[]):Promise { + return items; + } +} diff --git a/src/douban/sync/handler/DoubanMusicSyncHandler.ts b/src/douban/sync/handler/DoubanMusicSyncHandler.ts new file mode 100644 index 0000000..79821b3 --- /dev/null +++ b/src/douban/sync/handler/DoubanMusicSyncHandler.ts @@ -0,0 +1,26 @@ +import {CheerioAPI} from "cheerio"; +import {DoubanAbstractSyncHandler} from "./DoubanAbstractSyncHandler"; +import DoubanBroadcastMovieSubject from "../model/DoubanBroadcastMoveSubject"; +import DoubanPlugin from "../../../../main"; +import {SyncType} from "../../../constant/Constsant"; +import {SyncConfig} from "@App/sync/model/SyncConfig"; +import HandleContext from "@App/data/model/HandleContext"; + +//TODO will support in future version +export class DoubanMusicSyncHandler extends DoubanAbstractSyncHandler { + + getSyncType(): SyncType { + return SyncType.music; + } + + support(t: string): boolean { + throw new Error("Method not implemented."); + } + + async sync(syncConfig: SyncConfig, context: HandleContext): Promise{ + return Promise.resolve(); + } + + + +} diff --git a/src/douban/sync/handler/DoubanNoteSyncHandler.ts b/src/douban/sync/handler/DoubanNoteSyncHandler.ts new file mode 100644 index 0000000..758bc03 --- /dev/null +++ b/src/douban/sync/handler/DoubanNoteSyncHandler.ts @@ -0,0 +1,26 @@ +import {CheerioAPI} from "cheerio"; +import {DoubanAbstractSyncHandler} from "./DoubanAbstractSyncHandler"; +import DoubanBroadcastMovieSubject from "../model/DoubanBroadcastMoveSubject"; +import DoubanPlugin from "../../../../main"; +import {SyncType} from "../../../constant/Constsant"; +import {SyncConfig} from "@App/sync/model/SyncConfig"; +import HandleContext from "@App/data/model/HandleContext"; + +//TODO will support in future version +export class DoubanNoteSyncHandler extends DoubanAbstractSyncHandler { + + getSyncType(): SyncType { + return SyncType.note; + } + + support(t: string): boolean { + throw new Error("Method not implemented."); + } + + async sync(syncConfig: SyncConfig, context: HandleContext): Promise{ + return Promise.resolve(); + } + + + +} diff --git a/src/douban/sync/handler/DoubanOtherSyncHandler.ts b/src/douban/sync/handler/DoubanOtherSyncHandler.ts new file mode 100644 index 0000000..9ad4550 --- /dev/null +++ b/src/douban/sync/handler/DoubanOtherSyncHandler.ts @@ -0,0 +1,28 @@ +import {CheerioAPI} from "cheerio"; +import {DoubanAbstractSyncHandler} from "./DoubanAbstractSyncHandler"; +import DoubanBroadcastMovieSubject from "../model/DoubanBroadcastMoveSubject"; +import DoubanPlugin from "../../../../main"; +import {SyncType} from "../../../constant/Constsant"; +import {SyncConfig} from "@App/sync/model/SyncConfig"; +import HandleContext from "@App/data/model/HandleContext"; + +//TODO will support in future version +export class DoubanOtherSyncHandler extends DoubanAbstractSyncHandler { + + getSyncType(): SyncType { + throw new Error("暂不支持同步这类型的数据"); + } + + + + support(t: string): boolean { + throw new Error("Method not implemented."); + } + + async sync(syncConfig: SyncConfig, context: HandleContext): Promise{ + return Promise.resolve(); + } + + + +} diff --git a/src/douban/sync/handler/DoubanPageBroadcastTransformer.ts b/src/douban/sync/handler/DoubanPageBroadcastTransformer.ts deleted file mode 100644 index 07c423c..0000000 --- a/src/douban/sync/handler/DoubanPageBroadcastTransformer.ts +++ /dev/null @@ -1,32 +0,0 @@ -import {CheerioAPI} from "cheerio"; -import {DoubanBroadcastAbstractHandler} from "./DoubanBroadcastAbstractHandler"; -import {DoubanBroadcastMovieHandler} from "./DoubanBroadcastMovieHandler"; -import DoubanBroadcastSubject from "../model/DoubanBroadcastSubject"; -import DoubanPageBroadcastSubject from "../model/DoubanPageBroadcastSubject"; - -//TODO will support in future version -export class DoubanPageBroadcastTransformer { - - private handlers: DoubanBroadcastAbstractHandler[]; - - - constructor() { - this.handlers = [ - new DoubanBroadcastMovieHandler(), - ] - - } - - public transform(data: CheerioAPI): DoubanPageBroadcastSubject { - let doubanBroadcastSubjects: DoubanBroadcastSubject[] = data('.new-status .status-wrapper') - .get() - .map(i => this.transformElement(i, data)); - return new DoubanPageBroadcastSubject(); - } - - public transformElement(element: any, source: CheerioAPI): DoubanBroadcastSubject { - let targetType: string = element.innerHTML; - return this.handlers.filter(h => h.support(targetType))[0].transform(element, source); - } - -} diff --git a/src/douban/sync/handler/DoubanSyncHandler.ts b/src/douban/sync/handler/DoubanSyncHandler.ts new file mode 100644 index 0000000..655b396 --- /dev/null +++ b/src/douban/sync/handler/DoubanSyncHandler.ts @@ -0,0 +1,14 @@ +import {CheerioAPI} from "cheerio"; +import DoubanSyncSubject from "../model/DoubanSyncSubject"; +import {SyncConfig} from "@App/sync/model/SyncConfig"; +import HandleContext from "@App/data/model/HandleContext"; + +export interface DoubanSyncHandler { + + support(t: string): boolean; + + sync(syncConfig: SyncConfig, context: HandleContext):Promise ; + +} + + diff --git a/src/douban/sync/handler/SyncHandler.ts b/src/douban/sync/handler/SyncHandler.ts new file mode 100644 index 0000000..2dab80c --- /dev/null +++ b/src/douban/sync/handler/SyncHandler.ts @@ -0,0 +1,58 @@ +import HandleContext from "@App/data/model/HandleContext"; +import {SyncConfig} from "@App/sync/model/SyncConfig"; +import DoubanPlugin from "main"; +import {App} from "obsidian"; +import {DoubanSyncHandler} from "@App/sync/handler/DoubanSyncHandler"; +import DoubanOtherLoadHandler from "@App/data/handler/DoubanOtherLoadHandler"; +import DoubanMovieLoadHandler from "@App/data/handler/DoubanMovieLoadHandler"; +import DoubanBookLoadHandler from "@App/data/handler/DoubanBookLoadHandler"; +import {DoubanTeleplayLoadHandler} from "@App/data/handler/DoubanTeleplayLoadHandler"; +import DoubanMusicLoadHandler from "@App/data/handler/DoubanMusicLoadHandler"; +import DoubanNoteLoadHandler from "@App/data/handler/DoubanNoteLoadHandler"; +import DoubanGameLoadHandler from "@App/data/handler/DoubanGameLoadHandler"; +import { DoubanBroadcastSyncHandler } from "./DoubanBroadcastSyncHandler"; +import {DoubanOtherSyncHandler} from "@App/sync/handler/DoubanOtherSyncHandler"; +import { DoubanMovieSyncHandler } from "./DoubanMovieSyncHandler"; +import { DoubanNoteSyncHandler } from "./DoubanNoteSyncHandler"; +import { DoubanMusicSyncHandler } from "./DoubanMusicSyncHandler"; +import { DoubanBookSyncHandler } from "./DoubanBookSyncHandler"; +import DoubanSubjectLoadHandler from "@App/data/handler/DoubanSubjectLoadHandler"; +import DoubanSubject from "@App/data/model/DoubanSubject"; +import {DoubanAbstractSyncHandler} from "@App/sync/handler/DoubanAbstractSyncHandler"; + +export default class SyncHandler { + private app: App; + private plugin: DoubanPlugin; + private syncConfig: SyncConfig; + private context: HandleContext; + private syncHandlers: DoubanSyncHandler[]; + private defaultSyncHandler: DoubanSyncHandler; + + constructor(app: App, plugin: DoubanPlugin, syncConfig: SyncConfig, context: HandleContext) { + this.app = app; + this.plugin = plugin; + this.syncConfig = syncConfig; + this.context = context; + this.defaultSyncHandler = new DoubanOtherSyncHandler(plugin); + this.syncHandlers = + [ + new DoubanMovieSyncHandler(plugin), + new DoubanBookSyncHandler(plugin), + new DoubanBroadcastSyncHandler(plugin), + new DoubanNoteSyncHandler(plugin), + new DoubanMusicSyncHandler(plugin), + this.defaultSyncHandler + ]; + } + + async sync() { + if (this.syncConfig && this.syncConfig.syncType && this.syncConfig.scope) { + let syncHandler = this.syncHandlers.find(handler => handler.support(this.syncConfig.syncType)); + if (syncHandler) { + await syncHandler.sync(this.syncConfig, this.context); + } else { + await this.defaultSyncHandler.sync(this.syncConfig, this.context); + } + } + } +} diff --git a/src/douban/sync/handler/list/DoubanAbstractListHandler.ts b/src/douban/sync/handler/list/DoubanAbstractListHandler.ts new file mode 100644 index 0000000..76005d1 --- /dev/null +++ b/src/douban/sync/handler/list/DoubanAbstractListHandler.ts @@ -0,0 +1,87 @@ +import {moment, request, RequestUrlParam, TFile} from "obsidian"; +import {i18nHelper} from 'src/lang/helper'; +import {log} from "src/utils/Logutil"; +import {CheerioAPI, load} from "cheerio"; +import HandleContext from "@App/data/model/HandleContext"; +import {doubanSubjectSyncListUrl} from "../../../../constant/Douban"; +import {BasicConst, PAGE_SIZE} from "../../../../constant/Constsant"; +import DoubanSearchResultSubject from "@App/data/model/DoubanSearchResultSubject"; +import {SubjectListItem} from "@App/data/model/SubjectListItem"; +import {DoubanListHandler} from "@App/sync/handler/list/DoubanListHandler"; +import {SyncConfig} from "@App/sync/model/SyncConfig"; +import TimeUtil from "../../../../utils/TimeUtil"; + +export default abstract class DoubanAbstractListHandler implements DoubanListHandler{ + + async getAllPageList(context: HandleContext):Promise{ + let all:SubjectListItem[] = []; + let pages:SubjectListItem[] = []; + let start = 0; + do { + const url:string = this.getUrl(context, start); + pages = await TimeUtil.delayRange(() => this.getPageList(url, context), + BasicConst.CLEAN_STATUS_BAR_DELAY - BasicConst.CLEAN_STATUS_BAR_DELAY_RANGE, + BasicConst.CLEAN_STATUS_BAR_DELAY - BasicConst.CLEAN_STATUS_BAR_DELAY_RANGE); + if (pages) { + all = all.concat(pages); + } + start = start + PAGE_SIZE; + } while (pages) + return all; + } + + async delay(ms: number) { + } + + private getUrl(context: HandleContext, start:number) { + return doubanSubjectSyncListUrl(this.getSyncType(), context.userComponent.getUserId(), this.getDoType(), start); + } + + abstract getDoType():string; + + abstract getSyncType():string; + + async getPageList(url: string, context: HandleContext):Promise { + let headers = JSON.parse(context.settings.searchHeaders); + headers.Cookie = context.settings.loginCookiesContent; + const requestUrlParam: RequestUrlParam = { + url: url, + method: "GET", + headers: headers, + throw: true + }; + return request(requestUrlParam) + .then(load) + .then(data => this.parseSubjectFromHtml(data, context)) + .catch(e => log + .error( + i18nHelper.getMessage('130101') + .replace('{0}', e.toString()) + , e)); + ; + + } + + + + + + parseSubjectFromHtml(dataHtml: CheerioAPI, context: HandleContext):SubjectListItem[] { + return dataHtml('.item-show') + .get() + .map((i: any) => { + const item = dataHtml(i); + const linkValue:string = item.find('div.title > a').attr('href'); + let idPattern = /(\d){5,10}/g; + let ececResult = idPattern.exec(linkValue); + return ececResult?{id: ececResult[0], url: linkValue}:null; + // return linkValue; + }) + } + + support(config: SyncConfig): boolean { + return this.getDoType() == config.scope; + } +} + + diff --git a/src/douban/sync/handler/list/DoubanListHandler.ts b/src/douban/sync/handler/list/DoubanListHandler.ts new file mode 100644 index 0000000..e934244 --- /dev/null +++ b/src/douban/sync/handler/list/DoubanListHandler.ts @@ -0,0 +1,10 @@ +import HandleContext from "@App/data/model/HandleContext"; +import {SubjectListItem} from "@App/data/model/SubjectListItem"; +import {SyncConfig} from "@App/sync/model/SyncConfig"; + +export interface DoubanListHandler { + + getAllPageList(context: HandleContext):Promise; + + support(config:SyncConfig):boolean; +} diff --git a/src/douban/sync/handler/list/DoubanMovieCollectListHandler.ts b/src/douban/sync/handler/list/DoubanMovieCollectListHandler.ts new file mode 100644 index 0000000..8970acc --- /dev/null +++ b/src/douban/sync/handler/list/DoubanMovieCollectListHandler.ts @@ -0,0 +1,10 @@ +import { DoubanSubjectState} from "src/constant/DoubanUserState"; +import { DoubanMovieListHandler } from "./DoubanMovieListHandler"; + + +export default class DoubanMovieCollectListHandler extends DoubanMovieListHandler{ + getDoType(): string { + return DoubanSubjectState.collect; + } + +} diff --git a/src/douban/sync/handler/list/DoubanMovieDoListHandler.ts b/src/douban/sync/handler/list/DoubanMovieDoListHandler.ts new file mode 100644 index 0000000..b8fbc0a --- /dev/null +++ b/src/douban/sync/handler/list/DoubanMovieDoListHandler.ts @@ -0,0 +1,10 @@ +import { DoubanSubjectState} from "src/constant/DoubanUserState"; +import { DoubanMovieListHandler } from "./DoubanMovieListHandler"; + + +export default class DoubanMovieDoListHandler extends DoubanMovieListHandler{ + getDoType(): string { + return DoubanSubjectState.do; + } + +} diff --git a/src/douban/sync/handler/list/DoubanMovieListHandler.ts b/src/douban/sync/handler/list/DoubanMovieListHandler.ts new file mode 100644 index 0000000..b621eaa --- /dev/null +++ b/src/douban/sync/handler/list/DoubanMovieListHandler.ts @@ -0,0 +1,13 @@ +import DoubanAbstractListHandler from "@App/sync/handler/list/DoubanAbstractListHandler"; +import { SyncType} from "../../../../constant/Constsant"; + +export abstract class DoubanMovieListHandler extends DoubanAbstractListHandler { + getSyncType(): string { + return SyncType.movie; + } + + abstract getDoType(): string; + +} + + diff --git a/src/douban/sync/handler/list/DoubanMovieWishListHandler.ts b/src/douban/sync/handler/list/DoubanMovieWishListHandler.ts new file mode 100644 index 0000000..d5f9e34 --- /dev/null +++ b/src/douban/sync/handler/list/DoubanMovieWishListHandler.ts @@ -0,0 +1,10 @@ +import { DoubanSubjectState} from "src/constant/DoubanUserState"; +import { DoubanMovieListHandler } from "./DoubanMovieListHandler"; + + +export default class DoubanMovieWishListHandler extends DoubanMovieListHandler{ + getDoType(): string { + return DoubanSubjectState.wish; + } + +} diff --git a/src/douban/sync/model/DoubanBroadcastMoveSubject.ts b/src/douban/sync/model/DoubanBroadcastMoveSubject.ts index 6e2d5a2..4d52cc0 100644 --- a/src/douban/sync/model/DoubanBroadcastMoveSubject.ts +++ b/src/douban/sync/model/DoubanBroadcastMoveSubject.ts @@ -1,4 +1,4 @@ -import DoubanBroadcastSubject from "./DoubanBroadcastSubject"; +import DoubanSyncSubject from "./DoubanSyncSubject"; -export default class DoubanBroadcastMovieSubject extends DoubanBroadcastSubject { +export default class DoubanBroadcastMovieSubject extends DoubanSyncSubject { } diff --git a/src/douban/sync/model/DoubanBroadcastSubject1.ts b/src/douban/sync/model/DoubanBroadcastSubject1.ts new file mode 100644 index 0000000..7c1b94c --- /dev/null +++ b/src/douban/sync/model/DoubanBroadcastSubject1.ts @@ -0,0 +1,12 @@ +export default class DoubanBroadcastSubject1 { + id: string; + type: string; + title: string; + desc: string; + url: string; + author: string; + authorUrl: string; + timePublished: Date; + image: string; + content: string; +} diff --git a/src/douban/sync/model/DoubanBroadcastSubject.ts b/src/douban/sync/model/DoubanSyncSubject.ts similarity index 78% rename from src/douban/sync/model/DoubanBroadcastSubject.ts rename to src/douban/sync/model/DoubanSyncSubject.ts index ef1911a..40c014d 100644 --- a/src/douban/sync/model/DoubanBroadcastSubject.ts +++ b/src/douban/sync/model/DoubanSyncSubject.ts @@ -1,4 +1,4 @@ -export default class DoubanBroadcastSubject { +export default class DoubanSyncSubject { id: string; type: string; title: string; diff --git a/src/douban/sync/model/SyncConfig.ts b/src/douban/sync/model/SyncConfig.ts new file mode 100644 index 0000000..86b9e84 --- /dev/null +++ b/src/douban/sync/model/SyncConfig.ts @@ -0,0 +1,5 @@ +export interface SyncConfig { + syncType: string, + scope: string, + force:boolean, +} diff --git a/src/douban/user/UserComponent.ts b/src/douban/user/UserComponent.ts index 48d633b..d66829d 100644 --- a/src/douban/user/UserComponent.ts +++ b/src/douban/user/UserComponent.ts @@ -23,6 +23,10 @@ export default class UserComponent { return this.user; } + getUserId() { + return this.user?this.user.id:null; + } + isLogin() { return this.user && this.user.login; diff --git a/src/file/FileHandler.ts b/src/file/FileHandler.ts index 922bfe5..38a8ba6 100644 --- a/src/file/FileHandler.ts +++ b/src/file/FileHandler.ts @@ -112,7 +112,7 @@ export default class FileHandler { * A new markdown file will be created at the given file path (`input`) * in the specified parent folder (`this.folder`) */ - async createNewNoteWithData(originalFilePath: string, data:string): Promise { + async createNewNoteWithData(originalFilePath: string, data:string, showAfterCreate:boolean=false): Promise { const {vault} = this._app; const {adapter} = vault; const prependDirInput = FileUtil.join("", originalFilePath); @@ -131,8 +131,10 @@ export default class FileHandler { } const File = await vault.create(filePath, data); // Create the file and open it in the active leaf - const leaf = this._app.workspace.splitLeafOrActive(); - await leaf.openFile(File); + if (showAfterCreate) { + const leaf = this._app.workspace.splitLeafOrActive(); + await leaf.openFile(File); + } } catch (error) { log.error(error.toString(), error); } diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts index 0ae949a..2ce38fd 100644 --- a/src/lang/locale/en.ts +++ b/src/lang/locale/en.ts @@ -10,6 +10,8 @@ export default { '110101': 'search douban and create file', '110201': `{0} already exists`, '110202': `{0} template can not read`, + '110103': 'sync personal data from douban', + '110007': `Start Sync`, @@ -166,6 +168,9 @@ export default { '140204': `[Obsidian Douban]: replace '{0}'`, '140205': `[Obsidian Douban]: complete '{0}'`, '140206': `[Obsidian Douban]: occur error '{0}'`, + '140301': `Douban: Syncing...`, + '140303': `Douban: User Info Expire, Please login again`, + '140302': `Douban: Sync complete`, '150101': `Choose an item...`, @@ -361,40 +366,43 @@ export default { '500000': `UNKNOWN`, - '500101': `NOT`, - '500102': `WANTED`, - '500103': `DOING`, - '500104': `DONE`, + '500101': `not`, + '500102': `wish`, + '500103': `do`, + '500104': `collect`, - '500201': `NOT`, - '500202': `WANTED`, - '500203': `DOING`, - '500204': `DONE`, + '500201': `not`, + '500202': `wish`, + '500203': `do`, + '500204': `collect`, - '500301': `NOT`, - '500302': `WANTED`, - '500303': `DOING`, - '500304': `DONE`, + '500301': `not`, + '500302': `wish`, + '500303': `do`, + '500304': `collect`, - '500401': `NOT`, - '500402': `WANTED`, - '500403': `DOING`, - '500404': `DONE`, + '500401': `not`, + '500402': `wish`, + '500403': `do`, + '500404': `collect`, - '500501': `NOT`, - '500502': `WANTED`, - '500503': `DOING`, - '500504': `DONE`, + '500501': `not`, + '500502': `wish`, + '500503': `do`, + '500504': `collect`, - '500601': `NOT`, - '500602': `WANTED`, - '500603': `DOING`, - '500604': `DONE`, + '500601': `not`, + '500602': `wish`, + '500603': `do`, + '500604': `collect`, + + '500701': `not`, + '500702': `wish`, + '500703': `do`, + '500704': `collect`, + + '500004': `ALL`, - '500701': `NOT`, - '500702': `WANTED`, - '500703': `DOING`, - '500704': `DONE`, '160225': `You can use those variables in your template after login. `, '160226': `The tags that I tag for subject`, @@ -405,6 +413,13 @@ export default { '500001': `Sync Config`, + '504102': `My Book`, + '504103': `My Movie`, + '504104': `My Broadcast`, + '504105': `My Note`, + '504106': `My Music`, + + '500110': `Replace exists or not`, 'ALL': `all`, diff --git a/src/lang/locale/zh-cn.ts b/src/lang/locale/zh-cn.ts index 5df137b..0faadda 100644 --- a/src/lang/locale/zh-cn.ts +++ b/src/lang/locale/zh-cn.ts @@ -9,6 +9,9 @@ export default { '110005': `取消`, '110006': `同步豆瓣广播至Obsidian`, '110101': '搜索豆瓣并创建文档', + '110103': '同步豆瓣个人记录', + '110007': `开始同步`, + '110201': `{0} 文件已经存在.`, '110202': `{0} 模板文件无法读取`, @@ -170,6 +173,11 @@ export default { '140205': `[Obsidian Douban]: 处理完成'{0}'`, '140206': `[Obsidian Douban]: 出现错误'{0}'`, + + '140301': `Douban: 开始同步...`, + '140302': `Douban: 同步完成`, + '140303': `Douban: 用户信息已过期,请至插件中重新登录`, + '150101': `选择一项内容...`, '121902': `重置为默认值`, @@ -418,6 +426,10 @@ export default { '500703': `在看`, '500704': `看过`, + '500004': `所有`, + '500110': `强制更新所有, 如果未启用则只增量更新新增的部分`, + + '160225': `以下参数登录后方可在模板中使用, 使用时请用'{{}}'包裹, 举例: 参数myTags, 则使用时为{{myTags}}`, '160226': `我标记的标签`, @@ -427,7 +439,10 @@ export default { '160230': `我的评论/标记的日期`, '500001': `同步设置`, - + '504102': `我的书籍`, + '504103': `我的电影`, + '504104': `我的广播`, + '504105': `我的日记`, 'ALL': `全部类型`, 'MOVIE': `电影`, diff --git a/src/utils/NumberUtil.ts b/src/utils/NumberUtil.ts new file mode 100644 index 0000000..69d1eb6 --- /dev/null +++ b/src/utils/NumberUtil.ts @@ -0,0 +1,12 @@ +export default class NumberUtil { + /** + * 生成范围随机数 + * @Min 最小值 + * @Max 最大值 + */ + public static getRandomNum(min:number, max:number):number { + const range = max - min; + const rand = Math.random(); + return (min + Math.round(rand * range)); + } +} diff --git a/src/utils/TimeUtil.ts b/src/utils/TimeUtil.ts new file mode 100644 index 0000000..c2f8e5b --- /dev/null +++ b/src/utils/TimeUtil.ts @@ -0,0 +1,13 @@ +import NumberUtil from "./NumberUtil"; + +export default class TimeUtil { + public static async delay(callback: Function, ms: number):Promise { + return await new Promise(resolve => setTimeout(() => callback, ms)); + } + + public static async delayRange(callback: Function, msMin: number, msMax:number):Promise { + return await new Promise(resolve => setTimeout(() => callback, NumberUtil.getRandomNum(msMin, msMax))); + } + + +}