Merge branch 'main' into AddUnitTests

This commit is contained in:
Emrik Östling 2025-08-11 14:10:42 +02:00 committed by GitHub
commit c3d461f102
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 160 additions and 80 deletions

View file

@ -1,3 +1,4 @@
import { Cookie } from "elysia";
import db from "../db/db";
import { MAX_CONVERT_PROCESS } from "../helpers/env";
import { normalizeFiletype, normalizeOutputFiletype } from "../helpers/normalizeFiletype";
@ -119,11 +120,11 @@ const properties: Record<
};
function chunks<T>(arr: T[], size: number): T[][] {
if(size <= 0){
return [arr]
if (size <= 0) {
return [arr];
}
return Array.from({ length: Math.ceil(arr.length / size) }, (_: T, i: number) =>
arr.slice(i * size, i * size + size)
arr.slice(i * size, i * size + size),
);
}
@ -133,17 +134,15 @@ export async function handleConvert(
userOutputDir: string,
convertTo: string,
converterName: string,
jobId: any
jobId: Cookie<string | undefined>,
) {
const query = db.query(
"INSERT INTO file_names (job_id, file_name, output_file_name, status) VALUES (?1, ?2, ?3, ?4)",
);
for (const chunk of chunks(fileNames, MAX_CONVERT_PROCESS)) {
const toProcess: Promise<string>[] = [];
for(const fileName of chunk) {
for (const fileName of chunk) {
const filePath = `${userUploadsDir}${fileName}`;
const fileTypeOrig = fileName.split(".").pop() ?? "";
const fileType = normalizeFiletype(fileTypeOrig);
@ -154,28 +153,23 @@ export async function handleConvert(
);
const targetPath = `${userOutputDir}${newFileName}`;
toProcess.push(
new Promise((resolve, reject) => {
mainConverter(
filePath,
fileType,
convertTo,
targetPath,
{},
converterName,
).then(r => {
new Promise((resolve, reject) => {
mainConverter(filePath, fileType, convertTo, targetPath, {}, converterName)
.then((r) => {
if (jobId.value) {
query.run(jobId.value, fileName, newFileName, r);
}
resolve(r);
}).catch(c => reject(c));
})
})
.catch((c) => reject(c));
}),
);
}
await Promise.all(toProcess);
}
}
export async function mainConverter(
async function mainConverter(
inputFilePath: string,
fileTypeOriginal: string,
convertTo: string,

View file

@ -16,7 +16,10 @@ export const WEBROOT = process.env.WEBROOT ?? "";
export const LANGUAGE = process.env.LANGUAGE?.toLowerCase() || "en";
export const MAX_CONVERT_PROCESS = process.env.MAX_CONVERT_PROCESS && Number(process.env.MAX_CONVERT_PROCESS) > 0 ? Number(process.env.MAX_CONVERT_PROCESS) : 0
export const MAX_CONVERT_PROCESS =
process.env.MAX_CONVERT_PROCESS && Number(process.env.MAX_CONVERT_PROCESS) > 0
? Number(process.env.MAX_CONVERT_PROCESS)
: 0;
export const UNAUTHENTICATED_USER_SHARING =
process.env.UNAUTHENTICATED_USER_SHARING?.toLowerCase() === "true" || false;
process.env.UNAUTHENTICATED_USER_SHARING?.toLowerCase() === "true" || false;

View file

@ -46,6 +46,11 @@ export const convert = new Elysia().use(userService).post(
const convertTo = normalizeFiletype(body.convert_to.split(",")[0] ?? "");
const converterName = body.convert_to.split(",")[1];
if (!converterName) {
return redirect(`${WEBROOT}/`, 302);
}
const fileNames = JSON.parse(body.file_names) as string[];
for (let i = 0; i < fileNames.length; i++) {

View file

@ -1,11 +1,11 @@
import path from "node:path";
import { Elysia } from "elysia";
import sanitize from "sanitize-filename";
import * as tar from "tar";
import { outputDir } from "..";
import db from "../db/db";
import { WEBROOT } from "../helpers/env";
import { userService } from "./user";
import path from "node:path";
import * as tar from "tar";
export const download = new Elysia()
.use(userService)
@ -58,8 +58,17 @@ export const download = new Elysia()
const userId = decodeURIComponent(params.userId);
const jobId = decodeURIComponent(params.jobId);
const outputPath = `${outputDir}${userId}/${jobId}`;
const outputTar = path.join(outputPath, `converted_files_${jobId}.tar`)
const outputTar = path.join(outputPath, `converted_files_${jobId}.tar`);
await tar.create({file: outputTar, cwd: outputPath, filter: (path) => { return !path.match(".*\\.tar"); }}, ["."]);
await tar.create(
{
file: outputTar,
cwd: outputPath,
filter: (path) => {
return !path.match(".*\\.tar");
},
},
["."],
);
return Bun.file(outputTar);
});

View file

@ -1,4 +1,5 @@
import { Html } from "@elysiajs/html";
import { JWTPayloadSpec } from "@elysiajs/jwt";
import { Elysia } from "elysia";
import { BaseHtml } from "../components/base";
import { Header } from "../components/header";
@ -6,7 +7,6 @@ import db from "../db/db";
import { Filename, Jobs } from "../db/types";
import { ALLOW_UNAUTHENTICATED, WEBROOT } from "../helpers/env";
import { userService } from "./user";
import { JWTPayloadSpec } from "@elysiajs/jwt";
function ResultsArticle({
user,
@ -26,7 +26,7 @@ function ResultsArticle({
<div class="mb-4 flex items-center justify-between">
<h1 class="text-xl">Results</h1>
<div>
<a
<a
style={files.length !== job.num_files ? "pointer-events: none;" : ""}
href={`${WEBROOT}/archive/${user.id}/${job.id}`}
download={`converted_files_${job.id}.tar`}
@ -35,7 +35,7 @@ function ResultsArticle({
type="button"
class="float-right w-40 btn-primary"
{...(files.length !== job.num_files ? { disabled: true, "aria-busy": "true" } : "")}
>
>
{files.length === job.num_files ? "Download All" : "Converting..."}
</button>
</a>

View file

@ -34,7 +34,9 @@ export const root = new Elysia()
let user: ({ id: string } & JWTPayloadSpec) | false = false;
if (ALLOW_UNAUTHENTICATED) {
const newUserId = String(
UNAUTHENTICATED_USER_SHARING ? 0 : randomInt(2 ** 24, Math.min(2 ** 48 + 2 ** 24 - 1, Number.MAX_SAFE_INTEGER)),
UNAUTHENTICATED_USER_SHARING
? 0
: randomInt(2 ** 24, Math.min(2 ** 48 + 2 ** 24 - 1, Number.MAX_SAFE_INTEGER)),
);
const accessToken = await jwt.sign({
id: newUserId,

View file

@ -44,4 +44,4 @@
/* lime-400 */
--accent-400: oklch(84.1% 0.238 128.85);
}
}
}