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.
166 lines
6.1 KiB
166 lines
6.1 KiB
import {getClient} from "../utils/database.js";
|
|
|
|
|
|
export async function getRecommendations(req, res) {
|
|
|
|
const token = req.headers.authorization?.split(' ')[1];
|
|
|
|
if (!req.headers.authorization || !token) {
|
|
|
|
// GET MOST USED TAGS
|
|
let client = await getClient();
|
|
let queryMostUsedTags = `SELECT id, name FROM tags ORDER BY usage_count DESC LIMIT 3;`;
|
|
let result = await client.query(queryMostUsedTags);
|
|
|
|
// GET 10 VIDEOS WITH THE TAGS
|
|
|
|
let tagIds = result.rows.map(tag => tag.id);
|
|
let queryVideosWithTags = `
|
|
|
|
SELECT
|
|
v.id,
|
|
v.title,
|
|
v.thumbnail,
|
|
v.description AS video_description,
|
|
v.channel,
|
|
v.visibility,
|
|
v.file,
|
|
v.slug,
|
|
v.release_date,
|
|
v.channel AS channel_id,
|
|
c.owner,
|
|
COUNT(h.id) AS views,
|
|
json_build_object(
|
|
'name', c.name,
|
|
'profilePicture', u.picture,
|
|
'description', c.description
|
|
) AS creator,
|
|
'video' AS type
|
|
FROM public.videos v
|
|
INNER JOIN public.video_tags vt ON v.id = vt.video
|
|
INNER JOIN public.tags t ON vt.tag = t.id
|
|
INNER JOIN public.channels c ON v.channel = c.id
|
|
INNER JOIN public.users u ON c.owner = u.id
|
|
LEFT JOIN public.history h ON h.video = v.id
|
|
WHERE t.id = ANY($1::int[])
|
|
AND v.visibility = 'public'
|
|
GROUP BY
|
|
v.id,
|
|
v.title,
|
|
v.thumbnail,
|
|
v.description,
|
|
v.channel,
|
|
v.visibility,
|
|
v.file,
|
|
v.slug,
|
|
v.release_date,
|
|
c.owner,
|
|
c.name,
|
|
u.picture,
|
|
c.description
|
|
ORDER BY views DESC, v.release_date DESC
|
|
LIMIT 10;
|
|
|
|
`;
|
|
let videoResult = await client.query(queryVideosWithTags, [tagIds]);
|
|
const recommendations = videoResult.rows;
|
|
res.status(200).json(recommendations);
|
|
|
|
} else {
|
|
|
|
// Recuperer les 20 derniere vu de l'historique
|
|
let client = await getClient();
|
|
let queryLastVideos = `SELECT video_id FROM history WHERE user_id = $1 ORDER BY viewed_at DESC LIMIT 20;`;
|
|
// TODO: Implement retrieval of recommendations based on user history and interactions
|
|
|
|
// Recuperer les likes de l'utilisateur sur les 20 derniere videos recuperees
|
|
|
|
// Recuperer les commentaires de l'utilisateur sur les 20 derniere videos recuperees
|
|
|
|
// Recuperer les 3 tags avec lesquels l'utilisateur a le plus interagi
|
|
|
|
// Recuperer 10 videos avec les 3 tags ayant le plus d'interaction avec l'utilisateur
|
|
|
|
client.end()
|
|
res.status(200).json({
|
|
message: "Recommendations based on user history and interactions are not yet implemented."
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
export async function getTrendingVideos(req, res) {
|
|
try {
|
|
// GET 10 VIDEOS WITH THE MOST LIKES AND COMMENTS
|
|
let client = await getClient();
|
|
let queryTrendingVideos = `
|
|
SELECT v.id, v.title, v.description, v.release_date, v.thumbnail, v.visibility,
|
|
COUNT(DISTINCT l.id) AS like_count, COUNT(DISTINCT c.id) AS comment_count
|
|
FROM videos v
|
|
LEFT JOIN likes l ON v.id = l.video
|
|
LEFT JOIN comments c ON v.id = c.video
|
|
WHERE v.visibility = 'public'
|
|
GROUP BY v.id
|
|
ORDER BY like_count DESC, comment_count DESC
|
|
LIMIT 10
|
|
`;
|
|
let result = await client.query(queryTrendingVideos);
|
|
const trendingVideos = result.rows;
|
|
|
|
for (let video of trendingVideos) {
|
|
// Get the number of views for each video
|
|
let viewsQuery = `SELECT COUNT(*) AS view_count FROM history WHERE video = $1;`;
|
|
let viewsResult = await client.query(viewsQuery, [video.id]);
|
|
video.views = viewsResult.rows[0].view_count;
|
|
|
|
// Get the creator of each video
|
|
let creatorQuery = `SELECT c.id, c.name FROM channels c JOIN videos v ON c.id = v.channel WHERE v.id = $1;`;
|
|
let creatorResult = await client.query(creatorQuery, [video.id]);
|
|
if (creatorResult.rows.length > 0) {
|
|
video.creator = creatorResult.rows[0];
|
|
} else {
|
|
video.creator = {id: null, name: "Unknown"};
|
|
}
|
|
|
|
// GET THE PROFILE PICTURE OF THE CREATOR
|
|
let profilePictureQuery = `SELECT u.picture FROM users u JOIN channels c ON u.id = c.owner WHERE c.id = $1;`;
|
|
let profilePictureResult = await client.query(profilePictureQuery, [video.creator.id]);
|
|
if (profilePictureResult.rows.length > 0) {
|
|
video.creator.profilePicture = profilePictureResult.rows[0].picture;
|
|
} else {
|
|
video.creator.profilePicture = null; // Default or placeholder image can be set here
|
|
}
|
|
|
|
}
|
|
|
|
client.end();
|
|
res.status(200).json(trendingVideos);
|
|
} catch (error) {
|
|
console.error("Error fetching trending videos:", error);
|
|
res.status(500).json({error: "Internal server error while fetching trending videos."});
|
|
}
|
|
}
|
|
|
|
export async function getTopCreators(req, res) {
|
|
try {
|
|
// GET TOP 5 CREATORS BASED ON NUMBER OF SUBSCRIBERS
|
|
let client = await getClient();
|
|
let queryTopCreators = `
|
|
SELECT c.id, c.name, c.description, u.picture AS profilePicture, COUNT(s.id) AS subscriber_count
|
|
FROM channels c
|
|
JOIN users u ON c.owner = u.id
|
|
LEFT JOIN subscriptions s ON c.id = s.channel
|
|
GROUP BY c.id, u.picture
|
|
ORDER BY subscriber_count DESC
|
|
LIMIT 10;
|
|
`;
|
|
let result = await client.query(queryTopCreators);
|
|
const topCreators = result.rows;
|
|
|
|
client.end();
|
|
res.status(200).json(topCreators);
|
|
} catch (error) {
|
|
console.error("Error fetching top creators:", error);
|
|
res.status(500).json({error: "Internal server error while fetching top creators."});
|
|
}
|
|
}
|