add new setting for {{scoreStar}} and {{myRatingStar}}

This commit is contained in:
HughWan 2023-12-29 18:25:01 +08:00
parent 232fde720c
commit 446f405a79
17 changed files with 384 additions and 59 deletions

@ -40,6 +40,8 @@
{{myComment}} {{myComment}}
```` ````
5. 设置模板为上面的模板 5. 设置模板为上面的模板
6. 增加数组输出形式
进入插件设置界面,找到[数组输出]
## 模板参考 ## 模板参考
### 书籍 ### 书籍
@ -53,6 +55,7 @@ series: {{series}}
type: {{type}} type: {{type}}
author: {{author}} author: {{author}}
score: {{score}} score: {{score}}
scoreStar: {{scoreStar}}
myRating: {{myRating}} myRating: {{myRating}}
datePublished: {{datePublished}} datePublished: {{datePublished}}
translator: {{translator}} translator: {{translator}}

@ -2,6 +2,7 @@ import {i18nHelper} from "../lang/helper";
import DoubanSearchResultSubject from "../douban/data/model/DoubanSearchResultSubject"; import DoubanSearchResultSubject from "../douban/data/model/DoubanSearchResultSubject";
import StringUtil from "../utils/StringUtil"; import StringUtil from "../utils/StringUtil";
import {DoubanPluginOnlineSettings} from "../douban/setting/model/DoubanPluginOnlineSettings"; import {DoubanPluginOnlineSettings} from "../douban/setting/model/DoubanPluginOnlineSettings";
import {DataField} from "../utils/model/DataField";
/** /**
* *
@ -414,3 +415,28 @@ export enum DataTargetType {
content, content,
} }
export const EXAMPLE_RATE = 8.5;
export const EXAMPLE_RATE_MAX = 10;
export const EXAMPLE_SUBJECT_MAP: Map<string, DataField> = new Map([
["id", new DataField("id", DataValueType.string, DataValueType.string, "2253379")],
["title", new DataField("title", DataValueType.string, DataValueType.string, "简爱")],
["type", new DataField("type", DataValueType.string, DataValueType.string, "book")],
["score", new DataField("score", DataValueType.number, DataValueType.number, EXAMPLE_RATE)],
["image", new DataField("image", DataValueType.url, DataValueType.url, "https://img9.doubanio.com/view/subject/s/public/s1070959.jpg")],
["imageUrl", new DataField("imageUrl", DataValueType.url, DataValueType.url, "https://img9.doubanio.com/view/subject/s/public/s1070959.jpg")],
["url", new DataField("url", DataValueType.url, DataValueType.url, "https://book.douban.com/subject/2253379/")],
["desc", new DataField("desc", DataValueType.string, DataValueType.string, "简爱是一部关于爱、关于成长、关于追求自由与尊严的伟大小说。")],
["publisher", new DataField("publisher", DataValueType.string, DataValueType.string, "人民文学出版社")],
["datePublished", new DataField("datePublished", DataValueType.date, DataValueType.date, "2020-1-1")],
["genre", new DataField("genre", DataValueType.array, DataValueType.array, "小说")],
["tags", new DataField("tags", DataValueType.array, DataValueType.array, "小说")],
["rate", new DataField("rate", DataValueType.number, DataValueType.number, 9.0)],
["state", new DataField("state", DataValueType.string, DataValueType.string, "wish")],
["collectionDate", new DataField("collectionDate", DataValueType.date, DataValueType.date, "2020-1-1")],
["comment", new DataField("comment", DataValueType.string, DataValueType.string, "简爱是一部关于爱、关于成长、关于追求自由与尊严的伟大小说。")],
["author", new DataField("author", DataValueType.person, DataValueType.person, "夏洛蒂·勃朗特")],
["translator", new DataField("translator", DataValueType.person, DataValueType.person, "李继宏")],
]);
export const MAX_STAR_NUMBER = 100;

@ -47,5 +47,14 @@ export const DEFAULT_SETTINGS: DoubanPluginSetting = {
cacheImage: true, cacheImage: true,
cacheHighQuantityImage: true, cacheHighQuantityImage: true,
attachmentPath: 'assets', attachmentPath: 'assets',
syncHandledDataArray: [] syncHandledDataArray: [],
scoreSetting: {
starFull: '⭐',
starEmpty: '☆',
displayStarEmpty: true,
maxStar: 5,
} }
}

@ -6,6 +6,7 @@ doubanId: {{id}}
title: {{title}} title: {{title}}
type: {{type}} type: {{type}}
score: {{score}} score: {{score}}
scoreStar: {{scoreStar}}
originalTitle: {{originalTitle}} originalTitle: {{originalTitle}}
genre: {{genre}} genre: {{genre}}
datePublished: {{datePublished}} datePublished: {{datePublished}}
@ -35,6 +36,7 @@ series: {{series}}
type: {{type}} type: {{type}}
author: {{author}} author: {{author}}
score: {{score}} score: {{score}}
scoreStar: {{scoreStar}}
datePublished: {{datePublished}} datePublished: {{datePublished}}
translator: {{translator}} translator: {{translator}}
publisher: {{publisher}} publisher: {{publisher}}
@ -60,6 +62,7 @@ title: {{title}}
type: {{type}} type: {{type}}
actor: {{actor}} actor: {{actor}}
score: {{score}} score: {{score}}
scoreStar: {{scoreStar}}
genre: {{genre}} genre: {{genre}}
medium: {{medium}} medium: {{medium}}
albumType: {{albumType}} albumType: {{albumType}}
@ -98,6 +101,7 @@ title: {{title}}
aliases: {{aliases}} aliases: {{aliases}}
type: {{type}} type: {{type}}
score: {{score}} score: {{score}}
scoreStar: {{scoreStar}}
dateTimePublished: {{datePublished}} dateTimePublished: {{datePublished}}
publisher: {{publisher}} publisher: {{publisher}}
genre: {{genre}} genre: {{genre}}
@ -116,6 +120,7 @@ doubanId: {{id}}
title: {{title}} title: {{title}}
type: {{type}} type: {{type}}
score: {{score}} score: {{score}}
scoreStar: {{scoreStar}}
originalTitle: {{originalTitle}} originalTitle: {{originalTitle}}
genre: {{genre}} genre: {{genre}}
datePublished: {{datePublished}} datePublished: {{datePublished}}
@ -145,7 +150,9 @@ doubanId: {{id}}
title: {{title}} title: {{title}}
type: {{type}} type: {{type}}
score: {{score}} score: {{score}}
scoreStar: {{scoreStar}}
myRating: {{myRating}} myRating: {{myRating}}
myRatingStar: {{myRatingStar}}
originalTitle: {{originalTitle}} originalTitle: {{originalTitle}}
genre: {{genre}} genre: {{genre}}
datePublished: {{datePublished}} datePublished: {{datePublished}}
@ -180,7 +187,9 @@ series: {{series}}
type: {{type}} type: {{type}}
author: {{author}} author: {{author}}
score: {{score}} score: {{score}}
scoreStar: {{scoreStar}}
myRating: {{myRating}} myRating: {{myRating}}
myRatingStar: {{myRatingStar}}
datePublished: {{datePublished}} datePublished: {{datePublished}}
translator: {{translator}} translator: {{translator}}
publisher: {{publisher}} publisher: {{publisher}}
@ -211,7 +220,9 @@ title: {{title}}
type: {{type}} type: {{type}}
actor: {{actor}} actor: {{actor}}
score: {{score}} score: {{score}}
scoreStar: {{scoreStar}}
myRating: {{myRating}} myRating: {{myRating}}
myRatingStar: {{myRatingStar}}
genre: {{genre}} genre: {{genre}}
medium: {{medium}} medium: {{medium}}
albumType: {{albumType}} albumType: {{albumType}}
@ -256,7 +267,9 @@ title: {{title}}
aliases: {{aliases}} aliases: {{aliases}}
type: {{type}} type: {{type}}
score: {{score}} score: {{score}}
scoreStar: {{scoreStar}}
myRating: {{myRating}} myRating: {{myRating}}
myRatingStar: {{myRatingStar}}
dateTimePublished: {{datePublished}} dateTimePublished: {{datePublished}}
publisher: {{publisher}} publisher: {{publisher}}
genre: {{genre}} genre: {{genre}}
@ -280,7 +293,9 @@ doubanId: {{id}}
title: {{title}} title: {{title}}
type: {{type}} type: {{type}}
score: {{score}} score: {{score}}
scoreStar: {{scoreStar}}
myRating: {{myRating}} myRating: {{myRating}}
myRatingStar: {{myRatingStar}}
originalTitle: {{originalTitle}} originalTitle: {{originalTitle}}
genre: {{genre}} genre: {{genre}}
datePublished: {{datePublished}} datePublished: {{datePublished}}

@ -32,6 +32,7 @@ import HttpUtil from "../../../utils/HttpUtil";
import HtmlUtil from "../../../utils/HtmlUtil"; import HtmlUtil from "../../../utils/HtmlUtil";
import {VariableUtil} from "../../../utils/VariableUtil"; import {VariableUtil} from "../../../utils/VariableUtil";
import {DataField} from "../../../utils/model/DataField"; import {DataField} from "../../../utils/model/DataField";
import NumberUtil from "../../../utils/NumberUtil";
export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject> implements DoubanSubjectLoadHandler<T> { export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject> implements DoubanSubjectLoadHandler<T> {
@ -258,6 +259,14 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
continue; continue;
} }
const type:DataValueType = VariableUtil.getType(value); const type:DataValueType = VariableUtil.getType(value);
if (key == 'score') {
variableMap.set(DoubanParameterName.SCORE_STAR, new DataField(
DoubanParameterName.SCORE_STAR,
DataValueType.string,
value,
NumberUtil.getRateMaxFiveStar(value, 10)
));
}
variableMap.set(key, new DataField(key, type, value, value)); variableMap.set(key, new DataField(key, type, value, value));
} }
variableMap.set(DoubanParameterName.IMAGE_URL, new DataField( variableMap.set(DoubanParameterName.IMAGE_URL, new DataField(
@ -297,10 +306,10 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
currentDate, currentDate,
moment(currentDate).format(context.settings.timeFormat) moment(currentDate).format(context.settings.timeFormat)
)); ));
this.parseUserInfo(template, variableMap, extract, context, textMode); this.parseUserInfo(template, variableMap, extract, context, textMode);
this.parseVariable(template, variableMap, extract, context, textMode); this.parseVariable(template, variableMap, extract, context, textMode);
this.handleCustomVariable(template, variableMap, context); return VariableUtil.replaceSubject(variableMap, template, this.getSupportType(), this.doubanPlugin.settingsManager);
return VariableUtil.replace(variableMap, template, this.doubanPlugin.settingsManager);
} }
@ -330,9 +339,15 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
variableMap.set(DoubanUserParameterName.MY_STATE, new DataField( variableMap.set(DoubanUserParameterName.MY_STATE, new DataField(
DoubanUserParameterName.MY_STATE, DoubanUserParameterName.MY_STATE,
DataValueType.string, DataValueType.string,
userState, userState.state,
this.getUserStateName(userState.state) this.getUserStateName(userState.state)
)); ));
variableMap.set(DoubanUserParameterName.MY_RATING_STAR, new DataField(
DoubanUserParameterName.MY_STATE,
DataValueType.string,
userState.rate,
NumberUtil.getRateStarMaxFiveMaxFiveStar(userState.rate)
));
variableMap.set(DoubanUserParameterName.MY_COLLECTION_DATE, new DataField( variableMap.set(DoubanUserParameterName.MY_COLLECTION_DATE, new DataField(
DoubanUserParameterName.MY_COLLECTION_DATE, DoubanUserParameterName.MY_COLLECTION_DATE,
@ -342,31 +357,7 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
)); ));
} }
/**
*
* @param template
* @param context
* @private
*/
private handleCustomVariable(template: string, variableMap:Map<string, DataField>, context: HandleContext): void {
const customProperties = context.settings.customProperties;
if (!customProperties) {
return ;
}
const customPropertiesMap= new Map();
customProperties.filter(customProperty => customProperty.name &&
customProperty.field
&& (customProperty.field.toLowerCase() == SupportType.ALL ||
customProperty.field.toLowerCase() == this.getSupportType())).forEach(customProperty => {
customPropertiesMap.set(customProperty.name, customProperty.value);
});
customPropertiesMap.forEach((value, key) => {
variableMap.set(key,
new DataField(
key, DataValueType.string, value,
VariableUtil.replace(variableMap, value, this.doubanPlugin.settingsManager)));
})
}
private getTemplateKey():TemplateKey { private getTemplateKey():TemplateKey {
let templateKey: TemplateKey; let templateKey: TemplateKey;

@ -45,6 +45,7 @@ export const DoubanParameterName = {
TITLE: 'title', TITLE: 'title',
TYPE: 'type', TYPE: 'type',
SCORE: 'score', SCORE: 'score',
SCORE_STAR: 'scoreStar',
IMAGE: 'image', IMAGE: 'image',
IMAGE_URL: 'imageData.url', IMAGE_URL: 'imageData.url',
URL: 'url', URL: 'url',

@ -19,6 +19,7 @@ export const DoubanUserParameter = {
export const DoubanUserParameterName = { export const DoubanUserParameterName = {
MY_TAGS: 'myTags', MY_TAGS: 'myTags',
MY_RATING: 'myRating', MY_RATING: 'myRating',
MY_RATING_STAR: 'myRatingStar',
MY_STATE: 'myState', MY_STATE: 'myState',
MY_COMMENT: 'myComment', MY_COMMENT: 'myComment',
MY_COLLECTION_DATE: 'myCollectionDate', MY_COLLECTION_DATE: 'myCollectionDate',

@ -1,11 +1,114 @@
import {i18nHelper} from "../../lang/helper"; import {i18nHelper} from "../../lang/helper";
import {Setting} from "obsidian"; import {Setting, TextComponent, ToggleComponent, ValueComponent} from "obsidian";
import {createFolderSelectionSetting} from "./TemplateSettingHelper"; import {createFolderSelectionSetting} from "./TemplateSettingHelper";
import {DEFAULT_SETTINGS} from "../../constant/DefaultSettings"; import {DEFAULT_SETTINGS} from "../../constant/DefaultSettings";
import { PersonNameMode, PersonNameModeRecords} from "../../constant/Constsant"; import {
DEFAULT_SETTINGS_ARRAY_INPUT_SIZE, EXAMPLE_RATE, EXAMPLE_RATE_MAX,
EXAMPLE_SUBJECT_MAP, MAX_STAR_NUMBER,
PersonNameMode,
PersonNameModeRecords,
SupportType
} from "../../constant/Constsant";
import SettingsManager from "./SettingsManager"; import SettingsManager from "./SettingsManager";
import NumberUtil from "../../utils/NumberUtil";
import {VariableUtil} from "../../utils/VariableUtil";
import {FileUtil} from "../../utils/FileUtil";
import {ScoreSetting} from "./model/ScoreSetting";
function showStarExample(containerEl: HTMLElement, manager: SettingsManager) {
containerEl.empty();
const document = new DocumentFragment();
document.createDiv('score-show-title')
.innerHTML = `score: ${NumberUtil.getRateStar(EXAMPLE_RATE, EXAMPLE_RATE_MAX, {scoreSetting: manager.plugin.settings.scoreSetting})}`;
new Setting(containerEl)
.setName(i18nHelper.getMessage('120603'))
.setDesc(document);
}
export function showFileExample(containerEl: HTMLElement, manager: SettingsManager) {
containerEl.empty();
const document = new DocumentFragment();
document.createDiv('file-path-example')
.innerHTML = `文件路径预览<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,
manager)}`;
new Setting(containerEl)
.setName(i18nHelper.getMessage('120603'))
.setDesc(document);
}
function scoreSettingDisplay(containerEl: HTMLElement, manager: SettingsManager) {
new Setting(containerEl)
.setName(i18nHelper.getMessage('1243'))
.setDesc(i18nHelper.getMessage('124310', EXAMPLE_RATE, EXAMPLE_RATE_MAX));
const scoreSettingsUI = containerEl.createDiv('score-settings');
const scoreShowUI = containerEl.createDiv('score-show');
const scoreSetting:ScoreSetting = manager.getSetting('scoreSetting');
scoreSettingsUI.createEl('span', {text: i18nHelper.getMessage('124120')})
const starFullUI = new TextComponent(scoreSettingsUI);
starFullUI.setPlaceholder(DEFAULT_SETTINGS.scoreSetting.starFull)
.setValue(scoreSetting.starFull)
.onChange(async (value) => {
scoreSetting.starFull = value;
await manager.plugin.saveSettings();
showStarExample(scoreShowUI, manager);
});
const starFullEl = starFullUI.inputEl;
starFullEl.size = DEFAULT_SETTINGS_ARRAY_INPUT_SIZE;
starFullEl.addClass('obsidian_douban_settings_input')
scoreSettingsUI.appendChild(starFullEl).appendText(" ");
scoreSettingsUI.createEl('span', {text: i18nHelper.getMessage('124121')})
const starEmptyUI = new TextComponent(scoreSettingsUI);
starEmptyUI.setPlaceholder(DEFAULT_SETTINGS.scoreSetting.starEmpty)
.setValue(scoreSetting.starEmpty)
.onChange(async (value) => {
scoreSetting.starEmpty = value;
await manager.plugin.saveSettings();
showStarExample(scoreShowUI, manager);
});
const starEmptyEl = starEmptyUI.inputEl;
starEmptyEl.addClass('obsidian_douban_settings_input')
starEmptyEl.size = DEFAULT_SETTINGS_ARRAY_INPUT_SIZE;
scoreSettingsUI.appendChild(starEmptyEl).appendText(" ");
scoreSettingsUI.createEl('span', {text: i18nHelper.getMessage('124311')})
const maxStarUI = new TextComponent(scoreSettingsUI);
maxStarUI.setPlaceholder(i18nHelper.getMessage('124312') + DEFAULT_SETTINGS.scoreSetting.maxStar)
.setValue(scoreSetting.maxStar + "")
.onChange(async (value) => {
if (!NumberUtil.isInt(value) && NumberUtil.value(value) > MAX_STAR_NUMBER && NumberUtil.value(value) < 1) {
return;
}
scoreSetting.maxStar = NumberUtil.value(value);
await manager.plugin.saveSettings();
showStarExample(scoreShowUI, manager);
});
const maxStarEl = maxStarUI.inputEl;
maxStarEl.addClass('obsidian_douban_settings_input')
maxStarEl.size = DEFAULT_SETTINGS_ARRAY_INPUT_SIZE;
scoreSettingsUI.appendChild(maxStarEl).appendText(" ");
scoreSettingsUI.createEl('span', {text: i18nHelper.getMessage('124122')})
const displayEmptyStarUI = new ToggleComponent(scoreSettingsUI);
displayEmptyStarUI.setValue(scoreSetting.displayStarEmpty)
.onChange(async (value) => {
scoreSetting.displayStarEmpty = value;
await manager.plugin.saveSettings();
showStarExample(scoreShowUI, manager);
});
// displayEmptyStarUI.('obsidian_douban_settings_input')
const displayEmptyStarEl = displayEmptyStarUI.toggleEl;
displayEmptyStarEl.addClass('obsidian_douban_settings_input')
scoreSettingsUI.appendChild(displayEmptyStarEl).appendText(" ");
showStarExample(scoreShowUI, manager);
}
export function constructOutUI(containerEl: HTMLElement, manager: SettingsManager) { export function constructOutUI(containerEl: HTMLElement, manager: SettingsManager) {
containerEl.createEl('h3', { text: i18nHelper.getMessage('1220') }); containerEl.createEl('h3', { text: i18nHelper.getMessage('1220') });
@ -13,10 +116,12 @@ export function constructOutUI(containerEl: HTMLElement, manager: SettingsManage
const attachmentFileSetting = containerEl.createDiv({ cls: 'settings-item-attachment' }); const attachmentFileSetting = containerEl.createDiv({ cls: 'settings-item-attachment' });
constructAttachmentFileSettingsUI(attachmentFileSetting, manager); constructAttachmentFileSettingsUI(attachmentFileSetting, manager);
new Setting(containerEl).then(createFolderSelectionSetting({name: '121501', desc: '121502', placeholder: '121503', key: 'dataFilePath', manager: manager})); const folder = new Setting(containerEl);
const outFolder = containerEl.createDiv({ cls: 'settings-item' }); const outFolder = containerEl.createDiv({ cls: 'settings-item' });
const filePathDisplayExample = containerEl.createDiv('filePath-display-example');
folder.then(createFolderSelectionSetting({name: '121501', desc: '121502', placeholder: '121503', key: 'dataFilePath', manager: manager}, filePathDisplayExample));
constructOutputFileNameUI(outFolder, filePathDisplayExample, manager);
constructOutputFileNameUI(outFolder, manager);
new Setting(containerEl).setName(i18nHelper.getMessage('121201')).then((setting) => { new Setting(containerEl).setName(i18nHelper.getMessage('121201')).then((setting) => {
setting.addDropdown((dropdwon) => { setting.addDropdown((dropdwon) => {
@ -44,16 +149,14 @@ export function constructOutUI(containerEl: HTMLElement, manager: SettingsManage
}); });
}); });
}); });
scoreSettingDisplay(containerEl, manager);
} }
export function constructOutputFileNameUI(containerEl: HTMLElement, manager: SettingsManager) { export function constructOutputFileNameUI(containerEl: HTMLElement, filePathDisplayExample:HTMLDivElement , manager: SettingsManager) {
containerEl.empty(); containerEl.empty();
const dataFilePathSetting = new Setting(containerEl) const dataFilePathSetting = new Setting(containerEl);
.setName(i18nHelper.getMessage('121601')) dataFilePathSetting.setName(i18nHelper.getMessage('121601'))
.setDesc(i18nHelper.getMessage('121602')) .setDesc(i18nHelper.getMessage('121602'))
.addText((textField) => { .addText((textField) => {
textField.setPlaceholder(DEFAULT_SETTINGS.dataFileNamePath) textField.setPlaceholder(DEFAULT_SETTINGS.dataFileNamePath)
@ -61,6 +164,7 @@ export function constructOutputFileNameUI(containerEl: HTMLElement, manager: Set
.onChange(async (value) => { .onChange(async (value) => {
manager.plugin.settings.dataFileNamePath = value; manager.plugin.settings.dataFileNamePath = value;
await manager.plugin.saveSettings(); await manager.plugin.saveSettings();
showFileExample(filePathDisplayExample, manager);
}); });
}); });
dataFilePathSetting.addExtraButton((button) => { dataFilePathSetting.addExtraButton((button) => {
@ -70,9 +174,10 @@ export function constructOutputFileNameUI(containerEl: HTMLElement, manager: Set
.onClick(async () => { .onClick(async () => {
manager.plugin.settings.dataFileNamePath = DEFAULT_SETTINGS.dataFileNamePath; manager.plugin.settings.dataFileNamePath = DEFAULT_SETTINGS.dataFileNamePath;
await manager.plugin.saveSettings(); await manager.plugin.saveSettings();
constructOutputFileNameUI(containerEl, manager) constructOutputFileNameUI(containerEl, filePathDisplayExample, manager)
}); });
}) })
showFileExample(filePathDisplayExample, manager);
} }

@ -168,4 +168,28 @@ export default class SettingsManager {
await this.plugin.saveSettings(); await this.plugin.saveSettings();
return arraySetting; return arraySetting;
} }
getSettingStr(field: keyof DoubanPluginSetting): string {
const setting = this.getSetting(field);
if (setting) {
if (typeof setting == 'string') {
return setting;
}else {
return setting.toString();
}
}
return '';
}
getSettingBoolean(field: keyof DoubanPluginSetting): boolean {
const setting = this.getSetting(field);
if (setting) {
if (typeof setting == 'boolean') {
return setting;
}else {
return !!setting;
}
}
return false;
}
} }

@ -6,6 +6,7 @@ import { log } from "src/org/wanxp/utils/Logutil";
import {getDefaultTemplateContent} from "../../constant/DefaultTemplateContent"; import {getDefaultTemplateContent} from "../../constant/DefaultTemplateContent";
import {FolderSuggest} from "./model/FolderSuggest"; import {FolderSuggest} from "./model/FolderSuggest";
import SettingsManager from "./SettingsManager"; import SettingsManager from "./SettingsManager";
import {showFileExample} from "./OutputSettingsHelper";
export function constructTemplateUI(containerEl: HTMLElement, manager: SettingsManager) { export function constructTemplateUI(containerEl: HTMLElement, manager: SettingsManager) {
@ -67,7 +68,7 @@ export function createFileSelectionSetting({name, desc, placeholder, key, manage
export function createFolderSelectionSetting({ export function createFolderSelectionSetting({
name, desc, placeholder, key, manager, name, desc, placeholder, key, manager,
}: CreateTemplateSelectParams) { }: CreateTemplateSelectParams, filePathDisplayExample?:HTMLDivElement) {
return (setting: Setting) => { return (setting: Setting) => {
// @ts-ignore // @ts-ignore
setting.setName( i18nHelper.getMessage(name)); setting.setName( i18nHelper.getMessage(name));
@ -86,7 +87,9 @@ export function createFolderSelectionSetting({
.setPlaceholder(i18nHelper.getMessage(placeholder)) .setPlaceholder(i18nHelper.getMessage(placeholder))
.onChange(async (value: string) => { .onChange(async (value: string) => {
manager.updateSetting(key, value); manager.updateSetting(key, value);
if (filePathDisplayExample) {
showFileExample(filePathDisplayExample, manager);
}
}); });
}); });
}; };

@ -61,6 +61,16 @@ ${i18nHelper.getMessage('122004')}
<td>${i18nHelper.getMessage('310504')}</td> <td>${i18nHelper.getMessage('310504')}</td>
<td>${i18nHelper.getMessage('310604')}</td> <td>${i18nHelper.getMessage('310604')}</td>
<td>${i18nHelper.getMessage('310704')}</td> <td>${i18nHelper.getMessage('310704')}</td>
</tr>
<tr>
<td>scoreStar</td>
<td>${i18nHelper.getMessage('410200')}</td>
<td>${i18nHelper.getMessage('410200')}</td>
<td>${i18nHelper.getMessage('410200')}</td>
<td>${i18nHelper.getMessage('410200')}</td>
<td>${i18nHelper.getMessage('410200')}</td>
<td>${i18nHelper.getMessage('410200')}</td>
<td>${i18nHelper.getMessage('410200')}</td>
</tr> </tr>
<tr> <tr>
<td>image</td> <td>image</td>
@ -305,6 +315,7 @@ ${i18nHelper.getMessage('160225')}
<br> <br>
<strong>myTags</strong> ${i18nHelper.getMessage('160226')}<br> <strong>myTags</strong> ${i18nHelper.getMessage('160226')}<br>
<strong>myRating</strong> ${i18nHelper.getMessage('160227')}<br> <strong>myRating</strong> ${i18nHelper.getMessage('160227')}<br>
<strong>myRatingStar</strong> ${i18nHelper.getMessage('160231')}<br>
<strong>myState</strong> ${i18nHelper.getMessage('160228')}<br> <strong>myState</strong> ${i18nHelper.getMessage('160228')}<br>
<strong>myComment</strong> ${i18nHelper.getMessage('160229')}<br> <strong>myComment</strong> ${i18nHelper.getMessage('160229')}<br>
<strong>myCollectionDate</strong> ${i18nHelper.getMessage('160230')}<br> <strong>myCollectionDate</strong> ${i18nHelper.getMessage('160230')}<br>

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

@ -0,0 +1,6 @@
export interface ScoreSetting {
starEmpty: string,
starFull: string,
displayStarEmpty: boolean
maxStar: number
}

@ -125,6 +125,15 @@ PS: This file could be delete if you want to.
'124112': `ElementEnd:`, '124112': `ElementEnd:`,
'124113': `ArrayEnd:`, '124113': `ArrayEnd:`,
'1243': `Score Display`,
'124120': `FullValue:`,
'124121': `EmptyValue:`,
'124122': `DisplayEmpty:`,
'124310': `The setting will effect variables {{scoreStar}} and {{myRatingStar}}. When the score is {0}/{1}, template is \`score: {{scoreStar}}\``,
'124311': `MaxStar:`,
'124312': `Integer:`,
'121101': `Template File`, '121101': `Template File`,
'121102': `This template will be used when creating new notes. If keep empty, it will use default template`, '121102': `This template will be used when creating new notes. If keep empty, it will use default template`,
@ -296,6 +305,7 @@ PS: This file could be delete if you want to.
'410101': `Unknown`, '410101': `Unknown`,
'410200': `评分⭐`,
//参数 //参数
'300101': `参数`, '300101': `参数`,
@ -542,6 +552,7 @@ PS: This file could be delete if you want to.
'160228': `My state at book-reading/video-watching.`, '160228': `My state at book-reading/video-watching.`,
'160229': `Comment`, '160229': `Comment`,
'160230': `Rate Date`, '160230': `Rate Date`,
'160231': `The rate that I rate to subject.(1⭐-5⭐)`,
'500001': `Sync Config`, '500001': `Sync Config`,

@ -193,6 +193,14 @@ export default {
'124112': `元素尾:`, '124112': `元素尾:`,
'124113': `尾:`, '124113': `尾:`,
'1243': `评分scoreStar/myRateStar显示`,
'124120': `得分符号:`,
'124121': `未得分符号:`,
'124122': `显示未得分:`,
'124310': `评分(星)参数{{scoreStar}} and {{myRatingStar}}输出格式。当分数是{0}/{1}时,模板案例\`score: {{scoreStar}}\``,
'124311': `最大符号数:`,
'124312': `默认整数:`,
'120701': `豆瓣HTTP请求头`, '120701': `豆瓣HTTP请求头`,
'120702': `如果豆瓣搜索或者获取数据失败,请尝试修改这个参数,\n '120702': `如果豆瓣搜索或者获取数据失败,请尝试修改这个参数,\n
:\n :\n
@ -314,7 +322,7 @@ export default {
'410101': ``, '410101': ``,
'410102': `未知`, '410102': `未知`,
'410200': `评分⭐`,
//参数 //参数
'300101': `参数`, '300101': `参数`,
@ -550,6 +558,8 @@ export default {
'160225': `以下参数登录后方可在模板中使用, 使用时请用'{{}}'包裹, 举例: 参数myTags, 则使用时为{{myTags}}`, '160225': `以下参数登录后方可在模板中使用, 使用时请用'{{}}'包裹, 举例: 参数myTags, 则使用时为{{myTags}}`,
'160226': `我标记的标签`, '160226': `我标记的标签`,
'160227': `我的评分(1-5)`, '160227': `我的评分(1-5)`,
'160231': `我的评分(⭐)`,
'160228': `我的阅读/欣赏/听/玩的状态`, '160228': `我的阅读/欣赏/听/玩的状态`,
'160229': `我的评论`, '160229': `我的评论`,
'160230': `我的评论/标记的日期`, '160230': `我的评论/标记的日期`,

@ -1,3 +1,6 @@
import {DEFAULT_SETTINGS} from "../constant/DefaultSettings";
import {ScoreSetting} from "../douban/setting/model/ScoreSetting";
export default class NumberUtil { export default class NumberUtil {
/** /**
* *
@ -9,4 +12,56 @@ export default class NumberUtil {
const rand = Math.random(); const rand = Math.random();
return (min + Math.round(rand * range)); return (min + Math.round(rand * range));
} }
/**
*
* @param rate
* @param rateMax
* @param rateStarMax
* @param options
*/
static getRateStar(rate: number, rateMax: number, options?:{scoreSetting?:ScoreSetting}):string {
if (rate > rateMax) {
this.getRateStarMaxRate(1, options);
}
return this.getRateStarMaxRate(rate / rateMax, options);
}
/**
*
* @param rate [0 - 1]
* @param rateStarMax
* @param options
*/
private static getRateStarMaxRate(star: number, options?:{scoreSetting?:ScoreSetting}):string {
let result = '';
const scoreSetting = options&&options.scoreSetting?options.scoreSetting:DEFAULT_SETTINGS.scoreSetting;
const starFull = scoreSetting&&scoreSetting.starFull?scoreSetting.starFull: '★';
const starEmpty = scoreSetting&&scoreSetting.starEmpty?scoreSetting.starEmpty: '☆';
const displayStarEmpty =scoreSetting&&(scoreSetting.displayStarEmpty != null)?scoreSetting.displayStarEmpty:true;
const rateStarMax =scoreSetting&&scoreSetting.maxStar?scoreSetting.maxStar:5;
star = Math.floor(star * rateStarMax);
for (let i = 0; i < rateStarMax; i++) {
if (i < star) {
result += starFull;
} else if (displayStarEmpty) {
result += starEmpty;
}
}
return result;
}
static isNumber(value: string) {
return !isNaN(Number(value));
}
static isInt(value: string) {
return Number.isInteger(Number(value));
}
static value(value: string) {
return Number(value);
}
} }

@ -4,11 +4,40 @@ import StringUtil from "./StringUtil";
import YamlUtil from "./YamlUtil"; import YamlUtil from "./YamlUtil";
import {log} from "./Logutil"; import {log} from "./Logutil";
import {i18nHelper} from "../lang/helper"; import {i18nHelper} from "../lang/helper";
import {DataValueType} from "../constant/Constsant"; 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";
export class VariableUtil { export class VariableUtil {
/**
*
* @param obj
* @param content
* @param settingManager
*/
static replaceSubject(obj: any, content: string, subjectType: SupportType, 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) {
this.handleCustomVariable(subjectType, obj, settingManager)
content = this.replaceMap(obj, allVariables, content, settingManager);
}else {
const map = this.objToMap(obj);
this.handleCustomVariable(subjectType, map, settingManager)
content = this.replaceMap(map, allVariables, content, settingManager);
}
return content;
}
/** /**
* *
@ -28,8 +57,8 @@ export class VariableUtil {
if (obj instanceof Map) { if (obj instanceof Map) {
content = this.replaceMap(obj, allVariables, content, settingManager); content = this.replaceMap(obj, allVariables, content, settingManager);
}else { }else {
content = this.replaceObject(obj, allVariables, content, settingManager); const map = this.objToMap(obj);
} content = this.replaceMap(map, allVariables, content, settingManager); }
return content; return content;
} }
@ -142,18 +171,6 @@ export class VariableUtil {
} }
} }
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) { private static replaceMap(obj: Map<string, any>, allVariables:FieldVariable[], content: string, settingManager: SettingsManager) {
allVariables.forEach(variable => { allVariables.forEach(variable => {
@ -211,4 +228,39 @@ export class VariableUtil {
return content; return content;
} }
/**
*
* @param template
* @param context
* @private
*/
static handleCustomVariable(subjectType: SupportType, variableMap:Map<string, DataField>, settingMananger: SettingsManager): void {
// @ts-ignore
const customProperties: CustomProperty[] = settingMananger.getSetting('customProperties');
if (!customProperties) {
return ;
}
const customPropertiesMap= new Map();
customProperties.filter(customProperty => customProperty.name &&
customProperty.field
&& (customProperty.field.toLowerCase() == SupportType.ALL ||
customProperty.field.toLowerCase() == subjectType)).forEach(customProperty => {
customPropertiesMap.set(customProperty.name, customProperty.value);
});
customPropertiesMap.forEach((value, key) => {
variableMap.set(key,
new DataField(
key, DataValueType.string, value,
VariableUtil.replace(variableMap, value, settingMananger)));
})
}
private static objToMap(obj: any):Map<string, any> {
const map = new Map<string, any>();
Object.keys(obj).forEach(key => {
map.set(key, obj[key]);
});
return map;
}
} }