365 lines
12 KiB
JavaScript
365 lines
12 KiB
JavaScript
/**
|
|
* Lycostorrent - Admin Latest Categories
|
|
* Configuration des catégories par tracker pour les nouveautés
|
|
*/
|
|
|
|
let allTrackers = [];
|
|
let selectedTracker = null;
|
|
let trackerCategories = {}; // Catégories disponibles par tracker
|
|
let config = {}; // Configuration sauvegardée
|
|
|
|
// Initialisation
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
loadTrackers();
|
|
loadConfig();
|
|
|
|
document.getElementById('saveConfigBtn').addEventListener('click', saveConfig);
|
|
document.getElementById('resetConfigBtn').addEventListener('click', resetCurrentTracker);
|
|
});
|
|
|
|
// ============================================================
|
|
// CHARGEMENT DES DONNÉES
|
|
// ============================================================
|
|
|
|
async function loadTrackers() {
|
|
try {
|
|
const response = await fetch('/api/trackers');
|
|
const data = await response.json();
|
|
|
|
if (data.success) {
|
|
allTrackers = data.trackers;
|
|
displayTrackerSelector(allTrackers);
|
|
} else {
|
|
showMessage('Erreur lors du chargement des trackers', 'error');
|
|
}
|
|
} catch (error) {
|
|
console.error('Erreur:', error);
|
|
showMessage('Impossible de charger les trackers', 'error');
|
|
}
|
|
}
|
|
|
|
async function loadConfig() {
|
|
try {
|
|
const response = await fetch('/api/admin/latest-config');
|
|
const data = await response.json();
|
|
|
|
if (data.success) {
|
|
config = data.config || {};
|
|
displayConfigSummary();
|
|
}
|
|
} catch (error) {
|
|
console.error('Erreur chargement config:', error);
|
|
config = {};
|
|
}
|
|
}
|
|
|
|
async function loadTrackerCategories(trackerId) {
|
|
try {
|
|
document.getElementById('availableCategories').innerHTML = '<p class="loading">Chargement des catégories...</p>';
|
|
|
|
const response = await fetch(`/api/admin/tracker-categories/${trackerId}`);
|
|
const data = await response.json();
|
|
|
|
if (data.success) {
|
|
trackerCategories[trackerId] = data.categories;
|
|
displayAvailableCategories(data.categories);
|
|
} else {
|
|
document.getElementById('availableCategories').innerHTML = '<p class="error">Impossible de charger les catégories</p>';
|
|
}
|
|
} catch (error) {
|
|
console.error('Erreur:', error);
|
|
document.getElementById('availableCategories').innerHTML = '<p class="error">Erreur de connexion</p>';
|
|
}
|
|
}
|
|
|
|
// ============================================================
|
|
// AFFICHAGE
|
|
// ============================================================
|
|
|
|
function displayTrackerSelector(trackers) {
|
|
const container = document.getElementById('trackerSelector');
|
|
|
|
if (trackers.length === 0) {
|
|
container.innerHTML = '<p class="no-data">Aucun tracker configuré dans Jackett</p>';
|
|
return;
|
|
}
|
|
|
|
container.innerHTML = trackers.map(tracker => `
|
|
<button class="tracker-btn" data-tracker-id="${tracker.id}" data-tracker-name="${tracker.name}">
|
|
${tracker.name}
|
|
${config[tracker.id] ? '<span class="configured-badge">✓</span>' : ''}
|
|
</button>
|
|
`).join('');
|
|
|
|
// Event listeners
|
|
container.querySelectorAll('.tracker-btn').forEach(btn => {
|
|
btn.addEventListener('click', function() {
|
|
selectTracker(this.dataset.trackerId, this.dataset.trackerName);
|
|
});
|
|
});
|
|
}
|
|
|
|
function selectTracker(trackerId, trackerName) {
|
|
selectedTracker = trackerId;
|
|
|
|
// Mettre à jour l'UI
|
|
document.querySelectorAll('.tracker-btn').forEach(btn => btn.classList.remove('active'));
|
|
document.querySelector(`[data-tracker-id="${trackerId}"]`).classList.add('active');
|
|
|
|
document.getElementById('selectedTrackerName').textContent = trackerName;
|
|
document.getElementById('configTrackerName').textContent = trackerName;
|
|
|
|
// Afficher les sections
|
|
document.getElementById('categoriesSection').classList.remove('hidden');
|
|
document.getElementById('configSection').classList.remove('hidden');
|
|
|
|
// Charger les catégories du tracker
|
|
loadTrackerCategories(trackerId);
|
|
|
|
// Remplir les inputs avec la config existante
|
|
fillConfigInputs(trackerId);
|
|
}
|
|
|
|
function displayAvailableCategories(categories) {
|
|
const container = document.getElementById('availableCategories');
|
|
|
|
if (!categories || categories.length === 0) {
|
|
container.innerHTML = '<p class="no-data">Aucune catégorie trouvée pour ce tracker</p>';
|
|
return;
|
|
}
|
|
|
|
// Grouper par type (milliers)
|
|
const grouped = {};
|
|
categories.forEach(cat => {
|
|
const prefix = Math.floor(parseInt(cat.id) / 1000) * 1000;
|
|
if (!grouped[prefix]) grouped[prefix] = [];
|
|
grouped[prefix].push(cat);
|
|
});
|
|
|
|
const prefixNames = {
|
|
1000: '🎮 Console/Jeux',
|
|
2000: '🎥 Films',
|
|
3000: '🎵 Audio/Musique',
|
|
4000: '💻 PC/Logiciels',
|
|
5000: '📺 TV/Séries',
|
|
6000: '📦 Autre',
|
|
7000: '📚 Livres',
|
|
8000: '📦 Autre'
|
|
};
|
|
|
|
let html = '<div class="categories-grid">';
|
|
|
|
for (const [prefix, cats] of Object.entries(grouped).sort((a, b) => a[0] - b[0])) {
|
|
html += `
|
|
<div class="category-group">
|
|
<h4>${prefixNames[prefix] || `Catégorie ${prefix}`}</h4>
|
|
<div class="category-list">
|
|
${cats.map(cat => `
|
|
<div class="category-item" data-id="${cat.id}">
|
|
<span class="cat-id">${cat.id}</span>
|
|
<span class="cat-name">${escapeHtml(cat.name)}</span>
|
|
<button class="btn-add-cat" title="Ajouter">+</button>
|
|
</div>
|
|
`).join('')}
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
html += '</div>';
|
|
container.innerHTML = html;
|
|
|
|
// Event listeners pour les boutons d'ajout
|
|
container.querySelectorAll('.btn-add-cat').forEach(btn => {
|
|
btn.addEventListener('click', function() {
|
|
const catId = this.parentElement.dataset.id;
|
|
showAddCategoryModal(catId);
|
|
});
|
|
});
|
|
|
|
// Mettre à jour les quick-add buttons
|
|
updateQuickAddButtons(categories);
|
|
}
|
|
|
|
function updateQuickAddButtons(categories) {
|
|
const targets = ['movies', 'tv', 'anime', 'music'];
|
|
|
|
targets.forEach(target => {
|
|
const container = document.querySelector(`.quick-add[data-target="${target}"]`);
|
|
if (!container) return;
|
|
|
|
// Filtrer les catégories pertinentes
|
|
let relevantCats = [];
|
|
switch (target) {
|
|
case 'movies':
|
|
relevantCats = categories.filter(c => c.id.startsWith('2'));
|
|
break;
|
|
case 'tv':
|
|
relevantCats = categories.filter(c => c.id.startsWith('5') && !c.name.toLowerCase().includes('anime'));
|
|
break;
|
|
case 'anime':
|
|
relevantCats = categories.filter(c => c.name.toLowerCase().includes('anime'));
|
|
break;
|
|
case 'music':
|
|
relevantCats = categories.filter(c => c.id.startsWith('3'));
|
|
break;
|
|
}
|
|
|
|
if (relevantCats.length > 0) {
|
|
container.innerHTML = `
|
|
<div class="quick-add-label">Ajout rapide:</div>
|
|
${relevantCats.slice(0, 6).map(cat => `
|
|
<button class="quick-add-btn" data-id="${cat.id}" data-target="${target}" title="${escapeHtml(cat.name)}">
|
|
${cat.id}
|
|
</button>
|
|
`).join('')}
|
|
`;
|
|
|
|
container.querySelectorAll('.quick-add-btn').forEach(btn => {
|
|
btn.addEventListener('click', function() {
|
|
addCategoryToInput(this.dataset.target, this.dataset.id);
|
|
});
|
|
});
|
|
} else {
|
|
container.innerHTML = '';
|
|
}
|
|
});
|
|
}
|
|
|
|
function addCategoryToInput(target, catId) {
|
|
const input = document.getElementById(`config-${target}`);
|
|
const currentValue = input.value.trim();
|
|
const categories = currentValue ? currentValue.split(',').map(c => c.trim()) : [];
|
|
|
|
if (!categories.includes(catId)) {
|
|
categories.push(catId);
|
|
input.value = categories.join(',');
|
|
}
|
|
}
|
|
|
|
function showAddCategoryModal(catId) {
|
|
const target = prompt(`Ajouter la catégorie ${catId} à quel type ?\n\nOptions: movies, tv, anime, music`);
|
|
if (target && ['movies', 'tv', 'anime', 'music'].includes(target.toLowerCase())) {
|
|
addCategoryToInput(target.toLowerCase(), catId);
|
|
showMessage(`Catégorie ${catId} ajoutée à ${target}`, 'success');
|
|
}
|
|
}
|
|
|
|
function fillConfigInputs(trackerId) {
|
|
const trackerConfig = config[trackerId] || {};
|
|
|
|
document.getElementById('config-movies').value = trackerConfig.movies || '';
|
|
document.getElementById('config-tv').value = trackerConfig.tv || '';
|
|
document.getElementById('config-anime').value = trackerConfig.anime || '';
|
|
document.getElementById('config-music').value = trackerConfig.music || '';
|
|
}
|
|
|
|
function displayConfigSummary() {
|
|
const container = document.getElementById('configSummary');
|
|
|
|
if (Object.keys(config).length === 0) {
|
|
container.innerHTML = '<p class="no-data">Aucune configuration sauvegardée. Les catégories par défaut seront utilisées.</p>';
|
|
return;
|
|
}
|
|
|
|
let html = '<table class="summary-table"><thead><tr><th>Tracker</th><th>Films</th><th>Séries</th><th>Anime</th><th>Musique</th></tr></thead><tbody>';
|
|
|
|
for (const [trackerId, trackerConfig] of Object.entries(config)) {
|
|
const tracker = allTrackers.find(t => t.id === trackerId);
|
|
const trackerName = tracker ? tracker.name : trackerId;
|
|
|
|
html += `
|
|
<tr>
|
|
<td><strong>${escapeHtml(trackerName)}</strong></td>
|
|
<td>${trackerConfig.movies || '-'}</td>
|
|
<td>${trackerConfig.tv || '-'}</td>
|
|
<td>${trackerConfig.anime || '-'}</td>
|
|
<td>${trackerConfig.music || '-'}</td>
|
|
</tr>
|
|
`;
|
|
}
|
|
|
|
html += '</tbody></table>';
|
|
container.innerHTML = html;
|
|
|
|
// Mettre à jour les badges "configuré"
|
|
displayTrackerSelector(allTrackers);
|
|
}
|
|
|
|
// ============================================================
|
|
// SAUVEGARDE
|
|
// ============================================================
|
|
|
|
async function saveConfig() {
|
|
if (!selectedTracker) {
|
|
showMessage('Veuillez sélectionner un tracker', 'error');
|
|
return;
|
|
}
|
|
|
|
const trackerConfig = {
|
|
movies: document.getElementById('config-movies').value.trim(),
|
|
tv: document.getElementById('config-tv').value.trim(),
|
|
anime: document.getElementById('config-anime').value.trim(),
|
|
music: document.getElementById('config-music').value.trim()
|
|
};
|
|
|
|
// Supprimer les entrées vides
|
|
Object.keys(trackerConfig).forEach(key => {
|
|
if (!trackerConfig[key]) delete trackerConfig[key];
|
|
});
|
|
|
|
config[selectedTracker] = trackerConfig;
|
|
|
|
try {
|
|
const response = await fetch('/api/admin/latest-config', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ config })
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (data.success) {
|
|
showMessage('Configuration sauvegardée !', 'success');
|
|
displayConfigSummary();
|
|
} else {
|
|
showMessage(data.error || 'Erreur lors de la sauvegarde', 'error');
|
|
}
|
|
} catch (error) {
|
|
console.error('Erreur:', error);
|
|
showMessage('Erreur de connexion', 'error');
|
|
}
|
|
}
|
|
|
|
function resetCurrentTracker() {
|
|
if (!selectedTracker) return;
|
|
|
|
if (confirm('Réinitialiser la configuration de ce tracker ?')) {
|
|
document.getElementById('config-movies').value = '';
|
|
document.getElementById('config-tv').value = '';
|
|
document.getElementById('config-anime').value = '';
|
|
document.getElementById('config-music').value = '';
|
|
|
|
delete config[selectedTracker];
|
|
showMessage('Configuration réinitialisée (pensez à sauvegarder)', 'info');
|
|
}
|
|
}
|
|
|
|
// ============================================================
|
|
// UTILITAIRES
|
|
// ============================================================
|
|
|
|
function showMessage(message, type = 'info') {
|
|
const messageBox = document.getElementById('messageBox');
|
|
messageBox.textContent = message;
|
|
messageBox.className = `message-box ${type}`;
|
|
messageBox.classList.remove('hidden');
|
|
setTimeout(() => messageBox.classList.add('hidden'), 4000);
|
|
}
|
|
|
|
function escapeHtml(text) {
|
|
if (!text) return '';
|
|
const div = document.createElement('div');
|
|
div.textContent = text;
|
|
return div.innerHTML;
|
|
} |