fix search error

This commit is contained in:
HughWan 2023-12-18 23:28:14 +08:00
parent 7bd4b6b96f
commit 96fe6d6771
26 changed files with 467 additions and 52 deletions

@ -35,7 +35,7 @@ esbuild.build({
'@codemirror/panel',
'@codemirror/rangeset',
'@codemirror/rectangular-selection',
'@codemirror/search',
'@codemirror/searcher',
'@codemirror/state',
'@codemirror/stream-parser',
'@codemirror/text',

34
package-lock.json generated

@ -1,18 +1,19 @@
{
"name": "obsidian-douban-plugin",
"version": "1.9.3",
"version": "1.9.6",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "obsidian-douban-plugin",
"version": "1.9.3",
"version": "1.9.6",
"license": "MIT",
"dependencies": {
"@notable/html2markdown": "^1.1.3",
"@popperjs/core": "^2.11.6",
"cheerio": "^1.0.0-rc.11",
"follow-redirects": "^1.15.3",
"iconv-lite": "^0.6.3",
"schema-dts": "^1.1.0"
},
"devDependencies": {
@ -3290,6 +3291,17 @@
"node": ">=10.17.0"
}
},
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/ignore": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
@ -4872,6 +4884,11 @@
"queue-microtask": "^1.2.2"
}
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/schema-dts": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/schema-dts/-/schema-dts-1.1.0.tgz",
@ -7844,6 +7861,14 @@
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
"dev": true
},
"iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"requires": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
}
},
"ignore": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
@ -9020,6 +9045,11 @@
"queue-microtask": "^1.2.2"
}
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"schema-dts": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/schema-dts/-/schema-dts-1.1.0.tgz",

