feat: rehashdoc
This commit is contained in:
parent
58adb46323
commit
f543ad1cf4
@ -1,7 +1,17 @@
|
|||||||
import useSWR from "swr";
|
import useSWR, { useSWRConfig } from "swr";
|
||||||
import type { Document } from "dbtype";
|
import type { Document } from "dbtype";
|
||||||
import { fetcher } from "./fetcher";
|
import { fetcher } from "./fetcher";
|
||||||
|
|
||||||
export function useGalleryDoc(id: string) {
|
export function useGalleryDoc(id: string) {
|
||||||
return useSWR<Document>(`/api/doc/${id}`, fetcher);
|
return useSWR<Document>(`/api/doc/${id}`, fetcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useRehashDoc() {
|
||||||
|
const { mutate } = useSWRConfig();
|
||||||
|
return async (id: string) => {
|
||||||
|
await fetch(`/api/doc/${id}/_rehash`, {
|
||||||
|
method: "POST",
|
||||||
|
});
|
||||||
|
mutate(`/api/doc/${id}`);
|
||||||
|
};
|
||||||
|
}
|
@ -1,10 +1,11 @@
|
|||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
import { useGalleryDoc } from "../hook/useGalleryDoc.ts";
|
import { useGalleryDoc, useRehashDoc } from "../hook/useGalleryDoc.ts";
|
||||||
import TagBadge from "@/components/gallery/TagBadge";
|
import TagBadge from "@/components/gallery/TagBadge";
|
||||||
import StyledLink from "@/components/gallery/StyledLink";
|
import StyledLink from "@/components/gallery/StyledLink";
|
||||||
import { Link } from "wouter";
|
import { Link } from "wouter";
|
||||||
import { classifyTags } from "../lib/classifyTags.tsx";
|
import { classifyTags } from "../lib/classifyTags.tsx";
|
||||||
import { DescTagItem, DescItem } from "../components/gallery/DescItem.tsx";
|
import { DescTagItem, DescItem } from "../components/gallery/DescItem.tsx";
|
||||||
|
import { Button } from "@/components/ui/button.tsx";
|
||||||
|
|
||||||
export interface ContentInfoPageProps {
|
export interface ContentInfoPageProps {
|
||||||
params: {
|
params: {
|
||||||
@ -14,6 +15,7 @@ export interface ContentInfoPageProps {
|
|||||||
|
|
||||||
export function ContentInfoPage({ params }: ContentInfoPageProps) {
|
export function ContentInfoPage({ params }: ContentInfoPageProps) {
|
||||||
const { data, error, isLoading } = useGalleryDoc(params.id);
|
const { data, error, isLoading } = useGalleryDoc(params.id);
|
||||||
|
const rehashDoc = useRehashDoc();
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return <div className="p-4">Loading...</div>
|
return <div className="p-4">Loading...</div>
|
||||||
@ -43,7 +45,13 @@ export function ContentInfoPage({ params }: ContentInfoPageProps) {
|
|||||||
alt={data.title} />
|
alt={data.title} />
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
<Card className="flex-1">
|
<Card className="flex-1 relative">
|
||||||
|
<div className="absolute top-0 right-0 p-2">
|
||||||
|
<Button variant="ghost" onClick={async () => {
|
||||||
|
// Rehash
|
||||||
|
await rehashDoc(params.id);
|
||||||
|
}}>Rehash</Button>
|
||||||
|
</div>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>
|
<CardTitle>
|
||||||
<StyledLink to={contentLocation}>
|
<StyledLink to={contentLocation}>
|
||||||
|
@ -15,6 +15,8 @@ import { AllContentRouter } from "./all.ts";
|
|||||||
import type { ContentLocation } from "./context.ts";
|
import type { ContentLocation } from "./context.ts";
|
||||||
import { sendError } from "./error_handler.ts";
|
import { sendError } from "./error_handler.ts";
|
||||||
import { ParseQueryArgString, ParseQueryArray, ParseQueryBoolean, ParseQueryNumber } from "./util.ts";
|
import { ParseQueryArgString, ParseQueryArray, ParseQueryBoolean, ParseQueryNumber } from "./util.ts";
|
||||||
|
import { oshash } from "src/util/oshash.ts";
|
||||||
|
|
||||||
|
|
||||||
const ContentIDHandler = (controller: DocumentAccessor) => async (ctx: Context, next: Next) => {
|
const ContentIDHandler = (controller: DocumentAccessor) => async (ctx: Context, next: Next) => {
|
||||||
const num = Number.parseInt(ctx.params.num);
|
const num = Number.parseInt(ctx.params.num);
|
||||||
@ -154,6 +156,34 @@ const ContentHandler = (controller: DocumentAccessor) => async (ctx: Context, ne
|
|||||||
await next();
|
await next();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function RehashContentHandler(controller: DocumentAccessor) {
|
||||||
|
return async (ctx: Context, next: Next) => {
|
||||||
|
const num = Number.parseInt(ctx.params.num);
|
||||||
|
const c = await controller.findById(num);
|
||||||
|
if (c === undefined || c.deleted_at !== null) {
|
||||||
|
return sendError(404);
|
||||||
|
}
|
||||||
|
const filepath = join(c.basepath, c.filename);
|
||||||
|
let new_hash: string;
|
||||||
|
try {
|
||||||
|
new_hash = (await oshash(filepath)).toString();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
// if file is not found, return 404
|
||||||
|
if ( (e as NodeJS.ErrnoException).code === "ENOENT") {
|
||||||
|
return sendError(404, "file not found");
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
const r = await controller.update({
|
||||||
|
id: num,
|
||||||
|
content_hash: new_hash,
|
||||||
|
});
|
||||||
|
ctx.body = JSON.stringify(r);
|
||||||
|
ctx.type = "json";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export const getContentRouter = (controller: DocumentAccessor) => {
|
export const getContentRouter = (controller: DocumentAccessor) => {
|
||||||
const ret = new Router();
|
const ret = new Router();
|
||||||
ret.get("/search", PerCheck(Per.QueryContent), ContentQueryHandler(controller));
|
ret.get("/search", PerCheck(Per.QueryContent), ContentQueryHandler(controller));
|
||||||
@ -167,6 +197,7 @@ export const getContentRouter = (controller: DocumentAccessor) => {
|
|||||||
ret.del("/:num(\\d+)", AdminOnly, DeleteContentHandler(controller));
|
ret.del("/:num(\\d+)", AdminOnly, DeleteContentHandler(controller));
|
||||||
ret.all("/:num(\\d+)/(.*)", PerCheck(Per.QueryContent), ContentHandler(controller));
|
ret.all("/:num(\\d+)/(.*)", PerCheck(Per.QueryContent), ContentHandler(controller));
|
||||||
ret.use("/:num(\\d+)", PerCheck(Per.QueryContent), new AllContentRouter().routes());
|
ret.use("/:num(\\d+)", PerCheck(Per.QueryContent), new AllContentRouter().routes());
|
||||||
|
ret.post("/:num(\\d+)/_rehash", AdminOnly, RehashContentHandler(controller));
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user