mirror of
https://github.com/Wanxp/obsidian-douban.git
synced 2026-04-06 01:58:48 +08:00
Compare commits
No commits in common. "master" and "2.2.4" have entirely different histories.
2
.gitignore
vendored
2
.gitignore
vendored
@ -20,5 +20,3 @@ data.json
|
|||||||
|
|
||||||
# Exclude macOS Finder (System Explorer) View States
|
# Exclude macOS Finder (System Explorer) View States
|
||||||
.DS_Store
|
.DS_Store
|
||||||
doc/.vitepress/dist
|
|
||||||
doc/.vitepress/cache
|
|
||||||
|
|||||||
12
README.md
12
README.md
@ -22,7 +22,7 @@
|
|||||||
这是一款[Obsidian](https://obsidian.md/)插件,支持在Obsidian中导入[豆瓣]()中的 _电影、书籍、音乐、电视剧、日记、游戏_
|
这是一款[Obsidian](https://obsidian.md/)插件,支持在Obsidian中导入[豆瓣]()中的 _电影、书籍、音乐、电视剧、日记、游戏_
|
||||||
甚至是 _你标记过的书影音_ , 包含你的评分、观看日期、评论、阅读状态等信息.
|
甚至是 _你标记过的书影音_ , 包含你的评分、观看日期、评论、阅读状态等信息.
|
||||||
|
|
||||||
访问[Get Started/指导手册](https://obsidian-douban.wxp.hk/) 获取更多
|
访问[Get Started/指导手册](https://wanxp.github.io/obsidian-douban/) 获取更多
|
||||||
|
|
||||||
[//]: # (访问[Get Started/指导手册](https://obsidian-douban.wanxuping.com/) 获取更多 )
|
[//]: # (访问[Get Started/指导手册](https://obsidian-douban.wanxuping.com/) 获取更多 )
|
||||||

|

|
||||||
@ -32,7 +32,7 @@
|
|||||||
如果觉得喜欢或对您有帮助,欢迎一键三连-点亮 ⭐Star
|
如果觉得喜欢或对您有帮助,欢迎一键三连-点亮 ⭐Star
|
||||||
|
|
||||||
- [异常, 问题 & 新的想法](https://github.com/Wanxp/obsidian-douban/issues)
|
- [异常, 问题 & 新的想法](https://github.com/Wanxp/obsidian-douban/issues)
|
||||||
- 阅读其它语言的介绍请点击 [English](README.en.md) | 简体中文
|
- 阅读其它语言的介绍请点击 [English](./doc/README.en.md) | 简体中文
|
||||||
|
|
||||||
## 功能
|
## 功能
|
||||||
- ☑️ 导入电影、电视剧、书籍、音乐、游戏、日记
|
- ☑️ 导入电影、电视剧、书籍、音乐、游戏、日记
|
||||||
@ -42,7 +42,6 @@
|
|||||||
- ⬜ 支持图床自定义
|
- ⬜ 支持图床自定义
|
||||||
- ☑️ 支持自定义参数
|
- ☑️ 支持自定义参数
|
||||||
- ☑️ 支持移动端导入
|
- ☑️ 支持移动端导入
|
||||||
- ⬜ 支持使用AI大模型ChatGPT、Deepseek、Ollama分析导入
|
|
||||||
|
|
||||||
## 效果
|
## 效果
|
||||||
1. 结合Timeline插件 __构建个人观影时间线__,请参照[结合timeline插件实现时间线效果](./doc/Obsidian-Douban-TimeLine.md)
|
1. 结合Timeline插件 __构建个人观影时间线__,请参照[结合timeline插件实现时间线效果](./doc/Obsidian-Douban-TimeLine.md)
|
||||||
@ -121,7 +120,7 @@
|
|||||||
3. 在obsidian插件中心开启当前插件功能
|
3. 在obsidian插件中心开启当前插件功能
|
||||||
|
|
||||||
## 如何开发调试
|
## 如何开发调试
|
||||||
### 开发
|
|
||||||
1. 进入你的Obsidian测试文档文件夹下的`/.obsidian/plugins/`
|
1. 进入你的Obsidian测试文档文件夹下的`/.obsidian/plugins/`
|
||||||
2. 克隆代码
|
2. 克隆代码
|
||||||
`git clone git@github.com:Wanxp/obsidian-douban.git`
|
`git clone git@github.com:Wanxp/obsidian-douban.git`
|
||||||
@ -135,10 +134,7 @@
|
|||||||
`npm run dev`
|
`npm run dev`
|
||||||
7. 进入Obsidian插件中心重新加载当前插件
|
7. 进入Obsidian插件中心重新加载当前插件
|
||||||
8. 享受开发吧
|
8. 享受开发吧
|
||||||
#### 文档
|
|
||||||
```shell
|
|
||||||
npm run docs:dev
|
|
||||||
```
|
|
||||||
## 支持开发者
|
## 支持开发者
|
||||||
如果觉得插件对你有帮助,欢迎请我喝杯咖啡,让我有更多的动力去维护和更新插件
|
如果觉得插件对你有帮助,欢迎请我喝杯咖啡,让我有更多的动力去维护和更新插件
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +0,0 @@
|
|||||||
编写github action ,完成以下目标:
|
|
||||||
1. 当文件mainfest.json文件发生变更时才运行
|
|
||||||
2. 提供node18 环境
|
|
||||||
3. 执行npm install
|
|
||||||
4. 执行npm run build
|
|
||||||
5. 提取 package.json中的版本
|
|
||||||
6. 将当前master创建为版本的tag
|
|
||||||
7. 发布到github release 预发布版本,且版本的名称为当前版本
|
|
||||||
8. 发布的信息从commit中提取
|
|
||||||
9. 发布的内容为生成的main.js、mainfest.json、style.css 三个文件
|
|
||||||
10. 输出内容: 发布预发布版本{版本}正常
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
import { defineConfig } from 'vitepress'
|
|
||||||
|
|
||||||
// https://vitepress.dev/reference/site-config
|
|
||||||
export default defineConfig({
|
|
||||||
title: "Obsidian Douban",
|
|
||||||
description: "Plugin for obsidian to manage your douban data",
|
|
||||||
themeConfig: {
|
|
||||||
lang: 'zh-CN',
|
|
||||||
search: {
|
|
||||||
provider: 'local'
|
|
||||||
},
|
|
||||||
// https://vitepress.dev/reference/default-theme-config
|
|
||||||
logo: '/obsidian-douban-logo.png',
|
|
||||||
nav: [
|
|
||||||
{ text: '首页', link: '/' },
|
|
||||||
{ text: '特殊效果', items: [
|
|
||||||
{ text: '时间线效果', link: '/Obsidian-Douban-TimeLine' },
|
|
||||||
{ text: '类网页效果', link: '/Obsidian-Douban-BlueTopaz' },
|
|
||||||
{ text: '书架效果', link: 'Obsidian-Douban-DataView-Jump' }
|
|
||||||
] },
|
|
||||||
{ text: '作者', link: 'https://wxp.hk' },
|
|
||||||
],
|
|
||||||
|
|
||||||
sidebar: [
|
|
||||||
{
|
|
||||||
text: '如何安装', link: '/10_install'
|
|
||||||
},
|
|
||||||
{ text: '使用说明', link: '/20_howtouse_10_detail' },
|
|
||||||
{ text: '登录方式', link: '/20_howtouse_25_setting_login_douban_cookie' },
|
|
||||||
{ text: '图床配置', link: '/20_howtouse_30_picturebed' },
|
|
||||||
{ text: '功能支持', link: '/30_function_10' },
|
|
||||||
{ text: '可用参数', link: '/30_function_20_support_variables' },
|
|
||||||
{ text: '时间线效果', link: '/Obsidian-Douban-TimeLine' },
|
|
||||||
{ text: '类网页效果', link: '/Obsidian-Douban-BlueTopaz' },
|
|
||||||
{ text: '书架效果', link: 'Obsidian-Douban-DataView-Jump' },
|
|
||||||
{ text: '数据影响', link: '/80_others_20_effect' },
|
|
||||||
{ text: '免责声明', link: '/80_others_disclaimer' },
|
|
||||||
{ text: '开发调试', link: '/70_develop' },
|
|
||||||
{ text: '反馈建议', link: '/97_issues' },
|
|
||||||
{ text: '支持作者', link: '/99_support' },
|
|
||||||
|
|
||||||
|
|
||||||
],
|
|
||||||
socialLinks: [
|
|
||||||
{ icon: 'github', link: 'https://github.com/Wanxp/obsidian-douban' },
|
|
||||||
// { icon: 'blog', link: 'https://github.com/Wanxp/obsidian-douban' }
|
|
||||||
],
|
|
||||||
lastUpdated: {
|
|
||||||
text: '最后更新于',
|
|
||||||
formatOptions: {
|
|
||||||
dateStyle: 'full',
|
|
||||||
timeStyle: 'medium'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
:root {
|
|
||||||
--vp-c-brand-1: #646cff;
|
|
||||||
--vp-c-brand-2: #747bff;
|
|
||||||
--vp-home-hero-name-color: transparent;
|
|
||||||
--vp-home-hero-name-background: -webkit-linear-gradient(120deg, #34fe48, #bd34fe);
|
|
||||||
--vp-home-hero-image-background-image: linear-gradient( 135deg, #34fe48 10%, #bd34fe 100%);
|
|
||||||
--vp-home-hero-image-filter: blur(80px);
|
|
||||||
/*--vp-home-hero-image-background-image: linear-gradient(*/
|
|
||||||
/* -45deg,*/
|
|
||||||
/* #34fe48 50%,*/
|
|
||||||
/* #bd34fe 50%*/
|
|
||||||
/*);*/
|
|
||||||
/*--vp-home-hero-image-filter: blur(44px);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
import DefaultTheme from 'vitepress/theme'
|
|
||||||
import './custom.css'
|
|
||||||
|
|
||||||
|
|
||||||
export default DefaultTheme
|
|
||||||
@ -1,15 +1,17 @@
|
|||||||
---
|
---
|
||||||
title: 如何安装
|
title: 如何安装
|
||||||
|
layout: default
|
||||||
nav_order: 200
|
nav_order: 200
|
||||||
---
|
---
|
||||||
# 如何安装
|
|
||||||
## 从Obsidian插件中心
|
## 如何安装
|
||||||
|
### 从Obsidian插件中心
|
||||||
1. 进入Obsidian插件中心
|
1. 进入Obsidian插件中心
|
||||||
2. 搜索obsidian-douban
|
2. 搜索obsidian-douban
|
||||||
3. 安装
|
3. 安装
|
||||||
4. 开启插件
|
4. 开启插件
|
||||||
|
|
||||||
## 手动安装
|
### 手动安装
|
||||||
|
|
||||||
1. 从[Github release](https://github.com/Wanxp/obsidian-douban/releases) 页面下载 `main.js`, `manifest.json`, `styles.css`
|
1. 从[Github release](https://github.com/Wanxp/obsidian-douban/releases) 页面下载 `main.js`, `manifest.json`, `styles.css`
|
||||||
2. 将下载的文件复制到你的Obsidian文档根目录下的`/.obsidian/plugins/obsidian-douban`路径,若不存在则新建文件夹(注意.obsidian文件夹可能是个隐藏为文件夹)
|
2. 将下载的文件复制到你的Obsidian文档根目录下的`/.obsidian/plugins/obsidian-douban`路径,若不存在则新建文件夹(注意.obsidian文件夹可能是个隐藏为文件夹)
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
---
|
---
|
||||||
title: 使用说明
|
title: 使用说明
|
||||||
|
layout: default
|
||||||
nav_order: 300
|
nav_order: 300
|
||||||
parent: 如何使用
|
parent: 如何使用
|
||||||
---
|
---
|
||||||
# 如何使用
|
## 如何使用
|
||||||
# 搜索
|
## 搜索
|
||||||
使用方式: 输入<kbd>Ctrl</kbd> + <kbd>P</kbd>,输入“豆瓣”或“Douban”,选择搜索并使用
|
使用方式: 输入<kbd>Ctrl</kbd> + <kbd>P</kbd>,输入“豆瓣”或“Douban”,选择搜索并使用
|
||||||
- 搜索数据并创建笔记
|
- 搜索数据并创建笔记
|
||||||
- 通过当前文件名搜索
|
- 通过当前文件名搜索
|
||||||
@ -12,6 +13,6 @@ parent: 如何使用
|
|||||||

|

|
||||||
|
|
||||||
|
|
||||||
# 同步
|
## 同步
|
||||||
- 同步个人的观影、观剧、阅读、游戏、音乐记录
|
- 同步个人的观影、观剧、阅读、游戏、音乐记录
|
||||||

|

|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
---
|
---
|
||||||
title: 设置
|
title: 设置
|
||||||
|
layout: default
|
||||||
nav_order: 350
|
nav_order: 350
|
||||||
parent: 如何使用
|
parent: 如何使用
|
||||||
---
|
---
|
||||||
|
|
||||||
# 设置
|
## 设置
|
||||||
- 设置豆瓣账号(可选,可使用少部分功能)
|
- 设置豆瓣账号(可选,可使用少部分功能)
|
||||||
- 设置导入模板(可选,不设置的情况下使用默认模板)
|
- 设置导入模板(可选,不设置的情况下使用默认模板)
|
||||||
- 设置导入路径(可选,不设置的情况下使用默认路径)
|
- 设置导入路径(可选,不设置的情况下使用默认路径)
|
||||||
|
|||||||
@ -1,17 +1,10 @@
|
|||||||
---
|
---
|
||||||
title: Cookie登录Douban
|
title: Cookie登录Douban
|
||||||
|
layout: default
|
||||||
nav_order: 350
|
nav_order: 350
|
||||||
parent: 如何使用
|
parent: 如何使用
|
||||||
---
|
---
|
||||||
# 登录方式
|
|
||||||
Obsidian-Douban插件提供了两种登录方式,扫码登录和Cookie登录。扫码登录是推荐的方式,但如果扫码登录失败,可以使用Cookie登录。
|
|
||||||
## 扫码登录
|
|
||||||
扫码登录是Obsidian-Douban插件的默认登录方式,适用于大多数用户。扫码登录的步骤如下:
|
|
||||||
1. 在Obsidian-Douban插件设置中点击`登录按钮`
|
|
||||||
2. 弹出扫码登录窗口
|
|
||||||
3. 使用手机或其他设备的豆瓣APP 扫描二维码
|
|
||||||
4. 在手机上确认登录
|
|
||||||
5. 登录成功后,Obsidian-Douban插件会自动获取您的豆瓣账号信息
|
|
||||||
## Cookie登录Douban
|
## Cookie登录Douban
|
||||||
此方式仅在Obsidian-Douban中点击`登录按钮`,弹窗后,扫码登录失败的用户
|
此方式仅在Obsidian-Douban中点击`登录按钮`,弹窗后,扫码登录失败的用户
|
||||||
### 操作
|
### 操作
|
||||||
|
|||||||
@ -1,21 +1,22 @@
|
|||||||
---
|
---
|
||||||
title: 图床
|
title: 图床
|
||||||
|
layout: default
|
||||||
nav_order: 380
|
nav_order: 380
|
||||||
parent: 如何使用
|
parent: 如何使用
|
||||||
---
|
---
|
||||||
|
|
||||||
# 图床
|
## 图床
|
||||||
## PicGo
|
### PicGo
|
||||||
### 设置步骤
|
#### 设置步骤
|
||||||
1. 安装并下载PicGo图床软件
|
1. 安装并下载PicGo图床软件
|
||||||
2. 设置PicGo图床
|
2. 设置PicGo图床
|
||||||
3. (由于Obsidian-Douban是通过剪贴板上传图片的)需要在PicGo设置中开启剪贴板上传
|
3. (由于Obsidian-Douban是通过剪贴板上传图片的)需要在PicGo设置中开启剪贴板上传
|
||||||
4. 需要设置Server,开启并设置 端口36677
|
4. 需要设置Server,开启并设置 端口36677
|
||||||
5. 设置完成之后,可以尝试点击PicGo主界面的`剪贴板上传`按钮,验证是否可以上传图片
|
5. 设置完成之后,可以尝试点击PicGo主界面的`剪贴板上传`按钮,验证是否可以上传图片
|
||||||
6. 若在Obsidian-Douban设置中使用PicGo上传图片至图床,则每次导入书影音数据前,需要保证提前打开了PicGo软件
|
6. 若在Obsidian-Douban设置中使用PicGo上传图片至图床,则每次导入书影音数据前,需要保证提前打开了PicGo软件
|
||||||
### 注意事项
|
#### 注意事项
|
||||||
Obsidian-Douban插件使用PicGo上传图片至图床仅在Linux系统下测试通过,其他系统未测试,其它系统有问题欢迎及时反馈
|
Obsidian-Douban插件使用PicGo上传图片至图床仅在Linux系统下测试通过,其他系统未测试,其它系统有问题欢迎及时反馈
|
||||||
#### Linux
|
##### Linux
|
||||||
1. x11图形界面下,还需要安装xclip软件,否则无法使用剪贴板上传图片
|
1. x11图形界面下,还需要安装xclip软件,否则无法使用剪贴板上传图片
|
||||||
2. wayland图形界面下, 还需要安装wl-clipboard软件,否则无法使用剪贴板上传图片
|
2. wayland图形界面下, 还需要安装wl-clipboard软件,否则无法使用剪贴板上传图片
|
||||||
3. 若无法上传图片,可尝试开启PicGo软件设置中的`使用内置剪贴板上传`选项
|
3. 若无法上传图片,可尝试开启PicGo软件设置中的`使用内置剪贴板上传`选项
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
---
|
---
|
||||||
title: 基础功能
|
title: 基础功能
|
||||||
|
layout: default
|
||||||
nav_order: 400
|
nav_order: 400
|
||||||
parent: 功能
|
parent: 功能
|
||||||
---
|
---
|
||||||
# 功能
|
## 功能
|
||||||
- ☑️ 导入电影、电视剧、书籍、音乐、游戏、日记
|
- ☑️ 导入电影、电视剧、书籍、音乐、游戏、日记
|
||||||
- ☑️ 同步个人听过/看过的电影、电视剧、书籍、音乐、游戏
|
- ☑️ 同步个人听过/看过的电影、电视剧、书籍、音乐
|
||||||
- ☑️ 导入个人的评论,评论时间,阅读状态,个人评分
|
- ☑️ 导入个人的评论,评论时间,阅读状态,个人评分
|
||||||
- ☑️ 支持保存封面至本地/图床
|
- ☑️ 支持保存封面至本地
|
||||||
- ⬜ 支持图床自定义
|
|
||||||
- ☑️ 支持自定义参数
|
- ☑️ 支持自定义参数
|
||||||
- ☑️ 支持移动端导入
|
|
||||||
- ⬜ 支持使用AI大模型ChatGPT、Deepseek、Ollama分析导入
|
|
||||||
@ -1,10 +1,11 @@
|
|||||||
---
|
---
|
||||||
title: 支持的参数
|
title: 支持的参数
|
||||||
|
layout: default
|
||||||
nav_order: 500
|
nav_order: 500
|
||||||
parent: 功能
|
parent: 功能
|
||||||
---
|
---
|
||||||
|
|
||||||
# 支持的字段
|
## 支持的字段
|
||||||
(若有缺少想导入的字段, 欢迎提issues反馈)
|
(若有缺少想导入的字段, 欢迎提issues反馈)
|
||||||
|
|
||||||
| 字段 | 电影 | 电视剧 | 书籍 | 音乐 | 日记 | 游戏 | 人物 |
|
| 字段 | 电影 | 电视剧 | 书籍 | 音乐 | 日记 | 游戏 | 人物 |
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
---
|
---
|
||||||
title: 效果介绍
|
title: 效果介绍
|
||||||
|
layout: default
|
||||||
nav_order: 450
|
nav_order: 450
|
||||||
parent: 特殊效果
|
parent: 特殊效果
|
||||||
---
|
---
|
||||||
|
|
||||||
# 效果
|
## 效果
|
||||||
1. 结合Timeline插件 __构建个人观影时间线__,请参照[结合timeline插件实现时间线效果](Obsidian-Douban-TimeLine)
|
1. 结合Timeline插件 __构建个人观影时间线__,请参照[结合timeline插件实现时间线效果](Obsidian-Douban-TimeLine)
|
||||||

|

|
||||||
<!--2. 结合DataView插件,__构建个人电子书架(书库数据)__,请参照[结合dateview插件实现个人书架效果](Obsidian-Douban-DataView.md))-->
|
<!--2. 结合DataView插件,__构建个人电子书架(书库数据)__,请参照[结合dateview插件实现个人书架效果](Obsidian-Douban-DataView.md))-->
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
---
|
---
|
||||||
title: 开发
|
title: 开发
|
||||||
|
layout: default
|
||||||
nav_order: 700
|
nav_order: 700
|
||||||
---
|
---
|
||||||
|
|
||||||
# 如何开发调试
|
## 如何开发调试
|
||||||
|
|
||||||
1. 进入你的Obsidian测试文档文件夹下的`/.obsidian/plugins/`
|
1. 进入你的Obsidian测试文档文件夹下的`/.obsidian/plugins/`
|
||||||
2. 克隆代码
|
2. 克隆代码
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
---
|
---
|
||||||
title: 数据影响
|
title: 数据影响
|
||||||
|
layout: default
|
||||||
nav_order: 800
|
nav_order: 800
|
||||||
parent: 其它
|
parent: 其它
|
||||||
---
|
---
|
||||||
|
|
||||||
# 数据影响
|
## 数据影响
|
||||||
注意: 除了在同步书影音数据时勾选 `替换同名文档` 有可能会修改同路径同文档名的笔记外,其余操作均不会修改已有笔记。
|
注意: 除了在同步书影音数据时勾选 `替换同名文档` 有可能会修改同路径同文档名的笔记外,其余操作均不会修改已有笔记。
|
||||||
|
|
||||||
| 操作 | 条件 | 影响 | 举例 |
|
| 操作 | 条件 | 影响 | 举例 |
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
---
|
---
|
||||||
title: 鸣谢
|
title: 鸣谢
|
||||||
|
layout: default
|
||||||
nav_order: 810
|
nav_order: 810
|
||||||
parent: 其它
|
parent: 其它
|
||||||
---
|
---
|
||||||
# 鸣谢
|
## 鸣谢
|
||||||
## IDE支持
|
### IDE支持
|
||||||
[<image src="img/jb_beam.svg"> </image>](https://www.jetbrains.com/?from=obsidian-douban)
|
[<image src="img/jb_beam.svg"> </image>](https://www.jetbrains.com/?from=obsidian-douban)
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
---
|
---
|
||||||
title: 免责声明
|
title: 免责声明
|
||||||
|
layout: default
|
||||||
nav_order: 820
|
nav_order: 820
|
||||||
parent: 其它
|
parent: 其它
|
||||||
---
|
---
|
||||||
|
|
||||||
# 免责声明
|
## 免责声明
|
||||||
1. 建议使用本插件前,一定要至少有一种方式备份你的数据,以防万一。
|
1. 建议使用本插件前,一定要至少有一种方式备份你的数据,以防万一。
|
||||||
2. 本程序没有爬取任何书影音等内容,只供技术研究使用。没有侵犯书影音作者版权和豆瓣官方利益。如有任何侵权行为,请联系我删除。
|
2. 本程序没有爬取任何书影音等内容,只供技术研究使用。没有侵犯书影音作者版权和豆瓣官方利益。如有任何侵权行为,请联系我删除。
|
||||||
3. 本程序仅供学习交流使用。
|
3. 本程序仅供学习交流使用。
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
---
|
---
|
||||||
title: 反馈与建议
|
title: 反馈与建议
|
||||||
|
layout: default
|
||||||
nav_order: 950
|
nav_order: 950
|
||||||
---
|
---
|
||||||
|
|
||||||
# 反馈与建议
|
## 反馈与建议
|
||||||
如果你有任何问题或建议,欢迎在提交[Issues](https://github.com/Wanxp/obsidian-douban/issues)
|
如果你有任何问题或建议,欢迎在提交[Issues](https://github.com/Wanxp/obsidian-douban/issues)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,17 +1,18 @@
|
|||||||
---
|
---
|
||||||
title: 支持
|
title: 支持
|
||||||
|
layout: default
|
||||||
nav_order: 1000
|
nav_order: 1000
|
||||||
---
|
---
|
||||||
|
|
||||||
# 支持
|
## 支持
|
||||||
愿世界充满爱与和平!
|
愿世界充满爱与和平!
|
||||||
如果觉得喜欢或对您有帮助,欢迎请我喝杯咖啡,让我有更多的动力去维护和更新插件
|
如果觉得喜欢或对您有帮助,欢迎请我喝杯咖啡,让我有更多的动力去维护和更新插件
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## 交流社群
|
## 交流社群
|
||||||
<img src="/img/obsidian-douban-qq-qr_code.svg" width="300px" style="display: inline-block;"><img src="/img/wechat_group.png" width="245px" style="display: inline-block;">
|
<img src="img/obsidian-douban-qq-qr_code.svg" width="300px">
|
||||||
|
<img src="img/wechat_group.png" width="245px">
|
||||||
|
|
||||||
或者[邮件联系我](mailto:977741432@qq.com)
|
或者[邮件联系我](mailto:977741432@qq.com)
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
gem "jekyll" # installed by `gem jekyll`
|
gem "jekyll", "~> 4.3.3" # installed by `gem jekyll`
|
||||||
# gem "webrick" # required when using Ruby >= 3 and Jekyll <= 4.2.2
|
# gem "webrick" # required when using Ruby >= 3 and Jekyll <= 4.2.2
|
||||||
|
|
||||||
gem "just-the-docs" # pinned to the current release
|
gem "just-the-docs", "0.8.2" # pinned to the current release
|
||||||
# gem "just-the-docs" # always download the latest release
|
# gem "just-the-docs" # always download the latest release
|
||||||
|
|
||||||
gem 'json'
|
gem 'json'
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: 类豆瓣网页显示
|
title: 类豆瓣网页显示
|
||||||
|
layout: default
|
||||||
nav_order: 455
|
nav_order: 455
|
||||||
parent: 特殊效果
|
parent: 特殊效果
|
||||||
render_with_liquid: false
|
render_with_liquid: false
|
||||||
|
|||||||
@ -1,3 +0,0 @@
|
|||||||
## 书架效果
|
|
||||||
点击以下链接跳转至少数派
|
|
||||||
[使用Obsidian打造个人图书馆!](https://sspai.com/post/85574)
|
|
||||||
70
doc/Obsidian-Douban-TimeLine.en.md
Normal file
70
doc/Obsidian-Douban-TimeLine.en.md
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
## 效果如下
|
||||||
|

|
||||||
|
## 适用人群
|
||||||
|
1. 在豆瓣有标记/评论/评分的习惯的人
|
||||||
|
比如看完电影,会在豆瓣进行评分或评论。或者阅读完的书籍,进行评分或评论。支持包含:电影、书籍、电视剧、音乐、游戏
|
||||||
|
## 实现步骤
|
||||||
|
1. 安装[Timeline](https://github.com/Darakah/obsidian-timelines)插件
|
||||||
|
2. 安装[Obsidian-Douban](https://github.com/Wanxp/obsidian-douban)插件(本插件)
|
||||||
|
3. 在Obsidian-Douban插件配置中登录Douban
|
||||||
|
4. 配置同步需要的模板 电影/书籍的模板中的frontmatter,在frontmatter中 **增加** 特定tags(根据自己的需要指定),用于需要过滤成为timeline的笔记,如增加tags:`我看过的电影`
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
tags: 我看过的电影
|
||||||
|
---
|
||||||
|
````
|
||||||
|
5. 同时,在电影/书籍... 模板中的 **最后增加** timeline插件需要的html标签如下:
|
||||||
|
```html
|
||||||
|
<span class='ob-timelines' data-date='{{myCollectionDate}}'
|
||||||
|
data-title='{{title}}' data-img='{{image}}'
|
||||||
|
data-class = "custom-my-movie-time-line">{{myComment}} |简介: {{desc}}
|
||||||
|
</span>
|
||||||
|
```
|
||||||
|
6. 选择上述模板导入 电影/书籍...,操作方式是打开obsidian命令窗口,输入豆瓣,找到导入功能,在导入界面配置 选择模板进行导入
|
||||||
|
7. 导入需要一定时间,每条内容导入需要15-30s左右,所有有导入完成后会有导入汇总
|
||||||
|
8. 导入完成后,新建一个笔记,笔记内容加入timeline的代码块,代码块的内容就是你上面指定的tags的内容,如`我看过的电影`,代码块如下:
|
||||||
|
````markdown
|
||||||
|
```timeline
|
||||||
|
我看过的电影
|
||||||
|
```
|
||||||
|
````
|
||||||
|
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}}
|
||||||
|
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)
|
||||||
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: 看剧时间线
|
title: 看剧时间线
|
||||||
|
layout: default
|
||||||
nav_order: 456
|
nav_order: 456
|
||||||
parent: 特殊效果
|
parent: 特殊效果
|
||||||
render_with_liquid: false
|
render_with_liquid: false
|
||||||
|
|||||||
@ -21,13 +21,13 @@
|
|||||||
|
|
||||||
Bring your data from [Douban]() to Your [Obsidian](https://obsidian.md/)
|
Bring your data from [Douban]() to Your [Obsidian](https://obsidian.md/)
|
||||||
Including your _Movie, Book, Music, Teleplay, Note, Game_ even your personal State and Comment
|
Including your _Movie, Book, Music, Teleplay, Note, Game_ even your personal State and Comment
|
||||||

|

|
||||||
|
|
||||||
---
|
---
|
||||||
If you want some features or have any questions about this plugin, create issues or join the development is welcome or ⭐Star
|
If you want some features or have any questions about this plugin, create issues or join the development is welcome or ⭐Star
|
||||||
|
|
||||||
- [Bugs, Issues, & Feature Requests](https://github.com/Wanxp/obsidian-douban/issues)
|
- [Bugs, Issues, & Feature Requests](https://github.com/Wanxp/obsidian-douban/issues)
|
||||||
- Read Other Languages: English | [简体中文](README.md)
|
- Read Other Languages: English | [简体中文](../README.md)
|
||||||
|
|
||||||
## Target
|
## Target
|
||||||
- [x] Sync Personal Movie/TV/Book/Music
|
- [x] Sync Personal Movie/TV/Book/Music
|
||||||
@ -36,23 +36,23 @@ If you want some features or have any questions about this plugin, create issues
|
|||||||
- [x] Custom Variables
|
- [x] Custom Variables
|
||||||
|
|
||||||
## 效果
|
## 效果
|
||||||
1. 结合Timeline插件 __构建个人观影时间线__,请参照[结合timeline插件实现时间线效果](doc/Obsidian-Douban-TimeLine.md)
|
1. 结合Timeline插件 __构建个人观影时间线__,请参照[结合timeline插件实现时间线效果](./Obsidian-Douban-TimeLine.md)
|
||||||

|

|
||||||
<!--2. 结合DataView插件,__构建个人电子书架(书库数据)__,请参照[结合dateview插件实现个人书架效果](./doc/Obsidian-Douban-DataView.md))-->
|
<!--2. 结合DataView插件,__构建个人电子书架(书库数据)__,请参照[结合dateview插件实现个人书架效果](./doc/Obsidian-Douban-DataView.md))-->
|
||||||
2. 结合主题 __构建类豆瓣网页效果__,请参照[结合Blue Topaz实现网页效果](doc/Obsidian-Douban-BlueTopaz.md)
|
2. 结合主题 __构建类豆瓣网页效果__,请参照[结合Blue Topaz实现网页效果](./Obsidian-Douban-BlueTopaz.md)
|
||||||

|

|
||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
### Sync
|
### Sync
|
||||||
- Sync Data From Douban
|
- Sync Data From Douban
|
||||||
Sync data from Douban (to learn how to use the TimeLine plugin to build a reading/movie watching timeline, please refer to [here](Obsidian-Douban-TimeLine.en.md)).
|
Sync data from Douban (to learn how to use the TimeLine plugin to build a reading/movie watching timeline, please refer to [here](Obsidian-Douban-TimeLine.en.md)).
|
||||||

|

|
||||||
### Search
|
### Search
|
||||||
Use the following method: Enter <kbd>Ctrl</kbd> + <kbd>P</kbd>, enter "Douban", select search and use
|
Use the following method: Enter <kbd>Ctrl</kbd> + <kbd>P</kbd>, enter "Douban", select search and use
|
||||||
- Search Data And Create Note
|
- Search Data And Create Note
|
||||||
- Search Data By File Name
|
- Search Data By File Name
|
||||||
- Search Movie By Input Text
|
- Search Movie By Input Text
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## Support Field
|
## Support Field
|
||||||
@ -119,7 +119,9 @@ Use the following method: Enter <kbd>Ctrl</kbd> + <kbd>P</kbd>, enter "Douban",
|
|||||||
7. Enjoy your develop
|
7. Enjoy your develop
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
<img src="doc/img/obsidian-douban-qq-qr_code.svg" width="300px"> <img src="doc/img/wechat_group.png" width="245px">
|
<img src="img/obsidian-douban-qq-qr_code.svg" width="300px">
|
||||||
|
<img src="https://picture-bed-public.wanxuping.com/obsidian-douban/wechat_group.png" width="245px">
|
||||||
|
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
1. This program does not crawl any content such as books and videos, and is only for technical research purposes. It does not violate the copyright of authors of books and videos or the official interests of Douban. If there is any infringement, please contact me to delete it.
|
1. This program does not crawl any content such as books and videos, and is only for technical research purposes. It does not violate the copyright of authors of books and videos or the official interests of Douban. If there is any infringement, please contact me to delete it.
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 27 KiB |
79
doc/index.md
79
doc/index.md
@ -1,34 +1,53 @@
|
|||||||
---
|
---
|
||||||
# https://vitepress.dev/reference/default-theme-home-page
|
title: 简介
|
||||||
layout: home
|
layout: home
|
||||||
|
nav_order: 10
|
||||||
hero:
|
|
||||||
name: "Obsidian Douban"
|
|
||||||
text: "obsidian插件\n同步你的豆瓣书影音"
|
|
||||||
tagline:
|
|
||||||
image:
|
|
||||||
src: /obsidian-douban-logo.png
|
|
||||||
alt: Obsidian Douban Logo
|
|
||||||
actions:
|
|
||||||
- theme: brand
|
|
||||||
text: 开始使用
|
|
||||||
link: /20_howtouse_10_detail
|
|
||||||
- theme: alt
|
|
||||||
text: 安装
|
|
||||||
link: /10_install
|
|
||||||
|
|
||||||
features:
|
|
||||||
- title: 搜索导入影音
|
|
||||||
icon: 📘
|
|
||||||
details: 搜索豆瓣中您喜欢的电影、电视剧、书籍、音乐、游戏等信息结构化并导入到Obsidian中
|
|
||||||
link: /20_howtouse_10_detail
|
|
||||||
- title: 同步个人数据
|
|
||||||
icon: 🙋
|
|
||||||
details: 登录后可同步个人的观影、观剧、阅读、游戏、音乐记录到您的Obsidian中
|
|
||||||
link: /20_howtouse_10_detail
|
|
||||||
- title: 建立个人书架
|
|
||||||
icon: 📚
|
|
||||||
details: 结合DataView生成,整合你的书籍,建立个人书架,统一管理
|
|
||||||
link: /Obsidian-Douban-DataView-Jump
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
|
这是一款[Obsidian](https://obsidian.md/)的插件, 用于导入[豆瓣](https://www.douban.com/)中的 _电影、书籍、音乐、电视剧、日记、游戏
|
||||||
|
甚至是你标记过的书影音, 包含你的评分、观看日期、评论、阅读状态等信息.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 基本功能
|
||||||
|
- ☑️ 导入电影、电视剧、书籍、音乐、游戏、日记
|
||||||
|
- ☑️ 同步个人听过/看过的电影、电视剧、书籍、音乐、游戏
|
||||||
|
- ☑️ 导入个人的评论,评论时间,阅读状态,个人评分
|
||||||
|
- ☑️ 支持保存封面至本地/图床
|
||||||
|
- ⬜ 支持图床自定义
|
||||||
|
- ☑️ 支持自定义参数
|
||||||
|
- ☑️ 支持移动端导入
|
||||||
|
|
||||||
|
## 支持
|
||||||
|
如果觉得喜欢或对您有帮助,欢迎请我喝杯咖啡,让我有更多的动力去维护和更新插件
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 交流社群
|
||||||
|
<img src="img/obsidian-douban-qq-qr_code.svg" width="300px">
|
||||||
|
<img src="img/wechat_group.png" width="245px">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/Wanxp/obsidian-douban/releases/latest">
|
||||||
|
<img src="https://img.shields.io/github/manifest-json/v/Wanxp/obsidian-douban?color=blue">
|
||||||
|
</a>
|
||||||
|
<img src="https://img.shields.io/github/release-date/Wanxp/obsidian-douban">
|
||||||
|
<a href="https://github.com/Wanxp/obsidian-douban/blob/master/License">
|
||||||
|
<img src="https://img.shields.io/github/license/Wanxp/obsidian-douban">
|
||||||
|
</a>
|
||||||
|
<img src="https://img.shields.io/github/downloads/Wanxp/obsidian-douban/total">
|
||||||
|
<a href="https://github.com/Wanxp/obsidian-douban/issues">
|
||||||
|
<img src="https://img.shields.io/github/issues/Wanxp/obsidian-douban">
|
||||||
|
</a>
|
||||||
|
<br>
|
||||||
|
<img src="https://img.shields.io/tokei/lines/github/Wanxp/obsidian-douban">
|
||||||
|
<a href="https://www.codefactor.io/repository/github/wanxp/obsidian-douban">
|
||||||
|
<img src="https://www.codefactor.io/repository/github/wanxp/obsidian-douban/badge" alt="CodeFactor" />
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
[Just the Docs repo]: https://github.com/Wanxp/obsidian-douban
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 780 KiB |
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"id": "obsidian-douban-plugin",
|
"id": "obsidian-douban-plugin",
|
||||||
"name": "Douban",
|
"name": "Douban",
|
||||||
"version": "2.3.2",
|
"version": "2.2.4",
|
||||||
"minAppVersion": "0.12.0",
|
"minAppVersion": "0.12.0",
|
||||||
"description": "This is a plugin that can import movies/books/musics/notes/games info data from Douban for Obsidian .",
|
"description": "This is a plugin that can import movies/books/musics/notes/games info data from Douban for Obsidian .",
|
||||||
"author": "Wanxp",
|
"author": "Wanxp",
|
||||||
|
|||||||
9428
package-lock.json
generated
Normal file
9428
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@ -1,16 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "obsidian-douban-plugin",
|
"name": "obsidian-douban-plugin",
|
||||||
"version": "2.3.2",
|
"version": "2.2.4",
|
||||||
"description": "This is a plugin for Obsidian (https://obsidian.md) that can import data from Douban (https://www.douban.com/).",
|
"description": "This is a plugin for Obsidian (https://obsidian.md) that can import data from Douban (https://www.douban.com/).",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "node esbuild.config.mjs",
|
"dev": "node esbuild.config.mjs",
|
||||||
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
|
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
|
||||||
"version": "node version-bump.mjs && git add manifest.json versions.json",
|
"version": "node version-bump.mjs && git add manifest.json versions.json",
|
||||||
"test": "jest",
|
"test": "jest"
|
||||||
"docs:dev": "vitepress dev doc",
|
|
||||||
"docs:build": "vitepress build doc",
|
|
||||||
"docs:preview": "vitepress preview doc"
|
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
@ -26,8 +23,7 @@
|
|||||||
"obsidian": "latest",
|
"obsidian": "latest",
|
||||||
"ts-jest": "^28.0.5",
|
"ts-jest": "^28.0.5",
|
||||||
"tslib": "2.3.1",
|
"tslib": "2.3.1",
|
||||||
"typescript": "^4.7.2",
|
"typescript": "^4.7.2"
|
||||||
"vitepress": "^1.6.3"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@notable/html2markdown": "^1.1.3",
|
"@notable/html2markdown": "^1.1.3",
|
||||||
|
|||||||
@ -101,34 +101,15 @@ export enum TemplateKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum SupportType {
|
export enum SupportType {
|
||||||
all = "all",
|
ALL = "all",
|
||||||
movie = 'movie',
|
MOVIE = 'movie',
|
||||||
book = 'book',
|
BOOK = 'book',
|
||||||
music = 'music',
|
MUSIC = 'music',
|
||||||
note = 'note',
|
NOTE = 'note',
|
||||||
game = 'game',
|
GAME = 'game',
|
||||||
teleplay = 'teleplay',
|
TELEPLAY = 'teleplay',
|
||||||
theater = 'theater',
|
THEATER = 'theater',
|
||||||
}
|
}
|
||||||
export const SupportTypeMap:object = {
|
|
||||||
"all": SupportType.all,
|
|
||||||
"movie": SupportType.movie,
|
|
||||||
"book": SupportType.book,
|
|
||||||
"music": SupportType.music,
|
|
||||||
"note": SupportType.note,
|
|
||||||
"game": SupportType.game,
|
|
||||||
"teleplay": SupportType.teleplay,
|
|
||||||
"theater": SupportType.theater,
|
|
||||||
"ALL": SupportType.all,
|
|
||||||
"MOVIE": SupportType.movie,
|
|
||||||
"BOOK": SupportType.book,
|
|
||||||
"MUSIC": SupportType.music,
|
|
||||||
"NOTE": SupportType.note,
|
|
||||||
"GAME": SupportType.game,
|
|
||||||
"TELEPLAY": SupportType.teleplay,
|
|
||||||
"THEATER": SupportType.theater,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export enum PropertyName {
|
export enum PropertyName {
|
||||||
//base
|
//base
|
||||||
@ -202,13 +183,13 @@ export enum PropertyName {
|
|||||||
*/
|
*/
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
export const SearchTypeRecords: { [key in SupportType]: string } = {
|
export const SearchTypeRecords: { [key in SupportType]: string } = {
|
||||||
[SupportType.all]: i18nHelper.getMessage('ALL'),
|
[SupportType.ALL]: i18nHelper.getMessage('ALL'),
|
||||||
[SupportType.movie]: i18nHelper.getMessage('MOVIE_AND_TELEPLAY'),
|
[SupportType.MOVIE]: i18nHelper.getMessage('MOVIE_AND_TELEPLAY'),
|
||||||
[SupportType.book]: i18nHelper.getMessage('BOOK'),
|
[SupportType.BOOK]: i18nHelper.getMessage('BOOK'),
|
||||||
[SupportType.music]: i18nHelper.getMessage('MUSIC'),
|
[SupportType.MUSIC]: i18nHelper.getMessage('MUSIC'),
|
||||||
[SupportType.note]: i18nHelper.getMessage('NOTE'),
|
[SupportType.NOTE]: i18nHelper.getMessage('NOTE'),
|
||||||
[SupportType.game]: i18nHelper.getMessage('GAME'),
|
[SupportType.GAME]: i18nHelper.getMessage('GAME'),
|
||||||
[SupportType.theater]: i18nHelper.getMessage('THEATER'),
|
// [SupportType.THEATER]: i18nHelper.getMessage('THEATER'),
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -252,7 +233,7 @@ export const SyncTypeRecords: { [key in SyncType | string]: string } = {
|
|||||||
// [SyncType.broadcast]: i18nHelper.getMessage('504104'),
|
// [SyncType.broadcast]: i18nHelper.getMessage('504104'),
|
||||||
// [SyncType.note]: i18nHelper.getMessage('504105'),
|
// [SyncType.note]: i18nHelper.getMessage('504105'),
|
||||||
[SyncType.music]: i18nHelper.getMessage('504106'),
|
[SyncType.music]: i18nHelper.getMessage('504106'),
|
||||||
[SyncType.game]: i18nHelper.getMessage('504108'),
|
// [SyncType.game]: i18nHelper.getMessage('504108'),
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -395,13 +376,13 @@ sec-ch-ua-platform: "Windows"
|
|||||||
export const ONLINE_SETTING_DEFAULT: DoubanPluginOnlineSettings = {
|
export const ONLINE_SETTING_DEFAULT: DoubanPluginOnlineSettings = {
|
||||||
properties: [
|
properties: [
|
||||||
{
|
{
|
||||||
type: SupportType.book,
|
type: SupportType.BOOK,
|
||||||
name: PropertyName.comment,
|
name: PropertyName.comment,
|
||||||
selectors: ['#interest_sect_level > div > span:nth-child(7)'
|
selectors: ['#interest_sect_level > div > span:nth-child(7)'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: SupportType.movie,
|
type: SupportType.MOVIE,
|
||||||
name: PropertyName.comment,
|
name: PropertyName.comment,
|
||||||
selectors: ['#interest_sect_level > div > span:nth-child(8)',
|
selectors: ['#interest_sect_level > div > span:nth-child(8)',
|
||||||
'#interest_sect_level > div > span:nth-child(7)',
|
'#interest_sect_level > div > span:nth-child(7)',
|
||||||
@ -517,34 +498,3 @@ export const SyncConditionTypeRecords: { [key in SyncConditionType|string]: stri
|
|||||||
[SyncConditionType.CUSTOM_TIME]: i18nHelper.getMessage('110074'),
|
[SyncConditionType.CUSTOM_TIME]: i18nHelper.getMessage('110074'),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const DoubanSearchResultSubject_EMPTY: DoubanSearchResultSubject = {
|
|
||||||
id: '',
|
|
||||||
title: i18nHelper.getMessage('150107'),
|
|
||||||
score: null,
|
|
||||||
cast: '',
|
|
||||||
type: 'navigate',
|
|
||||||
desc: '-',
|
|
||||||
url: 'https://www.douban.com',
|
|
||||||
image: "",
|
|
||||||
imageUrl: "",
|
|
||||||
publisher: "",
|
|
||||||
datePublished: undefined,
|
|
||||||
genre: []
|
|
||||||
};
|
|
||||||
|
|
||||||
export const DoubanSearchResultSubject_TIP_EMPTY: DoubanSearchResultSubject = {
|
|
||||||
id: '',
|
|
||||||
title: i18nHelper.getMessage('150108'),
|
|
||||||
score: null,
|
|
||||||
cast: '',
|
|
||||||
type: 'navigate',
|
|
||||||
desc: '-',
|
|
||||||
url: 'https://www.douban.com',
|
|
||||||
image: "",
|
|
||||||
imageUrl: "",
|
|
||||||
publisher: "",
|
|
||||||
datePublished: undefined,
|
|
||||||
genre: []
|
|
||||||
};
|
|
||||||
@ -38,20 +38,18 @@ export const DEFAULT_SETTINGS: DoubanPluginSetting = {
|
|||||||
statusBar: true,
|
statusBar: true,
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
customProperties: [
|
customProperties: [
|
||||||
{name: 'myType', value: 'movie', field: SupportType.movie},
|
{name: 'myType', value: 'movie', field: SupportType.MOVIE},
|
||||||
{name: 'myType', value: 'book', field: SupportType.book},
|
{name: 'myType', value: 'book', field: SupportType.BOOK},
|
||||||
{name: 'myType', value: 'music', field: SupportType.music},
|
{name: 'myType', value: 'music', field: SupportType.MUSIC},
|
||||||
{name: 'myType', value: 'note', field: SupportType.note},
|
{name: 'myType', value: 'note', field: SupportType.NOTE},
|
||||||
{name: 'myType', value: 'game', field: SupportType.game},
|
{name: 'myType', value: 'game', field: SupportType.GAME},
|
||||||
{name: 'myType', value: 'teleplay', field: SupportType.teleplay},
|
{name: 'myType', value: 'teleplay', field: SupportType.TELEPLAY},
|
||||||
{name: 'myType', value: 'theater', field: SupportType.theater},
|
|
||||||
],
|
],
|
||||||
loginCookiesContent: '',
|
loginCookiesContent: '',
|
||||||
loginHeadersContent: '',
|
loginHeadersContent: '',
|
||||||
cacheImage: true,
|
cacheImage: true,
|
||||||
cacheHighQuantityImage: true,
|
cacheHighQuantityImage: true,
|
||||||
attachmentPath: 'assets',
|
attachmentPath: 'assets',
|
||||||
attachmentFileName: "{{title}}",
|
|
||||||
syncHandledDataArray: [],
|
syncHandledDataArray: [],
|
||||||
// syncLastUpdateTime: new Map<string, string>(),
|
// syncLastUpdateTime: new Map<string, string>(),
|
||||||
scoreSetting: {
|
scoreSetting: {
|
||||||
@ -59,8 +57,7 @@ export const DEFAULT_SETTINGS: DoubanPluginSetting = {
|
|||||||
starEmpty: '☆',
|
starEmpty: '☆',
|
||||||
displayStarEmpty: false,
|
displayStarEmpty: false,
|
||||||
maxStar: 5,
|
maxStar: 5,
|
||||||
},
|
}
|
||||||
searchDefaultType: SupportType.all,
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -78,10 +78,6 @@ desc: {{desc}}
|
|||||||
---
|
---
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
---
|
|
||||||
Menu:
|
|
||||||
{{menu}}
|
|
||||||
`,
|
`,
|
||||||
noteTemplateFileContent: `---
|
noteTemplateFileContent: `---
|
||||||
doubanId: {{id}}
|
doubanId: {{id}}
|
||||||
@ -244,12 +240,8 @@ desc: {{desc}}
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
---
|
|
||||||
Menu:
|
|
||||||
{{menu}}
|
|
||||||
|
|
||||||
---
|
|
||||||
Comment:
|
Comment:
|
||||||
|
---
|
||||||
{{myComment}}
|
{{myComment}}
|
||||||
|
|
||||||
`,
|
`,
|
||||||
|
|||||||
@ -66,14 +66,14 @@ export const DoubanSubjectStateRecords_THEATER: { [key in DoubanSubjectState]: s
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const DoubanSubjectStateRecords: { [key in SupportType]: Record<DoubanSubjectState, string> } = {
|
export const DoubanSubjectStateRecords: { [key in SupportType]: Record<DoubanSubjectState, string> } = {
|
||||||
[SupportType.all]:DoubanSubjectStateRecords_ALL,
|
[SupportType.ALL]:DoubanSubjectStateRecords_ALL,
|
||||||
[SupportType.movie]:DoubanSubjectStateRecords_MOVIE,
|
[SupportType.MOVIE]:DoubanSubjectStateRecords_MOVIE,
|
||||||
[SupportType.book]:DoubanSubjectStateRecords_BOOK,
|
[SupportType.BOOK]:DoubanSubjectStateRecords_BOOK,
|
||||||
[SupportType.music]:DoubanSubjectStateRecords_MUSIC,
|
[SupportType.MUSIC]:DoubanSubjectStateRecords_MUSIC,
|
||||||
[SupportType.note]:DoubanSubjectStateRecords_NOTE,
|
[SupportType.NOTE]:DoubanSubjectStateRecords_NOTE,
|
||||||
[SupportType.game]:DoubanSubjectStateRecords_GAME,
|
[SupportType.GAME]:DoubanSubjectStateRecords_GAME,
|
||||||
[SupportType.teleplay]:DoubanSubjectStateRecords_TELEPLAY,
|
[SupportType.TELEPLAY]:DoubanSubjectStateRecords_TELEPLAY,
|
||||||
[SupportType.theater]:DoubanSubjectStateRecords_THEATER,
|
[SupportType.THEATER]:DoubanSubjectStateRecords_THEATER,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ export const DoubanSubjectStateRecords_BOOK_SYNC: { [key in DoubanSubjectState]:
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
export const DoubanSubjectStateRecords_GAME_SYNC: { [key in DoubanSubjectState]: string } = {
|
export const DoubanSubjectStateRecords_GAME_SYNC: { [key in DoubanSubjectState]: string } = {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
// [ALL]: i18nHelper.getMessage('500004'),
|
[ALL]: i18nHelper.getMessage('500004'),
|
||||||
[DoubanSubjectState.wish]: i18nHelper.getMessage('500602'),
|
[DoubanSubjectState.wish]: i18nHelper.getMessage('500602'),
|
||||||
[DoubanSubjectState.do]: i18nHelper.getMessage('500603'),
|
[DoubanSubjectState.do]: i18nHelper.getMessage('500603'),
|
||||||
[DoubanSubjectState.collect]: i18nHelper.getMessage('500604'),
|
[DoubanSubjectState.collect]: i18nHelper.getMessage('500604'),
|
||||||
@ -146,37 +146,32 @@ export const DoubanSubjectStateRecords_SYNC: { [key in SyncType]: Record<DoubanS
|
|||||||
|
|
||||||
|
|
||||||
export const DoubanSubjectStateRecords_KEY_WORD_TYPE: Map<string, SupportType> = new Map<string, SupportType> (
|
export const DoubanSubjectStateRecords_KEY_WORD_TYPE: Map<string, SupportType> = new Map<string, SupportType> (
|
||||||
[['我看过这部电视剧', SupportType.teleplay],
|
[['我看过这部电视剧', SupportType.TELEPLAY],
|
||||||
['我最近看过这部电视剧', SupportType.teleplay],
|
['我最近看过这部电视剧', SupportType.TELEPLAY],
|
||||||
['我想看这部电视剧', SupportType.teleplay],
|
['我想看这部电视剧', SupportType.TELEPLAY],
|
||||||
['我在看这部电视剧', SupportType.teleplay],
|
['我在看这部电视剧', SupportType.TELEPLAY],
|
||||||
['我最近在看这部电视剧', SupportType.teleplay],
|
['我最近在看这部电视剧', SupportType.TELEPLAY],
|
||||||
|
|
||||||
['我最近看过这部电影', SupportType.movie],
|
['我最近看过这部电影', SupportType.MOVIE],
|
||||||
['我看过这部电影', SupportType.movie],
|
['我看过这部电影', SupportType.MOVIE],
|
||||||
['我想看这部电影', SupportType.movie],
|
['我想看这部电影', SupportType.MOVIE],
|
||||||
|
|
||||||
['我读过这本书', SupportType.book],
|
['我读过这本书', SupportType.BOOK],
|
||||||
['我想读这本书', SupportType.book],
|
['我想读这本书', SupportType.BOOK],
|
||||||
['我在读这本书', SupportType.book],
|
['我在读这本书', SupportType.BOOK],
|
||||||
['我最近在读这本书', SupportType.book],
|
['我最近在读这本书', SupportType.BOOK],
|
||||||
|
|
||||||
['我最近听过这张唱片', SupportType.music],
|
['我最近听过这张唱片', SupportType.MUSIC],
|
||||||
['我听过这张唱片', SupportType.music],
|
['我听过这张唱片', SupportType.MUSIC],
|
||||||
['我想听这张唱片', SupportType.music],
|
['我想听这张唱片', SupportType.MUSIC],
|
||||||
['我在听这张唱片', SupportType.music],
|
['我在听这张唱片', SupportType.MUSIC],
|
||||||
['我最近在听这张唱片', SupportType.music],
|
['我最近在听这张唱片', SupportType.MUSIC],
|
||||||
|
|
||||||
['我最近玩过这个游戏', SupportType.game],
|
['我最近玩过这个游戏', SupportType.GAME],
|
||||||
['我玩过这个游戏', SupportType.game],
|
['我玩过这个游戏', SupportType.GAME],
|
||||||
['我想玩这个游戏', SupportType.game],
|
['我想玩这个游戏', SupportType.GAME],
|
||||||
['我在玩这个游戏', SupportType.game],
|
['我在玩这个游戏', SupportType.GAME],
|
||||||
['我最近在玩这个游戏', SupportType.game],
|
['我最近在玩这个游戏', SupportType.GAME],]
|
||||||
|
|
||||||
['我最近看过这部电影', SupportType.movie],
|
|
||||||
['我看过这部电影', SupportType.movie],
|
|
||||||
['我想看这部电影', SupportType.movie],
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,92 +0,0 @@
|
|||||||
import {CheerioAPI} from 'cheerio';
|
|
||||||
import DoubanPlugin from "../../../main";
|
|
||||||
import SchemaOrg from "src/org/wanxp/utils/SchemaOrg";
|
|
||||||
import {DataValueType, PropertyName, SupportType} from "../../../constant/Constsant";
|
|
||||||
import {moment} from "obsidian";
|
|
||||||
import {TITLE_ALIASES_SPECIAL_CHAR_REG_G} from "../../../utils/YamlUtil";
|
|
||||||
import {DataField} from "../../../utils/model/DataField";
|
|
||||||
import DoubanAbstractLoadHandler from "../../data/handler/DoubanAbstractLoadHandler";
|
|
||||||
import DoubanTheaterSubject from "../../data/model/DoubanTheaterSubject";
|
|
||||||
import HandleContext from "../../data/model/HandleContext";
|
|
||||||
import DoubanSubject from "../../data/model/DoubanSubject";
|
|
||||||
import {UserStateSubject} from "../../data/model/UserStateSubject";
|
|
||||||
|
|
||||||
export default class DoubanTheaterAiLoadHandler extends DoubanAbstractLoadHandler<DoubanTheaterSubject> {
|
|
||||||
constructor(doubanPlugin: DoubanPlugin) {
|
|
||||||
super(doubanPlugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
getSupportType(): SupportType {
|
|
||||||
return SupportType.theater;
|
|
||||||
}
|
|
||||||
|
|
||||||
getHighQuantityImageUrl(fileName: string): string {
|
|
||||||
return `https://img9.doubanio.com/view/photo/l/public/${fileName}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
getSubjectUrl(id:string):string{
|
|
||||||
return `https://www.douban.com/location/drama/${id}/`;
|
|
||||||
}
|
|
||||||
|
|
||||||
parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: DoubanTheaterSubject, context: HandleContext): void {
|
|
||||||
variableMap.set("director", new DataField(
|
|
||||||
"director",
|
|
||||||
DataValueType.array,
|
|
||||||
extract.director,
|
|
||||||
(extract.director || []).map(SchemaOrg.getPersonName).filter(c => c)
|
|
||||||
));
|
|
||||||
|
|
||||||
variableMap.set("actor", new DataField(
|
|
||||||
"actor",
|
|
||||||
DataValueType.array,
|
|
||||||
extract.actor,
|
|
||||||
(extract.actor || []).map(SchemaOrg.getPersonName).filter(c => c)
|
|
||||||
));
|
|
||||||
|
|
||||||
variableMap.set("author", new DataField(
|
|
||||||
"author",
|
|
||||||
DataValueType.array,
|
|
||||||
extract.author,
|
|
||||||
(extract.author || []).map(SchemaOrg.getPersonName).map(name => super.getPersonName(name, context)).filter(c => c)
|
|
||||||
));
|
|
||||||
variableMap.set("aliases", new DataField("aliases", DataValueType.array, extract.aliases,
|
|
||||||
(extract.aliases || []).map(a=>a
|
|
||||||
.trim()
|
|
||||||
// .replace(TITLE_ALIASES_SPECIAL_CHAR_REG_G, '_')
|
|
||||||
// //replase multiple _ to single _
|
|
||||||
// .replace(/_+/g, '_')
|
|
||||||
// .replace(/^_/, '')
|
|
||||||
// .replace(/_$/, '')
|
|
||||||
.replace(/:\s+/g, ':')
|
|
||||||
)));
|
|
||||||
// super.parseAliases(beforeContent, variableMap, extract, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
support(extract: DoubanSubject): boolean {
|
|
||||||
return extract && extract.type && (extract.type.contains("舞台剧") || extract.type.contains("舞剧") || extract.type.contains("Theater") || extract.type.contains("theater"));
|
|
||||||
}
|
|
||||||
|
|
||||||
analysisUser(html: CheerioAPI, context: HandleContext): { data: CheerioAPI, userState: UserStateSubject } {
|
|
||||||
const rate = html('input#n_rating').val();
|
|
||||||
const tagsStr = html('div#interest_sect_level > div.a_stars > span.color_gray').text().trim();
|
|
||||||
const tags = tagsStr ? tagsStr.replace('标签:', '').trim().split(' ') : null;
|
|
||||||
const stateWord = html('#interest_sect_level > h2').text().trim();
|
|
||||||
const collectionDateStr = html('div#interest_sect_level > div.a_stars > span.mr10 > span.collection_date').text().trim();
|
|
||||||
const userState1 = DoubanAbstractLoadHandler.getUserState(stateWord);
|
|
||||||
const component = this.getPropertyValue(html, PropertyName.comment);
|
|
||||||
const userState: UserStateSubject = {
|
|
||||||
tags: tags,
|
|
||||||
rate: rate ? Number(rate) : null,
|
|
||||||
state: userState1,
|
|
||||||
collectionDate: collectionDateStr ? moment(collectionDateStr, 'YYYY-MM-DD').toDate() : null,
|
|
||||||
comment: component
|
|
||||||
}
|
|
||||||
return {data: html, userState: userState};
|
|
||||||
}
|
|
||||||
|
|
||||||
parseSubjectFromHtml(html: CheerioAPI, context: HandleContext): DoubanTheaterSubject {
|
|
||||||
const obj: DoubanTheaterSubject = new DoubanTheaterSubject();
|
|
||||||
obj.id = this.getPropertyValue(html, PropertyName.id);
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -150,7 +150,6 @@ ${syncStatus.getHandle() == 0? '...' : i18nHelper.getMessage('110042') + ':' + T
|
|||||||
cacheImage: ( settings.cacheImage == null) ? DEFAULT_SETTINGS.cacheImage : settings.cacheImage,
|
cacheImage: ( settings.cacheImage == null) ? DEFAULT_SETTINGS.cacheImage : settings.cacheImage,
|
||||||
cacheHighQuantityImage: ( settings.cacheHighQuantityImage == null) ? DEFAULT_SETTINGS.cacheHighQuantityImage : settings.cacheHighQuantityImage,
|
cacheHighQuantityImage: ( settings.cacheHighQuantityImage == null) ? DEFAULT_SETTINGS.cacheHighQuantityImage : settings.cacheHighQuantityImage,
|
||||||
attachmentPath: (settings.attachmentPath == '' || settings.attachmentPath == null) ? DEFAULT_SETTINGS.attachmentPath : settings.attachmentPath,
|
attachmentPath: (settings.attachmentPath == '' || settings.attachmentPath == null) ? DEFAULT_SETTINGS.attachmentPath : settings.attachmentPath,
|
||||||
attachmentFileName: (settings.attachmentFileName == '' || settings.attachmentFileName == null) ? DEFAULT_SETTINGS.attachmentFileName : settings.attachmentFileName,
|
|
||||||
templateFile: (settings.movieTemplateFile == '' || settings.movieTemplateFile == null) ? DEFAULT_SETTINGS.movieTemplateFile : settings.movieTemplateFile,
|
templateFile: (settings.movieTemplateFile == '' || settings.movieTemplateFile == null) ? DEFAULT_SETTINGS.movieTemplateFile : settings.movieTemplateFile,
|
||||||
incrementalUpdate: true,
|
incrementalUpdate: true,
|
||||||
syncConditionType: SyncConditionType.ALL,
|
syncConditionType: SyncConditionType.ALL,
|
||||||
@ -169,6 +168,9 @@ ${syncStatus.getHandle() == 0? '...' : i18nHelper.getMessage('110042') + ':' + T
|
|||||||
const syncButton = new ButtonComponent(controls)
|
const syncButton = new ButtonComponent(controls)
|
||||||
.setButtonText(i18nHelper.getMessage('110007'))
|
.setButtonText(i18nHelper.getMessage('110007'))
|
||||||
.onClick(async () => {
|
.onClick(async () => {
|
||||||
|
if (!this.plugin.userComponent.isLogin()) {
|
||||||
|
await this.plugin.userComponent.login();
|
||||||
|
}
|
||||||
if(!await this.plugin.checkLogin(this.context)) {
|
if(!await this.plugin.checkLogin(this.context)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -233,7 +235,6 @@ ${syncStatus.getHandle() == 0? '...' : i18nHelper.getMessage('110042') + ':' + T
|
|||||||
this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_TELEPLAY_SYNC, config, disable);
|
this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_TELEPLAY_SYNC, config, disable);
|
||||||
break;
|
break;
|
||||||
case SyncType.game:
|
case SyncType.game:
|
||||||
config.scope = DoubanSubjectState.collect;
|
|
||||||
this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_GAME_SYNC, config, disable);
|
this.showScopeDropdown(contentEl, DoubanSubjectStateRecords_GAME_SYNC, config, disable);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -425,20 +426,6 @@ ${syncStatus.getHandle() == 0? '...' : i18nHelper.getMessage('110042') + ':' + T
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
.setDisabled(disable);
|
.setDisabled(disable);
|
||||||
new Setting(containerEl)
|
|
||||||
.setName( i18nHelper.getMessage('121452'))
|
|
||||||
.setDesc( i18nHelper.getMessage('121453'))
|
|
||||||
.addSearch(async (search: SearchComponent) => {
|
|
||||||
new FolderSuggest(this.plugin.app, search.inputEl);
|
|
||||||
// @ts-ignore
|
|
||||||
search.setValue(config.attachmentFileName)
|
|
||||||
// @ts-ignore
|
|
||||||
.setPlaceholder(i18nHelper.getMessage('121454'))
|
|
||||||
.onChange(async (value: string) => {
|
|
||||||
config.attachmentFileName = value;
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.setDisabled(disable);
|
|
||||||
|
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
.setName(i18nHelper.getMessage('121435'))
|
.setName(i18nHelper.getMessage('121435'))
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import {moment, Platform, TFile} from "obsidian";
|
|||||||
import {i18nHelper} from 'src/org/wanxp/lang/helper';
|
import {i18nHelper} from 'src/org/wanxp/lang/helper';
|
||||||
import {log} from "src/org/wanxp/utils/Logutil";
|
import {log} from "src/org/wanxp/utils/Logutil";
|
||||||
import {CheerioAPI, load} from "cheerio";
|
import {CheerioAPI, load} from "cheerio";
|
||||||
import YamlUtil, {TITLE_ALIASES_SPECIAL_CHAR_REG_G} from "../../../utils/YamlUtil";
|
import YamlUtil from "../../../utils/YamlUtil";
|
||||||
import {
|
import {
|
||||||
BasicConst,
|
BasicConst,
|
||||||
DataValueType,
|
DataValueType,
|
||||||
@ -47,44 +47,36 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
|
|||||||
|
|
||||||
async parse(extract: T, context: HandleContext): Promise<HandleResult> {
|
async parse(extract: T, context: HandleContext): Promise<HandleResult> {
|
||||||
const template: string = await this.getTemplate(extract, context);
|
const template: string = await this.getTemplate(extract, context);
|
||||||
const variableMap = this.buildVariableMap(extract, context);
|
await this.saveImage(extract, context);
|
||||||
this.parseUserInfo(template, variableMap, extract, context);
|
|
||||||
this.parseVariable(template, variableMap, extract, context);
|
|
||||||
await this.saveImage(extract, context, variableMap);
|
|
||||||
|
|
||||||
const frontMatterStart: number = template.indexOf(BasicConst.YAML_FRONT_MATTER_SYMBOL, 0);
|
const frontMatterStart: number = template.indexOf(BasicConst.YAML_FRONT_MATTER_SYMBOL, 0);
|
||||||
const frontMatterEnd: number = template.indexOf(BasicConst.YAML_FRONT_MATTER_SYMBOL, frontMatterStart + 1);
|
const frontMatterEnd: number = template.indexOf(BasicConst.YAML_FRONT_MATTER_SYMBOL, frontMatterStart + 1);
|
||||||
let frontMatter = '';
|
let frontMatter = '';
|
||||||
let frontMatterBefore = '';
|
let frontMatterBefore = '';
|
||||||
let frontMatterAfter = '';
|
let frontMatterAfter = '';
|
||||||
let result = '';
|
let result = '';
|
||||||
|
|
||||||
if (frontMatterStart > -1 && frontMatterEnd > -1) {
|
if (frontMatterStart > -1 && frontMatterEnd > -1) {
|
||||||
frontMatterBefore = template.substring(0, frontMatterStart);
|
frontMatterBefore = template.substring(0, frontMatterStart);
|
||||||
frontMatter = template.substring(frontMatterStart, frontMatterEnd + 3);
|
frontMatter = template.substring(frontMatterStart, frontMatterEnd + 3);
|
||||||
frontMatterAfter = template.substring(frontMatterEnd + 3);
|
frontMatterAfter = template.substring(frontMatterEnd + 3);
|
||||||
if (frontMatterBefore.length > 0) {
|
if (frontMatterBefore.length > 0) {
|
||||||
frontMatterBefore = this.parsePartText(frontMatterBefore, extract, context, variableMap);
|
frontMatterBefore = this.parsePartText(frontMatterBefore, extract, context);
|
||||||
}
|
}
|
||||||
if (frontMatterAfter.length > 0) {
|
if (frontMatterAfter.length > 0) {
|
||||||
frontMatterAfter = this.parsePartText(frontMatterAfter, extract, context, variableMap);
|
frontMatterAfter = this.parsePartText(frontMatterAfter, extract, context);
|
||||||
}
|
}
|
||||||
if (frontMatter.length > 0) {
|
if (frontMatter.length > 0) {
|
||||||
frontMatter = this.parsePartYml(frontMatter, extract, context, variableMap);
|
frontMatter = this.parsePartText(frontMatter, extract, context, TemplateTextMode.YAML);
|
||||||
}
|
}
|
||||||
result = frontMatterBefore + frontMatter + frontMatterAfter;
|
result = frontMatterBefore + frontMatter + frontMatterAfter;
|
||||||
} else {
|
} else {
|
||||||
result = this.parsePartText(template, extract, context, variableMap);
|
result = this.parsePartText(template, extract, context);
|
||||||
}
|
|
||||||
let filePath = '';
|
|
||||||
if (SearchHandleMode.FOR_CREATE == context.mode) {
|
|
||||||
filePath = this.parsePartPath(this.getFilePath(context), extract, context, variableMap);
|
|
||||||
}
|
}
|
||||||
let fileName = '';
|
let fileName = '';
|
||||||
if (SearchHandleMode.FOR_CREATE == context.mode) {
|
if (SearchHandleMode.FOR_CREATE == context.mode) {
|
||||||
fileName = this.parsePartPath(this.getFileName(context), extract, context, variableMap);
|
fileName = this.parsePartText(this.getFileName(context), extract, context);
|
||||||
}
|
}
|
||||||
return {content: result,filePath: filePath, fileName: fileName, subject:extract};
|
|
||||||
|
return {content: result, fileName: fileName, subject:extract};
|
||||||
}
|
}
|
||||||
|
|
||||||
private getFileName(context: HandleContext): string {
|
private getFileName(context: HandleContext): string {
|
||||||
@ -96,22 +88,13 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
|
|||||||
return dataFileNamePath ? dataFileNamePath : DEFAULT_SETTINGS.dataFileNamePath;
|
return dataFileNamePath ? dataFileNamePath : DEFAULT_SETTINGS.dataFileNamePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getFilePath(context: HandleContext): string {
|
|
||||||
const {syncConfig} = context;
|
|
||||||
if (syncConfig) {
|
|
||||||
return syncConfig.dataFilePath;
|
|
||||||
}
|
|
||||||
const {dataFilePath} = context.settings;
|
|
||||||
return dataFilePath ? dataFilePath : DEFAULT_SETTINGS.dataFilePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
abstract getSupportType(): SupportType;
|
abstract getSupportType(): SupportType;
|
||||||
|
|
||||||
abstract parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: T, context: HandleContext): void;
|
abstract parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: T, context: HandleContext, textMode: TemplateTextMode): void;
|
||||||
|
|
||||||
abstract support(extract: DoubanSubject): boolean;
|
abstract support(extract: DoubanSubject): boolean;
|
||||||
|
|
||||||
@ -142,7 +125,7 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
|
|||||||
}else {
|
}else {
|
||||||
context.syncStatusHolder?context.syncStatusHolder.syncStatus.handled(1):null;
|
context.syncStatusHolder?context.syncStatusHolder.syncStatus.handled(1):null;
|
||||||
}
|
}
|
||||||
return undefined;
|
return e;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -271,25 +254,13 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
private parsePartYml(template: string, extract: T, context: HandleContext, variableMap : Map<string, DataField>): string {
|
private parsePartText(template: string, extract: T, context: HandleContext, textMode: TemplateTextMode = TemplateTextMode.NORMAL): string {
|
||||||
return VariableUtil.replaceSubject(variableMap, template, this.getSupportType(), this.doubanPlugin.settingsManager, 'yml_text');
|
const variableMap:Map<string, DataField> = new Map();
|
||||||
}
|
|
||||||
|
|
||||||
private parsePartText(template: string, extract: T, context: HandleContext, variableMap : Map<string, DataField>): string {
|
|
||||||
return VariableUtil.replaceSubject(variableMap, template, this.getSupportType(), this.doubanPlugin.settingsManager, 'text');
|
|
||||||
}
|
|
||||||
|
|
||||||
private parsePartPath(template: string, extract: T, context: HandleContext, variableMap : Map<string, DataField>): string {
|
|
||||||
return VariableUtil.replaceSubject(variableMap, template, this.getSupportType(), this.doubanPlugin.settingsManager, 'path');
|
|
||||||
}
|
|
||||||
|
|
||||||
private buildVariableMap(extract: T, context: HandleContext) {
|
|
||||||
const variableMap: Map<string, DataField> = new Map();
|
|
||||||
for (const [key, value] of Object.entries(extract)) {
|
for (const [key, value] of Object.entries(extract)) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const type: DataValueType = VariableUtil.getType(value);
|
const type:DataValueType = VariableUtil.getType(value);
|
||||||
if (key == 'score') {
|
if (key == 'score') {
|
||||||
variableMap.set(DoubanParameterName.SCORE_STAR, new DataField(
|
variableMap.set(DoubanParameterName.SCORE_STAR, new DataField(
|
||||||
DoubanParameterName.SCORE_STAR,
|
DoubanParameterName.SCORE_STAR,
|
||||||
@ -337,10 +308,14 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
|
|||||||
currentDate,
|
currentDate,
|
||||||
moment(currentDate).format(context.settings.timeFormat)
|
moment(currentDate).format(context.settings.timeFormat)
|
||||||
));
|
));
|
||||||
return variableMap;
|
|
||||||
|
this.parseUserInfo(template, variableMap, extract, context, textMode);
|
||||||
|
this.parseVariable(template, variableMap, extract, context, textMode);
|
||||||
|
return VariableUtil.replaceSubject(variableMap, template, this.getSupportType(), this.doubanPlugin.settingsManager);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseUserInfo(resultContent: string, variableMap:Map<string, DataField>, extract: T, context: HandleContext) {
|
private parseUserInfo(resultContent: string, variableMap:Map<string, DataField>, extract: T, context: HandleContext, textMode: TemplateTextMode) {
|
||||||
const userState = extract.userState;
|
const userState = extract.userState;
|
||||||
if ((resultContent.indexOf(DoubanUserParameter.MY_TAGS) >= 0 ||
|
if ((resultContent.indexOf(DoubanUserParameter.MY_TAGS) >= 0 ||
|
||||||
resultContent.indexOf(DoubanUserParameter.MY_RATING) >= 0 ||
|
resultContent.indexOf(DoubanUserParameter.MY_RATING) >= 0 ||
|
||||||
@ -414,22 +389,22 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
|
|||||||
private getTemplateKey():TemplateKey {
|
private getTemplateKey():TemplateKey {
|
||||||
let templateKey: TemplateKey;
|
let templateKey: TemplateKey;
|
||||||
switch (this.getSupportType()) {
|
switch (this.getSupportType()) {
|
||||||
case SupportType.movie:
|
case SupportType.MOVIE:
|
||||||
templateKey = TemplateKey.movieTemplateFile;
|
templateKey = TemplateKey.movieTemplateFile;
|
||||||
break;
|
break;
|
||||||
case SupportType.book:
|
case SupportType.BOOK:
|
||||||
templateKey = TemplateKey.bookTemplateFile;
|
templateKey = TemplateKey.bookTemplateFile;
|
||||||
break;
|
break;
|
||||||
case SupportType.music:
|
case SupportType.MUSIC:
|
||||||
templateKey = TemplateKey.musicTemplateFile;
|
templateKey = TemplateKey.musicTemplateFile;
|
||||||
break;
|
break;
|
||||||
case SupportType.teleplay:
|
case SupportType.TELEPLAY:
|
||||||
templateKey = TemplateKey.teleplayTemplateFile;
|
templateKey = TemplateKey.teleplayTemplateFile;
|
||||||
break;
|
break;
|
||||||
case SupportType.game:
|
case SupportType.GAME:
|
||||||
templateKey = TemplateKey.gameTemplateFile;
|
templateKey = TemplateKey.gameTemplateFile;
|
||||||
break;
|
break;
|
||||||
case SupportType.note:
|
case SupportType.NOTE:
|
||||||
templateKey = TemplateKey.noteTemplateFile;
|
templateKey = TemplateKey.noteTemplateFile;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -522,82 +497,43 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async saveImage(extract: T, context: HandleContext, variableMap : Map<string, DataField>) {
|
private async saveImage(extract: T, context: HandleContext) {
|
||||||
const {syncConfig} = context;
|
const {syncConfig} = context;
|
||||||
if (!extract.image || (syncConfig && !syncConfig.cacheImage) || !context.settings.cacheImage) {
|
if (!extract.image || (syncConfig && !syncConfig.cacheImage) || !context.settings.cacheImage) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const image = extract.image;
|
const image = extract.image;
|
||||||
|
const filename = image.split('/').pop();
|
||||||
let folder = syncConfig? syncConfig.attachmentPath : context.settings.attachmentPath;
|
let folder = syncConfig? syncConfig.attachmentPath : context.settings.attachmentPath;
|
||||||
if (!folder) {
|
if (!folder) {
|
||||||
folder = DEFAULT_SETTINGS.attachmentPath;
|
folder = DEFAULT_SETTINGS.attachmentPath;
|
||||||
}
|
}
|
||||||
folder = this.parsePartPath(folder, extract, context, variableMap)
|
folder = this.parsePartText(folder, extract, context)
|
||||||
let fileName = syncConfig? syncConfig.attachmentFileName : context.settings.attachmentFileName;
|
|
||||||
if (!fileName) {
|
const referHeaders = {'referer': image};
|
||||||
fileName = DEFAULT_SETTINGS.attachmentFileName;
|
|
||||||
}
|
|
||||||
let fileNameSuffix = image ? image.substring(image.lastIndexOf('.')) : '.jpg';
|
|
||||||
if (fileNameSuffix && fileNameSuffix.length > 10) {
|
|
||||||
fileNameSuffix = '.jpg';
|
|
||||||
}
|
|
||||||
fileName = this.parsePartPath(fileName, extract, context, variableMap)
|
|
||||||
fileName = fileName + fileNameSuffix;
|
|
||||||
const imageReferer = (extract.id ? this.getSubjectUrl(extract.id) : '') || extract.url;
|
|
||||||
const referHeaders = HttpUtil.buildImageRequestHeaders(
|
|
||||||
context.plugin.settingsManager.getHeaders() as Record<string, any>,
|
|
||||||
imageReferer
|
|
||||||
);
|
|
||||||
if ((syncConfig ? syncConfig.cacheHighQuantityImage : context.settings.cacheHighQuantityImage) && context.userComponent.isLogin()) {
|
if ((syncConfig ? syncConfig.cacheHighQuantityImage : context.settings.cacheHighQuantityImage) && context.userComponent.isLogin()) {
|
||||||
try {
|
try {
|
||||||
const highImageFilename = this.getImageFilename(image);
|
const fileNameSpilt = filename.split('.');
|
||||||
const highImage = this.getHighQuantityImageUrl(highImageFilename);
|
const highFilename = fileNameSpilt.first() + '.jpg';
|
||||||
const highImageHeaders = HttpUtil.buildImageRequestHeaders(
|
|
||||||
context.plugin.settingsManager.getHeaders() as Record<string, any>,
|
const highImage = this.getHighQuantityImageUrl(highFilename);
|
||||||
imageReferer
|
const resultValue = await this.handleImage(highImage, folder, highFilename, context, false, referHeaders);
|
||||||
);
|
|
||||||
const resultValue = await this.handleImage(highImage, folder, fileName, context, false, highImageHeaders);
|
|
||||||
if (resultValue && resultValue.success) {
|
if (resultValue && resultValue.success) {
|
||||||
extract.image = resultValue.filepath;
|
extract.image = resultValue.filepath;
|
||||||
this.initImageVariableMap(extract, context, variableMap);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}catch (e) {
|
}catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
console.error('下载高清封面失败,将会使用普通封面')
|
console.error('下载高清封面失败,将会使用普通封面')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const resultValue = await this.handleImage(image, folder, fileName, context, true, referHeaders);
|
const resultValue = await this.handleImage(image, folder, filename, context, true, referHeaders);
|
||||||
if (resultValue && resultValue.success) {
|
if (resultValue && resultValue.success) {
|
||||||
extract.image = resultValue.filepath;
|
extract.image = resultValue.filepath;
|
||||||
this.initImageVariableMap(extract, context, variableMap);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getImageFilename(image: string): string {
|
|
||||||
if (!image) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
const imageUrl = image.split('?').first() || image;
|
|
||||||
return imageUrl.substring(imageUrl.lastIndexOf('/') + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private initImageVariableMap(extract: T, context: HandleContext, variableMap : Map<string, DataField>) {
|
|
||||||
variableMap.set(DoubanParameterName.IMAGE_URL, new DataField(
|
|
||||||
DoubanParameterName.IMAGE_URL,
|
|
||||||
DataValueType.url,
|
|
||||||
extract.imageUrl,
|
|
||||||
extract.imageUrl
|
|
||||||
));
|
|
||||||
variableMap.set(DoubanParameterName.IMAGE, new DataField(
|
|
||||||
DoubanParameterName.IMAGE,
|
|
||||||
DataValueType.path,
|
|
||||||
extract.image,
|
|
||||||
extract.image
|
|
||||||
));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private async handleImage(image: string, folder: string, filename: string, context: HandleContext, showError: boolean, headers?: any) {
|
private async handleImage(image: string, folder: string, filename: string, context: HandleContext, showError: boolean, headers?: any) {
|
||||||
//只有在桌面版且开启了图片上传才会使用PicGo,并且开启图床功能
|
//只有在桌面版且开启了图片上传才会使用PicGo,并且开启图床功能
|
||||||
if (context.settings.pictureBedFlag && Platform.isDesktopApp) {
|
if (context.settings.pictureBedFlag && Platform.isDesktopApp) {
|
||||||
@ -621,20 +557,12 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
|
|||||||
|
|
||||||
handlePersonNameByMeta(html: CheerioAPI, movie: DoubanSubject, context: HandleContext,
|
handlePersonNameByMeta(html: CheerioAPI, movie: DoubanSubject, context: HandleContext,
|
||||||
metaProperty:string, objectProperty:string) {
|
metaProperty:string, objectProperty:string) {
|
||||||
if (!movie) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const metaProperties: string[] = html(`head > meta[property='${metaProperty}']`).get()
|
const metaProperties: string[] = html(`head > meta[property='${metaProperty}']`).get()
|
||||||
.map((e) => {
|
.map((e) => {
|
||||||
return html(e).attr('content');
|
return html(e).attr('content');
|
||||||
});
|
});
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const currentArray = movie[objectProperty];
|
movie[objectProperty]
|
||||||
if (!Array.isArray(currentArray)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// @ts-ignore
|
|
||||||
currentArray
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
.filter((p:Person) => p.name)
|
.filter((p:Person) => p.name)
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export default class DoubanBookLoadHandler extends DoubanAbstractLoadHandler<Dou
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSupportType(): SupportType {
|
getSupportType(): SupportType {
|
||||||
return SupportType.book;
|
return SupportType.BOOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
getHighQuantityImageUrl(fileName:string):string{
|
getHighQuantityImageUrl(fileName:string):string{
|
||||||
@ -28,11 +28,11 @@ export default class DoubanBookLoadHandler extends DoubanAbstractLoadHandler<Dou
|
|||||||
return `https://book.douban.com/subject/${id}/`;
|
return `https://book.douban.com/subject/${id}/`;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: DoubanBookSubject, context: HandleContext): void {
|
parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: DoubanBookSubject, context: HandleContext, textMode: TemplateTextMode): void {
|
||||||
variableMap.set(DoubanBookParameter.author, new DataField(DoubanBookParameter.author,
|
variableMap.set(DoubanBookParameter.author, new DataField(DoubanBookParameter.author,
|
||||||
DataValueType.array, extract.author, (extract.author || []).map(this.handleSpecialAuthorName)));
|
DataValueType.array, extract.author, extract.author.map(this.handleSpecialAuthorName)));
|
||||||
variableMap.set(DoubanBookParameter.translator, new DataField(DoubanBookParameter.translator,
|
variableMap.set(DoubanBookParameter.translator, new DataField(DoubanBookParameter.translator,
|
||||||
DataValueType.array, extract.translator, (extract.translator || []).map(this.handleSpecialAuthorName)));
|
DataValueType.array, extract.translator, extract.translator.map(this.handleSpecialAuthorName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
support(extract: DoubanSubject): boolean {
|
support(extract: DoubanSubject): boolean {
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import {UserStateSubject} from "../model/UserStateSubject";
|
|||||||
import {moment} from "obsidian";
|
import {moment} from "obsidian";
|
||||||
import {TITLE_ALIASES_SPECIAL_CHAR_REG_G} from "../../../utils/YamlUtil";
|
import {TITLE_ALIASES_SPECIAL_CHAR_REG_G} from "../../../utils/YamlUtil";
|
||||||
import {DataField} from "../../../utils/model/DataField";
|
import {DataField} from "../../../utils/model/DataField";
|
||||||
import {b} from "@shikijs/engine-javascript/dist/shared/engine-javascript.BnuFKbIS";
|
|
||||||
|
|
||||||
export default class DoubanGameLoadHandler extends DoubanAbstractLoadHandler<DoubanGameSubject> {
|
export default class DoubanGameLoadHandler extends DoubanAbstractLoadHandler<DoubanGameSubject> {
|
||||||
|
|
||||||
@ -18,7 +17,7 @@ export default class DoubanGameLoadHandler extends DoubanAbstractLoadHandler<Dou
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSupportType(): SupportType {
|
getSupportType(): SupportType {
|
||||||
return SupportType.game;
|
return SupportType.GAME;
|
||||||
}
|
}
|
||||||
getHighQuantityImageUrl(fileName:string):string{
|
getHighQuantityImageUrl(fileName:string):string{
|
||||||
return `https://img9.doubanio.com/lpic/${fileName}`;
|
return `https://img9.doubanio.com/lpic/${fileName}`;
|
||||||
@ -29,18 +28,7 @@ export default class DoubanGameLoadHandler extends DoubanAbstractLoadHandler<Dou
|
|||||||
}
|
}
|
||||||
|
|
||||||
parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: DoubanGameSubject, context: HandleContext): void {
|
parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: DoubanGameSubject, context: HandleContext): void {
|
||||||
// super.parseAliases(beforeContent, variableMap, extract, context);
|
variableMap.set("aliases", new DataField("aliases", DataValueType.array, extract.aliases, extract.aliases.map(a=>a.replace(TITLE_ALIASES_SPECIAL_CHAR_REG_G, '_'))));
|
||||||
variableMap.set("aliases", new DataField("aliases", DataValueType.array, extract.aliases,
|
|
||||||
(extract.aliases || []).map(a=>a
|
|
||||||
.trim()
|
|
||||||
// .replace(TITLE_ALIASES_SPECIAL_CHAR_REG_G, '_')
|
|
||||||
// //replase multiple _ to single _
|
|
||||||
// .replace(/_+/g, '_')
|
|
||||||
// .replace(/^_/, '')
|
|
||||||
// .replace(/_$/, '')
|
|
||||||
.replace(/:\s+/g, ':')
|
|
||||||
)));
|
|
||||||
// super.parseAliases(beforeContent, variableMap, extract, context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
support(extract: DoubanSubject): boolean {
|
support(extract: DoubanSubject): boolean {
|
||||||
|
|||||||
@ -19,7 +19,7 @@ export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<Do
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSupportType(): SupportType {
|
getSupportType(): SupportType {
|
||||||
return SupportType.movie;
|
return SupportType.MOVIE;
|
||||||
}
|
}
|
||||||
|
|
||||||
getHighQuantityImageUrl(fileName:string):string{
|
getHighQuantityImageUrl(fileName:string):string{
|
||||||
@ -35,34 +35,30 @@ export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<Do
|
|||||||
"director",
|
"director",
|
||||||
DataValueType.array,
|
DataValueType.array,
|
||||||
extract.director,
|
extract.director,
|
||||||
(extract.director || []).map(SchemaOrg.getPersonName).filter(c => c)
|
extract.director.map(SchemaOrg.getPersonName).filter(c => c)
|
||||||
));
|
));
|
||||||
|
|
||||||
variableMap.set("actor", new DataField(
|
variableMap.set("actor", new DataField(
|
||||||
"actor",
|
"actor",
|
||||||
DataValueType.array,
|
DataValueType.array,
|
||||||
extract.actor,
|
extract.actor,
|
||||||
(extract.actor || []).map(SchemaOrg.getPersonName).filter(c => c)
|
extract.actor.map(SchemaOrg.getPersonName).filter(c => c)
|
||||||
));
|
));
|
||||||
|
|
||||||
variableMap.set("author", new DataField(
|
variableMap.set("author", new DataField(
|
||||||
"author",
|
"author",
|
||||||
DataValueType.array,
|
DataValueType.array,
|
||||||
extract.author,
|
extract.author,
|
||||||
(extract.author || []).map(SchemaOrg.getPersonName).map(name => super.getPersonName(name, context)).filter(c => c)
|
extract.author.map(SchemaOrg.getPersonName).map(name => super.getPersonName(name, context)).filter(c => c)
|
||||||
));
|
));
|
||||||
variableMap.set("aliases", new DataField("aliases", DataValueType.array, extract.aliases,
|
|
||||||
(extract.aliases || []).map(a=>a
|
variableMap.set("aliases", new DataField(
|
||||||
.trim()
|
"aliases",
|
||||||
// .replace(TITLE_ALIASES_SPECIAL_CHAR_REG_G, '_')
|
DataValueType.array,
|
||||||
// //replase multiple _ to single _
|
extract.aliases,
|
||||||
// .replace(/_+/g, '_')
|
extract.aliases.map(a => a.replace(TITLE_ALIASES_SPECIAL_CHAR_REG_G, '_'))
|
||||||
// .replace(/^_/, '')
|
));
|
||||||
// .replace(/_$/, '')
|
}
|
||||||
.replace(/:\s+/g, ':')
|
|
||||||
)));
|
|
||||||
// super.parseAliases(beforeContent, variableMap, extract, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
support(extract: DoubanSubject): boolean {
|
support(extract: DoubanSubject): boolean {
|
||||||
return extract && extract.type && (extract.type.contains("电影") || extract.type.contains("Movie") || extract.type.contains("movie"));
|
return extract && extract.type && (extract.type.contains("电影") || extract.type.contains("Movie") || extract.type.contains("movie"));
|
||||||
@ -98,7 +94,7 @@ export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<Do
|
|||||||
}
|
}
|
||||||
|
|
||||||
parseSubjectFromHtml(html: CheerioAPI, context: HandleContext): DoubanMovieSubject {
|
parseSubjectFromHtml(html: CheerioAPI, context: HandleContext): DoubanMovieSubject {
|
||||||
let movie: DoubanMovieSubject | undefined = html('script')
|
const movie:DoubanMovieSubject = html('script')
|
||||||
.get()
|
.get()
|
||||||
.filter(scd => "application/ld+json" == html(scd).attr("type"))
|
.filter(scd => "application/ld+json" == html(scd).attr("type"))
|
||||||
.map(i => {
|
.map(i => {
|
||||||
@ -108,8 +104,8 @@ export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<Do
|
|||||||
const idPattern = /(\d){5,10}/g;
|
const idPattern = /(\d){5,10}/g;
|
||||||
const id = idPattern.exec(obj.url);
|
const id = idPattern.exec(obj.url);
|
||||||
const name = obj.name;
|
const name = obj.name;
|
||||||
const title = super.getTitleNameByMode(name, PersonNameMode.CH_NAME, context) ?? name;
|
const title = super.getTitleNameByMode(name, PersonNameMode.CH_NAME, context)??name;
|
||||||
const originalTitle = super.getTitleNameByMode(name, PersonNameMode.EN_NAME, context) ?? name;
|
const originalTitle = super.getTitleNameByMode(name, PersonNameMode.EN_NAME, context) ?? name;
|
||||||
|
|
||||||
const result: DoubanMovieSubject = {
|
const result: DoubanMovieSubject = {
|
||||||
id: id ? id[0] : '',
|
id: id ? id[0] : '',
|
||||||
@ -119,14 +115,14 @@ export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<Do
|
|||||||
originalTitle: originalTitle,
|
originalTitle: originalTitle,
|
||||||
desc: obj.description,
|
desc: obj.description,
|
||||||
url: "https://movie.douban.com" + obj.url,
|
url: "https://movie.douban.com" + obj.url,
|
||||||
director: obj.director || [],
|
director: obj.director,
|
||||||
author: obj.author || [],
|
author: obj.author,
|
||||||
actor: obj.actor || [],
|
actor: obj.actor,
|
||||||
aggregateRating: obj.aggregateRating,
|
aggregateRating: obj.aggregateRating,
|
||||||
datePublished: obj.datePublished ? new Date(obj.datePublished) : undefined,
|
datePublished: obj.datePublished ? new Date(obj.datePublished) : undefined,
|
||||||
image: obj.image,
|
image: obj.image,
|
||||||
imageUrl: obj.image,
|
imageUrl: obj.image,
|
||||||
genre: obj.genre || [],
|
genre: obj.genre,
|
||||||
publisher: '',
|
publisher: '',
|
||||||
aliases: [""],
|
aliases: [""],
|
||||||
language: [""],
|
language: [""],
|
||||||
@ -136,52 +132,10 @@ export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<Do
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
})[0];
|
})[0];
|
||||||
|
this.handlePersonNameByMeta(html, movie, context, 'video:actor', 'actor');
|
||||||
|
this.handlePersonNameByMeta(html, movie, context, 'video:director', 'director');
|
||||||
|
|
||||||
// Fallback: if JSON-LD parsing failed (e.g., anti-bot page), extract from meta tags
|
const desc:string = html("span[property='v:summary']").text();
|
||||||
if (!movie) {
|
|
||||||
const title = html(html("head > meta[property='og:title']").get(0)).attr("content") || '';
|
|
||||||
const image = html(html("head > meta[property='og:image']").get(0)).attr("content") || '';
|
|
||||||
const urlMeta = html(html("head > meta[property='og:url']").get(0)).attr("content") || '';
|
|
||||||
const desc = html(html("head > meta[property='og:description']").get(0)).attr("content") || '';
|
|
||||||
|
|
||||||
// Extract ID from URL
|
|
||||||
const idPattern = /(\d){5,10}/g;
|
|
||||||
const idMatch = idPattern.exec(urlMeta);
|
|
||||||
const id = idMatch ? idMatch[0] : '';
|
|
||||||
|
|
||||||
// Extract score from HTML
|
|
||||||
const scoreText = html("#interest_sectl strong[property='v:average']").text();
|
|
||||||
const score = scoreText ? parseFloat(scoreText) : undefined;
|
|
||||||
|
|
||||||
movie = {
|
|
||||||
id,
|
|
||||||
title,
|
|
||||||
type: this.getSupportType(),
|
|
||||||
score,
|
|
||||||
originalTitle: title,
|
|
||||||
desc,
|
|
||||||
url: urlMeta || (id ? `https://movie.douban.com/subject/${id}/` : ''),
|
|
||||||
director: [],
|
|
||||||
author: [],
|
|
||||||
actor: [],
|
|
||||||
aggregateRating: undefined,
|
|
||||||
datePublished: undefined,
|
|
||||||
image,
|
|
||||||
imageUrl: image,
|
|
||||||
genre: [],
|
|
||||||
publisher: '',
|
|
||||||
aliases: [],
|
|
||||||
language: [],
|
|
||||||
country: [],
|
|
||||||
time: null,
|
|
||||||
IMDb: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
this.handlePersonNameByMeta(html, movie, context, 'video:actor', 'actor');
|
|
||||||
this.handlePersonNameByMeta(html, movie, context, 'video:director', 'director');
|
|
||||||
|
|
||||||
const desc: string = html("span[property='v:summary']").text();
|
|
||||||
if (desc) {
|
if (desc) {
|
||||||
movie.desc = desc;
|
movie.desc = desc;
|
||||||
}
|
}
|
||||||
@ -198,7 +152,7 @@ export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<Do
|
|||||||
// value = html(info.next.next).text().trim();
|
// value = html(info.next.next).text().trim();
|
||||||
const vas = html(info.next).text().trim();
|
const vas = html(info.next).text().trim();
|
||||||
value = vas.split("/").map((v) => v.trim());
|
value = vas.split("/").map((v) => v.trim());
|
||||||
} else if (key.indexOf('片长') >= 0) {
|
} else if(key.indexOf('片长') >= 0) {
|
||||||
value = html(info.next.next).text().trim()
|
value = html(info.next.next).text().trim()
|
||||||
} else {
|
} else {
|
||||||
value = html(info.next).text().trim();
|
value = html(info.next).text().trim();
|
||||||
@ -206,11 +160,11 @@ export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<Do
|
|||||||
valueMap.set(MovieKeyValueMap.get(key), value);
|
valueMap.set(MovieKeyValueMap.get(key), value);
|
||||||
})
|
})
|
||||||
|
|
||||||
movie.country = valueMap.has('country') ? valueMap.get('country') : [];
|
movie.country = valueMap.has('country') ? valueMap.get('country') : [];
|
||||||
movie.language = valueMap.has('language') ? valueMap.get('language') : [];
|
movie.language = valueMap.has('language') ? valueMap.get('language') : [];
|
||||||
movie.time = valueMap.has('time') ? valueMap.get('time') : "";
|
movie.time = valueMap.has('time') ? valueMap.get('time') : "";
|
||||||
movie.aliases = valueMap.has('aliases') ? valueMap.get('aliases') : [];
|
movie.aliases = valueMap.has('aliases') ? valueMap.get('aliases') : [];
|
||||||
movie.IMDb = valueMap.has('IMDb') ? valueMap.get('IMDb') : "";
|
movie.IMDb = valueMap.has('IMDb') ? valueMap.get('IMDb') : "";
|
||||||
return movie;
|
return movie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ export default class DoubanMusicLoadHandler extends DoubanAbstractLoadHandler<Do
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSupportType(): SupportType {
|
getSupportType(): SupportType {
|
||||||
return SupportType.music;
|
return SupportType.MUSIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
getHighQuantityImageUrl(fileName:string):string{
|
getHighQuantityImageUrl(fileName:string):string{
|
||||||
@ -88,9 +88,6 @@ export default class DoubanMusicLoadHandler extends DoubanAbstractLoadHandler<Do
|
|||||||
const idPattern = /(\d){5,10}/g;
|
const idPattern = /(\d){5,10}/g;
|
||||||
const id = idPattern.exec(url);
|
const id = idPattern.exec(url);
|
||||||
|
|
||||||
const trackItems = html('.track-list .track-items li');
|
|
||||||
const tracks = Array.from(trackItems).map(item => html(item).text().trim());
|
|
||||||
|
|
||||||
const result: DoubanMusicSubject = {
|
const result: DoubanMusicSubject = {
|
||||||
image: image,
|
image: image,
|
||||||
imageUrl: image,
|
imageUrl: image,
|
||||||
@ -107,10 +104,11 @@ export default class DoubanMusicLoadHandler extends DoubanAbstractLoadHandler<Do
|
|||||||
genre: valueMap.has('genre') ? [valueMap.get('genre')] : [""],
|
genre: valueMap.has('genre') ? [valueMap.get('genre')] : [""],
|
||||||
albumType: valueMap.has('albumType') ? valueMap.get('albumType') : "",
|
albumType: valueMap.has('albumType') ? valueMap.get('albumType') : "",
|
||||||
medium: valueMap.has('medium') ? valueMap.get('medium') : "",
|
medium: valueMap.has('medium') ? valueMap.get('medium') : "",
|
||||||
barcode: valueMap.has('barcode') ? valueMap.get('barcode') : "",
|
barcode: valueMap.has('barcode') ? valueMap.get('barcode') : ""
|
||||||
menu: tracks
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ export default class DoubanNoteLoadHandler extends DoubanAbstractLoadHandler<Dou
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSupportType(): SupportType {
|
getSupportType(): SupportType {
|
||||||
return SupportType.note;
|
return SupportType.NOTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
getHighQuantityImageUrl(fileName:string):string{
|
getHighQuantityImageUrl(fileName:string):string{
|
||||||
|
|||||||
@ -12,8 +12,8 @@ import {DataField} from "../../../utils/model/DataField";
|
|||||||
* 默认的处理器
|
* 默认的处理器
|
||||||
*/
|
*/
|
||||||
export default class DoubanOtherLoadHandler extends DoubanAbstractLoadHandler<DoubanSubject> {
|
export default class DoubanOtherLoadHandler extends DoubanAbstractLoadHandler<DoubanSubject> {
|
||||||
getSupportType(): SupportType.all {
|
getSupportType(): SupportType.ALL {
|
||||||
return SupportType.all;
|
return SupportType.ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: DoubanSubject, context: HandleContext): void {
|
parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: DoubanSubject, context: HandleContext): void {
|
||||||
|
|||||||
@ -21,35 +21,31 @@ export class DoubanTeleplayLoadHandler extends DoubanAbstractLoadHandler<DoubanT
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSupportType(): SupportType {
|
getSupportType(): SupportType {
|
||||||
return SupportType.teleplay;
|
return SupportType.TELEPLAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: DoubanTeleplaySubject, context: HandleContext): void {
|
parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: DoubanTeleplaySubject, context: HandleContext): void {
|
||||||
variableMap.set("director", new DataField("director", DataValueType.array, extract.director,(extract.director || []).map(SchemaOrg.getPersonName).filter(c => c)));
|
variableMap.set("director", new DataField("director", DataValueType.array, extract.director,extract.director.map(SchemaOrg.getPersonName).filter(c => c)));
|
||||||
variableMap.set("actor", new DataField(
|
variableMap.set("actor", new DataField(
|
||||||
"actor",
|
"actor",
|
||||||
DataValueType.array,
|
DataValueType.array,
|
||||||
extract.actor,
|
extract.actor,
|
||||||
(extract.actor || []).map(SchemaOrg.getPersonName).filter(c => c)
|
extract.actor.map(SchemaOrg.getPersonName).filter(c => c)
|
||||||
));
|
));
|
||||||
|
|
||||||
variableMap.set("author", new DataField(
|
variableMap.set("author", new DataField(
|
||||||
"author",
|
"author",
|
||||||
DataValueType.array,
|
DataValueType.array,
|
||||||
extract.author,
|
extract.author,
|
||||||
(extract.author || []).map(SchemaOrg.getPersonName).map(name => super.getPersonName(name, context)).filter(c => c)
|
extract.author.map(SchemaOrg.getPersonName).map(name => super.getPersonName(name, context)).filter(c => c)
|
||||||
|
));
|
||||||
|
|
||||||
|
variableMap.set("aliases", new DataField(
|
||||||
|
"aliases",
|
||||||
|
DataValueType.array,
|
||||||
|
extract.aliases,
|
||||||
|
extract.aliases.map(a => a.replace(TITLE_ALIASES_SPECIAL_CHAR_REG_G, '_'))
|
||||||
));
|
));
|
||||||
variableMap.set("aliases", new DataField("aliases", DataValueType.array, extract.aliases,
|
|
||||||
(extract.aliases || []).map(a=>a
|
|
||||||
.trim()
|
|
||||||
// .replace(TITLE_ALIASES_SPECIAL_CHAR_REG_G, '_')
|
|
||||||
// //replase multiple _ to single _
|
|
||||||
// .replace(/_+/g, '_')
|
|
||||||
// .replace(/^_/, '')
|
|
||||||
// .replace(/_$/, '')
|
|
||||||
.replace(/:\s+/g, ':')
|
|
||||||
)));
|
|
||||||
// super.parseAliases(beforeContent, variableMap, extract, context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
support(extract: DoubanSubject): boolean {
|
support(extract: DoubanSubject): boolean {
|
||||||
@ -84,7 +80,7 @@ export class DoubanTeleplayLoadHandler extends DoubanAbstractLoadHandler<DoubanT
|
|||||||
}
|
}
|
||||||
|
|
||||||
parseSubjectFromHtml(html: CheerioAPI, context: HandleContext): DoubanTeleplaySubject {
|
parseSubjectFromHtml(html: CheerioAPI, context: HandleContext): DoubanTeleplaySubject {
|
||||||
let teleplay: DoubanTeleplaySubject | undefined = html('script')
|
const teleplay:DoubanTeleplaySubject = html('script')
|
||||||
.get()
|
.get()
|
||||||
.filter(scd => "application/ld+json" == html(scd).attr("type"))
|
.filter(scd => "application/ld+json" == html(scd).attr("type"))
|
||||||
.map(i => {
|
.map(i => {
|
||||||
@ -104,14 +100,14 @@ export class DoubanTeleplayLoadHandler extends DoubanAbstractLoadHandler<DoubanT
|
|||||||
originalTitle: originalTitle,
|
originalTitle: originalTitle,
|
||||||
desc: obj.description,
|
desc: obj.description,
|
||||||
url: "https://movie.douban.com" + obj.url,
|
url: "https://movie.douban.com" + obj.url,
|
||||||
director: obj.director || [],
|
director: obj.director,
|
||||||
author: obj.author || [],
|
author: obj.author,
|
||||||
actor: obj.actor || [],
|
actor: obj.actor,
|
||||||
aggregateRating: obj.aggregateRating,
|
aggregateRating: obj.aggregateRating,
|
||||||
datePublished: obj.datePublished ? new Date(obj.datePublished) : undefined,
|
datePublished: obj.datePublished ? new Date(obj.datePublished) : undefined,
|
||||||
image: obj.image,
|
image: obj.image,
|
||||||
imageUrl: obj.image,
|
imageUrl: obj.image,
|
||||||
genre: obj.genre || [],
|
genre: obj.genre,
|
||||||
score: obj.aggregateRating ? obj.aggregateRating.ratingValue : undefined,
|
score: obj.aggregateRating ? obj.aggregateRating.ratingValue : undefined,
|
||||||
publisher: "",
|
publisher: "",
|
||||||
aliases: [""],
|
aliases: [""],
|
||||||
@ -124,46 +120,6 @@ export class DoubanTeleplayLoadHandler extends DoubanAbstractLoadHandler<DoubanT
|
|||||||
return result;
|
return result;
|
||||||
})[0];
|
})[0];
|
||||||
|
|
||||||
// Fallback: if JSON-LD parsing failed, extract from meta tags
|
|
||||||
if (!teleplay) {
|
|
||||||
const title = html(html("head > meta[property='og:title']").get(0)).attr("content") || '';
|
|
||||||
const image = html(html("head > meta[property='og:image']").get(0)).attr("content") || '';
|
|
||||||
const urlMeta = html(html("head > meta[property='og:url']").get(0)).attr("content") || '';
|
|
||||||
const desc = html(html("head > meta[property='og:description']").get(0)).attr("content") || '';
|
|
||||||
|
|
||||||
const idPattern = /(\d){5,10}/g;
|
|
||||||
const idMatch = idPattern.exec(urlMeta);
|
|
||||||
const id = idMatch ? idMatch[0] : '';
|
|
||||||
|
|
||||||
const scoreText = html("#interest_sectl strong[property='v:average']").text();
|
|
||||||
const score = scoreText ? parseFloat(scoreText) : undefined;
|
|
||||||
|
|
||||||
teleplay = {
|
|
||||||
id,
|
|
||||||
title,
|
|
||||||
type: this.getSupportType(),
|
|
||||||
score,
|
|
||||||
originalTitle: title,
|
|
||||||
desc,
|
|
||||||
url: urlMeta || (id ? `https://movie.douban.com/subject/${id}/` : ''),
|
|
||||||
director: [],
|
|
||||||
author: [],
|
|
||||||
actor: [],
|
|
||||||
aggregateRating: undefined,
|
|
||||||
datePublished: undefined,
|
|
||||||
image,
|
|
||||||
imageUrl: image,
|
|
||||||
genre: [],
|
|
||||||
publisher: '',
|
|
||||||
aliases: [],
|
|
||||||
language: [],
|
|
||||||
country: [],
|
|
||||||
episode: null,
|
|
||||||
time: null,
|
|
||||||
IMDb: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
this.handlePersonNameByMeta(html, teleplay, context, 'video:actor', 'actor');
|
this.handlePersonNameByMeta(html, teleplay, context, 'video:actor', 'actor');
|
||||||
this.handlePersonNameByMeta(html, teleplay, context, 'video:director', 'director');
|
this.handlePersonNameByMeta(html, teleplay, context, 'video:director', 'director');
|
||||||
const desc:string = html("span[property='v:summary']").text();
|
const desc:string = html("span[property='v:summary']").text();
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export default class DoubanTheaterLoadHandler extends DoubanAbstractLoadHandler<
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSupportType(): SupportType {
|
getSupportType(): SupportType {
|
||||||
return SupportType.theater;
|
return SupportType.THEATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
getHighQuantityImageUrl(fileName: string): string {
|
getHighQuantityImageUrl(fileName: string): string {
|
||||||
@ -33,36 +33,28 @@ export default class DoubanTheaterLoadHandler extends DoubanAbstractLoadHandler<
|
|||||||
"director",
|
"director",
|
||||||
DataValueType.array,
|
DataValueType.array,
|
||||||
extract.director,
|
extract.director,
|
||||||
(extract.director || []).map(SchemaOrg.getPersonName).filter(c => c)
|
extract.director.map(SchemaOrg.getPersonName).filter(c => c)
|
||||||
));
|
));
|
||||||
|
|
||||||
variableMap.set("actor", new DataField(
|
variableMap.set("actor", new DataField(
|
||||||
"actor",
|
"actor",
|
||||||
DataValueType.array,
|
DataValueType.array,
|
||||||
extract.actor,
|
extract.actor,
|
||||||
(extract.actor || []).map(SchemaOrg.getPersonName).filter(c => c)
|
extract.actor.map(SchemaOrg.getPersonName).filter(c => c)
|
||||||
));
|
));
|
||||||
|
|
||||||
variableMap.set("author", new DataField(
|
variableMap.set("author", new DataField(
|
||||||
"author",
|
"author",
|
||||||
DataValueType.array,
|
DataValueType.array,
|
||||||
extract.author,
|
extract.author,
|
||||||
(extract.author || []).map(SchemaOrg.getPersonName).map(name => super.getPersonName(name, context)).filter(c => c)
|
extract.author.map(SchemaOrg.getPersonName).map(name => super.getPersonName(name, context)).filter(c => c)
|
||||||
));
|
));
|
||||||
|
|
||||||
variableMap.set("aliases", new DataField(
|
variableMap.set("aliases", new DataField(
|
||||||
"aliases",
|
"aliases",
|
||||||
DataValueType.array,
|
DataValueType.array,
|
||||||
extract.aliases,
|
extract.aliases,
|
||||||
(extract.aliases || []).map(a => a
|
extract.aliases.map(a => a.replace(TITLE_ALIASES_SPECIAL_CHAR_REG_G, '_'))
|
||||||
.trim()
|
|
||||||
.replace(TITLE_ALIASES_SPECIAL_CHAR_REG_G, '_')
|
|
||||||
//replace multiple _ to single _
|
|
||||||
.replace(/_+/g, '_')
|
|
||||||
.replace(/^_/, '')
|
|
||||||
.replace(/_$/, '')
|
|
||||||
|
|
||||||
)
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,5 +6,4 @@ export default class DoubanMusicSubject extends DoubanSubject {
|
|||||||
medium: string;
|
medium: string;
|
||||||
records: number;
|
records: number;
|
||||||
barcode: string;
|
barcode: string;
|
||||||
menu: string[];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import DoubanSubject from "./DoubanSubject";
|
|||||||
|
|
||||||
export default interface HandleResult {
|
export default interface HandleResult {
|
||||||
content:string
|
content:string
|
||||||
filePath?:string
|
|
||||||
fileName?:string
|
fileName?:string
|
||||||
subject?:DoubanSubject,
|
subject?:DoubanSubject,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,10 +5,10 @@ import {SearchPageTypeOf} from "./SearchPageTypeOf";
|
|||||||
export class SearchPage extends SearchPageTypeOf<any> {
|
export class SearchPage extends SearchPageTypeOf<any> {
|
||||||
|
|
||||||
public static empty(type: SupportType): SearchPage {
|
public static empty(type: SupportType): SearchPage {
|
||||||
return new SearchPage(0, 1, 0, type, []);
|
return new SearchPage(0, 0, 0, type, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
static emptyWithNoType() {
|
static emptyWithNoType() {
|
||||||
return new SearchPage(0, 1, 0, null, []);
|
return new SearchPage(0, 0, 0, null, []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -77,7 +77,7 @@ export class SearchPageInfo {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return new SearchPageInfo(this.total, this._pageNum - 1,
|
return new SearchPageInfo(this.total, this._pageNum - 1,
|
||||||
this._pageSize, SupportType.all);
|
this._pageSize, SupportType.ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -20,10 +20,10 @@ export class SearchPageTypeOf<T> extends SearchPageInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static empty(type: SupportType): SearchPageTypeOf<any> {
|
public static empty(type: SupportType): SearchPageTypeOf<any> {
|
||||||
return new SearchPageTypeOf(0, 1, 0, type, []);
|
return new SearchPageTypeOf(0, 0, 0, type, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
static emptyWithNoType() {
|
static emptyWithNoType() {
|
||||||
return new SearchPageTypeOf(0, 1, 0, null, []);
|
return new SearchPageTypeOf(0, 0, 0, null, []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,9 @@
|
|||||||
import {
|
import {
|
||||||
DoubanSearchGroupPublishResultSubjectNextPage,
|
DoubanSearchGroupPublishResultSubjectNextPage, DoubanSearchGroupPublishResultSubjectPreviousPage,
|
||||||
DoubanSearchGroupPublishResultSubjectPreviousPage,
|
|
||||||
DoubanSearchResultSubject_EMPTY, DoubanSearchResultSubject_TIP_EMPTY,
|
|
||||||
DoubanSearchResultSubjectNextPage,
|
DoubanSearchResultSubjectNextPage,
|
||||||
DoubanSearchResultSubjectNextPageNeedLogin,
|
DoubanSearchResultSubjectNextPageNeedLogin,
|
||||||
DoubanSearchResultSubjectPreviousPage,
|
DoubanSearchResultSubjectPreviousPage,
|
||||||
NavigateType,
|
NavigateType, SEARCH_ITEM_PAGE_SIZE, SupportType
|
||||||
SEARCH_ITEM_PAGE_SIZE,
|
|
||||||
SupportType
|
|
||||||
} from "../../../constant/Constsant";
|
} from "../../../constant/Constsant";
|
||||||
import {FuzzySuggestModal, RequestUrlParam, request} from "obsidian";
|
import {FuzzySuggestModal, RequestUrlParam, request} from "obsidian";
|
||||||
|
|
||||||
@ -31,7 +27,7 @@ class DoubanFuzzySuggester extends FuzzySuggestModal<DoubanSearchResultSubject>
|
|||||||
private searchItem:string;
|
private searchItem:string;
|
||||||
|
|
||||||
constructor(plugin: DoubanPlugin, context: HandleContext, searchItem:string) {
|
constructor(plugin: DoubanPlugin, context: HandleContext, searchItem:string) {
|
||||||
super(plugin.app);
|
super(app);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.searchItem = searchItem;
|
this.searchItem = searchItem;
|
||||||
@ -110,18 +106,9 @@ class DoubanFuzzySuggester extends FuzzySuggestModal<DoubanSearchResultSubject>
|
|||||||
|
|
||||||
private initItems(searchPage: SearchPage) {
|
private initItems(searchPage: SearchPage) {
|
||||||
const doubanList: DoubanSearchResultSubject[] = searchPage.list;
|
const doubanList: DoubanSearchResultSubject[] = searchPage.list;
|
||||||
|
|
||||||
if (searchPage.type == SupportType.all && searchPage.pageNum == 1) {
|
|
||||||
if (doubanList.length == 0) {
|
|
||||||
// if (searchPage.list.length > 0) {
|
|
||||||
doubanList.push(DoubanSearchResultSubject_EMPTY);
|
|
||||||
}else if (searchPage.list.length < SEARCH_ITEM_PAGE_SIZE) {
|
|
||||||
doubanList.push(DoubanSearchResultSubject_TIP_EMPTY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (searchPage.hasNext) {
|
if (searchPage.hasNext) {
|
||||||
if (this.plugin.userComponent.isLogin()) {
|
if (this.plugin.userComponent.isLogin()) {
|
||||||
if (searchPage.type == SupportType.all && searchPage.pageNum == 1) {
|
if (searchPage.type == SupportType.ALL && searchPage.pageNum == 1) {
|
||||||
doubanList.push(DoubanSearchGroupPublishResultSubjectNextPage)
|
doubanList.push(DoubanSearchGroupPublishResultSubjectNextPage)
|
||||||
}else {
|
}else {
|
||||||
doubanList.push(DoubanSearchResultSubjectNextPage)
|
doubanList.push(DoubanSearchResultSubjectNextPage)
|
||||||
@ -131,7 +118,7 @@ class DoubanFuzzySuggester extends FuzzySuggestModal<DoubanSearchResultSubject>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (searchPage.hasPrevious) {
|
if (searchPage.hasPrevious) {
|
||||||
if (searchPage.type == SupportType.all && searchPage.pageNum == 2) {
|
if (searchPage.type == SupportType.ALL && searchPage.pageNum == 2) {
|
||||||
doubanList.unshift(DoubanSearchGroupPublishResultSubjectPreviousPage)
|
doubanList.unshift(DoubanSearchGroupPublishResultSubjectPreviousPage)
|
||||||
}else {
|
}else {
|
||||||
doubanList.unshift(DoubanSearchResultSubjectPreviousPage);
|
doubanList.unshift(DoubanSearchResultSubjectPreviousPage);
|
||||||
|
|||||||
@ -8,19 +8,16 @@ import {sleep} from "../../../utils/TimeUtil";
|
|||||||
|
|
||||||
export class DoubanSearchModal extends Modal {
|
export class DoubanSearchModal extends Modal {
|
||||||
searchTerm: string;
|
searchTerm: string;
|
||||||
searchType: SupportType = SupportType.all;
|
searchType: SupportType = SupportType.ALL;
|
||||||
plugin: DoubanPlugin;
|
plugin: DoubanPlugin;
|
||||||
context: HandleContext
|
context: HandleContext
|
||||||
|
|
||||||
constructor(app: App, plugin: DoubanPlugin, context: HandleContext, type: SupportType) {
|
constructor(app: App, plugin: DoubanPlugin, context: HandleContext) {
|
||||||
super(app);
|
super(app);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.searchType = type??SupportType.all;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
onOpen() {
|
onOpen() {
|
||||||
let {contentEl} = this;
|
let {contentEl} = this;
|
||||||
|
|
||||||
@ -45,7 +42,7 @@ export class DoubanSearchModal extends Modal {
|
|||||||
const typeSelect = content.createDiv("type-select");
|
const typeSelect = content.createDiv("type-select");
|
||||||
const typeSelectInput = new DropdownComponent(typeSelect)
|
const typeSelectInput = new DropdownComponent(typeSelect)
|
||||||
.addOptions(SearchTypeRecords)
|
.addOptions(SearchTypeRecords)
|
||||||
.setValue(this.searchType)
|
.setValue(SupportType.ALL)
|
||||||
.onChange((value:SupportType) => {
|
.onChange((value:SupportType) => {
|
||||||
this.searchType = value;
|
this.searchType = value;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,21 +1,31 @@
|
|||||||
import {
|
import {SupportType} from "../../../../constant/Constsant";
|
||||||
SupportType
|
|
||||||
} from "../../../../constant/Constsant";
|
|
||||||
import {SearchResultPageParserInterface} from "./SearchResultPageParserInterface";
|
import {SearchResultPageParserInterface} from "./SearchResultPageParserInterface";
|
||||||
import {SearchPage} from "../../model/SearchPage";
|
import {SearchPage} from "../../model/SearchPage";
|
||||||
import SearchParserHandler from "../SearchParser";
|
import SearchParserHandlerV2 from "../SearchParserV2";
|
||||||
|
import StringUtil from "../../../../utils/StringUtil";
|
||||||
import {log} from "../../../../utils/Logutil";
|
import {log} from "../../../../utils/Logutil";
|
||||||
|
|
||||||
export class AllFirstPageSearchResultPageParser implements SearchResultPageParserInterface {
|
export class AllFirstPageSearchResultPageParser implements SearchResultPageParserInterface {
|
||||||
support(type:SupportType, pageNum:number):boolean {
|
support(type:SupportType, pageNum:number):boolean {
|
||||||
return pageNum == 1 && type == SupportType.all;
|
return pageNum == 1 && type == SupportType.ALL;
|
||||||
}
|
}
|
||||||
parse(source:string, type:SupportType, pageNum:number, pageSize:number):SearchPage {
|
parse(source:string, type:SupportType, pageNum:number, pageSize:number):SearchPage {
|
||||||
log.debug("解析给多页面结果");
|
if (!source || StringUtil.notJsonString(source)) {
|
||||||
if (!source) {
|
//TODO 国际化
|
||||||
return new SearchPage(0, 0, 0, type, []);
|
log.notice("Obsidian-Douban:查询结果为空,无匹配结果,请尝试登录获取获取更多数据(已登录则忽略)");
|
||||||
|
return SearchPage.empty(type);
|
||||||
}
|
}
|
||||||
return SearchParserHandler.parseSearchJson(source, type, pageNum);
|
|
||||||
|
const {subjects} = JSON.parse(source);
|
||||||
|
if (!subjects) {
|
||||||
|
return SearchPage.empty(type);
|
||||||
|
}
|
||||||
|
const {items} = subjects;
|
||||||
|
if (!items ||items.length == 0) {
|
||||||
|
return SearchPage.empty(type);
|
||||||
|
}
|
||||||
|
const doubanSearchResultSubjects = SearchParserHandlerV2.itemMapToSearchResult(items);
|
||||||
|
return new SearchPage(2000, pageNum, pageSize, type, doubanSearchResultSubjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import SearchParserHandler from "../SearchParser";
|
|||||||
|
|
||||||
export class NotAllPageSearchResultPageParser implements SearchResultPageParserInterface {
|
export class NotAllPageSearchResultPageParser implements SearchResultPageParserInterface {
|
||||||
support(type:SupportType, pageNum:number):boolean {
|
support(type:SupportType, pageNum:number):boolean {
|
||||||
return type != SupportType.all && !(pageNum ==1 && type == SupportType.note);
|
return type != SupportType.ALL && !(pageNum ==1 && type == SupportType.NOTE);
|
||||||
}
|
}
|
||||||
parse(source:string, type:SupportType, pageNum:number, pageSize:number):SearchPage {
|
parse(source:string, type:SupportType, pageNum:number, pageSize:number):SearchPage {
|
||||||
log.debug("解析给多页面结果");
|
log.debug("解析给多页面结果");
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import DoubanSearchResultSubject from "../../model/DoubanSearchResultSubject";
|
|||||||
|
|
||||||
export class NoteFirstPageSearchResultPageParser implements SearchResultPageParserInterface {
|
export class NoteFirstPageSearchResultPageParser implements SearchResultPageParserInterface {
|
||||||
support(type:SupportType, pageNum:number):boolean {
|
support(type:SupportType, pageNum:number):boolean {
|
||||||
return pageNum == 1 && type == SupportType.note;
|
return pageNum == 1 && type == SupportType.NOTE;
|
||||||
}
|
}
|
||||||
parse(source:string, type:SupportType, pageNum:number, pageSize:number):SearchPage {
|
parse(source:string, type:SupportType, pageNum:number, pageSize:number):SearchPage {
|
||||||
const pageData = load(source);
|
const pageData = load(source);
|
||||||
|
|||||||
@ -2,18 +2,21 @@ import {SupportType} from "../../../../constant/Constsant";
|
|||||||
import {SearchResultPageParserInterface} from "./SearchResultPageParserInterface";
|
import {SearchResultPageParserInterface} from "./SearchResultPageParserInterface";
|
||||||
import {log} from "../../../../utils/Logutil";
|
import {log} from "../../../../utils/Logutil";
|
||||||
import {SearchPage} from "../../model/SearchPage";
|
import {SearchPage} from "../../model/SearchPage";
|
||||||
import SearchParserHandler from "../SearchParser";
|
import SearchParserHandlerV2 from "../SearchParserV2";
|
||||||
|
|
||||||
export class OtherAllPageSearchResultPageParser implements SearchResultPageParserInterface {
|
export class OtherAllPageSearchResultPageParser implements SearchResultPageParserInterface {
|
||||||
support(type:SupportType, pageNum:number):boolean {
|
support(type:SupportType, pageNum:number):boolean {
|
||||||
return pageNum > 1 && type == SupportType.all;
|
return pageNum > 1 && type == SupportType.ALL;
|
||||||
}
|
}
|
||||||
parse(source:string, type:SupportType, pageNum:number, pageSize:number):SearchPage {
|
parse(source:string, type:SupportType, pageNum:number, pageSize:number):SearchPage {
|
||||||
log.debug("解析给多页面结果");
|
log.debug("解析给多页面结果");
|
||||||
if (!source) {
|
const {contents} = JSON.parse(source);
|
||||||
|
if (!contents) {
|
||||||
return new SearchPage(0, 0, 0, type, []);
|
return new SearchPage(0, 0, 0, type, []);
|
||||||
}
|
}
|
||||||
return SearchParserHandler.parseSearchJson(source, type, pageNum);
|
const data:{total:number, start:number, count:number, items:any[]} = contents;
|
||||||
|
const doubanSearchResultSubjects = SearchParserHandlerV2.itemMapToSearchResult(data.items);
|
||||||
|
return new SearchPage(data.total, pageNum, pageSize, type, doubanSearchResultSubjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,9 +17,8 @@ export abstract class AbstractSearchPageFetcher implements SearchPageFetcherInte
|
|||||||
|
|
||||||
support(type: SupportType, pageNum?:number): boolean {
|
support(type: SupportType, pageNum?:number): boolean {
|
||||||
throw new Error("Method not implemented.");
|
throw new Error("Method not implemented.");
|
||||||
}
|
}
|
||||||
|
fetch(keyword: string, pageNum: number, pageSize: number): Promise<string> {
|
||||||
fetch(keyword: string, pageNum: number, pageSize: number): Promise<string> {
|
|
||||||
const start:number = Math.floor((pageNum - 1) * pageSize);
|
const start:number = Math.floor((pageNum - 1) * pageSize);
|
||||||
const url:string = this.getSearchUrl(keyword, start, pageSize);
|
const url:string = this.getSearchUrl(keyword, start, pageSize);
|
||||||
if (!url) {
|
if (!url) {
|
||||||
@ -28,8 +27,7 @@ export abstract class AbstractSearchPageFetcher implements SearchPageFetcherInte
|
|||||||
return DoubanHttpUtil.httpRequestGet(url, this.settingsManager.getHeaders(), this.settingsManager)
|
return DoubanHttpUtil.httpRequestGet(url, this.settingsManager.getHeaders(), this.settingsManager)
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
throw log.error(i18nHelper.getMessage('130101').replace('{0}', e.toString()), e);
|
throw log.error(i18nHelper.getMessage('130101').replace('{0}', e.toString()), e);
|
||||||
});
|
}); }
|
||||||
}
|
|
||||||
|
|
||||||
getSearchUrl(keyword: string, start: number, pageSize: number):string {
|
getSearchUrl(keyword: string, start: number, pageSize: number):string {
|
||||||
keyword = keyword.trim();
|
keyword = keyword.trim();
|
||||||
|
|||||||
@ -2,11 +2,11 @@ import {AbstractSearchPageFetcher} from "./AbstractSearchPageFetcher";
|
|||||||
import { SupportType } from "src/org/wanxp/constant/Constsant";
|
import { SupportType } from "src/org/wanxp/constant/Constsant";
|
||||||
|
|
||||||
export class AllPageSearchPageFetcher extends AbstractSearchPageFetcher {
|
export class AllPageSearchPageFetcher extends AbstractSearchPageFetcher {
|
||||||
getUrl(keyword: string, start: number, pageSize: number): string {
|
getUrl(keyword: string, pageNum: number, pageSize: number): string {
|
||||||
return `https://www.douban.com/j/search?q=${keyword}&start=${start}`;
|
return `https://m.douban.com/rexxar/api/v2/search?q=${keyword}&start=${pageNum}&count=${pageSize}`;
|
||||||
}
|
}
|
||||||
support(type: SupportType): boolean {
|
support(type: SupportType): boolean {
|
||||||
return type == SupportType.all;
|
return type == SupportType.ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ export class BookPageSearchPageFetcher extends AbstractSearchPageFetcher {
|
|||||||
return `https://www.douban.com/j/search?q=${keyword}&start=${start}&cat=1001`;
|
return `https://www.douban.com/j/search?q=${keyword}&start=${start}&cat=1001`;
|
||||||
}
|
}
|
||||||
support(type: SupportType): boolean {
|
support(type: SupportType): boolean {
|
||||||
return type == SupportType.book;
|
return type == SupportType.BOOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ export class GamePageSearchPageFetcher extends AbstractSearchPageFetcher {
|
|||||||
return `https://www.douban.com/j/search?q=${keyword}&start=${start}&cat=3114`;
|
return `https://www.douban.com/j/search?q=${keyword}&start=${start}&cat=3114`;
|
||||||
}
|
}
|
||||||
support(type: SupportType): boolean {
|
support(type: SupportType): boolean {
|
||||||
return type == SupportType.game;
|
return type == SupportType.GAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ export class MoviePageSearchPageFetcher extends AbstractSearchPageFetcher {
|
|||||||
return `https://www.douban.com/j/search?q=${keyword}&start=${start}&cat=1002`;
|
return `https://www.douban.com/j/search?q=${keyword}&start=${start}&cat=1002`;
|
||||||
}
|
}
|
||||||
support(type: SupportType): boolean {
|
support(type: SupportType): boolean {
|
||||||
return type == SupportType.movie;
|
return type == SupportType.MOVIE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ export class MusicPageSearchPageFetcher extends AbstractSearchPageFetcher {
|
|||||||
return `https://www.douban.com/j/search?q=${keyword}&start=${start}&cat=1003`;
|
return `https://www.douban.com/j/search?q=${keyword}&start=${start}&cat=1003`;
|
||||||
}
|
}
|
||||||
support(type: SupportType): boolean {
|
support(type: SupportType): boolean {
|
||||||
return type == SupportType.music;
|
return type == SupportType.MUSIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ export class NoteFirstPageSearchPageFetcher extends AbstractSearchPageFetcher {
|
|||||||
return `https://www.douban.com/search?cat=1015&q=${keyword}`;
|
return `https://www.douban.com/search?cat=1015&q=${keyword}`;
|
||||||
}
|
}
|
||||||
support(type: SupportType, pageNum:number): boolean {
|
support(type: SupportType, pageNum:number): boolean {
|
||||||
return type == SupportType.note && pageNum == 1;
|
return type == SupportType.NOTE && pageNum == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ export class NotePageSearchPageFetcher extends AbstractSearchPageFetcher {
|
|||||||
return `https://www.douban.com/j/search?q=${keyword}&start=${start}&cat=1015`;
|
return `https://www.douban.com/j/search?q=${keyword}&start=${start}&cat=1015`;
|
||||||
}
|
}
|
||||||
support(type: SupportType, pageNum:number): boolean {
|
support(type: SupportType, pageNum:number): boolean {
|
||||||
return type == SupportType.note && pageNum > 1;
|
return type == SupportType.NOTE && pageNum > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ export class TheaterPageSearchPageFetcher extends AbstractSearchPageFetcher {
|
|||||||
return `https://www.douban.com/j/search?q=${keyword}&start=${start}&cat=3069`;
|
return `https://www.douban.com/j/search?q=${keyword}&start=${start}&cat=3069`;
|
||||||
}
|
}
|
||||||
support(type: SupportType): boolean {
|
support(type: SupportType): boolean {
|
||||||
return type == SupportType.theater;
|
return type == SupportType.THEATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import {createFolderSelectionSetting} from "./TemplateSettingHelper";
|
|||||||
import StringUtil from "../../utils/StringUtil";
|
import StringUtil from "../../utils/StringUtil";
|
||||||
import {log} from "../../utils/Logutil";
|
import {log} from "../../utils/Logutil";
|
||||||
import DoubanPlugin from "../../main";
|
import DoubanPlugin from "../../main";
|
||||||
import {SearchTypeRecords, SupportType, SupportTypeMap} from "../../constant/Constsant";
|
|
||||||
|
|
||||||
export function constructBasicUI(containerEl: HTMLElement, manager: SettingsManager) {
|
export function constructBasicUI(containerEl: HTMLElement, manager: SettingsManager) {
|
||||||
// containerEl.createEl('h3', { text: i18nHelper.getMessage('1210') });
|
// containerEl.createEl('h3', { text: i18nHelper.getMessage('1210') });
|
||||||
@ -98,19 +97,6 @@ export function constructBasicUI(containerEl: HTMLElement, manager: SettingsMana
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
new Setting(containerEl)
|
|
||||||
.setName(i18nHelper.getMessage('121410'))
|
|
||||||
.setDesc(i18nHelper.getMessage('121411'))
|
|
||||||
.addDropdown((dropdown) => {
|
|
||||||
dropdown
|
|
||||||
.addOptions(SearchTypeRecords)
|
|
||||||
.setValue(manager.plugin.settings.searchDefaultType)
|
|
||||||
.onChange(async (value) => {
|
|
||||||
// @ts-ignore
|
|
||||||
manager.plugin.settings.searchDefaultType = SupportTypeMap[value];
|
|
||||||
await manager.plugin.saveSettings();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import {i18nHelper} from "../../lang/helper";
|
|||||||
import SettingsManager from "./SettingsManager";
|
import SettingsManager from "./SettingsManager";
|
||||||
import {CustomProperty} from "./model/CustomProperty";
|
import {CustomProperty} from "./model/CustomProperty";
|
||||||
import {ButtonComponent, DropdownComponent, ExtraButtonComponent, Setting, TextComponent} from "obsidian";
|
import {ButtonComponent, DropdownComponent, ExtraButtonComponent, Setting, TextComponent} from "obsidian";
|
||||||
import {SupportType, SupportTypeMap} from "../../constant/Constsant";
|
import {SupportType} from "../../constant/Constsant";
|
||||||
import DoubanPlugin from "../../main";
|
import DoubanPlugin from "../../main";
|
||||||
|
|
||||||
export function constructCustomPropertySettingsUI(containerEl: HTMLElement, manager: SettingsManager) {
|
export function constructCustomPropertySettingsUI(containerEl: HTMLElement, manager: SettingsManager) {
|
||||||
@ -16,7 +16,7 @@ export function constructCustomPropertySettingsUI(containerEl: HTMLElement, mana
|
|||||||
button.setTooltip(i18nHelper.getMessage('124101'));
|
button.setTooltip(i18nHelper.getMessage('124101'));
|
||||||
button.setIcon('plus');
|
button.setIcon('plus');
|
||||||
button.onClick(async () => {
|
button.onClick(async () => {
|
||||||
customProperties.push({name: '', value: '', field: SupportType.all});
|
customProperties.push({name: '', value: '', field: SupportType.ALL});
|
||||||
constructCustomPropertyUI(list, customProperties, manager);
|
constructCustomPropertyUI(list, customProperties, manager);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -68,15 +68,11 @@ function addFilterInput(data: CustomProperty, el: HTMLElement, customProperties:
|
|||||||
|
|
||||||
const fieldsDropdown = new DropdownComponent(el);
|
const fieldsDropdown = new DropdownComponent(el);
|
||||||
for (const fieldSelect in SupportType) {
|
for (const fieldSelect in SupportType) {
|
||||||
|
// @ts-ignore
|
||||||
fieldsDropdown.addOption(fieldSelect, i18nHelper.getMessage(fieldSelect));
|
fieldsDropdown.addOption(fieldSelect, i18nHelper.getMessage(fieldSelect));
|
||||||
}
|
}
|
||||||
item.createEl('span', { text: i18nHelper.getMessage('124106') });
|
item.createEl('span', { text: i18nHelper.getMessage('124106') });
|
||||||
let dataFieldValue = data.field;
|
fieldsDropdown.setValue(data.field)
|
||||||
if(typeof dataFieldValue === 'string') {
|
|
||||||
// @ts-ignore
|
|
||||||
dataFieldValue = SupportTypeMap[dataFieldValue];
|
|
||||||
}
|
|
||||||
fieldsDropdown.setValue(dataFieldValue)
|
|
||||||
.onChange(async (value: SupportType) => {
|
.onChange(async (value: SupportType) => {
|
||||||
customProperties[idx].field = value;
|
customProperties[idx].field = value;
|
||||||
await manager.plugin.saveSettings();
|
await manager.plugin.saveSettings();
|
||||||
|
|||||||
@ -10,17 +10,17 @@ export function constructLoginUI(containerEl: HTMLElement, manager: SettingsMana
|
|||||||
// containerEl.createEl('h3', { text: i18nHelper.getMessage('1210') });
|
// containerEl.createEl('h3', { text: i18nHelper.getMessage('1210') });
|
||||||
|
|
||||||
const userComponent = manager.plugin.userComponent;
|
const userComponent = manager.plugin.userComponent;
|
||||||
if (userComponent.isLogin() && !userComponent.isVerified()) {
|
if (userComponent.needLogin()) {
|
||||||
// Assumed login — verify to get user ID/name for settings display
|
try {
|
||||||
userComponent.login()
|
userComponent.login()
|
||||||
.then(() => constructDoubanLoginSettingsUI(containerEl, manager))
|
.then(() => {
|
||||||
.catch(() => constructDoubanLoginSettingsUI(containerEl, manager));
|
constructDoubanLoginSettingsUI(containerEl, manager);
|
||||||
} else if (userComponent.needLogin()) {
|
});
|
||||||
// Has credentials but not yet logged in
|
}catch (e) {
|
||||||
userComponent.login()
|
log.debug(i18nHelper.getMessage('100101'));
|
||||||
.then(() => constructDoubanLoginSettingsUI(containerEl, manager))
|
constructDoubanLoginSettingsUI(containerEl, manager);
|
||||||
.catch(() => constructDoubanLoginSettingsUI(containerEl, manager));
|
}
|
||||||
} else {
|
}else {
|
||||||
constructDoubanLoginSettingsUI(containerEl, manager);
|
constructDoubanLoginSettingsUI(containerEl, manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -33,8 +33,8 @@ export function showFileExample(containerEl: HTMLElement, manager: SettingsManag
|
|||||||
const document = new DocumentFragment();
|
const document = new DocumentFragment();
|
||||||
document.createDiv('file-path-example')
|
document.createDiv('file-path-example')
|
||||||
.innerHTML = `${i18nHelper.getMessage('121604')}<a href="https://book.douban.com/subject/2253379/">《简爱》</a>: ${VariableUtil.replaceSubject(EXAMPLE_SUBJECT_MAP,
|
.innerHTML = `${i18nHelper.getMessage('121604')}<a href="https://book.douban.com/subject/2253379/">《简爱》</a>: ${VariableUtil.replaceSubject(EXAMPLE_SUBJECT_MAP,
|
||||||
FileUtil.join(manager.plugin.settings.dataFilePath, manager.plugin.settings.dataFileNamePath + ".md"), SupportType.book,
|
FileUtil.join(manager.plugin.settings.dataFilePath, manager.plugin.settings.dataFileNamePath + ".md"), SupportType.BOOK,
|
||||||
manager, 'path')}`;
|
manager)}`;
|
||||||
|
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
.setName(i18nHelper.getMessage('120603'))
|
.setName(i18nHelper.getMessage('120603'))
|
||||||
@ -223,8 +223,7 @@ export function constructAttachmentFileSettingsUI(containerEl: HTMLElement, mana
|
|||||||
}else {
|
}else {
|
||||||
new Setting(containerEl).then(createFolderSelectionSetting({containerEl: containerEl, name: '121432', desc: '121433', placeholder: null, key: null, manager: manager}));
|
new Setting(containerEl).then(createFolderSelectionSetting({containerEl: containerEl, name: '121432', desc: '121433', placeholder: null, key: null, manager: manager}));
|
||||||
new Setting(containerEl).then(createFolderSelectionSettingInput({containerEl: containerEl, name: null, desc: null, placeholder: '121434', key: 'attachmentPath', manager: manager}));
|
new Setting(containerEl).then(createFolderSelectionSettingInput({containerEl: containerEl, name: null, desc: null, placeholder: '121434', key: 'attachmentPath', manager: manager}));
|
||||||
new Setting(containerEl).then(createFolderSelectionSetting({containerEl: containerEl, name: '121452', desc: '121453', placeholder: null, key: null, manager: manager}));
|
|
||||||
new Setting(containerEl).then(createFolderSelectionSettingInput({containerEl: containerEl, name: null, desc: null, placeholder: '121454', key: 'attachmentFileName', manager: manager}));
|
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -301,16 +301,6 @@ ${i18nHelper.getMessage('122004')}
|
|||||||
<td>${i18nHelper.getMessage('310520')}</th>
|
<td>${i18nHelper.getMessage('310520')}</th>
|
||||||
<td>${i18nHelper.getMessage('310620')}</th>
|
<td>${i18nHelper.getMessage('310620')}</th>
|
||||||
<td>${i18nHelper.getMessage('310720')}</th>
|
<td>${i18nHelper.getMessage('310720')}</th>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>${i18nHelper.getMessage('320111')}</th>
|
|
||||||
<td>${i18nHelper.getMessage('310122')}</th>
|
|
||||||
<td>${i18nHelper.getMessage('310222')}</th>
|
|
||||||
<td>${i18nHelper.getMessage('310322')}</th>
|
|
||||||
<td>${i18nHelper.getMessage('310422')}</th>
|
|
||||||
<td>${i18nHelper.getMessage('310522')}</th>
|
|
||||||
<td>${i18nHelper.getMessage('310622')}</th>
|
|
||||||
<td>${i18nHelper.getMessage('310722')}</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>`;
|
</table>`;
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import {SyncHandledData} from "./SyncHandledData";
|
|||||||
import {ArraySetting} from "./ArraySetting";
|
import {ArraySetting} from "./ArraySetting";
|
||||||
import {ScoreSetting} from "./ScoreSetting";
|
import {ScoreSetting} from "./ScoreSetting";
|
||||||
import PictureBedSetting from "./PictureBedSetting";
|
import PictureBedSetting from "./PictureBedSetting";
|
||||||
import {SupportType} from "../../../constant/Constsant";
|
|
||||||
|
|
||||||
export interface DoubanPluginSetting {
|
export interface DoubanPluginSetting {
|
||||||
onlineSettingsFileName: string;
|
onlineSettingsFileName: string;
|
||||||
@ -33,7 +32,6 @@ export interface DoubanPluginSetting {
|
|||||||
cacheImage: boolean,
|
cacheImage: boolean,
|
||||||
cacheHighQuantityImage: boolean,
|
cacheHighQuantityImage: boolean,
|
||||||
attachmentPath: string,
|
attachmentPath: string,
|
||||||
attachmentFileName: string,
|
|
||||||
pictureBedFlag: boolean
|
pictureBedFlag: boolean
|
||||||
pictureBedType: string;
|
pictureBedType: string;
|
||||||
pictureBedSetting: PictureBedSetting;
|
pictureBedSetting: PictureBedSetting;
|
||||||
@ -41,5 +39,4 @@ export interface DoubanPluginSetting {
|
|||||||
// syncLastUpdateTime: Map<string, string>,
|
// syncLastUpdateTime: Map<string, string>,
|
||||||
arraySettings: ArraySetting[],
|
arraySettings: ArraySetting[],
|
||||||
scoreSetting: ScoreSetting,
|
scoreSetting: ScoreSetting,
|
||||||
searchDefaultType: SupportType,
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,9 +11,6 @@ import {i18nHelper} from "../../../lang/helper";
|
|||||||
import {DoubanTeleplaySyncHandler} from "./DoubanTeleplaySyncHandler";
|
import {DoubanTeleplaySyncHandler} from "./DoubanTeleplaySyncHandler";
|
||||||
import {SyncConditionType} from "../../../constant/Constsant";
|
import {SyncConditionType} from "../../../constant/Constsant";
|
||||||
import {DoubanGameSyncHandler} from "./DoubanGameSyncHandler";
|
import {DoubanGameSyncHandler} from "./DoubanGameSyncHandler";
|
||||||
import {DataField} from "../../../utils/model/DataField";
|
|
||||||
import {VariableUtil} from "../../../utils/VariableUtil";
|
|
||||||
import {FileUtil} from "../../../utils/FileUtil";
|
|
||||||
|
|
||||||
export default class SyncHandler {
|
export default class SyncHandler {
|
||||||
private app: App;
|
private app: App;
|
||||||
@ -104,7 +101,7 @@ export default class SyncHandler {
|
|||||||
`;
|
`;
|
||||||
}else {
|
}else {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
details+= `${value.id}-[[${FileUtil.replaceSpecialCharactersForFileName(value.title)}]]: ${i18nHelper.getMessage(value.status)}
|
details+= `${value.id}-[[${value.title}]]: ${i18nHelper.getMessage(value.status)}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,7 +40,7 @@ export abstract class DoubanGameListHandler extends DoubanAbstractListHandler {
|
|||||||
.find("div.title > a")
|
.find("div.title > a")
|
||||||
.text()
|
.text()
|
||||||
.trim();
|
.trim();
|
||||||
const updateDateStr: string = item.find("span.date").text().trim();
|
const updateDateStr: string = item.find("div.date").text().trim();
|
||||||
let updateDate = null;
|
let updateDate = null;
|
||||||
try {
|
try {
|
||||||
updateDate = new Date(updateDateStr);
|
updateDate = new Date(updateDateStr);
|
||||||
@ -73,10 +73,11 @@ export abstract class DoubanGameListHandler extends DoubanAbstractListHandler {
|
|||||||
});
|
});
|
||||||
const {syncConfig} = context;
|
const {syncConfig} = context;
|
||||||
const {scope} = syncConfig;
|
const {scope} = syncConfig;
|
||||||
|
const pattern = /(\d+)/g;
|
||||||
|
|
||||||
const wishCount = this.getCount(countDescs, '想玩');
|
const wishCount = this.getCount(countDescs, '想玩', pattern);
|
||||||
const collectCount = this.getCount(countDescs, '玩过');
|
const collectCount = this.getCount(countDescs, '玩过', pattern);
|
||||||
const doCount = this.getCount(countDescs, '在玩');
|
const doCount = this.getCount(countDescs, '在玩', pattern);
|
||||||
|
|
||||||
|
|
||||||
switch (scope) {
|
switch (scope) {
|
||||||
@ -93,9 +94,8 @@ export abstract class DoubanGameListHandler extends DoubanAbstractListHandler {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private getCount(countDescs:string[], keyword:string):number {
|
private getCount(countDescs:string[], keyword:string, pattern:RegExp):number {
|
||||||
return countDescs.filter(desc => desc.includes(keyword)).map(desc => {
|
return countDescs.filter(desc => desc.includes(keyword)).map(desc => {
|
||||||
const pattern = /(\d+)/g;
|
|
||||||
const result = pattern.exec(desc);
|
const result = pattern.exec(desc);
|
||||||
return result ? parseInt(result[0], 10) : 0;
|
return result ? parseInt(result[0], 10) : 0;
|
||||||
})[0];
|
})[0];
|
||||||
|
|||||||
@ -13,7 +13,6 @@ export interface SyncConfig {
|
|||||||
|
|
||||||
cacheHighQuantityImage:boolean;
|
cacheHighQuantityImage:boolean;
|
||||||
attachmentPath: string;
|
attachmentPath: string;
|
||||||
attachmentFileName: string;
|
|
||||||
templateFile: string;
|
templateFile: string;
|
||||||
incrementalUpdate: boolean;
|
incrementalUpdate: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,6 @@ import {DoubanHttpUtil} from "../../utils/DoubanHttpUtil";
|
|||||||
export default class UserComponent {
|
export default class UserComponent {
|
||||||
private settingsManager: SettingsManager;
|
private settingsManager: SettingsManager;
|
||||||
private user: User;
|
private user: User;
|
||||||
private verified: boolean = false;
|
|
||||||
|
|
||||||
constructor(settingsManager: SettingsManager) {
|
constructor(settingsManager: SettingsManager) {
|
||||||
this.settingsManager = settingsManager;
|
this.settingsManager = settingsManager;
|
||||||
@ -40,26 +39,11 @@ export default class UserComponent {
|
|||||||
this.user.login = false;
|
this.user.login = false;
|
||||||
}
|
}
|
||||||
this.user = null;
|
this.user = null;
|
||||||
this.verified = false;
|
|
||||||
this.settingsManager.updateSetting('loginCookiesContent', '');
|
this.settingsManager.updateSetting('loginCookiesContent', '');
|
||||||
this.settingsManager.updateSetting('loginHeadersContent', '');
|
this.settingsManager.updateSetting('loginHeadersContent', '');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assumeLoggedIn(): void {
|
|
||||||
const headers: any = this.settingsManager.getSetting('loginHeadersContent');
|
|
||||||
const cookies: any = this.settingsManager.getSetting('loginCookiesContent');
|
|
||||||
if (headers || cookies) {
|
|
||||||
this.user = new User();
|
|
||||||
this.user.login = true;
|
|
||||||
this.verified = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isVerified(): boolean {
|
|
||||||
return this.verified;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
needLogin() {
|
needLogin() {
|
||||||
@ -84,7 +68,6 @@ export default class UserComponent {
|
|||||||
this.settingsManager.debug(`配置界面:loginCookie:豆瓣headers信息正常,${user&&user.id?'获取用户信息成功id:'+ StringUtil.confuse(user.id) + ',用户名:'+ StringUtil.confuse(user.name) :'获取用户信息失败'}`);
|
this.settingsManager.debug(`配置界面:loginCookie:豆瓣headers信息正常,${user&&user.id?'获取用户信息成功id:'+ StringUtil.confuse(user.id) + ',用户名:'+ StringUtil.confuse(user.name) :'获取用户信息失败'}`);
|
||||||
});
|
});
|
||||||
if(this.user) {
|
if(this.user) {
|
||||||
this.verified = true;
|
|
||||||
this.settingsManager.updateSetting('loginHeadersContent', JSON.stringify(headers));
|
this.settingsManager.updateSetting('loginHeadersContent', JSON.stringify(headers));
|
||||||
}
|
}
|
||||||
return this.user;
|
return this.user;
|
||||||
@ -156,9 +139,6 @@ export default class UserComponent {
|
|||||||
this.user = user;
|
this.user = user;
|
||||||
this.settingsManager.debug(`主界面:loginByCookie:豆瓣cookies信息正常,${user&&user.id?'获取用户信息成功id:'+ StringUtil.confuse(user.id) + ',用户名:'+ StringUtil.confuse(user.name) :'获取用户信息失败'}`);
|
this.settingsManager.debug(`主界面:loginByCookie:豆瓣cookies信息正常,${user&&user.id?'获取用户信息成功id:'+ StringUtil.confuse(user.id) + ',用户名:'+ StringUtil.confuse(user.name) :'获取用户信息失败'}`);
|
||||||
});
|
});
|
||||||
if (this.user && this.user.id) {
|
|
||||||
this.verified = true;
|
|
||||||
}
|
|
||||||
return this.user;
|
return this.user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,13 @@
|
|||||||
//简体中文
|
//简体中文
|
||||||
export default {
|
export default {
|
||||||
//main.ts
|
//main.ts
|
||||||
'110001': 'search by current file name',
|
'110001': 'search douban by current file name',
|
||||||
'110002': 'search and import to current file',
|
'110002': 'search douban and import to current file',
|
||||||
'110003': `Enter Search Term:`,
|
'110003': `Enter Search Term:`,
|
||||||
'110004': `Search`,
|
'110004': `Search`,
|
||||||
'110005': `Cancel`,
|
'110005': `Cancel`,
|
||||||
'110006': `sync personal book-movie-music to Obsidian`,
|
'110006': `sync douban personal book-movie-music to Obsidian`,
|
||||||
'110101': 'search and create file',
|
'110101': 'search douban and create file',
|
||||||
'110102': 'search movie or tv and create ',
|
|
||||||
'110104': 'search book and create',
|
|
||||||
'110105': 'search music and create ',
|
|
||||||
'110106': 'search game and create ',
|
|
||||||
|
|
||||||
'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',
|
'110103': 'sync personal data from douban',
|
||||||
@ -245,19 +240,12 @@ PS: This file could be delete if you want to.
|
|||||||
'121401': `Status Bar`,
|
'121401': `Status Bar`,
|
||||||
'121402': `Display status bar when import data ?`,
|
'121402': `Display status bar when import data ?`,
|
||||||
|
|
||||||
'121410': `Search Default Type`,
|
'121430': `Save Attachment File`,
|
||||||
'121411': `Search defuault type when open command palette 'search douban and create file'`,
|
|
||||||
|
|
||||||
'121430': `Save Attachment(Picture) File`,
|
|
||||||
'121431': `Save attachment file to local disk, such as image ? If you do not enable this feature, it will not show cover image in note`,
|
'121431': `Save attachment file to local disk, such as image ? If you do not enable this feature, it will not show cover image in note`,
|
||||||
'121432': `Attachment(Picture) folder`,
|
'121432': `Attachment folder`,
|
||||||
'121433': `Attachment file created from Obsidian-Douban will be placed in this folder,
|
'121433': `Attachment file created from Obsidian-Douban will be placed in this folder,
|
||||||
If blank, they will be created by default name. support all basic template variables. example: {{type}}/assets`,
|
If blank, they will be created by default name. support all basic template variables. example: {{type}}/assets`,
|
||||||
'121434': `assets`,
|
'121434': `assets`,
|
||||||
'121452': `Attachment(Picture) File Name`,
|
|
||||||
'121453': `Attachment file name, If blank, they will be created by default name '{{title}}'. support all basic template variables. example: {{type}}-{{title}}`,
|
|
||||||
|
|
||||||
'121454': `{{title}}`,
|
|
||||||
'121435': `Save High Definition Cover`,
|
'121435': `Save High Definition Cover`,
|
||||||
'121436': `High Definition Cover looks better but it will take more space, and you must login douban in this plugin`,
|
'121436': `High Definition Cover looks better but it will take more space, and you must login douban in this plugin`,
|
||||||
'121437': `Please login first, Then this function could be enable`,
|
'121437': `Please login first, Then this function could be enable`,
|
||||||
@ -334,10 +322,6 @@ PS: This file could be delete if you want to.
|
|||||||
'140102': `subject type is different, will not sync this, chosen sync type is {0} but this {1} subject type is {2}`,
|
'140102': `subject type is different, will not sync this, chosen sync type is {0} but this {1} subject type is {2}`,
|
||||||
'130105': `Can not use Douban this time, Please try again after 12 hour or 24 hour. Or you can reset your connection `,
|
'130105': `Can not use Douban this time, Please try again after 12 hour or 24 hour. Or you can reset your connection `,
|
||||||
'130106': `Can not use Douban this time, Please try Login In Douban Plugin. If not working please again after 12 hour or 24 hour. Or you can reset your connection `,
|
'130106': `Can not use Douban this time, Please try Login In Douban Plugin. If not working please again after 12 hour or 24 hour. Or you can reset your connection `,
|
||||||
'130404': `404 Url Not Found`,
|
|
||||||
'130109': `Downloaded image is empty`,
|
|
||||||
'130110': `Clipboard write failed`,
|
|
||||||
|
|
||||||
|
|
||||||
'130107': `Can not find array setting for {1} in {0} , Please add it in array settings`,
|
'130107': `Can not find array setting for {1} in {0} , Please add it in array settings`,
|
||||||
'130108': `Redirect times too much, please check your network or proxy`,
|
'130108': `Redirect times too much, please check your network or proxy`,
|
||||||
@ -365,8 +349,6 @@ PS: This file could be delete if you want to.
|
|||||||
'150103': `[Next Page]...`,
|
'150103': `[Next Page]...`,
|
||||||
'150105': `[Next Page (Group Post)]...`,
|
'150105': `[Next Page (Group Post)]...`,
|
||||||
'150104': `[Next Page (Please Login First)]...`,
|
'150104': `[Next Page (Please Login First)]...`,
|
||||||
'150107': `Result is empty. Please choose type before search`,
|
|
||||||
'150108': `If you can't find what you want, try changing the keyword or search type`,
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -666,18 +648,6 @@ PS: This file could be delete if you want to.
|
|||||||
|
|
||||||
'MOVIE_AND_TELEPLAY': `movie&tv`,
|
'MOVIE_AND_TELEPLAY': `movie&tv`,
|
||||||
|
|
||||||
'all': `all`,
|
|
||||||
'movie': `movie`,
|
|
||||||
'book': `book`,
|
|
||||||
'music': `music`,
|
|
||||||
'note': `note`,
|
|
||||||
'game': `game`,
|
|
||||||
'teleplay': `teleplay`,
|
|
||||||
'theater': `theater`,
|
|
||||||
|
|
||||||
'movie_and_teleplay': `movie&tv`,
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
'DAY': `D`,
|
'DAY': `D`,
|
||||||
'HOUR': `H`,
|
'HOUR': `H`,
|
||||||
|
|||||||
@ -1,26 +1,17 @@
|
|||||||
//简体中文
|
//简体中文
|
||||||
//简体中文
|
|
||||||
|
|
||||||
import {SyncItemStatus} from "../../constant/Constsant";
|
import {SyncItemStatus} from "../../constant/Constsant";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
//main.ts
|
//main.ts
|
||||||
'110001': '搜索当前文档名并写入',
|
'110001': '搜索豆瓣当前文档名并写入',
|
||||||
'110002': '搜索并写入当前文档',
|
'110002': '搜索豆瓣并写入当前文档',
|
||||||
'110003': `输入搜索内容:`,
|
'110003': `输入搜索内容:`,
|
||||||
'110004': `搜索`,
|
'110004': `搜索`,
|
||||||
'110005': `取消`,
|
'110005': `取消`,
|
||||||
'110006': `同步广播至Obsidian`,
|
'110006': `同步豆瓣广播至Obsidian`,
|
||||||
'110101': '搜索并创建文档',
|
'110101': '搜索豆瓣并创建文档',
|
||||||
'110103': '同步个人书影音广播记录',
|
'110103': '同步豆瓣个人书影音广播记录',
|
||||||
//'110102': 'search douban and create movie or tv',
|
|
||||||
'110102': '搜索电影或电视剧并创建',
|
|
||||||
// '110104': 'search douban and create book',
|
|
||||||
'110104': '搜索书籍并创建',
|
|
||||||
//'110105': 'search douban and create music',
|
|
||||||
'110105': '搜索音乐并创建',
|
|
||||||
//'110106': 'search douban and create game',
|
|
||||||
'110106': '搜索游戏并创建',
|
|
||||||
'110007': `开始同步`,
|
'110007': `开始同步`,
|
||||||
'110009': `停止同步`,
|
'110009': `停止同步`,
|
||||||
'110010': `后台运行`,
|
'110010': `后台运行`,
|
||||||
@ -70,7 +61,7 @@ export default {
|
|||||||
{1}
|
{1}
|
||||||
|
|
||||||
### 同步结果明细
|
### 同步结果明细
|
||||||
{2}
|
{1}
|
||||||
|
|
||||||
---
|
---
|
||||||
注:此文档可删除
|
注:此文档可删除
|
||||||
@ -293,22 +284,11 @@ export default {
|
|||||||
'121401': `状态栏`,
|
'121401': `状态栏`,
|
||||||
'121402': `当在导入数据时, 是否需要在状态栏显示处理状态? `,
|
'121402': `当在导入数据时, 是否需要在状态栏显示处理状态? `,
|
||||||
|
|
||||||
// '121410': `Search Default Type`,
|
|
||||||
// '121411': `Search defuault type for open command palette 'search douban and create file'`,
|
|
||||||
'121410': `默认搜索类型`,
|
|
||||||
'121411': `在打开"搜索豆瓣并创建文件"时默认搜索的类型`,
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
'121430': `保存图片附件`,
|
'121430': `保存图片附件`,
|
||||||
'121431': `导入数据会同步保存图片附件到本地文件夹, 如电影封面,书籍封面。如果需要显示封面,请保持开启该功能。`,
|
'121431': `导入数据会同步保存图片附件到本地文件夹, 如电影封面,书籍封面。如果需要显示封面,请保持开启该功能。`,
|
||||||
'121432': `附件(图片)存放位置`,
|
'121432': `附件存放位置`,
|
||||||
'121433': `保存的附件将会存放至该文件夹中. 如果为空, 笔记将会存放到默认位置(assets), 且支持所有'通用'的参数。如:{{myType}}/attachments`,
|
'121433': `保存的附件将会存放至该文件夹中. 如果为空, 笔记将会存放到默认位置(assets), 且支持所有'通用'的参数。如:{{myType}}/attachments`,
|
||||||
'121452': `附件(图片)文件名`,
|
|
||||||
'121453': `附件的文件名模板, 支持所有'通用'的参数作为名称(如:{{type}}-{{title}}),且支持路径, 比如: '{{myType}}/附件-{{title}}'。如果为空, 则使用默认名称{{title}}`,
|
|
||||||
'121434': `assets`,
|
'121434': `assets`,
|
||||||
'121454': `{{title}}`,
|
|
||||||
'121435': `保存高清封面`,
|
'121435': `保存高清封面`,
|
||||||
'121436': `高清封面图片质量更高清晰度更好, 需要您在此插件 登录豆瓣 才能生效, 若未登录则默认使用低精度版本封面`,
|
'121436': `高清封面图片质量更高清晰度更好, 需要您在此插件 登录豆瓣 才能生效, 若未登录则默认使用低精度版本封面`,
|
||||||
'121437': `登录后此功能才会生效`,
|
'121437': `登录后此功能才会生效`,
|
||||||
@ -350,8 +330,6 @@ export default {
|
|||||||
'130105': `由于多次频繁请求数据,豆瓣当前暂时不可用. 请于12小时或24小时后再重试,或重置你的网络(如重新拨号或更换网络) `,
|
'130105': `由于多次频繁请求数据,豆瓣当前暂时不可用. 请于12小时或24小时后再重试,或重置你的网络(如重新拨号或更换网络) `,
|
||||||
'130106': `请尝试在Douban插件中登录后操作. 若还是无效果则尝试于12小时或24小时后再重试,或重置你的网络(如重新拨号或更换网络) `,
|
'130106': `请尝试在Douban插件中登录后操作. 若还是无效果则尝试于12小时或24小时后再重试,或重置你的网络(如重新拨号或更换网络) `,
|
||||||
'130107': `参数{0}中指定的数组输出类型{1}不存在,请前往配置进行设置`,
|
'130107': `参数{0}中指定的数组输出类型{1}不存在,请前往配置进行设置`,
|
||||||
'130109': `下载图片内容为空`,
|
|
||||||
'130110': `写入剪贴板失败`,
|
|
||||||
'130120': `同步时发生错误,但同步将会继续。错误项目是 {}。`,
|
'130120': `同步时发生错误,但同步将会继续。错误项目是 {}。`,
|
||||||
'130121': `总数只有{0}, 选择的开始比总数还要大,将不会同步。`,
|
'130121': `总数只有{0}, 选择的开始比总数还要大,将不会同步。`,
|
||||||
|
|
||||||
@ -377,9 +355,6 @@ export default {
|
|||||||
'150103': `[下一页]...`,
|
'150103': `[下一页]...`,
|
||||||
'150105': `[下一页]...(小组帖子结果)`,
|
'150105': `[下一页]...(小组帖子结果)`,
|
||||||
'150104': `[下一页]...(请先在插件中登录才能使用此功能)`,
|
'150104': `[下一页]...(请先在插件中登录才能使用此功能)`,
|
||||||
// '150107': `Result is empty. Please choose type before search`,
|
|
||||||
'150107': `结果为空,请先选择类型再搜索`,
|
|
||||||
'150108': `如果没有找到你想要的内容, 请尝试更换关键字或者更换搜索类型`,
|
|
||||||
|
|
||||||
//content
|
//content
|
||||||
'200101': `。`,
|
'200101': `。`,
|
||||||
@ -450,7 +425,6 @@ export default {
|
|||||||
'310118': `producer:出品方`,
|
'310118': `producer:出品方`,
|
||||||
'310130': `出版年份`,
|
'310130': `出版年份`,
|
||||||
'310121': `封面URL`,
|
'310121': `封面URL`,
|
||||||
'310122': `menu:目录`,
|
|
||||||
|
|
||||||
|
|
||||||
//电影
|
//电影
|
||||||
@ -476,7 +450,6 @@ export default {
|
|||||||
'310220': `-`,
|
'310220': `-`,
|
||||||
'310230': `上映年份`,
|
'310230': `上映年份`,
|
||||||
'310221': `封面URL`,
|
'310221': `封面URL`,
|
||||||
'310222': `-`,
|
|
||||||
|
|
||||||
//电视剧
|
//电视剧
|
||||||
'310301': `豆瓣ID`,
|
'310301': `豆瓣ID`,
|
||||||
@ -501,7 +474,6 @@ export default {
|
|||||||
'310320': `episode:集数`,
|
'310320': `episode:集数`,
|
||||||
'310330': `上映年份`,
|
'310330': `上映年份`,
|
||||||
'310321': `封面URL`,
|
'310321': `封面URL`,
|
||||||
'310322': `-`,
|
|
||||||
|
|
||||||
|
|
||||||
//音乐
|
//音乐
|
||||||
@ -525,7 +497,6 @@ export default {
|
|||||||
'310418': `-`,
|
'310418': `-`,
|
||||||
'310430': `发行年份`,
|
'310430': `发行年份`,
|
||||||
'310421': `封面URL`,
|
'310421': `封面URL`,
|
||||||
'310422': `menu:目录`,
|
|
||||||
|
|
||||||
|
|
||||||
//日记
|
//日记
|
||||||
@ -549,7 +520,6 @@ export default {
|
|||||||
'310518': `-`,
|
'310518': `-`,
|
||||||
'310530': `发布年份`,
|
'310530': `发布年份`,
|
||||||
'310521': `封面URL`,
|
'310521': `封面URL`,
|
||||||
'310522': `-`,
|
|
||||||
|
|
||||||
//游戏
|
//游戏
|
||||||
'310601': `豆瓣ID`,
|
'310601': `豆瓣ID`,
|
||||||
@ -572,7 +542,6 @@ export default {
|
|||||||
'310618': `-`,
|
'310618': `-`,
|
||||||
'310630': `发行年份`,
|
'310630': `发行年份`,
|
||||||
'310621': `封面URL`,
|
'310621': `封面URL`,
|
||||||
'310622': `-`,
|
|
||||||
|
|
||||||
|
|
||||||
//广播
|
//广播
|
||||||
@ -595,8 +564,7 @@ export default {
|
|||||||
'310717': `-`,
|
'310717': `-`,
|
||||||
'310718': `-`,
|
'310718': `-`,
|
||||||
'310730': `-`,
|
'310730': `-`,
|
||||||
'310721': `-`,
|
'310721': `封面URL`,
|
||||||
'310722': `-`,
|
|
||||||
|
|
||||||
'320101': `扩展1`,
|
'320101': `扩展1`,
|
||||||
'320102': `扩展2`,
|
'320102': `扩展2`,
|
||||||
@ -687,16 +655,6 @@ export default {
|
|||||||
'MOVIE_AND_TELEPLAY': `影视剧`,
|
'MOVIE_AND_TELEPLAY': `影视剧`,
|
||||||
|
|
||||||
|
|
||||||
'all': `全部类型`,
|
|
||||||
'movie': `电影`,
|
|
||||||
'book': `书籍`,
|
|
||||||
'music': `音乐`,
|
|
||||||
'note': `笔记`,
|
|
||||||
'game': `游戏`,
|
|
||||||
'teleplay': `电视剧`,
|
|
||||||
'theater': `戏剧`,
|
|
||||||
'movie_and_teleplay': `影视剧`,
|
|
||||||
|
|
||||||
'DAY': `天`,
|
'DAY': `天`,
|
||||||
'HOUR': `时`,
|
'HOUR': `时`,
|
||||||
'MINUTE': `分`,
|
'MINUTE': `分`,
|
||||||
|
|||||||
@ -105,7 +105,12 @@ export default class DoubanPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async createFile(context: HandleContext, result: HandleResult) {
|
async createFile(context: HandleContext, result: HandleResult) {
|
||||||
let filePath = result.filePath?result.filePath:DEFAULT_SETTINGS.dataFilePath;
|
let filePath = this.settings.dataFilePath;
|
||||||
|
const {syncConfig} = context;
|
||||||
|
if (syncConfig) {
|
||||||
|
filePath = syncConfig.dataFilePath;
|
||||||
|
}
|
||||||
|
filePath = filePath?filePath:DEFAULT_SETTINGS.dataFilePath;
|
||||||
filePath = FileUtil.join(filePath, result.fileName);
|
filePath = FileUtil.join(filePath, result.fileName);
|
||||||
const syncStatus = context.syncStatusHolder && context.syncStatusHolder.syncStatus ? context.syncStatusHolder.syncStatus : null;
|
const syncStatus = context.syncStatusHolder && context.syncStatusHolder.syncStatus ? context.syncStatusHolder.syncStatus : null;
|
||||||
const {subject} = result;
|
const {subject} = result;
|
||||||
@ -146,21 +151,17 @@ export default class DoubanPlugin extends Plugin {
|
|||||||
if (activeFile) {
|
if (activeFile) {
|
||||||
const searchTerm = activeFile.basename;
|
const searchTerm = activeFile.basename;
|
||||||
if (searchTerm) {
|
if (searchTerm) {
|
||||||
await this.search(searchTerm, SupportType.all, context);
|
await this.search(searchTerm, SupportType.ALL, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getDoubanTextForCreateNewNote(context: HandleContext) {
|
async getDoubanTextForCreateNewNote(context: HandleContext) {
|
||||||
new DoubanSearchModal(this.app, this, context, null).open();
|
new DoubanSearchModal(this.app, this, context).open();
|
||||||
}
|
|
||||||
|
|
||||||
async getDoubanTextForCreateNewNoteForType(context: HandleContext, type: SupportType) {
|
|
||||||
new DoubanSearchModal(this.app, this, context, type).open();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getDoubanTextForSearchTerm(context: HandleContext) {
|
async getDoubanTextForSearchTerm(context: HandleContext) {
|
||||||
new DoubanSearchModal(this.app, this, context, null).open();
|
new DoubanSearchModal(this.app, this, context).open();
|
||||||
}
|
}
|
||||||
|
|
||||||
async showSyncModal(context: HandleContext) {
|
async showSyncModal(context: HandleContext) {
|
||||||
@ -179,13 +180,13 @@ export default class DoubanPlugin extends Plugin {
|
|||||||
id: "searcher-douban-import-and-create-file",
|
id: "searcher-douban-import-and-create-file",
|
||||||
name: i18nHelper.getMessage("110101"),
|
name: i18nHelper.getMessage("110101"),
|
||||||
callback: () =>
|
callback: () =>
|
||||||
this.getDoubanTextForCreateNewNoteForType({plugin: this,
|
this.getDoubanTextForCreateNewNote({plugin: this,
|
||||||
mode: SearchHandleMode.FOR_CREATE,
|
mode: SearchHandleMode.FOR_CREATE,
|
||||||
settings: this.settings,
|
settings: this.settings,
|
||||||
userComponent: this.userComponent,
|
userComponent: this.userComponent,
|
||||||
netFileHandler: this.netFileHandler,
|
netFileHandler: this.netFileHandler,
|
||||||
showAfterCreate:true,
|
showAfterCreate:true,
|
||||||
action: Action.SearchAndCrate}, this.settings.searchDefaultType),
|
action: Action.SearchAndCrate}),
|
||||||
});
|
});
|
||||||
|
|
||||||
this.addCommand({
|
this.addCommand({
|
||||||
@ -227,66 +228,10 @@ export default class DoubanPlugin extends Plugin {
|
|||||||
syncStatusHolder: this.statusHolder}),
|
syncStatusHolder: this.statusHolder}),
|
||||||
});
|
});
|
||||||
|
|
||||||
this.addCommand({
|
this.settingsManager = new SettingsManager(app, this);
|
||||||
id: "searcher-douban-import-and-create-file-movie-tv",
|
|
||||||
name: i18nHelper.getMessage("110102"),
|
|
||||||
callback: () =>
|
|
||||||
this.getDoubanTextForCreateNewNoteForType({plugin: this,
|
|
||||||
mode: SearchHandleMode.FOR_CREATE,
|
|
||||||
settings: this.settings,
|
|
||||||
userComponent: this.userComponent,
|
|
||||||
netFileHandler: this.netFileHandler,
|
|
||||||
showAfterCreate:true,
|
|
||||||
action: Action.SearchAndCrate}, SupportType.movie),
|
|
||||||
});
|
|
||||||
|
|
||||||
this.addCommand({
|
|
||||||
id: "searcher-douban-import-and-create-file-book",
|
|
||||||
name: i18nHelper.getMessage("110104"),
|
|
||||||
callback: () =>
|
|
||||||
this.getDoubanTextForCreateNewNoteForType({plugin: this,
|
|
||||||
mode: SearchHandleMode.FOR_CREATE,
|
|
||||||
settings: this.settings,
|
|
||||||
userComponent: this.userComponent,
|
|
||||||
netFileHandler: this.netFileHandler,
|
|
||||||
showAfterCreate:true,
|
|
||||||
action: Action.SearchAndCrate}, SupportType.book),
|
|
||||||
});
|
|
||||||
|
|
||||||
this.addCommand({
|
|
||||||
id: "searcher-douban-import-and-create-file-music",
|
|
||||||
name: i18nHelper.getMessage("110105"),
|
|
||||||
callback: () =>
|
|
||||||
this.getDoubanTextForCreateNewNoteForType({plugin: this,
|
|
||||||
mode: SearchHandleMode.FOR_CREATE,
|
|
||||||
settings: this.settings,
|
|
||||||
userComponent: this.userComponent,
|
|
||||||
netFileHandler: this.netFileHandler,
|
|
||||||
showAfterCreate:true,
|
|
||||||
action: Action.SearchAndCrate}, SupportType.music),
|
|
||||||
});
|
|
||||||
|
|
||||||
this.addCommand({
|
|
||||||
id: "searcher-douban-import-and-create-file-game",
|
|
||||||
name: i18nHelper.getMessage("110106"),
|
|
||||||
callback: () =>
|
|
||||||
this.getDoubanTextForCreateNewNoteForType({plugin: this,
|
|
||||||
mode: SearchHandleMode.FOR_CREATE,
|
|
||||||
settings: this.settings,
|
|
||||||
userComponent: this.userComponent,
|
|
||||||
netFileHandler: this.netFileHandler,
|
|
||||||
showAfterCreate:true,
|
|
||||||
action: Action.SearchAndCrate}, SupportType.game),
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.settingsManager = new SettingsManager(this.app, this);
|
|
||||||
// this.fetchOnlineData(this.settingsManager);
|
// this.fetchOnlineData(this.settingsManager);
|
||||||
this.userComponent = new UserComponent(this.settingsManager);
|
this.userComponent = new UserComponent(this.settingsManager);
|
||||||
this.netFileHandler = new NetFileHandler(this.fileHandler);
|
this.netFileHandler = new NetFileHandler(this.fileHandler);
|
||||||
this.userComponent.assumeLoggedIn();
|
|
||||||
|
|
||||||
this.settingTab = new DoubanSettingTab(this.app, this);
|
this.settingTab = new DoubanSettingTab(this.app, this);
|
||||||
this.addSettingTab(this.settingTab);
|
this.addSettingTab(this.settingTab);
|
||||||
@ -356,16 +301,11 @@ export default class DoubanPlugin extends Plugin {
|
|||||||
|
|
||||||
async checkLogin(context: HandleContext):Promise<boolean> {
|
async checkLogin(context: HandleContext):Promise<boolean> {
|
||||||
this.settingsManager.debug('主界面:同步时的登录状态检测');
|
this.settingsManager.debug('主界面:同步时的登录状态检测');
|
||||||
const uc = context.userComponent;
|
if (!context.userComponent.needLogin()) {
|
||||||
// If assumed-logged-in but not verified, verify now (sync needs real user ID)
|
this.settingsManager.debug('主界面:同步时的登录状态检测完成: 无用户信息, 尝试获取用户信息');
|
||||||
if (uc.isLogin() && !uc.isVerified()) {
|
await context.userComponent.login();
|
||||||
await uc.login();
|
|
||||||
}
|
}
|
||||||
// If has saved credentials but not logged in, try login
|
if (!context.userComponent.isLogin()) {
|
||||||
if (uc.needLogin()) {
|
|
||||||
await uc.login();
|
|
||||||
}
|
|
||||||
if (!uc.isLogin()) {
|
|
||||||
this.settingsManager.debug('主界面:同步时的登录状态检测完成: 尝试获取用户信息失败');
|
this.settingsManager.debug('主界面:同步时的登录状态检测完成: 尝试获取用户信息失败');
|
||||||
new Notice(i18nHelper.getMessage('140303'));
|
new Notice(i18nHelper.getMessage('140303'));
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -17,30 +17,17 @@ export default class NetFileHandler {
|
|||||||
|
|
||||||
async downloadDBFile(url: string, folder:string, filename: string, context:HandleContext, showError:boolean, headers?:any): Promise<{ success: boolean, error:string, filepath: string }> {
|
async downloadDBFile(url: string, folder:string, filename: string, context:HandleContext, showError:boolean, headers?:any): Promise<{ success: boolean, error:string, filepath: string }> {
|
||||||
const filePath:string = FileUtil.join(folder, filename);
|
const filePath:string = FileUtil.join(folder, filename);
|
||||||
return HttpUtil.httpRequestBuffer(url, headers, context.plugin.settingsManager)
|
return HttpUtil.httpRequestBuffer(url, headers, context.plugin.settingsManager)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.status == 404) {
|
if (response.status == 403) {
|
||||||
throw new Error(i18nHelper.getMessage('130404'));
|
throw new Error(i18nHelper.getMessage('130106'));
|
||||||
}
|
}
|
||||||
if (response.status == 403) {
|
return response.textArrayBuffer;
|
||||||
throw new Error(i18nHelper.getMessage('130106'));
|
})
|
||||||
}
|
|
||||||
if (response.status == 418) {
|
|
||||||
throw new Error(i18nHelper.getMessage('130105'));
|
|
||||||
}
|
|
||||||
return response.textArrayBuffer;
|
|
||||||
})
|
|
||||||
.then((buffer) => {
|
.then((buffer) => {
|
||||||
if (!buffer || buffer.byteLength == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
this.fileHandler.creatAttachmentWithData(filePath, buffer);
|
this.fileHandler.creatAttachmentWithData(filePath, buffer);
|
||||||
return buffer.byteLength;
|
}).then(() => {
|
||||||
}).then((size) => {
|
return {success: true, error: '', filepath: filePath};
|
||||||
if (size == 0) {
|
|
||||||
return {success: false, size: size, error: '文件唯恐', filepath: null};
|
|
||||||
}
|
|
||||||
return {success: true, size: size, error: '', filepath: filePath};
|
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
if (showError) {
|
if (showError) {
|
||||||
@ -59,23 +46,15 @@ export default class NetFileHandler {
|
|||||||
async downloadDBUploadPicGoByClipboard(url: string, filename: string, context:HandleContext, showError:boolean, headers?:any): Promise<{ success: boolean, error:string, filepath: string }> {
|
async downloadDBUploadPicGoByClipboard(url: string, filename: string, context:HandleContext, showError:boolean, headers?:any): Promise<{ success: boolean, error:string, filepath: string }> {
|
||||||
return HttpUtil.httpRequestBuffer(url, headers, context.plugin.settingsManager)
|
return HttpUtil.httpRequestBuffer(url, headers, context.plugin.settingsManager)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.status == 404) {
|
|
||||||
throw new Error(i18nHelper.getMessage('130404'));
|
|
||||||
}
|
|
||||||
if (response.status == 403) {
|
if (response.status == 403) {
|
||||||
throw new Error(i18nHelper.getMessage('130106'));
|
throw new Error(i18nHelper.getMessage('130106'));
|
||||||
}
|
}
|
||||||
if (response.status == 418) {
|
|
||||||
throw new Error(i18nHelper.getMessage('130105'));
|
|
||||||
}
|
|
||||||
return response.textArrayBuffer;
|
return response.textArrayBuffer;
|
||||||
})
|
})
|
||||||
.then(async (buffer) => {
|
.then((buffer) => {
|
||||||
if (!buffer || buffer.byteLength == 0) {
|
ClipboardUtil.writeImage(buffer);
|
||||||
throw new Error(i18nHelper.getMessage('130109'));
|
}).then(() => {
|
||||||
}
|
return this.uploadClipboardFile(context);
|
||||||
await ClipboardUtil.writeImage(buffer);
|
|
||||||
return await this.uploadClipboardFile(context);
|
|
||||||
}).then((data) => {
|
}).then((data) => {
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
return {success: true, error: '', filepath: HttpUtil.extractURLFromString(data.result[0])};
|
return {success: true, error: '', filepath: HttpUtil.extractURLFromString(data.result[0])};
|
||||||
@ -119,3 +98,4 @@ export default class NetFileHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,78 +1,12 @@
|
|||||||
|
|
||||||
|
|
||||||
import {i18nHelper} from "../lang/helper";
|
export class ClipboardUtil {
|
||||||
|
|
||||||
export class ClipboardUtil {
|
public static async writeImage(data:ArrayBuffer, options: ClipboardOptions = defaultClipboardOptions) {
|
||||||
|
const { clipboard, nativeImage } = require('electron');
|
||||||
|
|
||||||
public static async writeImage(data:ArrayBuffer, options: ClipboardOptions = defaultClipboardOptions) {
|
await clipboard.writeImage(nativeImage.createFromBuffer(data));
|
||||||
if (!data || data.byteLength == 0) {
|
console.log(`Copied to clipboard as HTML`);
|
||||||
throw new Error(i18nHelper.getMessage('130110'));
|
|
||||||
}
|
|
||||||
const { clipboard, nativeImage } = require('electron');
|
|
||||||
const isWebp = this.isWebp(data);
|
|
||||||
let image = nativeImage.createFromBuffer(Buffer.from(data));
|
|
||||||
if ((!image || image.isEmpty()) && isWebp) {
|
|
||||||
image = await this.createNativeImageFromWebp(data);
|
|
||||||
}
|
|
||||||
if (!image || image.isEmpty()) {
|
|
||||||
throw new Error(i18nHelper.getMessage('130110'));
|
|
||||||
}
|
|
||||||
clipboard.clear();
|
|
||||||
clipboard.writeImage(image);
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 100));
|
|
||||||
const clipboardImage = clipboard.readImage();
|
|
||||||
if (!clipboardImage || clipboardImage.isEmpty()) {
|
|
||||||
throw new Error(i18nHelper.getMessage('130110'));
|
|
||||||
}
|
|
||||||
console.log(`Copied to clipboard as HTML`);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static isWebp(data: ArrayBuffer): boolean {
|
|
||||||
const bytes = new Uint8Array(data);
|
|
||||||
if (bytes.length < 12) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return bytes[0] === 0x52
|
|
||||||
&& bytes[1] === 0x49
|
|
||||||
&& bytes[2] === 0x46
|
|
||||||
&& bytes[3] === 0x46
|
|
||||||
&& bytes[8] === 0x57
|
|
||||||
&& bytes[9] === 0x45
|
|
||||||
&& bytes[10] === 0x42
|
|
||||||
&& bytes[11] === 0x50;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async createNativeImageFromWebp(data: ArrayBuffer) {
|
|
||||||
const { nativeImage } = require('electron');
|
|
||||||
const imageElement = await this.loadImage(URL.createObjectURL(new Blob([data], {type: 'image/webp'})));
|
|
||||||
try {
|
|
||||||
const canvas = document.createElement('canvas');
|
|
||||||
canvas.width = imageElement.naturalWidth || imageElement.width;
|
|
||||||
canvas.height = imageElement.naturalHeight || imageElement.height;
|
|
||||||
const context = canvas.getContext('2d');
|
|
||||||
if (!context) {
|
|
||||||
throw new Error(i18nHelper.getMessage('130110'));
|
|
||||||
}
|
|
||||||
context.drawImage(imageElement, 0, 0);
|
|
||||||
return nativeImage.createFromDataURL(canvas.toDataURL('image/png'));
|
|
||||||
} finally {
|
|
||||||
imageElement.src = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static loadImage(url: string): Promise<HTMLImageElement> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const image = new Image();
|
|
||||||
image.onload = () => {
|
|
||||||
URL.revokeObjectURL(url);
|
|
||||||
resolve(image);
|
|
||||||
};
|
|
||||||
image.onerror = () => {
|
|
||||||
URL.revokeObjectURL(url);
|
|
||||||
reject(new Error(i18nHelper.getMessage('130110')));
|
|
||||||
};
|
|
||||||
image.src = url;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -86,3 +20,4 @@ interface ClipboardOptions {
|
|||||||
const defaultClipboardOptions: ClipboardOptions = {
|
const defaultClipboardOptions: ClipboardOptions = {
|
||||||
contentType: 'text/plain',
|
contentType: 'text/plain',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -58,15 +58,10 @@ export const FileUtil = {
|
|||||||
/**
|
/**
|
||||||
* replace special characters for filename
|
* replace special characters for filename
|
||||||
*/
|
*/
|
||||||
replaceSpecialCharactersForFileName(fileNameInput: string): string {
|
replaceSpecialCharactersForFileName(fileName: string): string {
|
||||||
let fileName = fileNameInput.replaceAll(/[\\/:*?"<>|]/g, '_');
|
return fileName.replaceAll(/[\\/:*?"<>|]/g, '_');
|
||||||
fileName = fileName.replaceAll(/[\n\r\t]/g, '_');
|
|
||||||
fileName = fileName.replaceAll(/\s+/g, '_');
|
|
||||||
fileName = fileName.replaceAll(/^\.+/g, '_'); // remove leading dots
|
|
||||||
fileName = fileName.replaceAll(/\.+$/g, '_'); // remove trailing dots
|
|
||||||
fileName = fileName.replaceAll(/_+/g, '_'); // remove duplicate underscores
|
|
||||||
return fileName;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -7,19 +7,6 @@ import {HttpResponse} from "./model/HttpResponse";
|
|||||||
|
|
||||||
export default class HttpUtil {
|
export default class HttpUtil {
|
||||||
|
|
||||||
private static readonly IMAGE_REQUEST_HEADERS_TO_DROP = new Set([
|
|
||||||
'authority',
|
|
||||||
'content-length',
|
|
||||||
'content-type',
|
|
||||||
'host',
|
|
||||||
'origin',
|
|
||||||
'referer',
|
|
||||||
'sec-fetch-dest',
|
|
||||||
'sec-fetch-mode',
|
|
||||||
'sec-fetch-site',
|
|
||||||
'sec-fetch-user',
|
|
||||||
]);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,27 +60,6 @@ export default class HttpUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static buildImageRequestHeaders(headers: Record<string, any> = {}, referer?: string): Record<string, string> {
|
|
||||||
const nextHeaders: Record<string, string> = {};
|
|
||||||
Object.entries(headers || {}).forEach(([key, value]) => {
|
|
||||||
if (value == null || value === '') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const lowerKey = key.toLowerCase();
|
|
||||||
if (lowerKey === 'referer') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.IMAGE_REQUEST_HEADERS_TO_DROP.has(lowerKey) || lowerKey.startsWith('sec-ch-ua')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
nextHeaders[key] = String(value);
|
|
||||||
});
|
|
||||||
if (referer) {
|
|
||||||
nextHeaders.Referer = referer;
|
|
||||||
}
|
|
||||||
return nextHeaders;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static parse(url: string): { protocol: string, host: string, port: string, path: string } {
|
public static parse(url: string): { protocol: string, host: string, port: string, path: string } {
|
||||||
const regex = /^(.*?):\/\/([^\/:]+)(?::(\d+))?([^?]*)$/;
|
const regex = /^(.*?):\/\/([^\/:]+)(?::(\d+))?([^?]*)$/;
|
||||||
|
|||||||
@ -117,8 +117,6 @@ export default class StringUtil {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EscapeMap:Map< { [Symbol.replace](string: string, replaceValue: string): string; }, string> = new Map([
|
export const EscapeMap:Map< { [Symbol.replace](string: string, replaceValue: string): string; }, string> = new Map([
|
||||||
|
|||||||
@ -8,26 +8,18 @@ import {DataValueType, SupportType} from "../constant/Constsant";
|
|||||||
import {DataField} from "./model/DataField";
|
import {DataField} from "./model/DataField";
|
||||||
import {FieldVariable} from "./model/FieldVariable";
|
import {FieldVariable} from "./model/FieldVariable";
|
||||||
import {CustomProperty} from "../douban/setting/model/CustomProperty";
|
import {CustomProperty} from "../douban/setting/model/CustomProperty";
|
||||||
import {FileUtil} from "./FileUtil";
|
|
||||||
|
|
||||||
type TargetType = 'text' | 'path' | 'yml_text';
|
|
||||||
|
|
||||||
|
|
||||||
export class VariableUtil {
|
export class VariableUtil {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
*
|
*
|
||||||
* @param obj
|
* @param obj
|
||||||
* @param content
|
* @param content
|
||||||
* @param subjectType
|
|
||||||
* @param settingManager
|
* @param settingManager
|
||||||
* @param targetType
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static replaceSubject(obj: any, content: string, subjectType: SupportType, settingManager:SettingsManager, targetType: TargetType): string {
|
static replaceSubject(obj: any, content: string, subjectType: SupportType, settingManager:SettingsManager): string {
|
||||||
if (!content || !obj) {
|
if (!content || !obj) {
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
@ -36,12 +28,12 @@ export class VariableUtil {
|
|||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
if (obj instanceof Map) {
|
if (obj instanceof Map) {
|
||||||
this.handleCustomVariable(subjectType, obj, settingManager, 'text')
|
this.handleCustomVariable(subjectType, obj, settingManager)
|
||||||
content = this.replaceMap(obj, allVariables, content, settingManager, targetType);
|
content = this.replaceMap(obj, allVariables, content, settingManager);
|
||||||
}else {
|
}else {
|
||||||
const map = this.objToMap(obj);
|
const map = this.objToMap(obj);
|
||||||
this.handleCustomVariable(subjectType, map, settingManager, 'text')
|
this.handleCustomVariable(subjectType, map, settingManager)
|
||||||
content = this.replaceMap(map, allVariables, content, settingManager, targetType);
|
content = this.replaceMap(map, allVariables, content, settingManager);
|
||||||
}
|
}
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
@ -52,10 +44,9 @@ export class VariableUtil {
|
|||||||
* @param obj
|
* @param obj
|
||||||
* @param content
|
* @param content
|
||||||
* @param settingManager
|
* @param settingManager
|
||||||
* @param targetType
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static replace(obj: any, content: string, settingManager:SettingsManager, targetType : TargetType): string {
|
static replace(obj: any, content: string, settingManager:SettingsManager): string {
|
||||||
if (!content || !obj) {
|
if (!content || !obj) {
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
@ -64,10 +55,10 @@ export class VariableUtil {
|
|||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
if (obj instanceof Map) {
|
if (obj instanceof Map) {
|
||||||
content = this.replaceMap(obj, allVariables, content, settingManager, targetType);
|
content = this.replaceMap(obj, allVariables, content, settingManager);
|
||||||
}else {
|
}else {
|
||||||
const map = this.objToMap(obj);
|
const map = this.objToMap(obj);
|
||||||
content = this.replaceMap(map, allVariables, content, settingManager, targetType); }
|
content = this.replaceMap(map, allVariables, content, settingManager); }
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
@ -84,24 +75,23 @@ export class VariableUtil {
|
|||||||
* @param value
|
* @param value
|
||||||
* @param content
|
* @param content
|
||||||
* @param settingManager
|
* @param settingManager
|
||||||
* @param targetType
|
|
||||||
*/
|
*/
|
||||||
static replaceVariable(variable: FieldVariable, value: any, content: string, settingManager:SettingsManager, targetType: TargetType): string {
|
static replaceVariable(variable: FieldVariable, value: any, content: string, settingManager:SettingsManager): string {
|
||||||
if (!content) {
|
if (!content) {
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
//根据value的类型,替换对应的变量
|
//根据value的类型,替换对应的变量
|
||||||
if (value instanceof Array) {
|
if (value instanceof Array) {
|
||||||
content = this.replaceArray(variable, value, content, settingManager, targetType);
|
content = this.replaceArray(variable, value, content, settingManager);
|
||||||
} else if(value instanceof DataField) {
|
} else if(value instanceof DataField) {
|
||||||
content = this.replaceDataField(variable, value, content, settingManager, targetType);
|
content = this.replaceDataField(variable, value, content, settingManager);
|
||||||
} else {
|
} else {
|
||||||
content = this.replaceString(variable, value, value, content, settingManager, targetType);
|
content = this.replaceString(variable, value, content, settingManager);
|
||||||
}
|
}
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
static replaceArray(variable: FieldVariable, value: any[], content: string, settingManager:SettingsManager, targetType: TargetType): string {
|
static replaceArray(variable: FieldVariable, value: any[], content: string, settingManager:SettingsManager): string {
|
||||||
if (!content) {
|
if (!content) {
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
@ -124,7 +114,7 @@ export class VariableUtil {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(v => v)
|
.filter(v => v)
|
||||||
.map(v => this.handleText(v, targetType))
|
.map(v => YamlUtil.handleText(v))
|
||||||
;
|
;
|
||||||
const arrayValue = StringUtil.handleArray(strValues, arraySettings);
|
const arrayValue = StringUtil.handleArray(strValues, arraySettings);
|
||||||
content = content.replaceAll(variableStr, arrayValue);
|
content = content.replaceAll(variableStr, arrayValue);
|
||||||
@ -135,19 +125,19 @@ export class VariableUtil {
|
|||||||
return `{{${key}}}`;
|
return `{{${key}}}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static replaceString(variable: FieldVariable, valueField: DataField, value: any, content: string, settingManager:SettingsManager, targetType: TargetType): string {
|
static replaceString(variable: FieldVariable, value: any, content: string, settingManager:SettingsManager): string {
|
||||||
if (!content) {
|
if (!content) {
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
let strValue = value? value.toString() : "";
|
let strValue = value? value.toString() : "";
|
||||||
return content.replaceAll(variable.variable, this.handleText(strValue, targetType, valueField));
|
strValue = YamlUtil.handleText(strValue);
|
||||||
|
return content.replaceAll(variable.variable, strValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从key中提取 arrayName, 然后从settings中获取对应的ArraySetting
|
* 从key中提取 arrayName, 然后从settings中获取对应的ArraySetting
|
||||||
|
* @param key
|
||||||
* @private
|
* @private
|
||||||
* @param content
|
|
||||||
* @param settingManager
|
|
||||||
*/
|
*/
|
||||||
private static getAllVariables(content: string, settingManager:SettingsManager): FieldVariable[] {
|
private static getAllVariables(content: string, settingManager:SettingsManager): FieldVariable[] {
|
||||||
const reg =/\{\{[a-zA-Z-0-9_.]+([(a-zA-Z-0-9)]+)?}}/g
|
const reg =/\{\{[a-zA-Z-0-9_.]+([(a-zA-Z-0-9)]+)?}}/g
|
||||||
@ -171,7 +161,6 @@ export class VariableUtil {
|
|||||||
/**
|
/**
|
||||||
* 从key中提取 arrayName, 然后从settings中获取对应的ArraySetting
|
* 从key中提取 arrayName, 然后从settings中获取对应的ArraySetting
|
||||||
* @param outTypeName
|
* @param outTypeName
|
||||||
* @param settingManager
|
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
private static getArraySetting(outTypeName: string, settingManager:SettingsManager): ArraySetting {
|
private static getArraySetting(outTypeName: string, settingManager:SettingsManager): ArraySetting {
|
||||||
@ -183,10 +172,10 @@ export class VariableUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static replaceMap(obj: Map<string, any>, allVariables:FieldVariable[], content: string, settingManager: SettingsManager, targetType: TargetType) {
|
private static replaceMap(obj: Map<string, any>, allVariables:FieldVariable[], content: string, settingManager: SettingsManager) {
|
||||||
allVariables.forEach(variable => {
|
allVariables.forEach(variable => {
|
||||||
const value = obj.get(variable.key);
|
const value = obj.get(variable.key);
|
||||||
content = this.replaceVariable(variable, value, content, settingManager, targetType);
|
content = this.replaceVariable(variable, value,content, settingManager);
|
||||||
});
|
});
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
@ -210,7 +199,7 @@ export class VariableUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static replaceDataField(variable: FieldVariable, value: DataField, content: string, settingManager: SettingsManager, targetType: TargetType) {
|
private static replaceDataField(variable: FieldVariable, value: DataField, content: string, settingManager: SettingsManager) {
|
||||||
if (!content) {
|
if (!content) {
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
@ -220,19 +209,19 @@ export class VariableUtil {
|
|||||||
}
|
}
|
||||||
switch (value.type) {
|
switch (value.type) {
|
||||||
case DataValueType.string:
|
case DataValueType.string:
|
||||||
content = this.replaceString(variable, value, value.value, content, settingManager, targetType);
|
content = this.replaceString(variable, value.value, content, settingManager);
|
||||||
break;
|
break;
|
||||||
case DataValueType.number:
|
case DataValueType.number:
|
||||||
content = content.replaceAll(variableStr, this.handleText(value.value.toString(), targetType, value));
|
content = content.replaceAll(variableStr, value.value.toString());
|
||||||
break;
|
break;
|
||||||
case DataValueType.date:
|
case DataValueType.date:
|
||||||
content = content.replaceAll(variableStr, this.handleText(value.value, targetType, value));
|
content = content.replaceAll(variableStr, value.value);
|
||||||
break;
|
break;
|
||||||
case DataValueType.array:
|
case DataValueType.array:
|
||||||
content = this.replaceArray(variable, value.value, content, settingManager, targetType);
|
content = this.replaceArray(variable, value.value, content, settingManager);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
content = content.replaceAll(variableStr, this.handleText(value.value, targetType, value));
|
content = content.replaceAll(variableStr, value.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -242,13 +231,11 @@ export class VariableUtil {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理自定义参数
|
* 处理自定义参数
|
||||||
|
* @param template
|
||||||
|
* @param context
|
||||||
* @private
|
* @private
|
||||||
* @param subjectType
|
|
||||||
* @param variableMap
|
|
||||||
* @param settingMananger
|
|
||||||
* @param targetType
|
|
||||||
*/
|
*/
|
||||||
static handleCustomVariable(subjectType: SupportType, variableMap:Map<string, DataField>, settingMananger: SettingsManager, targetType:TargetType): void {
|
static handleCustomVariable(subjectType: SupportType, variableMap:Map<string, DataField>, settingMananger: SettingsManager): void {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const customProperties: CustomProperty[] = settingMananger.getSetting('customProperties');
|
const customProperties: CustomProperty[] = settingMananger.getSetting('customProperties');
|
||||||
if (!customProperties) {
|
if (!customProperties) {
|
||||||
@ -257,7 +244,7 @@ export class VariableUtil {
|
|||||||
const customPropertiesMap= new Map();
|
const customPropertiesMap= new Map();
|
||||||
customProperties.filter(customProperty => customProperty.name &&
|
customProperties.filter(customProperty => customProperty.name &&
|
||||||
customProperty.field
|
customProperty.field
|
||||||
&& (customProperty.field.toLowerCase() == SupportType.all ||
|
&& (customProperty.field.toLowerCase() == SupportType.ALL ||
|
||||||
customProperty.field.toLowerCase() == subjectType)).forEach(customProperty => {
|
customProperty.field.toLowerCase() == subjectType)).forEach(customProperty => {
|
||||||
customPropertiesMap.set(customProperty.name, customProperty.value);
|
customPropertiesMap.set(customProperty.name, customProperty.value);
|
||||||
});
|
});
|
||||||
@ -265,7 +252,7 @@ export class VariableUtil {
|
|||||||
variableMap.set(key,
|
variableMap.set(key,
|
||||||
new DataField(
|
new DataField(
|
||||||
key, DataValueType.string, value,
|
key, DataValueType.string, value,
|
||||||
VariableUtil.replace(variableMap, value, settingMananger, targetType)));
|
VariableUtil.replace(variableMap, value, settingMananger)));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,16 +263,4 @@ export class VariableUtil {
|
|||||||
});
|
});
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static handleText(v: string, targetType: TargetType, dataField: DataField = null): string {
|
|
||||||
if (targetType === 'yml_text') {
|
|
||||||
return YamlUtil.handleText(v, dataField);
|
|
||||||
}
|
|
||||||
if (targetType === 'text') {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
if (targetType === 'path') {
|
|
||||||
return FileUtil.replaceSpecialCharactersForFileName(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
import {DataField} from "./model/DataField";
|
|
||||||
import {DataValueType} from "../constant/Constsant";
|
|
||||||
|
|
||||||
export default class YamlUtil {
|
export default class YamlUtil {
|
||||||
|
|
||||||
|
|
||||||
public static hasSpecialChar(str: string): boolean {
|
public static hasSpecialChar(str: string): boolean {
|
||||||
return SPECIAL_CHAR_REG.test(str);
|
return SPECIAL_CHAR_REG.test(str);
|
||||||
}
|
}
|
||||||
@ -16,26 +14,21 @@ export default class YamlUtil {
|
|||||||
return '"' + text + '"';
|
return '"' + text + '"';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static handleText(text: string, dataField: DataField = null): string {
|
public static handleText(text: string) {
|
||||||
if (YamlUtil.hasSpecialChar(text)) {
|
return YamlUtil.hasSpecialChar(text)
|
||||||
text = text.replaceAll('"', '\\"')
|
? YamlUtil.handleSpecialChar(text.replaceAll('"', '\\"'))
|
||||||
.replaceAll(/\s+/g, ' ')
|
.replaceAll(/\s+/g,' ')
|
||||||
.replaceAll('\n', '。')
|
.replaceAll('\n', '。')
|
||||||
.replaceAll('。。', '。')
|
.replaceAll('。。', '。')
|
||||||
.replace(/^" /, '"') // Remove leading "
|
.replace(/^" /, '"') // Remove leading "
|
||||||
.replace(/ "$/, '"') // Remove trailing "
|
.replace(/ "$/, '"') // Remove trailing "
|
||||||
if (dataField && dataField.type === DataValueType.date) {
|
: text;
|
||||||
return text;
|
|
||||||
}
|
|
||||||
YamlUtil.handleSpecialChar(text);
|
|
||||||
}
|
|
||||||
return text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SPECIAL_CHAR_REG = /[{}\[\]&*#?|\-<>=!%@:"`,\n]/;
|
export const SPECIAL_CHAR_REG = /[{}\[\]&*#?|\-<>=!%@:"`,\n]/;
|
||||||
export const TITLE_ALIASES_SPECIAL_CHAR_REG_G = /[{}\[\]&*#?|\-<>=!%@:"`,,\n]/g;
|
export const TITLE_ALIASES_SPECIAL_CHAR_REG_G = /[{}\[\]&*#?|\-<>=!%@:"`,, \n]/g;
|
||||||
|
|
||||||
const SPECIAL_CHAR_REG_REPLACE: Map<string, string> = new Map([
|
const SPECIAL_CHAR_REG_REPLACE: Map<string, string> = new Map([
|
||||||
['{', '\\{'],
|
['{', '\\{'],
|
||||||
|
|||||||
@ -59,9 +59,6 @@
|
|||||||
"2.2.1": "0.12.0",
|
"2.2.1": "0.12.0",
|
||||||
"2.2.2": "0.12.0",
|
"2.2.2": "0.12.0",
|
||||||
"2.2.3": "0.12.0",
|
"2.2.3": "0.12.0",
|
||||||
"2.2.4": "0.12.0",
|
"2.2.4": "0.12.0"
|
||||||
"2.3.0": "0.12.0",
|
|
||||||
"2.3.1": "0.12.0",
|
|
||||||
"2.3.2": "0.12.0"
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user