You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
260 lines
9.8 KiB
260 lines
9.8 KiB
import {getClient} from "../utils/database.js";
|
|
import * as path from "node:path";
|
|
import * as fs from "node:fs";
|
|
import { fileURLToPath } from 'url';
|
|
import { dirname } from 'path';
|
|
import jwt from "jsonwebtoken";
|
|
import {query} from "express-validator";
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = dirname(__filename);
|
|
|
|
export async function upload(req, res) {
|
|
|
|
const fileBuffer = req.file.buffer;
|
|
let isGenerate = false;
|
|
while (isGenerate === false) {
|
|
const client = await getClient();
|
|
let letters = "0123456789ABCDEF";
|
|
let hex = '';
|
|
for (let i = 0; i < 16; i++)
|
|
hex += letters[(Math.floor(Math.random() * 16))];
|
|
|
|
|
|
const query = `SELECT * FROM videos WHERE slug='${hex}'`;
|
|
const result = await client.query(query);
|
|
client.end();
|
|
if (result.rows.length === 0) {
|
|
isGenerate = true;
|
|
req.body.slug = hex;
|
|
}
|
|
}
|
|
|
|
const finalName = req.body.slug + "." + req.file.originalname.split(".")[1];
|
|
const destinationPath = path.join(__dirname, "../uploads/videos/" + finalName)
|
|
|
|
fs.writeFileSync(destinationPath, fileBuffer);
|
|
const client = await getClient();
|
|
const video = {
|
|
title: req.body.title,
|
|
description: req.body.description,
|
|
//TODO thumbnail
|
|
file: "/api/media/video/" + finalName,
|
|
channel: req.body.channel,
|
|
slug: req.body.slug,
|
|
format: req.file.originalname.split(".")[1],
|
|
visibility: req.body.visibility,
|
|
}
|
|
|
|
const logger = req.body.logger;
|
|
logger.write("try to upload video");
|
|
const releaseDate = new Date(Date.now()).toISOString();
|
|
|
|
const query = `INSERT INTO videos (title, thumbnail, description, channel, visibility, file, slug, format, release_date) VALUES ('${video.title}', 'null', '${video.description}', '${video.channel}', '${video.visibility}', '${video.file}', '${video.slug}', '${video.format}', '${releaseDate}')`;
|
|
await client.query(query);
|
|
logger.write("successfully uploaded video", 200);
|
|
res.status(200).json({"message": "Successfully uploaded video"});
|
|
|
|
}
|
|
|
|
export async function uploadThumbnail(req, res) {
|
|
const fileBuffer = req.file.buffer;
|
|
const client = await getClient();
|
|
const videoId = req.body.video;
|
|
const videoSlugQuery = `SELECT * from videos WHERE id = ${videoId}`;
|
|
const result = await client.query(videoSlugQuery);
|
|
|
|
const fileName = result.rows[0].slug + "." + req.file.originalname.split(".")[1];
|
|
const destinationPath = path.join(__dirname, "../uploads/thumbnails/", fileName);
|
|
fs.writeFileSync(destinationPath, fileBuffer);
|
|
|
|
const logger = req.body.logger;
|
|
logger.action("try to add thumbnail to video " + req.body.video);
|
|
|
|
const file = "/api/media/thumbnail/" + fileName;
|
|
|
|
const updateQuery = `UPDATE videos SET thumbnail = '${file}' WHERE id = ${req.body.video}`;
|
|
await client.query(updateQuery);
|
|
logger.write("successfully uploaded thumbnail", 200);
|
|
res.status(200).json({"message": "Successfully uploaded thumbnail"});
|
|
}
|
|
|
|
export async function getById(req, res) {
|
|
const id = req.params.id;
|
|
|
|
const logger = req.body.logger;
|
|
logger.action("try to get video " + id);
|
|
const client = await getClient();
|
|
const query = `SELECT * FROM videos WHERE id = ${id}`;
|
|
const result = await client.query(query);
|
|
const video = result.rows[0];
|
|
logger.write("successfully get video " + id, 200);
|
|
res.status(200).json(video);
|
|
}
|
|
|
|
export async function getByChannel(req, res) {
|
|
const id = req.params.id;
|
|
const logger = req.body.logger;
|
|
logger.action("try to get video from channel " + id);
|
|
const client = await getClient();
|
|
const query = `SELECT * FROM videos WHERE channel = ${id}`;
|
|
const result = await client.query(query);
|
|
logger.write("successfully get video from channel " + id, 200);
|
|
res.status(200).json(result.rows);
|
|
}
|
|
|
|
export async function update(req, res) {
|
|
const id = req.params.id;
|
|
const logger = req.body.logger;
|
|
logger.action("try to update video " + id);
|
|
const client = await getClient();
|
|
const query = `UPDATE videos SET title='${req.body.title}', description:'${req.body.description}', visibility:'${req.body.visibility}'`;
|
|
await client.query(query);
|
|
logger.write("successfully updated video", 200);
|
|
res.status(200).json({"message": "Successfully updated video"});
|
|
}
|
|
|
|
export async function updateVideo(req, res) {
|
|
const id = req.params.id;
|
|
const logger = req.body.logger;
|
|
logger.action("try to update video file " + id);
|
|
const client = await getClient();
|
|
const videoQuery = `SELECT slug, format FROM videos WHERE id = ${id}`;
|
|
const videoResult = await client.query(videoQuery);
|
|
const video = videoResult.rows[0];
|
|
const slug = video.slug;
|
|
const format = video.format;
|
|
const pathToDelete = path.join(__dirname, "../uploads/videos/", slug + "." + format );
|
|
fs.unlink(pathToDelete, (error) => {
|
|
if (error) {
|
|
logger.write(error, 500);
|
|
res.status(500).json({"message": "Failed to delete video"});
|
|
return
|
|
}
|
|
logger.action("successfully deleted video " + slug + "." + format );
|
|
const fileBuffer = req.file.buffer;
|
|
const finalName = slug + "." + format;
|
|
const destinationPath = path.join(__dirname, "../uploads/videos/" + finalName)
|
|
|
|
fs.writeFileSync(destinationPath, fileBuffer);
|
|
|
|
logger.write("successfully updated video", 200);
|
|
res.status(200).json({"message": "Successfully updated video"});
|
|
})
|
|
|
|
|
|
}
|
|
|
|
export async function del(req, res) {
|
|
const id = req.params.id;
|
|
const logger = req.body.logger;
|
|
logger.action("try to delete video " + id);
|
|
const client = await getClient();
|
|
const query = `SELECT slug, format, thumbnail FROM videos WHERE id = ${id}`;
|
|
const result = await client.query(query);
|
|
const video = result.rows[0];
|
|
const slug = video.slug;
|
|
const format = video.format;
|
|
const thumbnailFile = video.thumbnail.split("/")[4];
|
|
let pathToDelete = path.join(__dirname, "../uploads/videos/", slug + "." + format);
|
|
fs.unlink(pathToDelete, (error) => {
|
|
if (error) {
|
|
logger.write(error, 500);
|
|
res.status(500).json({"message": "Failed to delete video"});
|
|
return
|
|
}
|
|
|
|
pathToDelete = path.join(__dirname, "../uploads/thumbnails/", thumbnailFile);
|
|
fs.unlink(pathToDelete, async (error) => {
|
|
if (error) {
|
|
logger.write(error, 500);
|
|
res.status(500).json({"message": "Failed to delete video"});
|
|
return
|
|
}
|
|
const query = `DELETE FROM videos WHERE id = ${id}`;
|
|
await client.query(query);
|
|
logger.write("successfully deleted video", 200);
|
|
res.status(200).json({"message": "Successfully deleted video"});
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
export async function toggleLike(req, res) {
|
|
const id = req.params.id;
|
|
const logger = req.body.logger;
|
|
logger.action("try to toggle like on video " + id);
|
|
const token = req.headers.authorization.split(" ")[1];
|
|
const claims = jwt.decode(token);
|
|
const client = await getClient();
|
|
const userId = claims.id;
|
|
|
|
const getLikeQuery = `SELECT * FROM likes WHERE owner = ${userId} AND video = ${id}`;
|
|
const likeResult = await client.query(getLikeQuery);
|
|
|
|
if (likeResult.rows.length === 0) {
|
|
const query = `INSERT INTO likes (video, owner) VALUES (${id},${userId})`;
|
|
await client.query(query);
|
|
logger.write("no likes found adding likes for video " + id, 200);
|
|
res.status(200).json({"message": "Successfully added like"});
|
|
} else {
|
|
const query = `DELETE FROM likes WHERE owner = ${userId} AND video = ${id}`;
|
|
await client.query(query);
|
|
logger.write("likes found, removing like for video " + id, 200);
|
|
res.status(200).json({"message": "Successfully removed like"});
|
|
}
|
|
|
|
|
|
}
|
|
|
|
export async function addTags(req, res) {
|
|
const tags = req.body.tags;
|
|
const videoId = req.params.id;
|
|
|
|
const logger = req.body.logger;
|
|
logger.action("try to add tags to video " + videoId);
|
|
|
|
const client = await getClient();
|
|
|
|
// DECREASE USAGE COUNT FOR ALL TAGS
|
|
const decreaseUsageCountQuery = `UPDATE tags SET usage_count = usage_count - 1 WHERE id IN (SELECT tag FROM video_tags WHERE video = ${videoId})`;
|
|
await client.query(decreaseUsageCountQuery);
|
|
|
|
// DELETE ALL TAGS FOR VIDEO
|
|
let deleteQuery = `DELETE FROM video_tags WHERE video = ${videoId}`;
|
|
await client.query(deleteQuery);
|
|
|
|
// INSERT NEW TAGS
|
|
for (const tag of tags) {
|
|
const tagQuery = `SELECT * FROM tags WHERE name = '${tag}'`;
|
|
const tagResult = await client.query(tagQuery);
|
|
let id = null;
|
|
|
|
if (tagResult.rows.length === 0) {
|
|
const insertTagQuery = `INSERT INTO tags (name, usage_count) VALUES ('${tag}', 1) RETURNING id`;
|
|
const result = await client.query(insertTagQuery);
|
|
id = result.rows[0].id;
|
|
} else {
|
|
logger.write("Tag " + tag + " already exists for video " + videoId, 200);
|
|
const getTagQuery = `SELECT usage_count FROM tags WHERE name = '${tag}'`;
|
|
const getTagResult = await client.query(getTagQuery);
|
|
const usageCount = getTagResult.rows[0].usage_count + 1;
|
|
const updateTagQuery = `UPDATE tags SET usage_count = ${usageCount} WHERE name = '${tag}'`;
|
|
await client.query(updateTagQuery);
|
|
id = tagResult.rows[0].id;
|
|
}
|
|
|
|
console.log("Tag ID: ", id);
|
|
console.log("Video ID: ", videoId);
|
|
|
|
// INSERT INTO video_tags
|
|
const insertVideoTagQuery = `INSERT INTO video_tags (tag, video) VALUES (${id}, ${videoId})`;
|
|
await client.query(insertVideoTagQuery);
|
|
}
|
|
logger.write("successfully added tags to video " + videoId, 200);
|
|
await client.end();
|
|
res.status(200).json({"message": "Successfully added tags to video"});
|
|
|
|
}
|