complete version 1.0.1

This commit is contained in:
wanxp 2022-06-05 23:31:28 +08:00
parent 9b55b3b88e
commit 20f49a685c
25 changed files with 266 additions and 163 deletions

@ -1,73 +1,18 @@
# Obsidian Sample Plugin
This is a sample plugin for Obsidian (https://obsidian.md).
This project uses Typescript to provide type checking and documentation.
The repo depends on the latest plugin API (obsidian.d.ts) in Typescript Definition format, which contains TSDoc comments describing what it does.
**Note:** The Obsidian API is still in early alpha and is subject to change at any time!
This sample plugin demonstrates some of the basic functionality the plugin API can do.
- Changes the default font color to red using `styles.css`.
- Adds a ribbon icon, which shows a Notice when clicked.
- Adds a command "Open Sample Modal" which opens a Modal.
- Adds a plugin setting tab to the settings page.
- Registers a global click event and output 'click' to the console.
- Registers a global interval which logs 'setInterval' to the console.
## First time developing plugins?
Quick starting guide for new plugin devs:
- Check if [someone already developed a plugin for what you want](https://obsidian.md/plugins)! There might be an existing plugin similar enough that you can partner up with.
- Make a copy of this repo as a template with the "Use this template" button (login to GitHub if you don't see it).
- Clone your repo to a local development folder. For convenience, you can place this folder in your `.obsidian/plugins/your-plugin-name` folder.
- Install NodeJS, then run `npm i` in the command line under your repo folder.
- Run `npm run dev` to compile your plugin from `main.ts` to `main.js`.
- Make changes to `main.ts` (or create new `.ts` files). Those changes should be automatically compiled into `main.js`.
- Reload Obsidian to load the new version of your plugin.
- Enable plugin in settings window.
- For updates to the Obsidian API run `npm update` in the command line under your repo folder.
## Releasing new releases
- Update your `manifest.json` with your new version number, such as `1.0.1`, and the minimum Obsidian version required for your latest release.
- Update your `versions.json` file with `"new-plugin-version": "minimum-obsidian-version"` so older versions of Obsidian can download an older version of your plugin that's compatible.
- Create new GitHub release using your new version number as the "Tag version". Use the exact version number, don't include a prefix `v`. See here for an example: https://github.com/obsidianmd/obsidian-sample-plugin/releases
- Upload the files `manifest.json`, `main.js`, `styles.css` as binary attachments. Note: The manifest.json file must be in two places, first the root path of your repository and also in the release.
- Publish the release.
> You can simplify the version bump process by running `npm version patch`, `npm version minor` or `npm version major` after updating `minAppVersion` manually in `manifest.json`.
> The command will bump version in `manifest.json` and `package.json`, and add the entry for the new version to `versions.json`
## Adding your plugin to the community plugin list
- Check https://github.com/obsidianmd/obsidian-releases/blob/master/plugin-review.md
- Publish an initial version.
- Make sure you have a `README.md` file in the root of your repo.
- Make a pull request at https://github.com/obsidianmd/obsidian-releases to add your plugin.
# Obsidian Douban Plugin
![GitHub release](https://img.shields.io/github/v/release/pyrochlore/obsidian-tracker)
Import Movies, Books, Music Data from Douban in [Obsidian](https://obsidian.md/)
在[Obsidian](https://obsidian.md/)使用并导入豆瓣中的电影/音乐/以及书籍等, 评分/发布日期/演员表等信息
- [Bugs, Issues, & Feature Requests](https://github.com/Wanxp/obsidian-douban/issues)
- [Development Roadmap](https://github.com/users/Wanxp/projects/1)
## How to use
- Clone this repo.
- `npm i` or `yarn` to install dependencies
- `npm run dev` to start compilation in watch mode.
## Manually installing the plugin
- Copy over `main.js`, `styles.css`, `manifest.json` to your vault `VaultFolder/.obsidian/plugins/your-plugin-id/`.
## Improve code quality with eslint (optional)
- [ESLint](https://eslint.org/) is a tool that analyzes your code to quickly find problems. You can run ESLint against your plugin to find common bugs and ways to improve your code.
- To use eslint with this project, make sure to install eslint from terminal:
- `npm install -g eslint`
- To use eslint to analyze this project use this command:
- `eslint main.ts`
- eslint will then create a report with suggestions for code improvement by file and line number.
- If your source code is in a folder, such as `src`, you can use eslint with this command to analyze all files in that folder:
- `eslint .\src\`
## API Documentation
See https://github.com/obsidianmd/obsidian-api
### Movie
- Search Movie By File Name/通过文件名搜索
![Search Movie By File Name](./doc/search_by_file_name.gif)
- Search Movie By Input Text/通过输入文本搜索
![Search Movie By Input Text](./doc/search_by_input.gif)
## Settings
- Setting Example1/设置案例1
![Setting Example1](./doc/setting_en.gif)
- Setting Example2/设置案例2
![Setting Example2](./doc/setting_en.gif)

BIN
doc/search_by_file_name.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 KiB

BIN
doc/search_by_input.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

BIN
doc/setting_en.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

BIN
doc/setting_zh.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

@ -1,11 +1,19 @@
import { i18nHelper } from "lang/helper";
import { type } from "os";
interface DoubanPluginSettings {
export interface DoubanPluginSettings {
movieTemplate:string,
dateFormat:string,
searchUrl:string,
arraySpilt:string,
searchHeaders?:string,
personNameMode:PersonNameMode,
}
export enum PersonNameMode {
CH_NAME = "CH",
EN_NAME = "EN",
CH_EN_NAME = "CH_EN",
}
@ -32,15 +40,15 @@ export const DEFAULT_SETTINGS:DoubanPluginSettings = {
searchUrl: 'https://www.douban.com/search?q=',
searchHeaders: JSON.stringify(doubanHeadrs),
dateFormat: "yyyy_MM_DD",
arraySpilt: ", "
arraySpilt: ", ",
personNameMode: PersonNameMode.CH_NAME
}
export const personNameModeRecords: {[key in PersonNameMode]: string} = {
[PersonNameMode.CH_NAME]: i18nHelper.getMessage("Chinese Name"),
[PersonNameMode.EN_NAME]: i18nHelper.getMessage("English Name"),
[PersonNameMode.CH_EN_NAME]: i18nHelper.getMessage("Chinese And English Name"),
}
export class DefaultSettingsContent {
}
export type {DoubanPluginSettings}

@ -1,8 +1,9 @@
import { App, PluginSettingTab, Setting } from "obsidian";
import { DEFAULT_SETTINGS, PersonNameMode, personNameModeRecords } from "./Douban";
import { DEFAULT_SETTINGS } from "./Douban";
import DoubanPlugin from "main";
import { i18nHelper } from "lang/helper";
import { log } from "utils/Logutil";
export class DoubanSettingTab extends PluginSettingTab {
plugin: DoubanPlugin;
@ -87,6 +88,33 @@ export class DoubanSettingTab extends PluginSettingTab {
});
});
new Setting(containerEl).setName(i18nHelper.getMessage("Person Name Language Mode")).then((setting) => {
setting.addDropdown((dropdwon) => {
setting.descEl.appendChild(
createFragment((frag) => {
frag.appendText(i18nHelper.getMessage('options:'));
frag.createEl('br');
frag.appendText(i18nHelper.getMessage('Chinese Name mode, only show Chinese name'));
frag.createEl('br');
frag.appendText(i18nHelper.getMessage('English Name mode, only show English name'));
frag.createEl('br');
frag.appendText(i18nHelper.getMessage('Chinese English Name mode, show Chinese English name both'));
frag.createEl('br');
})
);
// dropdwon.inputEl.addClass("settings_area");
// dropdwon.inputEl.setAttr("rows", 10);
dropdwon.addOption(PersonNameMode.CH_NAME, personNameModeRecords.CH)
dropdwon.addOption(PersonNameMode.EN_NAME, personNameModeRecords.EN)
dropdwon.addOption(PersonNameMode.CH_EN_NAME, personNameModeRecords.CH_EN)
dropdwon.setValue(this.plugin.settings.personNameMode)
.onChange(async (value:string) => {
this.plugin.settings.personNameMode = value as PersonNameMode;
await this.plugin.saveSettings();
});
});
});

@ -1,13 +1,14 @@
import { DoubanPluginSettings, PersonNameMode } from "douban/Douban";
import cheerio, { CheerioAPI } from "cheerio";
import { get, readStream } from "tiny-network";
import DoubanPlugin from "main";
import { DoubanPluginSettings } from "douban/Douban";
import DoubanSubject from "douban/model/DoubanSubject";
import DoubanSubjectLoadHandler from "./DoubanSubjectLoadHandler";
import { Editor } from "obsidian";
import HttpUtil from "utils/HttpUtil";
import { log } from "utils/logutil";
import { json } from "stream/consumers";
import { log } from "utils/Logutil";
export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject> implements DoubanSubjectLoadHandler<T> {
@ -18,7 +19,7 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
this.doubanPlugin = doubanPlugin;
}
abstract parseText(template: string, arraySpilt:string, extract: T): string;
abstract parseText(extract: T, settings:DoubanPluginSettings): string;
abstract support(extract: DoubanSubject): boolean;
@ -41,4 +42,52 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
return extract;
}
getPersonName(name:string, settings:DoubanPluginSettings):string {
if(!name || !settings || !settings.personNameMode) {
return "";
}
var resultName = "";
switch(settings.personNameMode) {
case PersonNameMode.CH_NAME:
var regValue = /[\u4e00-\u9fa5]{2,20}/g.exec(name);
resultName = regValue?regValue[0]:name;
break;
case PersonNameMode.EN_NAME:
var regValue = /[a-zA-Z.\s\-]{2,50}/g.exec(name);
resultName = regValue?regValue[0]:name;
break;
default:
resultName = name;
}
return resultName;
}
html_encode(str:string):string
{
var s = "";
if (str.length == 0) return "";
s = str.replace(/&/g, "&amp;");
s = s.replace(/</g, "&lt;");
s = s.replace(/>/g, "&gt;");
s = s.replace(/ /g, "&nbsp;");
s = s.replace(/\'/g, "&#39;");
s = s.replace(/\"/g, "&quot;");
s = s.replace(/\n/g, "<br/>");
return s;
}
html_decode(str:string):string
{
var s = "";
if (str.length == 0) return "";
s = str.replace(/&amp;/g, "&");
s = s.replace(/&lt;/g, "<");
s = s.replace(/&gt;/g, ">");
s = s.replace(/&nbsp;/g, " ");
s = s.replace(/&#39;/g, "\'");
s = s.replace(/&quot;/g, "\"");
s = s.replace(/<br\/>/g, "\n");
return s;
}
}

@ -30,7 +30,7 @@ export class DoubanEtractHandler {
return;
}
var doubanSubjectHandlers:DoubanSubjectLoadHandler<DoubanSubject>[] = this._doubanSubjectHandlers
.filter(h => h.support);
.filter(h => h.support(searchExtract));
if(doubanSubjectHandlers && doubanSubjectHandlers.length > 0) {
var result = doubanSubjectHandlers.map(h => h.handle(searchExtract.url, editor))
if(result && result.length > 0) {
@ -41,21 +41,21 @@ export class DoubanEtractHandler {
}
}
public parseText(template: string, arraySpilt:string, extract:DoubanSubject):string {
if(!template) {
public parseText(extract:DoubanSubject, settings:DoubanPluginSettings):string {
if(!settings) {
return "";
}
var doubanSubjectHandlers:DoubanSubjectLoadHandler<DoubanSubject>[] = this._doubanSubjectHandlers
.filter(h => h.support);
.filter(h => h.support(extract));
if(doubanSubjectHandlers && doubanSubjectHandlers.length > 0) {
var result = doubanSubjectHandlers.map(h => h.parseText(template, arraySpilt, extract));
var result = doubanSubjectHandlers.map(h => h.parseText(extract, settings));
if(result && result.length > 0) {
return result[0];
}else {
return "";
}
}else {
return this._doubanSubjectHandlerDefault.parseText(template, arraySpilt, extract);
return this._doubanSubjectHandlerDefault.parseText(extract, settings);
}
}

@ -1,4 +1,4 @@
import { Editor, renderResults } from "obsidian";
import { Editor, moment, renderResults } from "obsidian";
import cheerio, { CheerioAPI } from 'cheerio';
import { get, readStream } from "tiny-network";
@ -7,27 +7,30 @@ import DoubanMovieSubject from "douban/model/DoubanMovieSubject";
import DoubanPlugin from "main";
import { DoubanPluginSettings } from "douban/Douban";
import DoubanSubject from "douban/model/DoubanSubject";
import { log } from "utils/logutil";
import SchemaOrg from "utils/SchemaOrg";
import { log } from "utils/Logutil";
export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<DoubanMovieSubject> {
parseText(template: string, arraySpilt:string, extract: DoubanMovieSubject): string {
return template ? template.replace("{{id}}", extract.id)
.replace("{{type}}", extract.type ? extract.type : "")
.replace("{{title}}", extract.title ? extract.title : "")
.replace("{{desc}}", extract.desc ? extract.desc : "")
.replace("{{image}}", extract.image ? extract.image : "")
.replace("{{director}}", extract.director ? extract.director.join(arraySpilt) : "")
.replace("{{actor}}", extract.actor ? extract.actor.join(arraySpilt) : "")
.replace("{{author}}", extract.author ? extract.author.join(arraySpilt) : "")
.replace("{{datePublished}}", extract.datePublished ? extract.datePublished : "")
.replace("{{url}}", extract.url ? extract.url : "")
.replace("{{score}}", extract.aggregateRating && extract.aggregateRating.ratingValue ? extract.aggregateRating.ratingValue + "" : "")
parseText(extract: DoubanMovieSubject, settings:DoubanPluginSettings): string {
return settings.movieTemplate ? settings.movieTemplate.replaceAll("{{id}}", extract.id)
.replaceAll("{{type}}", extract.type ? extract.type : "")
.replaceAll("{{title}}", extract.title ? extract.title : "")
.replaceAll("{{desc}}", extract.desc ? extract.desc : "")
.replaceAll("{{image}}", extract.image ? extract.image : "")
.replaceAll("{{director}}", extract.director ? extract.director.map(SchemaOrg.getPersonName).map(name => super.getPersonName(name, settings)).filter(c => c).join(settings.arraySpilt) : "")
.replaceAll("{{actor}}", extract.actor ? extract.actor.map(SchemaOrg.getPersonName).map(name => super.getPersonName(name, settings)).filter(c => c).join(settings.arraySpilt) : "")
.replaceAll("{{author}}", extract.author ? extract.author.map(SchemaOrg.getPersonName).map(name => super.getPersonName(name, settings)).filter(c => c).join(settings.arraySpilt) : "")
.replaceAll("{{datePublished}}", extract.datePublished ? moment(extract.datePublished).format(settings.dateFormat) : "")
.replaceAll("{{url}}", extract.url ? extract.url : "")
.replaceAll("{{score}}", extract.aggregateRating && extract.aggregateRating.ratingValue ? extract.aggregateRating.ratingValue + "" : "")
: undefined; }
support(extract: DoubanSubject): boolean {
return extract && ('[电影]'==extract.type || 'Movie' == extract.type);
return extract && extract.type && (extract.type.contains("电影") || extract.type.contains("Movie") || extract.type.contains("movie"));
}
constructor(doubanPlugin:DoubanPlugin) {
@ -40,10 +43,10 @@ export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<Do
.filter(scd => "application/ld+json" == data(scd).attr("type"))
.map(i => {
var item = data(i).text();
var obj = JSON.parse(item);
item = super.html_decode(item);
var obj = JSON.parse(item.replace(/[\r\n\s+]/g, ''));
var idPattern = /(\d){5,10}/g;
var id = idPattern.exec(obj.url);
log.info(item);
const result:DoubanMovieSubject = {
id: id?id[0]:'',
type: 'Movie',
@ -54,10 +57,9 @@ export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<Do
author: obj.author,
actor: obj.actor,
aggregateRating: obj.aggregateRating,
datePublished:obj.datePublished,
datePublished: obj.datePublished ? new Date(obj.datePublished) : undefined,
image:obj.image
}
log.info(result);
return result;
})[0];
}

@ -2,15 +2,16 @@ import { Editor, Notice } from "obsidian";
import { CheerioAPI } from "cheerio";
import DoubanAbstractLoadHandler from "./DoubanAbstractLoadHandler";
import { DoubanPluginSettings } from "douban/Douban";
import DoubanSubject from "douban/model/DoubanSubject";
import { i18nHelper } from "lang/helper";
import { log } from "utils/logutil";
import { log } from "utils/Logutil";
/**
*
*/
export default class DoubanOtherLoadHandler extends DoubanAbstractLoadHandler<DoubanSubject> {
parseText(template: string, arraySpilt: string, extract: DoubanSubject): string {
parseText(extract: DoubanSubject, settings:DoubanPluginSettings): string {
log.warn(i18nHelper.getMessage('current version not support type'));
return "";
}

@ -1,9 +1,10 @@
import { DoubanPluginSettings } from "douban/Douban";
import DoubanSubject from "douban/model/DoubanSubject";
import { Editor } from "obsidian";
export default interface DoubanSubjectLoadHandler<T extends DoubanSubject> {
parseText(template: string, arraySpilt:string, extract: DoubanSubject): string;
parseText(extract: T, settings:DoubanPluginSettings): string;
support(extract:DoubanSubject):boolean;

@ -1,12 +1,12 @@
import DoubanSubject from "./DoubanSubject";
import {AggregateRating, Person, WithContext} from 'schema-dts';
import DoubanSubject from "./DoubanSubject";
export default class DoubanMovieSubject extends DoubanSubject {
director:Person[];
author:Person[];
actor:Person[];
aggregateRating:AggregateRating;
datePublished:string;
datePublished:Date;
image:string
}

@ -1,8 +1,8 @@
import DoubanSearchResultSubject from "douban/model/DoubanSearchResultSubject";
import DoubanPlugin from "main";
import { FuzzySuggestModal,App, Editor } from "obsidian";
import { log } from "utils/logutil";
import { App, Editor, FuzzySuggestModal } from "obsidian";
import DoubanPlugin from "main";
import DoubanSearchResultSubject from "douban/model/DoubanSearchResultSubject";
import { log } from "utils/Logutil";
export {DoubanFuzzySuggester}
@ -19,13 +19,6 @@ class DoubanFuzzySuggester extends FuzzySuggestModal<DoubanSearchResultSubject>
this.plugin = plugin;
this.setPlaceholder("Choose an item...");
// this.inputEl.addEventListener("keydown", (event) => {
// if (event.key === "Enter") {
// log.info("enter")
// this.reloadSearch();
// }
// })
}
@ -40,7 +33,6 @@ class DoubanFuzzySuggester extends FuzzySuggestModal<DoubanSearchResultSubject>
}
onChooseItem(item: DoubanSearchResultSubject, evt: MouseEvent | KeyboardEvent): void {
log.warn(`choose itme ${JSON.stringify(item)}`);
this.plugin.doubanEtractHandler.handle(item, this.editor);
}

@ -1,6 +1,8 @@
import { App, Editor, Modal, TextComponent } from "obsidian";
import { log } from "utils/logutil";
import DoubanPlugin from "../../main";
import { i18nHelper } from "lang/helper";
import { log } from "utils/Logutil";
export class DoubanSearchModal extends Modal {
searchTerm: string;
@ -16,16 +18,18 @@ export class DoubanSearchModal extends Modal {
onOpen() {
let { contentEl } = this;
contentEl.createEl("h2", { text: "Enter Search Term:" });
contentEl.createEl("h2", { text: i18nHelper.getMessage('Enter Search Term:') });
const inputs = contentEl.createDiv("inputs");
const searchInput = new TextComponent(inputs).onChange((searchTerm) => {
this.searchTerm = searchTerm;
});
searchInput.inputEl.addClass("search_input");
searchInput.inputEl.focus();
searchInput.inputEl.addEventListener("keydown", (event) => {
if (event.key === "Enter") {
this.search();
this.close();
}
});
@ -33,35 +37,29 @@ export class DoubanSearchModal extends Modal {
const controls = contentEl.createDiv("controls");
const searchButton = controls.createEl("button", {
text: "Search",
text: i18nHelper.getMessage('Search'),
cls: "mod-cta",
attr: {
autofocus: true,
},
});
searchButton.addClass("search_button");
searchButton.addEventListener("click", this.close.bind(this));
const cancelButton = controls.createEl("button", { text: "Cancel" });
const cancelButton = controls.createEl("button", { text: i18nHelper.getMessage('Cancel') });
cancelButton.addEventListener("click", this.close.bind(this));
}
async search() {
let { contentEl } = this;
contentEl.empty();
if (this.searchTerm) {
this.close();
await this.plugin.search(this.searchTerm, this.editor);
cancelButton.addClass("search_button");
}
}
async onClose() {
let { contentEl } = this;
contentEl.empty();
if (this.searchTerm) {
// await this.plugin.pasteIntoEditor(this.editor, this.searchTerm);
}
await this.plugin.search(this.searchTerm, this.editor);
}
}
}

@ -1,10 +1,11 @@
import cheerio from 'cheerio';
import { doubanHeadrs, DoubanPluginSettings } from 'douban/Douban';
import { DoubanPluginSettings, doubanHeadrs } from 'douban/Douban';
import { get, readStream } from 'tiny-network';
import { ensureStatusCode } from 'douban/ResponseHandle';
import { log } from 'utils/logutil';
import DoubanSearchResultSubject from 'douban/model/DoubanSearchResultSubject';
import SearchParserHandler from './SearchParser';
import cheerio from 'cheerio';
import { ensureStatusCode } from 'douban/ResponseHandle';
import { log } from 'utils/Logutil';
export default class Searcher {
static search(searchItem:string, doubanSettings:DoubanPluginSettings):Promise<DoubanSearchResultSubject[]> {
@ -17,6 +18,7 @@ export default class Searcher {
.then(ensureStatusCode(200))
.then(readStream)
.then(cheerio.load)
.then(SearchParserHandler.parseSearch);
.then(SearchParserHandler.parseSearch)
.then(log.trace);
};
}

@ -2,7 +2,10 @@
export default {
//main.ts
'search douban by current file name':'search douban by current file name',
'search douban and input current file':'search douban and input current file',
'search douban and import to current file':'search douban and import to current file',
'Enter Search Term:':`Enter Search Term:`,
'Search':`Search`,
'Cancel':`Cancel`,
//DoubanSettingTab
'douban search url': `Douban Search Url`,
'douban search url desc 1': `Douban search page request address. `,
@ -30,5 +33,12 @@ export default {
'Douban Request Headers':`Douban Request Headers`,
'current version not support type': `This type of import is not supported temporarily, please go to github to submit issues for help`,
'Douban': `Douban`,
'Person Name Language Mode':'Person Name Language Mode',
'options:':"options:",
'Chinese Name mode, only show Chinese name':'Chinese Name mode, person name only show Chinese name',
'English Name mode, only show English name':'English Name mode, person name only show English name',
'Chinese English Name mode, show Chinese English name both':'Chinese English Name mode, show Chinese and English name both',
'Chinese Name': 'Chinese Name',
'English Name': 'English Name',
'Chinese And English Name': 'Chinese And English Name',
}

@ -1,8 +1,12 @@
//简体中文
export default {
//main.ts
'search in douban by current file name':'用当前文档名搜索豆瓣并写入当前文档',
'search douban and input current file':'在豆瓣搜索并写入到当前文档',
'search douban by current file name':'用当前文档名搜索豆瓣并写入当前文档',
'search douban and import to current file':'在豆瓣搜索并写入到当前文档',
'Enter Search Term:':`输入搜索内容:`,
'Search':`搜索`,
'Cancel':`取消`,
//DoubanSettingTab
'douban search url': `豆瓣搜索地址`,
'douban search url desc 1': `豆瓣搜索页面请求地址, 通常是网页搜索的地址. `,
@ -33,5 +37,15 @@ export default {
1. 访http://www.douban.com
2. , `,
'current version not support type': `暂时不支持该类型导入,请至github提交issuess获取帮助`,
'Douban': `豆瓣网`
'Douban': `豆瓣网`,
'Person Name Language Mode':'人名显示模式',
'options:':"可选项:",
'Chinese Name mode, only show Chinese name':'中文名称模式, 人名只显示中文名',
'English Name mode, only show English name':'英文名称模式, 人名只显示英文名',
'Chinese English Name mode, show Chinese English name both':'中文和英文名称模式, 人名同时显示中文和英文名',
'Chinese Name': '中文名',
'English Name': '英文名',
'Chinese And English Name': '中文名和英文名',
}

11
main.ts

@ -9,14 +9,17 @@ import { DoubanSettingTab } from "douban/DoubanSettingTab";
import DoubanSubject from "douban/model/DoubanSubject";
import Searcher from "douban/search/Search";
import { i18nHelper } from './lang/helper';
import { log } from "utils/Logutil";
export default class DoubanPlugin extends Plugin {
public settings: DoubanPluginSettings;
public doubanEtractHandler: DoubanEtractHandler;
async putToEditor(editor:Editor, extract:DoubanSubject) {
var content:string = this.doubanEtractHandler.parseText(this.settings.movieTemplate,
this.settings.arraySpilt, extract)
if(!editor || !extract) {
return;
}
var content:string = this.doubanEtractHandler.parseText(extract, this.settings)
if(content) {
editor.replaceSelection(content);
}
@ -24,7 +27,9 @@ export default class DoubanPlugin extends Plugin {
async search(searchTerm:string, editor: Editor) {
log.trace("[main] start search:" + searchTerm);
const resultList = await Searcher.search(searchTerm, this.settings);
log.trace("[main] complete search:" + searchTerm + ",\n result list:" + JSON.stringify(resultList));
new DoubanFuzzySuggester(this, editor).showSearchList(resultList);
}
@ -55,7 +60,7 @@ export default class DoubanPlugin extends Plugin {
this.addCommand({
id: "search-douban-and-input-current-file",
name: i18nHelper.getMessage("search douban and input current file"),
name: i18nHelper.getMessage("search douban and import to current file"),
editorCallback: (editor: Editor) =>
this.geDoubanMovieTextForSearchTerm(editor),
});

@ -1,10 +1,10 @@
{
"id": "obsidian-sample-plugin",
"name": "Sample Plugin",
"id": "obsidian-douban-plugin",
"name": "Douban",
"version": "1.0.1",
"minAppVersion": "0.12.0",
"description": "This is a sample plugin for Obsidian. This plugin demonstrates some of the capabilities of the Obsidian API.",
"author": "Obsidian",
"authorUrl": "https://obsidian.md",
"description": "This is a plugin that can import movies , books or musics info data from Douban for Obsidian .",
"author": "Wanxp",
"authorUrl": "https://wanxuping.com",
"isDesktopOnly": false
}

@ -10,4 +10,18 @@
margin-right: 5px;
font-size: 14px;
width: 100%;
}
.search_input {
margin-left: 5px;
margin-right: 5px;
font-size: 14px;
width: 90%;
}
.search_button {
margin-top: 10px;
margin-left: 10px;
margin-right: 5px;
font-size: 14px;
}

@ -14,7 +14,8 @@
"DOM",
"ES5",
"ES6",
"ES7"
"ES7",
"ES2021.String"
],
"outDir": "dist",

@ -1,6 +1,7 @@
import * as https from 'https';
import { get } from 'tiny-network';
import { log } from './logutil';
import { log } from './Logutil';
export default class HttpUtil {

25
utils/SchemaOrg.ts Normal file

@ -0,0 +1,25 @@
import { Person } from "schema-dts";
export default class SchemaOrg {
public static getPersonName(p:Person):string {
if(isString(p)) {
return p;
}else {
let name: any = getProperty(p, 'name');
return name + "";
}
}
}
function isString(s:any): s is string {
return typeof s === 'string';
}
function getProperty<T, K extends keyof T>(o: T, name: K): T[K] {
return o[name];
}

@ -1,4 +1,5 @@
import { Notice } from "obsidian";
import SchemaOrg from "./SchemaOrg";
class Logger {
@ -13,9 +14,15 @@ class Logger {
}
public info(e:any):any {
console.log("Douban Plugin Info: " + e);
console.log(`Douban Plugin info: ${typeof e == 'string' ? e : JSON.stringify(e)}`);
return e;
}
public trace(e:any):any {
return e;
// console.log(`Douban Plugin trace: ${typeof e == 'string' ? e : JSON.stringify(e)}`);
// return e;
}
}
export const log:Logger = new Logger();