add douban login

This commit is contained in:
wanxp 2022-11-07 23:08:26 +08:00
parent 53ca2ec446
commit 1f30482542
13 changed files with 202 additions and 50 deletions

@ -34,30 +34,31 @@ If you want some features or have any questions about this plugin, create issues
(若有缺少想导入的字段, 欢迎提issues反馈)
---
| 字段 | 电影 | 电视剧 | 书籍 | 音乐 | 日记 | 游戏 | 广播 |
| ------------- | -------------------- | -------------------- | -------------------- | ------------------ | ------------------ | ---------------- | ---- |
| id | 豆瓣ID | 豆瓣ID | 豆瓣ID | 豆瓣ID | 豆瓣ID | 豆瓣ID | - |
| title | 电影名称 | 电视剧名称 | 书名 | 音乐名 | 日记标题 | 游戏名称 | - |
| type | 类型 | 类型 | 类型 | 类型 | 类型 | 类型 | - |
| score | 评分 | 评分 | 评分 | 评分 | 评分 | 评分 | - |
| image | 封面 | 封面 | 封面 | 封面 | 图片 | 封面 | - |
| url | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | - |
| desc | 简介 | 简介 | 内容简介 | 简介 | 简介 | 简介 | - |
| publisher | - | - | 出版社 | 出版者 | 发布者 | 发行商 | - |
| 字段 | 电影 | 电视剧 | 书籍 | 音乐 | 日记 | 游戏 | 广播 |
| ----------- | -------------------- | -------------------- |-------------------| ------------------ | ------------------ | ---------------- | ---- |
| id | 豆瓣ID | 豆瓣ID | 豆瓣ID | 豆瓣ID | 豆瓣ID | 豆瓣ID | - |
| title | 电影名称 | 电视剧名称 | 书名 | 音乐名 | 日记标题 | 游戏名称 | - |
| type | 类型 | 类型 | 类型 | 类型 | 类型 | 类型 | - |
| score | 评分 | 评分 | 评分 | 评分 | 评分 | 评分 | - |
| image | 封面 | 封面 | 封面 | 封面 | 图片 | 封面 | - |
| url | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | - |
| desc | 简介 | 简介 | 内容简介 | 简介 | 简介 | 简介 | - |
| publisher | - | - | 出版社 | 出版者 | 发布者 | 发行商 | - |
| datePublished | 上映日期 | 上映日期 | 出版年 | 发行时间 | 发布时间 | 发行日期 | - |
| genre | 类型 | 类型 | - | 流派 | - | 类型 | - |
| currentDate | 今日日期 | 今日日期 | 今日日期 | 今日日期 | 今日日期 | 今日日期 | |
| currentTime | 当前时间 | 当前时间 | 当前时间 | 当前时间 | 当前时间 | 当前时间 | |
| genre | 类型 | 类型 | - | 流派 | - | 类型 | - |
| currentDate | 今日日期 | 今日日期 | 今日日期 | 今日日期 | 今日日期 | 今日日期 | |
| currentTime | 当前时间 | 当前时间 | 当前时间 | 当前时间 | 当前时间 | 当前时间 | |
| 扩展1 | director:导演 | director:导演 | author:原作者 | actor: 表演者 | author:作者 | aliases:别名 | |
| 扩展2 | author:编剧 | author:编剧 | translator:译者 | albumType:专辑类型 | authorUrl:作者网址 | developer:开发商 | |
| 扩展3 | actor:主演 | actor:主演 | isbn:isbn | medium:介质 | content:日记内容 | platform:平台 | |
| 扩展2 | author:编剧 | author:编剧 | translator:译者 | albumType:专辑类型 | authorUrl:作者网址 | developer:开发商 | |
| 扩展3 | actor:主演 | actor:主演 | isbn:isbn | medium:介质 | content:日记内容 | platform:平台 | |
| 扩展4 | originalTitle:原作名 | originalTitle:原作名 | originalTitle:原作名 | records:唱片数 | | | |
| 扩展5 | | | subTitle:副标题 | barcode:条形码 | | | |
| 扩展6 | | | totalPage:页数 | | | | |
| 扩展7 | | | series:丛书 | | | | |
| 扩展8 | | | menu:目录 | | | | |
| 扩展9 | | | price:定价 | | | | |
| 扩展7 | | | binding:装帧 | | | | |
| 扩展6 | | | totalPage:页数 | | | | |
| 扩展7 | | | series:丛书 | | | | |
| 扩展8 | | | menu:目录 | | | | |
| 扩展9 | | | price:定价 | | | | |
| 扩展7 | | | binding:装帧 | | | | |
| 扩展8 | | | producer: 出品方 | | | | |
## How to use
### Search

10
main.ts

