add douban subject

This commit is contained in:
wanxp 2022-06-03 17:58:34 +08:00
parent 143c004c6e
commit f4bda2c9d0
10 changed files with 83 additions and 206 deletions

@ -18,7 +18,7 @@ export const DEFAULT_SETTINGS:DoubanPluginSettings = {
"---\n" + "---\n" +
"title: {{title}}" + "title: {{title}}" +
"cast: {{cast}}" + "cast: {{cast}}" +
"score: {{score}}" + "score: {{score}}\n" +
"---", "---",
searchUrl: 'https://www.douban.com/search?q=', searchUrl: 'https://www.douban.com/search?q=',
searchHeaders: JSON.stringify(doubanHeadrs) searchHeaders: JSON.stringify(doubanHeadrs)

@ -1,28 +0,0 @@
import DoubanPlugin from "main";
import { App } from "obsidian";
import DoubanMovieLoadHandler from "./handler/DoubanMovieLoadHandler";
import DoubanSubjectLoadHandler from "./handler/DoubanSubjectLoadHandler";
import DoubanSubject from "./model/DoubanSubject";
export class DoubanEtractHandler {
private _app:App;
private _doubanPlugin:DoubanPlugin;
private _doubanSubjectHandlers:DoubanSubjectLoadHandler<DoubanSubject>[];
public DoubanEtractHandler(app:App, doubanPlugin:DoubanPlugin) {
this._app = app;
this._doubanPlugin = doubanPlugin;
this._doubanSubjectHandlers = [new DoubanMovieLoadHandler(), ]
}
public getSubjectTextById(searchExtract:DoubanSubject):string | undefined{
if(!searchExtract) {
return;
}
}
}

@ -1,69 +0,0 @@
import { App, Editor, Modal, TextComponent } from "obsidian";
import { log } from "utils/logutil";
import DoubanPlugin from "../main";
export class DoubanSearchModal extends Modal {
searchTerm: string;
plugin: DoubanPlugin;
editor: Editor;
constructor(app: App, plugin: DoubanPlugin, editor: Editor) {
super(app);
this.plugin = plugin;
this.editor = editor;
}
onOpen() {
let { contentEl } = this;
contentEl.createEl("h2", { text: "Enter Search Term:" });
const inputs = contentEl.createDiv("inputs");
const searchInput = new TextComponent(inputs).onChange((searchTerm) => {
this.searchTerm = searchTerm;
});
searchInput.inputEl.focus();
searchInput.inputEl.addEventListener("keydown", (event) => {
if (event.key === "Enter") {
this.search();
}
});
const controls = contentEl.createDiv("controls");
const searchButton = controls.createEl("button", {
text: "Search",
cls: "mod-cta",
attr: {
autofocus: true,
},
});
searchButton.addEventListener("click", this.close.bind(this));
const cancelButton = controls.createEl("button", { text: "Cancel" });
cancelButton.addEventListener("click", this.close.bind(this));
}
async search() {
log.info("start search :" + this.searchTerm);
let { contentEl } = this;
contentEl.empty();
if (this.searchTerm) {
this.close();
await this.plugin.search(this.searchTerm);
// await this.plugin.pasteIntoEditor(this.editor, null);
}
}
async onClose() {
let { contentEl } = this;
contentEl.empty();
if (this.searchTerm) {
// await this.plugin.pasteIntoEditor(this.editor, this.searchTerm);
}
}
}

@ -1,19 +1,34 @@
import { DoubanPluginSettings } from "douban/Douban"; import { DoubanPluginSettings } from "douban/Douban";
import DoubanSubject from "douban/model/DoubanSubject"; import DoubanSubject from "douban/model/DoubanSubject";
import cheerio, { CheerioAPI } from "cheerio";
import { get, readStream } from "tiny-network";
import { log } from "utils/logutil";
import DoubanSubjectLoadHandler from "./DoubanSubjectLoadHandler"; import DoubanSubjectLoadHandler from "./DoubanSubjectLoadHandler";
import DoubanPlugin from "main";
export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject> implements DoubanSubjectLoadHandler<T> { export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject> implements DoubanSubjectLoadHandler<T> {
doubanSettings:DoubanPluginSettings; doubanPlugin:DoubanPlugin;
DoubanAbstractLoadHandler(doubanSettings:DoubanPluginSettings) { constructor(doubanPlugin:DoubanPlugin) {
this.doubanSettings = doubanSettings; this.doubanPlugin = doubanPlugin;
} }
abstract getSubject(url:string): T; handle(url:string):void {
abstract getTextResult(url:string): string; Promise
abstract getType(): string; .resolve()
.then(() => get(url, JSON.parse(this.doubanPlugin.settings.searchHeaders)))
.then(readStream)
.then(log.info)
.then(cheerio.load)
.then(this.parseSubjectFromHtml);
}
abstract parseSubjectFromHtml(data:CheerioAPI):T | undefined;
abstract getType(): string | undefined;

@ -0,0 +1,31 @@
import DoubanPlugin from "main";
import { App } from "obsidian";
import DoubanMovieLoadHandler from "./DoubanMovieLoadHandler";
import DoubanOtherLoadHandler from "./DoubanOtherLoadHandler";
import DoubanSubjectLoadHandler from "./DoubanSubjectLoadHandler";
import DoubanSubject from "../model/DoubanSubject";
export class DoubanEtractHandler {
private _app:App;
private _doubanPlugin:DoubanPlugin;
private _doubanSubjectHandlers:DoubanSubjectLoadHandler<DoubanSubject>[];
constructor(app:App, doubanPlugin:DoubanPlugin) {
this._app = app;
this._doubanPlugin = doubanPlugin;
this._doubanSubjectHandlers = [new DoubanMovieLoadHandler(this._doubanPlugin),
new DoubanOtherLoadHandler(this._doubanPlugin)];
}
public handle(searchExtract:DoubanSubject):void{
if(!searchExtract) {
return;
}
this._doubanSubjectHandlers
.filter(h => h.support)
.forEach(h => h.handle(searchExtract.url));
}
}

@ -3,42 +3,21 @@ import { get, readStream } from "tiny-network";
import { log } from "utils/logutil"; import { log } from "utils/logutil";
import DoubanAbstractLoadHandler from "./DoubanAbstractLoadHandler"; import DoubanAbstractLoadHandler from "./DoubanAbstractLoadHandler";
import cheerio, { CheerioAPI } from 'cheerio'; import cheerio, { CheerioAPI } from 'cheerio';
import { DoubanPluginSettings } from "douban/Douban";
import DoubanPlugin from "main";
export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<DoubanMovieSubject> { export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<DoubanMovieSubject> {
constructor(doubanPlugin:DoubanPlugin) {
super(doubanPlugin);
getSubject(url:string): DoubanMovieSubject {
return this.fetchFromDouban(url);
}
getTextResult(url:string): string {
throw new Error("Method not implemented.");
}
getType(): string {
throw new Error("Method not implemented.");
}
fetchFromDouban(url:string):DoubanMovieSubject {
const reuslt = await this.fetchFromDoubanWeb(url);
return reuslt;
} }
fetchFromDoubanWeb(url:string):Promise<DoubanMovieSubject> { parseSubjectFromHtml(data: CheerioAPI): DoubanMovieSubject {
return Promise return data('.result')
.resolve()
.then(() => get(url, JSON.parse(this.doubanSettings.searchHeaders)))
.then(readStream)
.then(log.info)
.then(cheerio.load)
.then(this.parseMovieSubjectFromHtml);
}
parseMovieSubjectFromHtml(responseHtml:CheerioAPI):DoubanMovieSubject {
return responseHtml('.result')
.get() .get()
.map((i:any) => { .map((i:any) => {
const item = responseHtml(i); const item = data(i);
var idPattern = /(\d){5,10}/g; var idPattern = /(\d){5,10}/g;
var urlPattern = /(https%3A%2F%2F)\S+(\d){5,10}/g; var urlPattern = /(https%3A%2F%2F)\S+(\d){5,10}/g;
var linkValue = item.find("div.content > div > h3 > a").text(); var linkValue = item.find("div.content > div > h3 > a").text();
@ -60,8 +39,13 @@ export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<Do
url: urlResult?decodeURIComponent(urlResult[0]):'https://www.douban.com', url: urlResult?decodeURIComponent(urlResult[0]):'https://www.douban.com',
}; };
return result; return result;
})[0]; })[0];
} }
getType(): string |undefined {
throw new Error("Method not implemented.");
}
} }

@ -1,16 +1,15 @@
import { CheerioAPI } from "cheerio";
import DoubanSubject from "douban/model/DoubanSubject"; import DoubanSubject from "douban/model/DoubanSubject";
import DoubanAbstractLoadHandler from "./DoubanAbstractLoadHandler"; import DoubanAbstractLoadHandler from "./DoubanAbstractLoadHandler";
export default class DoubanOtherLoadHandler extends DoubanAbstractLoadHandler<DoubanSubject> { export default class DoubanOtherLoadHandler extends DoubanAbstractLoadHandler<DoubanSubject> {
getSubject(): DoubanSubject { parseSubjectFromHtml(data: CheerioAPI): DoubanSubject | undefined{
throw new Error("Method not implemented.");
}
getTextResult(): string {
throw new Error("Method not implemented.");
}
getType(): string {
return undefined; return undefined;
} }
getType(): string | undefined{
return undefined
}

@ -2,12 +2,11 @@ import DoubanSubject from "douban/model/DoubanSubject";
export default interface DoubanSubjectLoadHandler<T extends DoubanSubject> { export default interface DoubanSubjectLoadHandler<T extends DoubanSubject> {
getType():string; getType():string | undefined;
support(extract:DoubanSubject):boolean; support(extract:DoubanSubject):boolean;
getSubject(url:string):T; handle(url:string):void;
getTextResult(url:string):string;
} }

@ -1,54 +0,0 @@
import cheerio from 'cheerio';
import { DoubanExtract, doubanHeadrs } from 'douban/Douban';
import { get, readStream } from 'tiny-network';
import { ensureStatusCode } from 'douban/ResponseHandle';
interface DoubanMovieExtract extends DoubanExtract {
}
export const playing = (city:string) => {
return Promise
.resolve()
.then(() => get(`https://movie.douban.com/cinema/nowplaying/${city}/`))
.then(ensureStatusCode(200))
.then(readStream)
.then(cheerio.load)
.then(parsePlaying)
};
export const parsePlaying = (dataHtml:any) => {
return dataHtml('.list-item')
.get()
.map((i:any) => {
const item = dataHtml(i);
console.log("version 5");
const result = {
id: item.attr('id'),
title: item.attr('data-title'),
score: item.attr('data-score'),
duration: item.attr('data-duration'),
region: item.attr('data-region'),
director: item.attr('data-director'),
actors: item.attr('data-actors'),
poster: item.find('.poster img').attr('src'),
link: `https://movie.douban.com/subject/${item.attr('id')}`,
};
// console.log("content is " + JSON.stringify(result));
return result;
})
};

@ -1,17 +1,17 @@
import DoubanSearchResultSubject from "douban/model/DoubanSearchResultSubject";
import DoubanPlugin from "main"; import DoubanPlugin from "main";
import { FuzzySuggestModal,App } from "obsidian"; import { FuzzySuggestModal,App } from "obsidian";
import { log } from "utils/logutil"; import { log } from "utils/logutil";
import { DoubanSearchResultExtract } from "./SearchParser";
export {DoubanFuzzySuggester} export {DoubanFuzzySuggester}
class DoubanFuzzySuggester extends FuzzySuggestModal<DoubanSearchResultExtract> { class DoubanFuzzySuggester extends FuzzySuggestModal<DoubanSearchResultSubject> {
public app: App; public app: App;
private plugin: DoubanPlugin; private plugin: DoubanPlugin;
private doubanSearchResultExtract:DoubanSearchResultExtract[] private doubanSearchResultExtract:DoubanSearchResultSubject[]
constructor(app: App, plugin: DoubanPlugin) { constructor(app: App, plugin: DoubanPlugin) {
super(app); super(app);
@ -35,20 +35,20 @@ class DoubanFuzzySuggester extends FuzzySuggestModal<DoubanSearchResultExtract>
} }
} }
getItems(): DoubanSearchResultExtract[] { getItems(): DoubanSearchResultSubject[] {
return this.doubanSearchResultExtract; return this.doubanSearchResultExtract;
} }
getItemText(item: DoubanSearchResultExtract): string { getItemText(item: DoubanSearchResultSubject): string {
let text:string = item.type + "/" + item.score + "/" + item.title + "/" + item.cast; let text:string = item.type + "/" + item.score + "/" + item.title + "/" + item.cast;
return text; return text;
} }
onChooseItem(item: DoubanSearchResultExtract, evt: MouseEvent | KeyboardEvent): void { onChooseItem(item: DoubanSearchResultSubject, evt: MouseEvent | KeyboardEvent): void {
this.plugin.geDoubanMovieTextForSearchTerm this.plugin.doubanEtractHandler.handle(item);
} }
public showSearchList(doubanSearchResultExtractList:DoubanSearchResultExtract[]) { public showSearchList(doubanSearchResultExtractList:DoubanSearchResultSubject[]) {
this.doubanSearchResultExtract = doubanSearchResultExtractList; this.doubanSearchResultExtract = doubanSearchResultExtractList;
log.info("show search result" ); log.info("show search result" );
this.start(); this.start();