mirror of
https://github.com/Wanxp/obsidian-douban.git
synced 2026-04-04 08:38:41 +08:00
add search douban in suggestion
This commit is contained in:
parent
89d363ebcf
commit
c3fb407215
37
douban/Douban.ts
Normal file
37
douban/Douban.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import { type } from "os";
|
||||
|
||||
interface DoubanPluginSettings {
|
||||
template:string,
|
||||
searchUrl:string,
|
||||
searchHeaders?:string
|
||||
}
|
||||
|
||||
export interface DoubanExtract {
|
||||
id: string,
|
||||
type: string;
|
||||
title: string;
|
||||
desc: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
|
||||
export const doubanHeadrs = {
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
|
||||
"Accept-Language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
|
||||
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.61 Safari/537.36",
|
||||
};
|
||||
|
||||
export const DEFAULT_SETTINGS:DoubanPluginSettings = {
|
||||
template:
|
||||
"---\n" +
|
||||
"title: {{title}}" +
|
||||
"cast: {{cast}}" +
|
||||
"score: {{score}}" +
|
||||
"---",
|
||||
searchUrl: 'https://www.douban.com/search?q=',
|
||||
searchHeaders: JSON.stringify(doubanHeadrs)
|
||||
|
||||
}
|
||||
|
||||
|
||||
export type {DoubanPluginSettings}
|
||||
69
douban/DoubanSearchModal.ts
Normal file
69
douban/DoubanSearchModal.ts
Normal file
@ -0,0 +1,69 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
59
douban/DoubanSettingTab.ts
Normal file
59
douban/DoubanSettingTab.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import DoubanPlugin from "main";
|
||||
import { App, PluginSettingTab, Setting } from "obsidian";
|
||||
|
||||
export class DoubanSettingTab extends PluginSettingTab {
|
||||
plugin: DoubanPlugin;
|
||||
|
||||
constructor(app: App, plugin: DoubanPlugin) {
|
||||
super(app, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
display(): void {
|
||||
let { containerEl } = this;
|
||||
|
||||
containerEl.empty();
|
||||
|
||||
containerEl.createEl("h2", { text: "Obsidian Wikipedia" });
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Douban Search Url")
|
||||
.setDesc(`full search url with https ahead `)
|
||||
.addText((textField) => {
|
||||
textField
|
||||
.setValue(this.plugin.settings.searchUrl)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.searchUrl = value;
|
||||
await this.plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Douban Request Headers")
|
||||
.setDesc(`full search url with https ahead `)
|
||||
.addText((textField) => {
|
||||
textField
|
||||
.setValue(this.plugin.settings.searchHeaders)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.searchHeaders = value;
|
||||
await this.plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Content Template")
|
||||
.setDesc(
|
||||
`Set markdown template for extract to be inserted.\n
|
||||
Available template variables are {{id}}, {{type}}, {{title}}, {{score}}, {{cast}}, {{desc}} and {{url}}.
|
||||
`
|
||||
)
|
||||
.addTextArea((textarea) =>
|
||||
textarea
|
||||
.setValue(this.plugin.settings.template)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.template = value;
|
||||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
13
douban/ResponseHandle.ts
Normal file
13
douban/ResponseHandle.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { Notice } from "obsidian";
|
||||
|
||||
export const ensureStatusCode = (expected:any) => {
|
||||
if (!Array.isArray(expected))
|
||||
expected = [expected];
|
||||
return (res:any) => {
|
||||
const { statusCode } = res;
|
||||
if(!expected.includes(statusCode)) {
|
||||
new Notice(`Request Douban failed, Status code must be "${expected}" but actually "${statusCode}"`)
|
||||
}
|
||||
return res;
|
||||
};
|
||||
};
|
||||
54
douban/movie/Movie.ts
Normal file
54
douban/movie/Movie.ts
Normal file
@ -0,0 +1,54 @@
|
||||
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;
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
50
douban/search/DoubanSearchFuzzySuggestModal.ts
Normal file
50
douban/search/DoubanSearchFuzzySuggestModal.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import DoubanPlugin from "main";
|
||||
import { FuzzySuggestModal,App } from "obsidian";
|
||||
import { log } from "utils/logutil";
|
||||
import { DoubanSearchResultExtract } from "./SearchParser";
|
||||
|
||||
|
||||
export {DoubanFuzzySuggester}
|
||||
|
||||
|
||||
class DoubanFuzzySuggester extends FuzzySuggestModal<DoubanSearchResultExtract> {
|
||||
|
||||
public app: App;
|
||||
private plugin: DoubanPlugin;
|
||||
private doubanSearchResultExtract:DoubanSearchResultExtract[]
|
||||
|
||||
constructor(app: App, plugin: DoubanPlugin) {
|
||||
super(app);
|
||||
this.app = app;
|
||||
this.plugin = plugin;
|
||||
this.setPlaceholder("Choose an item...");
|
||||
}
|
||||
|
||||
getItems(): DoubanSearchResultExtract[] {
|
||||
return this.doubanSearchResultExtract;
|
||||
}
|
||||
|
||||
getItemText(item: DoubanSearchResultExtract): string {
|
||||
let text:string = item.type + ":" + item.title + " [score]:" + item.score + ",[cast]:" + item.cast;
|
||||
return text;
|
||||
}
|
||||
|
||||
onChooseItem(item: DoubanSearchResultExtract, evt: MouseEvent | KeyboardEvent): void {
|
||||
log.warn("choose item " + item.title + " id " + item.id);
|
||||
}
|
||||
|
||||
public showSearchList(doubanSearchResultExtractList:DoubanSearchResultExtract[]) {
|
||||
this.doubanSearchResultExtract = doubanSearchResultExtractList;
|
||||
log.info("show search result" );
|
||||
this.start();
|
||||
}
|
||||
|
||||
public start(): void {
|
||||
try {
|
||||
this.open();
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
24
douban/search/Search.ts
Normal file
24
douban/search/Search.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import cheerio from 'cheerio';
|
||||
import { doubanHeadrs, DoubanPluginSettings } from 'douban/Douban';
|
||||
import { get, readStream } from 'tiny-network';
|
||||
import { ensureStatusCode } from 'douban/ResponseHandle';
|
||||
import { DoubanSearchResultExtract, SearchParserHandler } from './SearchParser';
|
||||
import { log } from 'utils/logutil';
|
||||
|
||||
class Searcher {
|
||||
static search(searchItem:string, doubanSettings:DoubanPluginSettings):Promise<DoubanSearchResultExtract[]> {
|
||||
// getData();
|
||||
// getData2();
|
||||
// return Promise.resolve();
|
||||
return Promise
|
||||
.resolve()
|
||||
.then(() => get(doubanSettings.searchUrl + searchItem, JSON.parse(doubanSettings.searchHeaders)))
|
||||
.then(ensureStatusCode(200))
|
||||
.then(readStream)
|
||||
.then(log.info)
|
||||
.then(cheerio.load)
|
||||
.then(SearchParserHandler.parseSearch);
|
||||
};
|
||||
}
|
||||
|
||||
export {Searcher}
|
||||
43
douban/search/SearchParser.ts
Normal file
43
douban/search/SearchParser.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { CheerioAPI } from "cheerio";
|
||||
import { DoubanExtract } from "douban/Douban";
|
||||
import { type } from "os";
|
||||
|
||||
interface DoubanSearchResultExtract extends DoubanExtract{
|
||||
cast: string;
|
||||
score: string;
|
||||
}
|
||||
|
||||
|
||||
class SearchParserHandler {
|
||||
static parseSearch(dataHtml:CheerioAPI):DoubanSearchResultExtract[] {
|
||||
return dataHtml('.result')
|
||||
.get()
|
||||
.map((i:any) => {
|
||||
const item = dataHtml(i);
|
||||
var idPattern = /(\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 ececResult = idPattern.exec(linkValue);
|
||||
var urlResult = urlPattern.exec(linkValue);
|
||||
var cast = item.find(".subject-cast").text();
|
||||
const result:DoubanSearchResultExtract = {
|
||||
id: ececResult?ececResult[0]:'',
|
||||
title: item.find("div.content > div > h3 > a").text(),
|
||||
score: item.find(".rating_nums").text(),
|
||||
// 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'),
|
||||
cast: cast,
|
||||
type: item.find("div.content > div > h3 > span").text(),
|
||||
desc: item.find("div.content > p").text(),
|
||||
url: urlResult?decodeURIComponent(urlResult[0]):'https://www.douban.com',
|
||||
};
|
||||
return result;
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
export {SearchParserHandler}
|
||||
export type {DoubanSearchResultExtract}
|
||||
235
main.ts
235
main.ts
@ -1,137 +1,126 @@
|
||||
import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian';
|
||||
import { DoubanSearchModal } from "douban/DoubanSearchModal";
|
||||
import { DoubanSettingTab } from "douban/DoubanSettingTab";
|
||||
import { DoubanFuzzySuggester } from "douban/search/DoubanSearchFuzzySuggestModal";
|
||||
import { Editor, Notice, Plugin} from "obsidian";
|
||||
import { log } from "utils/logutil";
|
||||
import { DEFAULT_SETTINGS, DoubanExtract, DoubanPluginSettings } from "./douban/Douban";
|
||||
import { Searcher } from "./douban/search/Search";
|
||||
import { DoubanSearchResultExtract } from "./douban/search/SearchParser";
|
||||
|
||||
// Remember to rename these classes and interfaces!
|
||||
export default class DoubanPlugin extends Plugin {
|
||||
public settings: DoubanPluginSettings;
|
||||
public fuzzySuggester: DoubanFuzzySuggester;
|
||||
|
||||
interface MyPluginSettings {
|
||||
mySetting: string;
|
||||
}
|
||||
|
||||
const DEFAULT_SETTINGS: MyPluginSettings = {
|
||||
mySetting: 'default'
|
||||
}
|
||||
|
||||
export default class MyPlugin extends Plugin {
|
||||
settings: MyPluginSettings;
|
||||
|
||||
async onload() {
|
||||
await this.loadSettings();
|
||||
|
||||
// This creates an icon in the left ribbon.
|
||||
const ribbonIconEl = this.addRibbonIcon('dice', 'Sample Plugin', (evt: MouseEvent) => {
|
||||
// Called when the user clicks the icon.
|
||||
new Notice('This is a notice!');
|
||||
});
|
||||
// Perform additional things with the ribbon
|
||||
ribbonIconEl.addClass('my-plugin-ribbon-class');
|
||||
|
||||
// This adds a status bar item to the bottom of the app. Does not work on mobile apps.
|
||||
const statusBarItemEl = this.addStatusBarItem();
|
||||
statusBarItemEl.setText('Status Bar Text');
|
||||
|
||||
// This adds a simple command that can be triggered anywhere
|
||||
this.addCommand({
|
||||
id: 'open-sample-modal-simple',
|
||||
name: 'Open sample modal (simple)',
|
||||
callback: () => {
|
||||
new SampleModal(this.app).open();
|
||||
}
|
||||
});
|
||||
// This adds an editor command that can perform some operation on the current editor instance
|
||||
this.addCommand({
|
||||
id: 'sample-editor-command',
|
||||
name: 'Sample editor command',
|
||||
editorCallback: (editor: Editor, view: MarkdownView) => {
|
||||
console.log(editor.getSelection());
|
||||
editor.replaceSelection('Sample Editor Command');
|
||||
}
|
||||
});
|
||||
// This adds a complex command that can check whether the current state of the app allows execution of the command
|
||||
this.addCommand({
|
||||
id: 'open-sample-modal-complex',
|
||||
name: 'Open sample modal (complex)',
|
||||
checkCallback: (checking: boolean) => {
|
||||
// Conditions to check
|
||||
const markdownView = this.app.workspace.getActiveViewOfType(MarkdownView);
|
||||
if (markdownView) {
|
||||
// If checking is true, we're simply "checking" if the command can be run.
|
||||
// If checking is false, then we want to actually perform the operation.
|
||||
if (!checking) {
|
||||
new SampleModal(this.app).open();
|
||||
}
|
||||
|
||||
// This command will only show up in Command Palette when the check function returns true
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// This adds a settings tab so the user can configure various aspects of the plugin
|
||||
this.addSettingTab(new SampleSettingTab(this.app, this));
|
||||
|
||||
// If the plugin hooks up any global DOM events (on parts of the app that doesn't belong to this plugin)
|
||||
// Using this function will automatically remove the event listener when this plugin is disabled.
|
||||
this.registerDomEvent(document, 'click', (evt: MouseEvent) => {
|
||||
console.log('click', evt);
|
||||
});
|
||||
|
||||
// When registering intervals, this function will automatically clear the interval when the plugin is disabled.
|
||||
this.registerInterval(window.setInterval(() => console.log('setInterval'), 5 * 60 * 1000));
|
||||
formatExtractText(extract: DoubanExtract): string {
|
||||
return this.settings.template ?
|
||||
this.settings.template.replace("{{id}}", extract.id)
|
||||
.replace("{{type}}", extract.type)
|
||||
.replace("{{title}}", extract.title)
|
||||
.replace("{{desc}}", extract.desc)
|
||||
.replace("{{url}}", extract.url) : "";
|
||||
}
|
||||
|
||||
onunload() {
|
||||
handleNotFound(searchTerm: string) {
|
||||
log.error(`${searchTerm} not found on Wikipedia.`);
|
||||
}
|
||||
|
||||
handleCouldntResolveDisambiguation() {
|
||||
log.error(`Could not automatically resolve disambiguation.`);
|
||||
}
|
||||
|
||||
|
||||
parseSearchList(extract: DoubanSearchResultExtract[]):DoubanSearchResultExtract[] {
|
||||
// return extract.map(result => {
|
||||
// return {
|
||||
// id: result.id,
|
||||
// type: result.type,
|
||||
// title: result.title,
|
||||
// desc: result.desc,
|
||||
// url: result.url,
|
||||
// score: result.score,
|
||||
// cast: result.cast
|
||||
// }
|
||||
// })
|
||||
return extract;
|
||||
}
|
||||
|
||||
async getDoubanSearchList(title: string): Promise<DoubanSearchResultExtract[] | undefined> {
|
||||
return Searcher.search(title, this.settings);
|
||||
}
|
||||
|
||||
async getDoubanMovieText(title: DoubanSearchResultExtract): Promise<DoubanExtract | undefined> {
|
||||
// const moviesPromise = search(title);
|
||||
// const movies = await moviesPromise;
|
||||
// const extract = this.parseResponse(movies);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
async pasteIntoEditor(editor: Editor, extract: DoubanExtract) {
|
||||
|
||||
if (!extract) {
|
||||
this.handleNotFound("Not Found Subject");
|
||||
return;
|
||||
}
|
||||
editor.replaceSelection(this.formatExtractText(extract));
|
||||
}
|
||||
|
||||
|
||||
async search(searchTerm:string) {
|
||||
log.info("plugin search :" + searchTerm);
|
||||
const resultListPromise = this.getDoubanSearchList(searchTerm);
|
||||
resultListPromise.then(log.info);
|
||||
const resultList = await resultListPromise;
|
||||
const result = this.parseSearchList(resultList);
|
||||
log.info("plugin search result:" + JSON.stringify(result));
|
||||
this.fuzzySuggester.showSearchList(result);
|
||||
}
|
||||
|
||||
async getDoubanMovieTextForActiveFile(editor: Editor) {
|
||||
const activeFile = await this.app.workspace.getActiveFile();
|
||||
if (activeFile) {
|
||||
const searchTerm = activeFile.basename;
|
||||
if (searchTerm) {
|
||||
await this.search(searchTerm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async geDoubanMovieTextForSearchTerm(editor: Editor) {
|
||||
log.info("start open search windows");
|
||||
new DoubanSearchModal(this.app, this, editor).open();
|
||||
}
|
||||
|
||||
async onload() {
|
||||
await this.loadSettings();
|
||||
|
||||
this.addCommand({
|
||||
id: "douban-movie-for-current-file",
|
||||
name: "get dou ban movie",
|
||||
editorCallback: (editor: Editor) =>
|
||||
this.getDoubanMovieTextForActiveFile(editor),
|
||||
});
|
||||
|
||||
|
||||
this.addCommand({
|
||||
id: "douban-movie-for-search",
|
||||
name: "douban-movie-for-search",
|
||||
editorCallback: (editor: Editor) =>
|
||||
this.geDoubanMovieTextForSearchTerm(editor),
|
||||
});
|
||||
|
||||
this.addSettingTab(new DoubanSettingTab(this.app, this));
|
||||
this.fuzzySuggester = new DoubanFuzzySuggester(this.app, this);
|
||||
}
|
||||
|
||||
async loadSettings() {
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
||||
}
|
||||
|
||||
async saveSettings() {
|
||||
await this.saveData(this.settings);
|
||||
await this.saveData(this.settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SampleModal extends Modal {
|
||||
constructor(app: App) {
|
||||
super(app);
|
||||
}
|
||||
|
||||
onOpen() {
|
||||
const {contentEl} = this;
|
||||
contentEl.setText('Woah!');
|
||||
}
|
||||
|
||||
onClose() {
|
||||
const {contentEl} = this;
|
||||
contentEl.empty();
|
||||
}
|
||||
}
|
||||
|
||||
class SampleSettingTab extends PluginSettingTab {
|
||||
plugin: MyPlugin;
|
||||
|
||||
constructor(app: App, plugin: MyPlugin) {
|
||||
super(app, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
display(): void {
|
||||
const {containerEl} = this;
|
||||
|
||||
containerEl.empty();
|
||||
|
||||
containerEl.createEl('h2', {text: 'Settings for my awesome plugin.'});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Setting #1')
|
||||
.setDesc('It\'s a secret')
|
||||
.addText(text => text
|
||||
.setPlaceholder('Enter your secret')
|
||||
.setValue(this.plugin.settings.mySetting)
|
||||
.onChange(async (value) => {
|
||||
console.log('Secret: ' + value);
|
||||
this.plugin.settings.mySetting = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
2130
package-lock.json
generated
Normal file
2130
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -20,5 +20,11 @@
|
||||
"obsidian": "latest",
|
||||
"tslib": "2.3.1",
|
||||
"typescript": "4.4.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.27.2",
|
||||
"cheerio": "^1.0.0-rc.11",
|
||||
"douban-search-crack": "^1.0.6",
|
||||
"tiny-network": "0.0.6"
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,9 @@
|
||||
"ES5",
|
||||
"ES6",
|
||||
"ES7"
|
||||
]
|
||||
],
|
||||
"outDir": "dist",
|
||||
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts"
|
||||
|
||||
6
typings/tiny-network.d.ts
vendored
Normal file
6
typings/tiny-network.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
declare module 'tiny-network' {
|
||||
export function get(url:string, headers:any): any;
|
||||
export function get(url:string): any;
|
||||
export function readStream(param:any): any;
|
||||
export function ensureStatusCode(code:number): any;
|
||||
}
|
||||
21
utils/logutil.ts
Normal file
21
utils/logutil.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { Notice } from "obsidian";
|
||||
|
||||
class Logger {
|
||||
|
||||
public error(e:any):any {
|
||||
new Notice("Douban Plugin Error: " + e);
|
||||
return e;
|
||||
}
|
||||
|
||||
public warn(e:any):any {
|
||||
new Notice("Douban Plugin Warn: " + e);
|
||||
return e;
|
||||
}
|
||||
|
||||
public info(e:any):any {
|
||||
console.log("Douban Plugin Warn: " + e);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
export const log:Logger = new Logger();
|
||||
Loading…
Reference in New Issue
Block a user