HTTP Server

This commit is contained in:
Simon Cambier
2023-10-12 20:20:39 +02:00
parent e59f252cb4
commit 35d3eb04a9
4 changed files with 131 additions and 6 deletions

View File

@@ -24,10 +24,13 @@ import { database, OmnisearchCache } from './database'
import * as NotesIndex from './notes-index'
import { searchEngine } from './search/omnisearch'
import { cacheManager } from './cache-manager'
import getServer from './tools/api-server'
export default class OmnisearchPlugin extends Plugin {
private ribbonButton?: HTMLElement
public apiHttpServer = getServer()
async onload(): Promise<void> {
await loadSettings(this)
this.addSettingTab(new SettingsTab(this))
@@ -112,6 +115,10 @@ export default class OmnisearchPlugin extends Plugin {
this.executeFirstLaunchTasks()
await this.populateIndex()
if (settings.httpApiEnabled) {
this.apiHttpServer.listen(settings.httpApiPort)
}
})
}
@@ -137,6 +144,7 @@ export default class OmnisearchPlugin extends Plugin {
if (process.env.NODE_ENV === 'production') {
await database.clearCache()
}
this.apiHttpServer.close()
}
addRibbonButton(): void {

View File

@@ -58,6 +58,8 @@ export interface OmnisearchSettings extends WeightingSettings {
verboseLogging: boolean
vimLikeNavigationShortcut: boolean
fuzziness: '0' | '1' | '2'
httpApiEnabled: boolean
httpApiPort: string
}
/**
@@ -284,7 +286,9 @@ export class SettingsTab extends PluginSettingTab {
'Navigate down the results with Ctrl/⌘ + J/N, or navigate up with Ctrl/⌘ + K/P'
)
.addToggle(toggle =>
toggle.setValue(settings.vimLikeNavigationShortcut).onChange(async v => {
toggle
.setValue(settings.vimLikeNavigationShortcut)
.onChange(async v => {
settings.vimLikeNavigationShortcut = v
await saveSettings(this.plugin)
})
@@ -454,7 +458,52 @@ export class SettingsTab extends PluginSettingTab {
})
)
//#endregion Debugginh
//#endregion Debugging
//#region HTTP Server
const httpServerDesc = new DocumentFragment()
httpServerDesc.createSpan({}, span => {
span.innerHTML = `Omnisearch can be used through a simple HTTP server (<a href="https://publish.obsidian.md/omnisearch/Public+API+%26+URL+Scheme#HTTP">more information</a>).`
})
new Setting(containerEl)
.setName('API Access Through HTTP')
.setHeading()
.setDesc(httpServerDesc)
new Setting(containerEl)
.setName('Enable the HTTP server')
.addToggle(toggle =>
toggle.setValue(settings.httpApiEnabled).onChange(async v => {
settings.httpApiEnabled = v
if (v) {
this.plugin.apiHttpServer.listen(settings.httpApiPort)
} else {
this.plugin.apiHttpServer.close()
}
await saveSettings(this.plugin)
})
)
new Setting(containerEl).setName('HTTP Port').addText(component => {
component
.setValue(settings.httpApiPort)
.setPlaceholder('51361')
.onChange(async v => {
if (parseInt(v) > 65535) {
v = settings.httpApiPort
component.setValue(settings.httpApiPort)
}
settings.httpApiPort = v
if (settings.httpApiEnabled) {
this.plugin.apiHttpServer.close()
this.plugin.apiHttpServer.listen(settings.httpApiPort)
}
await saveSettings(this.plugin)
})
})
//#endregion HTTP Server
//#region Danger Zone
new Setting(containerEl).setName('Danger Zone').setHeading()
@@ -479,6 +528,7 @@ export class SettingsTab extends PluginSettingTab {
})
)
// Disable Omnisearch
const disableDesc = new DocumentFragment()
disableDesc.createSpan({}, span => {
span.innerHTML = `Disable Omnisearch on this device only.<br>
@@ -498,6 +548,7 @@ export class SettingsTab extends PluginSettingTab {
})
)
// Clear cache data
if (isCacheEnabled()) {
const resetCacheDesc = new DocumentFragment()
resetCacheDesc.createSpan({}, span => {
@@ -522,7 +573,7 @@ export class SettingsTab extends PluginSettingTab {
cb.setLimits(1, 5, 0.1)
.setValue(settings[key])
.setDynamicTooltip()
.onChange(async (v) => {
.onChange(async v => {
settings[key] = v
await saveSettings(this.plugin)
})
@@ -557,6 +608,9 @@ export const DEFAULT_SETTINGS: OmnisearchSettings = {
weightH3: 1.1,
weightUnmarkedTags: 1.1,
httpApiEnabled: false,
httpApiPort: '51361',
welcomeMessage: '',
verboseLogging: false,
} as const

61
src/tools/api-server.ts Normal file
View File

@@ -0,0 +1,61 @@
import * as http from 'http'
import * as url from 'url'
import api from './api'
import { Notice } from 'obsidian'
export function getServer() {
const server = http.createServer(async function (req, res) {
res.setHeader('Access-Control-Allow-Origin', '*')
res.setHeader(
'Access-Control-Allow-Methods',
'GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE'
)
res.setHeader(
'Access-Control-Allow-Headers',
'Access-Control-Allow-Headers, Origin, Authorization,Accept,x-client-id, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, hypothesis-client-version'
)
res.setHeader('Access-Control-Allow-Credentials', 'true')
try {
if (req.url) {
// parse URL
const parsedUrl = url.parse(req.url, true)
console.log(parsedUrl)
if (parsedUrl.pathname === '/search') {
const q = parsedUrl.query.q as string
console.log(q)
const results = await api.search(q)
res.statusCode = 200
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify(results))
}
else {
res.end()
}
}
} catch (e) {
res.statusCode = 500
res.end(e)
}
})
return {
listen(port: string) {
console.log(`Omnisearch - Starting HTTP server on port ${port}`)
server.listen({
port: parseInt(port),
host: 'localhost',
})
console.log(`Omnisearch - Started HTTP server on port ${port}`)
new Notice(`Omnisearch - Started HTTP server on port ${port}`)
},
close() {
server.close()
console.log(`Omnisearch - Terminated HTTP server`)
new Notice(`Omnisearch - Terminated HTTP server`)
},
}
}
export default getServer
export type StaticServer = ReturnType<typeof getServer>

View File

@@ -6,6 +6,7 @@ import { refreshIndex } from '../notes-index'
type ResultNoteApi = {
score: number
vault: string
path: string
basename: string
foundWords: string[]
@@ -33,6 +34,7 @@ function mapResults(results: ResultNote[]): ResultNoteApi[] {
const res: ResultNoteApi = {
score,
vault: app.vault.getName(),
path,
basename,
foundWords,