39 Commits

Author SHA1 Message Date
Emrik Östling
961a55cbe5 Merge pull request #213 from C4illin/release-please--branches--main--components--convertx-frontend 2025-01-21 23:28:20 +01:00
Emrik Östling
cdf9bad903 chore(main): release 0.10.1 2025-01-21 23:25:50 +01:00
C4illin
6769fa2f83 chore: update deps 2025-01-21 23:25:11 +01:00
C4illin
3b7ea88b73 fix: ffmpeg works without ffmpeg_args
issue #212
2025-01-21 23:24:53 +01:00
Emrik Östling
59310c095d Merge pull request #192 from C4illin/release-please--branches--main--components--convertx-frontend
chore(main): release 0.10.0
2025-01-18 12:46:01 +01:00
Emrik Östling
c47f0c12fe chore(main): release 0.10.0 2025-01-18 12:01:01 +01:00
Emrik Östling
ca71a40485 Merge pull request #211 from C4illin/renovate/oven-bun-1.x
chore(deps): update oven/bun docker tag to v1.1.45
2025-01-18 12:00:28 +01:00
renovate[bot]
d4e8f376c1 chore(deps): update oven/bun docker tag to v1.1.45 2025-01-17 17:41:37 +00:00
Emrik Östling
14c6ea1e6b Merge pull request #210 from C4illin/renovate/oven-bun-1.x
chore(deps): update oven/bun docker tag to v1.1.44
2025-01-17 11:14:27 +01:00
renovate[bot]
d6e4d8fbd6 chore(deps): update oven/bun docker tag to v1.1.44 2025-01-17 09:03:11 +00:00
C4illin
460bda62d5 chore: update deps 2025-01-16 21:30:10 +01:00
Emrik Östling
d2702ab673 Merge pull request #208 from C4illin/renovate/oven-bun-1.x
chore(deps): update oven/bun docker tag to v1.1.43
2025-01-08 23:35:11 +01:00
renovate[bot]
e2581f42f5 chore(deps): update oven/bun docker tag to v1.1.43 2025-01-08 19:03:18 +00:00
Emrik Östling
f0fcfc159f Merge pull request #203 from tejashah88/fix-unauthed-users-1
Fix: skip account setup when ALLOW_UNAUTHENTICATED is true
2025-01-04 17:36:04 +01:00
Tejas Shah
538c5b60c9 fix: skip account setup when ALLOW_UNAUTHENTICATED is true 2025-01-04 17:05:03 +01:00
Emrik Östling
2fabb7bbb2 Merge pull request #197 from C4illin/renovate/oven-bun-1.x
chore(deps): update oven/bun docker tag to v1.1.42
2025-01-04 14:27:59 +01:00
renovate[bot]
e7c34a9c94 chore(deps): update oven/bun docker tag to v1.1.42 2025-01-04 12:43:57 +00:00
Emrik Östling
618f9fce5a Merge pull request #204 from C4illin/fix-calibre-build-error
fix: add qt6-qtbase-private-dev from community repo
2025-01-04 13:43:30 +01:00
C4illin
95dbc9f678 fix: add qt6-qtbase-private-dev from community repo 2025-01-04 12:54:22 +01:00
Emrik Östling
aa87bc5c51 Merge pull request #200 from tejashah88/main
Fixed example docker-compose.yml file
2024-12-27 03:34:01 +01:00
Tejas Shah
815de531ed Fixed example docker-compose.yml file 2024-12-26 07:04:26 -08:00
Emrik Östling
cf2b026dc4 Merge pull request #196 from C4illin/renovate/oven-bun-1.x
chore(deps): update oven/bun docker tag to v1.1.41
2024-12-20 16:44:02 +01:00
renovate[bot]
9ce46aefba chore(deps): update oven/bun docker tag to v1.1.41 2024-12-20 15:33:31 +00:00
Emrik Östling
98b2db7818 Merge pull request #195 from C4illin/renovate/oven-bun-1.x
chore(deps): update oven/bun docker tag to v1.1.40
2024-12-18 13:20:35 +01:00
renovate[bot]
0229851bf9 chore(deps): update oven/bun docker tag to v1.1.40 2024-12-18 09:07:21 +00:00
C4illin
9e15114fe8 chore: update deps 2024-12-17 21:56:24 +01:00
Emrik Östling
7f66a76bb0 Merge pull request #194 from C4illin/renovate/oven-bun-1.x
chore(deps): update oven/bun docker tag to v1.1.39
2024-12-17 18:04:50 +01:00
renovate[bot]
e9cc8392bb chore(deps): update oven/bun docker tag to v1.1.39 2024-12-17 16:08:25 +00:00
C4illin
d0b89ce74f chore: add ffmpeg args and calibre to readme 2024-12-11 11:09:03 +01:00
C4illin
f537c81db7 fix: add FFMPEG_ARGS env variable
issue #190
2024-12-11 11:01:39 +01:00
C4illin
03d3edfff6 feat: add calibre
issue #191
2024-12-07 02:38:30 +01:00
Emrik Östling
447b4c5e5c Merge pull request #189 from C4illin/renovate/oven-bun-1.x 2024-12-01 12:22:47 +01:00
renovate[bot]
cb143209ae chore(deps): update oven/bun docker tag to v1.1.38 2024-11-29 14:10:18 +00:00
C4illin
9c24fe73b5 chore: add table overview for images 2024-11-27 17:06:35 +01:00
C4illin
19ae85424b chore: add dockerhub pulls badge 2024-11-27 16:51:31 +01:00
C4illin
22fad99552 chore: update converter count 2024-11-26 17:18:48 +01:00
Emrik Östling
8144bbef74 Merge pull request #188 from C4illin/renovate/oven-bun-1.x
chore(deps): update oven/bun docker tag to v1.1.37
2024-11-26 09:31:12 +01:00
renovate[bot]
aad6da0ae8 chore(deps): update oven/bun docker tag to v1.1.37 2024-11-26 04:13:39 +00:00
C4illin
c5f8162a22 chore: update deps 2024-11-25 23:22:18 +01:00
13 changed files with 978 additions and 811 deletions

