From 44697ac05aec91a9fd3ac67715bffaa99fdc3a4c Mon Sep 17 00:00:00 2001 From: wanxp <977741432@qq.com> Date: Wed, 20 Sep 2023 09:54:29 +0800 Subject: [PATCH] feature: theater function: HttpUtil --- README.md | 4 + doc/Obsidian-Douban-DataView.md | 69 ++++++++++++++ doc/Obsidian-Douban-TimeLine.md | 1 + .../data/handler/DoubanAbstractLoadHandler.ts | 22 +---- .../data/handler/DoubanTheaterLoadHandler.ts | 2 +- .../handler/list/DoubanAbstractListHandler.ts | 9 +- src/org/wanxp/douban/user/UserComponent.ts | 46 +++------- src/org/wanxp/utils/HttpUtil.ts | 90 +++++++++++++++++++ 8 files changed, 182 insertions(+), 61 deletions(-) create mode 100644 doc/Obsidian-Douban-DataView.md create mode 100644 src/org/wanxp/utils/HttpUtil.ts diff --git a/README.md b/README.md index 1df867f..135a496 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,10 @@ - [x] 支持自定义参数 - [ ] 广播 +## 拓展 +1. 结合Timeline插件 __构建个人观影时间线__,请参照[结合timeline插件实现时间线效果](./doc/Obsidian-Douban-TimeLine.md)) +2. 结合DataView插件,__构建个人电子书架(书库数据)__,请参照[结合dateview插件实现个人书架效果](./doc/Obsidian-Douban-DataView.md)) + ## 如何使用 ### 同步 diff --git a/doc/Obsidian-Douban-DataView.md b/doc/Obsidian-Douban-DataView.md new file mode 100644 index 0000000..c46dc4d --- /dev/null +++ b/doc/Obsidian-Douban-DataView.md @@ -0,0 +1,69 @@ +## 效果如下 +![](./img/obsidian-douban-time-preview-example.gif) +## 适用人群 +1. 在豆瓣有标记/评论/评分的习惯的人 +比如看完电影,会在豆瓣进行评分或评论。或者阅读完的书籍,进行评分或评论。支持包含:电影、书籍、电视剧、音乐、游戏 +## 实现步骤 +1. 安装[obsidian-dataview](https://github.com/blacksmithgu/obsidian-dataview)插件 +2. 安装[Obsidian-Douban](https://github.com/Wanxp/obsidian-douban)插件(本插件) +3. 在Obsidian-Douban插件配置中登录Douban +4. 配置同步需要的模板 电影/书籍的模板中的frontmatter,在frontmatter中 **增加** 特定tags(根据自己的需要指定),用于需要过滤成为timeline的笔记,如增加tags:`书籍` +````markdown +--- +tags: 书籍 +--- +```` +5. 同时,在电影/书籍... 模板中的 **最后增加** timeline插件需要的html标签如下: + +``` + +``` +6. 选择上述模板导入 电影/书籍...,操作方式是打开obsidian命令窗口,输入豆瓣,找到导入功能,在导入界面配置 选择模板进行导入 +7. 导入需要一定时间,每条内容导入需要15-30s左右,所有有导入完成后会有导入汇总 +8. 导入完成后,新建一个笔记,笔记内容加入DataView的代码块,指定搜索上面指定的tags的内容,如`书籍`,代码块如下: +````markdown +```dataview +table file.name +``` +```` +9. 预览这个笔记就能看出已经出现了时间线 +## 模板参考 +### 电影 +````markdown +--- +doubanId: {{id}} +title: {{title}} +type: {{type}} +score: {{score}} +myRate: {{myRate}} +originalTitle: {{originalTitle}} +genre: {{genre}} +datePublished: {{datePublished}} +director: {{director}} +actor: {{actor}} +author: {{author}} +tags: {{type}}, 我看过的电影, {{myTags}} +state: {{myState}} +url: {{url}} +coverUrl: {{imageData.url}} +createTime: {{currentDate}} {{currentTime}} +collectionDate: {{myCollectionDate}} +desc: {{desc}} +--- + +![image]({{image}}) + +Comment: +--- +{{myComment}} + + +{{myComment}} |简介: {{desc}} + +```` +### 书籍、电视剧、音乐、游戏 +请参照电影模板 +## 更多 +参照讨论 [结合timeline插件的妙用](https://github.com/Wanxp/obsidian-douban/issues/19#issuecomment-1428307130) diff --git a/doc/Obsidian-Douban-TimeLine.md b/doc/Obsidian-Douban-TimeLine.md index 03ab3a9..34ac899 100644 --- a/doc/Obsidian-Douban-TimeLine.md +++ b/doc/Obsidian-Douban-TimeLine.md @@ -48,6 +48,7 @@ author: {{author}} tags: {{type}}, 我看过的电影, {{myTags}} state: {{myState}} url: {{url}} +coverUrl: {{imageData.url}} createTime: {{currentDate}} {{currentTime}} collectionDate: {{myCollectionDate}} desc: {{desc}} diff --git a/src/org/wanxp/douban/data/handler/DoubanAbstractLoadHandler.ts b/src/org/wanxp/douban/data/handler/DoubanAbstractLoadHandler.ts index e294447..741642a 100644 --- a/src/org/wanxp/douban/data/handler/DoubanAbstractLoadHandler.ts +++ b/src/org/wanxp/douban/data/handler/DoubanAbstractLoadHandler.ts @@ -25,6 +25,7 @@ import DoubanLoginModel from "../../component/DoubanLoginModel"; import DoubanHumanCheckModel from "../../component/DoubanHumanCheckModel"; import DoubanMovieSubject from "../model/DoubanMovieSubject"; import {Person} from "schema-dts"; +import HttpUtil from "../../../utils/HttpUtil"; export default abstract class DoubanAbstractLoadHandler implements DoubanSubjectLoadHandler { @@ -143,14 +144,7 @@ export default abstract class DoubanAbstractLoadHandler headers.Cookie = context.settings.loginCookiesContent; context.plugin.settingsManager.debug(`开始请求地址:${url}`) context.plugin.settingsManager.debug(`(注意:请勿向任何人透露你的Cookie,此处若需要截图请**打码**)请求cookie:${context.settings.loginCookiesContent}`) - const requestUrlParam: RequestUrlParam = { - url: url, - method: "GET", - headers: headers, - throw: true - }; - await request(requestUrlParam) - .then(s => this.humanCheck(s, url)) + await HttpUtil.httpRequestGet(url, headers, context.plugin.settingsManager) .then(load) .then(data => this.analysisUserState(data, context)) .then(({data, userState}) => { @@ -487,20 +481,8 @@ export default abstract class DoubanAbstractLoadHandler abstract getHighQuantityImageUrl(fileName:string):string; - private async humanCheck(html:any, url:string):Promise { - this.doubanPlugin.settingsManager.debug(html); - if (html && html.indexOf("禁止访问") != -1) { - const loginModel = new DoubanHumanCheckModel(url); - await loginModel.load(); - return ''; - }else { - return html; - } - - } - handlePersonNameByMeta(html: CheerioAPI, movie: DoubanSubject, context: HandleContext, metaProperty:string, objectProperty:string) { let metaProperties: string[] = html(`head > meta[property='${metaProperty}']`).get() diff --git a/src/org/wanxp/douban/data/handler/DoubanTheaterLoadHandler.ts b/src/org/wanxp/douban/data/handler/DoubanTheaterLoadHandler.ts index 5671ae8..70bb085 100644 --- a/src/org/wanxp/douban/data/handler/DoubanTheaterLoadHandler.ts +++ b/src/org/wanxp/douban/data/handler/DoubanTheaterLoadHandler.ts @@ -83,7 +83,7 @@ export default class DoubanTheaterLoadHandler extends DoubanAbstractLoadHandler< const result: DoubanMovieSubject = { id: id ? id[0] : '', title: title, - type: 'Movie', + type: 'Theater', score: obj.aggregateRating ? obj.aggregateRating.ratingValue : undefined, originalTitle: originalTitle, desc: obj.description, diff --git a/src/org/wanxp/douban/sync/handler/list/DoubanAbstractListHandler.ts b/src/org/wanxp/douban/sync/handler/list/DoubanAbstractListHandler.ts index 1867868..133c94c 100644 --- a/src/org/wanxp/douban/sync/handler/list/DoubanAbstractListHandler.ts +++ b/src/org/wanxp/douban/sync/handler/list/DoubanAbstractListHandler.ts @@ -10,6 +10,7 @@ import {DoubanListHandler} from "./DoubanListHandler"; import {SyncConfig} from "../../model/SyncConfig"; import { sleepRange} from "../../../../utils/TimeUtil"; import {ALL} from "../../../../constant/DoubanUserState"; +import HttpUtil from "../../../../utils/HttpUtil"; export default abstract class DoubanAbstractListHandler implements DoubanListHandler{ @@ -47,13 +48,7 @@ export default abstract class DoubanAbstractListHandler implements DoubanListHan 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) + return HttpUtil.httpRequestGet(url, headers, context.plugin.settingsManager) .then(load) .then(data => this.parseSubjectFromHtml(data, context)) .catch(e => log diff --git a/src/org/wanxp/douban/user/UserComponent.ts b/src/org/wanxp/douban/user/UserComponent.ts index 8ac6512..e6e6334 100644 --- a/src/org/wanxp/douban/user/UserComponent.ts +++ b/src/org/wanxp/douban/user/UserComponent.ts @@ -1,5 +1,5 @@ import SettingsManager from "../setting/SettingsManager"; -import {request, RequestUrlParam} from "obsidian"; +import {RequestUrlParam} from "obsidian"; import {CheerioAPI, load} from "cheerio"; import {log} from "../../utils/Logutil"; import {i18nHelper} from "../../lang/helper"; @@ -7,6 +7,8 @@ import User from "./User"; import StringUtil from "../../utils/StringUtil"; import {DEFAULT_SETTINGS} from "../../constant/DefaultSettings"; import {doubanHeaders} from "../../constant/Douban"; +import { request } from "https"; +import HttpUtil from "../../utils/HttpUtil"; export default class UserComponent { private settingsManager: SettingsManager; @@ -79,39 +81,17 @@ export default class UserComponent { async loadUserInfo(cookie: any): Promise { - const headers1 = { - 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', - 'Accept-Language': 'zh-CN,zh;q=0.9', - 'Cookie': cookie, - 'Referer': 'https://accounts.douban.com/', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36' - } - // Object.assign(headers, doubanHeaders, {'Cookie': cookie}, {'Referer': 'https://accounts.douban.com/'}) - let requestUrlParam: RequestUrlParam = { - url: 'https://www.douban.com/mine/', - method: "GET", - headers: headers1, - throw: true - }; - this.settingsManager.debug('loadUserInfo:尝试获取用户信息:https://www.douban.com/mine/'); - return request(requestUrlParam) - .then(requestUrlResponse => { - if (requestUrlResponse.indexOf('https://sec.douban.com/a') > 0) { - this.settingsManager.debug(`loadUserInfo:登录Douban获取异常网页如下:\n${requestUrlResponse}`); - log.notice(i18nHelper.getMessage('130105')) - } - this.settingsManager.debug(`loadUserInfo:登录Douban获取网页如下:\n${requestUrlResponse}`); - return requestUrlResponse; - }) + const headers1 = { + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', + 'Accept-Language': 'zh-CN,zh;q=0.9', + 'Cookie': cookie, + 'Referer': 'https://accounts.douban.com/', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36' + } + // const headers1 = StringUtil.parseHeaders(cookie) + return HttpUtil.httpRequestGet('https://www.douban.com/mine/', headers1, this.settingsManager) .then(load) - .then(this.getUserInfo) - .catch(e => { - if(e.toString().indexOf('403') > 0) { - throw log.error(i18nHelper.getMessage('130105'), e) - }else { - throw log.error(i18nHelper.getMessage('130101').replace('{0}', e.toString()), e) - } - }); + .then(this.getUserInfo); }; diff --git a/src/org/wanxp/utils/HttpUtil.ts b/src/org/wanxp/utils/HttpUtil.ts new file mode 100644 index 0000000..aa7a992 --- /dev/null +++ b/src/org/wanxp/utils/HttpUtil.ts @@ -0,0 +1,90 @@ +import axios from "axios"; +import {log} from "./Logutil"; +import {i18nHelper} from "../lang/helper"; +import SettingsManager from "../douban/setting/SettingsManager"; +import {request, RequestUrlParam} from "obsidian"; +import DoubanHumanCheckModel from "../douban/component/DoubanHumanCheckModel"; + +export default class HttpUtil { + /** + * get请求 + * @param url 请求地址 + * @param headers 请求参数 + * @param settingsManager 设置管理器 + */ + public static httpRequestGet(url: string, headers:any, settingsManager?:SettingsManager): Promise { + let requestUrlParam: RequestUrlParam = { + url: url, + method: "GET", + headers: headers, + throw: true + }; + return request(requestUrlParam) + // .then(res => res.text) + .then(data => { + if (data && data.indexOf('https://sec.douban.com/a') > 0) { + log.notice(i18nHelper.getMessage('130105')) + if (settingsManager) { + settingsManager.debug(`Obsidian-Douban:获取异常网页如下:\n${data}`); + } + } + settingsManager.debug(`Obsidian-Douban:获取网页如下:\n${data}`); + return data; + }) + .then(s => this.humanCheck(s, url, settingsManager)) + .catch(e => { + if(e.toString().indexOf('403') > 0) { + throw log.error(i18nHelper.getMessage('130105'), e) + }else { + throw log.error(i18nHelper.getMessage('130101').replace('{0}', e.toString()), e) + } + }) + + + } + + + public static async humanCheck(html:any, url:string, settingsManager?: SettingsManager):Promise { + if (settingsManager) { + settingsManager.debug(html); + } + if (html && html.indexOf("禁止访问") != -1) { + const loginModel = new DoubanHumanCheckModel(url); + await loginModel.load(); + return ''; + }else { + return html; + } + + + + } + + /** + * get请求 + * @param url 请求地址 + * @param settingsManager 设置管理器 + */ + public static httpRequestGetUrl(url: string, settingsManager?:SettingsManager): Promise { + return axios.get(url) + .then(res => res.data) + .then(data => { + if (data && data.indexOf('https://sec.douban.com/a') > 0) { + log.notice(i18nHelper.getMessage('130105')) + if (settingsManager) { + settingsManager.debug(`Obsidian-Douban:获取异常网页如下:\n${data}`); + } + } + settingsManager.debug(`Obsidian-Douban:获取网页如下:\n${data}`); + return data; + }) + .catch(e => { + if(e.toString().indexOf('403') > 0) { + throw log.error(i18nHelper.getMessage('130105'), e) + }else { + throw log.error(i18nHelper.getMessage('130101').replace('{0}', e.toString()), e) + } + }) + } + +}