mirror of
https://github.com/Wanxp/obsidian-douban.git
synced 2026-04-04 16:48:44 +08:00
add douban subject
This commit is contained in:
parent
143c004c6e
commit
f4bda2c9d0
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
31
douban/handler/DoubanExtractHandler.ts
Normal file
31
douban/handler/DoubanExtractHandler.ts
Normal file
@ -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 {
|
parseSubjectFromHtml(data: CheerioAPI): DoubanMovieSubject {
|
||||||
const reuslt = await this.fetchFromDoubanWeb(url);
|
return data('.result')
|
||||||
return reuslt;
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchFromDoubanWeb(url:string):Promise<DoubanMovieSubject> {
|
|
||||||
return Promise
|
|
||||||
.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();
|
||||||
@ -63,5 +42,10 @@ export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<Do
|
|||||||
})[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();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user