From a1d818af2f86b3dec4b6a99056d073594948c39c Mon Sep 17 00:00:00 2001 From: wanxp <977741432@qq.com> Date: Mon, 27 Jun 2022 00:25:47 +0800 Subject: [PATCH] add douban note import --- douban/Douban.ts | 20 ++++- douban/DoubanSettingTab.ts | 80 +++++++++++++++---- douban/handler/DoubanAbstractLoadHandler.ts | 4 +- douban/handler/DoubanNoteLoadHandler.ts | 68 ++++++++++++++++ .../handler/DoubanSearchChooseItemHandler.ts | 3 + douban/model/DoubanNoteSubject.ts | 11 +++ lang/locale/en.ts | 17 ++++ lang/locale/zh-cn.ts | 17 +++- utils/Logutil.ts | 9 ++- 9 files changed, 205 insertions(+), 24 deletions(-) create mode 100644 douban/handler/DoubanNoteLoadHandler.ts create mode 100644 douban/model/DoubanNoteSubject.ts diff --git a/douban/Douban.ts b/douban/Douban.ts index aa4ce74..d239afa 100644 --- a/douban/Douban.ts +++ b/douban/Douban.ts @@ -5,7 +5,9 @@ export interface DoubanPluginSettings { movieTemplate:string, bookTemplate:string, musicTemplate:string, + noteTemplate:string dateFormat:string, + dateTimeFormat:string, searchUrl:string, arraySpilt:string, searchHeaders?:string, @@ -87,11 +89,27 @@ desc: {{desc}} ![image|150]({{image}}) `, +noteTemplate: +`--- +doubanId: {{id}} +title: {{title}} +type: {{type}} +author: [{{author}}]({{authorUrl}}) +timePublished: {{timePublished}} +url: {{url}} +tags: Article +desc: {{desc}} +--- + +- content +{{content}} +`, // totalWord: {{totalWord}} searchUrl: 'https://www.douban.com/search?q=', searchHeaders: JSON.stringify(doubanHeadrs), - dateFormat: "yyyy_MM_DD", + dateFormat: "yyyy-MM-DD", + dateTimeFormat: "yyyy-MM-DD HH:mm:ss", arraySpilt: ", ", personNameMode: PersonNameMode.CH_NAME diff --git a/douban/DoubanSettingTab.ts b/douban/DoubanSettingTab.ts index ae46d3d..856d4da 100644 --- a/douban/DoubanSettingTab.ts +++ b/douban/DoubanSettingTab.ts @@ -146,6 +146,34 @@ export class DoubanSettingTab extends PluginSettingTab { }); }); + new Setting(containerEl).setName(i18nHelper.getMessage("note content template")).then((setting) => { + setting.addTextArea((textarea) => { + setting.descEl.appendChild( + createFragment((frag) => { + frag.appendText(i18nHelper.getMessage('note content template desc 1')); + frag.createEl('br'); + frag.appendText(i18nHelper.getMessage('note content template desc 2')); + frag.createEl('br'); + frag.appendText(i18nHelper.getMessage('note content template desc 3')); + frag.createEl('br'); + frag.appendText(i18nHelper.getMessage('note content template desc 4')); + frag.createEl('br'); + frag.appendText(i18nHelper.getMessage('note content template desc 5')); + frag.createEl('br'); + + }) + ); + textarea.inputEl.addClass("settings_area"); + textarea.inputEl.setAttr("rows", 10); + textarea.setPlaceholder(DEFAULT_SETTINGS.noteTemplate) + .setValue(this.plugin.settings.noteTemplate) + .onChange(async (value) => { + this.plugin.settings.noteTemplate = value; + await this.plugin.saveSettings(); + }); + }); + }); + new Setting(containerEl).setName(i18nHelper.getMessage("Person Name Language Mode")).then((setting) => { setting.addDropdown((dropdwon) => { setting.descEl.appendChild( @@ -211,6 +239,41 @@ export class DoubanSettingTab extends PluginSettingTab { }); }); + new Setting(containerEl).setName(i18nHelper.getMessage('DateTime format')).then((setting) => { + setting.addMomentFormat((mf) => { + setting.descEl.appendChild( + createFragment((frag) => { + frag.appendText( + i18nHelper.getMessage('This format will be used when available template variables contain dateTime.') + ); + frag.createEl('br'); + frag.appendText(i18nHelper.getMessage('For more syntax, refer to') + ' '); + frag.createEl( + 'a', + { + text: i18nHelper.getMessage('format reference'), + href: 'https://momentjs.com/docs/#/displaying/format/', + }, + (a) => { + a.setAttr('target', '_blank'); + } + ); + frag.createEl('br'); + frag.appendText(i18nHelper.getMessage('Your current syntax looks like this') + ': '); + mf.setSampleEl(frag.createEl('b', { cls: 'u-pop' })); + frag.createEl('br'); + }) + ); + mf.setPlaceholder(DEFAULT_SETTINGS.dateTimeFormat); + mf.setValue(this.plugin.settings.dateTimeFormat) + mf.onChange(async (value) => { + this.plugin.settings.dateTimeFormat = value; + await this.plugin.saveSettings(); + }); + + }); + }); + new Setting(containerEl) .setName(i18nHelper.getMessage("Array Spilt String")) @@ -224,22 +287,5 @@ export class DoubanSettingTab extends PluginSettingTab { }); }); - - - // new Setting(containerEl) - // .setName("Douban Request Headers") - // .setDesc(`if can not fetch data from douban,\n - // please go to douban.com\n and copy headers to this text area `) - // .addTextArea((textField) => { - // textField - // .setPlaceholder(DEFAULT_SETTINGS.searchHeaders) - // .setValue(this.plugin.settings.searchHeaders) - // .onChange(async (value) => { - // this.plugin.settings.searchHeaders = value; - // await this.plugin.saveSettings(); - // }); - // }); - - } } \ No newline at end of file diff --git a/douban/handler/DoubanAbstractLoadHandler.ts b/douban/handler/DoubanAbstractLoadHandler.ts index 3b8ca49..7e0ff49 100644 --- a/douban/handler/DoubanAbstractLoadHandler.ts +++ b/douban/handler/DoubanAbstractLoadHandler.ts @@ -6,6 +6,7 @@ import DoubanPlugin from "main"; import DoubanSubject from "douban/model/DoubanSubject"; import DoubanSubjectLoadHandler from "./DoubanSubjectLoadHandler"; import { Editor } from "obsidian"; +import { i18nHelper } from 'lang/helper'; import { log } from "utils/Logutil"; export default abstract class DoubanAbstractLoadHandler implements DoubanSubjectLoadHandler { @@ -22,13 +23,14 @@ export default abstract class DoubanAbstractLoadHandler abstract support(extract: DoubanSubject): boolean; handle(url:string, editor:Editor):void { - Promise.resolve().then(() => get(log.traceN("GET URL", url + "/"), log.traceN("GET HEAD", {headers: JSON.parse(this.doubanPlugin.settings.searchHeaders)}))) + Promise.resolve().then(() => get(log.traceN("GET URL", url + "/"), log.traceN("GET HEAD", JSON.parse(this.doubanPlugin.settings.searchHeaders)))) .then(readStream) .then(a => {log.trace(a.toString()); return a;}) .then(load) .then(this.parseSubjectFromHtml) .then(content => this.toEditor(editor, content)) // .then(content => content ? editor.replaceSelection(content) : content) + .catch(e => log.error(i18nHelper.getMessage("Fetch Data Error"))) ; } diff --git a/douban/handler/DoubanNoteLoadHandler.ts b/douban/handler/DoubanNoteLoadHandler.ts new file mode 100644 index 0000000..839742d --- /dev/null +++ b/douban/handler/DoubanNoteLoadHandler.ts @@ -0,0 +1,68 @@ +import { CheerioAPI } from 'cheerio'; +import DoubanAbstractLoadHandler from "./DoubanAbstractLoadHandler"; +import DoubanNoteSubject from 'douban/model/DoubanNoteSubject'; +import DoubanPlugin from "main"; +import { DoubanPluginSettings } from "douban/Douban"; +import DoubanSubject from "douban/model/DoubanSubject"; +import { moment } from "obsidian"; + +export default class DoubanNoteLoadHandler extends DoubanAbstractLoadHandler { + + parseText(extract: DoubanNoteSubject, settings:DoubanPluginSettings): string { + return settings.bookTemplate ? settings.noteTemplate + .replaceAll("{{id}}", extract.id) + .replaceAll("{{type}}", extract.type ? extract.type : "") + .replaceAll("{{title}}", extract.title ? extract.title : "") + .replaceAll("{{desc}}", extract.desc ? extract.desc : "") + .replaceAll("{{image}}", extract.image ? extract.image : "") + .replaceAll("{{timePublished}}", extract.timePublished ? moment(extract.timePublished).format(settings.dateTimeFormat) : "") + .replaceAll("{{url}}", extract.url ? extract.url : "") + .replaceAll("{{content}}", extract.content ? extract.content : "") + .replaceAll("{{url}}", extract.url ? extract.url : "") + .replaceAll("{{authorUrl}}", extract.authorUrl ? extract.authorUrl : "") + .replaceAll("{{author}}", extract.author ? extract.author : "") + + + : undefined; + } + support(extract: DoubanSubject): boolean { + return extract && extract.type && (extract.type.contains("日记") || extract.type.contains("Note") || extract.type.contains("Article")); + } + + + + + + constructor(doubanPlugin:DoubanPlugin) { + super(doubanPlugin); + } + + parseSubjectFromHtml(html: CheerioAPI): DoubanNoteSubject { + var title = html(html("head > meta[property= 'og:title']").get(0)).attr("content"); + var desc = html(html("head > meta[property= 'og:description']").get(0)).attr("content"); + var url = html(html("head > meta[property= 'og:url']").get(0)).attr("content"); + var image = html(html("head > meta[property= 'og:image']").get(0)).attr("content"); + var type = html(html("head > meta[property= 'og:type']").get(0)).attr("content"); + var authorA = html(html("a.note-author").get(0)); + var timePublished = html(html(".pub-date").get(0)).text(); + var content = html(html(".note").get(1)); + var idPattern = /(\d){5,10}/g; + var id = idPattern.exec(url); + + const result:DoubanNoteSubject = { + image: image, + timePublished: timePublished ? new Date(timePublished) : null, + content: content ? content.toString().replaceAll(`
`, "").replaceAll(`
`, "").replaceAll(`
`, " \n"): "", + id: id ? id[0] : "", + type: "Article", + title: title, + desc: desc, + url: url, + author: authorA ? authorA.text() : null, + authorUrl: authorA ? authorA.attr("href") : null, + }; + return result; +} + + +} diff --git a/douban/handler/DoubanSearchChooseItemHandler.ts b/douban/handler/DoubanSearchChooseItemHandler.ts index 8db93e8..5d20947 100644 --- a/douban/handler/DoubanSearchChooseItemHandler.ts +++ b/douban/handler/DoubanSearchChooseItemHandler.ts @@ -3,6 +3,7 @@ import { App, Editor } from "obsidian"; import DoubanBookLoadHandler from "./DoubanBookLoadHandler"; import DoubanMovieLoadHandler from "./DoubanMovieLoadHandler"; import DoubanMusicLoadHandler from "./DoubanMusicLoadHandler"; +import DoubanNoteLoadHandler from "./DoubanNoteLoadHandler"; import DoubanOtherLoadHandler from "./DoubanOtherLoadHandler"; import DoubanPlugin from "main"; import { DoubanPluginSettings } from "douban/Douban"; @@ -26,6 +27,8 @@ export class DoubanSearchChooseItemHandler { this._doubanSubjectHandlers = [new DoubanMovieLoadHandler(doubanPlugin), new DoubanBookLoadHandler(doubanPlugin), new DoubanTeleplayLoadHandler(doubanPlugin), new DoubanMusicLoadHandler(doubanPlugin), + new DoubanNoteLoadHandler(doubanPlugin), + this._doubanSubjectHandlerDefault]; } diff --git a/douban/model/DoubanNoteSubject.ts b/douban/model/DoubanNoteSubject.ts new file mode 100644 index 0000000..cd13513 --- /dev/null +++ b/douban/model/DoubanNoteSubject.ts @@ -0,0 +1,11 @@ +import {AggregateRating, Person, WithContext} from 'schema-dts'; + +import DoubanSubject from "./DoubanSubject"; + +export default class DoubanNoteSubject extends DoubanSubject { + author:string; + authorUrl:string; + timePublished:Date; + image:string; + content:string; +} diff --git a/lang/locale/en.ts b/lang/locale/en.ts index 383442f..cf1f436 100644 --- a/lang/locale/en.ts +++ b/lang/locale/en.ts @@ -37,10 +37,21 @@ export default { 'music content template desc 4': `{{score}}, {{medium}}, {{datePublished}}, {{type}},`, 'music content template desc 5': `{{publish}}, {{desc}}, {{albumType}}, {{barcode}},`, 'music content template desc 6': `{{image}}, {{url}}, {{numberOfRecords}}, {{desc}}`, + + 'note content template': `Article Content Template`, + 'note content template desc 1': `Set markdown Article template for extract to be inserted.`, + 'note content template desc 2': `Available Article template variables are :`, + 'note content template desc 3': `{{id}}, {{title}}, {{author}}, {{authorUrl}},`, + 'note content template desc 4': `{{timePublished}}, {{url}}, {{desc}}, {{type}},`, + 'note content template desc 5': `{{content}}`, 'Date format': `Date Format`, + 'DateTime format': `DateTime Format`, + 'This format will be used when available template variables contain date.': `This format will be used when available template variables contain date.`, + 'This format will be used when available template variables contain dateTime.': + `This format will be used when available template variables contain dateTime.`, 'For more syntax, refer to': `For more syntax, refer to`, 'Your current syntax looks like this':`Your current syntax looks like this`, 'format reference': `format reference`, @@ -57,4 +68,10 @@ export default { 'Chinese Name': 'Chinese Name', 'English Name': 'English Name', 'Chinese And English Name': 'Chinese And English Name', + + + //error + "Fetch Data Error": "Fetch Data Error, You can go to Github add Issues", + "Obsidian Douban Plugin Error:": "Obsidian Douban Plugin Error: ", + "Obsidian Douban Plugin Warn:": "Obsidian Douban Plugin Warn: ", } \ No newline at end of file diff --git a/lang/locale/zh-cn.ts b/lang/locale/zh-cn.ts index fb5e7c6..d6ca27a 100644 --- a/lang/locale/zh-cn.ts +++ b/lang/locale/zh-cn.ts @@ -39,10 +39,21 @@ export default { 'music content template desc 5': `{{publish}}, {{desc}}, {{albumType}}, {{barcode}},`, 'music content template desc 6': `{{image}}, {{url}}, {{numberOfRecords}}, {{desc}}`, + 'note content template': `日记文本模板`, + 'note content template desc 1': `设置选择日记后导入的文本内容模板,`, + 'note content template desc 2': `支持以下参数名称 :`, + 'note content template desc 3': `{{id}}, {{title}}, {{author}}, {{authorUrl}},`, + 'note content template desc 4': `{{timePublished}}, {{url}}, {{desc}}, {{type}},`, + 'note content template desc 5': `{{content}}`, + 'Date format': `参数日期格式`, 'This format will be used when available template variables contain date.': - `这个格式是给上面获取到的参数进行格式化时显示的内容 .`, + `这个格式是给上面获取到的参数进行格式化日期时显示的内容 .`, + + 'DateTime format': `参数时间格式`, + 'This format will be used when available template variables contain dateTime.': + `这个格式是给上面获取到的参数进行格式化时间时显示的内容 .`, 'For more syntax, refer to': `详细介绍请参考`, 'Your current syntax looks like this':`时间参数时间格式预览`, 'format reference': `格式参考`, @@ -65,4 +76,8 @@ export default { 'English Name': '英文名', 'Chinese And English Name': '中文名和英文名', + "Fetch Data Error": "获取数据失败,您如有需要请至Github提交Issues", + "Obsidian Douban Plugin Error: ": "Obsidian Douban插件错误提示:", + "Obsidian Douban Plugin Warn: ": "Obsidian Douban插件异常提示:", + } \ No newline at end of file diff --git a/utils/Logutil.ts b/utils/Logutil.ts index 001bf07..38e1ec9 100644 --- a/utils/Logutil.ts +++ b/utils/Logutil.ts @@ -1,26 +1,27 @@ import { Notice } from "obsidian"; import SchemaOrg from "./SchemaOrg"; +import { i18nHelper } from "lang/helper"; class Logger { public error(e:any):any { - new Notice("Douban Plugin Error: " + e); + new Notice(i18nHelper.getMessage("Obsidian Douban Plugin Error:") + e); return e; } public warn(e:any):any { - new Notice("Obsidian Douban Plugin Warn: " + e); + new Notice(i18nHelper.getMessage("Obsidian Douban Plugin Warn:") + e); return e; } public info(e:any):any { - console.log(`Douban Plugin info: ${typeof e == 'string' ? e : JSON.stringify(e)}`); + console.log(`Douban Plugin info:` + `${typeof e == 'string' ? e : JSON.stringify(e)}`); return e; } public trace(e:any):any { // return e; - console.log(`Douban Plugin trace: ${typeof e == 'string' ? e : JSON.stringify(e)}`); + console.log(`Douban Plugin trace:` + `${typeof e == 'string' ? e : JSON.stringify(e)}`); return e; }