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.
302 lines
11 KiB
302 lines
11 KiB
import {getClient} from "../utils/database.js";
|
|
import jwt from "jsonwebtoken";
|
|
|
|
|
|
export async function create(req, res) {
|
|
const { name } = req.body;
|
|
const token = req.headers.authorization.split(' ')[1];
|
|
const userId = jwt.decode(token)["id"];
|
|
const logger = req.body.logger;
|
|
|
|
const client = await getClient();
|
|
const query = `INSERT INTO playlists (name, owner) VALUES ($1, $2) RETURNING id`;
|
|
|
|
try {
|
|
const result = await client.query(query, [name, userId]);
|
|
logger.write("Playlist created with id " + result.rows[0].id, 200);
|
|
client.end()
|
|
res.status(200).json({ id: result.rows[0].id });
|
|
} catch (error) {
|
|
logger.write("Error creating playlist: " + error.message, 500);
|
|
client.end();
|
|
res.status(500).json({ error: "Internal server error" });
|
|
}
|
|
}
|
|
|
|
export async function addVideo(req, res) {
|
|
const { id } = req.params;
|
|
const { video } = req.body;
|
|
const logger = req.body.logger;
|
|
|
|
const client = await getClient();
|
|
const query = `INSERT INTO playlist_elements (video, playlist) VALUES ($1, $2) RETURNING id`;
|
|
try {
|
|
const result = await client.query(query, [video, id]);
|
|
logger.write("Video added to playlist with id " + id, 200);
|
|
client.end();
|
|
res.status(200).json({id: result.rows[0].id});
|
|
} catch (error) {
|
|
logger.write("Error adding video to playlist: " + error.message, 500);
|
|
client.end();
|
|
res.status(500).json({error: "Internal server error"});
|
|
}
|
|
}
|
|
|
|
export async function getByUser(req, res) {
|
|
const { id } = req.params;
|
|
const logger = req.body.logger;
|
|
|
|
const client = await getClient();
|
|
const query = `
|
|
SELECT *
|
|
FROM (
|
|
SELECT playlists.id, playlists.name, playlists.owner, v.thumbnail as thumbnail,
|
|
ROW_NUMBER() OVER (PARTITION BY playlists.id ORDER BY pt.id DESC) as rn
|
|
FROM playlists
|
|
LEFT JOIN playlist_elements pt on playlist = playlists.id
|
|
LEFT JOIN videos v on pt.video = v.id
|
|
WHERE owner = $1
|
|
) ranked
|
|
WHERE rn = 1 OR rn IS NULL
|
|
`;
|
|
|
|
try {
|
|
const result = await client.query(query, [id]);
|
|
if (result.rows.length === 0) {
|
|
logger.write("No playlists found for user with id " + id, 404);
|
|
client.end();
|
|
res.status(404).json({ error: "No playlists found" });
|
|
return;
|
|
}
|
|
logger.write("Playlists retrieved for user with id " + id, 200);
|
|
client.end();
|
|
res.status(200).json(result.rows);
|
|
} catch (error) {
|
|
logger.write("Error retrieving playlists: " + error.message, 500);
|
|
client.end();
|
|
res.status(500).json({ error: "Internal server error" });
|
|
}
|
|
}
|
|
|
|
export async function getById(req, res) {
|
|
const { id } = req.params;
|
|
const logger = req.body.logger;
|
|
|
|
const client = await getClient();
|
|
const query = `
|
|
SELECT
|
|
playlists.id,
|
|
playlists.name,
|
|
COALESCE(
|
|
JSON_AGG(
|
|
JSON_BUILD_OBJECT(
|
|
'id', video_data.id,
|
|
'title', video_data.title,
|
|
'thumbnail', video_data.thumbnail,
|
|
'video_description', video_data.description,
|
|
'channel', video_data.channel,
|
|
'visibility', video_data.visibility,
|
|
'file', video_data.file,
|
|
'slug', video_data.slug,
|
|
'format', video_data.format,
|
|
'release_date', video_data.release_date,
|
|
'channel_id', video_data.channel,
|
|
'owner', channels.owner,
|
|
'views', CAST(video_data.views AS TEXT),
|
|
'creator', JSON_BUILD_OBJECT(
|
|
'name', channels.name,
|
|
'profilePicture', users.picture,
|
|
'description', channels.description
|
|
),
|
|
'type', 'video'
|
|
)
|
|
) FILTER (WHERE video_data.id IS NOT NULL),
|
|
'[]'::json
|
|
) AS videos
|
|
FROM
|
|
playlists
|
|
LEFT JOIN playlist_elements ON playlists.id = playlist_elements.playlist
|
|
LEFT JOIN (
|
|
SELECT
|
|
videos.id,
|
|
videos.title,
|
|
videos.description,
|
|
videos.thumbnail,
|
|
videos.release_date,
|
|
videos.visibility,
|
|
videos.file,
|
|
videos.slug,
|
|
videos.format,
|
|
videos.channel,
|
|
COUNT(history.id) AS views
|
|
FROM videos
|
|
LEFT JOIN history ON history.video = videos.id
|
|
GROUP BY videos.id, videos.title, videos.description, videos.thumbnail, videos.release_date, videos.visibility, videos.file, videos.slug, videos.format, videos.channel
|
|
) video_data ON playlist_elements.video = video_data.id
|
|
LEFT JOIN channels ON video_data.channel = channels.id
|
|
LEFT JOIN users ON channels.owner = users.id
|
|
WHERE
|
|
playlists.id = $1
|
|
GROUP BY
|
|
playlists.id;
|
|
`;
|
|
|
|
try {
|
|
const result = await client.query(query, [id]);
|
|
if (result.rows.length === 0) {
|
|
logger.write("No playlist found with id " + id, 404);
|
|
client.end();
|
|
res.status(404).json({ error: "Playlist not found" });
|
|
return;
|
|
}
|
|
logger.write("Playlist retrieved with id " + id, 200);
|
|
client.end();
|
|
res.status(200).json(result.rows[0]);
|
|
} catch (error) {
|
|
logger.write("Error retrieving playlist: " + error.message, 500);
|
|
client.end();
|
|
res.status(500).json({ error: "Internal server error" });
|
|
}
|
|
}
|
|
|
|
export async function update(req, res) {
|
|
const { id } = req.params;
|
|
const { name } = req.body;
|
|
const logger = req.body.logger;
|
|
|
|
const client = await getClient();
|
|
const query = `UPDATE playlists SET name = $1 WHERE id = $2 RETURNING id`;
|
|
|
|
try {
|
|
const result = await client.query(query, [name, id]);
|
|
if (result.rows.length === 0) {
|
|
logger.write("No playlist found with id " + id, 404);
|
|
client.end();
|
|
res.status(404).json({ error: "Playlist not found", result: result.rows, query: query });
|
|
return;
|
|
}
|
|
logger.write("Playlist updated with id " + result.rows[0].id, 200);
|
|
client.end();
|
|
res.status(200).json({ id: result.rows[0].id });
|
|
} catch (error) {
|
|
logger.write("Error updating playlist: " + error.message, 500);
|
|
client.end();
|
|
res.status(500).json({ error: "Internal server error" });
|
|
}
|
|
}
|
|
|
|
export async function deleteVideo(req, res) {
|
|
const { id, videoId } = req.params;
|
|
const logger = req.body.logger;
|
|
|
|
const client = await getClient();
|
|
const query = `DELETE FROM playlist_elements WHERE video = $1 AND playlist = $2 RETURNING id`;
|
|
|
|
try {
|
|
const result = await client.query(query, [videoId, id]);
|
|
if (result.rows.length === 0) {
|
|
logger.write("No video found in playlist with id " + id, 404);
|
|
client.end();
|
|
res.status(404).json({ error: "Video not found in playlist" });
|
|
return;
|
|
}
|
|
logger.write("Video deleted from playlist with id " + id, 200);
|
|
client.end();
|
|
res.status(200).json({ id: result.rows[0].id });
|
|
} catch (error) {
|
|
logger.write("Error deleting video from playlist: " + error.message, 500);
|
|
client.end();
|
|
res.status(500).json({ error: "Internal server error" });
|
|
}
|
|
}
|
|
|
|
export async function del(req, res) {
|
|
const { id } = req.params;
|
|
const logger = req.body.logger;
|
|
|
|
const client = await getClient();
|
|
const query = `DELETE FROM playlists WHERE id = $1 RETURNING id`;
|
|
|
|
try {
|
|
const result = await client.query(query, [id]);
|
|
logger.write("Playlist deleted", 200);
|
|
client.end()
|
|
res.status(200).json({ "message": "playlist deleted" });
|
|
} catch (error) {
|
|
logger.write("Error deleting playlist: " + error.message, 500);
|
|
client.end();
|
|
res.status(500).json({ error: "Internal server error" });
|
|
}
|
|
}
|
|
|
|
export async function getSeeLater(req, res) {
|
|
|
|
const token = req.headers.authorization.split(' ')[1];
|
|
const userId = jwt.decode(token)["id"];
|
|
const logger = req.body.logger;
|
|
|
|
const client = await getClient();
|
|
const query = `
|
|
SELECT
|
|
JSON_AGG(
|
|
json_build_object(
|
|
'video_id', videos.id,
|
|
'title', videos.title,
|
|
'thumbnail', videos.thumbnail,
|
|
'video_decscription', videos.description,
|
|
'channel', videos.channel,
|
|
'visibility', videos.visibility,
|
|
'file', videos.file,
|
|
'format', videos.format,
|
|
'release_date', videos.release_date,
|
|
'channel_id', channels.id,
|
|
'owner', channels.owner,
|
|
'views', COALESCE(video_views.view_count, 0),
|
|
'creator', json_build_object(
|
|
'name', channels.name,
|
|
'profilePicture', users.picture,
|
|
'description', channels.description
|
|
)
|
|
)
|
|
) AS videos
|
|
FROM
|
|
public.playlists
|
|
LEFT JOIN public.playlist_elements ON public.playlists.id = public.playlist_elements.playlist
|
|
LEFT JOIN (
|
|
SELECT
|
|
*
|
|
FROM public.videos
|
|
LIMIT 10
|
|
) videos ON public.playlist_elements.video = videos.id
|
|
LEFT JOIN public.channels ON videos.channel = public.channels.id
|
|
LEFT JOIN public.users ON public.channels.owner = public.users.id
|
|
LEFT JOIN (
|
|
SELECT video, COUNT(*) as view_count
|
|
FROM public.history
|
|
GROUP BY video
|
|
) video_views ON videos.id = video_views.video
|
|
WHERE
|
|
playlists.owner = $1
|
|
GROUP BY playlists.id, playlists.name
|
|
ORDER BY
|
|
playlists.id ASC
|
|
LIMIT 1;
|
|
`;
|
|
try {
|
|
const result = await client.query(query, [userId]);
|
|
if (result.rows.length === 0) {
|
|
logger.write("No 'See Later' playlist found for user with id " + userId, 404);
|
|
client.end();
|
|
res.status(404).json({ error: "'See Later' playlist not found" });
|
|
return;
|
|
}
|
|
logger.write("'See Later' playlist retrieved for user with id " + userId, 200);
|
|
client.end();
|
|
res.status(200).json(result.rows[0].videos);
|
|
} catch (error) {
|
|
logger.write("Error retrieving 'See Later' playlist: " + error.message, 500);
|
|
client.end();
|
|
res.status(500).json({ error: "Internal server error" });
|
|
}
|
|
|
|
}
|