@ -15,12 +15,16 @@ import HandleResult from "@App/data/model/HandleResult";
import {FileUtil} from "./src/utils/FileUtil";
import { DoubanPluginSetting } from "@App/setting/model/DoubanPluginSetting";
import {DEFAULT_SETTINGS} from "./src/constant/DefaultSettings";
import UserComponent from "@App/user/UserComponent";
import SettingsManager from "@App/setting/SettingsManager";
export default class DoubanPlugin extends Plugin {
public settings: DoubanPluginSetting;
public doubanExtractHandler: DoubanSearchChooseItemHandler;
public doubanStatusBar: HTMLElement;
public fileHandler: FileHandler;
public userComponent: UserComponent;
public settingsManager: SettingsManager;
async putToObsidian(context: HandleContext, extract: DoubanSubject) {
@ -124,6 +128,12 @@ export default class DoubanPlugin extends Plugin {
editorCallback: (editor: Editor) =>
this.getDoubanTextForSearchTerm({mode: SearchHandleMode.FOR_REPLACE, settings: this.settings, editor: editor}),
});
this.settingsManager = new SettingsManager(app, this);
this.userComponent = new UserComponent(this.settingsManager);
if (this.userComponent.needLogin()) {
this.userComponent.loginByCookie();
}
this.addSettingTab(new DoubanSettingTab(this.app, this));
}

@ -32,6 +32,7 @@ score: {{score}}
datePublished: {{datePublished}}
translator: {{translator}}
publisher: {{publisher}}
producer: {{producer}}
isbn: {{isbn}}
url: {{url}}
totalPage: {{totalPage}}

@ -1,13 +0,0 @@
import {Notice} from "obsidian";
export const ensureStatusCode = (expected: any) => {
if (!Array.isArray(expected))
expected = [expected];
return (res: any) => {
const {statusCode} = res;
if (!expected.includes(statusCode)) {
new Notice(`Request Douban failed, Status code must be "${expected}" but actually "${statusCode}"`)
}
return res;
};
};