View File

@@ -1,5 +1,26 @@
# Changelog # Changelog
## [0.10.1](https://github.com/C4illin/ConvertX/compare/v0.10.0...v0.10.1) (2025-01-21)
### Bug Fixes
* ffmpeg works without ffmpeg_args ([3b7ea88](https://github.com/C4illin/ConvertX/commit/3b7ea88b7382f7c21b120bdc9bda5bb10547f55d)), closes [#212](https://github.com/C4illin/ConvertX/issues/212)
## [0.10.0](https://github.com/C4illin/ConvertX/compare/v0.9.0...v0.10.0) (2025-01-18)
### Features
* add calibre ([03d3edf](https://github.com/C4illin/ConvertX/commit/03d3edfff65c252dd4b8922fc98257c089c1ff74)), closes [#191](https://github.com/C4illin/ConvertX/issues/191)
### Bug Fixes
* add FFMPEG_ARGS env variable ([f537c81](https://github.com/C4illin/ConvertX/commit/f537c81db7815df8017f834e3162291197e1c40f)), closes [#190](https://github.com/C4illin/ConvertX/issues/190)
* add qt6-qtbase-private-dev from community repo ([95dbc9f](https://github.com/C4illin/ConvertX/commit/95dbc9f678bec7e6e2c03587e1473fb8ff708ea3))
* skip account setup when ALLOW_UNAUTHENTICATED is true ([538c5b6](https://github.com/C4illin/ConvertX/commit/538c5b60c9e27a8184740305475245da79bae143))
## [0.9.0](https://github.com/C4illin/ConvertX/compare/v0.8.1...v0.9.0) (2024-11-21) ## [0.9.0](https://github.com/C4illin/ConvertX/compare/v0.8.1...v0.9.0) (2024-11-21)

View File

@@ -1,4 +1,4 @@
FROM oven/bun:1.1.36-alpine AS base FROM oven/bun:1.1.45-alpine AS base
LABEL org.opencontainers.image.source="https://github.com/C4illin/ConvertX" LABEL org.opencontainers.image.source="https://github.com/C4illin/ConvertX"
WORKDIR /app WORKDIR /app
@@ -51,7 +51,12 @@ RUN apk --no-cache add \
vips-jxl \ vips-jxl \
libjxl-tools \ libjxl-tools \
assimp \ assimp \
inkscape inkscape \
poppler-utils
RUN apk --no-cache add qt6-qtbase-private-dev --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community/
RUN apk --no-cache add calibre --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing/
# this might be needed for some latex use cases, will add it if needed. # this might be needed for some latex use cases, will add it if needed.
# texmf-dist-fontsextra \ # texmf-dist-fontsextra \

View File

@@ -4,6 +4,7 @@
[![Docker](https://github.com/C4illin/ConvertX/actions/workflows/docker-publish.yml/badge.svg?branch=main)](https://github.com/C4illin/ConvertX/actions/workflows/docker-publish.yml) [![Docker](https://github.com/C4illin/ConvertX/actions/workflows/docker-publish.yml/badge.svg?branch=main)](https://github.com/C4illin/ConvertX/actions/workflows/docker-publish.yml)
[![ghcr.io Pulls](https://img.shields.io/badge/dynamic/json?logo=github&url=https%3A%2F%2Fipitio.github.io%2Fbackage%2FC4illin%2FConvertX%2Fconvertx.json&query=%24.downloads&label=ghcr.io%20pulls&cacheSeconds=14400)](https://github.com/C4illin/ConvertX/pkgs/container/ConvertX) [![ghcr.io Pulls](https://img.shields.io/badge/dynamic/json?logo=github&url=https%3A%2F%2Fipitio.github.io%2Fbackage%2FC4illin%2FConvertX%2Fconvertx.json&query=%24.downloads&label=ghcr.io%20pulls&cacheSeconds=14400)](https://github.com/C4illin/ConvertX/pkgs/container/ConvertX)
[![Docker Pulls](https://img.shields.io/docker/pulls/c4illin/convertx?style=flat&logo=docker&label=dockerhub%20pulls&link=https%3A%2F%2Fhub.docker.com%2Frepository%2Fdocker%2Fc4illin%2Fconvertx%2Fgeneral)](https://hub.docker.com/r/c4illin/convertx)
[![GitHub Release](https://img.shields.io/github/v/release/C4illin/ConvertX)](https://github.com/C4illin/ConvertX/pkgs/container/convertx) [![GitHub Release](https://img.shields.io/github/v/release/C4illin/ConvertX)](https://github.com/C4illin/ConvertX/pkgs/container/convertx)
![GitHub commits since latest release](https://img.shields.io/github/commits-since/C4illin/ConvertX/latest) ![GitHub commits since latest release](https://img.shields.io/github/commits-since/C4illin/ConvertX/latest)
![GitHub repo size](https://img.shields.io/github/repo-size/C4illin/ConvertX) ![GitHub repo size](https://img.shields.io/github/repo-size/C4illin/ConvertX)
@@ -26,12 +27,13 @@ A self-hosted online file converter. Supports over a thousand different formats.
| [libjxl](https://github.com/libjxl/libjxl) | JPEG XL | 11 | 11 | | [libjxl](https://github.com/libjxl/libjxl) | JPEG XL | 11 | 11 |
| [resvg](https://github.com/RazrFalcon/resvg) | SVG | 1 | 1 | | [resvg](https://github.com/RazrFalcon/resvg) | SVG | 1 | 1 |
| [Vips](https://github.com/libvips/libvips) | Images | 45 | 23 | | [Vips](https://github.com/libvips/libvips) | Images | 45 | 23 |
| [Assimp](https://github.com/assimp/assimp) | 3D Assets | 70 | 24 |
| [XeLaTeX](https://tug.org/xetex/) | LaTeX | 1 | 1 | | [XeLaTeX](https://tug.org/xetex/) | LaTeX | 1 | 1 |
| [Calibre](https://calibre-ebook.com/) | E-books | 26 | 19 |
| [Pandoc](https://pandoc.org/) | Documents | 43 | 65 | | [Pandoc](https://pandoc.org/) | Documents | 43 | 65 |
| [GraphicsMagick](http://www.graphicsmagick.org/) | Images | 166 | 133 | | [GraphicsMagick](http://www.graphicsmagick.org/) | Images | 167 | 130 |
| [Inkscape](https://inkscape.org/) | Vector images | 7 | 17 | | [Inkscape](https://inkscape.org/) | Vector images | 7 | 17 |
| [FFmpeg](https://ffmpeg.org/) | Video | ~473 | ~280 | | [Assimp](https://github.com/assimp/assimp) | 3D Assets | 77 | 23 |
| [FFmpeg](https://ffmpeg.org/) | Video | ~472 | ~199 |
<!-- many ffmpeg fileformats are duplicates --> <!-- many ffmpeg fileformats are duplicates -->
@@ -51,7 +53,7 @@ services:
environment: environment:
- JWT_SECRET=aLongAndSecretStringUsedToSignTheJSONWebToken1234 # will use randomUUID() if unset - JWT_SECRET=aLongAndSecretStringUsedToSignTheJSONWebToken1234 # will use randomUUID() if unset
volumes: volumes:
- convertx:/app/data - ./data:/app/data
``` ```
or or
@@ -75,11 +77,27 @@ All are optional, JWT_SECRET is recommended to be set.
| HTTP_ALLOWED | false | Allow HTTP connections, only set this to true locally | | HTTP_ALLOWED | false | Allow HTTP connections, only set this to true locally |
| ALLOW_UNAUTHENTICATED | false | Allow unauthenticated users to use the service, only set this to true locally | | ALLOW_UNAUTHENTICATED | false | Allow unauthenticated users to use the service, only set this to true locally |
| AUTO_DELETE_EVERY_N_HOURS | 24 | Checks every n hours for files older then n hours and deletes them, set to 0 to disable | | AUTO_DELETE_EVERY_N_HOURS | 24 | Checks every n hours for files older then n hours and deletes them, set to 0 to disable |
| WEBROOT | "" | The address to the root path setting this to "/convert" will serve the website on "example.com/convert/" | | WEBROOT | | The address to the root path setting this to "/convert" will serve the website on "example.com/convert/" |
| FFMPEG_ARGS | | Arguments to pass to ffmpeg, e.g. `-preset veryfast` |
> [!WARNING] > [!WARNING]
> If you can't login, make sure you are accessing the service over https or set HTTP_ALLOWED=true > If you can't login, make sure you are accessing the service over https or set HTTP_ALLOWED=true
### Docker images
There is a `:latest` tag that is updated with every release and a `:main` tag that is updated with every push to the main branch. `:latest` is recommended for normal use.
The image is available on [GitHub Container Registry](https://github.com/C4illin/ConvertX/pkgs/container/ConvertX) and [Docker Hub](https://hub.docker.com/r/c4illin/convertx).
| Image | What it is |
|-------|------------|
| `image: ghcr.io/c4illin/convertx` | The latest release on ghcr |
| `image: ghcr.io/c4illin/convertx:main` | The latest commit on ghcr |
| `image: c4illin/convertx` | The latest release on docker hub |
| `image: c4illin/convertx:main` | The latest commit on docker hub |
<!-- Dockerhub was introduced in 0.9.0 and older releases -->
### Tutorial ### Tutorial
Tutorial in french: <https://belginux.com/installer-convertx-avec-docker/> Tutorial in french: <https://belginux.com/installer-convertx-avec-docker/>

BIN
bun.lockb

Binary file not shown.

View File

@@ -11,6 +11,7 @@ services:
- HTTP_ALLOWED=true # setting this to true is unsafe, only set this to true locally - HTTP_ALLOWED=true # setting this to true is unsafe, only set this to true locally
- ALLOW_UNAUTHENTICATED=true # allows anyone to use the service without logging in, only set this to true locally - ALLOW_UNAUTHENTICATED=true # allows anyone to use the service without logging in, only set this to true locally
- AUTO_DELETE_EVERY_N_HOURS=1 # checks every n hours for files older then n hours and deletes them, set to 0 to disable - AUTO_DELETE_EVERY_N_HOURS=1 # checks every n hours for files older then n hours and deletes them, set to 0 to disable
- WEBROOT=/convertx # the root path of the web interface, leave empty to disable # - FFMPEG_ARGS=-hwaccel vulkan # additional arguments to pass to ffmpeg
# - WEBROOT=/convertx # the root path of the web interface, leave empty to disable
ports: ports:
- 3000:3000 - 3000:3000

View File

@@ -1,6 +1,6 @@
{ {
"name": "convertx-frontend", "name": "convertx-frontend",
"version": "0.9.0", "version": "0.10.1",
"scripts": { "scripts": {
"dev": "bun run --watch src/index.tsx", "dev": "bun run --watch src/index.tsx",
"hot": "bun run --hot src/index.tsx", "hot": "bun run --hot src/index.tsx",
@@ -13,11 +13,11 @@
}, },
"dependencies": { "dependencies": {
"@elysiajs/cookie": "^0.8.0", "@elysiajs/cookie": "^0.8.0",
"@elysiajs/html": "^1.1.1", "@elysiajs/html": "^1.2.0",
"@elysiajs/jwt": "^1.1.1", "@elysiajs/jwt": "^1.2.0",
"@elysiajs/static": "^1.1.1", "@elysiajs/static": "^1.2.0",
"@kitajs/html": "^4.2.4", "@kitajs/html": "^4.2.7",
"elysia": "^1.1.25" "elysia": "^1.2.10"
}, },
"module": "src/index.tsx", "module": "src/index.tsx",
"type": "module", "type": "module",
@@ -25,31 +25,31 @@
"start": "bun run src/index.tsx" "start": "bun run src/index.tsx"
}, },
"devDependencies": { "devDependencies": {
"@eslint/compat": "^1.2.3", "@eslint/compat": "^1.2.5",
"@eslint/js": "^9.15.0", "@eslint/js": "^9.18.0",
"@ianvs/prettier-plugin-sort-imports": "^4.4.0", "@ianvs/prettier-plugin-sort-imports": "^4.4.1",
"@kitajs/ts-html-plugin": "^4.1.0", "@kitajs/ts-html-plugin": "^4.1.1",
"@total-typescript/ts-reset": "^0.6.1", "@total-typescript/ts-reset": "^0.6.1",
"@types/bun": "^1.1.13", "@types/bun": "^1.1.16",
"@types/eslint-plugin-tailwindcss": "^3.17.0", "@types/eslint-plugin-tailwindcss": "^3.17.0",
"@types/eslint__js": "^8.42.3", "@types/eslint__js": "^8.42.3",
"@types/node": "^22.9.1", "@types/node": "^22.10.7",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"cssnano": "^7.0.6", "cssnano": "^7.0.6",
"eslint": "^9.15.0", "eslint": "^9.18.0",
"eslint-plugin-deprecation": "^3.0.0", "eslint-plugin-deprecation": "^3.0.0",
"eslint-plugin-readable-tailwind": "^1.8.2", "eslint-plugin-readable-tailwind": "^1.8.2",
"eslint-plugin-simple-import-sort": "^12.1.1", "eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-tailwindcss": "^3.17.5", "eslint-plugin-tailwindcss": "^3.17.5",
"globals": "^15.12.0", "globals": "^15.14.0",
"knip": "^5.37.1", "knip": "^5.42.1",
"npm-run-all2": "^7.0.1", "npm-run-all2": "^7.0.2",
"postcss": "^8.4.49", "postcss": "^8.5.1",
"postcss-cli": "^11.0.0", "postcss-cli": "^11.0.0",
"prettier": "^3.3.3", "prettier": "^3.4.2",
"tailwind-scrollbar": "^3.1.0", "tailwind-scrollbar": "^3.1.0",
"tailwindcss": "^3.4.15", "tailwindcss": "^3.4.17",
"typescript": "^5.6.3", "typescript": "^5.7.3",
"typescript-eslint": "^8.15.0" "typescript-eslint": "^8.20.0"
} }
} }

View File

@@ -3,10 +3,12 @@ import { Html } from "@kitajs/html";
export const Header = ({ export const Header = ({
loggedIn, loggedIn,
accountRegistration, accountRegistration,
allowUnauthenticated,
webroot = "", webroot = "",
}: { }: {
loggedIn?: boolean; loggedIn?: boolean;
accountRegistration?: boolean; accountRegistration?: boolean;
allowUnauthenticated?: boolean;
webroot?: string; webroot?: string;
}) => { }) => {
let rightNav: JSX.Element; let rightNav: JSX.Element;
@@ -24,6 +26,7 @@ export const Header = ({
History History
</a> </a>
</li> </li>
{!allowUnauthenticated ? (
<li> <li>
<a <a
class={` class={`
@@ -35,6 +38,7 @@ export const Header = ({
Logout Logout
</a> </a>
</li> </li>
) : null}
</ul> </ul>
); );
} else { } else {

View File

@@ -1,9 +1,8 @@
import { exec } from "node:child_process"; import { exec } from "node:child_process";
// This could be done dynamically by running `ffmpeg -formats` and parsing the output
export const properties = { export const properties = {
from: { from: {
muxer: [ object: [
"3d", "3d",
"3ds", "3ds",
"3mf", "3mf",
@@ -84,7 +83,7 @@ export const properties = {
], ],
}, },
to: { to: {
muxer: [ object: [
"3ds", "3ds",
"3mf", "3mf",
"assbin", "assbin",
@@ -120,8 +119,6 @@ export async function convert(
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
options?: unknown, options?: unknown,
): Promise<string> { ): Promise<string> {
// let command = "ffmpeg";
const command = `assimp export "${filePath}" "${targetPath}"`; const command = `assimp export "${filePath}" "${targetPath}"`;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {

86
src/converters/calibre.ts Normal file
View File

@@ -0,0 +1,86 @@
import { exec } from "node:child_process";
export const properties = {
from: {
document: [
"azw4",
"chm",
"cbr",
"cbz",
"cbt",
"cba",
"cb7",
"djvu",
"docx",
"epub",
"fb2",
"htlz",
"html",
"lit",
"lrf",
"mobi",
"odt",
"pdb",
"pdf",
"pml",
"rb",
"rtf",
"recipe",
"snb",
"tcr",
"txt",
],
},
to: {
document: [
"azw3",
"docx",
"epub",
"fb2",
"html",
"htmlz",
"lit",
"lrf",
"mobi",
"oeb",
"pdb",
"pdf",
"pml",
"rb",
"rtf",
"snb",
"tcr",
"txt",
"txtz",
],
},
};
export async function convert(
filePath: string,
fileType: string,
convertTo: string,
targetPath: string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
options?: unknown,
): Promise<string> {
const command = `ebook-convert "${filePath}" "${targetPath}"`;
return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
if (error) {
reject(`error: ${error}`);
}
if (stdout) {
console.log(`stdout: ${stdout}`);
}
if (stderr) {
console.error(`stderr: ${stderr}`);
}
resolve("Done");
});
});
}

View File

@@ -700,7 +700,7 @@ export async function convert(
message = "Done: resized to 256x256"; message = "Done: resized to 256x256";
} }
const command = `ffmpeg -i "${filePath}" ${extra} "${targetPath}"`; const command = `ffmpeg ${process.env.FFMPEG_ARGS || ""} -i "${filePath}" ${extra} "${targetPath}"`;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => { exec(command, (error, stdout, stderr) => {

View File

@@ -8,6 +8,7 @@ import { convert as convertPandoc, properties as propertiesPandoc } from "./pand
import { convert as convertresvg, properties as propertiesresvg } from "./resvg"; import { convert as convertresvg, properties as propertiesresvg } from "./resvg";
import { convert as convertImage, properties as propertiesImage } from "./vips"; import { convert as convertImage, properties as propertiesImage } from "./vips";
import { convert as convertxelatex, properties as propertiesxelatex } from "./xelatex"; import { convert as convertxelatex, properties as propertiesxelatex } from "./xelatex";
import { convert as convertCalibre, properties as propertiesCalibre } from "./calibre";
// This should probably be reconstructed so that the functions are not imported instead the functions hook into this to make the converters more modular // This should probably be reconstructed so that the functions are not imported instead the functions hook into this to make the converters more modular
@@ -56,6 +57,10 @@ const properties: Record<
properties: propertiesxelatex, properties: propertiesxelatex,
converter: convertxelatex, converter: convertxelatex,
}, },
calibre: {
properties: propertiesCalibre,
converter: convertCalibre,
},
pandoc: { pandoc: {
properties: propertiesPandoc, properties: propertiesPandoc,
converter: convertPandoc, converter: convertPandoc,

View File

@@ -103,6 +103,16 @@ if (process.env.NODE_ENV === "production") {
} }
}); });
exec("ebook-convert --version", (error, stdout) => {
if (error) {
console.error("ebook-convert (calibre) is not installed");
}
if (stdout) {
console.log(stdout.split("\n")[0]);
}
});
exec("bun -v", (error, stdout) => { exec("bun -v", (error, stdout) => {
if (error) { if (error) {
console.error("Bun is not installed. wait what"); console.error("Bun is not installed. wait what");

View File

@@ -215,6 +215,7 @@ const app = new Elysia({
<Header <Header
webroot={WEBROOT} webroot={WEBROOT}
accountRegistration={ACCOUNT_REGISTRATION} accountRegistration={ACCOUNT_REGISTRATION}
allowUnauthenticated={ALLOW_UNAUTHENTICATED}
/> />
<main class="w-full px-4"> <main class="w-full px-4">
<article class="article"> <article class="article">
@@ -340,6 +341,7 @@ const app = new Elysia({
<Header <Header
webroot={WEBROOT} webroot={WEBROOT}
accountRegistration={ACCOUNT_REGISTRATION} accountRegistration={ACCOUNT_REGISTRATION}
allowUnauthenticated={ALLOW_UNAUTHENTICATED}
/> />
<main class="w-full px-4"> <main class="w-full px-4">
<article class="article"> <article class="article">
@@ -457,36 +459,19 @@ const app = new Elysia({
return redirect(`${WEBROOT}/login`, 302); return redirect(`${WEBROOT}/login`, 302);
}) })
.get("/", async ({ jwt, redirect, cookie: { auth, jobId } }) => { .get("/", async ({ jwt, redirect, cookie: { auth, jobId } }) => {
if (!ALLOW_UNAUTHENTICATED) {
if (FIRST_RUN) { if (FIRST_RUN) {
return redirect(`${WEBROOT}/setup`, 302); return redirect(`${WEBROOT}/setup`, 302);
} }
if (!auth?.value && !ALLOW_UNAUTHENTICATED) { if (!auth?.value) {
return redirect(`${WEBROOT}/login`, 302); return redirect(`${WEBROOT}/login`, 302);
} }
}
// validate jwt // validate jwt
let user: ({ id: string } & JWTPayloadSpec) | false = false; let user: ({ id: string } & JWTPayloadSpec) | false = false;
if (auth?.value) { if (ALLOW_UNAUTHENTICATED) {
user = await jwt.verify(auth.value);
if (user !== false && user.id) {
if (Number.parseInt(user.id) < 2 ** 24 || !ALLOW_UNAUTHENTICATED) {
// make sure user exists in db
const existingUser = db
.query("SELECT * FROM users WHERE id = ?")
.as(User)
.get(user.id);
if (!existingUser) {
if (auth?.value) {
auth.remove();
}
return redirect(`${WEBROOT}/login`, 302);
}
}
}
} else if (ALLOW_UNAUTHENTICATED) {
const newUserId = String( const newUserId = String(
randomInt( randomInt(
2 ** 24, 2 ** 24,
@@ -512,6 +497,25 @@ const app = new Elysia({
maxAge: 24 * 60 * 60, maxAge: 24 * 60 * 60,
sameSite: "strict", sameSite: "strict",
}); });
} else if (auth?.value) {
user = await jwt.verify(auth.value);
if (user !== false && user.id) {
if (Number.parseInt(user.id) < 2 ** 24 || !ALLOW_UNAUTHENTICATED) {
// make sure user exists in db
const existingUser = db
.query("SELECT * FROM users WHERE id = ?")
.as(User)
.get(user.id);
if (!existingUser) {
if (auth?.value) {
auth.remove();
}
return redirect(`${WEBROOT}/login`, 302);
}
}
}
} }
if (!user) { if (!user) {
@@ -547,7 +551,11 @@ const app = new Elysia({
return ( return (
<BaseHtml webroot={WEBROOT}> <BaseHtml webroot={WEBROOT}>
<> <>
<Header webroot={WEBROOT} loggedIn /> <Header
webroot={WEBROOT}
allowUnauthenticated={ALLOW_UNAUTHENTICATED}
loggedIn
/>
<main class="w-full px-4"> <main class="w-full px-4">
<article class="article"> <article class="article">
<h1 class="mb-4 text-xl">Convert</h1> <h1 class="mb-4 text-xl">Convert</h1>
@@ -951,7 +959,11 @@ const app = new Elysia({
return ( return (
<BaseHtml webroot={WEBROOT} title="ConvertX | Results"> <BaseHtml webroot={WEBROOT} title="ConvertX | Results">
<> <>
<Header webroot={WEBROOT} loggedIn /> <Header
webroot={WEBROOT}
allowUnauthenticated={ALLOW_UNAUTHENTICATED}
loggedIn
/>
<main class="w-full px-4"> <main class="w-full px-4">
<article class="article"> <article class="article">
<h1 class="mb-4 text-xl">Results</h1> <h1 class="mb-4 text-xl">Results</h1>
@@ -1038,7 +1050,11 @@ const app = new Elysia({
return ( return (
<BaseHtml webroot={WEBROOT} title="ConvertX | Result"> <BaseHtml webroot={WEBROOT} title="ConvertX | Result">
<> <>
<Header webroot={WEBROOT} loggedIn /> <Header
webroot={WEBROOT}
allowUnauthenticated={ALLOW_UNAUTHENTICATED}
loggedIn
/>
<main class="w-full px-4"> <main class="w-full px-4">
<article class="article"> <article class="article">
<div class="mb-4 flex items-center justify-between"> <div class="mb-4 flex items-center justify-between">
@@ -1284,7 +1300,11 @@ const app = new Elysia({
return ( return (
<BaseHtml webroot={WEBROOT} title="ConvertX | Converters"> <BaseHtml webroot={WEBROOT} title="ConvertX | Converters">
<> <>
<Header webroot={WEBROOT} loggedIn /> <Header
webroot={WEBROOT}
allowUnauthenticated={ALLOW_UNAUTHENTICATED}
loggedIn
/>
<main class="w-full px-4"> <main class="w-full px-4">
<article class="article"> <article class="article">
<h1 class="mb-4 text-xl">Converters</h1> <h1 class="mb-4 text-xl">Converters</h1>