Initial commit - Projet Managerr
This commit is contained in:
commit
848a79a04e
36 changed files with 3850 additions and 0 deletions
100
backend/controllers/authController.js
Normal file
100
backend/controllers/authController.js
Normal 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');
|
||||
}
|
||||
};
|
||||
83
backend/controllers/radarrController.js
Normal file
83
backend/controllers/radarrController.js
Normal 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' });
|
||||
}
|
||||
};
|
||||
112
backend/controllers/settingsController.js
Normal file
112
backend/controllers/settingsController.js
Normal 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' });
|
||||
}
|
||||
};
|
||||
76
backend/controllers/sonarrController.js
Normal file
76
backend/controllers/sonarrController.js
Normal 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' });
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue