refactor: add full documentation and fix theme loading robustness

- Add JSDoc comments across frontend and backend modules
- Improve code readability and maintainability with consistent documentation style
- Document Electron IPC handlers, UI utilities, and theme system
- Add missing function/class documentation in theme loader and app services
- Minor structural improvements and cleanup across Electron main process modules
- Minor fixes on variable names
This commit is contained in:
MasterAcnolo
2026-05-31 20:38:42 +02:00
parent 6afc5e06d6
commit 0218664c5a
34 changed files with 1777 additions and 340 deletions

View File

@@ -3,70 +3,114 @@ const { parseVideo, parsePlaylist } = require("../helpers/parseInfo.helpers");
const { logger } = require("../logger");
const { isValidUrl } = require("../helpers/validation.helpers");
async function infoController(req, res){
/**
* Handles metadata retrieval for a video or playlist.
*
* This controller:
* - Validates incoming URL (query or body)
* - Calls yt-dlp metadata extraction service
* - Detects playlist vs single video context
* - Applies fallback strategy if playlist extraction fails
* - Returns normalized parsed response (video or playlist)
*
* @param {import("express").Request} req
* @param {import("express").Response} res
*/
async function infoController(req, res) {
const url = req.body.url || req.query.url; // POST et GET
const url = req.body.url || req.query.url; // Supports POST and GET requests
// If no url, non-string url or invalid url
if (!url || typeof url !== "string" || !isValidUrl(url)) return res.status(400).send("Invalid URL Or Missing");
logger.info(`/Info Request receive by the Info Controller. URL: ${url}`);
if (url.includes("&list") || url.includes("?list")) {
logger.info("Estimated Data Type: Playlist")
} else{
logger.info("Estimated Data Type: Video")
/**
* Basic validation:
* - URL must exist
* - Must be a string
* - Must pass custom URL validation
*/
if (!url || typeof url !== "string" || !isValidUrl(url)) {
return res.status(400).send("Invalid URL Or Missing");
}
try {
let data;
let fetchError = null;
logger.info(`Info request received. URL: ${url}`);
// Lightweight heuristic to detect playlist URLs
const isPlaylistUrl = url.includes("&list") || url.includes("?list");
logger.info(
isPlaylistUrl
? "Estimated Data Type: Playlist"
: "Estimated Data Type: Video"
);
try {
data = await fetchInfo(url);
} catch (err) {
fetchError = err;
// If it's a playlist URL and fetch failed, try fetching just the single video
if ((url.includes("&list") || url.includes("?list"))) {
logger.info(`Playlist fetch failed: ${err.message}. Retrying with single video...`);
// Remove the &list parameter
const singleVideoUrl = url.split("&list")[0].split("?list")[0];
try {
data = await fetchInfo(singleVideoUrl);
logger.info(`Single video fetch succeeded after playlist failure`);
} catch (retryErr) {
logger.error(`Single video fetch also failed: ${retryErr.message}`);
throw err; // Throw the original error
let data;
/**
* Primary metadata fetch attempt
*/
try {
data = await fetchInfo(url);
} catch (err) {
/**
* Fallback strategy:
* If playlist extraction fails, retry as single video
*/
if (isPlaylistUrl) {
logger.info(
`Playlist fetch failed: ${err.message}. Retrying as single video...`
);
// Remove playlist query parameter (best-effort cleanup)
const singleVideoUrl = url.split("&list")[0].split("?list")[0];
try {
data = await fetchInfo(singleVideoUrl);
logger.info("Single video fetch succeeded after playlist failure");
} catch (retryErr) {
logger.error(
`Single video fetch also failed: ${retryErr.message}`
);
// Preserve original error context
throw err;
}
} else {
throw err;
}
} else {
throw err;
}
}
if (data._type === "playlist") {
/**
* Normalize response based on yt-dlp output type
*/
if (data._type === "playlist") {
const playlist = parsePlaylist(data);
logger.info(`Playlist : ${playlist.title} (${playlist.count} vidéos)`);
return res.json(playlist);
const playlist = parsePlaylist(data);
} else{
const video = parseVideo(data);
logger.info(`Unique Video: ${video.title}`);
return res.json(video);
}
logger.info(
`Playlist fetched: ${playlist.title} (${playlist.count} videos)`
);
return res.json(playlist);
} else {
const video = parseVideo(data);
logger.info(`Video fetched: ${video.title}`);
return res.json(video);
}
} catch (err) {
logger.error(`Info controller error: ${err && err.message ? err.message : err}`);
return res.status(500).send(`Unable to fetch info`);
logger.error(
`Info controller error: ${err && err.message ? err.message : err}`
);
return res.status(500).send("Unable to fetch info");
}
}
module.exports = {infoController};
module.exports = { infoController };