@ -54,6 +54,7 @@ export const ESTIMATE_TIME_PER_WITH_REQUEST_SLOW: number = ESTIMATE_TIME_PER + B
*/
export const ESTIMATE_TIME_PER_WITH_REQUEST: number = ESTIMATE_TIME_PER + BasicConst.CALL_DOUBAN_DELAY + BasicConst.CALL_DOUBAN_DELAY_RANGE / 2;
/**
*
*/
@ -176,6 +177,20 @@ export enum PropertyName {
content = "content",
}
/**
*
*/
export const SearchTypeRecords: { [key in SupportType]: string } = {
[SupportType.ALL]: i18nHelper.getMessage('ALL'),
[SupportType.MOVIE]: i18nHelper.getMessage('MOVIE_AND_TELEPLAY'),
[SupportType.BOOK]: i18nHelper.getMessage('BOOK'),
[SupportType.MUSIC]: i18nHelper.getMessage('MUSIC'),
[SupportType.NOTE]: i18nHelper.getMessage('NOTE'),
[SupportType.GAME]: i18nHelper.getMessage('GAME'),
[SupportType.TELEPLAY]: i18nHelper.getMessage('TELEPLAY'),
[SupportType.THEATER]: i18nHelper.getMessage('THEATER'),
}
/**
*
*/
@ -296,7 +311,7 @@ export const DoubanSearchResultSubjectNextPageNeedLogin: DoubanSearchResultSubje
url: NavigateType.nextNeedLogin
}
export const SEARCH_ITEM_PAGE_SIZE: number = 20;
export const SEARCH_ITEM_PAGE_SIZE: number = 10;
/**
*

@ -1,16 +1,21 @@
import {SearchPageInfo} from "./SearchPageInfo";
import {SupportType} from "../../../constant/Constsant";
export class SearchPage extends SearchPageInfo{
private _list:any[];
constructor(total: number, pageNum: number, pageSize: number, list: any[]) {
super(total, pageNum, pageSize);
constructor(total: number, pageNum: number, pageSize: number, type:SupportType, list: any[]) {
super(total, pageNum, pageSize, type);
this._list = list;
}
public get list() {
return this._list;
}
public static empty(type:SupportType):SearchPage {
return new SearchPage(0, 0, 0, type, []);
}
}

@ -1,15 +1,19 @@
import {SupportType} from "../../../constant/Constsant";
export class SearchPageInfo {
private _total: number;
private _pageSize: number;
private _pageNum: number;
private _hasNext: boolean;
private _type: SupportType;
constructor(total: number, pageNum: number, pageSize: number) {
constructor(total: number, pageNum: number, pageSize: number, type: SupportType) {
this._total = total;
this._pageNum = pageNum;
this._pageSize = pageSize;
this._hasNext = ((pageNum + 1) * pageSize) < total;
this._type = type;
}
public nextPage(): SearchPageInfo {
@ -17,7 +21,7 @@ export class SearchPageInfo {
return this;
}
return new SearchPageInfo(this.total, this._pageNum + 1,
this._pageSize);
this._pageSize, this._type);
}
public previousPage(): SearchPageInfo {
@ -25,7 +29,12 @@ export class SearchPageInfo {
return this;
}
return new SearchPageInfo(this.total, this._pageNum - 1,
this._pageSize);
this._pageSize, this._type);
}
public typePage(type: SupportType): SearchPageInfo {
return new SearchPageInfo(this.total, 0,
this._pageSize, this._type);
}
@ -53,4 +62,18 @@ export class SearchPageInfo {
get pageNum(): number {
return this._pageNum;
}
get type(): SupportType {
return this._type;
}
allPage() {
if (this._pageNum == 0) {
return this;
}
return new SearchPageInfo(this.total, this._pageNum - 1,
this._pageSize, SupportType.ALL);
}
}

@ -2,7 +2,7 @@ import {
DoubanSearchResultSubjectNextPage,
DoubanSearchResultSubjectNextPageNeedLogin,
DoubanSearchResultSubjectPreviousPage,
NavigateType
NavigateType, SEARCH_ITEM_PAGE_SIZE, SupportType
} from "../../../constant/Constsant";
import {FuzzySuggestModal, RequestUrlParam, request} from "obsidian";
@ -11,13 +11,9 @@ import DoubanSearchResultSubject from "../model/DoubanSearchResultSubject";
import HandleContext from "../model/HandleContext";
import {SearchPage} from "../model/SearchPage";
import {SearchPageInfo} from "../model/SearchPageInfo";
import Searcher from "./Search";
import User from "../../user/User";
import {flat} from "builtin-modules";
import {i18nHelper} from "../../../lang/helper";
import {init} from "cjs-module-lexer";
import {load} from "cheerio";
import {log} from "src/org/wanxp/utils/Logutil";
import SearcherV2 from "./SearchV2";
export {DoubanFuzzySuggester}
@ -61,6 +57,12 @@ class DoubanFuzzySuggester extends FuzzySuggestModal<DoubanSearchResultSubject>
}
return;
}
if(this.isTypeSelect(item)) {
if (await this.handleTypeSelect(item)) {
this.start();
}
return;
}
this.plugin.showStatus(i18nHelper.getMessage('140204', item.title));
this.context.listItem = item;
if (item) {
@ -87,29 +89,28 @@ class DoubanFuzzySuggester extends FuzzySuggestModal<DoubanSearchResultSubject>
break;
}
if (result) {
const searchPageResult: SearchPage =
await Searcher.loadSearchItem(this.searchItem, currentPage.start, this.plugin.settings, this.plugin.settingsManager);
this.context.searchPage = new SearchPageInfo(searchPageResult.total, currentPage.pageNum, searchPageResult.pageSize);
this.updatePageResult(searchPageResult);
// const searchPageResult: SearchPage =
// await SearcherV2.loadSearchItem(this.searchItem, currentPage.start, SEARCH_ITEM_PAGE_SIZE, this.plugin.settings, this.plugin.settingsManager);
// this.context.searchPage = new SearchPageInfo(searchPageResult.total, currentPage.pageNum, searchPageResult.pageSize, item.type);
// this.updatePageResult(searchPageResult);
}
return result;
}
private updatePageResult(searchPageResult: SearchPage) {
this.initItems(searchPageResult.list);
this.initItems(searchPageResult);
}
public showSearchList(doubanSearchResultExtractList: DoubanSearchResultSubject[]) {
this.initItems(doubanSearchResultExtractList);
public showSearchPage(searchPage: SearchPage) {
this.initItems(searchPage);
this.start();
}
private initItems(doubanSearchResultExtractList: DoubanSearchResultSubject[]) {
let doubanList: DoubanSearchResultSubject[] = doubanSearchResultExtractList;
const {searchPage} = this.context;
private initItems(searchPage: SearchPage) {
const doubanList: DoubanSearchResultSubject[] = searchPage.list;
if (searchPage.hasNext) {
if (this.plugin.userComponent.isLogin()) {
doubanList.push(DoubanSearchResultSubjectNextPage)
@ -117,6 +118,7 @@ class DoubanFuzzySuggester extends FuzzySuggestModal<DoubanSearchResultSubject>
doubanList.push(DoubanSearchResultSubjectNextPageNeedLogin)
}
}
this.initTypeSelect(doubanList, searchPage);
if (searchPage.hasPrevious) {
doubanList.unshift(DoubanSearchResultSubjectPreviousPage);
}
@ -124,6 +126,12 @@ class DoubanFuzzySuggester extends FuzzySuggestModal<DoubanSearchResultSubject>
}
private initTypeSelect(doubanList: DoubanSearchResultSubject[], searchPage: SearchPage) {
if (SupportType.ALL == searchPage.type) {
}
}
public start(): void {
try {
this.open();
@ -132,4 +140,29 @@ class DoubanFuzzySuggester extends FuzzySuggestModal<DoubanSearchResultSubject>
}
}
private isTypeSelect(item: DoubanSearchResultSubject) {
return item.type == "type";
}
private async handleTypeSelect(item: DoubanSearchResultSubject) {
const {searchPage} = this.context;
let currentPage:SearchPageInfo = searchPage;
let result:boolean = false;
switch (item.url) {
case SupportType.ALL:
currentPage = searchPage.previousPage();
result = true;
break;
case NavigateType.next:
currentPage = searchPage.nextPage();
result = true;
break;
case NavigateType.nextNeedLogin:
log.warn(i18nHelper.getMessage("140304"));
break;
}
if (result) {
}
return result;
}
}

@ -1,11 +1,13 @@
import {App, Modal, TextComponent} from "obsidian";
import {App, DropdownComponent, Modal, TextComponent} from "obsidian";
import DoubanPlugin from "../../../main";
import {i18nHelper} from "src/org/wanxp/lang/helper";
import HandleContext from "../model/HandleContext";
import {SearchTypeRecords, SupportType} from "../../../constant/Constsant";
export class DoubanSearchModal extends Modal {
searchTerm: string;
searchType: SupportType = SupportType.ALL;
plugin: DoubanPlugin;
context: HandleContext
@ -19,14 +21,25 @@ export class DoubanSearchModal extends Modal {
let {contentEl} = this;
contentEl.createEl("h3", {text: i18nHelper.getMessage('110003')});
const content = contentEl.createDiv("content");
const inputs = contentEl.createDiv("inputs");
const typeSelect = content.createDiv("type-select");
const typeSelectInput = new DropdownComponent(typeSelect)
.addOptions(SearchTypeRecords)
.setValue(SupportType.ALL)
.onChange((value:SupportType) => {
this.searchType = value;
});
typeSelect.addClass('obsidian_douban_search_input');
const inputs = content.createDiv("inputs");
const searchInput = new TextComponent(inputs).onChange((searchTerm) => {
this.searchTerm = searchTerm;
});
searchInput.inputEl.addClass("obsidian_douban_search_input");
inputs.addClass("obsidian_douban_search_input");
searchInput.inputEl.size = 40;
searchInput.inputEl.focus();
searchInput.inputEl.addEventListener("keydown", (event) => {
if (event.key === "Enter") {
this.close();
@ -34,6 +47,9 @@ export class DoubanSearchModal extends Modal {
});
const controls = contentEl.createDiv("controls");
const searchButton = controls.createEl("button", {
text: i18nHelper.getMessage('110004'),
@ -48,6 +64,7 @@ export class DoubanSearchModal extends Modal {
const cancelButton = controls.createEl("button", {text: i18nHelper.getMessage('110005')});
cancelButton.addEventListener("click", this.close.bind(this));
cancelButton.addClass("obsidian_douban_search_button");
searchInput.inputEl.focus();
}
@ -56,7 +73,7 @@ export class DoubanSearchModal extends Modal {
let {contentEl} = this;
contentEl.empty();
if (this.searchTerm) {
await this.plugin.search(this.searchTerm, this.context);
await this.plugin.search(this.searchTerm, this.searchType, this.context);
}
}

@ -11,9 +11,10 @@ import {i18nHelper} from "../../../lang/helper";
import {load} from 'cheerio';
import {log} from 'src/org/wanxp/utils/Logutil';
import HttpUtil from "../../../utils/HttpUtil";
import {SupportType} from "../../../constant/Constsant";
export default class Searcher {
static search(searchItem: string, doubanSettings: DoubanPluginSetting, settingsManager:SettingsManager): Promise<DoubanSearchResultSubject[]> {
static search(searchItem: string, type:SupportType, doubanSettings: DoubanPluginSetting, settingsManager:SettingsManager): Promise<DoubanSearchResultSubject[]> {
return HttpUtil.httpRequestGet(DEFAULT_SETTINGS.searchUrl + searchItem, settingsManager.getHeaders(), settingsManager)
.then(load)
.then(SearchParserHandler.parseSearch)
@ -23,11 +24,11 @@ export default class Searcher {
};
static loadSearchItem(searchItem: string, start:number, doubanSettings: DoubanPluginSetting, settingsManager:SettingsManager): Promise<SearchPage> {
static loadSearchItem(searchItem: string, type:SupportType, start:number, doubanSettings: DoubanPluginSetting, settingsManager:SettingsManager): Promise<SearchPage> {
const url:string = `https://www.douban.com/j/search?q=${searchItem}&start=${start}&subtype=item`;
log.debug(`请求更多页面:${url}`);
return HttpUtil.httpRequestGet(url, settingsManager.getHeaders(), settingsManager)
.then(e=>SearchParserHandler.parseSearchJson(e, start))
.then(e=>SearchParserHandler.parseSearchJson(e, type, start))
.catch(e => {
throw log.error(i18nHelper.getMessage('130101').replace('{0}', e.toString()), e);
});

@ -1,7 +1,7 @@
import {CheerioAPI, load} from "cheerio";
import DoubanSearchResultSubject from "../model/DoubanSearchResultSubject";
import {SearchPage} from "../model/SearchPage";
import {SEARCH_ITEM_PAGE_SIZE} from "../../../constant/Constsant";
import {SEARCH_ITEM_PAGE_SIZE, SupportType} from "../../../constant/Constsant";
import {log} from "../../../utils/Logutil";
export default class SearchParserHandler {
@ -38,7 +38,7 @@ export default class SearchParserHandler {
})
};
static parseSearchJson(result: string, start:number): SearchPage {
static parseSearchJson(result: string, type:SupportType, start:number): SearchPage {
log.debug("解析给多页面结果");
const data:{total:number, limit:number, more:boolean, items:string[]} = JSON.parse(result);
const list:string[] = data.items;
@ -46,7 +46,7 @@ export default class SearchParserHandler {
.map(e => load(e))
.map(e=>this.parseSearch(e))
.map(e => e? e[0]:null);
return new SearchPage(data.total, start / data.limit, data.limit, resultList);
return new SearchPage(data.total, start / data.limit, data.limit, type, resultList);
};
}

@ -0,0 +1,29 @@
import DoubanSearchResultSubject from "../model/DoubanSearchResultSubject";
export default class SearchParserHandlerV2 {
static itemMapToSearchResult(items:any):DoubanSearchResultSubject[] {
if (!items) {
return [];
}
return items.map((i: any) => {
const target:any = i.target;
const result: DoubanSearchResultSubject = {
id: target.id ??'',
title: target.title ?? '-',
score: target.rating && target.rating.value ? Number(target.rating.value) : null,
cast: target.card_subtitle?? '',
type: i.type_name ?? '-',
desc: '-',
url: target.uri? (target.uri.replaceAll('douban://', 'https://')) : 'https://www.douban.com',
image: "",
imageUrl: "",
publisher: "",
datePublished: undefined,
genre: []
};
return result;
})
}
}

@ -0,0 +1,17 @@
import {DoubanPluginSetting} from "../../setting/model/DoubanPluginSetting";
import {SearchPage} from "../model/SearchPage";
import SettingsManager from "../../setting/SettingsManager";
import {SupportType} from "../../../constant/Constsant";
import {SearchPageFetcher} from "./searcher/SearchPageFetcher";
import {SearchResultPageParser} from "./parser/SearchResultPageParser";
export default class SearcherV2 {
static search(searchItem: string, searchType: SupportType, pageNum:number, pageSize:number, doubanSettings: DoubanPluginSetting, settingsManager:SettingsManager): Promise<SearchPage> {
return new SearchPageFetcher(settingsManager)
.fetch(searchItem, searchType, pageNum, pageSize)
.then(e => new SearchResultPageParser()
.parse(e, searchType, pageNum, pageSize));
}
}

@ -0,0 +1,24 @@
import {SupportType} from "../../../../constant/Constsant";
import {SearchResultPageParserInterface} from "./SearchResultPageParserInterface";
import {SearchPage} from "../../model/SearchPage";
import SearchParserHandlerV2 from "../SearchParserV2";
export class FistAllPageSearchResultPageParser implements SearchResultPageParserInterface {
support(type:SupportType, pageNum:number):boolean {
return pageNum == 1 && type == SupportType.ALL;
}
parse(source:string, type:SupportType, pageNum:number, pageSize:number):SearchPage {
const {subjects} = JSON.parse(source);
if (!subjects) {
return SearchPage.empty(type);
}
const {items} = subjects;
if (!items ||items.length == 0) {
return SearchPage.empty(type);
}
const doubanSearchResultSubjects = SearchParserHandlerV2.itemMapToSearchResult(items);
return new SearchPage(items.length, pageNum, pageSize, type, doubanSearchResultSubjects);
}
}

@ -0,0 +1,22 @@
import {SupportType} from "../../../../constant/Constsant";
import {SearchResultPageParserInterface} from "./SearchResultPageParserInterface";
import {log} from "../../../../utils/Logutil";
import {SearchPage} from "../../model/SearchPage";
import SearchParserHandlerV2 from "../SearchParserV2";
export class OtherAllPageSearchResultPageParser implements SearchResultPageParserInterface {
support(type:SupportType, pageNum:number):boolean {
return pageNum > 1 && type == SupportType.ALL;
}
parse(source:string, type:SupportType, pageNum:number, pageSize:number):SearchPage {
log.debug("解析给多页面结果");
const {contents} = JSON.parse(source);
if (!contents) {
return new SearchPage(0, 0, 0, type, []);
}
const data:{total:number, start:number, count:number, items:any[]} = contents;
const doubanSearchResultSubjects = SearchParserHandlerV2.itemMapToSearchResult(data.items);
return new SearchPage(data.total, pageNum, pageSize, type, doubanSearchResultSubjects);
}
}

@ -0,0 +1,25 @@
import {SearchResultPageParserInterface} from "./SearchResultPageParserInterface";
import {FistAllPageSearchResultPageParser} from "./FistAllPageSearchResultPageParser";
import {OtherAllPageSearchResultPageParser} from "./OtherAllPageSearchResultPageParser";
import {SearchPage} from "../../model/SearchPage";
import {SupportType} from "../../../../constant/Constsant";
export class SearchResultPageParser {
private parsers:SearchResultPageParserInterface[] = [];
constructor() {
this.parsers.push(new FistAllPageSearchResultPageParser());
this.parsers.push(new OtherAllPageSearchResultPageParser());
}
public parse(source:string, type:SupportType, pageNum:number, pageSize:number):SearchPage {
for (const parser of this.parsers) {
if (parser.support(type, pageNum)) {
return parser.parse(source, type, pageNum, pageSize);
}
}
throw new Error(`not support type:${type} pageNum:${pageNum}`);
}
}

@ -0,0 +1,9 @@
import {SearchPage} from "../../model/SearchPage";
import {SupportType} from "../../../../constant/Constsant";
import DoubanSearchResultSubject from "../../model/DoubanSearchResultSubject";
export interface SearchResultPageParserInterface {
support(type:SupportType, pageNum:number):boolean;
parse(source:string, type:SupportType, pageNum:number, pageSize:number):SearchPage;
}

@ -0,0 +1,32 @@
import { SupportType } from "src/org/wanxp/constant/Constsant";
import SettingsManager from "../../../setting/SettingsManager";
import {SearchPageFetcherInterface} from "./SearchPageFetcherInterface";
import HttpUtil from "../../../../utils/HttpUtil";
import {log} from "../../../../utils/Logutil";
import {i18nHelper} from "../../../../lang/helper";
export abstract class AbstractSearchPageFetcher implements SearchPageFetcherInterface {
protected settingsManager: SettingsManager;
constructor(settingsManager: SettingsManager) {
this.settingsManager = settingsManager;
}
support(type: SupportType): boolean {
throw new Error("Method not implemented.");
}
fetch(keyword: string, pageNum: number, pageSize: number): Promise<string> {
const url:string = this.getUrl(keyword, pageNum, pageSize);
if (!url) {
return Promise.resolve("");
}
return HttpUtil.httpRequestGet(url, this.settingsManager.getHeaders(), this.settingsManager)
.catch(e => {
throw log.error(i18nHelper.getMessage('130101').replace('{0}', e.toString()), e);
}); }
abstract getUrl(keyword: string, pageNum: number, pageSize: number):string;
}

@ -0,0 +1,13 @@
import {AbstractSearchPageFetcher} from "./AbstractSearchPageFetcher";
import { SupportType } from "src/org/wanxp/constant/Constsant";
export class BookPageSearchPageFetcher extends AbstractSearchPageFetcher {
getUrl(keyword: string, pageNum: number, pageSize: number): string {
return `https://www.douban.com/j/search?q=${keyword}&start=${pageNum * pageSize}&cat=1001`;
}
support(type: SupportType): boolean {
return type == SupportType.MOVIE;
}
}

@ -0,0 +1,13 @@
import {AbstractSearchPageFetcher} from "./AbstractSearchPageFetcher";
import { SupportType } from "src/org/wanxp/constant/Constsant";
export class FistAllPageSearchPageFetcher extends AbstractSearchPageFetcher {
getUrl(keyword: string, pageNum: number, pageSize: number): string {
return `https://m.douban.com/rexxar/api/v2/search?q=${keyword}&start=${pageNum}&count=${pageSize}`;
}
support(type: SupportType): boolean {
return type == SupportType.ALL;
}
}

@ -0,0 +1,13 @@
import {AbstractSearchPageFetcher} from "./AbstractSearchPageFetcher";
import { SupportType } from "src/org/wanxp/constant/Constsant";
export class MoviePageSearchPageFetcher extends AbstractSearchPageFetcher {
getUrl(keyword: string, pageNum: number, pageSize: number): string {
return `https://www.douban.com/j/search?q=${keyword}&start=${pageNum * pageSize}&cat=1002`;
}
support(type: SupportType): boolean {
return type == SupportType.MOVIE;
}
}

@ -0,0 +1,28 @@
import {SearchPageFetcherInterface} from "./SearchPageFetcherInterface";
import {FistAllPageSearchPageFetcher} from "./FistAllPageSearchPageFetcher";
import SettingsManager from "../../../setting/SettingsManager";
import {SupportType} from "../../../../constant/Constsant";
import {MoviePageSearchPageFetcher} from "./MoviePageSearchPageFetcher";
import {BookPageSearchPageFetcher} from "./BookPageSearchPageFetcher";
export class SearchPageFetcher {
private fetchers:SearchPageFetcherInterface[] = [];
constructor(settingsManager:SettingsManager) {
this.fetchers.push(new FistAllPageSearchPageFetcher(settingsManager));
this.fetchers.push(new MoviePageSearchPageFetcher(settingsManager));
this.fetchers.push(new BookPageSearchPageFetcher(settingsManager))
}
fetch(keyword:string, type:SupportType, pageNum:number, pageSize:number):Promise<string> {
for (const fetcher of this.fetchers) {
if (fetcher.support(type)) {
return fetcher.fetch(keyword, pageNum, pageSize);
}
}
throw new Error(`not support type:${type} pageNum:${pageNum}`);
}
}

@ -0,0 +1,9 @@
import {SupportType} from "../../../../constant/Constsant";
export interface SearchPageFetcherInterface {
support(type:SupportType):boolean;
fetch(keyword:string, pageNum:number, pageSize:number):Promise<string>;
}

@ -1,13 +1,13 @@
//简体中文
export default {
//main.ts
'110001': 'search douban by current file name',
'110002': 'search douban and import to current file',
'110001': 'searcher douban by current file name',
'110002': 'searcher douban and import to current file',
'110003': `Enter Search Term:`,
'110004': `Search`,
'110005': `Cancel`,
'110006': `sync douban personal book-movie-music to Obsidian`,
'110101': 'search douban and create file',
'110101': 'searcher douban and create file',
'110201': `{0} already exists`,
'110202': `{0} template can not read`,
'110103': 'sync personal data from douban',
@ -557,6 +557,10 @@ PS: This file could be delete if you want to.
'NOTE': `note`,
'GAME': `game`,
'TELEPLAY': `teleplay`,
'THEATER': `theater`,
'MOVIE_AND_TELEPLAY': `movie&teleplay`,
'DAY': `D`,
'HOUR': `H`,

@ -562,6 +562,9 @@ export default {
'NOTE': `笔记`,
'GAME': `游戏`,
'TELEPLAY': `电视剧`,
'THEATER': `戏剧`,
'MOVIE_AND_TELEPLAY': `影视剧`,
'DAY': ``,
'HOUR': ``,

@ -1,4 +1,12 @@
import {Action, BasicConst, SearchHandleMode, SubjectHandledStatus, SyncTypeRecords} from "./constant/Constsant";
import {
Action,
BasicConst,
SEARCH_ITEM_PAGE_SIZE,
SearchHandleMode,
SubjectHandledStatus,
SupportType,
SyncTypeRecords
} from "./constant/Constsant";
import {Editor, Notice, Plugin} from "obsidian";
import {DEFAULT_SETTINGS} from "./constant/DefaultSettings";
@ -6,7 +14,6 @@ import {DoubanFuzzySuggester} from "./douban/data/search/DoubanSearchFuzzySugges
import {DoubanPluginSetting} from "./douban/setting/model/DoubanPluginSetting";
import {DoubanSearchChooseItemHandler} from "./douban/data/handler/DoubanSearchChooseItemHandler";
import {DoubanSearchModal} from "./douban/data/search/DoubanSearchModal";
import DoubanSearchResultSubject from "./douban/data/model/DoubanSearchResultSubject";
import {DoubanSettingTab} from "./douban/setting/DoubanSettingTab";
import DoubanSubject from "./douban/data/model/DoubanSubject";
import {DoubanSyncModal} from "./douban/component/DoubanSyncModal";
@ -16,8 +23,6 @@ import GlobalStatusHolder from "./douban/model/GlobalStatusHolder";
import HandleContext from "./douban/data/model/HandleContext";
import HandleResult from "./douban/data/model/HandleResult";
import NetFileHandler from "./net/NetFileHandler";
import {SearchPageInfo} from "./douban/data/model/SearchPageInfo";
import Searcher from "./douban/data/search/Search";
import SettingsManager from "./douban/setting/SettingsManager";
import {SyncConfig} from "./douban/sync/model/SyncConfig";
import SyncHandler from "./douban/sync/handler/SyncHandler";
@ -26,6 +31,8 @@ import {i18nHelper} from './lang/helper';
import {log} from "src/org/wanxp/utils/Logutil";
import GithubUtil from "./utils/GithubUtil";
import {DoubanPluginOnlineData} from "./douban/setting/model/DoubanPluginOnlineData";
import SearcherV2 from "./douban/data/search/SearchV2";
import {SearchPage} from "./douban/data/model/SearchPage";
export default class DoubanPlugin extends Plugin {
public settings: DoubanPluginSetting;
@ -119,13 +126,13 @@ export default class DoubanPlugin extends Plugin {
}
}
async search(searchTerm: string, context: HandleContext) {
async search(searchTerm: string, searchType: SupportType, context: HandleContext) {
try {
this.showStatus(i18nHelper.getMessage('140201', searchTerm));
const resultList:DoubanSearchResultSubject[] = await Searcher.search(searchTerm, this.settings, context.plugin.settingsManager);
this.showStatus(i18nHelper.getMessage('140202', resultList.length.toString()));
context.searchPage = new SearchPageInfo(21,-1,20);
new DoubanFuzzySuggester(this, context, searchTerm).showSearchList(resultList);
const result:SearchPage = await SearcherV2.search(searchTerm, searchType, 1, SEARCH_ITEM_PAGE_SIZE, this.settings, context.plugin.settingsManager);
this.showStatus(i18nHelper.getMessage('140202', result.list.toString()));
context.searchPage = result;
new DoubanFuzzySuggester(this, context, searchTerm).showSearchPage(result);
} catch (e) {
log.error(i18nHelper.getMessage('140206').replace('{0}', e.message), e);
} finally {
@ -138,7 +145,7 @@ export default class DoubanPlugin extends Plugin {
if (activeFile) {
const searchTerm = activeFile.basename;
if (searchTerm) {
await this.search(searchTerm, context);
await this.search(searchTerm, SupportType.ALL, context);
}
}
}
@ -162,7 +169,7 @@ export default class DoubanPlugin extends Plugin {
}
this.addCommand({
id: "search-douban-import-and-create-file",
id: "searcher-douban-import-and-create-file",
name: i18nHelper.getMessage("110101"),
callback: () =>
this.getDoubanTextForCreateNewNote({plugin: this,
@ -175,7 +182,7 @@ export default class DoubanPlugin extends Plugin {
});
this.addCommand({
id: "search-douban-and-input-current-file",
id: "searcher-douban-and-input-current-file",
name: i18nHelper.getMessage("110002"),
editorCallback: (editor: Editor) =>
this.getDoubanTextForSearchTerm({plugin: this,
@ -188,7 +195,7 @@ export default class DoubanPlugin extends Plugin {
});
this.addCommand({
id: "search-douban-by-current-file-name",
id: "searcher-douban-by-current-file-name",
name: i18nHelper.getMessage("110001"),
editorCallback: (editor: Editor) =>
this.getDoubanTextForActiveFile({plugin: this,

@ -19,6 +19,7 @@ export default class HttpUtil {
*/
// Cookie: 'll="108296"; bid=xHRJLeWBrjQ; _pk_id.100001.8cb4=f8f83e81ec224a1a.1691572669.; __utmv=30149280.13103; __yadk_uid=ce95W7OsgT0iKFceWgbMSUdw1oOqxNTk; __gads=ID=62585f60f3f637d0-2234f63fc6e200a5:T=1691572672:RT=1691572672:S=ALNI_MaIqTxSWHsfpnX9nAmMHcPQEsaezg; __gpi=UID=00000c29a9f98e5b:T=1691572672:RT=1691572672:S=ALNI_MbLAq8XNoKrRPKNqGCMdgXSPZvidw; ap_v=0,6.0; __utma=30149280.135860784.1691572641.1691572641.1694509646.2; __utmc=30149280; __utmz=30149280.1694509646.2.2.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; _pk_ref.100001.8cb4=%5B%22%22%2C%22%22%2C1694509648%2C%22https%3A%2F%2Fmovie.douban.com%2Ftv%2F%22%5D; _pk_ses.100001.8cb4=1; __utmt=1; dbcl2="131038721:LUssju34QFw"; ck=dCQj; push_noty_num=0; push_doumail_num=0; __utmb=30149280.3.10.1694509646'
public static httpRequestGet(url: string, headers: any, settingsManager?: SettingsManager): Promise<string> {
settingsManager.debug(`请求地址:${url}`);
const {['Accept-Encoding']: acceptEncoding, ...headersInner} = headers;
let options = {
headers: headersInner
@ -48,6 +49,43 @@ export default class HttpUtil {
})
}
/**
* get请求
* @param url
* @param headers
* @param settingsManager
*/
// Cookie: 'll="108296"; bid=xHRJLeWBrjQ; _pk_id.100001.8cb4=f8f83e81ec224a1a.1691572669.; __utmv=30149280.13103; __yadk_uid=ce95W7OsgT0iKFceWgbMSUdw1oOqxNTk; __gads=ID=62585f60f3f637d0-2234f63fc6e200a5:T=1691572672:RT=1691572672:S=ALNI_MaIqTxSWHsfpnX9nAmMHcPQEsaezg; __gpi=UID=00000c29a9f98e5b:T=1691572672:RT=1691572672:S=ALNI_MbLAq8XNoKrRPKNqGCMdgXSPZvidw; ap_v=0,6.0; __utma=30149280.135860784.1691572641.1691572641.1694509646.2; __utmc=30149280; __utmz=30149280.1694509646.2.2.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; _pk_ref.100001.8cb4=%5B%22%22%2C%22%22%2C1694509648%2C%22https%3A%2F%2Fmovie.douban.com%2Ftv%2F%22%5D; _pk_ses.100001.8cb4=1; __utmt=1; dbcl2="131038721:LUssju34QFw"; ck=dCQj; push_noty_num=0; push_doumail_num=0; __utmb=30149280.3.10.1694509646'
public static httpRequestGetJson(url: string, headers: any, settingsManager?: SettingsManager): Promise<any> {
const {['Accept-Encoding']: acceptEncoding, ...headersInner} = headers;
let options = {
headers: headersInner
}
settingsManager.debug(`Obsidian-Douban:从网络获取json开始:\nurl:${url}\nheaders:${JSON.stringify(headers)}`);
return new Promise((resolve, rejects) => {
https.get(url, { ...options }, function (response: any) {
let chunks: any = [],
size = 0;
if (response.status == 403) {
rejects(new Error(i18nHelper.getMessage('130106')));
}
response.on("data", function (chunk: any) {
chunks.push(chunk)
size += chunk.length
})
response.on("end", function () {
let data = Buffer.concat(chunks, size)
let html = data.toString()
if (settingsManager) {
settingsManager.debug(`Obsidian-Douban:从网络获取网页完成:\nhtml:\n${html}`);
}
resolve(html)
})
})
})
}
/**
* get请求
* @param url

@ -34,6 +34,11 @@
}
.obsidian_douban_search_input {
margin-left: 5px;
float: left;
}
.obsidian_douban_search_input_content {
margin-left: 5px;
margin-right: 5px;
width: 90%;