This repository has been archived on 2024-01-24. You can view files and clone it, but cannot push or open issues or pull requests.
celery-search/index.ts

125 lines
3.5 KiB
TypeScript
Raw Normal View History

2023-04-07 23:38:48 +00:00
import { Application } from "https://deno.land/x/abc@v1.3.3/mod.ts";
import { logger } from "https://deno.land/x/abc@v1.3.3/middleware/logger.ts";
import { renderFile } from "https://deno.land/x/dejs@0.10.3/mod.ts";
2023-09-09 09:08:37 +00:00
import { cleanUrl, scrape } from "./scraper.ts";
import {
2023-09-09 23:19:07 +00:00
upsertWebsite,
getWebsite,
2023-09-09 09:08:37 +00:00
countWebsites,
deleteWebsite,
queryWebsites,
} from "./data.ts";
2023-04-28 04:17:24 +00:00
import { embedText } from "./embed.ts";
2023-04-07 23:38:48 +00:00
const app = new Application();
2023-09-09 23:19:07 +00:00
// app.use(logger());
2023-04-07 23:38:48 +00:00
app.static("/", "./static");
app.renderer = {
render(name: string, data: any): Promise<Deno.Reader> {
return renderFile(name, data);
},
};
app.get("/", async (c) => {
await c.render("./templates/index.ejs", {});
});
app.get("/search", async (c) => {
const { query, like, page } = c.queryParams;
if (!(query || like)) return c.redirect("/");
if (query && like) throw new Error("you can't have both query and like");
2023-04-29 13:27:22 +00:00
const start = Date.now();
const pageNum = parseInt(page) || 0;
const embedding = query ? await embedText(query) : (await getWebsite(like))?.embedding;
if (!embedding) throw new Error("failed to get embedding");
2023-04-28 04:17:24 +00:00
const results = await queryWebsites(embedding, pageNum);
return c.render("./templates/search.ejs", {
2023-09-09 09:08:37 +00:00
results,
query,
page: pageNum,
admin: false,
duration: Date.now() - start,
});
});
2023-04-08 03:27:32 +00:00
app.get("/search.json", async (c) => {
const { query, like, page } = c.queryParams;
if (query && like) throw new Error("you can't have both query and like");
2023-04-08 03:27:32 +00:00
const pageNum = parseInt(page) || 0;
const embedding = query ? await embedText(query) : (await getWebsite(like))?.embedding;
if (!embedding) throw new Error("failed to get embedding");
2023-04-28 04:17:24 +00:00
const results = await queryWebsites(embedding, pageNum);
return c.json(results);
2023-04-07 23:38:48 +00:00
});
app.post("/admin/add", async (c) => {
const { url: rawUrl } = await c.body;
2023-09-09 09:08:37 +00:00
if (rawUrl) {
2023-04-07 23:38:48 +00:00
try {
const url = cleanUrl(rawUrl);
2023-04-08 06:21:43 +00:00
const data = await scrape(url);
2023-09-09 09:08:37 +00:00
const embedding = await embedText(
`${data.title}\n${data.description}\n${data.content}`,
);
2023-09-09 23:19:07 +00:00
if (!embedding) throw new Error("failed to embed text");
const upserted = await upsertWebsite(data, embedding);
2023-09-09 09:08:37 +00:00
2023-04-29 13:27:22 +00:00
console.log(`added url ${data.url}`);
2023-09-09 09:08:37 +00:00
await c.render("./templates/add.ejs", {
state: upserted ? "exists" : "success",
2023-09-09 23:19:07 +00:00
});
2023-04-07 23:38:48 +00:00
} catch (error) {
console.error(`failed to add ${rawUrl}: ${error}`);
2023-09-09 23:19:07 +00:00
console.error(error);
2023-04-08 06:21:43 +00:00
await c.render("./templates/add.ejs", { state: "error", error }, 400);
2023-04-07 23:38:48 +00:00
}
} else {
2023-04-08 06:21:43 +00:00
await c.render("./templates/add.ejs", { state: "default" });
2023-04-07 23:38:48 +00:00
}
});
app.get("/admin/add", async (c) => {
2023-04-08 06:21:43 +00:00
await c.render("./templates/add.ejs", { state: "default" });
2023-04-07 23:38:48 +00:00
});
app.get("/admin/search", async (c) => {
const { query, page } = c.queryParams;
if (!query) return c.redirect("/");
2023-04-29 13:27:22 +00:00
const start = Date.now();
const pageNum = parseInt(page) || 0;
2023-04-28 04:17:24 +00:00
const embedding = await embedText(query);
const results = await queryWebsites(embedding, pageNum);
2023-09-09 09:08:37 +00:00
await c.render("./templates/search.ejs", {
results,
query,
page: pageNum,
admin: true,
duration: Date.now() - start,
});
});
app.delete("/admin/document/:docid", async (c) => {
console.log("delete " + c.params.docid);
2023-04-28 04:17:24 +00:00
deleteWebsite(c.params.docid);
await c.json({}, 204);
});
app.get("/info", async (c) => {
await c.render("./templates/info.ejs", {
2023-09-09 23:19:07 +00:00
indexed: await countWebsites(),
});
});
app.get("/info.json", async (c) => {
await c.json({
2023-09-10 00:16:00 +00:00
indexed: (await countWebsites()).toString(),
});
});
2023-04-07 23:38:48 +00:00
await app.start({ port: 3974 });
console.log("ready");