add array display type

fix write enter to editor when search item
fix desc has "\"     " error
This commit is contained in:
HughWan 2023-12-26 15:18:11 +08:00
parent 0455b379d6
commit 446a37e03b
32 changed files with 1011 additions and 389 deletions

@ -40,7 +40,7 @@
## 效果
1. 结合Timeline插件 __构建个人观影时间线__,请参照[结合timeline插件实现时间线效果](./doc/Obsidian-Douban-TimeLine.md)
<!--2. 结合DataView插件__构建个人电子书架书库数据__请参照[结合dateview插件实现个人书架效果](./doc/Obsidian-Douban-DataView.md))-->
2. 结合主题 __构建类豆瓣网页效果__,请参照[结合Blue Topaz实现网页效果](./doc/Obsidian-Douban-TimeLine.md)
2. 结合主题 __构建类豆瓣网页效果__,请参照[结合Blue Topaz实现网页效果](./doc/Obsidian-Douban-BlueTopaz.md)
## 如何使用
@ -62,16 +62,16 @@
## 支持的字段
(若有缺少想导入的字段, 欢迎提issues反馈)
| 字段 | 电影 | 电视剧 | 书籍 | 音乐 | 日记 | 游戏 | * |
|------------------|-------------------|------------------|-------------------|----------------|----------------|---------------|-------|
| 字段 | 电影 | 电视剧 | 书籍 | 音乐 | 日记 | 游戏 | 人物 |
|------------------|-------------------|-------------------|-------------------|----------------|----------------|---------------|-------|
| id | 豆瓣ID | 豆瓣ID | 豆瓣ID | 豆瓣ID | 豆瓣ID | 豆瓣ID | id |
| title | 电影名称 | 电视剧名称 | 书名 | 音乐名 | 日记标题 | 游戏名称 | 名 |
| title | 电影名称 | 电视剧名称 | 书名 | 音乐名 | 日记标题 | 游戏名称 | 名 |
| type | 类型 | 类型 | 类型 | 类型 | 类型 | 类型 | 类型 |
| score | 评分 | 评分 | 评分 | 评分 | 评分 | 评分 | 评分 |
| image | 封面 | 封面 | 封面 | 封面 | 图片 | 封面 | 封面 |
| imageData.url | 封面url | 封面url | 封面url | 封面url | 封面url | 封面url | 封面url |
| url | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | - |
| desc | 简介 | 简介 | 内容简介 | 简介 | 简介 | 简介 | - |
| score | 评分 | 评分 | 评分 | 评分 | 评分 | 评分 | |
| image | 封面 | 封面 | 封面 | 封面 | 图片 | 封面 | 照片 |
| imageData.url | 封面url | 封面url | 封面url | 封面url | 封面url | 封面url | 照片url |
| url | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 |
| desc | 简介 | 简介 | 内容简介 | 简介 | 简介 | 简介 | 简介 |
| publisher | - | - | 出版社 | 出版者 | 发布者 | 发行商 | - |
| datePublished | 上映日期 | 上映日期 | 出版年 | 发行时间 | 发布时间 | 发行日期 | - |
| yearPublished | 上映年份 | 上映年份 | 出版年份 | 发行年份 | 发布年份 | 发行年份 | - |

@ -0,0 +1,100 @@
## 效果如下
![](./background.png)
## 适用人群
1. 在豆瓣有标记/评论/评分的习惯的人
比如看完电影,会在豆瓣进行评分或评论。或者阅读完的书籍,进行评分或评论。支持包含:电影、书籍、电视剧、音乐、游戏
## 实现步骤
1. 安装[Blue Topaz](https://github.com/PKM-er/Blue-Topaz_Obsidian-css)插件, 可在Obsidian主题搜索中找到 `Blue Topaz`
2. 安装[Obsidian-Douban](https://github.com/Wanxp/obsidian-douban)插件(本插件)
3. 在Obsidian-Douban插件配置中登录Douban
4. 配置需要的模板, 在模板最后增加以下内容,如下所示
````markdown
---
# {{title}}
<div style="text-align: center;"> {{originalTitle}} </div>
<div style="text-align: center;">⭐⭐⭐⭐⭐</div>
---
> [!bookinfo|noicon]+ 🗒️ **简介**
> ![bookcover|250]( {{image}})
>
| 属性 | 内容 |
|:-------- |:------------------------ |
| 笔记 | [[摘录:{{title}}]] |
| 作者 | [[{{author}}]] |
| 译者 | [[{{translator(ArrayType1)}}]] |
| 来源 | [ {{title}} ]( {{url}} ) |
| 网站评分 | {{score}} |
| 出版发行 | {{publisher}} |
| 原作名 | {{originalTitle}} |
| 出版年份 | {{yearPublished}} |
> [!note]- 书籍简介\
> {{desc}}
---
### 评论
{{myComment}}
````
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}}
coverUrl: {{imageData.url}}
createTime: {{currentDate}} {{currentTime}}
collectionDate: {{myCollectionDate}}
desc: {{desc}}
---
![image]({{image}})
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)

@ -395,5 +395,22 @@ export enum SubjectHandledStatus {
syncTypeDiffAbort = 'syncTypeDiffAbort',
}
export const DEFAULT_SETTINGS_ARRAY_INPUT_SIZE = 2;
export enum DataValueType {
date,
number,
string,
person,
array,
url,
path,
}
export enum DataTargetType {
fileName,
yaml,
content,
}

