file upload

This commit is contained in:
Theis Pieter Hollebeek 2024-01-19 03:44:55 +01:00
parent 57e248bb2d
commit 9257928d37
7 changed files with 74 additions and 15 deletions

3
.gitignore vendored
View File

@ -1,3 +1,4 @@
node_modules/
videos/*
!videos/.gitkeep
tmp/

View File

@ -5,6 +5,8 @@ import fileUpload from "express-fileupload";
import path from "path";
import childProcess from "child_process";
import levenshtein from "js-levenshtein";
import cookieParser from "cookie-parser";
import { fileURLToPath } from 'url';
const users = [];
let sessions = [];
@ -14,14 +16,19 @@ function randomString(length) {
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
let result = "";
for (let i = 0; i < length; ++i) {
result += chars[chars.length * Math.random()];
result += chars[Math.floor(chars.length * Math.random())];
}
return result;
}
function dirname() {
return path.dirname(fileURLToPath(import.meta.url));
}
const app = express();
app.use(cors());
app.use(express.json());
app.use(cookieParser());
app.use(express.urlencoded({ extended: true }));
app.use("/", express.static("public/"));
@ -77,7 +84,7 @@ app.get("/api/search", async (req, res) => {
.toSorted((a, b) => a.dist - b.dist)
.slice(start, end)
.map(video => {
const user = users.find(user => user.id === v.userId);
const user = users.find(user => user.id === video.userId);
if (!user) {
return {...video, author: "[Liberal]"};
}
@ -89,7 +96,7 @@ app.get("/api/search", async (req, res) => {
function authorized() {
return (req, res, next) => {
const token = (() => {
if ("token" in req.cookies) {
if (req.cookies && "token" in req.cookies) {
return req.cookies["token"];
} else if ("token" in req.query) {
return req.query["token"];
@ -100,13 +107,13 @@ function authorized() {
}
})();
if (token === null) {
return res.status(400).json({ ok: false, error: "unathorized" });
return res.status(400).json({ ok: false, error: "unauthorized" });
}
const session = sessions.find(session => session.token === token);
if (session === undefined) {
return res.status(400).json({ ok: false, error: "unathorized" });
return res.status(400).json({ ok: false, error: "unauthorized" });
}
const user = user.find(user => user.id === session.id);
const user = users.find(user => user.id === session.userId);
if (user === undefined) {
throw new Error("error: session with invalid userId");
}
@ -122,28 +129,31 @@ app.get("/api/logout", authorized(), (req, res) => {
app.post("/api/upload_video", authorized(), fileUpload({ limits: { fileSize: 2 ** 26 }, useTempFiles: true }), async (req, res) => {
const { title } = req.body;
if (req.files === undefined || req.files === null || req.files.length !== 1) {
if (!req.files || !req.files.video) {
return res.status(400).json({ ok: false, error: "bad request" });
}
if (req.files[0].mimetype !== "video/mp4") {
if (req.files.video.mimetype !== "video/mp4") {
return res.status(400).json({ ok: false, error: "bad mimetype" });
}
const userId = req.user.id;
const id = randomString(4);
const tempPath = req.files[0].tempFilePath;
const newPath = path.join("/videos", id, ".mp4");
const tempPath = req.files.video.tempFilePath;
const newPath = path.join(dirname(), "videos", `${id}.mp4`);
console.log(newPath);
const exitCode = await new Promise((resolve, _reject) => {
const process = childProcess.spawn("HandBrakeCLI", ["-i", tempPath, "-o", newPath, "-Z", "Social 25 MB 5 Minutes 360p60"]);
const process = childProcess.spawn("HandBrakeCLI", ["-i", tempPath, "-o", newPath, "-Z", "Social 50 MB 10 Minutes 480p30"]);
process.stderr.on("data", (data) => {
conole.error(data);
console.error(data.toString());
});
process.on("close", (code) => {
resolve(code);
})
});
})
if (exitCode !== 0) {
throw new Error("handbrake failed");
console.log(":/");
// throw new Error("handbrake failed");
return res.status(500).json({ ok: false, error: "server error" });
}
const video = {

21
package-lock.json generated
View File

@ -10,6 +10,7 @@
"license": "ISC",
"dependencies": {
"bcrypt": "^5.1.1",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"express": "^4.18.2",
"express-fileupload": "^1.4.3",
@ -249,6 +250,26 @@
"node": ">= 0.6"
}
},
"node_modules/cookie-parser": {
"version": "1.4.6",
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz",
"integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==",
"dependencies": {
"cookie": "0.4.1",
"cookie-signature": "1.0.6"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/cookie-parser/node_modules/cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",

View File

@ -12,6 +12,7 @@
"type": "module",
"dependencies": {
"bcrypt": "^5.1.1",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"express": "^4.18.2",
"express-fileupload": "^1.4.3",

View File

@ -7,6 +7,11 @@
</head>
<body>
<h1>MaoTube</h1>
<a href="/register">register</a> -
<a href="/login">login</a> -
<a href="/upload">upload</a>
<br>
<br>
<form method="GET" target="_self" action="/search">
<input type="text" name="query" placeholder="...">
<input type="submit" value="Search">

21
public/upload/index.html Normal file
View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>MaoTube</title>
<link rel="stylesheet" href="/style.css">
</head>
<body>
<h1>MaoTube</h1>
<form action="/api/upload_video" method="POST" enctype="multipart/form-data">
<label for="username"><p>Title</p></label>
<input type="text" name="title">
<label for="password"><p>Video</p></label>
<input type="file" name="video">
<br>
<br>
<input type="submit" id="submit" value="Upload">
</form>
</body>
</html>

0
videos/.gitkeep Normal file
View File