Initial commit - Projet Managerr

This commit is contained in:
mahek 2025-07-21 15:43:20 +02:00
commit 848a79a04e
36 changed files with 3850 additions and 0 deletions

View file

@ -0,0 +1,100 @@
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const User = require('../models/User');
// Inscription d'un nouvel utilisateur
exports.register = async (req, res) => {
try {
const { username, email, password } = req.body;
// Vérifier si l'utilisateur existe déjà
let user = await User.findOne({ email });
if (user) {
return res.status(400).json({ message: 'Cet utilisateur existe déjà' });
}
// Créer un nouvel utilisateur
user = new User({
username,
email,
password
});
// Hashage du mot de passe
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
// Sauvegarder l'utilisateur dans la base de données
await user.save();
// Générer un token JWT
const payload = {
user: {
id: user.id
}
};
jwt.sign(
payload,
process.env.JWT_SECRET || 'secret',
{ expiresIn: '24h' },
(err, token) => {
if (err) throw err;
res.json({ token });
}
);
} catch (err) {
console.error(err.message);
res.status(500).send('Erreur serveur');
}
};
// Connexion d'un utilisateur
exports.login = async (req, res) => {
try {
const { email, password } = req.body;
// Vérifier si l'utilisateur existe
const user = await User.findOne({ email });
if (!user) {
return res.status(400).json({ message: 'Identifiants invalides' });
}
// Vérifier le mot de passe
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) {
return res.status(400).json({ message: 'Identifiants invalides' });
}
// Générer un token JWT
const payload = {
user: {
id: user.id
}
};
jwt.sign(
payload,
process.env.JWT_SECRET || 'secret',
{ expiresIn: '24h' },
(err, token) => {
if (err) throw err;
res.json({ token });
}
);
} catch (err) {
console.error(err.message);
res.status(500).send('Erreur serveur');
}
};
// Récupérer les informations de l'utilisateur connecté
exports.getMe = async (req, res) => {
try {
const user = await User.findById(req.user.id).select('-password');
res.json(user);
} catch (err) {
console.error(err.message);
res.status(500).send('Erreur serveur');
}
};

View file

@ -0,0 +1,83 @@
const axios = require('axios');
const config = require('../../config/radarr');
// Client API pour Radarr
const radarrClient = axios.create({
baseURL: config.baseURL,
headers: {
'X-Api-Key': config.apiKey
}
});
// Récupérer tous les films
exports.getAllMovies = async (req, res) => {
try {
const response = await radarrClient.get('/movie');
res.json(response.data);
} catch (error) {
console.error('Erreur lors de la récupération des films:', error);
res.status(500).json({ message: 'Erreur lors de la récupération des films' });
}
};
// Récupérer les films manquants
exports.getMissingMovies = async (req, res) => {
try {
const response = await radarrClient.get('/movie');
const missingMovies = response.data.filter(movie => !movie.hasFile);
res.json(missingMovies);
} catch (error) {
console.error('Erreur lors de la récupération des films manquants:', error);
res.status(500).json({ message: 'Erreur lors de la récupération des films manquants' });
}
};
// Récupérer les films à venir
exports.getUpcomingMovies = async (req, res) => {
try {
const today = new Date();
const response = await radarrClient.get('/movie');
const upcomingMovies = response.data.filter(movie => {
const releaseDate = new Date(movie.digitalRelease || movie.physicalRelease || movie.inCinemas);
return releaseDate > today;
});
res.json(upcomingMovies);
} catch (error) {
console.error('Erreur lors de la récupération des films à venir:', error);
res.status(500).json({ message: 'Erreur lors de la récupération des films à venir' });
}
};
// Récupérer l'historique des téléchargements
exports.getHistory = async (req, res) => {
try {
const response = await radarrClient.get('/history');
res.json(response.data);
} catch (error) {
console.error('Erreur lors de la récupération de l\'historique:', error);
res.status(500).json({ message: 'Erreur lors de la récupération de l\'historique' });
}
};
// Récupérer le calendrier
exports.getCalendar = async (req, res) => {
try {
const { start, end } = req.query;
const startDate = start || new Date().toISOString();
const endDate = end || new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString();
const response = await radarrClient.get('/calendar', {
params: {
start: startDate,
end: endDate
}
});
res.json(response.data);
} catch (error) {
console.error('Erreur lors de la récupération du calendrier:', error);
res.status(500).json({ message: 'Erreur lors de la récupération du calendrier' });
}
};

View file