@ -3,7 +3,7 @@ import { log } from 'src/utils/Logutil';
import {i18nHelper} from "../../lang/helper";
import {DoubanSettingTab} from "@App/setting/DoubanSettingTab";
import SettingsManager from "@App/setting/SettingsManager";
import {constructDoubanTokenSettingsUI, constructLoginSettingsUI} from "@App/setting/BasicSettingsHelper";
import {constructDoubanTokenSettingsUI} from "@App/setting/BasicSettingsHelper";
// Credits go to zhaohongxuan's Weread Plugin : https://github.com/zhaohongxuan/obsidian-weread-plugin
@ -35,12 +35,12 @@ export default class DoubanLoginModel {
const filter = {
urls: ['https://www.douban.com/']
};
session.webRequest.onSendHeaders(filter, (details:any) => {
session.webRequest.onSendHeaders(filter, async (details:any) => {
const cookies = details.requestHeaders['Cookie'];
const cookieArr = this.parseCookies(cookies);
// const wr_name = cookieArr.find((cookie) => cookie.name == 'wr_name').value;
if (cookieArr) {
this.settingsManager.updateSetting('loginCookiesContent', cookieArr);
let user = await settingsManager.plugin.userComponent.loginCookie(cookieArr);
constructDoubanTokenSettingsUI(containerEl, settingsManager);
this.modal.close();
} else {

@ -9,9 +9,9 @@ import {log} from "../../utils/Logutil";
export default class DoubanLogoutModel {
private modal: any;
private containerEl: HTMLElement;
private settingsManager: SettingsManager;
constructor(containerEl: HTMLElement, settingsManager: SettingsManager) {
this.settingsManager = settingsManager;
const { remote } = require('electron');
const { BrowserWindow: RemoteBrowserWindow } = remote;
this.modal = new RemoteBrowserWindow({
@ -26,12 +26,11 @@ export default class DoubanLogoutModel {
});
const session = this.modal.webContents.session;
const filter = {
urls: ['https://www.douban.com/accounts/logout']
urls: ['https://www.douban.com/']
};
session.webRequest.onCompleted(filter, (details:any) => {
log.info('已请求登出成功:');
if (details.statusCode == 200) {
this.settingsManager.updateSetting('loginCookiesContent', '');
this.settingsManager.plugin.userComponent.logout();
constructDoubanTokenSettingsUI(containerEl, settingsManager);
this.modal.close();
}
@ -39,7 +38,7 @@ export default class DoubanLogoutModel {
}
async doLogout() {
await this.modal.loadURL('https://www.douban.com/logout');
await this.modal.loadURL('https://www.douban.com/');
}
onClose() {

@ -4,13 +4,13 @@ import {DEFAULT_SETTINGS} from "../../constant/DefaultSettings";
import SettingsManager from "@App/setting/SettingsManager";
import DoubanLoginModel from "@App/component/DoubanLoginModel";
import DoubanLogoutModel from "@App/component/DoubanLogoutModel";
import { log } from "src/utils/Logutil";
import User from "@App/user/User";
export function constructBasicUI(containerEl: HTMLElement, manager: SettingsManager) {
containerEl.createEl('h3', { text: i18nHelper.getMessage('1210') });
// containerEl.createDiv('login-setting', (loginSettingEl) => {
// constructDoubanTokenSettingsUI(loginSettingEl, manager);
// });
containerEl.createDiv('login-setting', async (loginSettingEl) => {
constructDoubanTokenSettingsUI(loginSettingEl, manager);
});
new Setting(containerEl).setName(i18nHelper.getMessage('120501')).then((setting) => {
setting.addMomentFormat((mf) => {
@ -97,16 +97,16 @@ export function constructBasicUI(containerEl: HTMLElement, manager: SettingsMana
}
export function constructDoubanTokenSettingsUI(containerEl: HTMLElement, manager: SettingsManager) {
let cookie = manager.getSetting('loginCookiesContent');
containerEl.empty();
let login = manager.plugin.userComponent.isLogin();
if (Platform.isDesktopApp) {
if(cookie) {
if(login) {
constructHasLoginSettingsUI(containerEl, manager);
}else {
constructLoginSettingsUI(containerEl, manager);
}
} else {
if(cookie) {
if(login) {
showMobileLogout(containerEl, manager);
}else {
showMobileLogin(containerEl, manager);
@ -131,9 +131,16 @@ export function constructLoginSettingsUI(containerEl: HTMLElement, manager: Sett
}
export function constructHasLoginSettingsUI(containerEl: HTMLElement, manager: SettingsManager) {
const user: User = manager.plugin.userComponent.getUser();
let userDom = new DocumentFragment();
userDom.createDiv().innerHTML =
`已登录<br>
ID: <a href="https://www.douban.com/people/${user.id}/">${user.id}</a><br>
昵称: ${user.name}`;
new Setting(containerEl)
.setName('豆瓣用户信息')
.setDesc('已登录')
.setDesc(userDom)
.addButton((button) => {
return button
.setButtonText('登出')
@ -142,6 +149,7 @@ export function constructHasLoginSettingsUI(containerEl: HTMLElement, manager: S
button.setDisabled(true);
const loginModel = new DoubanLogoutModel(containerEl, manager);
await loginModel.doLogout();
button.setDisabled(false);
// manager.updateSetting('loginCookiesContent', '');
});
});

@ -22,7 +22,7 @@ export class DoubanSettingTab extends PluginSettingTab {
constructor(app: App, plugin: DoubanPlugin) {
super(app, plugin);
this.plugin = plugin;
this.settingsManager = new SettingsManager(app, plugin);
this.settingsManager = plugin.settingsManager;
}
display(): void {

@ -236,6 +236,17 @@ ${i18nHelper.getMessage('122004')}
<td>${i18nHelper.getMessage('310617')}</th>
<td>${i18nHelper.getMessage('310717')}</th>
</tr>
<tr>
<td>${i18nHelper.getMessage('320108')}</th>
<td>${i18nHelper.getMessage('310118')}</th>
<td>${i18nHelper.getMessage('310218')}</th>
<td>${i18nHelper.getMessage('310318')}</th>
<td>${i18nHelper.getMessage('310418')}</th>
<td>${i18nHelper.getMessage('310518')}</th>
<td>${i18nHelper.getMessage('310618')}</th>
<td>${i18nHelper.getMessage('310718')}</th>
</tr>
</table>`;

11
src/douban/user/User.ts Normal file

@ -0,0 +1,11 @@
export default class User {
uid?: string
name?: string;
avatar?: string;
alt?: string;
id?: string;
type?: string;
url?: string;
imageUrl?: string;
login: boolean;
}

@ -0,0 +1,109 @@
import SettingsManager from "@App/setting/SettingsManager";
import {DoubanPluginSetting} from "@App/setting/model/DoubanPluginSetting";
import DoubanSearchResultSubject from "@App/data/model/DoubanSearchResultSubject";
import {request, RequestUrlParam} from "obsidian";
import {DEFAULT_SETTINGS} from "../../constant/DefaultSettings";
import {CheerioAPI, load} from "cheerio";
import SearchParserHandler from "@App/data/search/SearchParser";
import {log} from "../../utils/Logutil";
import {i18nHelper} from "../../lang/helper";
import User from "@App/user/User";
import DoubanGameSubject from "@App/data/model/DoubanGameSubject";
export default class UserComponent {
private settingsManager: SettingsManager;
private user: User;
constructor(settingsManager: SettingsManager) {
this.settingsManager = settingsManager;
}
getUser() {
return this.user;
}
isLogin() {
return this.user && this.user.login;
}
logout() {
if (this.user) {
this.user.login = false;
}
this.user = null;
this.settingsManager.updateSetting('loginCookiesContent', '');
}
needLogin() {
const cookie:any = this.settingsManager.getSetting('loginCookiesContent') ;
if(!cookie) {
return false;
}
return !this.isLogin();
}
async loginByCookie():Promise<User> {
let cookie = this.settingsManager.getSetting('loginCookiesContent');
if(!cookie) {
return new User();
}
await this.loadUserInfo(cookie).then(user => {
this.user = user;
});
return this.user;
}
async loginCookie(cookie: any):Promise<User> {
if(!cookie) {
return new User();
}
await this.loadUserInfo(cookie).then(user => {
this.user = user;
});
this.settingsManager.updateSetting('loginCookiesContent', cookie);
return this.user;
}
async loadUserInfo(cookie: any): Promise<User> {
let requestUrlParam: RequestUrlParam = {
url: 'https://www.douban.com/mine/',
method: "GET",
headers: {'Cookie': cookie},
throw: true
};
return request(requestUrlParam)
.then(load)
.then(this.getUserInfo)
.catch(e => log.error(i18nHelper.getMessage('130101')))
;
};
private getUserInfo(dataHtml: CheerioAPI): User {
let elements = dataHtml("#db-usr-profile > div.pic > a");
if (!elements) {
return new User();
}
let name = dataHtml(dataHtml("head > title").get(0)).text().trim();
let userUrl = dataHtml(elements.get(0)).attr("href");
let idPattern = /(\d){5,10}/g;
let idP = idPattern.exec(userUrl);
let id = idP ? idP[0] : "";
if (!id) {
return new User();
}
const result: User = {
id: id,
name: name,
url: userUrl,
login: true
}
return result;
};
}

@ -215,6 +215,7 @@ export default {
'310215': `-`,
'310216': `-`,
'310217': `-`,
'310218': `-`,
//电视剧
@ -235,6 +236,7 @@ export default {
'310315': `-`,
'310316': `-`,
'310317': `-`,
'310318': `-`,
@ -256,6 +258,7 @@ export default {
'310415': `barcode:条形码`,
'310416': `-`,
'310417': `-`,
'310418': `-`,
//日记
'310501': `豆瓣ID`,
@ -275,6 +278,7 @@ export default {
'310515': `-`,
'310516': `-`,
'310517': `-`,
'310518': `-`,
//游戏
'310601': `豆瓣ID`,
@ -294,6 +298,7 @@ export default {
'310615': `-`,
'310616': `-`,
'310617': `-`,
'310618': `-`,
//广播
'310701': `待开发`,
@ -313,6 +318,7 @@ export default {
'310715': `-`,
'310716': `-`,
'310717': `-`,
'310718': `-`,
'320101': `扩展1`,
'320102': `扩展2`,
@ -324,6 +330,7 @@ export default {
'320108': `扩展8`,
'320109': `扩展9`,
'320110': `扩展10`,
'320111': `扩展11`,
'330101': `今日日期`,
'330102': `当前时间`,

@ -212,6 +212,7 @@ export default {
'310115': `subTitle:副标题`,
'310116': `totalPage:页数`,
'310117': `binding:装帧`,
'310118': `producer:出品方`,
//电影
'310201': `豆瓣ID`,
@ -231,6 +232,7 @@ export default {
'310215': `-`,
'310216': `-`,
'310217': `-`,
'310218': `-`,
//电视剧
@ -251,6 +253,7 @@ export default {
'310315': `-`,
'310316': `-`,
'310317': `-`,
'310318': `-`,
@ -272,6 +275,7 @@ export default {
'310415': `barcode:条形码`,
'310416': `-`,
'310417': `-`,
'310418': `-`,
//日记
'310501': `豆瓣ID`,
@ -291,6 +295,7 @@ export default {
'310515': `-`,
'310516': `-`,
'310517': `-`,
'310518': `-`,
//游戏
'310601': `豆瓣ID`,
@ -310,6 +315,7 @@ export default {
'310615': `-`,
'310616': `-`,
'310617': `-`,
'310618': `-`,
//广播
'310701': `待开发`,
@ -329,6 +335,7 @@ export default {
'310715': `-`,
'310716': `-`,
'310717': `-`,
'310718': `-`,
'320101': `扩展1`,
'320102': `扩展2`,
@ -340,6 +347,7 @@ export default {
'320108': `扩展8`,
'320109': `扩展9`,
'320110': `扩展10`,
'320111': `扩展11`,