mirror of
https://github.com/Wanxp/obsidian-douban.git
synced 2026-04-04 16:48:44 +08:00
add function: sync user movie info
This commit is contained in:
parent
ba5b9f2550
commit
0a39541b02
53
main.ts
53
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 {DoubanFuzzySuggester} from "src/douban/data/search/DoubanSearchFuzzySuggestModal";
|
||||||
import {DoubanSearchChooseItemHandler} from "src/douban/data/handler/DoubanSearchChooseItemHandler";
|
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 UserComponent from "@App/user/UserComponent";
|
||||||
import SettingsManager from "@App/setting/SettingsManager";
|
import SettingsManager from "@App/setting/SettingsManager";
|
||||||
import NetFileHandler from "./src/net/NetFileHandler";
|
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 {
|
export default class DoubanPlugin extends Plugin {
|
||||||
public settings: DoubanPluginSetting;
|
public settings: DoubanPluginSetting;
|
||||||
@ -69,7 +72,7 @@ export default class DoubanPlugin extends Plugin {
|
|||||||
let filePath = this.settings.dataFilePath;
|
let filePath = this.settings.dataFilePath;
|
||||||
filePath = filePath?filePath:DEFAULT_SETTINGS.dataFilePath;
|
filePath = filePath?filePath:DEFAULT_SETTINGS.dataFilePath;
|
||||||
filePath = FileUtil.join(filePath, result.fileName);
|
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) {
|
async search(searchTerm: string, context: HandleContext) {
|
||||||
@ -103,6 +106,10 @@ export default class DoubanPlugin extends Plugin {
|
|||||||
new DoubanSearchModal(this.app, this, context).open();
|
new DoubanSearchModal(this.app, this, context).open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async showSyncModal(context: HandleContext) {
|
||||||
|
new DoubanSyncModal(this.app, this, context).open();
|
||||||
|
}
|
||||||
|
|
||||||
async onload() {
|
async onload() {
|
||||||
await this.loadSettings();
|
await this.loadSettings();
|
||||||
if (this.settings.statusBar) {
|
if (this.settings.statusBar) {
|
||||||
@ -116,7 +123,8 @@ export default class DoubanPlugin extends Plugin {
|
|||||||
this.getDoubanTextForCreateNewNote({mode: SearchHandleMode.FOR_CREATE,
|
this.getDoubanTextForCreateNewNote({mode: SearchHandleMode.FOR_CREATE,
|
||||||
settings: this.settings,
|
settings: this.settings,
|
||||||
userComponent: this.userComponent,
|
userComponent: this.userComponent,
|
||||||
netFileHandler: this.netFileHandler}),
|
netFileHandler: this.netFileHandler,
|
||||||
|
showAfterCreate:true}),
|
||||||
});
|
});
|
||||||
|
|
||||||
this.addCommand({
|
this.addCommand({
|
||||||
@ -141,6 +149,16 @@ export default class DoubanPlugin extends Plugin {
|
|||||||
netFileHandler: this.netFileHandler}),
|
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.settingsManager = new SettingsManager(app, this);
|
||||||
this.userComponent = new UserComponent(this.settingsManager);
|
this.userComponent = new UserComponent(this.settingsManager);
|
||||||
this.netFileHandler = new NetFileHandler(this.fileHandler);
|
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)
|
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<boolean> {
|
||||||
|
if (!context.userComponent.needLogin()) {
|
||||||
|
await context.userComponent.loginByCookie();
|
||||||
|
}
|
||||||
|
if (!context.userComponent.isLogin()) {
|
||||||
|
new Notice(i18nHelper.getMessage('140303'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,8 @@ import {i18nHelper} from "../lang/helper";
|
|||||||
export const BasicConst = {
|
export const BasicConst = {
|
||||||
YAML_FRONT_MATTER_SYMBOL: '---',
|
YAML_FRONT_MATTER_SYMBOL: '---',
|
||||||
CLEAN_STATUS_BAR_DELAY: 5000,
|
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 {
|
export enum SyncType {
|
||||||
MY_MOVIE= 'MY_MOVIE',
|
movie= 'movie',
|
||||||
MY_BOOK= 'MY_BOOK',
|
book= 'book',
|
||||||
BROADCAST= 'BROADCAST',
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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`;
|
||||||
|
}
|
||||||
|
|||||||
@ -2,68 +2,60 @@ import {i18nHelper} from "../lang/helper";
|
|||||||
import {SupportType} from "./Constsant";
|
import {SupportType} from "./Constsant";
|
||||||
|
|
||||||
export enum DoubanSubjectState {
|
export enum DoubanSubjectState {
|
||||||
HAVE_NOT = 'HAVE_NOT',
|
not = 'not',
|
||||||
WANTED = 'WANTED',
|
wish = 'wish',
|
||||||
DOING = 'DOING',
|
do = 'do',
|
||||||
DONE = 'DONE',
|
collect = 'collect',
|
||||||
UNKNOWN = 'UNKNOWN',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DoubanSubjectStateRecords_ALL: { [key in DoubanSubjectState]: string } = {
|
export const DoubanSubjectStateRecords_ALL: { [key in DoubanSubjectState]: string } = {
|
||||||
[DoubanSubjectState.HAVE_NOT]: i18nHelper.getMessage('500101'),
|
[DoubanSubjectState.not]: i18nHelper.getMessage('500101'),
|
||||||
[DoubanSubjectState.WANTED]: i18nHelper.getMessage('500102'),
|
[DoubanSubjectState.wish]: i18nHelper.getMessage('500102'),
|
||||||
[DoubanSubjectState.DOING]: i18nHelper.getMessage('500103'),
|
[DoubanSubjectState.do]: i18nHelper.getMessage('500103'),
|
||||||
[DoubanSubjectState.DONE]: i18nHelper.getMessage('500104'),
|
[DoubanSubjectState.collect]: i18nHelper.getMessage('500104'),
|
||||||
[DoubanSubjectState.UNKNOWN]: i18nHelper.getMessage('500000'),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DoubanSubjectStateRecords_MOVIE: { [key in DoubanSubjectState]: string } = {
|
export const DoubanSubjectStateRecords_MOVIE: { [key in DoubanSubjectState]: string } = {
|
||||||
[DoubanSubjectState.HAVE_NOT]: i18nHelper.getMessage('500201'),
|
[DoubanSubjectState.not]: i18nHelper.getMessage('500201'),
|
||||||
[DoubanSubjectState.WANTED]: i18nHelper.getMessage('500202'),
|
[DoubanSubjectState.wish]: i18nHelper.getMessage('500202'),
|
||||||
[DoubanSubjectState.DOING]: i18nHelper.getMessage('500203'),
|
[DoubanSubjectState.do]: i18nHelper.getMessage('500203'),
|
||||||
[DoubanSubjectState.DONE]: i18nHelper.getMessage('500204'),
|
[DoubanSubjectState.collect]: i18nHelper.getMessage('500204'),
|
||||||
[DoubanSubjectState.UNKNOWN]: i18nHelper.getMessage('500000'),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DoubanSubjectStateRecords_BOOK: { [key in DoubanSubjectState]: string } = {
|
export const DoubanSubjectStateRecords_BOOK: { [key in DoubanSubjectState]: string } = {
|
||||||
[DoubanSubjectState.HAVE_NOT]: i18nHelper.getMessage('500301'),
|
[DoubanSubjectState.not]: i18nHelper.getMessage('500301'),
|
||||||
[DoubanSubjectState.WANTED]: i18nHelper.getMessage('500302'),
|
[DoubanSubjectState.wish]: i18nHelper.getMessage('500302'),
|
||||||
[DoubanSubjectState.DOING]: i18nHelper.getMessage('500303'),
|
[DoubanSubjectState.do]: i18nHelper.getMessage('500303'),
|
||||||
[DoubanSubjectState.DONE]: i18nHelper.getMessage('500304'),
|
[DoubanSubjectState.collect]: i18nHelper.getMessage('500304'),
|
||||||
[DoubanSubjectState.UNKNOWN]: i18nHelper.getMessage('500000'),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const DoubanSubjectStateRecords_MUSIC: { [key in DoubanSubjectState]: string } = {
|
export const DoubanSubjectStateRecords_MUSIC: { [key in DoubanSubjectState]: string } = {
|
||||||
[DoubanSubjectState.HAVE_NOT]: i18nHelper.getMessage('500401'),
|
[DoubanSubjectState.not]: i18nHelper.getMessage('500401'),
|
||||||
[DoubanSubjectState.WANTED]: i18nHelper.getMessage('500402'),
|
[DoubanSubjectState.wish]: i18nHelper.getMessage('500402'),
|
||||||
[DoubanSubjectState.DOING]: i18nHelper.getMessage('500403'),
|
[DoubanSubjectState.do]: i18nHelper.getMessage('500403'),
|
||||||
[DoubanSubjectState.DONE]: i18nHelper.getMessage('500404'),
|
[DoubanSubjectState.collect]: i18nHelper.getMessage('500404'),
|
||||||
[DoubanSubjectState.UNKNOWN]: i18nHelper.getMessage('500000'),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DoubanSubjectStateRecords_NOTE: { [key in DoubanSubjectState]: string } = {
|
export const DoubanSubjectStateRecords_NOTE: { [key in DoubanSubjectState]: string } = {
|
||||||
[DoubanSubjectState.HAVE_NOT]: i18nHelper.getMessage('500501'),
|
[DoubanSubjectState.not]: i18nHelper.getMessage('500501'),
|
||||||
[DoubanSubjectState.WANTED]: i18nHelper.getMessage('500502'),
|
[DoubanSubjectState.wish]: i18nHelper.getMessage('500502'),
|
||||||
[DoubanSubjectState.DOING]: i18nHelper.getMessage('500503'),
|
[DoubanSubjectState.do]: i18nHelper.getMessage('500503'),
|
||||||
[DoubanSubjectState.DONE]: i18nHelper.getMessage('500504'),
|
[DoubanSubjectState.collect]: i18nHelper.getMessage('500504'),
|
||||||
[DoubanSubjectState.UNKNOWN]: i18nHelper.getMessage('500000'),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DoubanSubjectStateRecords_GAME: { [key in DoubanSubjectState]: string } = {
|
export const DoubanSubjectStateRecords_GAME: { [key in DoubanSubjectState]: string } = {
|
||||||
[DoubanSubjectState.HAVE_NOT]: i18nHelper.getMessage('500601'),
|
[DoubanSubjectState.not]: i18nHelper.getMessage('500601'),
|
||||||
[DoubanSubjectState.WANTED]: i18nHelper.getMessage('500602'),
|
[DoubanSubjectState.wish]: i18nHelper.getMessage('500602'),
|
||||||
[DoubanSubjectState.DOING]: i18nHelper.getMessage('500603'),
|
[DoubanSubjectState.do]: i18nHelper.getMessage('500603'),
|
||||||
[DoubanSubjectState.DONE]: i18nHelper.getMessage('500604'),
|
[DoubanSubjectState.collect]: i18nHelper.getMessage('500604'),
|
||||||
[DoubanSubjectState.UNKNOWN]: i18nHelper.getMessage('500000'),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DoubanSubjectStateRecords_TELEPLAY: { [key in DoubanSubjectState]: string } = {
|
export const DoubanSubjectStateRecords_TELEPLAY: { [key in DoubanSubjectState]: string } = {
|
||||||
[DoubanSubjectState.HAVE_NOT]: i18nHelper.getMessage('500701'),
|
[DoubanSubjectState.not]: i18nHelper.getMessage('500701'),
|
||||||
[DoubanSubjectState.WANTED]: i18nHelper.getMessage('500702'),
|
[DoubanSubjectState.wish]: i18nHelper.getMessage('500702'),
|
||||||
[DoubanSubjectState.DOING]: i18nHelper.getMessage('500703'),
|
[DoubanSubjectState.do]: i18nHelper.getMessage('500703'),
|
||||||
[DoubanSubjectState.DONE]: i18nHelper.getMessage('500704'),
|
[DoubanSubjectState.collect]: i18nHelper.getMessage('500704'),
|
||||||
[DoubanSubjectState.UNKNOWN]: i18nHelper.getMessage('500000'),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DoubanSubjectStateRecords: { [key in SupportType]: Record<DoubanSubjectState, string> } = {
|
export const DoubanSubjectStateRecords: { [key in SupportType]: Record<DoubanSubjectState, string> } = {
|
||||||
@ -76,3 +68,37 @@ export const DoubanSubjectStateRecords: { [key in SupportType]: Record<DoubanSub
|
|||||||
[SupportType.TELEPLAY]:DoubanSubjectStateRecords_TELEPLAY,
|
[SupportType.TELEPLAY]:DoubanSubjectStateRecords_TELEPLAY,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const ALL:string = 'ALL';
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
export const DoubanSubjectStateRecords_MOVIE_SYNC: { [key in DoubanSubjectState]: string } = {
|
||||||
|
// @ts-ignore
|
||||||
|
[ALL]: i18nHelper.getMessage('500004'),
|
||||||
|
[DoubanSubjectState.wish]: i18nHelper.getMessage('500202'),
|
||||||
|
[DoubanSubjectState.do]: i18nHelper.getMessage('500203'),
|
||||||
|
[DoubanSubjectState.collect]: i18nHelper.getMessage('500204'),
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
export const DoubanSubjectStateRecords_BOOK_SYNC: { [key in DoubanSubjectState]: string } = {
|
||||||
|
// @ts-ignore
|
||||||
|
[ALL]: i18nHelper.getMessage('500004'),
|
||||||
|
[DoubanSubjectState.wish]: i18nHelper.getMessage('500302'),
|
||||||
|
[DoubanSubjectState.do]: i18nHelper.getMessage('500303'),
|
||||||
|
[DoubanSubjectState.collect]: i18nHelper.getMessage('500304'),
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DoubanSubjectStateRecords_BROADCAST_SYNC: { [key :string]: string } = {
|
||||||
|
[ALL]: i18nHelper.getMessage('500004'),
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DoubanSubjectStateRecords_NOTE_SYNC: { [key :string]: string } = {
|
||||||
|
[ALL]: i18nHelper.getMessage('500004'),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -35,7 +35,7 @@ export default class DoubanLoginModel {
|
|||||||
|
|
||||||
const session = this.modal.webContents.session;
|
const session = this.modal.webContents.session;
|
||||||
const filter = {
|
const filter = {
|
||||||
urls: ['https://www.douban.com/']
|
urls: ['https://www.douban.com/','https://accounts.douban.com/']
|
||||||
};
|
};
|
||||||
session.webRequest.onSendHeaders(filter, async (details:any) => {
|
session.webRequest.onSendHeaders(filter, async (details:any) => {
|
||||||
const cookies = details.requestHeaders['Cookie'];
|
const cookies = details.requestHeaders['Cookie'];
|
||||||
|
|||||||
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
119
src/douban/component/DoubanSyncModal.ts
Normal file
119
src/douban/component/DoubanSyncModal.ts
Normal file
@ -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<string, string>) {
|
||||||
|
contentEl.empty();
|
||||||
|
const syncScopeTypeDropdown = new DropdownComponent(contentEl)
|
||||||
|
.addOptions(scopeSelections)
|
||||||
|
.setValue(ALL)
|
||||||
|
.onChange((value) => {
|
||||||
|
this.syncConfig.scope = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -112,7 +112,7 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
|
|||||||
handleSpecialContent(value: any, textMode: TemplateTextMode = TemplateTextMode.NORMAL, context: HandleContext = null): string {
|
handleSpecialContent(value: any, textMode: TemplateTextMode = TemplateTextMode.NORMAL, context: HandleContext = null): string {
|
||||||
let result;
|
let result;
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return i18nHelper.getMessage('410101');
|
return '';
|
||||||
}
|
}
|
||||||
if (value instanceof Array) {
|
if (value instanceof Array) {
|
||||||
result = this.handleContentArray(value, context, textMode);
|
result = this.handleContentArray(value, context, textMode);
|
||||||
@ -131,8 +131,8 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
|
|||||||
abstract support(extract: DoubanSubject): boolean;
|
abstract support(extract: DoubanSubject): boolean;
|
||||||
|
|
||||||
handle(url: string, context: HandleContext): void {
|
handle(url: string, context: HandleContext): void {
|
||||||
let headers = JSON.parse(this.doubanPlugin.settings.searchHeaders);
|
let headers = JSON.parse(context.settings.searchHeaders);
|
||||||
headers.Cookie = this.doubanPlugin.settings.loginCookiesContent;
|
headers.Cookie = context.settings.loginCookiesContent;
|
||||||
const requestUrlParam: RequestUrlParam = {
|
const requestUrlParam: RequestUrlParam = {
|
||||||
url: url,
|
url: url,
|
||||||
method: "GET",
|
method: "GET",
|
||||||
@ -254,7 +254,7 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
|
|||||||
.replaceAll(DoubanUserParameter.MY_RATING, this.handleSpecialContent(userState.rate, textMode))
|
.replaceAll(DoubanUserParameter.MY_RATING, this.handleSpecialContent(userState.rate, textMode))
|
||||||
.replaceAll(DoubanUserParameter.MY_STATE, this.getUserStateName(userState.state))
|
.replaceAll(DoubanUserParameter.MY_STATE, this.getUserStateName(userState.state))
|
||||||
.replaceAll(DoubanUserParameter.MY_COMMENT, this.handleSpecialContent(userState.comment, textMode))
|
.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<T extends DoubanSubject>
|
|||||||
public static getUserState(stateWord:string):DoubanSubjectState {
|
public static getUserState(stateWord:string):DoubanSubjectState {
|
||||||
let state:DoubanSubjectState;
|
let state:DoubanSubjectState;
|
||||||
if(!stateWord) {
|
if(!stateWord) {
|
||||||
return DoubanSubjectState.UNKNOWN;
|
return null;
|
||||||
}
|
}
|
||||||
if(stateWord.indexOf('想')>=0 ) {
|
if(stateWord.indexOf('想')>=0 ) {
|
||||||
state = DoubanSubjectState.WANTED;
|
state = DoubanSubjectState.wish;
|
||||||
}else if(stateWord.indexOf('在')>=0) {
|
}else if(stateWord.indexOf('在')>=0) {
|
||||||
state = DoubanSubjectState.DOING;
|
state = DoubanSubjectState.do;
|
||||||
}else if(stateWord.indexOf('过')>=0) {
|
}else if(stateWord.indexOf('过')>=0) {
|
||||||
state = DoubanSubjectState.DONE;
|
state = DoubanSubjectState.collect;
|
||||||
}else {
|
}else {
|
||||||
state = DoubanSubjectState.HAVE_NOT;
|
state = DoubanSubjectState.not;
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
|
|
||||||
@ -377,20 +377,20 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
|
|||||||
|
|
||||||
private getUserStateName(state: DoubanSubjectState): string {
|
private getUserStateName(state: DoubanSubjectState): string {
|
||||||
if (!state) {
|
if (!state) {
|
||||||
return DoubanSubjectStateRecords.ALL.UNKNOWN;
|
return '';
|
||||||
}
|
}
|
||||||
let v = DoubanSubjectStateRecords[this.getSupportType()];
|
let v = DoubanSubjectStateRecords[this.getSupportType()];
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case DoubanSubjectState.WANTED:
|
case DoubanSubjectState.wish:
|
||||||
return v.WANTED;
|
return v.wish;
|
||||||
case DoubanSubjectState.DOING:
|
case DoubanSubjectState.do:
|
||||||
return v.DOING;
|
return v.do;
|
||||||
case DoubanSubjectState.DONE:
|
case DoubanSubjectState.collect:
|
||||||
return v.DONE;
|
return v.collect;
|
||||||
case DoubanSubjectState.HAVE_NOT:
|
case DoubanSubjectState.not:
|
||||||
return v.HAVE_NOT;
|
return v.not;
|
||||||
default:
|
default:
|
||||||
return v.UNKNOWN;
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,4 +10,5 @@ export default interface HandleContext {
|
|||||||
editor?:Editor;
|
editor?:Editor;
|
||||||
userComponent: UserComponent;
|
userComponent: UserComponent;
|
||||||
netFileHandler: NetFileHandler;
|
netFileHandler: NetFileHandler;
|
||||||
|
showAfterCreate?:boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
4
src/douban/data/model/SubjectListItem.ts
Normal file
4
src/douban/data/model/SubjectListItem.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export interface SubjectListItem {
|
||||||
|
id:string;
|
||||||
|
url:string;
|
||||||
|
}
|
||||||
26
src/douban/sync/handler/DoubanAbstractSyncHandler.ts
Normal file
26
src/douban/sync/handler/DoubanAbstractSyncHandler.ts
Normal file
@ -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<void>;
|
||||||
|
|
||||||
|
abstract getSyncType(): SyncType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
19
src/douban/sync/handler/DoubanBookSyncHandler.ts
Normal file
19
src/douban/sync/handler/DoubanBookSyncHandler.ts
Normal file
@ -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<void>{
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,12 +0,0 @@
|
|||||||
import {CheerioAPI} from "cheerio";
|
|
||||||
import DoubanBroadcastSubject from "../model/DoubanBroadcastSubject";
|
|
||||||
|
|
||||||
export abstract class DoubanBroadcastAbstractHandler<T extends DoubanBroadcastSubject> {
|
|
||||||
|
|
||||||
abstract support(t: string): boolean;
|
|
||||||
|
|
||||||
abstract transform(data: Element, source: CheerioAPI): T;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ -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<DoubanBroadcastMovieSubject> {
|
|
||||||
support(t: string): boolean {
|
|
||||||
throw new Error("Method not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
transform(data: Element, source: CheerioAPI): DoubanBroadcastMovieSubject {
|
|
||||||
throw new Error("Method not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
25
src/douban/sync/handler/DoubanBroadcastSyncHandler.ts
Normal file
25
src/douban/sync/handler/DoubanBroadcastSyncHandler.ts
Normal file
@ -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<void>{
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
59
src/douban/sync/handler/DoubanMovieSyncHandler.ts
Normal file
59
src/douban/sync/handler/DoubanMovieSyncHandler.ts
Normal file
@ -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<DoubanMovieSubject>;
|
||||||
|
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<void>{
|
||||||
|
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<SubjectListItem[]> {
|
||||||
|
return this.doubanListHandlers.find((h) => h.support(syncConfig)).getAllPageList(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async removeExists(items:SubjectListItem[]):Promise<SubjectListItem[]> {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/douban/sync/handler/DoubanMusicSyncHandler.ts
Normal file
26
src/douban/sync/handler/DoubanMusicSyncHandler.ts
Normal file
@ -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<void>{
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
26
src/douban/sync/handler/DoubanNoteSyncHandler.ts
Normal file
26
src/douban/sync/handler/DoubanNoteSyncHandler.ts
Normal file
@ -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<void>{
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
28
src/douban/sync/handler/DoubanOtherSyncHandler.ts
Normal file
28
src/douban/sync/handler/DoubanOtherSyncHandler.ts
Normal file
@ -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<void>{
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -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<DoubanBroadcastSubject>[];
|
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
14
src/douban/sync/handler/DoubanSyncHandler.ts
Normal file
14
src/douban/sync/handler/DoubanSyncHandler.ts
Normal file
@ -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<void> ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
58
src/douban/sync/handler/SyncHandler.ts
Normal file
58
src/douban/sync/handler/SyncHandler.ts
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
87
src/douban/sync/handler/list/DoubanAbstractListHandler.ts
Normal file
87
src/douban/sync/handler/list/DoubanAbstractListHandler.ts
Normal file
@ -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<SubjectListItem[]>{
|
||||||
|
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<SubjectListItem[]> {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
10
src/douban/sync/handler/list/DoubanListHandler.ts
Normal file
10
src/douban/sync/handler/list/DoubanListHandler.ts
Normal file
@ -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<SubjectListItem[]>;
|
||||||
|
|
||||||
|
support(config:SyncConfig):boolean;
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
10
src/douban/sync/handler/list/DoubanMovieDoListHandler.ts
Normal file
10
src/douban/sync/handler/list/DoubanMovieDoListHandler.ts
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
13
src/douban/sync/handler/list/DoubanMovieListHandler.ts
Normal file
13
src/douban/sync/handler/list/DoubanMovieListHandler.ts
Normal file
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
10
src/douban/sync/handler/list/DoubanMovieWishListHandler.ts
Normal file
10
src/douban/sync/handler/list/DoubanMovieWishListHandler.ts
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import DoubanBroadcastSubject from "./DoubanBroadcastSubject";
|
import DoubanSyncSubject from "./DoubanSyncSubject";
|
||||||
|
|
||||||
export default class DoubanBroadcastMovieSubject extends DoubanBroadcastSubject {
|
export default class DoubanBroadcastMovieSubject extends DoubanSyncSubject {
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/douban/sync/model/DoubanBroadcastSubject1.ts
Normal file
12
src/douban/sync/model/DoubanBroadcastSubject1.ts
Normal file
@ -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;
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
export default class DoubanBroadcastSubject {
|
export default class DoubanSyncSubject {
|
||||||
id: string;
|
id: string;
|
||||||
type: string;
|
type: string;
|
||||||
title: string;
|
title: string;
|
||||||
5
src/douban/sync/model/SyncConfig.ts
Normal file
5
src/douban/sync/model/SyncConfig.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export interface SyncConfig {
|
||||||
|
syncType: string,
|
||||||
|
scope: string,
|
||||||
|
force:boolean,
|
||||||
|
}
|
||||||
@ -23,6 +23,10 @@ export default class UserComponent {
|
|||||||
return this.user;
|
return this.user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getUserId() {
|
||||||
|
return this.user?this.user.id:null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
isLogin() {
|
isLogin() {
|
||||||
return this.user && this.user.login;
|
return this.user && this.user.login;
|
||||||
|
|||||||
@ -112,7 +112,7 @@ export default class FileHandler {
|
|||||||
* A new markdown file will be created at the given file path (`input`)
|
* A new markdown file will be created at the given file path (`input`)
|
||||||
* in the specified parent folder (`this.folder`)
|
* in the specified parent folder (`this.folder`)
|
||||||
*/
|
*/
|
||||||
async createNewNoteWithData(originalFilePath: string, data:string): Promise<void> {
|
async createNewNoteWithData(originalFilePath: string, data:string, showAfterCreate:boolean=false): Promise<void> {
|
||||||
const {vault} = this._app;
|
const {vault} = this._app;
|
||||||
const {adapter} = vault;
|
const {adapter} = vault;
|
||||||
const prependDirInput = FileUtil.join("", originalFilePath);
|
const prependDirInput = FileUtil.join("", originalFilePath);
|
||||||
@ -131,8 +131,10 @@ export default class FileHandler {
|
|||||||
}
|
}
|
||||||
const File = await vault.create(filePath, data);
|
const File = await vault.create(filePath, data);
|
||||||
// Create the file and open it in the active leaf
|
// Create the file and open it in the active leaf
|
||||||
const leaf = this._app.workspace.splitLeafOrActive();
|
if (showAfterCreate) {
|
||||||
await leaf.openFile(File);
|
const leaf = this._app.workspace.splitLeafOrActive();
|
||||||
|
await leaf.openFile(File);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(error.toString(), error);
|
log.error(error.toString(), error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,8 @@ export default {
|
|||||||
'110101': 'search douban and create file',
|
'110101': 'search douban and create file',
|
||||||
'110201': `{0} already exists`,
|
'110201': `{0} already exists`,
|
||||||
'110202': `{0} template can not read`,
|
'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}'`,
|
'140204': `[Obsidian Douban]: replace '{0}'`,
|
||||||
'140205': `[Obsidian Douban]: complete '{0}'`,
|
'140205': `[Obsidian Douban]: complete '{0}'`,
|
||||||
'140206': `[Obsidian Douban]: occur error '{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...`,
|
'150101': `Choose an item...`,
|
||||||
|
|
||||||
@ -361,40 +366,43 @@ export default {
|
|||||||
|
|
||||||
|
|
||||||
'500000': `UNKNOWN`,
|
'500000': `UNKNOWN`,
|
||||||
'500101': `NOT`,
|
'500101': `not`,
|
||||||
'500102': `WANTED`,
|
'500102': `wish`,
|
||||||
'500103': `DOING`,
|
'500103': `do`,
|
||||||
'500104': `DONE`,
|
'500104': `collect`,
|
||||||
|
|
||||||
'500201': `NOT`,
|
'500201': `not`,
|
||||||
'500202': `WANTED`,
|
'500202': `wish`,
|
||||||
'500203': `DOING`,
|
'500203': `do`,
|
||||||
'500204': `DONE`,
|
'500204': `collect`,
|
||||||
|
|
||||||
'500301': `NOT`,
|
'500301': `not`,
|
||||||
'500302': `WANTED`,
|
'500302': `wish`,
|
||||||
'500303': `DOING`,
|
'500303': `do`,
|
||||||
'500304': `DONE`,
|
'500304': `collect`,
|
||||||
|
|
||||||
'500401': `NOT`,
|
'500401': `not`,
|
||||||
'500402': `WANTED`,
|
'500402': `wish`,
|
||||||
'500403': `DOING`,
|
'500403': `do`,
|
||||||
'500404': `DONE`,
|
'500404': `collect`,
|
||||||
|
|
||||||
'500501': `NOT`,
|
'500501': `not`,
|
||||||
'500502': `WANTED`,
|
'500502': `wish`,
|
||||||
'500503': `DOING`,
|
'500503': `do`,
|
||||||
'500504': `DONE`,
|
'500504': `collect`,
|
||||||
|
|
||||||
'500601': `NOT`,
|
'500601': `not`,
|
||||||
'500602': `WANTED`,
|
'500602': `wish`,
|
||||||
'500603': `DOING`,
|
'500603': `do`,
|
||||||
'500604': `DONE`,
|
'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. `,
|
'160225': `You can use those variables in your template after login. `,
|
||||||
'160226': `The tags that I tag for subject`,
|
'160226': `The tags that I tag for subject`,
|
||||||
@ -405,6 +413,13 @@ export default {
|
|||||||
|
|
||||||
|
|
||||||
'500001': `Sync Config`,
|
'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`,
|
'ALL': `all`,
|
||||||
|
|||||||
@ -9,6 +9,9 @@ export default {
|
|||||||
'110005': `取消`,
|
'110005': `取消`,
|
||||||
'110006': `同步豆瓣广播至Obsidian`,
|
'110006': `同步豆瓣广播至Obsidian`,
|
||||||
'110101': '搜索豆瓣并创建文档',
|
'110101': '搜索豆瓣并创建文档',
|
||||||
|
'110103': '同步豆瓣个人记录',
|
||||||
|
'110007': `开始同步`,
|
||||||
|
|
||||||
|
|
||||||
'110201': `{0} 文件已经存在.`,
|
'110201': `{0} 文件已经存在.`,
|
||||||
'110202': `{0} 模板文件无法读取`,
|
'110202': `{0} 模板文件无法读取`,
|
||||||
@ -170,6 +173,11 @@ export default {
|
|||||||
'140205': `[Obsidian Douban]: 处理完成'{0}'`,
|
'140205': `[Obsidian Douban]: 处理完成'{0}'`,
|
||||||
'140206': `[Obsidian Douban]: 出现错误'{0}'`,
|
'140206': `[Obsidian Douban]: 出现错误'{0}'`,
|
||||||
|
|
||||||
|
|
||||||
|
'140301': `Douban: 开始同步...`,
|
||||||
|
'140302': `Douban: 同步完成`,
|
||||||
|
'140303': `Douban: 用户信息已过期,请至插件中重新登录`,
|
||||||
|
|
||||||
'150101': `选择一项内容...`,
|
'150101': `选择一项内容...`,
|
||||||
'121902': `重置为默认值`,
|
'121902': `重置为默认值`,
|
||||||
|
|
||||||
@ -418,6 +426,10 @@ export default {
|
|||||||
'500703': `在看`,
|
'500703': `在看`,
|
||||||
'500704': `看过`,
|
'500704': `看过`,
|
||||||
|
|
||||||
|
'500004': `所有`,
|
||||||
|
'500110': `强制更新所有, 如果未启用则只增量更新新增的部分`,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
'160225': `以下参数登录后方可在模板中使用, 使用时请用'{{}}'包裹, 举例: 参数myTags, 则使用时为{{myTags}}`,
|
'160225': `以下参数登录后方可在模板中使用, 使用时请用'{{}}'包裹, 举例: 参数myTags, 则使用时为{{myTags}}`,
|
||||||
'160226': `我标记的标签`,
|
'160226': `我标记的标签`,
|
||||||
@ -427,7 +439,10 @@ export default {
|
|||||||
'160230': `我的评论/标记的日期`,
|
'160230': `我的评论/标记的日期`,
|
||||||
|
|
||||||
'500001': `同步设置`,
|
'500001': `同步设置`,
|
||||||
|
'504102': `我的书籍`,
|
||||||
|
'504103': `我的电影`,
|
||||||
|
'504104': `我的广播`,
|
||||||
|
'504105': `我的日记`,
|
||||||
|
|
||||||
'ALL': `全部类型`,
|
'ALL': `全部类型`,
|
||||||
'MOVIE': `电影`,
|
'MOVIE': `电影`,
|
||||||
|
|||||||
12
src/utils/NumberUtil.ts
Normal file
12
src/utils/NumberUtil.ts
Normal file
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/utils/TimeUtil.ts
Normal file
13
src/utils/TimeUtil.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import NumberUtil from "./NumberUtil";
|
||||||
|
|
||||||
|
export default class TimeUtil {
|
||||||
|
public static async delay(callback: Function, ms: number):Promise<any> {
|
||||||
|
return await new Promise(resolve => setTimeout(() => callback, ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async delayRange(callback: Function, msMin: number, msMax:number):Promise<any> {
|
||||||
|
return await new Promise(resolve => setTimeout(() => callback, NumberUtil.getRandomNum(msMin, msMax)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user