Skip to content

Commit 360d69f

Browse files
Bump v3.3.0 (#375)
* Aggiunta di una nuova interfaccia web per la ricerca e il download + fix hook precommit * Aggiornamento della documentazione README.md: aggiunti comandi per l'esecuzione delle migrazioni e per l'avvio del server di sviluppo. * Rifattorizzazione dell'interfaccia utente per la ricerca e i risultati: migliorata l'estetica con Tailwind CSS, aggiunti stili personalizzati per i form e implementate animazioni per una migliore esperienza utente. * Modifiche alla logica di selezione per il download: ora gestisce separatamente gli episodi per animeunity e aggiorna l'interfaccia utente per riflettere queste modifiche, nascondendo il campo stagione quando non necessario. * Aggiunta della funzione _ensure_direct_item per garantire la validità degli direct_item, ricostruendoli dal database se mancano campi chiave. Aggiornato il flusso di download per utilizzare il direct_item assicurato. * Aggiunta di normalizzazione degli spazi per stagione ed episodio, conversione del nome del sito in minuscolo e gestione del download di tutti gli episodi per animeunity se non specificato. Aggiornato il placeholder del campo episodio per migliorare l'usabilità. * Modifica del percorso di root_path in config.json per puntare alla directory Video corretta. Questo cambiamento migliora la gestione dei file di output. * Aggiunta della gestione della data di rilascio e dell'immagine di sfondo nei risultati di ricerca. Modifiche ai template per migliorare la visibilità delle opzioni selezionate e l'estetica generale. Aggiornamenti ai campi di input per la barra di ricerca veloce. * Aggiunta della vista `series_metadata` per gestire le richieste POST relative ai metadati delle serie. Implementati test unitari per verificare il comportamento della vista con diversi tipi di input e sorgenti. Aggiornato il routing per includere il nuovo endpoint. * Aggiunta del supporto per il tipo "OVA" nella gestione dei metadati delle serie. Aggiornati i test unitari per verificare il comportamento corretto con questo nuovo tipo. Modifiche ai template per nascondere le opzioni di stagione ed episodio quando il tipo è "OVA". * Modifiche agli stili CSS per migliorare le animazioni e la visibilità del testo nei selettori di stagione ed episodio. Aggiornati i parametri di animazione per una transizione più fluida e forzato il colore del testo in nero per i selettori richiesti. * ruff format * Aggiunta di gestione dei segnali per il thread principale nel downloader MP4. Ora il gestore di interruzione viene impostato solo se il codice è in esecuzione nel thread principale, migliorando la stabilità in contesti multithread. Gestita l'eccezione nel caso in cui l'impostazione del gestore di segnali fallisca. * Modifiche alla logica di gestione dei metadati: in caso di errore nel recupero, ora si nasconde completamente la selezione e si forza il download completo. Per le serie con una sola stagione, si mostra solo l'intervallo degli episodi e si imposta automaticamente la stagione a 1. --------- Co-authored-by: Francesco Grazioso <40018163+FrancescoGrazioso@users.noreply.github.com>
1 parent 288a933 commit 360d69f

File tree

23 files changed

+1427
-13
lines changed

23 files changed

+1427
-13
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,6 @@ bot_config.json
5454
scripts.json
5555
active_requests.json
5656
working_proxies.json
57-
start.sh
57+
start.sh
58+
.DS_Store
59+
GUI/db.sqlite3

GUI/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Web GUI per ricerca e download.
2+
3+
Comandi rapidi:
4+
- Installazione deps: `pip install -r .\GUI\requirements.txt`
5+
- Esecuzione migrazioni: `python GUI/manage.py migrate`
6+
- Avvio dev: `python GUI/manage.py runserver 0.0.0.0:8000`

GUI/config.json

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"DEFAULT": {
3+
"debug": false,
4+
"show_message": true,
5+
"clean_console": true,
6+
"show_trending": true,
7+
"use_api": true,
8+
"not_close": false,
9+
"telegram_bot": false,
10+
"download_site_data": true,
11+
"validate_github_config": true,
12+
"bypass_dns": false
13+
},
14+
"OUT_FOLDER": {
15+
"root_path": "../Video",
16+
"movie_folder_name": "Movie",
17+
"serie_folder_name": "Serie",
18+
"anime_folder_name": "Anime",
19+
"map_episode_name": "E%(episode)_%(episode_name)",
20+
"add_siteName": false
21+
},
22+
"QBIT_CONFIG": {
23+
"host": "192.168.1.51",
24+
"port": "6666",
25+
"user": "admin",
26+
"pass": "adminadmin"
27+
},
28+
"M3U8_DOWNLOAD": {
29+
"default_video_workers": 12,
30+
"default_audio_workers": 12,
31+
"segment_timeout": 8,
32+
"specific_list_audio": [
33+
"ita"
34+
],
35+
"download_subtitle": true,
36+
"merge_subs": true,
37+
"specific_list_subtitles": [
38+
"ita",
39+
"eng"
40+
],
41+
"cleanup_tmp_folder": true
42+
},
43+
"M3U8_CONVERSION": {
44+
"use_codec": false,
45+
"use_vcodec": true,
46+
"use_acodec": true,
47+
"use_bitrate": true,
48+
"use_gpu": false,
49+
"default_preset": "ultrafast"
50+
},
51+
"M3U8_PARSER": {
52+
"force_resolution": "Best"
53+
},
54+
"REQUESTS": {
55+
"verify": false,
56+
"timeout": 20,
57+
"max_retry": 8
58+
},
59+
"SITE_LOGIN": {
60+
"crunchyroll": {
61+
"etp_rt": "",
62+
"x_cr_tab_id": ""
63+
}
64+
}
65+
}