@ -0,0 +1,112 @@
const Settings = require('../models/Settings');
const axios = require('axios');
// Récupérer les paramètres de l'utilisateur connecté
exports.getSettings = async (req, res) => {
try {
// Rechercher les paramètres pour l'utilisateur connecté
const settings = await Settings.findOne({ user: req.user.id });
if (!settings) {
return res.status(404).json({ message: "Aucun paramètre trouvé pour cet utilisateur" });
}
// Ne pas envoyer l'ID de l'utilisateur ni l'ID du document dans la réponse
const { sonarr, radarr } = settings;
res.json({ sonarr, radarr });
} catch (error) {
console.error('Erreur lors de la récupération des paramètres:', error);
res.status(500).json({ message: 'Erreur serveur' });
}
};
// Sauvegarder ou mettre à jour les paramètres
exports.saveSettings = async (req, res) => {
try {
const { sonarr, radarr } = req.body;
// Validation des entrées
if (!sonarr || !radarr) {
return res.status(400).json({ message: 'Les configurations Sonarr et Radarr sont requises' });
}
if (!sonarr.url || !sonarr.apiKey || !radarr.url || !radarr.apiKey) {
return res.status(400).json({ message: 'Tous les champs sont requis' });
}
// Vérifier si l'utilisateur a déjà des paramètres
let settings = await Settings.findOne({ user: req.user.id });
if (settings) {
// Mettre à jour les paramètres existants
settings.sonarr = sonarr;
settings.radarr = radarr;
settings.updatedAt = Date.now();
} else {
// Créer de nouveaux paramètres
settings = new Settings({
user: req.user.id,
sonarr,
radarr
});
}
await settings.save();
res.json({ message: 'Paramètres enregistrés avec succès' });
} catch (error) {
console.error('Erreur lors de l\'enregistrement des paramètres:', error);
res.status(500).json({ message: 'Erreur serveur' });
}
};
// Tester la connexion à une API (Sonarr ou Radarr)
exports.testConnection = async (req, res) => {
try {
const { type, url, apiKey } = req.body;
// Validation des entrées
if (!type || !url || !apiKey) {
return res.status(400).json({ message: 'Type, URL et clé API sont requis' });
}
if (type !== 'sonarr' && type !== 'radarr') {
return res.status(400).json({ message: 'Type invalide. Doit être "sonarr" ou "radarr"' });
}
// Tentative de connexion à l'API
try {
// Utiliser le endpoint /system/status qui est disponible à la fois sur Sonarr et Radarr
const response = await axios.get(`${url}/system/status`, {
headers: {
'X-Api-Key': apiKey
},
timeout: 5000 // Timeout de 5 secondes
});
if (response.status === 200) {
res.json({
success: true,
message: 'Connexion établie avec succès',
details: {
version: response.data.version,
appName: response.data.appName
}
});
} else {
res.status(400).json({ success: false, message: 'Échec de la connexion' });
}
} catch (apiError) {
console.error(`Erreur lors du test de l'API ${type}:`, apiError);
res.status(400).json({
success: false,
message: 'Échec de la connexion',
error: apiError.message
});
}
} catch (error) {
console.error('Erreur lors du test de connexion:', error);
res.status(500).json({ message: 'Erreur serveur' });
}
};

View file

@ -0,0 +1,76 @@
const axios = require('axios');
const config = require('../../config/sonarr');
// Client API pour Sonarr
const sonarrClient = axios.create({
baseURL: config.baseURL,
headers: {
'X-Api-Key': config.apiKey
}
});
// Récupérer toutes les séries
exports.getAllSeries = async (req, res) => {
try {
const response = await sonarrClient.get('/series');
res.json(response.data);
} catch (error) {
console.error('Erreur lors de la récupération des séries:', error);
res.status(500).json({ message: 'Erreur lors de la récupération des séries' });
}
};
// Récupérer les séries manquantes
exports.getMissingSeries = async (req, res) => {
try {
const response = await sonarrClient.get('/wanted/missing');
res.json(response.data);
} catch (error) {
console.error('Erreur lors de la récupération des séries manquantes:', error);
res.status(500).json({ message: 'Erreur lors de la récupération des séries manquantes' });
}
};
// Récupérer les séries à venir
exports.getUpcomingSeries = async (req, res) => {
try {
const response = await sonarrClient.get('/calendar', {
params: {
start: new Date().toISOString(),
end: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString() // 30 jours
}
});
res.json(response.data);
} catch (error) {
console.error('Erreur lors de la récupération des séries à venir:', error);
res.status(500).json({ message: 'Erreur lors de la récupération des séries à venir' });
}
};
// Récupérer l'historique des téléchargements
exports.getHistory = async (req, res) => {
try {
const response = await sonarrClient.get('/history');
res.json(response.data);
} catch (error) {
console.error('Erreur lors de la récupération de l\'historique:', error);
res.status(500).json({ message: 'Erreur lors de la récupération de l\'historique' });
}
};
// Récupérer le calendrier
exports.getCalendar = async (req, res) => {
try {
const { start, end } = req.query;
const response = await sonarrClient.get('/calendar', {
params: {
start: start || new Date().toISOString(),
end: end || new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString()
}
});
res.json(response.data);
} catch (error) {
console.error('Erreur lors de la récupération du calendrier:', error);
res.status(500).json({ message: 'Erreur lors de la récupération du calendrier' });
}
};