mirror of
https://github.com/Wanxp/obsidian-douban.git
synced 2026-04-04 08:38:41 +08:00
feature: theater
function: HttpUtil
This commit is contained in:
parent
198cffaada
commit
44697ac05a
@ -44,6 +44,10 @@
|
||||
- [x] 支持自定义参数
|
||||
- [ ] 广播
|
||||
|
||||
## 拓展
|
||||
1. 结合Timeline插件 __构建个人观影时间线__,请参照[结合timeline插件实现时间线效果](./doc/Obsidian-Douban-TimeLine.md))
|
||||
2. 结合DataView插件,__构建个人电子书架(书库数据)__,请参照[结合dateview插件实现个人书架效果](./doc/Obsidian-Douban-DataView.md))
|
||||
|
||||
|
||||
## 如何使用
|
||||
### 同步
|
||||
|
||||
69
doc/Obsidian-Douban-DataView.md
Normal file
69
doc/Obsidian-Douban-DataView.md
Normal file
@ -0,0 +1,69 @@
|
||||
## 效果如下
|
||||

|
||||
## 适用人群
|
||||
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}}
|
||||
---
|
||||
|
||||

|
||||
|
||||
Comment:
|
||||
---
|
||||
{{myComment}}
|
||||
|
||||
|
||||
<span class='ob-timelines' data-date='{{myCollectionDate}}'
|
||||
data-title='{{title}}' data-img='{{image}}'
|
||||
data-class = "custom-my-movie-time-line">{{myComment}} |简介: {{desc}}
|
||||
</span>
|
||||
````
|
||||
### 书籍、电视剧、音乐、游戏
|
||||
请参照电影模板
|
||||
## 更多
|
||||
参照讨论 [结合timeline插件的妙用](https://github.com/Wanxp/obsidian-douban/issues/19#issuecomment-1428307130)
|
||||
@ -48,6 +48,7 @@ author: {{author}}
|
||||
tags: {{type}}, 我看过的电影, {{myTags}}
|
||||
state: {{myState}}
|
||||
url: {{url}}
|
||||
coverUrl: {{imageData.url}}
|
||||
createTime: {{currentDate}} {{currentTime}}
|
||||
collectionDate: {{myCollectionDate}}
|
||||
desc: {{desc}}
|
||||
|
||||
@ -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<T extends DoubanSubject> implements DoubanSubjectLoadHandler<T> {
|
||||
|
||||
@ -143,14 +144,7 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
|
||||
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<T extends DoubanSubject>
|
||||
|
||||
abstract getHighQuantityImageUrl(fileName:string):string;
|
||||
|
||||
private async humanCheck(html:any, url:string):Promise<any> {
|
||||
this.doubanPlugin.settingsManager.debug(html);
|
||||
if (html && html.indexOf("<title>禁止访问</title>") != -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()
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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<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)
|
||||
return HttpUtil.httpRequestGet(url, headers, context.plugin.settingsManager)
|
||||
.then(load)
|
||||
.then(data => this.parseSubjectFromHtml(data, context))
|
||||
.catch(e => log
|
||||
|
||||
@ -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;
|
||||
@ -86,32 +88,10 @@ export default class UserComponent {
|
||||
'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 = 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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
90
src/org/wanxp/utils/HttpUtil.ts
Normal file
90
src/org/wanxp/utils/HttpUtil.ts
Normal file
@ -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<string> {
|
||||
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<any> {
|
||||
if (settingsManager) {
|
||||
settingsManager.debug(html);
|
||||
}
|
||||
if (html && html.indexOf("<title>禁止访问</title>") != -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<string> {
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user