@ -2,6 +2,17 @@ import {DoubanPluginSetting} from "../douban/setting/model/DoubanPluginSetting";
import {PersonNameMode, SupportType} from "./Constsant";
export const DEFAULT_SETTINGS: DoubanPluginSetting = {
arraySettings: [
{
"arrayName": "ArrayType1",
"arrayStart": "",
"arrayElementStart": "[[",
"arraySpiltV2": ",",
"arrayElementEnd": "]]",
"arrayEnd": "",
"index": 1
}
],
onlineSettingsFileName: "obsidian_douban_plugin_online_settings.json",
onlineSettingsGistId: "35693f9ece9bd6abba98f94e81afde19",
movieTemplateFile: ``,

@ -1,14 +1,16 @@
import DoubanPlugin from "../../../main";
import DoubanSubject, {DoubanParameter} from '../model/DoubanSubject';
import DoubanSubject, {DoubanParameterName} from '../model/DoubanSubject';
import DoubanSubjectLoadHandler from "./DoubanSubjectLoadHandler";
import {moment, request, RequestUrlParam, TFile} from "obsidian";
import {moment, TFile} from "obsidian";
import {i18nHelper} from 'src/org/wanxp/lang/helper';
import {log} from "src/org/wanxp/utils/Logutil";
import {CheerioAPI, load} from "cheerio";
import YamlUtil from "../../../utils/YamlUtil";
import {
BasicConst,
PersonNameMode, PropertyName,
DataValueType,
PersonNameMode,
PropertyName,
SearchHandleMode,
SupportType,
TemplateKey,
@ -19,18 +21,17 @@ import HandleResult from "../model/HandleResult";
import {getDefaultTemplateContent} from "../../../constant/DefaultTemplateContent";
import StringUtil from "../../../utils/StringUtil";
import {DEFAULT_SETTINGS} from "../../../constant/DefaultSettings";
import {DoubanUserParameter, UserStateSubject} from "../model/UserStateSubject";
import {DoubanUserParameter, DoubanUserParameterName, UserStateSubject} from "../model/UserStateSubject";
import {
DoubanSubjectState,
DoubanSubjectStateRecords,
DoubanSubjectStateRecords_KEY_WORD_TYPE
} from "../../../constant/DoubanUserState";
import DoubanLoginModel from "../../component/DoubanLoginModel";
import DoubanHumanCheckModel from "../../component/DoubanHumanCheckModel";
import DoubanMovieSubject from "../model/DoubanMovieSubject";
import {Person} from "schema-dts";
import HttpUtil from "../../../utils/HttpUtil";
import HtmlUtil from "../../../utils/HtmlUtil";
import {VariableUtil} from "../../../utils/VariableUtil";
import {DataField} from "../../../utils/model/DataField";
export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject> implements DoubanSubjectLoadHandler<T> {
@ -46,10 +47,10 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
await this.saveImage(extract, context);
const frontMatterStart: number = template.indexOf(BasicConst.YAML_FRONT_MATTER_SYMBOL, 0);
const frontMatterEnd: number = template.indexOf(BasicConst.YAML_FRONT_MATTER_SYMBOL, frontMatterStart + 1);
let frontMatter: string = '';
let frontMatterBefore: string = '';
let frontMatterAfter: string = '';
let result: string = '';
let frontMatter = '';
let frontMatterBefore = '';
let frontMatterAfter = '';
let result = '';
if (frontMatterStart > -1 && frontMatterEnd > -1) {
frontMatterBefore = template.substring(0, frontMatterStart);
frontMatter = template.substring(frontMatterStart, frontMatterEnd + 3);
@ -67,7 +68,7 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
} else {
result = this.parsePartText(template, extract, context);
}
let fileName: string = '';
let fileName = '';
if (SearchHandleMode.FOR_CREATE == context.mode) {
fileName = this.parsePartText(this.getFileName(context), extract, context);
}
@ -99,48 +100,11 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
return result;
}
/**
*
* @param array
* @param settings
* @param textMode
*/
handleContentArray(array: any[], context: HandleContext, textMode: TemplateTextMode): string {
let result;
switch (textMode) {
// case TemplateTextMode.YAML:
// result = array.map(YamlUtil.handleText).join(', ');
// break;
default:
result = this.handleArray(array, context);
}
return result;
}
/**
*
* @param value
* @param textMode
* @param settings
*/
handleSpecialContent(value: any, textMode: TemplateTextMode = TemplateTextMode.NORMAL, context: HandleContext = null): string {
let result;
if (!value) {
return '';
}
if (value instanceof Array) {
result = this.handleContentArray(value, context, textMode);
} else if (value instanceof Number) {
result = value.toString();
} else {
result = this.handleSpecialText(value, textMode);
}
return result;
}
abstract getSupportType(): SupportType;
abstract parseText(beforeContent: string, extract: T, context: HandleContext, textMode: TemplateTextMode): string;
abstract parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: T, context: HandleContext, textMode: TemplateTextMode): void;
abstract support(extract: DoubanSubject): boolean;
@ -184,9 +148,9 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
*/
private getGuessType(data: CheerioAPI):SupportType {
if (data) {
let text = data.html();
const text = data.html();
if (text) {
for (let [key, value] of DoubanSubjectStateRecords_KEY_WORD_TYPE) {
for (const [key, value] of DoubanSubjectStateRecords_KEY_WORD_TYPE) {
if (text.indexOf(key) >= 0) {
return value;
}
@ -243,7 +207,7 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
let regValue: RegExpExecArray;
switch (personNameMode) {
case PersonNameMode.CH_NAME:
regValue = /[\u4e00-\u9fa50-9\. ·\:\u3002|\uff1f|\uff01|\uff0c|\u3001|\uff1b|\uff1a|\u201c|\u201d|\u2018|\u2019|\uff08|\uff09|\u300a|\u300b|\u3008|\u3009|\u3010|\u3011|\u300e|\u300f|\u300c|\u300d|\ufe43|\ufe44|\u3014|\u3015|\u2026|\u2014|\uff5e|\ufe4f|\uffe5\(\)]{2,}/g.exec(name);
regValue = /[\u4e00-\u9fa50-9. ·:\u3002|\uff1f|\uff01|\uff0c|\u3001|\uff1b|\uff1a|\u201c|\u201d|\u2018|\u2019|\uff08|\uff09|\u300a|\u300b|\u3008|\u3009|\u3010|\u3011|\u300e|\u300f|\u300c|\u300d|\ufe43|\ufe44|\u3014|\u3015|\u2026|\u2014|\uff5e|\ufe4f|\uffe5()]{2,}/g.exec(name);
resultName = regValue ? regValue[0] : name;
break;
case PersonNameMode.EN_NAME:
@ -294,35 +258,63 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
s = s.replace(/&lt;/g, "<");
s = s.replace(/&gt;/g, ">");
s = s.replace(/&nbsp;/g, " ");
s = s.replace(/&#39;/g, "\'");
s = s.replace(/&#39;/g, "'");
s = s.replace(/&quot;/g, "\"");
s = s.replace(/<br\/>/g, "\n");
return s;
}
private parsePartText(template: string, extract: T, context: HandleContext, textMode: TemplateTextMode = TemplateTextMode.NORMAL): string {
let resultContent = this.handleCustomVariable(template, context);
resultContent = resultContent.replaceAll(DoubanParameter.ID, extract.id)
.replaceAll(DoubanParameter.TITLE, this.handleSpecialContent(extract.title, textMode))
.replaceAll(DoubanParameter.TYPE, extract.type)
.replaceAll(DoubanParameter.SCORE, this.handleSpecialContent(extract.score))
.replaceAll(DoubanParameter.IMAGE, extract.image)
.replaceAll(DoubanParameter.IMAGE_URL, extract.imageUrl)
.replaceAll(DoubanParameter.URL, extract.url)
.replaceAll(DoubanParameter.DESC, this.handleSpecialContent(extract.desc, textMode))
.replaceAll(DoubanParameter.PUBLISHER, extract.publisher)
.replaceAll(DoubanParameter.YEAR_PUBLISHED, extract.datePublished ? moment(extract.datePublished).format('yyyy') : '')
.replaceAll(DoubanParameter.DATE_PUBLISHED, extract.datePublished ? moment(extract.datePublished).format(context.settings.dateFormat) : '')
.replaceAll(DoubanParameter.TIME_PUBLISHED, extract.datePublished ? moment(extract.datePublished).format(context.settings.timeFormat) : '')
.replaceAll(DoubanParameter.CURRENT_DATE, moment(new Date()).format(context.settings.dateFormat))
.replaceAll(DoubanParameter.CURRENT_TIME, moment(new Date()).format(context.settings.timeFormat))
.replaceAll(DoubanParameter.GENRE, this.handleSpecialContent(extract.genre, textMode, context))
;
resultContent = this.parseUserInfo(resultContent, extract, context, textMode);
return this.parseText(resultContent, extract, context, textMode);
const variableMap:Map<string, DataField> = new Map();
for (const [key, value] of Object.entries(extract)) {
const type:DataValueType = VariableUtil.getType(value);
variableMap.set(key, new DataField(key, type, value, value));
}
variableMap.set(DoubanParameterName.IMAGE_URL, new DataField(
DoubanParameterName.IMAGE_URL,
DataValueType.url,
extract.imageUrl,
extract.imageUrl
));
variableMap.set(DoubanParameterName.YEAR_PUBLISHED, new DataField(
DoubanParameterName.YEAR_PUBLISHED,
DataValueType.date,
extract.datePublished,
extract.datePublished ? moment(extract.datePublished).format('yyyy') : ''
));
variableMap.set(DoubanParameterName.DATE_PUBLISHED, new DataField(
DoubanParameterName.DATE_PUBLISHED,
DataValueType.date,
extract.datePublished,
extract.datePublished ? moment(extract.datePublished).format(context.settings.dateFormat) : ''
));
variableMap.set(DoubanParameterName.TIME_PUBLISHED, new DataField(
DoubanParameterName.TIME_PUBLISHED,
DataValueType.date,
extract.datePublished,
extract.datePublished ? moment(extract.datePublished).format(context.settings.timeFormat) : ''
));
const currentDate = new Date();
variableMap.set(DoubanParameterName.CURRENT_DATE, new DataField(
DoubanParameterName.CURRENT_DATE,
DataValueType.date,
currentDate,
moment(currentDate).format(context.settings.dateFormat)
));
variableMap.set(DoubanParameterName.CURRENT_TIME, new DataField(
DoubanParameterName.CURRENT_TIME,
DataValueType.date,
currentDate,
moment(currentDate).format(context.settings.timeFormat)
));
this.parseUserInfo(template, variableMap, extract, context, textMode);
this.parseVariable(template, variableMap, extract, context, textMode);
this.handleCustomVariable(template, variableMap, context);
return VariableUtil.replace(variableMap, template, this.doubanPlugin.settingsManager);
}
private parseUserInfo(resultContent: string, extract: T, context: HandleContext, textMode: TemplateTextMode) {
private parseUserInfo(resultContent: string, variableMap:Map<string, DataField>, extract: T, context: HandleContext, textMode: TemplateTextMode) {
const userState = extract.userState;
if ((resultContent.indexOf(DoubanUserParameter.MY_TAGS) >= 0 ||
resultContent.indexOf(DoubanUserParameter.MY_RATING) >= 0 ||
@ -341,11 +333,23 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
}else {
tags = [extract.type];
}
return resultContent.replaceAll(DoubanUserParameter.MY_TAGS, this.handleSpecialContent(tags, textMode, context))
.replaceAll(DoubanUserParameter.MY_RATING, this.handleSpecialContent(userState.rate, textMode))
.replaceAll(DoubanUserParameter.MY_STATE, this.getUserStateName(userState.state))
.replaceAll(DoubanUserParameter.MY_COMMENT, this.handleSpecialContent(userState.comment, textMode))
.replaceAll(DoubanUserParameter.MY_COLLECTION_DATE, userState.collectionDate?moment(userState.collectionDate).format(context.settings.dateFormat): '')
Object.entries(userState).forEach(([key, value]) => {
variableMap.set(key, value);
});
variableMap.set(DoubanUserParameterName.MY_TAGS, new DataField(DoubanUserParameterName.MY_TAGS, DataValueType.array, tags, tags));
variableMap.set(DoubanUserParameterName.MY_STATE, new DataField(
DoubanUserParameterName.MY_STATE,
DataValueType.string,
userState,
this.getUserStateName(userState.state)
));
variableMap.set(DoubanUserParameterName.MY_COLLECTION_DATE, new DataField(
DoubanUserParameterName.MY_COLLECTION_DATE,
DataValueType.date,
userState.collectionDate,
userState.collectionDate ? moment(userState.collectionDate).format(context.settings.dateFormat) : ''
));
}
/**
@ -354,19 +358,24 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
* @param context
* @private
*/
private handleCustomVariable(template: string, context: HandleContext): string {
let customProperties = context.settings.customProperties;
let resultContent = template;
private handleCustomVariable(template: string, variableMap:Map<string, DataField>, context: HandleContext): void {
const customProperties = context.settings.customProperties;
if (!customProperties) {
return resultContent;
return ;
}
const customPropertiesMap= new Map();
customProperties.filter(customProperty => customProperty.name &&
customProperty.field
&& (customProperty.field.toLowerCase() == SupportType.ALL ||
customProperty.field.toLowerCase() == this.getSupportType())).forEach(customProperty => {
resultContent = resultContent.replaceAll(`{{${customProperty.name}}}`, customProperty.value);
customPropertiesMap.set(customProperty.name, customProperty.value);
});
return resultContent;
customPropertiesMap.forEach((value, key) => {
variableMap.set(key,
new DataField(
key, DataValueType.string, value,
VariableUtil.replace(variableMap, value, this.doubanPlugin.settingsManager)));
})
}
private getTemplateKey():TemplateKey {
@ -421,7 +430,7 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
return getDefaultTemplateContent(tempKey, useUserState);
}
const defaultContent = getDefaultTemplateContent(tempKey, useUserState);
let firstLinkpathDest: TFile = this.doubanPlugin.app.metadataCache.getFirstLinkpathDest(templatePath, '');
const firstLinkpathDest: TFile = this.doubanPlugin.app.metadataCache.getFirstLinkpathDest(templatePath, '');
if (!firstLinkpathDest) {
return defaultContent;
} else {
@ -465,7 +474,7 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
if (!state) {
return '';
}
let v = DoubanSubjectStateRecords[this.getSupportType()];
const v = DoubanSubjectStateRecords[this.getSupportType()];
switch (state) {
case DoubanSubjectState.wish:
return v.wish;
@ -520,7 +529,7 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
handlePersonNameByMeta(html: CheerioAPI, movie: DoubanSubject, context: HandleContext,
metaProperty:string, objectProperty:string) {
let metaProperties: string[] = html(`head > meta[property='${metaProperty}']`).get()
const metaProperties: string[] = html(`head > meta[property='${metaProperty}']`).get()
.map((e) => {
return html(e).attr('content');
});
@ -544,10 +553,7 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
return HtmlUtil.getHtmlText(html, this.doubanPlugin.settingsManager.getSelector(this.getSupportType(), name));
}
protected handleArray(arr: string[], context: HandleContext): string {
const {settings} = context;
return StringUtil.handleArray(arr, settings);
}
}

@ -3,11 +3,12 @@ import DoubanAbstractLoadHandler from "./DoubanAbstractLoadHandler";
import DoubanBookSubject, {DoubanBookParameter} from "../model/DoubanBookSubject";
import DoubanPlugin from "../../../main";
import DoubanSubject from "../model/DoubanSubject";
import {PropertyName, SupportType, TemplateTextMode} from "../../../constant/Constsant";
import {DataValueType, PropertyName, SupportType, TemplateTextMode} from "../../../constant/Constsant";
import HandleContext from "../model/HandleContext";
import StringUtil from "../../../utils/StringUtil";
import {UserStateSubject} from "../model/UserStateSubject";
import {moment} from "obsidian";
import {DataField} from "../../../utils/model/DataField";
export default class DoubanBookLoadHandler extends DoubanAbstractLoadHandler<DoubanBookSubject> {
@ -27,22 +28,9 @@ export default class DoubanBookLoadHandler extends DoubanAbstractLoadHandler<Dou
return `https://book.douban.com/subject/${id}/`;
}
parseText(beforeContent: string, extract: DoubanBookSubject, context: HandleContext, textMode: TemplateTextMode): string {
return beforeContent
.replaceAll(DoubanBookParameter.author,
super.handleSpecialContent(
extract.author.map(this.handleSpecialAuthorName), textMode, context))
.replaceAll(DoubanBookParameter.translator, super.handleSpecialContent(extract.translator, textMode, context))
.replaceAll(DoubanBookParameter.isbn, extract.isbn)
.replaceAll(DoubanBookParameter.originalTitle, super.handleSpecialContent(extract.originalTitle, textMode))
.replaceAll(DoubanBookParameter.subTitle, super.handleSpecialContent(extract.subTitle, textMode))
.replaceAll(DoubanBookParameter.totalPage, super.handleSpecialContent(extract.totalPage, textMode))
.replaceAll(DoubanBookParameter.menu, extract.menu.join('\n'))
.replaceAll(DoubanBookParameter.price, super.handleSpecialContent(extract.price, textMode))
.replaceAll(DoubanBookParameter.series, super.handleSpecialContent(extract.series, textMode))
.replaceAll(DoubanBookParameter.binding, super.handleSpecialContent(extract.binding, textMode))
.replaceAll(DoubanBookParameter.producer, super.handleSpecialContent(extract.producer, textMode))
;
parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: DoubanBookSubject, context: HandleContext, textMode: TemplateTextMode): void {
variableMap.set(DoubanBookParameter.author, new DataField(DoubanBookParameter.author,
DataValueType.array, extract.author, extract.author.map(this.handleSpecialAuthorName)));
}
support(extract: DoubanSubject): boolean {

@ -3,11 +3,12 @@ import DoubanAbstractLoadHandler from "./DoubanAbstractLoadHandler";
import DoubanPlugin from "../../../main";
import DoubanSubject from '../model/DoubanSubject';
import DoubanGameSubject from '../model/DoubanGameSubject';
import StringUtil from "../../../utils/StringUtil";
import HandleContext from "../model/HandleContext";
import {PersonNameMode, SupportType, TemplateKey} from "../../../constant/Constsant";
import {DataValueType, PersonNameMode, SupportType} from "../../../constant/Constsant";
import {UserStateSubject} from "../model/UserStateSubject";
import {moment} from "obsidian";
import {TITLE_ALIASES_SPECIAL_CHAR_REG_G} from "../../../utils/YamlUtil";
import {DataField} from "../../../utils/model/DataField";
export default class DoubanGameLoadHandler extends DoubanAbstractLoadHandler<DoubanGameSubject> {
@ -26,12 +27,8 @@ export default class DoubanGameLoadHandler extends DoubanAbstractLoadHandler<Dou
return `https://www.douban.com/game/${id}/`;
}
parseText(beforeContent: string, extract: DoubanGameSubject, context: HandleContext): string {
const {settings} = context;
return beforeContent
.replaceAll("{{platform}}", this.handleArray(extract.platform, context))
.replaceAll("{{aliases}}", this.handleArray(extract.aliases, context))
.replaceAll("{{developer}}", extract.developer ? extract.developer : "");
parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: DoubanGameSubject, context: HandleContext): void {
variableMap.set("aliases", new DataField("aliases", DataValueType.array, extract.aliases, extract.aliases.map(a=>a.replace(TITLE_ALIASES_SPECIAL_CHAR_REG_G, '_'))));
}
support(extract: DoubanSubject): boolean {

@ -6,10 +6,11 @@ import DoubanSubject from '../model/DoubanSubject';
import DoubanMovieSubject from '../model/DoubanMovieSubject';
import StringUtil from "../../../utils/StringUtil";
import HandleContext from "../model/HandleContext";
import {PersonNameMode, PropertyName, SupportType, TemplateKey} from "../../../constant/Constsant";
import {DataValueType, PersonNameMode, PropertyName, SupportType, TemplateKey} from "../../../constant/Constsant";
import {UserStateSubject} from "../model/UserStateSubject";
import {moment} from "obsidian";
import YamlUtil, {SPECIAL_CHAR_REG, TITLE_ALIASES_SPECIAL_CHAR_REG_G} from "../../../utils/YamlUtil";
import {DataField} from "../../../utils/model/DataField";
export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<DoubanMovieSubject> {
@ -29,19 +30,34 @@ export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<Do
return `https://movie.douban.com/subject/${id}/`;
}
parseText(beforeContent: string, extract: DoubanMovieSubject, context: HandleContext): string {
const {settings} = context;
return beforeContent
.replaceAll("{{originalTitle}}", extract.originalTitle ?? "")
.replaceAll("{{director}}", this.handleArray(extract.director.map(SchemaOrg.getPersonName).filter(c => c), context))
.replaceAll("{{actor}}", this.handleArray( extract.actor.map(SchemaOrg.getPersonName).filter(c => c), context))
.replaceAll("{{author}}", this.handleArray(extract.author.map(SchemaOrg.getPersonName).map(name => super.getPersonName(name, context)).filter(c => c), context))
.replaceAll("{{aliases}}", this.handleArray(extract.aliases.map(a=>a.replace(TITLE_ALIASES_SPECIAL_CHAR_REG_G, '_')), context))
.replaceAll("{{country}}", this.handleArray( extract.country, context))
.replaceAll("{{language}}",this.handleArray( extract.language, context))
.replaceAll("{{IMDb}}", extract.IMDb ??"")
.replaceAll("{{time}}", extract.time ??"")
;
parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: DoubanMovieSubject, 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.replace(TITLE_ALIASES_SPECIAL_CHAR_REG_G, '_'))
));
}
support(extract: DoubanSubject): boolean {

@ -4,9 +4,10 @@ import DoubanMusicSubject from '../model/DoubanMusicSubject';
import DoubanPlugin from "../../../main";
import DoubanSubject from '../model/DoubanSubject';
import HandleContext from "../model/HandleContext";
import {SupportType, TemplateKey} from "../../../constant/Constsant";
import {SupportType} from "../../../constant/Constsant";
import {UserStateSubject} from "../model/UserStateSubject";
import {moment} from "obsidian";
import {DataField} from "../../../utils/model/DataField";
export default class DoubanMusicLoadHandler extends DoubanAbstractLoadHandler<DoubanMusicSubject> {
@ -26,15 +27,7 @@ export default class DoubanMusicLoadHandler extends DoubanAbstractLoadHandler<Do
return `https://music.douban.com/subject/${id}/`;
}
parseText(beforeContent: string, extract: DoubanMusicSubject, context: HandleContext): string {
const {settings} = context;
return beforeContent
.replaceAll("{{actor}}", this.handleArray(extract.actor, context ))
.replaceAll("{{barcode}}", extract.barcode ? extract.barcode : "")
.replaceAll("{{medium}}", extract.medium ? extract.medium : "")
.replaceAll("{{albumType}}", extract.albumType ? extract.albumType : "")
.replaceAll("{{records}}", extract.records ? extract.records + "" : "")
;
parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: DoubanMusicSubject, context: HandleContext): void {
}
support(extract: DoubanSubject): boolean {
@ -83,7 +76,7 @@ export default class DoubanMusicLoadHandler extends DoubanAbstractLoadHandler<Do
let value = '';
if (key.indexOf('表演者') >= 0) {
// value = html(info.next.next).text().trim();
let vas: string[] = key.split("\n \n ");
const vas: string[] = key.split("\n \n ");
value = vas && vas.length > 1 ? vas[1] : "";
key = vas && vas.length > 0 ? vas[0] : "";
} else {
@ -92,8 +85,8 @@ export default class DoubanMusicLoadHandler extends DoubanAbstractLoadHandler<Do
valueMap.set(MusicKeyValueMap.get(key), value);
})
let idPattern = /(\d){5,10}/g;
let id = idPattern.exec(url);
const idPattern = /(\d){5,10}/g;
const id = idPattern.exec(url);
const result: DoubanMusicSubject = {
image: image,

@ -7,6 +7,7 @@ import html2markdown from '@notable/html2markdown';
import HandleContext from "../model/HandleContext";
import {SupportType, TemplateKey} from "../../../constant/Constsant";
import {UserStateSubject} from "../model/UserStateSubject";
import {DataField} from "../../../utils/model/DataField";
export default class DoubanNoteLoadHandler extends DoubanAbstractLoadHandler<DoubanNoteSubject> {
@ -26,12 +27,7 @@ export default class DoubanNoteLoadHandler extends DoubanAbstractLoadHandler<Dou
return `https://www.douban.com/note/${id}/`;
}
parseText(beforeContent: string, extract: DoubanNoteSubject, context: HandleContext): string {
return beforeContent
.replaceAll("{{authorUrl}}", extract.authorUrl ? extract.authorUrl : "")
.replaceAll("{{content}}", extract.content ? extract.content : "")
.replaceAll("{{author}}", extract.author ? extract.author : "")
;
parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: DoubanNoteSubject, context: HandleContext): void {
}
support(extract: DoubanSubject): boolean {
@ -43,16 +39,16 @@ export default class DoubanNoteLoadHandler extends DoubanAbstractLoadHandler<Dou
}
parseSubjectFromHtml(html: CheerioAPI, context: HandleContext): DoubanNoteSubject {
let title = html(html("head > meta[property= 'og:title']").get(0)).attr("content");
let desc = html(html("head > meta[property= 'og:description']").get(0)).attr("content");
let url = html(html("head > meta[property= 'og:url']").get(0)).attr("content");
let image = html(html("head > meta[property= 'og:image']").get(0)).attr("content");
let type = html(html("head > meta[property= 'og:type']").get(0)).attr("content");
let authorA = html(html("a.note-author").get(0));
let timePublished = html(html(".pub-date").get(0)).text();
let content = html(html(".note").get(1));
let idPattern = /(\d){5,10}/g;
let id = idPattern.exec(url);
const title = html(html("head > meta[property= 'og:title']").get(0)).attr("content");
const desc = html(html("head > meta[property= 'og:description']").get(0)).attr("content");
const url = html(html("head > meta[property= 'og:url']").get(0)).attr("content");
const image = html(html("head > meta[property= 'og:image']").get(0)).attr("content");
const type = html(html("head > meta[property= 'og:type']").get(0)).attr("content");
const authorA = html(html("a.note-author").get(0));
const timePublished = html(html(".pub-date").get(0)).text();
const content = html(html(".note").get(1));
const idPattern = /(\d){5,10}/g;
const id = idPattern.exec(url);
const result: DoubanNoteSubject = {
image: image,

@ -6,6 +6,7 @@ import {log} from "src/org/wanxp/utils/Logutil";
import HandleContext from "../model/HandleContext";
import {SupportType, TemplateKey} from "../../../constant/Constsant";
import {UserStateSubject} from "../model/UserStateSubject";
import {DataField} from "../../../utils/model/DataField";
/**
*
@ -15,9 +16,8 @@ export default class DoubanOtherLoadHandler extends DoubanAbstractLoadHandler<Do
return SupportType.ALL;
}
parseText(beforeContent: string, extract: DoubanSubject, context: HandleContext): string {
parseVariable(beforeContent: string, variableMap:Map<string, DataField>, extract: DoubanSubject, context: HandleContext): void {
log.warn(i18nHelper.getMessage('140101'));
return "";
}
support(extract: DoubanSubject): boolean {

@ -5,11 +5,11 @@ import DoubanSubject from "../model/DoubanSubject";
import DoubanTeleplaySubject from "../model/DoubanTeleplaySubject";
import SchemaOrg from "src/org/wanxp/utils/SchemaOrg";
import HandleContext from "../model/HandleContext";
import {PersonNameMode, SupportType, TemplateKey} from "../../../constant/Constsant";
import {aliases} from "css-select";
import {DataValueType, PersonNameMode, SupportType} from "../../../constant/Constsant";
import {UserStateSubject} from "../model/UserStateSubject";
import {moment} from "obsidian";
import YamlUtil, {SPECIAL_CHAR_REG, 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";
/**
* teleplay
@ -24,20 +24,28 @@ export class DoubanTeleplayLoadHandler extends DoubanAbstractLoadHandler<DoubanT
return SupportType.TELEPLAY;
}
parseText(beforeContent: string, extract: DoubanTeleplaySubject, context: HandleContext): string {
const {settings} = context;
return beforeContent
.replaceAll("{{originalTitle}}", extract.originalTitle ?? "")
.replaceAll("{{director}}", this.handleArray( extract.director.map(SchemaOrg.getPersonName).filter(c => c), context))
.replaceAll("{{actor}}", this.handleArray( extract.actor.map(SchemaOrg.getPersonName).filter(c => c), context))
.replaceAll("{{author}}", this.handleArray( extract.author.map(SchemaOrg.getPersonName).map(name => super.getPersonName(name, context)).filter(c => c), context))
.replaceAll("{{aliases}}", this.handleArray( extract.aliases.map(a=>a.replace(TITLE_ALIASES_SPECIAL_CHAR_REG_G, '_')), context))
.replaceAll("{{country}}", this.handleArray( extract.country, context))
.replaceAll("{{language}}", this.handleArray(extract.language, context))
.replaceAll("{{IMDb}}", extract.IMDb?? "")
.replaceAll("{{time}}", extract.time ?? "")
.replaceAll("{{episode}}", extract.episode ?? "")
;
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("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.replace(TITLE_ALIASES_SPECIAL_CHAR_REG_G, '_'))
));
}
support(extract: DoubanSubject): boolean {
@ -52,14 +60,14 @@ export class DoubanTeleplayLoadHandler extends DoubanAbstractLoadHandler<DoubanT
}
analysisUser(html: CheerioAPI, context: HandleContext): {data:CheerioAPI , userState: UserStateSubject} {
let rate = html('input#n_rating').val();
const rate = html('input#n_rating').val();
const rating = html('span#rating');
let tagsStr = rating.next().next().text().trim();
let tags = tagsStr ? tagsStr.replace('标签:', '').trim().split(' ') : null;
let stateWord = html('div#interest_sect_level > div.a_stars > span.mr10').text().trim();
let collectionDateStr = html('div#interest_sect_level > div.a_stars > span.mr10 > span.collection_date').text().trim();
let userState1 = DoubanAbstractLoadHandler.getUserState(stateWord);
let component = rating.next().next().next().next().text().trim();
const tagsStr = rating.next().next().text().trim();
const tags = tagsStr ? tagsStr.replace('标签:', '').trim().split(' ') : null;
const stateWord = html('div#interest_sect_level > div.a_stars > span.mr10').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 = rating.next().next().next().next().text().trim();
const userState: UserStateSubject = {
tags: tags,

@ -4,11 +4,12 @@ import DoubanPlugin from "../../../main";
import SchemaOrg from "src/org/wanxp/utils/SchemaOrg";
import DoubanSubject from '../model/DoubanSubject';
import HandleContext from "../model/HandleContext";
import {PropertyName, SupportType} from "../../../constant/Constsant";
import {DataValueType, PropertyName, SupportType} from "../../../constant/Constsant";
import {UserStateSubject} from "../model/UserStateSubject";
import {moment} from "obsidian";
import {TITLE_ALIASES_SPECIAL_CHAR_REG_G} from "../../../utils/YamlUtil";
import DoubanTheaterSubject from "../model/DoubanTheaterSubject";
import {DataField} from "../../../utils/model/DataField";
export default class DoubanTheaterLoadHandler extends DoubanAbstractLoadHandler<DoubanTheaterSubject> {
constructor(doubanPlugin: DoubanPlugin) {
@ -27,15 +28,34 @@ export default class DoubanTheaterLoadHandler extends DoubanAbstractLoadHandler<
return `https://www.douban.com/location/drama/${id}/`;
}
parseText(beforeContent: string, extract: DoubanTheaterSubject, context: HandleContext): string {
return beforeContent
.replaceAll("{{originalTitle}}", extract.originalTitle ? extract.originalTitle : "")
.replaceAll("{{director}}", this.handleArray(extract.director.map(SchemaOrg.getPersonName).map(name => super.getPersonName(name, context)).filter(c => c), context))
.replaceAll("{{actor}}", this.handleArray(extract.actor.map(SchemaOrg.getPersonName).map(name => super.getPersonName(name, context)).filter(c => c), context))
.replaceAll("{{author}}", this.handleArray(extract.author.map(SchemaOrg.getPersonName).map(name => super.getPersonName(name, context)).filter(c => c), context))
.replaceAll("{{aliases}}", this.handleArray(extract.aliases.map(a => a.replace(TITLE_ALIASES_SPECIAL_CHAR_REG_G, '_')), context))
.replaceAll("{{language}}", this.handleArray(extract.language, context))
;
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.replace(TITLE_ALIASES_SPECIAL_CHAR_REG_G, '_'))
));
}
support(extract: DoubanSubject): boolean {
@ -43,13 +63,13 @@ export default class DoubanTheaterLoadHandler extends DoubanAbstractLoadHandler<
}
analysisUser(html: CheerioAPI, context: HandleContext): { data: CheerioAPI, userState: UserStateSubject } {
let rate = html('input#n_rating').val();
let tagsStr = html('div#interest_sect_level > div.a_stars > span.color_gray').text().trim();
let tags = tagsStr ? tagsStr.replace('标签:', '').trim().split(' ') : null;
let stateWord = html('#interest_sect_level > h2').text().trim();
let collectionDateStr = html('div#interest_sect_level > div.a_stars > span.mr10 > span.collection_date').text().trim();
let userState1 = DoubanAbstractLoadHandler.getUserState(stateWord);
let component = this.getPropertyValue(html, PropertyName.comment);
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,

@ -15,15 +15,15 @@ export default class DoubanBookSubject extends DoubanSubject {
}
export const DoubanBookParameter = {
author: '{{author}}',
translator: '{{translator}}',
isbn: '{{isbn}}',
originalTitle: '{{originalTitle}}',
subTitle: '{{subTitle}}',
totalPage: '{{totalPage}}',
series: '{{series}}',
menu: '{{menu}}',
price: '{{price}}',
binding: '{{binding}}',
producer: '{{producer}}',
author: 'author',
translator: 'translator',
isbn: 'isbn',
originalTitle: 'originalTitle',
subTitle: 'subTitle',
totalPage: 'totalPage',
series: 'series',
menu: 'menu',
price: 'price',
binding: 'binding',
producer: 'producer',
}

@ -39,3 +39,22 @@ export const DoubanParameter = {
CURRENT_DATE: '{{currentDate}}',
CURRENT_TIME: '{{currentTime}}',
}
export const DoubanParameterName = {
ID: 'id',
TITLE: 'title',
TYPE: 'type',
SCORE: 'score',
IMAGE: 'image',
IMAGE_URL: 'imageData.url',
URL: 'url',
DESC: 'desc',
PUBLISHER: 'publisher',
DATE_PUBLISHED: 'datePublished',
TIME_PUBLISHED: 'timePublished',
YEAR_PUBLISHED: 'yearPublished',
GENRE: 'genre',
CURRENT_DATE: 'currentDate',
CURRENT_TIME: 'currentTime',
}

@ -15,3 +15,11 @@ export const DoubanUserParameter = {
MY_COMMENT: '{{myComment}}',
MY_COLLECTION_DATE: '{{myCollectionDate}}',
}
export const DoubanUserParameterName = {
MY_TAGS: 'myTags',
MY_RATING: 'myRating',
MY_STATE: 'myState',
MY_COMMENT: 'myComment',
MY_COLLECTION_DATE: 'myCollectionDate',
}

@ -1,9 +1,10 @@
import {App, DropdownComponent, Modal, TextComponent} from "obsidian";
import {App, ButtonComponent, DropdownComponent, Modal, Setting, TextComponent} from "obsidian";
import DoubanPlugin from "../../../main";
import {i18nHelper} from "src/org/wanxp/lang/helper";
import HandleContext from "../model/HandleContext";
import {SearchTypeRecords, SupportType} from "../../../constant/Constsant";
import {sleep} from "../../../utils/TimeUtil";
export class DoubanSearchModal extends Modal {
searchTerm: string;
@ -32,6 +33,7 @@ export class DoubanSearchModal extends Modal {
searchInput.inputEl.addEventListener("keydown", (event) => {
if (event.key === "Enter") {
sleep(1000);
this.close();
}
});
@ -49,21 +51,17 @@ export class DoubanSearchModal extends Modal {
const controls = contentEl.createDiv("controls");
controls.addClass("obsidian_douban_search_controls")
const searchButton = controls.createEl("button", {
text: i18nHelper.getMessage('110004'),
cls: "mod-cta",
attr: {
autofocus: true,
},
});
searchButton.addClass("obsidian_douban_search_button");
searchButton.addEventListener("click", this.close.bind(this));
const cancelButton = controls.createEl("button", {text: i18nHelper.getMessage('110005')});
cancelButton.addEventListener("click", this.close.bind(this));
cancelButton.addClass("obsidian_douban_cancel_button");
searchInput.inputEl.focus();
new ButtonComponent(controls)
.setButtonText(i18nHelper.getMessage('110004'))
.setCta()
.onClick(() => {
this.close();
}).setClass( "obsidian_douban_search_button");
new ButtonComponent(controls)
.setButtonText(i18nHelper.getMessage('110005'))
.onClick(() => {
this.close();
}).setClass( "obsidian_douban_cancel_button");
}
@ -76,3 +74,4 @@ export class DoubanSearchModal extends Modal {
}
}

@ -0,0 +1,162 @@
import SettingsManager from "./SettingsManager";
import {ArraySetting, DEFAULT_SETTINGS_ARRAY_NAME} from "./model/ArraySetting";
import {Setting, TextComponent} from "obsidian";
import {i18nHelper} from "../../lang/helper";
import {DEFAULT_SETTINGS} from "../../constant/DefaultSettings";
import {DEFAULT_SETTINGS_ARRAY_INPUT_SIZE} from "../../constant/Constsant";
export function arraySettingDisplayUI(containerEl: HTMLElement, manager: SettingsManager) {
containerEl.createEl('h3', {text: i18nHelper.getMessage('120601')});
arraySettingDisplay(containerEl.createDiv('array-settings'), manager, false);
}
export function arraySettingDisplay(containerEl: HTMLElement, manager: SettingsManager, displayExtraListTypeFlag: boolean = false) {
containerEl.empty();
const arraySet = new Setting(containerEl)
.setName(i18nHelper.getMessage('120601'))
.setDesc( i18nHelper.getMessage('120602'))
.addButton((button) => {
button
.setIcon('plus')
.setTooltip(i18nHelper.getMessage('120607'))
.onClick(async () => {
await manager.addArraySetting();
arraySettingDisplay(containerEl, manager, true);
});
});
if (displayExtraListTypeFlag) {
arraySettingDisplayItem(containerEl, manager, manager.getArraySetting(DEFAULT_SETTINGS_ARRAY_NAME));
displayExtraListType(manager, containerEl);
arraySet.addButton((button) => {
button
.setIcon('down-chevron-glyph')
.setTooltip(i18nHelper.getMessage('120608'))
.onClick(async () => {
arraySettingDisplay(containerEl, manager, false);
});
});
}else {
arraySet.addButton((button) => {
button
.setIcon('right-chevron-glyph')
.setTooltip(i18nHelper.getMessage('120608'))
.onClick(async () => {
arraySettingDisplay(containerEl, manager, true);
});
});
}
}
function arraySettingDisplayItem(containerEl: HTMLElement, manager: SettingsManager, arraySetting:ArraySetting) {
const arrSettingsUI = containerEl.createDiv('array-settings');
const arrShow = containerEl.createDiv('array-show');
const typeName = arraySetting.arrayName;
const arraySettingItems = new Setting(arrSettingsUI)
.setName(i18nHelper.getMessage('120604') + typeName )
.setDesc(i18nHelper.getMessage(`120605`) + (typeName == DEFAULT_SETTINGS_ARRAY_NAME ? '' : `(${typeName})`) +`}}`)
;
if(typeName != DEFAULT_SETTINGS_ARRAY_NAME) {
arraySettingItems.addButton((button) => {
button
.setIcon('trash')
.setTooltip(i18nHelper.getMessage('120606'))
.onClick(async () => {
await manager.removeArraySetting(arraySetting.arrayName);
arraySettingDisplay(containerEl, manager, true);
});
});
}
arrSettingsUI.createEl('label', {text: i18nHelper.getMessage('124109')})
const arrayStart = new TextComponent(arrSettingsUI);
arrayStart.setPlaceholder(DEFAULT_SETTINGS.arrayStart)
.setValue(arraySetting.arrayStart)
.onChange(async (value) => {
arraySetting.arrayStart = value;
await manager.updateArraySetting(arraySetting);
showArrayExample(arrShow, manager, arraySetting);
});
const arrayStartEl = arrayStart.inputEl;
arrayStartEl.size = DEFAULT_SETTINGS_ARRAY_INPUT_SIZE;
arrayStartEl.addClass('obsidian_douban_settings_input')
arrSettingsUI.appendChild(arrayStartEl).appendText(" ");
arrSettingsUI.createEl('label', {text: i18nHelper.getMessage('124110')})
const arrayElementStart = new TextComponent(arrSettingsUI);
arrayElementStart.setPlaceholder(DEFAULT_SETTINGS.arrayElementStart)
.setValue(arraySetting.arrayElementStart)
.onChange(async (value) => {
arraySetting.arrayElementStart = value;
await manager.updateArraySetting(arraySetting);
showArrayExample(arrShow, manager, arraySetting);
});
const arrayElementStartEl = arrayElementStart.inputEl;
arrayElementStartEl.addClass('obsidian_douban_settings_input')
arrayElementStartEl.size = DEFAULT_SETTINGS_ARRAY_INPUT_SIZE;
arrSettingsUI.appendChild(arrayElementStartEl).appendText(" ");
arrSettingsUI.createEl('label', {text: i18nHelper.getMessage('124111')})
const arraySpiltV2 = new TextComponent(arrSettingsUI);
arraySpiltV2.setPlaceholder(DEFAULT_SETTINGS.arraySpiltV2)
.setValue(arraySetting.arraySpiltV2)
.onChange(async (value) => {
arraySetting.arraySpiltV2 = value;
await manager.updateArraySetting(arraySetting);
showArrayExample(arrShow, manager, arraySetting);
});
const arraySpiltV2El = arraySpiltV2.inputEl;
arraySpiltV2El.addClass('obsidian_douban_settings_input')
arraySpiltV2El.size = 2;
arrSettingsUI.appendChild(arraySpiltV2El).appendText(" ");
arrSettingsUI.createEl('label', {text: i18nHelper.getMessage('124112')})
const arrayElementEnd = new TextComponent(arrSettingsUI);
arrayElementEnd.setPlaceholder(DEFAULT_SETTINGS.arrayElementEnd)
.setValue(arraySetting.arrayElementEnd)
.onChange(async (value) => {
arraySetting.arrayElementEnd = value;
await manager.updateArraySetting(arraySetting);
showArrayExample(arrShow, manager, arraySetting);
});
const arrayElementEndEl = arrayElementEnd.inputEl;
arrayElementEndEl.addClass('obsidian_douban_settings_input')
arrayElementEndEl.size = DEFAULT_SETTINGS_ARRAY_INPUT_SIZE;
arrSettingsUI.appendChild(arrayElementEndEl).appendText(" ");
arrSettingsUI.createEl('label', {text: i18nHelper.getMessage('124113')})
const arrayEnd = new TextComponent(arrSettingsUI);
arrayEnd.setPlaceholder(DEFAULT_SETTINGS.arrayEnd)
.setValue(arraySetting.arrayEnd)
.onChange(async (value) => {
arraySetting.arrayEnd = value;
await manager.updateArraySetting(arraySetting);
showArrayExample(arrShow, manager, arraySetting);
});
const arrayEndEl = arrayEnd.inputEl;
arrayEndEl.addClass('obsidian_douban_settings_input')
arrayEndEl.size = DEFAULT_SETTINGS_ARRAY_INPUT_SIZE;
arrSettingsUI.appendChild(arrayEndEl).appendText(" ");
showArrayExample(arrShow, manager, arraySetting);
}
function displayExtraListType(manager: SettingsManager, containerEl: HTMLElement) {
manager.settings.arraySettings.forEach(arraySetting => {
new Setting(containerEl)
arraySettingDisplayItem(containerEl, manager, arraySetting);
})
}
function showArrayExample(arrShow: HTMLDivElement, manager: SettingsManager, arraySetting:ArraySetting) {
arrShow.empty();
const document = new DocumentFragment();
document.createDiv('array-show-title')
.innerHTML = `propertyName:${manager.handleArray(['value1', 'value2', 'value3'], arraySetting)}`;
new Setting(arrShow)
.setName(i18nHelper.getMessage('120603'))
.setDesc(document);
}

@ -1,18 +1,14 @@
import {App, PluginSettingTab, SearchComponent, Setting} from "obsidian";
import {App, PluginSettingTab, Setting} from "obsidian";
import DoubanPlugin from "../../main";
import {i18nHelper} from "src/org/wanxp/lang/helper";
import {PersonNameMode, PersonNameModeRecords} from "../../constant/Constsant";
import SettingsManager from "./SettingsManager";
import {FolderSuggest} from "./model/FolderSuggest";
import { DEFAULT_SETTINGS } from "src/org/wanxp/constant/DefaultSettings";
import { constructOutUI } from "./OutputSettingsHelper";
import { constructTemplateUI } from "./TemplateSettingHelper";
import { constructBasicUI } from "./BasicSettingsHelper";
import { constructTemplateVariablesUI } from "./TemplateVariableSettingsHelper";
import {constructCustomPropertySettingsUI, constructCustomPropertyUI} from "./CustomPropertySettingsHelper";
import {log} from "../../utils/Logutil";
import {constructCustomPropertySettingsUI } from "./CustomPropertySettingsHelper";
import { constructAdvancedUI } from "./AdvancedSettingsHelper";
import {arraySettingDisplay, arraySettingDisplayUI} from "./ArrayDisplayTypeSettingsHelper";
/**
*
@ -36,9 +32,11 @@ export class DoubanSettingTab extends PluginSettingTab {
constructBasicUI(containerEl, this.settingsManager);
constructTemplateUI(containerEl, this.settingsManager);
constructOutUI(containerEl, this.settingsManager);
arraySettingDisplayUI(containerEl, this.settingsManager);
constructCustomPropertySettingsUI(containerEl, this.settingsManager);
constructTemplateVariablesUI(containerEl, this.settingsManager);
constructAdvancedUI(containerEl, this.settingsManager);
}
hide(): void {

@ -1,106 +1,22 @@
import {i18nHelper} from "../../lang/helper";
import {Setting, TextComponent} from "obsidian";
import {Setting} from "obsidian";
import {createFolderSelectionSetting} from "./TemplateSettingHelper";
import {DEFAULT_SETTINGS} from "../../constant/DefaultSettings";
import { PersonNameMode, PersonNameModeRecords} from "../../constant/Constsant";
import SettingsManager from "./SettingsManager";
export function constructOutUI(containerEl: HTMLElement, manager: SettingsManager) {
containerEl.createEl('h3', { text: i18nHelper.getMessage('1220') });
new Setting(containerEl);
let attachmentFileSetting = containerEl.createDiv({ cls: 'settings-item-attachment' });
const attachmentFileSetting = containerEl.createDiv({ cls: 'settings-item-attachment' });
constructAttachmentFileSettingsUI(attachmentFileSetting, manager);
new Setting(containerEl).then(createFolderSelectionSetting({name: '121501', desc: '121502', placeholder: '121503', key: 'dataFilePath', manager: manager}));
let outfolder = containerEl.createDiv({ cls: 'settings-item' });
constructOutputFileNameUI(outfolder, manager);
let arrSettings = containerEl.createDiv('array-settings');
let arrShow = containerEl.createDiv('array-show');
const descFrag:DocumentFragment = new DocumentFragment();
const desc: HTMLElement = descFrag.createDiv('array-setting-desc')
desc.innerHTML = i18nHelper.getMessage('120602');
new Setting(arrSettings)
.setName(i18nHelper.getMessage('120601'))
.setDesc(descFrag);
arrSettings;
arrSettings.createEl('label', { text: i18nHelper.getMessage('124109') })
const arrayStart = new TextComponent(arrSettings);
arrayStart.setPlaceholder(DEFAULT_SETTINGS.arrayStart)
.setValue(manager.settings.arrayStart)
.onChange(async (value) => {
manager.plugin.settings.arrayStart = value;
await manager.plugin.saveSettings();
showArrayExample(arrShow, manager);
});
let arrayStartEl = arrayStart.inputEl;
arrayStartEl.size = 3;
arrayStartEl.addClass('obsidian_douban_settings_input')
arrSettings.appendChild(arrayStartEl).appendText(" ");
arrSettings.createEl('label', { text: i18nHelper.getMessage('124110') })
const arrayElementStart = new TextComponent(arrSettings);
arrayElementStart.setPlaceholder(DEFAULT_SETTINGS.arrayElementStart)
.setValue(manager.settings.arrayElementStart)
.onChange(async (value) => {
manager.plugin.settings.arrayElementStart = value;
await manager.plugin.saveSettings();
showArrayExample(arrShow, manager);
});
let arrayElementStartEl = arrayElementStart.inputEl;
arrayElementStartEl.addClass('obsidian_douban_settings_input')
arrayElementStartEl.size = 3;
arrSettings.appendChild(arrayElementStartEl).appendText(" ");
arrSettings.createEl('label', { text: i18nHelper.getMessage('124111') })
const arraySpiltV2 = new TextComponent(arrSettings);
arraySpiltV2.setPlaceholder(DEFAULT_SETTINGS.arraySpiltV2)
.setValue(manager.settings.arraySpiltV2)
.onChange(async (value) => {
manager.plugin.settings.arraySpiltV2 = value;
await manager.plugin.saveSettings();
showArrayExample(arrShow, manager);
});
let arraySpiltV2El = arraySpiltV2.inputEl;
arraySpiltV2El.addClass('obsidian_douban_settings_input')
arraySpiltV2El.size = 3;
arrSettings.appendChild(arraySpiltV2El).appendText(" ");
arrSettings.createEl('label', { text: i18nHelper.getMessage('124112') })
const arrayElementEnd = new TextComponent(arrSettings);
arrayElementEnd.setPlaceholder(DEFAULT_SETTINGS.arrayElementEnd)
.setValue(manager.settings.arrayElementEnd)
.onChange(async (value) => {
manager.plugin.settings.arrayElementEnd = value;
await manager.plugin.saveSettings();
showArrayExample(arrShow, manager);
});
let arrayElementEndEl = arrayElementEnd.inputEl;
arrayElementEndEl.addClass('obsidian_douban_settings_input')
arrayElementEndEl.size = 3;
arrSettings.appendChild(arrayElementEndEl).appendText(" ");
arrSettings.createEl('label', { text: i18nHelper.getMessage('124113') })
const arrayEnd = new TextComponent(arrSettings);
arrayEnd.setPlaceholder(DEFAULT_SETTINGS.arrayEnd)
.setValue(manager.settings.arrayEnd)
.onChange(async (value) => {
manager.plugin.settings.arrayEnd = value;
await manager.plugin.saveSettings();
showArrayExample(arrShow, manager);
});
let arrayEndEl = arrayEnd.inputEl;
arrayEndEl.addClass('obsidian_douban_settings_input')
arrayEndEl.size = 3;
arrSettings.appendChild(arrayEndEl).appendText(" ");
showArrayExample(arrShow, manager);
const outFolder = containerEl.createDiv({ cls: 'settings-item' });
constructOutputFileNameUI(outFolder, manager);
new Setting(containerEl).setName(i18nHelper.getMessage('121201')).then((setting) => {
setting.addDropdown((dropdwon) => {
@ -128,6 +44,9 @@ export function constructOutUI(containerEl: HTMLElement, manager: SettingsManage
});
});
});
}
@ -190,14 +109,4 @@ export function constructAttachmentFileSettingsUI(containerEl: HTMLElement, mana
});
}
}
function showArrayExample(arrShow: HTMLDivElement, manager: SettingsManager) {
arrShow.empty();
let document = new DocumentFragment();
document.createDiv('array-show-title')
.innerHTML = `propertyName:${manager.handleArray(['value1', 'value2', 'value3'])}`;
new Setting(arrShow)
.setName(i18nHelper.getMessage('120603'))
.setDesc(document);
}

@ -11,6 +11,12 @@ import {DoubanPluginOnlineSettings} from "./model/DoubanPluginOnlineSettings";
import {DoubanPluginSubjectProperty} from "./model/DoubanPluginSubjectProperty";
import HandleContext from "../data/model/HandleContext";
import HtmlUtil from "../../utils/HtmlUtil";
import {
ARRAY_NAME_PREFIX_NAME,
ArraySetting,
ArraySettingFieldName,
DEFAULT_SETTINGS_ARRAY_NAME
} from "./model/ArraySetting";
export default class SettingsManager {
app: App;
@ -97,9 +103,69 @@ export default class SettingsManager {
return [];
}
handleArray(arr: string[]): string {
let result:string = StringUtil.handleArray(arr, this.settings);
handleArray(arr: string[], arraySetting:ArraySetting): string {
let result:string = StringUtil.handleArray(arr, arraySetting);
return HtmlUtil.strToHtml(result);
}
async updateArraySetting(arraySetting: ArraySetting) {
if (arraySetting.arrayName == DEFAULT_SETTINGS_ARRAY_NAME) {
this.settings.arrayStart = arraySetting.arrayStart;
this.settings.arrayElementStart = arraySetting.arrayElementStart;
this.settings.arraySpiltV2 = arraySetting.arraySpiltV2;
this.settings.arrayElementEnd = arraySetting.arrayElementEnd;
this.settings.arrayEnd = arraySetting.arrayEnd;
}else {
const index = this.settings.arraySettings.findIndex(as => as.arrayName == arraySetting.arrayName);
if (index == -1) {
this.settings.arraySettings.push(arraySetting);
} else {
this.settings.arraySettings[index] = arraySetting;
}
}
await this.plugin.saveSettings();
}
async removeArraySetting(arrayName: string) {
if (arrayName == DEFAULT_SETTINGS_ARRAY_NAME) {
return;
}else {
this.settings.arraySettings = this.settings.arraySettings.filter(arraySetting => arraySetting.arrayName !== arrayName);
}
await this.plugin.saveSettings();
}
getArraySetting(arrayName: string) {
if (!this.settings.arraySettings) {
this.settings.arraySettings = [];
}
if (arrayName == DEFAULT_SETTINGS_ARRAY_NAME) {
return this.getDefaultArraySetting(DEFAULT_SETTINGS_ARRAY_NAME, 0);
}else {
const arraySetting = this.settings.arraySettings.find(arraySetting => arraySetting.arrayName == arrayName);
if (arraySetting) {
return arraySetting;
}
}
return null;
}
getDefaultArraySetting(arrayName:string, index:number): ArraySetting {
return {arrayName: arrayName,
arrayStart: this.settings.arrayStart,
arrayElementStart: this.settings.arrayElementStart,
arraySpiltV2: this.settings.arraySpiltV2,
arrayElementEnd: this.settings.arrayElementEnd,
arrayEnd: this.settings.arrayEnd,
index: index
};
}
async addArraySetting() {
const index = this.settings.arraySettings.length + 1;
const arraySetting = this.getDefaultArraySetting(ARRAY_NAME_PREFIX_NAME + index, index);
this.settings.arraySettings.push(arraySetting);
await this.plugin.saveSettings();
return arraySetting;
}
}

@ -0,0 +1,22 @@
export interface ArraySetting {
index: number;
arrayName: string;
arrayStart: string;
arrayElementStart: string;
arraySpiltV2: string;
arrayElementEnd: string;
arrayEnd: string;
}
export enum ArraySettingFieldName {
index = "index",
arrayName = "arrayName",
arrayStart = "arrayStart",
arrayElementStart = "arrayElementStart",
arraySpiltV2 = "arraySpiltV2",
arrayElementEnd = "arrayElementEnd",
arrayEnd = "arrayEnd",
}
export const DEFAULT_SETTINGS_ARRAY_NAME = "default";
export const ARRAY_NAME_PREFIX_NAME = "ArrayType";

@ -1,5 +1,6 @@
import {CustomProperty} from "./CustomProperty";
import {SyncHandledData} from "./SyncHandledData";
import {ArraySetting} from "./ArraySetting";
export interface DoubanPluginSetting {
onlineSettingsFileName: string;
@ -28,7 +29,7 @@ export interface DoubanPluginSetting {
loginHeadersContent: string,
cacheImage: boolean,
cacheHighQuantityImage: boolean,
attachmentPath: string,
syncHandledDataArray: SyncHandledData[],
arraySettings: ArraySetting[]
}

@ -25,7 +25,7 @@ class DoubanPageBroadcastLoadHandler extends DoubanAbstractLoadHandler<DoubanPag
return null;
}
parseText(beforeContent: string, extract: DoubanNoteSubject, context: HandleContext): string {
parseVariable(beforeContent: string, variableMap:Map<string, any>, extract: DoubanNoteSubject, context: HandleContext): void {
return null;
}

@ -218,7 +218,13 @@ PS: This file could be delete if you want to.
'121601': `Note Name`,
'121602': `Nodes created from Obsidian-Douban will use this fileName as template(also support filePath),
If blank, they will be created by default name. support all basic template variables. example: {{type}}/{{title}}`,
'120603': `Array Display Example`,
'120603': `Display Preview`,
'120604': `ArrayTypeName:`,
'120605': `Template use example propertyName:{{actor`,
'120606': `Delete Array Display Type`,
'120607': `Add Array Display Type`,
'120608': `Display/Hidden Array Setting`,
'121603': `assets`,
@ -244,6 +250,7 @@ PS: This file could be delete if you want to.
'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 `,
'130107': `Can not find array setting for {1} in {0} , Please add it in array settings`,
'140201': `[OB-Douban]: searching '{0}'...`,

@ -186,7 +186,7 @@ export default {
'120508': `格式参考`,
'120601': `数组显示形式`,
'120602': `当模板中的变量存在数组, 则需要设定数组元素中的分割符号以及起始与结束符号, 比如演员列表,
\n()`,
\\n()[>>][+]`,
'124109': `首:`,
'124110': `元素首:`,
'124111': `分隔符:`,
@ -229,7 +229,13 @@ export default {
'121601': `笔记名称`,
'121602': `创建的笔记将会使用此名称作为模板, 支持所有'通用'的参数作为名称(如:{{type}}/{{title}}), 且支持路径, 比如: 'MyData/{{title}}'. 如果为空, 笔记将会使用默认名称. `,
'120603': `数组分割字符串显示效果`,
'120603': `输出效果预览`,
'120604': `数组类型名称:`,
'120605': `模板中使用举例: propertyName:{{actor`,
'120606': `删除列表类型字段显示方式`,
'120607': `新增列表类型字段显示方式:`,
'120608': `显示或隐藏列表输出设置`,
'121701': `选择模板文件`,
@ -246,7 +252,7 @@ export default {
'140102': `同步的对象和选择对象不一致,将不会同步, 现在选择同步的类型:{0},但是获取[{1}]的类型:{2}`,
'130105': `由于多次频繁请求数据,豆瓣当前暂时不可用. 请于12小时或24小时后再重试或重置你的网络(如重新拨号或更换网络) `,
'130106': `请尝试在Douban插件中登录后操作. 若还是无效果则尝试于12小时或24小时后再重试或重置你的网络(如重新拨号或更换网络) `,
'130107': `参数{0}中指定的数组输出类型{1}不存在,请前往配置进行设置`,
'140201': `[OB-Douban]: 开始搜索'{0}'...`,

@ -1,4 +1,5 @@
import {DoubanPluginSetting} from "../douban/setting/model/DoubanPluginSetting";
import {ArraySetting} from "../douban/setting/model/ArraySetting";
export default class StringUtil {
@ -85,13 +86,13 @@ export default class StringUtil {
return newText;
}
public static handleArray(arr: string[], settings: DoubanPluginSetting): string {
public static handleArray(arr: string[], arraySetting: ArraySetting): string {
let content :string = "";
const elementStart:string = StringUtil.escape(settings.arrayElementStart);
const elementEnd:string = StringUtil.escape(settings.arrayElementEnd);
const spilt:string = StringUtil.escape(settings.arraySpiltV2);
const start:string = StringUtil.escape(settings.arrayStart);
const end:string = StringUtil.escape(settings.arrayEnd);
const elementStart:string = StringUtil.escape(arraySetting.arrayElementStart);
const elementEnd:string = StringUtil.escape(arraySetting.arrayElementEnd);
const spilt:string = StringUtil.escape(arraySetting.arraySpiltV2);
const start:string = StringUtil.escape(arraySetting.arrayStart);
const end:string = StringUtil.escape(arraySetting.arrayEnd);
for (let i = 0; i < arr.length; i++) {
let el = arr[i];
if (!el) {

@ -1,8 +1,5 @@
import NumberUtil from "./NumberUtil";
import {log} from "./Logutil";
import {BasicConst, ESTIMATE_TIME_PER_WITH_REQUEST, ESTIMATE_TIME_PER_WITH_REQUEST_SLOW} from "../constant/Constsant";
import {moment} from "obsidian";
import {Moment} from "moment";
import {i18nHelper} from "../lang/helper";
export default class TimeUtil {

@ -0,0 +1,214 @@
import SettingsManager from "../douban/setting/SettingsManager";
import {ArraySetting, DEFAULT_SETTINGS_ARRAY_NAME} from "../douban/setting/model/ArraySetting";
import StringUtil from "./StringUtil";
import YamlUtil from "./YamlUtil";
import {log} from "./Logutil";
import {i18nHelper} from "../lang/helper";
import {DataValueType} from "../constant/Constsant";
import {DataField} from "./model/DataField";
import {FieldVariable} from "./model/FieldVariable";
export class VariableUtil {
/**
*
* @param obj
* @param content
* @param settingManager
*/
static replace(obj: any, content: string, settingManager:SettingsManager): string {
if (!content || !obj) {
return content;
}
const allVariables = this.getAllVariables(content, settingManager);
if (!allVariables || allVariables.length == 0) {
return content;
}
if (obj instanceof Map) {
content = this.replaceMap(obj, allVariables, content, settingManager);
}else {
content = this.replaceObject(obj, allVariables, content, settingManager);
}
return content;
}
/**
* <h3>type</h3>
* <li>Number</li>
* <li>String</li>
* <li>Array</li>
*
* <h3>name</h3>
* <li> aliases</li>
* @param variable
* @param value
* @param content
* @param settingManager
*/
static replaceVariable(variable: FieldVariable, value: any, content: string, settingManager:SettingsManager): string {
if (!content) {
return content;
}
//根据value的类型替换对应的变量
if (value instanceof Array) {
content = this.replaceArray(variable, value, content, settingManager);
} else if(value instanceof DataField) {
content = this.replaceDataField(variable, value, content, settingManager);
} else {
content = this.replaceString(variable, value, content, settingManager);
}
return content;
}
static replaceArray(variable: FieldVariable, value: any[], content: string, settingManager:SettingsManager): string {
if (!content) {
return content;
}
const variableStr = variable.variable;
const outTypeName = variable.outTypeName;
if (!value) {
return content.replaceAll(variableStr, "");
}
const arraySettings = this.getArraySetting(outTypeName, settingManager);
if (!arraySettings) {
log.warn(i18nHelper.getMessage(`130107`, variable.variable, outTypeName));
return content;
}
const strValues:string[] = value.map((v) => {
if (typeof v === 'string') {
return v;
} else {
return v?v.toString() : null;
}
})
.filter(v => v)
.map(v => YamlUtil.handleText(v))
;
const arrayValue = StringUtil.handleArray(strValues, arraySettings);
content = content.replaceAll(variableStr, arrayValue);
return content;
}
static keyToVariable(key: string): string {
return `{{${key}}}`;
}
static replaceString(variable: FieldVariable, value: any, content: string, settingManager:SettingsManager): string {
if (!content) {
return content;
}
let strValue = value? value.toString() : "";
strValue = YamlUtil.handleText(strValue);
return content.replaceAll(variable.variable, strValue);
}
/**
* key中提取 arrayName, settings中获取对应的ArraySetting
* @param key
* @private
*/
private static getAllVariables(content: string, settingManager:SettingsManager): FieldVariable[] {
const reg =/\{\{[a-zA-Z-0-9_.]+([(a-zA-Z-0-9)]+)?}}/g
const result = content.match(reg);
if (!result) {
return [];
}
return result.map((v) => {
const reg2 = new RegExp(`[a-zA-Z-0-9_.]+`, 'g');
const result2 = v.match(reg2);
if (!result2) {
return null;
}
if (result2.length == 1) {
return new FieldVariable(result2[0], v, null);
}
return new FieldVariable(result2[0], v, result2[1]);
}).filter(v => v);
}
/**
* key中提取 arrayName, settings中获取对应的ArraySetting
* @param outTypeName
* @private
*/
private static getArraySetting(outTypeName: string, settingManager:SettingsManager): ArraySetting {
if (!outTypeName) {
return settingManager.getArraySetting(DEFAULT_SETTINGS_ARRAY_NAME);
} else {
return settingManager.getArraySetting(outTypeName);
}
}
private static replaceObject(obj: any, allVariables:FieldVariable[], content: string, settingManager: SettingsManager) {
allVariables.forEach(variable => {
const key = variable.key;
const value = obj.get(key);
if (obj.hasOwnProperty(key)) {
const value = obj[key];
content = this.replaceVariable(variable,value, content, settingManager);
}
content = this.replaceVariable(variable, value, content, settingManager);
});
return content;
}
private static replaceMap(obj: Map<string, any>, allVariables:FieldVariable[], content: string, settingManager: SettingsManager) {
allVariables.forEach(variable => {
const value = obj.get(variable.key);
content = this.replaceVariable(variable, value,content, settingManager);
});
return content;
}
static getType(value: any):DataValueType {
if (typeof value === 'number') {
return DataValueType.number;
} else if (typeof value === 'string') {
if (value.startsWith('http://') || value.startsWith('https://')) {
return DataValueType.url;
}else if (/^(\/|\.\/|\.\.\/|~\/|.*\.[a-zA-Z0-9]+$)/.test(value)) {
return DataValueType.path;
}
return DataValueType.string;
} else if (value instanceof Date) {
return DataValueType.date;
} else if (value instanceof Array) {
return DataValueType.array;
} else {
return DataValueType.string;
}
}
private static replaceDataField(variable: FieldVariable, value: DataField, content: string, settingManager: SettingsManager) {
if (!content) {
return content;
}
const variableStr = variable.variable;
if (!value) {
return content.replaceAll(variableStr, "");
}
switch (value.type) {
case DataValueType.string:
content = this.replaceString(variable, value.value, content, settingManager);
break;
case DataValueType.number:
content = content.replaceAll(variableStr, value.value.toString());
break;
case DataValueType.date:
content = content.replaceAll(variableStr, value.value);
break;
case DataValueType.array:
content = this.replaceArray(variable, value.value, content, settingManager);
break;
default:
content = content.replaceAll(variableStr, value.value);
break;
}
return content;
}
}

@ -15,10 +15,14 @@ export default class YamlUtil {
}
public static handleText(text: string) {
return YamlUtil.hasSpecialChar(text) ? YamlUtil.handleSpecialChar(text.replaceAll('"', '\\"'))
return YamlUtil.hasSpecialChar(text)
? YamlUtil.handleSpecialChar(text.replaceAll('"', '\\"'))
.replaceAll(/\s+/g,' ')
.replaceAll('\n', '。')
.replaceAll('。。', '。') : text;
.replaceAll('。。', '。')
.replace(/^" /, '"') // Remove leading "
.replace(/ "$/, '"') // Remove trailing "
: text;
}
}

@ -0,0 +1,32 @@
import {DataValueType} from "../../constant/Constsant";
export class DataField {
private _name: string;
private _type: DataValueType;
private _origin: any;
private _value: any;
constructor(name: string, type: DataValueType, origin: any, value: any) {
this._name = name;
this._type = type;
this._origin = origin;
this._value = value;
}
public get name():string{
return this._name;
}
public get type():DataValueType{
return this._type;
}
public get origin():any{
return this._origin;
}
public get value():any{
return this._value;
}
}

@ -0,0 +1,25 @@
export class FieldVariable {
private _key:string;
private _variable:string;
private _outTypeName:string;
constructor(key:string, variable:string, outTypeName:string) {
this._key = key;
this._variable = variable;
this._outTypeName = outTypeName;
}
public get key():string{
return this._key;
}
public get variable():string{
return this._variable;
}
public get outTypeName():string{
return this._outTypeName;
}
}