add language detection
Some checks failed
Publish Docker Image / docker (ubuntu-latest) (push) Waiting to run
Deploy App / docker (ubuntu-latest) (push) Has been cancelled

This commit is contained in:
Lee
2024-04-23 17:22:29 +01:00
parent 4cfc368f96
commit 134aa4fc6a
10 changed files with 75 additions and 41 deletions

View File

@ -1,9 +1,10 @@
import { ReactElement } from "react";
import { cache, ReactElement } from "react";
import { ActionMenu } from "@/app/components/action-menu";
import { Metadata } from "next";
import moment from "moment";
import { notFound } from "next/navigation";
import { CodeBlock } from "@/app/components/codeBlock";
import { detectLanguage } from "@/app/common/lang-detection/detection";
type PasteProps = {
params: {
@ -21,25 +22,14 @@ type Paste = {
* The date the paste was created.
*/
created: number;
/**
* The detected language of the paste.
*/
language: string;
};
export async function generateMetadata({
params: { id },
}: PasteProps): Promise<Metadata> {
const data: Paste | undefined = await getData(id);
if (data == undefined) {
return {
description: "Not found",
};
}
return {
title: `Paste - ${id}`,
description: `Created: ${moment(data.created)}\n\nClick to view the paste.`,
};
}
async function getData(id: string): Promise<Paste | undefined> {
const getPaste = cache(async (id: string) => {
const response: Response = await fetch(
`${process.env.NEXT_PUBLIC_API_ENDPOINT}/${id}`,
{
@ -53,13 +43,33 @@ async function getData(id: string): Promise<Paste | undefined> {
if (json.code && json.message) {
return undefined;
}
return json as Paste;
return {
content: json.content,
created: json.created,
language: await detectLanguage(json.content),
};
}) as (id: string) => Promise<Paste | undefined>;
export async function generateMetadata({
params: { id },
}: PasteProps): Promise<Metadata> {
const data: Paste | undefined = await getPaste(id);
if (data == undefined) {
return {
description: "Not found",
};
}
return {
title: `Paste - ${id}`,
description: `Created: ${moment(data.created)}\n\nClick to view the paste.`,
};
}
export default async function Paste({
params: { id },
}: PasteProps): Promise<ReactElement> {
const data: Paste | undefined = await getData(id);
const data: Paste | undefined = await getPaste(id);
if (data == undefined) {
return notFound();
@ -67,7 +77,10 @@ export default async function Paste({
return (
<div className="relative">
<ActionMenu />
<div className="absolute top-0 right-0 flex flex-col items-end mx-3 mt-2">
<ActionMenu />
<p>{data.language}</p>
</div>
<div className="p-1 hljs !bg-transparent text-sm">
<CodeBlock code={data.content} />

View File

@ -45,9 +45,11 @@ export default function Home(): ReactElement {
/>
</div>
<ActionMenu>
<Button onClick={() => createPaste()}>Save</Button>
</ActionMenu>
<div className="absolute top-0 right-0 mx-3 mt-2">
<ActionMenu>
<Button onClick={() => createPaste()}>Save</Button>
</ActionMenu>
</div>
</div>
);
}

View File

@ -0,0 +1,25 @@
import { ModelOperations } from "@vscode/vscode-languagedetection";
import fs from "node:fs";
const dir = `${process.cwd()}/src/app/common/lang-detection`;
const modelOperations = new ModelOperations({
modelJsonLoaderFunc: async () => {
const response = await fs.promises.readFile(dir + "/model.json");
return JSON.parse(response.toString());
},
weightsLoaderFunc: async () => {
const response = await fs.promises.readFile(dir + "/weights.bin");
return response.buffer;
},
});
/**
* Detects the programming language of the given content.
*
* @param content The content to detect the language of.
*/
export async function detectLanguage(content: string) {
const languages = await modelOperations.runModel(content);
return languages.length > 0 ? languages[0].languageId : "Text";
}

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -8,7 +8,7 @@ type ActionMenuProps = {
export function ActionMenu({ children }: ActionMenuProps) {
return (
<div className="absolute top-0 right-0 flex items-center mx-3 mt-2 bg-secondary rounded-md p-2 gap-2">
<div className="flex items-center bg-secondary rounded-md p-2 gap-2">
{children}
<Link href={"/"}>
<Button>New</Button>