mirror of
https://github.com/Wanxp/obsidian-douban.git
synced 2026-04-04 08:38:41 +08:00
add book search
This commit is contained in:
parent
382d79ec73
commit
ee2dead393
@ -24,9 +24,10 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
|
||||
abstract support(extract: DoubanSubject): boolean;
|
||||
|
||||
handle(url:string, editor:Editor):void {
|
||||
Promise.resolve().then(() => get(url + "/", {headers: JSON.parse(this.doubanPlugin.settings.searchHeaders)}))
|
||||
Promise.resolve().then(() => get(log.traceN("GET URL", url + "/"), log.traceN("GET HEAD", {headers: JSON.parse(this.doubanPlugin.settings.searchHeaders)})))
|
||||
.then(readStream)
|
||||
.then(cheerio.load)
|
||||
.then(log.trace)
|
||||
.then(this.parseSubjectFromHtml)
|
||||
.then(content => this.toEditor(editor, content))
|
||||
// .then(content => content ? editor.replaceSelection(content) : content)
|
||||
|
||||
68
douban/handler/DoubanBookLoadHandler.ts
Normal file
68
douban/handler/DoubanBookLoadHandler.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import { Editor, moment, renderResults } from "obsidian";
|
||||
import cheerio, { CheerioAPI } from 'cheerio';
|
||||
import { get, readStream } from "tiny-network";
|
||||
|
||||
import DoubanAbstractLoadHandler from "./DoubanAbstractLoadHandler";
|
||||
import DoubanBookSubject from "douban/model/DoubanBookSubject";
|
||||
import DoubanPlugin from "main";
|
||||
import { DoubanPluginSettings } from "douban/Douban";
|
||||
import DoubanSubject from "douban/model/DoubanSubject";
|
||||
import SchemaOrg from "utils/SchemaOrg";
|
||||
import { log } from "utils/Logutil";
|
||||
|
||||
export default class DoubanBookLoadHandler extends DoubanAbstractLoadHandler<DoubanBookSubject> {
|
||||
|
||||
parseText(extract: DoubanBookSubject, 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 && (extract.type.contains("书籍") || extract.type.contains("Book") || extract.type.contains("book"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
constructor(doubanPlugin:DoubanPlugin) {
|
||||
super(doubanPlugin);
|
||||
}
|
||||
|
||||
parseSubjectFromHtml(data: CheerioAPI): DoubanBookSubject {
|
||||
return data('script')
|
||||
.get()
|
||||
.filter(scd => "application/ld+json" == data(scd).attr("type"))
|
||||
.map(i => {
|
||||
var item = data(i).text();
|
||||
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);
|
||||
const result:DoubanBookSubject = {
|
||||
id: id?id[0]:'',
|
||||
type: 'Book',
|
||||
title: obj.name,
|
||||
desc: obj.description,
|
||||
url: "https://book.douban.com" + obj.url,
|
||||
author: obj.author,
|
||||
aggregateRating: obj.aggregateRating,
|
||||
datePublished: obj.datePublished ? new Date(obj.datePublished) : undefined,
|
||||
image:obj.image
|
||||
}
|
||||
return result;
|
||||
})[0];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ import { DoubanPluginSettings } from "douban/Douban";
|
||||
import DoubanSubject from "../model/DoubanSubject";
|
||||
import DoubanSubjectLoadHandler from "./DoubanSubjectLoadHandler";
|
||||
|
||||
export class DoubanEtractHandler {
|
||||
export class DoubanSearchChooseItemHandler {
|
||||
|
||||
private _app:App;
|
||||
private _doubanPlugin:DoubanPlugin;
|
||||
@ -32,10 +32,7 @@ export class DoubanEtractHandler {
|
||||
var doubanSubjectHandlers:DoubanSubjectLoadHandler<DoubanSubject>[] = this._doubanSubjectHandlers
|
||||
.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) {
|
||||
return result[0];
|
||||
}
|
||||
doubanSubjectHandlers[0].handle(searchExtract.url, editor);
|
||||
}else {
|
||||
this._doubanSubjectHandlerDefault.handle(searchExtract.url, editor);
|
||||
}
|
||||
10
douban/model/DoubanBookSubject.ts
Normal file
10
douban/model/DoubanBookSubject.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import {AggregateRating, Person, WithContext} from 'schema-dts';
|
||||
|
||||
import DoubanSubject from "./DoubanSubject";
|
||||
|
||||
export default class DoubanMovieSubject extends DoubanSubject {
|
||||
author:Person[];
|
||||
aggregateRating:AggregateRating;
|
||||
datePublished:Date;
|
||||
image:string
|
||||
}
|
||||
@ -33,6 +33,7 @@ class DoubanFuzzySuggester extends FuzzySuggestModal<DoubanSearchResultSubject>
|
||||
}
|
||||
|
||||
onChooseItem(item: DoubanSearchResultSubject, evt: MouseEvent | KeyboardEvent): void {
|
||||
log.trace(`you chosen : ${JSON.stringify(item)}`)
|
||||
this.plugin.doubanEtractHandler.handle(item, this.editor);
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ export default class Searcher {
|
||||
// return Promise.resolve();
|
||||
return Promise
|
||||
.resolve()
|
||||
.then(() => get(doubanSettings.searchUrl + searchItem, JSON.parse(doubanSettings.searchHeaders)))
|
||||
.then(() => get(log.traceN("GET", doubanSettings.searchUrl + searchItem), JSON.parse(doubanSettings.searchHeaders)))
|
||||
.then(ensureStatusCode(200))
|
||||
.then(readStream)
|
||||
.then(cheerio.load)
|
||||
|
||||
16
main.ts
16
main.ts
@ -1,9 +1,9 @@
|
||||
import { DEFAULT_SETTINGS, DoubanPluginSettings } from "./douban/Douban";
|
||||
import { Editor, Plugin } from "obsidian";
|
||||
|
||||
import { DoubanEtractHandler } from "douban/handler/DoubanExtractHandler";
|
||||
import { DoubanFuzzySuggester } from "douban/search/DoubanSearchFuzzySuggestModal";
|
||||
import DoubanMovieSubject from "douban/model/DoubanMovieSubject";
|
||||
import { DoubanSearchChooseItemHandler } from "douban/handler/DoubanSearchChooseItemHandler";
|
||||
import { DoubanSearchModal } from "douban/search/DoubanSearchModal";
|
||||
import { DoubanSettingTab } from "douban/DoubanSettingTab";
|
||||
import DoubanSubject from "douban/model/DoubanSubject";
|
||||
@ -13,12 +13,14 @@ import { log } from "utils/Logutil";
|
||||
|
||||
export default class DoubanPlugin extends Plugin {
|
||||
public settings: DoubanPluginSettings;
|
||||
public doubanEtractHandler: DoubanEtractHandler;
|
||||
public doubanEtractHandler: DoubanSearchChooseItemHandler;
|
||||
|
||||
async putToEditor(editor:Editor, extract:DoubanSubject) {
|
||||
if(!editor || !extract) {
|
||||
log.trace(`chosen item can not load data`);
|
||||
return;
|
||||
}
|
||||
log.trace(`you choose item load data success: ${JSON.stringify(extract)}`);
|
||||
var content:string = this.doubanEtractHandler.parseText(extract, this.settings)
|
||||
if(content) {
|
||||
editor.replaceSelection(content);
|
||||
@ -33,7 +35,7 @@ export default class DoubanPlugin extends Plugin {
|
||||
new DoubanFuzzySuggester(this, editor).showSearchList(resultList);
|
||||
}
|
||||
|
||||
async getDoubanMovieTextForActiveFile(editor: Editor) {
|
||||
async getDoubanTextForActiveFile(editor: Editor) {
|
||||
const activeFile = await this.app.workspace.getActiveFile();
|
||||
if (activeFile) {
|
||||
const searchTerm = activeFile.basename;
|
||||
@ -43,7 +45,7 @@ export default class DoubanPlugin extends Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
async geDoubanMovieTextForSearchTerm(editor: Editor) {
|
||||
async geDoubanTextForSearchTerm(editor: Editor) {
|
||||
new DoubanSearchModal(this.app, this, editor).open();
|
||||
}
|
||||
|
||||
@ -54,7 +56,7 @@ export default class DoubanPlugin extends Plugin {
|
||||
id: "search-douban-by-current-file-name",
|
||||
name: i18nHelper.getMessage("search douban by current file name"),
|
||||
editorCallback: (editor: Editor) =>
|
||||
this.getDoubanMovieTextForActiveFile(editor),
|
||||
this.getDoubanTextForActiveFile(editor),
|
||||
});
|
||||
|
||||
|
||||
@ -62,7 +64,7 @@ export default class DoubanPlugin extends Plugin {
|
||||
id: "search-douban-and-input-current-file",
|
||||
name: i18nHelper.getMessage("search douban and import to current file"),
|
||||
editorCallback: (editor: Editor) =>
|
||||
this.geDoubanMovieTextForSearchTerm(editor),
|
||||
this.geDoubanTextForSearchTerm(editor),
|
||||
});
|
||||
|
||||
this.addSettingTab(new DoubanSettingTab(this.app, this));
|
||||
@ -70,7 +72,7 @@ export default class DoubanPlugin extends Plugin {
|
||||
|
||||
async loadSettings() {
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
||||
this.doubanEtractHandler = new DoubanEtractHandler(this.app, this);
|
||||
this.doubanEtractHandler = new DoubanSearchChooseItemHandler(this.app, this);
|
||||
}
|
||||
|
||||
async saveSettings() {
|
||||
|
||||
@ -19,9 +19,15 @@ class Logger {
|
||||
}
|
||||
|
||||
public trace(e:any):any {
|
||||
return e;
|
||||
// console.log(`Douban Plugin trace: ${typeof e == 'string' ? e : JSON.stringify(e)}`);
|
||||
// return e;
|
||||
console.log(`Douban Plugin trace: ${typeof e == 'string' ? e : JSON.stringify(e)}`);
|
||||
return e;
|
||||
}
|
||||
|
||||
public traceN(notion:string, e:any):any {
|
||||
// return e;
|
||||
console.log(`${notion} ${typeof e == 'string' ? e : JSON.stringify(e)}`);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user