Initial commit
This commit is contained in:
880
app/templates/admin.html
Normal file
880
app/templates/admin.html
Normal file
@@ -0,0 +1,880 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Lycostorrent - Administration</title>
|
||||
|
||||
<!-- Chargement du thème (en premier pour éviter le flash) -->
|
||||
<script src="/static/js/theme-loader.js"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="theme-color" content="#e63946">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="apple-mobile-web-app-title" content="Lycostorrent">
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/static/manifest.json">
|
||||
|
||||
<!-- Icons -->
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/static/icons/icon-192x192.png">
|
||||
<link rel="apple-touch-icon" href="/static/icons/icon-192x192.png">
|
||||
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="stylesheet" href="/static/css/themes.css">
|
||||
<link rel="stylesheet" href="/static/css/admin.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- Header -->
|
||||
<header class="header">
|
||||
<h1>⚙️ Administration</h1>
|
||||
<p class="subtitle">Configuration de Lycostorrent</p>
|
||||
<nav class="main-nav" id="mainNav">
|
||||
<!-- Navigation générée dynamiquement -->
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<!-- Onglets -->
|
||||
<div class="admin-tabs">
|
||||
<button class="tab-btn active" data-tab="modules">
|
||||
<span class="tab-icon">🧩</span>
|
||||
<span class="tab-label">Modules</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="categories">
|
||||
<span class="tab-icon">📂</span>
|
||||
<span class="tab-label">Catégories</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="tags">
|
||||
<span class="tab-icon">🏷️</span>
|
||||
<span class="tab-label">Tags</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="filters">
|
||||
<span class="tab-icon">🎛️</span>
|
||||
<span class="tab-label">Filtres</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="rss">
|
||||
<span class="tab-icon">📡</span>
|
||||
<span class="tab-label">Flux RSS</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="cache">
|
||||
<span class="tab-icon">🔄</span>
|
||||
<span class="tab-label">Cache</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="torrent-client">
|
||||
<span class="tab-icon">⬇️</span>
|
||||
<span class="tab-label">Client Torrent</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="appearance">
|
||||
<span class="tab-icon">🎨</span>
|
||||
<span class="tab-label">Apparence</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Contenu des onglets -->
|
||||
<div class="admin-content">
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════
|
||||
ONGLET MODULES
|
||||
═══════════════════════════════════════════════════════════ -->
|
||||
<div id="tab-modules" class="tab-content active">
|
||||
<div class="tab-header">
|
||||
<h2>🧩 Modules</h2>
|
||||
<p>Activez ou désactivez les fonctionnalités de Lycostorrent.</p>
|
||||
</div>
|
||||
|
||||
<div class="admin-card">
|
||||
<h3>📱 Fonctionnalités disponibles</h3>
|
||||
<p class="help-text">Cochez les modules que vous souhaitez activer. La navigation s'adaptera automatiquement.</p>
|
||||
|
||||
<div class="modules-list">
|
||||
<div class="module-item">
|
||||
<div class="module-toggle">
|
||||
<input type="checkbox" id="module-search" checked>
|
||||
<label for="module-search"></label>
|
||||
</div>
|
||||
<div class="module-info">
|
||||
<div class="module-header">
|
||||
<span class="module-icon">🔍</span>
|
||||
<span class="module-name">Recherche</span>
|
||||
</div>
|
||||
<p class="module-description">Recherche de torrents sur vos trackers configurés (Jackett/Prowlarr).</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="module-item">
|
||||
<div class="module-toggle">
|
||||
<input type="checkbox" id="module-latest" checked>
|
||||
<label for="module-latest"></label>
|
||||
</div>
|
||||
<div class="module-info">
|
||||
<div class="module-header">
|
||||
<span class="module-icon">🎬</span>
|
||||
<span class="module-name">Nouveautés</span>
|
||||
</div>
|
||||
<p class="module-description">Dernières sorties depuis vos trackers (Films, Séries, Anime, Musique).</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="module-item">
|
||||
<div class="module-toggle">
|
||||
<input type="checkbox" id="module-discover">
|
||||
<label for="module-discover"></label>
|
||||
</div>
|
||||
<div class="module-info">
|
||||
<div class="module-header">
|
||||
<span class="module-icon">🌟</span>
|
||||
<span class="module-name">Découvrir</span>
|
||||
<span class="module-badge">Nouveau</span>
|
||||
</div>
|
||||
<p class="module-description">Explorez les nouveautés cinéma et TV depuis TMDb, puis trouvez les torrents disponibles.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="action-bar">
|
||||
<button id="saveModulesBtn" class="btn btn-primary">💾 Sauvegarder</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Configuration des trackers pour Discover -->
|
||||
<div class="admin-card" id="discoverTrackersCard">
|
||||
<h3>🌟 Trackers pour Découvrir</h3>
|
||||
<p class="help-text">Sélectionnez les trackers à utiliser pour la recherche de torrents dans la page Découvrir.</p>
|
||||
|
||||
<div class="discover-trackers-list" id="discoverTrackersList">
|
||||
<p class="loading">Chargement des trackers...</p>
|
||||
</div>
|
||||
|
||||
<div class="action-bar">
|
||||
<button id="selectAllDiscoverTrackers" class="btn btn-secondary">✅ Tout sélectionner</button>
|
||||
<button id="selectNoneDiscoverTrackers" class="btn btn-secondary">❌ Tout désélectionner</button>
|
||||
<button id="saveDiscoverTrackers" class="btn btn-primary">💾 Sauvegarder</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="admin-card">
|
||||
<h3>ℹ️ À propos des modules</h3>
|
||||
<div class="module-help">
|
||||
<p><strong>🔍 Recherche</strong> : Page d'accueil par défaut. Permet de rechercher des torrents par mots-clés sur tous vos trackers.</p>
|
||||
<p><strong>🎬 Nouveautés</strong> : Affiche les derniers torrents publiés sur vos trackers, enrichis avec les métadonnées TMDb/Last.fm.</p>
|
||||
<p><strong>🌟 Découvrir</strong> : Inverse la logique - part des nouveautés TMDb (films/séries récents) et recherche les torrents disponibles.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════
|
||||
ONGLET CATÉGORIES
|
||||
═══════════════════════════════════════════════════════════ -->
|
||||
<div id="tab-categories" class="tab-content">
|
||||
<div class="tab-header">
|
||||
<h2>📂 Configuration des Catégories</h2>
|
||||
<p>Associez les catégories Jackett/Prowlarr à chaque type de contenu pour chaque tracker.</p>
|
||||
</div>
|
||||
|
||||
<!-- Sélection du tracker -->
|
||||
<div class="admin-card">
|
||||
<h3>1. Sélectionner un tracker</h3>
|
||||
<div id="trackerSelector" class="tracker-grid">
|
||||
<p class="loading">Chargement des trackers...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Catégories disponibles -->
|
||||
<div id="categoriesSection" class="admin-card hidden">
|
||||
<h3>2. Catégories disponibles sur <span id="selectedTrackerName" class="highlight"></span></h3>
|
||||
<div id="availableCategories" class="categories-cloud">
|
||||
<p class="loading">Chargement...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Configuration -->
|
||||
<div id="configSection" class="admin-card hidden">
|
||||
<h3>3. Associer les catégories</h3>
|
||||
<p class="help-text">Cliquez sur une catégorie ci-dessus pour l'ajouter, ou entrez les IDs manuellement.</p>
|
||||
|
||||
<div class="config-grid">
|
||||
<div class="config-item">
|
||||
<label>🎥 Films</label>
|
||||
<input type="text" id="config-movies" placeholder="Ex: 2000,2010">
|
||||
<div class="quick-add" data-target="movies"></div>
|
||||
</div>
|
||||
<div class="config-item">
|
||||
<label>📺 Séries</label>
|
||||
<input type="text" id="config-tv" placeholder="Ex: 5000,5010">
|
||||
<div class="quick-add" data-target="tv"></div>
|
||||
</div>
|
||||
<div class="config-item">
|
||||
<label>🎌 Anime</label>
|
||||
<input type="text" id="config-anime" placeholder="Ex: 5070">
|
||||
<div class="quick-add" data-target="anime"></div>
|
||||
</div>
|
||||
<div class="config-item">
|
||||
<label>🎵 Musique</label>
|
||||
<input type="text" id="config-music" placeholder="Ex: 3000">
|
||||
<div class="quick-add" data-target="music"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="action-bar">
|
||||
<button id="saveConfigBtn" class="btn btn-primary">💾 Sauvegarder</button>
|
||||
<button id="resetConfigBtn" class="btn btn-secondary">🔄 Réinitialiser</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Résumé -->
|
||||
<div class="admin-card">
|
||||
<h3>📋 Configuration actuelle</h3>
|
||||
<div id="configSummary" class="config-summary">
|
||||
<p class="loading">Chargement...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════
|
||||
ONGLET TAGS
|
||||
═══════════════════════════════════════════════════════════ -->
|
||||
<div id="tab-tags" class="tab-content">
|
||||
<div class="tab-header">
|
||||
<h2>🏷️ Tags de Parsing</h2>
|
||||
<p>Ces tags sont utilisés pour nettoyer les titres avant la recherche TMDb/Last.fm.</p>
|
||||
</div>
|
||||
|
||||
<!-- Tags actuels -->
|
||||
<div class="admin-card">
|
||||
<h3>Tags de coupure</h3>
|
||||
<p class="help-text">Le titre sera coupé au premier tag rencontré. Ex: <code>Avatar.2009.MULTi.1080p</code> → <code>Avatar 2009</code></p>
|
||||
|
||||
<div id="tagsList" class="tags-cloud editable">
|
||||
<p class="loading">Chargement...</p>
|
||||
</div>
|
||||
|
||||
<div class="add-form">
|
||||
<input type="text" id="newTagInput" placeholder="Nouveau tag..." maxlength="30">
|
||||
<button id="addTagBtn" class="btn btn-primary">➕ Ajouter</button>
|
||||
</div>
|
||||
|
||||
<div class="action-bar">
|
||||
<button id="saveTagsBtn" class="btn btn-primary">💾 Sauvegarder</button>
|
||||
<button id="resetTagsBtn" class="btn btn-secondary">🔄 Réinitialiser</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Présets -->
|
||||
<div class="admin-card">
|
||||
<h3>📦 Ajouter des présets</h3>
|
||||
<div class="presets-grid">
|
||||
<button class="preset-btn" data-preset="langues">
|
||||
🗣️ Langues
|
||||
<small>VFF, VFQ, VOSTFR...</small>
|
||||
</button>
|
||||
<button class="preset-btn" data-preset="resolutions">
|
||||
📺 Résolutions
|
||||
<small>1080p, 720p, 4K...</small>
|
||||
</button>
|
||||
<button class="preset-btn" data-preset="sources">
|
||||
📀 Sources
|
||||
<small>BluRay, WEB, HDTV...</small>
|
||||
</button>
|
||||
<button class="preset-btn" data-preset="codecs">
|
||||
🎬 Codecs
|
||||
<small>x264, x265, HEVC...</small>
|
||||
</button>
|
||||
<button class="preset-btn" data-preset="audio">
|
||||
🔊 Audio
|
||||
<small>DTS, AC3, FLAC...</small>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Test -->
|
||||
<div class="admin-card">
|
||||
<h3>🧪 Tester le parsing</h3>
|
||||
<div class="test-form">
|
||||
<input type="text" id="testTitleInput" placeholder="Ex: Avatar.2009.MULTi.1080p.BluRay.x264">
|
||||
<button id="testParsingBtn" class="btn btn-primary">Tester</button>
|
||||
</div>
|
||||
<div id="testResult" class="test-result hidden">
|
||||
<div class="result-row">
|
||||
<span class="label">Original:</span>
|
||||
<span id="testOriginal" class="value"></span>
|
||||
</div>
|
||||
<div class="result-row success">
|
||||
<span class="label">Nettoyé:</span>
|
||||
<span id="testCleaned" class="value"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════
|
||||
ONGLET FILTRES
|
||||
═══════════════════════════════════════════════════════════ -->
|
||||
<div id="tab-filters" class="tab-content">
|
||||
<div class="tab-header">
|
||||
<h2>🎛️ Filtres de Recherche</h2>
|
||||
<p>Configurez les mots-clés détectés dans les titres de torrents pour créer les filtres.</p>
|
||||
</div>
|
||||
|
||||
<!-- Liste des filtres -->
|
||||
<div class="admin-card">
|
||||
<h3>Filtres configurés</h3>
|
||||
<p class="help-text">Cliquez sur un filtre pour modifier ses valeurs. Les valeurs sont détectées dans les titres de torrents.</p>
|
||||
|
||||
<div id="filtersList" class="filters-editor">
|
||||
<p class="loading">Chargement...</p>
|
||||
</div>
|
||||
|
||||
<div class="action-bar">
|
||||
<button id="saveFiltersBtn" class="btn btn-primary">💾 Sauvegarder</button>
|
||||
<button id="resetFiltersBtn" class="btn btn-secondary">🔄 Réinitialiser</button>
|
||||
<button id="addFilterBtn" class="btn btn-secondary">➕ Nouveau filtre</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Test -->
|
||||
<div class="admin-card">
|
||||
<h3>🧪 Tester la détection</h3>
|
||||
<p class="help-text">Entrez un titre de torrent pour voir les filtres détectés.</p>
|
||||
<div class="test-form">
|
||||
<input type="text" id="testFilterInput" placeholder="Ex: Gojira.-.Fortitude.2021.FLAC.24bit.WEB.Album">
|
||||
<button id="testFilterBtn" class="btn btn-primary">Tester</button>
|
||||
</div>
|
||||
<div id="filterTestResult" class="test-result hidden"></div>
|
||||
</div>
|
||||
|
||||
<!-- Aide -->
|
||||
<div class="admin-card collapsible collapsed">
|
||||
<h3 class="collapsible-header">
|
||||
❓ Aide - Comment ça marche
|
||||
<span class="collapse-icon">▼</span>
|
||||
</h3>
|
||||
<div class="collapsible-content">
|
||||
<div class="help-section">
|
||||
<h4>Principe</h4>
|
||||
<p>Le parser analyse les titres de torrents et cherche les mots-clés configurés. Chaque mot trouvé crée une option de filtre.</p>
|
||||
|
||||
<h4>Exemple</h4>
|
||||
<p><code>Gojira.-.Fortitude.2021.FLAC.24bit.WEB.Album</code></p>
|
||||
<p>→ Format Audio: <strong>FLAC, 24bit</strong> | Type: <strong>Album</strong> | Source: <strong>WEB</strong></p>
|
||||
|
||||
<h4>Conseils</h4>
|
||||
<ul>
|
||||
<li>Les mots-clés sont insensibles à la casse (FLAC = flac = Flac)</li>
|
||||
<li>Évitez les mots trop courts ou trop communs</li>
|
||||
<li>Testez vos modifications avant de sauvegarder</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════
|
||||
ONGLET RSS
|
||||
═══════════════════════════════════════════════════════════ -->
|
||||
<div id="tab-rss" class="tab-content">
|
||||
<div class="tab-header">
|
||||
<h2>📡 Flux RSS</h2>
|
||||
<p>Ajoutez des flux RSS pour les trackers non disponibles dans Jackett/Prowlarr.</p>
|
||||
</div>
|
||||
|
||||
<!-- Formulaire d'ajout -->
|
||||
<div class="admin-card">
|
||||
<h3>➕ Ajouter un flux</h3>
|
||||
|
||||
<form id="add-feed-form" class="rss-form">
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="feed-name">Nom *</label>
|
||||
<input type="text" id="feed-name" placeholder="Ex: YGG Films" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="feed-category">Catégorie *</label>
|
||||
<select id="feed-category" required>
|
||||
<option value="">-- Choisir --</option>
|
||||
<option value="movies">🎬 Films</option>
|
||||
<option value="tv">📺 Séries</option>
|
||||
<option value="anime">🎌 Anime</option>
|
||||
<option value="music">🎵 Musique</option>
|
||||
<option value="all">📦 Toutes</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="feed-url">URL du flux RSS *</label>
|
||||
<input type="url" id="feed-url" placeholder="https://tracker.xxx/rss?passkey={passkey}" required>
|
||||
<small>Utilisez <code>{passkey}</code> comme placeholder</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="feed-passkey">Passkey</label>
|
||||
<input type="text" id="feed-passkey" placeholder="Votre passkey privé">
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group checkbox-inline">
|
||||
<label>
|
||||
<input type="checkbox" id="feed-flaresolverr">
|
||||
<span>🛡️ Flaresolverr</span>
|
||||
</label>
|
||||
<small>Anti-Cloudflare</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="feed-cookies">Cookies de session</label>
|
||||
<textarea id="feed-cookies" rows="2" placeholder="ygg_=abc123; cf_clearance=xyz789"></textarea>
|
||||
<small>Récupérez-les depuis DevTools (F12) → Application → Cookies</small>
|
||||
</div>
|
||||
|
||||
<div class="action-bar">
|
||||
<button type="button" id="test-feed-btn" class="btn btn-secondary">🧪 Tester</button>
|
||||
<button type="submit" class="btn btn-primary">➕ Ajouter</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div id="test-result" class="test-result hidden"></div>
|
||||
</div>
|
||||
|
||||
<!-- Liste des flux -->
|
||||
<div class="admin-card">
|
||||
<h3>📋 Flux configurés</h3>
|
||||
<div id="feeds-list" class="feeds-list">
|
||||
<p class="loading">Chargement...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Aide -->
|
||||
<div class="admin-card collapsible">
|
||||
<h3 class="collapsible-header">
|
||||
❓ Aide - Comment configurer un flux RSS
|
||||
<span class="collapse-icon">▼</span>
|
||||
</h3>
|
||||
<div class="collapsible-content">
|
||||
<div class="help-section">
|
||||
<h4>YGGTorrent</h4>
|
||||
<ol>
|
||||
<li>Connectez-vous à YGG</li>
|
||||
<li>Profil → "Mon RSS"</li>
|
||||
<li>Copiez l'URL avec votre passkey</li>
|
||||
</ol>
|
||||
|
||||
<h4>Catégories YGG</h4>
|
||||
<div class="help-table">
|
||||
<span class="help-row"><code>id=2145</code> Films</span>
|
||||
<span class="help-row"><code>id=2184</code> Séries</span>
|
||||
<span class="help-row"><code>id=2179</code> Anime</span>
|
||||
<span class="help-row"><code>id=2139</code> Musique</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════
|
||||
ONGLET CACHE
|
||||
═══════════════════════════════════════════════════════════ -->
|
||||
<div id="tab-cache" class="tab-content">
|
||||
<div class="tab-header">
|
||||
<h2>🔄 Cache des données</h2>
|
||||
<p>Pré-chargez les données Latest et Discover pour un affichage instantané.</p>
|
||||
</div>
|
||||
|
||||
<!-- Statut du cache -->
|
||||
<div class="admin-card">
|
||||
<h3>📊 Statut du cache</h3>
|
||||
<div id="cacheStatus" class="cache-status">
|
||||
<div class="status-row">
|
||||
<span class="status-label">État :</span>
|
||||
<span id="cacheStatusBadge" class="status-badge">Chargement...</span>
|
||||
</div>
|
||||
<div class="status-row">
|
||||
<span class="status-label">Dernier refresh :</span>
|
||||
<span id="cacheLastRefresh">-</span>
|
||||
</div>
|
||||
<div class="status-row">
|
||||
<span class="status-label">Prochain refresh :</span>
|
||||
<span id="cacheNextRefresh">-</span>
|
||||
</div>
|
||||
<div class="status-row">
|
||||
<span class="status-label">Taille du cache :</span>
|
||||
<span id="cacheSizeDisplay">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="action-bar" style="margin-top: 15px;">
|
||||
<button id="refreshCacheBtn" class="btn btn-primary">🔄 Forcer le refresh maintenant</button>
|
||||
<button id="clearCacheBtn" class="btn btn-secondary">🗑️ Vider le cache</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Configuration -->
|
||||
<div class="admin-card">
|
||||
<h3>⚙️ Configuration</h3>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="cacheEnabled">
|
||||
<input type="checkbox" id="cacheEnabled">
|
||||
Activer le cache automatique
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="cacheInterval">Intervalle de refresh</label>
|
||||
<select id="cacheInterval">
|
||||
<option value="15">15 minutes</option>
|
||||
<option value="30">30 minutes</option>
|
||||
<option value="60" selected>1 heure</option>
|
||||
<option value="120">2 heures</option>
|
||||
<option value="240">4 heures</option>
|
||||
<option value="360">6 heures</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Configuration Latest -->
|
||||
<div class="admin-card">
|
||||
<h3>📥 Cache Latest (Nouveautés)</h3>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="cacheLatestEnabled">
|
||||
<input type="checkbox" id="cacheLatestEnabled" checked>
|
||||
Activer le cache Latest
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label>Catégories à cacher :</label>
|
||||
<div class="checkbox-group">
|
||||
<label><input type="checkbox" id="cacheLatestMovies" checked> 🎥 Films</label>
|
||||
<label><input type="checkbox" id="cacheLatestTv" checked> 📺 Séries</label>
|
||||
<label><input type="checkbox" id="cacheLatestAnime"> 🎌 Anime</label>
|
||||
<label><input type="checkbox" id="cacheLatestMusic"> 🎵 Musique</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="cacheLatestLimit">Nombre de résultats par catégorie</label>
|
||||
<select id="cacheLatestLimit">
|
||||
<option value="30">30</option>
|
||||
<option value="50" selected>50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label>Trackers à utiliser :</label>
|
||||
<p class="help-text">Laissez vide pour utiliser tous les trackers actifs</p>
|
||||
<div id="cacheTrackersList" class="checkbox-group trackers-checkboxes">
|
||||
<!-- Rempli dynamiquement -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Configuration Discover -->
|
||||
<div class="admin-card">
|
||||
<h3>🎬 Cache Discover</h3>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="cacheDiscoverEnabled">
|
||||
<input type="checkbox" id="cacheDiscoverEnabled" checked>
|
||||
Activer le cache Discover
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="cacheDiscoverLimit">Nombre de films/séries à cacher</label>
|
||||
<select id="cacheDiscoverLimit">
|
||||
<option value="20">20</option>
|
||||
<option value="30" selected>30</option>
|
||||
<option value="50">50</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sauvegarder -->
|
||||
<div class="admin-card">
|
||||
<div class="action-bar">
|
||||
<button id="saveCacheConfigBtn" class="btn btn-primary">💾 Sauvegarder la configuration</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════
|
||||
ONGLET CLIENT TORRENT
|
||||
═══════════════════════════════════════════════════════════ -->
|
||||
<div id="tab-torrent-client" class="tab-content">
|
||||
<div class="tab-header">
|
||||
<h2>⬇️ Client Torrent</h2>
|
||||
<p>Configurez votre client torrent pour envoyer directement les téléchargements.</p>
|
||||
</div>
|
||||
|
||||
<!-- Statut -->
|
||||
<div class="admin-card">
|
||||
<h3>📊 Statut</h3>
|
||||
<div id="torrentClientStatus" class="client-status">
|
||||
<span class="status-loading">Chargement...</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Configuration -->
|
||||
<div class="admin-card">
|
||||
<h3>⚙️ Configuration</h3>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="tcEnabled">
|
||||
<input type="checkbox" id="tcEnabled">
|
||||
Activer le client torrent
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="tcPlugin">Client</label>
|
||||
<select id="tcPlugin">
|
||||
<option value="">-- Sélectionner --</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="tcHost">Hôte</label>
|
||||
<input type="text" id="tcHost" placeholder="geco.useed.me ou 192.168.1.x">
|
||||
<small class="form-help">Domaine ou IP (sans http://)</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="tcPort">Port</label>
|
||||
<input type="number" id="tcPort" placeholder="8080 ou vide">
|
||||
<small class="form-help">Laisser vide si port par défaut</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="tcPath">Chemin (optionnel)</label>
|
||||
<input type="text" id="tcPath" placeholder="/qbittorrent">
|
||||
<small class="form-help">Si derrière un reverse proxy</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="tcUsername">Utilisateur</label>
|
||||
<input type="text" id="tcUsername" placeholder="admin">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="tcPassword">Mot de passe</label>
|
||||
<input type="password" id="tcPassword" placeholder="••••••••">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="tcSSL">
|
||||
<input type="checkbox" id="tcSSL">
|
||||
Utiliser SSL (HTTPS)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="action-bar">
|
||||
<button id="testTorrentClientBtn" class="btn btn-secondary">🔌 Tester la connexion</button>
|
||||
<button id="saveTorrentClientBtn" class="btn btn-primary">💾 Sauvegarder</button>
|
||||
</div>
|
||||
|
||||
<div id="tcTestResult" class="test-result hidden"></div>
|
||||
</div>
|
||||
|
||||
<!-- Catégories personnalisées -->
|
||||
<div class="admin-card">
|
||||
<h3>📁 Catégories & Dossiers</h3>
|
||||
<p class="help-text">Définissez vos catégories avec leur dossier de destination par défaut.</p>
|
||||
|
||||
<div id="customCategoriesList" class="custom-categories-list">
|
||||
<!-- Rempli dynamiquement -->
|
||||
</div>
|
||||
|
||||
<div class="add-category-form">
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="newCategoryName">Nom de la catégorie</label>
|
||||
<input type="text" id="newCategoryName" placeholder="Films, Séries, Musique...">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="newCategoryPath">Chemin de destination</label>
|
||||
<input type="text" id="newCategoryPath" placeholder="/downloads/films">
|
||||
</div>
|
||||
<div class="form-group form-group-btn">
|
||||
<button id="addCategoryBtn" class="btn btn-success">➕ Ajouter</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="action-bar">
|
||||
<button id="syncCategoriesBtn" class="btn btn-secondary">🔄 Synchroniser avec le client</button>
|
||||
<button id="saveCategoriesBtn" class="btn btn-primary">💾 Sauvegarder</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Plugins disponibles -->
|
||||
<div class="admin-card collapsible collapsed">
|
||||
<h3 class="collapsible-header">
|
||||
🔌 Plugins disponibles
|
||||
<span class="collapse-icon">▼</span>
|
||||
</h3>
|
||||
<div class="collapsible-content">
|
||||
<div id="pluginsList" class="plugins-list">
|
||||
<p class="loading">Chargement...</p>
|
||||
</div>
|
||||
<p class="help-text">
|
||||
Pour ajouter un nouveau client, créez un plugin dans <code>plugins/torrent_clients/</code>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════
|
||||
ONGLET APPARENCE
|
||||
═══════════════════════════════════════════════════════════ -->
|
||||
<div id="tab-appearance" class="tab-content">
|
||||
<div class="tab-header">
|
||||
<h2>🎨 Apparence</h2>
|
||||
<p>Personnalisez l'apparence de Lycostorrent.</p>
|
||||
</div>
|
||||
|
||||
<!-- Sélection du thème -->
|
||||
<div class="admin-card">
|
||||
<h3>🎭 Thème</h3>
|
||||
<p class="help-text">Choisissez un thème pour l'interface.</p>
|
||||
|
||||
<div class="theme-grid">
|
||||
<div class="theme-card" data-theme="dark">
|
||||
<div class="theme-preview theme-preview-dark">
|
||||
<div class="preview-header"></div>
|
||||
<div class="preview-content">
|
||||
<div class="preview-card"></div>
|
||||
<div class="preview-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="theme-name">🌙 Sombre</span>
|
||||
</div>
|
||||
|
||||
<div class="theme-card" data-theme="light">
|
||||
<div class="theme-preview theme-preview-light">
|
||||
<div class="preview-header"></div>
|
||||
<div class="preview-content">
|
||||
<div class="preview-card"></div>
|
||||
<div class="preview-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="theme-name">☀️ Clair</span>
|
||||
</div>
|
||||
|
||||
<div class="theme-card" data-theme="ocean">
|
||||
<div class="theme-preview theme-preview-ocean">
|
||||
<div class="preview-header"></div>
|
||||
<div class="preview-content">
|
||||
<div class="preview-card"></div>
|
||||
<div class="preview-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="theme-name">🌊 Océan</span>
|
||||
</div>
|
||||
|
||||
<div class="theme-card" data-theme="purple">
|
||||
<div class="theme-preview theme-preview-purple">
|
||||
<div class="preview-header"></div>
|
||||
<div class="preview-content">
|
||||
<div class="preview-card"></div>
|
||||
<div class="preview-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="theme-name">💜 Violet</span>
|
||||
</div>
|
||||
|
||||
<div class="theme-card" data-theme="nature">
|
||||
<div class="theme-preview theme-preview-nature">
|
||||
<div class="preview-header"></div>
|
||||
<div class="preview-content">
|
||||
<div class="preview-card"></div>
|
||||
<div class="preview-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="theme-name">🌿 Nature</span>
|
||||
</div>
|
||||
|
||||
<div class="theme-card" data-theme="sunset">
|
||||
<div class="theme-preview theme-preview-sunset">
|
||||
<div class="preview-header"></div>
|
||||
<div class="preview-content">
|
||||
<div class="preview-card"></div>
|
||||
<div class="preview-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="theme-name">🌅 Sunset</span>
|
||||
</div>
|
||||
|
||||
<div class="theme-card" data-theme="cyberpunk">
|
||||
<div class="theme-preview theme-preview-cyberpunk">
|
||||
<div class="preview-header"></div>
|
||||
<div class="preview-content">
|
||||
<div class="preview-card"></div>
|
||||
<div class="preview-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="theme-name">🤖 Cyberpunk</span>
|
||||
</div>
|
||||
|
||||
<div class="theme-card" data-theme="nord">
|
||||
<div class="theme-preview theme-preview-nord">
|
||||
<div class="preview-header"></div>
|
||||
<div class="preview-content">
|
||||
<div class="preview-card"></div>
|
||||
<div class="preview-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="theme-name">❄️ Nord</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Message toast -->
|
||||
<div id="toast" class="toast hidden"></div>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="app-footer">
|
||||
<span>Lycostorrent v<span id="app-version">1.0.0</span></span>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/admin.js"></script>
|
||||
<script src="/static/js/nav.js"></script>
|
||||
<script>
|
||||
fetch('/api/version').then(r => r.json()).then(data => {
|
||||
if (data.version) document.getElementById('app-version').textContent = data.version;
|
||||
}).catch(() => {});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
105
app/templates/admin_latest.html
Normal file
105
app/templates/admin_latest.html
Normal file
@@ -0,0 +1,105 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Lycostorrent - Admin Nouveautés</title>
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="stylesheet" href="/static/css/admin.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- Header -->
|
||||
<header class="header">
|
||||
<h1>⚙️ Administration</h1>
|
||||
<p class="subtitle">Configuration des catégories pour les Nouveautés</p>
|
||||
<nav class="main-nav">
|
||||
<a href="/">🔍 Recherche</a>
|
||||
<a href="/latest">🎬 Nouveautés</a>
|
||||
<a href="/admin/latest" class="active">⚙️ Catégories</a>
|
||||
<a href="/admin/parsing">🏷️ Tags</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<!-- Instructions -->
|
||||
<div class="admin-info">
|
||||
<h3>ℹ️ Comment ça marche</h3>
|
||||
<p>Configurez les catégories Jackett à utiliser pour chaque type de contenu et chaque tracker.</p>
|
||||
<p>Les catégories sont les IDs numériques de Jackett (ex: 2000 = Films, 5000 = Séries).</p>
|
||||
</div>
|
||||
|
||||
<!-- Sélection du tracker -->
|
||||
<div class="admin-section">
|
||||
<h2>1. Sélectionner un tracker</h2>
|
||||
<div id="trackerSelector" class="tracker-selector">
|
||||
<p class="loading">Chargement des trackers...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Catégories du tracker sélectionné -->
|
||||
<div id="categoriesSection" class="admin-section hidden">
|
||||
<h2>2. Catégories disponibles sur <span id="selectedTrackerName"></span></h2>
|
||||
<div id="availableCategories" class="available-categories">
|
||||
<p class="loading">Chargement des catégories...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Configuration des catégories -->
|
||||
<div id="configSection" class="admin-section hidden">
|
||||
<h2>3. Configuration pour <span id="configTrackerName"></span></h2>
|
||||
|
||||
<div class="config-grid">
|
||||
<!-- Films -->
|
||||
<div class="config-card">
|
||||
<h3>🎥 Films</h3>
|
||||
<p class="config-description">Catégories pour les films</p>
|
||||
<input type="text" id="config-movies" placeholder="Ex: 2000,2010,2020">
|
||||
<div class="quick-add" data-target="movies"></div>
|
||||
</div>
|
||||
|
||||
<!-- Séries -->
|
||||
<div class="config-card">
|
||||
<h3>📺 Séries</h3>
|
||||
<p class="config-description">Catégories pour les séries TV</p>
|
||||
<input type="text" id="config-tv" placeholder="Ex: 5000,5010,5020">
|
||||
<div class="quick-add" data-target="tv"></div>
|
||||
</div>
|
||||
|
||||
<!-- Anime -->
|
||||
<div class="config-card">
|
||||
<h3>🎌 Anime</h3>
|
||||
<p class="config-description">Catégories pour les animes</p>
|
||||
<input type="text" id="config-anime" placeholder="Ex: 5070,5080">
|
||||
<div class="quick-add" data-target="anime"></div>
|
||||
</div>
|
||||
|
||||
<!-- Musique -->
|
||||
<div class="config-card">
|
||||
<h3>🎵 Musique</h3>
|
||||
<p class="config-description">Catégories pour la musique</p>
|
||||
<input type="text" id="config-music" placeholder="Ex: 3000,3010">
|
||||
<div class="quick-add" data-target="music"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="config-actions">
|
||||
<button id="saveConfigBtn" class="btn-primary">💾 Sauvegarder</button>
|
||||
<button id="resetConfigBtn" class="btn-secondary">🔄 Réinitialiser</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Résumé de la configuration -->
|
||||
<div id="summarySection" class="admin-section">
|
||||
<h2>📋 Résumé de la configuration</h2>
|
||||
<div id="configSummary" class="config-summary">
|
||||
<p class="loading">Chargement...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Messages -->
|
||||
<div id="messageBox" class="message-box hidden"></div>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/admin_latest.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
108
app/templates/admin_parsing.html
Normal file
108
app/templates/admin_parsing.html
Normal file
@@ -0,0 +1,108 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Lycostorrent - Tags de Parsing</title>
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="stylesheet" href="/static/css/admin.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- Header -->
|
||||
<header class="header">
|
||||
<h1>🏷️ Tags de Parsing</h1>
|
||||
<p class="subtitle">Mots-clés utilisés pour couper les titres de torrents</p>
|
||||
<nav class="main-nav">
|
||||
<a href="/">🔍 Recherche</a>
|
||||
<a href="/latest">🎬 Nouveautés</a>
|
||||
<a href="/admin/latest">⚙️ Catégories</a>
|
||||
<a href="/admin/parsing" class="active">🏷️ Tags</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<!-- Instructions -->
|
||||
<div class="admin-info">
|
||||
<h3>ℹ️ Comment ça marche</h3>
|
||||
<p>Ces tags sont utilisés pour <strong>couper</strong> les titres de torrents avant de chercher sur TMDb/Last.fm.</p>
|
||||
<p>Exemple: <code>Avatar.2009.MULTi.1080p.BluRay</code> → si "MULTi" est dans la liste, le titre sera coupé à <code>Avatar</code></p>
|
||||
<p><strong>⚠️ Attention:</strong> N'ajoutez pas de mots qui pourraient être des vrais titres (ex: "Intégrale", "Complete", "Extended").</p>
|
||||
</div>
|
||||
|
||||
<!-- Tags actuels -->
|
||||
<div class="admin-section">
|
||||
<h2>Tags de coupure actuels</h2>
|
||||
|
||||
<div class="tags-editor">
|
||||
<div id="tagsList" class="tags-list-editor">
|
||||
<p class="loading">Chargement...</p>
|
||||
</div>
|
||||
|
||||
<div class="add-tag-form">
|
||||
<input type="text" id="newTagInput" placeholder="Nouveau tag (ex: VOSTFR)" maxlength="30">
|
||||
<button id="addTagBtn" class="btn-primary">➕ Ajouter</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="config-actions">
|
||||
<button id="saveTagsBtn" class="btn-primary">💾 Sauvegarder</button>
|
||||
<button id="resetTagsBtn" class="btn-secondary">🔄 Réinitialiser (défaut)</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Présets -->
|
||||
<div class="admin-section">
|
||||
<h2>📦 Ajouter des présets</h2>
|
||||
<p class="config-description">Cliquez pour ajouter un groupe de tags courants</p>
|
||||
|
||||
<div class="presets-grid">
|
||||
<button class="preset-btn" data-preset="langues">
|
||||
🗣️ Langues<br>
|
||||
<small>VFF, VFQ, VOSTFR, FRENCH...</small>
|
||||
</button>
|
||||
<button class="preset-btn" data-preset="resolutions">
|
||||
📺 Résolutions<br>
|
||||
<small>1080p, 720p, 4K, UHD...</small>
|
||||
</button>
|
||||
<button class="preset-btn" data-preset="sources">
|
||||
📀 Sources<br>
|
||||
<small>BluRay, WEB, HDTV, REMUX...</small>
|
||||
</button>
|
||||
<button class="preset-btn" data-preset="codecs">
|
||||
🎬 Codecs<br>
|
||||
<small>x264, x265, HEVC, AV1...</small>
|
||||
</button>
|
||||
<button class="preset-btn" data-preset="audio">
|
||||
🔊 Audio<br>
|
||||
<small>DTS, AC3, FLAC, Atmos...</small>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Test -->
|
||||
<div class="admin-section">
|
||||
<h2>🧪 Tester le parsing</h2>
|
||||
<p class="config-description">Entrez un titre de torrent pour voir le résultat du nettoyage</p>
|
||||
|
||||
<div class="test-form">
|
||||
<input type="text" id="testTitleInput" placeholder="Ex: Avatar.2009.MULTi.1080p.BluRay.x264">
|
||||
<button id="testParsingBtn" class="btn-primary">🔍 Tester</button>
|
||||
</div>
|
||||
|
||||
<div id="testResult" class="test-result hidden">
|
||||
<div class="test-original">
|
||||
<strong>Original:</strong> <span id="testOriginal"></span>
|
||||
</div>
|
||||
<div class="test-cleaned">
|
||||
<strong>Nettoyé:</strong> <span id="testCleaned"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Messages -->
|
||||
<div id="messageBox" class="message-box hidden"></div>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/admin_parsing.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
126
app/templates/admin_rss.html
Normal file
126
app/templates/admin_rss.html
Normal file
@@ -0,0 +1,126 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Lycostorrent - Flux RSS</title>
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="stylesheet" href="/static/css/admin.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header class="header">
|
||||
<h1>🔗 Gestion des Flux RSS</h1>
|
||||
<p>Ajoutez des flux RSS pour récupérer les nouveautés de trackers non supportés par Jackett/Prowlarr</p>
|
||||
</header>
|
||||
|
||||
<nav class="admin-nav">
|
||||
<a href="/">🔍 Recherche</a>
|
||||
<a href="/latest">🎬 Nouveautés</a>
|
||||
<a href="/admin/latest">⚙️ Catégories</a>
|
||||
<a href="/admin/parsing">🏷️ Tags</a>
|
||||
<a href="/admin/rss" class="active">🔗 RSS</a>
|
||||
</nav>
|
||||
|
||||
<!-- Formulaire d'ajout -->
|
||||
<section class="admin-section">
|
||||
<h2>➕ Ajouter un flux RSS</h2>
|
||||
|
||||
<form id="add-feed-form" class="feed-form">
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="feed-name">Nom du flux *</label>
|
||||
<input type="text" id="feed-name" placeholder="Ex: YGG Films" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="feed-category">Catégorie *</label>
|
||||
<select id="feed-category" required>
|
||||
<option value="">-- Sélectionner --</option>
|
||||
<option value="movies">🎬 Films</option>
|
||||
<option value="tv">📺 Séries</option>
|
||||
<option value="anime">🎌 Anime</option>
|
||||
<option value="music">🎵 Musique</option>
|
||||
<option value="all">📦 Toutes</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="feed-url">URL du flux RSS *</label>
|
||||
<input type="url" id="feed-url" placeholder="https://tracker.xxx/rss?cat=films&passkey={passkey}" required>
|
||||
<small>Utilisez <code>{passkey}</code> comme placeholder pour le passkey</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="feed-passkey">Passkey (optionnel)</label>
|
||||
<input type="text" id="feed-passkey" placeholder="Votre passkey privé">
|
||||
<small>Sera injecté à la place de <code>{passkey}</code> dans l'URL</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group checkbox-group">
|
||||
<label class="checkbox-label">
|
||||
<input type="checkbox" id="feed-flaresolverr">
|
||||
<span>🛡️ Utiliser Flaresolverr (anti-Cloudflare)</span>
|
||||
</label>
|
||||
<small>Activer si le site est protégé par Cloudflare (erreur 403)</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="feed-cookies">Cookies de session (optionnel)</label>
|
||||
<textarea id="feed-cookies" rows="2" placeholder="ygg_=abc123; cf_clearance=xyz789"></textarea>
|
||||
<small>Format: <code>nom1=valeur1; nom2=valeur2</code> - Récupérez-les depuis les DevTools (F12) → Application → Cookies</small>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="button" id="test-feed-btn" class="btn btn-secondary">🧪 Tester</button>
|
||||
<button type="submit" class="btn btn-primary">➕ Ajouter</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Résultat du test -->
|
||||
<div id="test-result" class="test-result hidden"></div>
|
||||
</section>
|
||||
|
||||
<!-- Liste des flux configurés -->
|
||||
<section class="admin-section">
|
||||
<h2>📋 Flux RSS configurés</h2>
|
||||
|
||||
<div id="feeds-list" class="feeds-list">
|
||||
<p class="loading">Chargement...</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Aide -->
|
||||
<section class="admin-section help-section">
|
||||
<h2>❓ Comment trouver l'URL RSS ?</h2>
|
||||
|
||||
<div class="help-content">
|
||||
<h4>YGGTorrent</h4>
|
||||
<ol>
|
||||
<li>Connectez-vous à YGG</li>
|
||||
<li>Allez dans votre profil → "Mon RSS"</li>
|
||||
<li>Copiez l'URL avec votre passkey</li>
|
||||
<li>Format: <code>https://www3.yggtorrent.xxx/rss?cat=XXX&passkey=VOTRE_PASSKEY</code></li>
|
||||
</ol>
|
||||
|
||||
<h4>Autres trackers privés</h4>
|
||||
<ol>
|
||||
<li>Cherchez "RSS" dans les paramètres du tracker</li>
|
||||
<li>Générez un flux personnalisé avec les catégories souhaitées</li>
|
||||
<li>Copiez l'URL (contient généralement un passkey ou token)</li>
|
||||
</ol>
|
||||
|
||||
<h4>Catégories YGG courantes</h4>
|
||||
<table class="help-table">
|
||||
<tr><td>Films</td><td><code>cat=2145</code></td></tr>
|
||||
<tr><td>Séries</td><td><code>cat=2184</code></td></tr>
|
||||
<tr><td>Anime</td><td><code>cat=2179</code></td></tr>
|
||||
<tr><td>Musique</td><td><code>cat=2139</code></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/admin_rss.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
129
app/templates/discover.html
Normal file
129
app/templates/discover.html
Normal file
@@ -0,0 +1,129 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Lycostorrent - Découvrir</title>
|
||||
|
||||
<!-- Chargement du thème (en premier pour éviter le flash) -->
|
||||
<script src="/static/js/theme-loader.js"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="theme-color" content="#e63946">
|
||||
<meta name="description" content="Découvrez les nouveautés cinéma et TV">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="apple-mobile-web-app-title" content="Lycostorrent">
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/static/manifest.json">
|
||||
|
||||
<!-- Icons -->
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/static/icons/icon-192x192.png">
|
||||
<link rel="apple-touch-icon" href="/static/icons/icon-192x192.png">
|
||||
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="stylesheet" href="/static/css/themes.css">
|
||||
<link rel="stylesheet" href="/static/css/discover.css">
|
||||
<link rel="stylesheet" href="/static/css/cache-info.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- Header -->
|
||||
<header class="header">
|
||||
<h1>🌟 Lycostorrent</h1>
|
||||
<p class="subtitle">Découvrez les nouveautés cinéma & TV</p>
|
||||
<nav class="main-nav" id="mainNav">
|
||||
<!-- Navigation générée dynamiquement -->
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<!-- Catégories simplifiées : Films / Séries -->
|
||||
<div class="discover-tabs">
|
||||
<button class="discover-tab active" data-category="movies">🎬 Films récents</button>
|
||||
<button class="discover-tab" data-category="tv">📺 Séries en cours</button>
|
||||
</div>
|
||||
|
||||
<!-- Info cache -->
|
||||
<div id="cacheInfo" class="cache-info hidden">
|
||||
<span class="cache-badge">📦 Cache</span>
|
||||
<span id="cacheTimestamp" class="cache-timestamp"></span>
|
||||
<button id="refreshLiveBtn" class="btn-refresh" onclick="refreshLive()" title="Actualiser en direct">🔄</button>
|
||||
</div>
|
||||
|
||||
<!-- Grille de résultats -->
|
||||
<div class="discover-grid" id="discoverGrid">
|
||||
<!-- Rempli dynamiquement -->
|
||||
</div>
|
||||
|
||||
<!-- Loader -->
|
||||
<div class="discover-loader hidden" id="discoverLoader">
|
||||
<div class="spinner"></div>
|
||||
<span>Chargement...</span>
|
||||
</div>
|
||||
|
||||
<!-- Message d'état -->
|
||||
<div class="discover-empty hidden" id="discoverEmpty">
|
||||
<span class="empty-icon">🎬</span>
|
||||
<p>Sélectionnez une catégorie pour découvrir les nouveautés</p>
|
||||
</div>
|
||||
|
||||
<!-- Modal détails -->
|
||||
<div class="modal-overlay hidden" id="detailModal">
|
||||
<div class="modal-content detail-modal">
|
||||
<button class="modal-close" onclick="closeDetailModal()">✕</button>
|
||||
<div class="detail-header">
|
||||
<img src="" alt="" class="detail-poster" id="detailPoster">
|
||||
<div class="detail-info">
|
||||
<h2 id="detailTitle"></h2>
|
||||
<div class="detail-meta">
|
||||
<span class="detail-year" id="detailYear"></span>
|
||||
<span class="detail-rating" id="detailRating">⭐ --</span>
|
||||
</div>
|
||||
<p class="detail-overview" id="detailOverview"></p>
|
||||
<div class="detail-genres" id="detailGenres"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bande-annonce YouTube -->
|
||||
<div class="detail-trailer hidden" id="detailTrailer">
|
||||
<h3>🎬 Bande-annonce</h3>
|
||||
<div class="trailer-container">
|
||||
<iframe id="trailerFrame" src="" frameborder="0" allowfullscreen
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture">
|
||||
</iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-torrents">
|
||||
<h3>🔍 Torrents disponibles</h3>
|
||||
<div class="torrents-loading hidden" id="torrentsLoading">
|
||||
<div class="spinner-small"></div>
|
||||
<span>Recherche sur vos trackers...</span>
|
||||
</div>
|
||||
<div class="torrents-list" id="torrentsList">
|
||||
<!-- Rempli dynamiquement -->
|
||||
</div>
|
||||
<div class="torrents-empty hidden" id="torrentsEmpty">
|
||||
<p>Aucun torrent trouvé pour ce titre</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="app-footer">
|
||||
<span>Lycostorrent v<span id="app-version">1.0.0</span></span>
|
||||
<span class="tmdb-credit">Données fournies par <a href="https://www.themoviedb.org" target="_blank">TMDb</a></span>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/discover.js"></script>
|
||||
<script src="/static/js/nav.js"></script>
|
||||
<script>
|
||||
fetch('/api/version').then(r => r.json()).then(data => {
|
||||
if (data.version) document.getElementById('app-version').textContent = data.version;
|
||||
}).catch(() => {});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
133
app/templates/index.html
Normal file
133
app/templates/index.html
Normal file
@@ -0,0 +1,133 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Lycostorrent - Recherche</title>
|
||||
|
||||
<!-- Chargement du thème (en premier pour éviter le flash) -->
|
||||
<script src="/static/js/theme-loader.js"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="theme-color" content="#e63946">
|
||||
<meta name="description" content="Recherche de torrents avec enrichissement TMDb">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="apple-mobile-web-app-title" content="Lycostorrent">
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/static/manifest.json">
|
||||
|
||||
<!-- Icons -->
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/static/icons/icon-192x192.png">
|
||||
<link rel="apple-touch-icon" href="/static/icons/icon-192x192.png">
|
||||
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="stylesheet" href="/static/css/themes.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- Header -->
|
||||
<header class="header">
|
||||
<h1>🔍 Lycostorrent</h1>
|
||||
<p class="subtitle">Recherche de torrents</p>
|
||||
<nav class="main-nav" id="mainNav">
|
||||
<!-- Navigation générée dynamiquement -->
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<!-- Barre de recherche -->
|
||||
<section class="search-section">
|
||||
<div class="search-bar">
|
||||
<input
|
||||
type="text"
|
||||
id="search-input"
|
||||
placeholder="Rechercher un film, série, musique..."
|
||||
autocomplete="off"
|
||||
>
|
||||
<button id="search-btn" class="btn-primary">Rechercher</button>
|
||||
</div>
|
||||
|
||||
<!-- Catégorie -->
|
||||
<div class="search-options">
|
||||
<div class="option-group">
|
||||
<label>Catégorie</label>
|
||||
<select id="category-select">
|
||||
<option value="all">Tout</option>
|
||||
<option value="movies">Films</option>
|
||||
<option value="tv">Séries TV</option>
|
||||
<option value="audio">Audio</option>
|
||||
<option value="pc">PC</option>
|
||||
<option value="console">Console</option>
|
||||
<option value="books">Livres</option>
|
||||
<option value="other">Autre</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sélection des trackers (style Nouveautés) -->
|
||||
<div class="trackers-selector">
|
||||
<button id="toggleTrackers" class="toggle-btn">🔧 Sélectionner les trackers</button>
|
||||
<div id="trackersPanel" class="trackers-panel hidden">
|
||||
<div class="trackers-actions">
|
||||
<button id="selectAllTrackers">Tout sélectionner</button>
|
||||
<button id="deselectAllTrackers">Tout désélectionner</button>
|
||||
</div>
|
||||
<div id="trackers-list" class="trackers-list">
|
||||
<p class="loading">Chargement des trackers...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Filtres dynamiques (masquables) -->
|
||||
<section id="filters-section" class="filters-section hidden">
|
||||
<div class="filters-header">
|
||||
<h3>🎛️ Filtres <span id="results-count" class="results-count"></span></h3>
|
||||
<button id="toggle-filters" class="btn-toggle" title="Masquer/Afficher les filtres">▼</button>
|
||||
</div>
|
||||
<div id="filters-content" class="filters-content">
|
||||
<div id="filters-container" class="filters-container">
|
||||
<!-- Filtres générés dynamiquement -->
|
||||
</div>
|
||||
<button id="clear-filters" class="btn-secondary">Effacer les filtres</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Résultats -->
|
||||
<section id="results-section" class="results-section">
|
||||
<div id="results-container">
|
||||
<p class="placeholder-text">Effectuez une recherche pour voir les résultats</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Loading overlay -->
|
||||
<div id="loading-overlay" class="loading-overlay hidden">
|
||||
<div class="spinner"></div>
|
||||
<p>Recherche en cours...</p>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="app-footer">
|
||||
<span>Lycostorrent v<span id="app-version">1.1.0</span></span>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/search.js"></script>
|
||||
<script>
|
||||
fetch('/api/version').then(r => r.json()).then(data => {
|
||||
if (data.version) document.getElementById('app-version').textContent = data.version;
|
||||
}).catch(() => {});
|
||||
|
||||
// Enregistrement du Service Worker pour PWA
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', () => {
|
||||
navigator.serviceWorker.register('/static/sw.js')
|
||||
.then(reg => console.log('✅ Service Worker enregistré'))
|
||||
.catch(err => console.log('❌ Service Worker erreur:', err));
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<script src="/static/js/nav.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
145
app/templates/latest.html
Normal file
145
app/templates/latest.html
Normal file
@@ -0,0 +1,145 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Lycostorrent - Nouveautés</title>
|
||||
|
||||
<!-- Chargement du thème (en premier pour éviter le flash) -->
|
||||
<script src="/static/js/theme-loader.js"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="theme-color" content="#e63946">
|
||||
<meta name="description" content="Dernières sorties Films, Séries et Musique">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="apple-mobile-web-app-title" content="Lycostorrent">
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/static/manifest.json">
|
||||
|
||||
<!-- Icons -->
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/static/icons/icon-192x192.png">
|
||||
<link rel="apple-touch-icon" href="/static/icons/icon-192x192.png">
|
||||
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="stylesheet" href="/static/css/themes.css">
|
||||
<link rel="stylesheet" href="/static/css/latest.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- Header -->
|
||||
<header class="header">
|
||||
<h1>🎬 Lycostorrent</h1>
|
||||
<p class="subtitle">Dernières sorties Films, Séries & Musique</p>
|
||||
<nav class="main-nav" id="mainNav">
|
||||
<!-- Navigation générée dynamiquement -->
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<!-- Paramètres -->
|
||||
<div class="latest-settings">
|
||||
<div class="categories">
|
||||
<button class="category-btn active" data-category="movies">🎥 Films</button>
|
||||
<button class="category-btn" data-category="tv">📺 Séries</button>
|
||||
<button class="category-btn" data-category="anime">🎌 Animes</button>
|
||||
<button class="category-btn" data-category="music">🎵 Musique</button>
|
||||
</div>
|
||||
|
||||
<div class="trackers-selector">
|
||||
<button id="toggleTrackers" class="toggle-btn">🔧 Sélectionner les trackers</button>
|
||||
<div id="trackersPanel" class="trackers-panel hidden">
|
||||
<div class="trackers-actions">
|
||||
<button id="selectAllTrackers">Tout sélectionner</button>
|
||||
<button id="deselectAllTrackers">Tout désélectionner</button>
|
||||
</div>
|
||||
<div id="trackersList" class="trackers-list">
|
||||
<p class="loading">Chargement des trackers...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="limit-selector">
|
||||
<label>Résultats:</label>
|
||||
<select id="limitSelect">
|
||||
<option value="10">10</option>
|
||||
<option value="20" selected>20</option>
|
||||
<option value="30">30</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
<button id="loadLatestBtn" class="btn-primary">📥 Charger</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filtres par année (pastilles) -->
|
||||
<div id="yearFilters" class="year-filters hidden">
|
||||
<span class="filter-label">Année :</span>
|
||||
<div class="year-pills">
|
||||
<button class="year-pill" data-year="2026">2026</button>
|
||||
<button class="year-pill" data-year="2025">2025</button>
|
||||
<button class="year-pill" data-year="2024">2024</button>
|
||||
<button class="year-pill" data-year="2023">2023</button>
|
||||
<button class="year-pill" data-year="old">≤2022</button>
|
||||
<button class="year-pill active" data-year="all">Tous</button>
|
||||
</div>
|
||||
<span id="filterCount" class="filter-count"></span>
|
||||
</div>
|
||||
|
||||
<!-- Résultats -->
|
||||
<div id="latestResults" class="latest-results hidden">
|
||||
<div class="results-header">
|
||||
<h2 id="resultsTitle">Dernières sorties</h2>
|
||||
<div class="results-meta">
|
||||
<span id="resultsCount">0 résultats</span>
|
||||
<div id="cacheInfo" class="cache-info hidden">
|
||||
<span class="cache-badge">📦 Cache</span>
|
||||
<span id="cacheTimestamp" class="cache-timestamp"></span>
|
||||
<button id="refreshLiveBtn" class="btn-refresh" title="Actualiser en direct">🔄</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="resultsGrid" class="results-grid"></div>
|
||||
</div>
|
||||
|
||||
<!-- Messages -->
|
||||
<div id="messageBox" class="message-box hidden"></div>
|
||||
|
||||
<!-- Loader -->
|
||||
<div id="loader" class="loader hidden">
|
||||
<div class="spinner"></div>
|
||||
<p>Chargement des nouveautés...</p>
|
||||
</div>
|
||||
|
||||
<!-- Modal pour les détails -->
|
||||
<div id="detailsModal" class="modal hidden">
|
||||
<div class="modal-content">
|
||||
<span class="modal-close">×</span>
|
||||
<div id="modalBody"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="app-footer">
|
||||
<span>Lycostorrent v<span id="app-version">1.0.0</span></span>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/latest.js"></script>
|
||||
<script>
|
||||
fetch('/api/version').then(r => r.json()).then(data => {
|
||||
if (data.version) document.getElementById('app-version').textContent = data.version;
|
||||
}).catch(() => {});
|
||||
|
||||
// Enregistrement du Service Worker pour PWA
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', () => {
|
||||
navigator.serviceWorker.register('/static/sw.js')
|
||||
.then(reg => console.log('✅ Service Worker enregistré'))
|
||||
.catch(err => console.log('❌ Service Worker erreur:', err));
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<script src="/static/js/nav.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
232
app/templates/login.html
Normal file
232
app/templates/login.html
Normal file
@@ -0,0 +1,232 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Lycostorrent - Connexion</title>
|
||||
|
||||
<!-- Chargement du thème (en premier pour éviter le flash) -->
|
||||
<script src="/static/js/theme-loader.js"></script>
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="theme-color" content="#e63946">
|
||||
<meta name="description" content="Connexion à Lycostorrent">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="apple-mobile-web-app-title" content="Lycostorrent">
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/static/manifest.json">
|
||||
|
||||
<!-- Icons -->
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/static/icons/icon-192x192.png">
|
||||
<link rel="apple-touch-icon" href="/static/icons/icon-192x192.png">
|
||||
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="stylesheet" href="/static/css/themes.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- Header -->
|
||||
<header class="header">
|
||||
<h1>🔐 Lycostorrent</h1>
|
||||
<p class="subtitle">Connexion requise</p>
|
||||
</header>
|
||||
|
||||
<!-- Formulaire de connexion -->
|
||||
<div class="login-wrapper">
|
||||
{% if locked_message %}
|
||||
<div class="alert alert-warning">
|
||||
<span class="alert-icon">🔒</span>
|
||||
<span>{{ locked_message }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if error %}
|
||||
<div class="alert alert-error">
|
||||
<span class="alert-icon">⚠️</span>
|
||||
<span>{{ error }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form method="POST" action="{{ url_for('login') }}{% if request.args.get('next') %}?next={{ request.args.get('next') }}{% endif %}" class="login-form" autocomplete="on">
|
||||
<!-- Token CSRF -->
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="username">Nom d'utilisateur</label>
|
||||
<input type="text"
|
||||
id="username"
|
||||
name="username"
|
||||
class="form-input"
|
||||
placeholder="admin"
|
||||
autocomplete="username"
|
||||
required
|
||||
autofocus
|
||||
{% if locked_message %}disabled{% endif %}>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">Mot de passe</label>
|
||||
<input type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
class="form-input"
|
||||
placeholder="••••••••"
|
||||
autocomplete="current-password"
|
||||
required
|
||||
{% if locked_message %}disabled{% endif %}>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn-primary btn-login" {% if locked_message %}disabled{% endif %}>
|
||||
{% if locked_message %}
|
||||
🔒 Verrouillé
|
||||
{% else %}
|
||||
🔐 Se connecter
|
||||
{% endif %}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="login-footer">
|
||||
<span class="security-badge">🛡️ Connexion sécurisée</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="app-footer">
|
||||
<span>Lycostorrent</span>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
{% if locked_message %}
|
||||
<script>
|
||||
// Rafraîchir la page après le délai de verrouillage
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 10000);
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
<style>
|
||||
/* Styles spécifiques à la page login - utilise les variables CSS du thème */
|
||||
.login-wrapper {
|
||||
max-width: 400px;
|
||||
margin: 2rem auto;
|
||||
padding: 2rem;
|
||||
background: var(--card-bg);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.login-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.25rem;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
color: var(--text-color);
|
||||
font-weight: 500;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
width: 100%;
|
||||
padding: 0.875rem 1rem;
|
||||
background: var(--bg-color);
|
||||
border: 2px solid var(--border-color);
|
||||
border-radius: 8px;
|
||||
color: var(--text-color);
|
||||
font-size: 1rem;
|
||||
transition: border-color 0.2s, box-shadow 0.2s;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-input:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent-color);
|
||||
box-shadow: 0 0 0 3px rgba(230, 57, 70, 0.2);
|
||||
}
|
||||
|
||||
.form-input::placeholder {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.form-input:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.btn-login {
|
||||
width: 100%;
|
||||
padding: 1rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.btn-login:disabled {
|
||||
background: var(--text-muted);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.alert {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 1rem;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.alert-icon {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
background: rgba(239, 68, 68, 0.15);
|
||||
border: 1px solid rgba(239, 68, 68, 0.3);
|
||||
color: #ef4444;
|
||||
}
|
||||
|
||||
.alert-warning {
|
||||
background: rgba(245, 158, 11, 0.15);
|
||||
border: 1px solid rgba(245, 158, 11, 0.3);
|
||||
color: #f59e0b;
|
||||
}
|
||||
|
||||
.login-footer {
|
||||
margin-top: 1.5rem;
|
||||
padding-top: 1.5rem;
|
||||
border-top: 1px solid var(--border-color);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.security-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
background: rgba(34, 197, 94, 0.15);
|
||||
color: #22c55e;
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 20px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.login-wrapper {
|
||||
margin: 1rem;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user