GUI/manage.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env python3
2+
import os
3+
import sys
4+
5+
6+
def main():
7+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "webgui.settings")
8+
from django.core.management import execute_from_command_line
9+
10+
execute_from_command_line(sys.argv)
11+
12+
13+
if __name__ == "__main__":
14+
main()

GUI/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
django>=4.2,<5.0

GUI/searchapp/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

GUI/searchapp/apps.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from django.apps import AppConfig
2+
3+
4+
class SearchappConfig(AppConfig):
5+
default_auto_field = "django.db.models.BigAutoField"
6+
name = "searchapp"

GUI/searchapp/forms.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from django import forms
2+
3+
4+
SITE_CHOICES = [
5+
("animeunity", "AnimeUnity"),
6+
("streamingcommunity", "StreamingCommunity"),
7+
]
8+
9+
10+
class SearchForm(forms.Form):
11+
site = forms.ChoiceField(
12+
choices=SITE_CHOICES,
13+
label="Sito",
14+
widget=forms.Select(
15+
attrs={
16+
"class": "block w-full appearance-none rounded-lg border border-gray-300 bg-white py-3 pl-12 pr-12 text-gray-900 placeholder-gray-500 shadow-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500",
17+
}
18+
),
19+
)
20+
query = forms.CharField(
21+
max_length=200,
22+
label="Cosa cerchi?",
23+
widget=forms.TextInput(
24+
attrs={
25+
"class": "block w-full rounded-lg border border-gray-300 bg-white py-3 pl-12 pr-12 text-gray-900 placeholder-gray-500 shadow-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500",
26+
"placeholder": "Cerca titolo...",
27+
"autocomplete": "off",
28+
}
29+
),
30+
)
31+
32+
33+
class DownloadForm(forms.Form):
34+
source_alias = forms.CharField(widget=forms.HiddenInput)
35+
item_payload = forms.CharField(widget=forms.HiddenInput)
36+
# Opzionali per serie
37+
season = forms.CharField(max_length=10, required=False, label="Stagione")
38+
episode = forms.CharField(max_length=20, required=False, label="Episodio (es: 1-3)")
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
<!DOCTYPE html>
2+
<html lang="it" class="dark">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1" />
6+
<title>StreamingCommunity - Ricerca</title>
7+
<script src="https://cdn.tailwindcss.com"></script>
8+
<script>
9+
tailwind.config = {
10+
darkMode: 'class',
11+
theme: {
12+
extend: {
13+
animation: {
14+
'fade-in': 'fadeIn 0.5s ease-in-out',
15+
'slide-up': 'slideUp 0.3s ease-out',
16+
'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite',
17+
},
18+
keyframes: {
19+
fadeIn: {
20+
'0%': { opacity: '0' },
21+
'100%': { opacity: '1' },
22+
},
23+
slideUp: {
24+
'0%': { transform: 'translateY(10px)', opacity: '0' },
25+
'100%': { transform: 'translateY(0)', opacity: '1' },
26+
}
27+
}
28+
}
29+
}
30+
}
31+
</script>
32+
<style>
33+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
34+
body { font-family: 'Inter', sans-serif; }
35+
</style>
36+
{% csrf_token %}
37+
</head>
38+
<body class="bg-gray-900 min-h-screen text-gray-100">
39+
<!-- Background Pattern -->
40+
<div class="absolute inset-0 bg-[url('data:image/svg+xml,%3Csvg width="60" height="60" viewBox="0 0 60 60" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="none" fill-rule="evenodd"%3E%3Cg fill="%236B7280" fill-opacity="0.03"%3E%3Ccircle cx="30" cy="30" r="2"/%3E%3C/g%3E%3C/g%3E%3C/svg%3E')] opacity-30"></div>
41+
42+
<div class="relative z-10 container mx-auto px-4 py-8">
43+
<!-- Header -->
44+
<div class="text-center mb-12 animate-fade-in">
45+
<div class="inline-flex items-center justify-center w-16 h-16 bg-blue-600 rounded-2xl mb-6 shadow-lg">
46+
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
47+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
48+
</svg>
49+
</div>
50+
<h1 class="text-4xl md:text-5xl font-bold text-white mb-4">
51+
StreamingCommunity
52+
</h1>
53+
<p class="text-gray-400 text-lg max-w-2xl mx-auto">
54+
Trova e scarica i tuoi contenuti preferiti da tutti i siti di streaming
55+
</p>
56+
</div>
57+
58+
<!-- Messages -->
59+
{% if messages %}
60+
<div class="max-w-2xl mx-auto mb-8 space-y-4 animate-slide-up">
61+
{% for message in messages %}
62+
<div class="flex items-center p-4 rounded-xl border {% if message.tags == 'success' %}bg-green-900/50 border-green-700 text-green-300{% elif message.tags == 'error' %}bg-red-900/50 border-red-700 text-red-300{% else %}bg-blue-900/50 border-blue-700 text-blue-300{% endif %}">
63+
<div class="flex-shrink-0 mr-3">
64+
{% if message.tags == 'success' %}
65+
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
66+
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path>
67+
</svg>
68+
{% elif message.tags == 'error' %}
69+
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
70+
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"></path>
71+
</svg>
72+
{% else %}
73+
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
74+
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd"></path>
75+
</svg>
76+
{% endif %}
77+
</div>
78+
<span class="text-sm font-medium">{{ message }}</span>
79+
</div>
80+
{% endfor %}
81+
</div>
82+
{% endif %}
83+
84+
<!-- Search Form -->
85+
<div class="max-w-2xl mx-auto animate-slide-up">
86+
<div class="bg-gray-800 border border-gray-700 rounded-2xl p-8 shadow-2xl">
87+
<form action="{% url 'search' %}" method="post" class="space-y-6">
88+
{% csrf_token %}
89+
90+
<!-- Site Selection -->
91+
<div>
92+
<label for="id_site" class="block text-sm font-semibold text-gray-200 mb-3">
93+
<svg class="inline w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
94+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9v-9m0-9v9"></path>
95+
</svg>
96+
Seleziona Sito
97+
</label>
98+
<div class="relative group">
99+
<div class="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none">
100+
<svg class="w-5 h-5 text-gray-400 group-focus-within:text-blue-500 transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24">
101+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"></path>
102+
</svg>
103+
</div>
104+
{{ form.site }}
105+
<div class="absolute inset-y-0 right-0 flex items-center pr-4 pointer-events-none">
106+
<svg class="w-5 h-5 text-gray-400 group-focus-within:text-blue-500 transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24">
107+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
108+
</svg>
109+
</div>
110+
</div>
111+
</div>
112+
113+
<!-- Search Query -->
114+
<div>
115+
<label for="id_query" class="block text-sm font-semibold text-gray-200 mb-3">
116+
<svg class="inline w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
117+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
118+
</svg>
119+
Cosa cerchi?
120+
</label>
121+
<div class="relative group">
122+
<div class="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none">
123+
<svg class="w-5 h-5 text-gray-400 group-focus-within:text-blue-500 transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24">
124+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
125+
</svg>
126+
</div>
127+
{{ form.query }}
128+
<div class="absolute inset-y-0 right-0 flex items-center pr-4 pointer-events-none">
129+
<div class="w-6 h-6 bg-blue-600 rounded-full flex items-center justify-center">
130+
<svg class="w-3 h-3 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
131+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
132+
</svg>
133+
</div>
134+
</div>
135+
</div>
136+
</div>
137+
138+
<!-- Submit Button -->
139+
<button type="submit" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-semibold py-4 px-6 rounded-xl transition-all duration-300 transform hover:scale-105 hover:shadow-lg focus:outline-none focus:ring-4 focus:ring-blue-500/50">
140+
<svg class="inline w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
141+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
142+
</svg>
143+
Cerca Contenuti
144+
</button>
145+
</form>
146+
</div>
147+
148+
<!-- Features -->
149+
<div class="mt-12 grid md:grid-cols-3 gap-6">
150+
<div class="text-center p-6 bg-gray-800 border border-gray-700 rounded-xl">
151+
<div class="w-12 h-12 bg-blue-600 rounded-xl flex items-center justify-center mx-auto mb-4">
152+
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
153+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
154+
</svg>
155+
</div>
156+
<h3 class="font-semibold text-white mb-2">Veloce</h3>
157+
<p class="text-sm text-gray-400">Ricerca istantanea su tutti i siti</p>
158+
</div>
159+
160+
<div class="text-center p-6 bg-gray-800 border border-gray-700 rounded-xl">
161+
<div class="w-12 h-12 bg-green-600 rounded-xl flex items-center justify-center mx-auto mb-4">
162+
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
163+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
164+
</svg>
165+
</div>
166+
<h3 class="font-semibold text-white mb-2">Sicuro</h3>
167+
<p class="text-sm text-gray-400">Download sicuro e protetto</p>
168+
</div>
169+
170+
<div class="text-center p-6 bg-gray-800 border border-gray-700 rounded-xl">
171+
<div class="w-12 h-12 bg-indigo-600 rounded-xl flex items-center justify-center mx-auto mb-4">
172+
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
173+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"></path>
174+
</svg>
175+
</div>
176+
<h3 class="font-semibold text-white mb-2">Completo</h3>
177+
<p class="text-sm text-gray-400">Film, serie TV e anime</p>
178+
</div>
179+
</div>
180+
</div>
181+
</div>
182+
183+
<style>
184+
/* Custom form styling */
185+
/* Rimosse regole generiche che potevano sovrascrivere i widget del form */
186+
187+
/* Override specifico per i campi del form */
188+
#id_site, #id_query {
189+
background-color: #ffffff !important; /* sfondo bianco */
190+
color: #111827 !important; /* testo quasi nero */
191+
border-color: #d1d5db !important; /* grigio chiaro */
192+
padding-left: 3rem; /* spazio per icone */
193+
padding-right: 3rem; /* spazio per icone */
194+
}
195+
196+
/* Specific styling for select */
197+
select {
198+
@apply py-3 px-12; /* Padding per le icone laterali */
199+
background-image: none !important; /* Rimuove la freccia di default */
200+
color: #111827 !important; /* Fix: opzione selezionata visibile in dark */
201+
}
202+
203+
/* Specific styling for input */
204+
input {
205+
@apply py-3 px-12; /* Padding per le icone laterali */
206+
}
207+
208+
select option {
209+
@apply bg-gray-700 text-white;
210+
background-color: #374151 !important;
211+
color: white !important;
212+
}
213+
214+
/* Hover effects */
215+
select:hover, input:hover {
216+
@apply border-gray-500;
217+
}
218+
219+
/* Focus effects */
220+
select:focus, input:focus {
221+
@apply border-blue-500 ring-2 ring-blue-500/20;
222+
}
223+
224+
/* Smooth scrolling */
225+
html {
226+
scroll-behavior: smooth;
227+
}
228+
</style>
229+
</body>
230+
</html>
231+
232+

0 commit comments

Comments
 (0)