StreamingCommunity 2.5.6__py3-none-any.whl → 2.5.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of StreamingCommunity might be problematic. Click here for more details.

Files changed (65) hide show
  1. StreamingCommunity/Api/Player/ddl.py +2 -3
  2. StreamingCommunity/Api/Site/1337xx/__init__.py +5 -6
  3. StreamingCommunity/Api/Site/1337xx/site.py +7 -14
  4. StreamingCommunity/Api/Site/1337xx/title.py +3 -5
  5. StreamingCommunity/Api/Site/altadefinizionegratis/__init__.py +7 -6
  6. StreamingCommunity/Api/Site/altadefinizionegratis/film.py +14 -19
  7. StreamingCommunity/Api/Site/altadefinizionegratis/site.py +6 -14
  8. StreamingCommunity/Api/Site/animeunity/__init__.py +7 -7
  9. StreamingCommunity/Api/Site/animeunity/film_serie.py +29 -31
  10. StreamingCommunity/Api/Site/animeunity/site.py +14 -22
  11. StreamingCommunity/Api/Site/cb01new/__init__.py +5 -4
  12. StreamingCommunity/Api/Site/cb01new/film.py +2 -5
  13. StreamingCommunity/Api/Site/cb01new/site.py +5 -13
  14. StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py +5 -4
  15. StreamingCommunity/Api/Site/ddlstreamitaly/series.py +12 -49
  16. StreamingCommunity/Api/Site/ddlstreamitaly/site.py +6 -16
  17. StreamingCommunity/Api/Site/ddlstreamitaly/util/ScrapeSerie.py +2 -3
  18. StreamingCommunity/Api/Site/guardaserie/__init__.py +5 -4
  19. StreamingCommunity/Api/Site/guardaserie/series.py +12 -46
  20. StreamingCommunity/Api/Site/guardaserie/site.py +5 -13
  21. StreamingCommunity/Api/Site/guardaserie/util/ScrapeSerie.py +10 -14
  22. StreamingCommunity/Api/Site/ilcorsaronero/__init__.py +5 -4
  23. StreamingCommunity/Api/Site/ilcorsaronero/site.py +5 -13
  24. StreamingCommunity/Api/Site/ilcorsaronero/title.py +3 -5
  25. StreamingCommunity/Api/Site/mostraguarda/__init__.py +2 -2
  26. StreamingCommunity/Api/Site/mostraguarda/film.py +4 -8
  27. StreamingCommunity/Api/Site/streamingcommunity/__init__.py +8 -7
  28. StreamingCommunity/Api/Site/streamingcommunity/film.py +14 -18
  29. StreamingCommunity/Api/Site/streamingcommunity/series.py +25 -76
  30. StreamingCommunity/Api/Site/streamingcommunity/site.py +11 -23
  31. StreamingCommunity/Api/Template/Util/__init__.py +8 -1
  32. StreamingCommunity/Api/Template/Util/manage_ep.py +46 -2
  33. StreamingCommunity/Api/Template/config_loader.py +71 -0
  34. StreamingCommunity/Lib/Downloader/HLS/downloader.py +60 -60
  35. StreamingCommunity/Lib/Downloader/HLS/segments.py +40 -15
  36. StreamingCommunity/Lib/Downloader/MP4/downloader.py +47 -40
  37. StreamingCommunity/Lib/FFmpeg/command.py +59 -3
  38. StreamingCommunity/Lib/M3U8/estimator.py +10 -12
  39. StreamingCommunity/Lib/M3U8/parser.py +12 -51
  40. StreamingCommunity/Lib/TMBD/tmdb.py +66 -99
  41. StreamingCommunity/TelegramHelp/telegram_bot.py +222 -68
  42. StreamingCommunity/Util/_jsonConfig.py +14 -13
  43. StreamingCommunity/Util/ffmpeg_installer.py +70 -64
  44. StreamingCommunity/Util/headers.py +11 -122
  45. StreamingCommunity/Util/os.py +65 -56
  46. StreamingCommunity/Util/table.py +62 -108
  47. StreamingCommunity/run.py +16 -11
  48. {StreamingCommunity-2.5.6.dist-info → StreamingCommunity-2.5.8.dist-info}/METADATA +57 -23
  49. StreamingCommunity-2.5.8.dist-info/RECORD +86 -0
  50. StreamingCommunity/Api/Site/1337xx/costant.py +0 -15
  51. StreamingCommunity/Api/Site/altadefinizionegratis/costant.py +0 -21
  52. StreamingCommunity/Api/Site/animeunity/costant.py +0 -21
  53. StreamingCommunity/Api/Site/cb01new/costant.py +0 -19
  54. StreamingCommunity/Api/Site/ddlstreamitaly/costant.py +0 -20
  55. StreamingCommunity/Api/Site/guardaserie/costant.py +0 -19
  56. StreamingCommunity/Api/Site/ilcorsaronero/costant.py +0 -19
  57. StreamingCommunity/Api/Site/mostraguarda/costant.py +0 -19
  58. StreamingCommunity/Api/Site/streamingcommunity/costant.py +0 -21
  59. StreamingCommunity/TelegramHelp/request_manager.py +0 -82
  60. StreamingCommunity/TelegramHelp/session.py +0 -56
  61. StreamingCommunity-2.5.6.dist-info/RECORD +0 -96
  62. {StreamingCommunity-2.5.6.dist-info → StreamingCommunity-2.5.8.dist-info}/LICENSE +0 -0
  63. {StreamingCommunity-2.5.6.dist-info → StreamingCommunity-2.5.8.dist-info}/WHEEL +0 -0
  64. {StreamingCommunity-2.5.6.dist-info → StreamingCommunity-2.5.8.dist-info}/entry_points.txt +0 -0
  65. {StreamingCommunity-2.5.6.dist-info → StreamingCommunity-2.5.8.dist-info}/top_level.txt +0 -0
@@ -6,17 +6,19 @@ from typing import Dict
6
6
 
7
7
  # External libraries
8
8
  import httpx
9
- from rich.console import Console
10
9
 
11
10
 
12
11
  # Internal utilities
13
12
  from .obj_tmbd import Json_film
13
+ from StreamingCommunity.Util.console import console
14
+ from StreamingCommunity.Util._jsonConfig import config_manager
14
15
  from StreamingCommunity.Util.table import TVShowManager
15
16
 
16
17
 
17
18
  # Variable
18
19
  table_show_manager = TVShowManager()
19
20
  api_key = "a800ed6c93274fb857ea61bd9e7256c5"
21
+ MAX_TIMEOUT = config_manager.get_int("REQUESTS", "timeout")
20
22
 
21
23
 
22
24
 
@@ -33,7 +35,7 @@ def get_select_title(table_show_manager, generic_obj):
33
35
 
34
36
  # Check if the generic_obj list is empty
35
37
  if not generic_obj:
36
- Console.print("\n[red]No media items available.")
38
+ console.print("\n[red]No media items available.")
37
39
  return None
38
40
 
39
41
  # Example of available colors for columns
@@ -76,7 +78,7 @@ def get_select_title(table_show_manager, generic_obj):
76
78
 
77
79
  # Handle user's quit command
78
80
  if last_command == "q" or last_command == "quit":
79
- Console.print("\n[red]Quit [white]...")
81
+ console.print("\n[red]Quit [white]...")
80
82
  sys.exit(0)
81
83
 
82
84
  # Check if the selected index is within range
@@ -84,7 +86,7 @@ def get_select_title(table_show_manager, generic_obj):
84
86
  return generic_obj[int(last_command)]
85
87
 
86
88
  else:
87
- Console.print("\n[red]Wrong index")
89
+ console.print("\n[red]Wrong index")
88
90
  sys.exit(0)
89
91
 
90
92
 
@@ -98,8 +100,9 @@ class TheMovieDB:
98
100
  """
99
101
  self.api_key = api_key
100
102
  self.base_url = "https://api.themoviedb.org/3"
101
- self.console = Console()
102
103
  #self.genres = self._fetch_genres()
104
+ self._cached_trending_tv = None
105
+ self._cached_trending_movies = None
103
106
 
104
107
  def _make_request(self, endpoint, params=None):
105
108
  """
@@ -117,7 +120,7 @@ class TheMovieDB:
117
120
 
118
121
  params['api_key'] = self.api_key
119
122
  url = f"{self.base_url}/{endpoint}"
120
- response = httpx.get(url, params=params)
123
+ response = httpx.get(url, params=params, timeout=MAX_TIMEOUT)
121
124
  response.raise_for_status()
122
125
 
123
126
  return response.json()
@@ -132,78 +135,66 @@ class TheMovieDB:
132
135
  genres = self._make_request("genre/movie/list")
133
136
  return {genre['id']: genre['name'] for genre in genres.get('genres', [])}
134
137
 
135
- def _process_and_add_tv_shows(self, data, columns):
138
+ def _display_top_5(self, category: str, data, name_key='title'):
136
139
  """
137
- Process TV show data and add it to the TV show manager.
140
+ Display top 5 most popular items in a single line with colors.
138
141
 
139
142
  Parameters:
140
- - data (list): List of dictionaries containing the data to process.
141
- - columns (list): A list of tuples, where each tuple contains the column name and the key to fetch the data from the dictionary.
143
+ - category (str): Category label (e.g., "Trending films", "Trending TV shows")
144
+ - data (list): List of media items
145
+ - name_key (str): Key to use for the name ('title' for movies, 'name' for TV shows)
142
146
  """
143
- # Define column styles with colors
144
- tv_show_manager = TVShowManager()
145
- column_info = {
146
- col[0]: {'color': col[2] if len(col) > 2 else 'white'}
147
- for col in columns
148
- }
149
- tv_show_manager.add_column(column_info)
150
-
151
- # Add each item to the TV show manager, including rank
152
- for index, item in enumerate(data):
153
-
154
- # Convert genre IDs to genre names
155
- genre_names = [self.genres.get(genre_id, 'Unknown') for genre_id in item.get('genre_ids', [])]
156
- tv_show = {
157
- col[0]: str(item.get(col[1], 'N/A')) if col[1] != 'genre_ids' else ', '.join(genre_names)
158
- for col in columns
159
- }
160
-
161
- tv_show_manager.add_tv_show(tv_show)
147
+ # Colors for the titles
148
+ colors = ['cyan', 'magenta', 'yellow', 'green', 'blue']
162
149
 
163
- # Display the processed TV show data
164
- tv_show_manager.display_data(tv_show_manager.tv_shows[tv_show_manager.slice_start:tv_show_manager.slice_end])
150
+ # Sort by popularity and get top 5
151
+ sorted_data = sorted(data, key=lambda x: x.get('popularity', 0), reverse=True)[:5]
152
+
153
+ # Create list of colored titles
154
+ colored_items = []
155
+ for item, color in zip(sorted_data, colors):
156
+ title = item.get(name_key, 'Unknown')
157
+ colored_items.append(f"[{color}]{title}[/]")
158
+
159
+ # Join with colored arrows and print with proper category label
160
+ console.print(
161
+ f"[bold purple]{category}:[/] {' [red]→[/] '.join(colored_items)}"
162
+ )
165
163
 
166
- def _display_with_title(self, title: str, data, columns):
164
+ def display_trending_tv_shows(self):
167
165
  """
168
- Display data with a title.
169
-
170
- Parameters:
171
- - title (str): The title to display.
172
- - data (list): List of dictionaries containing the data to process.
173
- - columns (list): A list of tuples, where each tuple contains the column name and the key to fetch the data from the dictionary.
166
+ Fetch and display the top 5 trending TV shows of the week.
167
+ Uses cached data if available, otherwise makes a new request.
174
168
  """
175
- self.console.print(f"\n{title}", style="bold underline")
176
- self._process_and_add_tv_shows(data, columns)
169
+ if self._cached_trending_tv is None:
170
+ self._cached_trending_tv = self._make_request("trending/tv/week").get("results", [])
171
+
172
+ self._display_top_5("Trending TV shows", self._cached_trending_tv, name_key='name')
177
173
 
178
- def display_trending_tv_shows(self):
174
+ def refresh_trending_tv_shows(self):
179
175
  """
180
- Fetch and display the trending TV shows of the week.
176
+ Force a refresh of the trending TV shows cache.
181
177
  """
182
- data = self._make_request("trending/tv/week").get("results", [])
183
- columns = [
184
- ("Title", "name", 'cyan'),
185
- ("First Air Date", "first_air_date", 'green'),
186
- ("Popularity", "popularity", 'magenta'),
187
- ("Genres", "genre_ids", 'blue'),
188
- ("Origin Country", "origin_country", 'red'),
189
- ("Vote Average", "vote_average", 'yellow')
190
- ]
191
- self._display_with_title("Trending TV Shows of the Week", data, columns)
178
+ self._cached_trending_tv = self._make_request("trending/tv/week").get("results", [])
179
+ return self._cached_trending_tv
192
180
 
193
181
  def display_trending_films(self):
194
182
  """
195
- Fetch and display the trending films of the week.
183
+ Fetch and display the top 5 trending films of the week.
184
+ Uses cached data if available, otherwise makes a new request.
196
185
  """
197
- data = self._make_request("trending/movie/week").get("results", [])
198
- columns = [
199
- ("Title", "title", 'cyan'),
200
- ("Release Date", "release_date", 'green'),
201
- ("Popularity", "popularity", 'magenta'),
202
- ("Genres", "genre_ids", 'blue'),
203
- ("Vote Average", "vote_average", 'yellow')
204
- ]
205
- self._display_with_title("Trending Films of the Week", data, columns)
186
+ if self._cached_trending_movies is None:
187
+ self._cached_trending_movies = self._make_request("trending/movie/week").get("results", [])
188
+
189
+ self._display_top_5("Trending films", self._cached_trending_movies, name_key='title')
206
190
 
191
+ def refresh_trending_films(self):
192
+ """
193
+ Force a refresh of the trending films cache.
194
+ """
195
+ self._cached_trending_movies = self._make_request("trending/movie/week").get("results", [])
196
+ return self._cached_trending_movies
197
+
207
198
  def search_movie(self, movie_name: str):
208
199
  """
209
200
  Search for a movie by name and return its TMDB ID.
@@ -217,10 +208,10 @@ class TheMovieDB:
217
208
  generic_obj = []
218
209
  data = self._make_request("search/movie", {"query": movie_name}).get("results", [])
219
210
  if not data:
220
- self.console.print("No movies found with that name.", style="red")
211
+ console.print("No movies found with that name.", style="red")
221
212
  return None
222
213
 
223
- self.console.print("\nSelect a Movie:")
214
+ console.print("\nSelect a Movie:")
224
215
  for i, movie in enumerate(data, start=1):
225
216
  generic_obj.append({
226
217
  'name': movie['title'],
@@ -243,7 +234,7 @@ class TheMovieDB:
243
234
  """
244
235
  movie = self._make_request(f"movie/{tmdb_id}")
245
236
  if not movie:
246
- self.console.print("Movie not found.", style="red")
237
+ console.print("Movie not found.", style="red")
247
238
  return None
248
239
 
249
240
  return Json_film(movie)
@@ -260,12 +251,12 @@ class TheMovieDB:
260
251
  """
261
252
  data = self._make_request("search/tv", {"query": tv_name}).get("results", [])
262
253
  if not data:
263
- self.console.print("No TV shows found with that name.", style="red")
254
+ console.print("No TV shows found with that name.", style="red")
264
255
  return None
265
256
 
266
- self.console.print("\nSelect a TV Show:")
257
+ console.print("\nSelect a TV Show:")
267
258
  for i, show in enumerate(data, start=1):
268
- self.console.print(f"{i}. {show['name']} (First Air Date: {show.get('first_air_date', 'N/A')})")
259
+ console.print(f"{i}. {show['name']} (First Air Date: {show.get('first_air_date', 'N/A')})")
269
260
 
270
261
  choice = int(input("Enter the number of the show you want: ")) - 1
271
262
  selected_show = data[choice]
@@ -283,12 +274,12 @@ class TheMovieDB:
283
274
  """
284
275
  data = self._make_request(f"tv/{tv_show_id}").get("seasons", [])
285
276
  if not data:
286
- self.console.print("No seasons found for this TV show.", style="red")
277
+ console.print("No seasons found for this TV show.", style="red")
287
278
  return None
288
279
 
289
- self.console.print("\nSelect a Season:")
280
+ console.print("\nSelect a Season:")
290
281
  for i, season in enumerate(data, start=1):
291
- self.console.print(f"{i}. {season['name']} (Episodes: {season['episode_count']})")
282
+ console.print(f"{i}. {season['name']} (Episodes: {season['episode_count']})")
292
283
 
293
284
  choice = int(input("Enter the number of the season you want: ")) - 1
294
285
  return data[choice]["season_number"]
@@ -306,12 +297,12 @@ class TheMovieDB:
306
297
  """
307
298
  data = self._make_request(f"tv/{tv_show_id}/season/{season_number}").get("episodes", [])
308
299
  if not data:
309
- self.console.print("No episodes found for this season.", style="red")
300
+ console.print("No episodes found for this season.", style="red")
310
301
  return None
311
302
 
312
- self.console.print("\nSelect an Episode:")
303
+ console.print("\nSelect an Episode:")
313
304
  for i, episode in enumerate(data, start=1):
314
- self.console.print(f"{i}. {episode['name']} (Air Date: {episode.get('air_date', 'N/A')})")
305
+ console.print(f"{i}. {episode['name']} (Air Date: {episode.get('air_date', 'N/A')})")
315
306
 
316
307
  choice = int(input("Enter the number of the episode you want: ")) - 1
317
308
  return data[choice]
@@ -319,28 +310,4 @@ class TheMovieDB:
319
310
 
320
311
 
321
312
  # Output
322
- tmdb = TheMovieDB(api_key)
323
-
324
-
325
- """
326
- Example:
327
-
328
-
329
- @ movie
330
- movie_name = "Interstellar"
331
- movie_id = tmdb.search_movie(movie_name)
332
-
333
- if movie_id:
334
- movie_details = tmdb.get_movie_details(tmdb_id=movie_id)
335
- print(movie_details)
336
-
337
-
338
- @ series
339
- tv_name = "Game of Thrones"
340
- tv_show_id = tmdb.search_tv_show(tv_name)
341
- if tv_show_id:
342
- season_number = tmdb.get_seasons(tv_show_id=tv_show_id)
343
- if season_number:
344
- episode = tmdb.get_episodes(tv_show_id=tv_show_id, season_number=season_number)
345
- print(episode)
346
- """
313
+ tmdb = TheMovieDB(api_key)
@@ -1,4 +1,4 @@
1
- # 04.02.25
1
+ # 04.02.26
2
2
  # Made by: @GiuPic
3
3
 
4
4
  import os
@@ -9,16 +9,141 @@ import uuid
9
9
  import json
10
10
  import threading
11
11
  import subprocess
12
-
12
+ import threading
13
+ from typing import Optional
13
14
 
14
15
  # External libraries
15
16
  import telebot
16
17
 
18
+ session_data = {}
19
+
20
+ class TelegramSession:
21
+
22
+ def set_session(value):
23
+ session_data['script_id'] = value
24
+
25
+ def get_session():
26
+ return session_data.get('script_id', 'unknown')
27
+
28
+ def updateScriptId(screen_id, titolo):
29
+ json_file = "../../scripts.json"
30
+ try:
31
+ with open(json_file, 'r') as f:
32
+ scripts_data = json.load(f)
33
+ except FileNotFoundError:
34
+ scripts_data = []
35
+
36
+ # cerco lo script con lo screen_id
37
+ for script in scripts_data:
38
+ if script["screen_id"] == screen_id:
39
+ # se trovo il match, aggiorno il titolo
40
+ script["titolo"] = titolo
41
+
42
+ # aggiorno il file json
43
+ with open(json_file, 'w') as f:
44
+ json.dump(scripts_data, f, indent=4)
45
+
46
+ return
47
+
48
+ print(f"Screen_id {screen_id} non trovato.")
49
+
50
+ def deleteScriptId(screen_id):
51
+ json_file = "../../scripts.json"
52
+ try:
53
+ with open(json_file, 'r') as f:
54
+ scripts_data = json.load(f)
55
+ except FileNotFoundError:
56
+ scripts_data = []
57
+
58
+ for script in scripts_data:
59
+ if script["screen_id"] == screen_id:
60
+ # se trovo il match, elimino lo script
61
+ scripts_data.remove(script)
62
+
63
+ # aggiorno il file json
64
+ with open(json_file, 'w') as f:
65
+ json.dump(scripts_data, f, indent=4)
66
+
67
+ print(f"Script eliminato per screen_id {screen_id}")
68
+ return
69
+
70
+ print(f"Screen_id {screen_id} non trovato.")
71
+
72
+ class TelegramRequestManager:
73
+ _instance = None
74
+
75
+ def __new__(cls, *args, **kwargs):
76
+ if not cls._instance:
77
+ cls._instance = super().__new__(cls)
78
+ return cls._instance
79
+
80
+ def __init__(self, json_file: str = "active_requests.json"):
81
+ if not hasattr(self, 'initialized'):
82
+ self.json_file = json_file
83
+ self.initialized = True
84
+ self.on_response_callback = None
85
+
86
+ def create_request(self, type: str) -> str:
87
+ request_data = {
88
+ "type": type,
89
+ "response": None,
90
+ "timestamp": time.time()
91
+ }
92
+
93
+ with open(self.json_file, "w") as f:
94
+ json.dump(request_data, f)
95
+
96
+ return "Ok"
97
+
98
+ def save_response(self, message_text: str) -> bool:
99
+ try:
100
+ # Carica il file JSON
101
+ with open(self.json_file, "r") as f:
102
+ data = json.load(f)
103
+
104
+ # Controlla se esiste la chiave 'type' e se la risposta è presente
105
+ if "type" in data and "response" in data:
106
+ data["response"] = message_text # Aggiorna la risposta
17
107
 
18
- # Fix import
19
- sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
20
- from StreamingCommunity.TelegramHelp.request_manager import RequestManager
108
+ with open(self.json_file, "w") as f:
109
+ json.dump(data, f, indent=4)
21
110
 
111
+ return True
112
+ else:
113
+ return False
114
+
115
+ except (FileNotFoundError, json.JSONDecodeError) as e:
116
+ print(f"⚠️ save_response - errore: {e}")
117
+ return False
118
+
119
+ def get_response(self) -> Optional[str]:
120
+ try:
121
+ with open(self.json_file, "r") as f:
122
+ data = json.load(f)
123
+
124
+ # Verifica se esiste la chiave "response"
125
+ if "response" in data:
126
+ response = data["response"] # Ottieni la risposta direttamente
127
+
128
+ if response is not None and self.on_response_callback:
129
+ self.on_response_callback(response)
130
+
131
+ return response
132
+
133
+ except (FileNotFoundError, json.JSONDecodeError) as e:
134
+ print(f"get_response - errore: {e}")
135
+ return None
136
+
137
+ def clear_file(self) -> bool:
138
+ try:
139
+ with open(self.json_file, "w") as f:
140
+ json.dump({}, f)
141
+ print(f"File {self.json_file} è stato svuotato con successo.")
142
+ return True
143
+
144
+ except Exception as e:
145
+ print(f"⚠️ clear_file - errore: {e}")
146
+ return False
22
147
 
23
148
  # Funzione per caricare variabili da un file .env
24
149
  def load_env(file_path="../../.env"):
@@ -44,13 +169,17 @@ class TelegramBot:
44
169
  if os.path.exists(cls._config_file):
45
170
  with open(cls._config_file, "r") as f:
46
171
  config = json.load(f)
47
- cls._instance = cls.init_bot(
48
- config["token"], config["authorized_user_id"]
49
- )
172
+
173
+ # Assicura che authorized_user_id venga trattato come una lista
174
+ authorized_users = config.get('authorized_user_id', [])
175
+ if isinstance(authorized_users, str):
176
+ authorized_users = [int(uid) for uid in authorized_users.split(",") if uid.strip().isdigit()]
177
+
178
+ cls._instance = cls.init_bot(config['token'], authorized_users)
179
+ #cls._instance = cls.init_bot(config['token'], config['authorized_user_id'])
180
+
50
181
  else:
51
- raise Exception(
52
- "Bot non ancora inizializzato. Chiamare prima init_bot() con token e authorized_user_id"
53
- )
182
+ raise Exception("Bot non ancora inizializzato. Chiamare prima init_bot() con token e authorized_user_id")
54
183
  return cls._instance
55
184
 
56
185
  @classmethod
@@ -63,7 +192,8 @@ class TelegramBot:
63
192
  json.dump(config, f)
64
193
  return cls._instance
65
194
 
66
- def __init__(self, token, authorized_user_id):
195
+ def __init__(self, token, authorized_users):
196
+
67
197
  def monitor_scripts():
68
198
  while True:
69
199
  try:
@@ -132,10 +262,10 @@ class TelegramBot:
132
262
  )
133
263
 
134
264
  self.token = token
135
- self.authorized_user_id = authorized_user_id
136
- self.chat_id = authorized_user_id
265
+ self.authorized_users = authorized_users
266
+ self.chat_id = authorized_users
137
267
  self.bot = telebot.TeleBot(token)
138
- self.request_manager = RequestManager()
268
+ self.request_manager = TelegramRequestManager()
139
269
 
140
270
  # Registra gli handler
141
271
  self.register_handlers()
@@ -171,7 +301,7 @@ class TelegramBot:
171
301
  self.handle_response(message)
172
302
 
173
303
  def is_authorized(self, user_id):
174
- return user_id == self.authorized_user_id
304
+ return user_id in self.authorized_users
175
305
 
176
306
  def handle_get_id(self, message):
177
307
  if not self.is_authorized(message.from_user.id):
@@ -194,7 +324,6 @@ class TelegramBot:
194
324
 
195
325
  screen_id = str(uuid.uuid4())[:8]
196
326
  debug_mode = os.getenv("DEBUG")
197
- verbose = debug_mode
198
327
 
199
328
  if debug_mode == "True":
200
329
  subprocess.Popen(["python3", "../../test_run.py", screen_id])
@@ -407,6 +536,13 @@ class TelegramBot:
407
536
  temp_file = f"/tmp/screen_output_{screen_id}.txt"
408
537
 
409
538
  try:
539
+ # Verifica se lo screen con l'ID specificato esiste
540
+ existing_screens = subprocess.check_output(["screen", "-list"]).decode('utf-8')
541
+ if screen_id not in existing_screens:
542
+ print(f"⚠️ La sessione screen con ID {screen_id} non esiste.")
543
+ self.bot.send_message(message.chat.id, f"⚠️ La sessione screen con ID {screen_id} non esiste.")
544
+ return
545
+
410
546
  # Cattura l'output della screen
411
547
  subprocess.run(
412
548
  ["screen", "-X", "-S", screen_id, "hardcopy", "-h", temp_file],
@@ -440,51 +576,22 @@ class TelegramBot:
440
576
  "\n\n", "\n"
441
577
  ) # Rimuovi newline multipli
442
578
 
443
- # Estrarre tutte le parti da "Download:" fino a "Video" o "Subtitle", senza includerli
444
- download_matches = re.findall(
445
- r"Download: (.*?)(?:Video|Subtitle)", cleaned_output
446
- )
447
- if download_matches:
448
- # Serie TV e Film StreamingCommunity
449
-
450
- proc_matches = re.findall(r"Proc: ([\d\.]+%)", cleaned_output)
451
-
452
- # Creare una stringa unica con tutti i risultati
453
- result_string = "\n".join(
454
- [
455
- f"Download: {download_matches[i].strip()}\nDownload al {proc_matches[i]}"
456
- for i in range(len(download_matches))
457
- if i < len(proc_matches)
458
- ]
459
- )
460
-
461
- if result_string != "":
462
- cleaned_output = result_string
463
- else:
464
- print(f"❌ La parola 'Download:' non è stata trovata nella stringa.")
465
- else:
466
-
467
- download_list = []
468
-
469
- # Estrai tutte le righe che iniziano con "Download:" fino al prossimo "Download" o alla fine della riga
470
- matches = re.findall(r"Download:\s*(.*?)(?=Download|$)", cleaned_output)
579
+ # Dentro cleaned_output c'è una stringa recupero quello che si trova tra ## ##
580
+ download_section = re.search(r"##(.*?)##", cleaned_output, re.DOTALL)
581
+ if download_section:
582
+ cleaned_output_0 = "Download: " + download_section.group(1).strip()
471
583
 
472
- # Se sono stati trovati download, stampali
473
- if matches:
474
- for i, match in enumerate(matches, 1):
475
- # rimuovo solo la parte "downloader.py:57Result:400" se esiste
476
- match = re.sub(r"downloader.py:\d+Result:400", "", match)
477
- match = match.strip() # Rimuovo gli spazi bianchi in eccesso
478
- if match: # Assicurati che la stringa non sia vuota
479
- print(f"Download {i}: {match}")
584
+ # Recupero tutto quello che viene dopo con ####
585
+ download_section_bottom = re.search(r"####(.*)", cleaned_output, re.DOTALL)
586
+ if download_section_bottom:
587
+ cleaned_output_1 = download_section_bottom.group(1).strip()
480
588
 
481
- # Aggiungi il risultato modificato alla lista
482
- download_list.append(f"Download {i}: {match}")
483
-
484
- # Creare una stringa unica con tutti i risultati
485
- cleaned_output = "\n".join(download_list)
486
- else:
487
- print("❌ Nessun download trovato")
589
+ # Unico i due risultati se esistono
590
+ if cleaned_output_0 and cleaned_output_1:
591
+ cleaned_output = f"{cleaned_output_0}\n{cleaned_output_1}"
592
+ # Rimuovo 'segments.py:302' e 'downloader.py:385' se presente
593
+ cleaned_output = re.sub(r'downloader\.py:\d+', '', cleaned_output)
594
+ cleaned_output = re.sub(r'segments\.py:\d+', '', cleaned_output)
488
595
 
489
596
  # Invia l'output pulito
490
597
  print(f"📄 Output della screen {screen_id}:\n{cleaned_output}")
@@ -505,7 +612,16 @@ class TelegramBot:
505
612
  os.remove(temp_file)
506
613
 
507
614
  def send_message(self, message, choices):
508
- if choices is None:
615
+
616
+ formatted_message = message
617
+ if choices:
618
+ formatted_choices = "\n".join(choices)
619
+ formatted_message = f"{message}\n\n{formatted_choices}"
620
+
621
+ for chat_id in self.authorized_users:
622
+ self.bot.send_message(chat_id, formatted_message)
623
+
624
+ """ if choices is None:
509
625
  if self.chat_id:
510
626
  print(f"{message}")
511
627
  self.bot.send_message(self.chat_id, message)
@@ -514,7 +630,7 @@ class TelegramBot:
514
630
  message = f"{message}\n\n{formatted_choices}"
515
631
  if self.chat_id:
516
632
  print(f"{message}")
517
- self.bot.send_message(self.chat_id, message)
633
+ self.bot.send_message(self.chat_id, message) """
518
634
 
519
635
  def _send_long_message(self, chat_id, text, chunk_size=4096):
520
636
  """Suddivide e invia un messaggio troppo lungo in più parti."""
@@ -527,16 +643,20 @@ class TelegramBot:
527
643
 
528
644
  if choices is None:
529
645
  print(f"{prompt_message}")
530
- self.bot.send_message(
646
+ """ self.bot.send_message(
531
647
  self.chat_id,
532
648
  f"{prompt_message}",
533
- )
649
+ ) """
650
+ for chat_id in self.authorized_users: # Manda a tutti gli ID autorizzati
651
+ self.bot.send_message(chat_id, f"{prompt_message}")
534
652
  else:
535
653
  print(f"{prompt_message}\n\nOpzioni: {', '.join(choices)}")
536
- self.bot.send_message(
654
+ """ self.bot.send_message(
537
655
  self.chat_id,
538
656
  f"{prompt_message}\n\nOpzioni: {', '.join(choices)}",
539
- )
657
+ ) """
658
+ for chat_id in self.authorized_users: # Manda a tutti gli ID autorizzati
659
+ self.bot.send_message(chat_id, f"{prompt_message}\n\nOpzioni: {', '.join(choices)}")
540
660
 
541
661
  start_time = time.time()
542
662
  while time.time() - start_time < timeout:
@@ -546,7 +666,8 @@ class TelegramBot:
546
666
  time.sleep(1)
547
667
 
548
668
  print(f"⚠️ Timeout: nessuna risposta ricevuta.")
549
- self.bot.send_message(self.chat_id, "⚠️ Timeout: nessuna risposta ricevuta.")
669
+ for chat_id in self.authorized_users: # Manda a tutti gli ID autorizzati
670
+ self.bot.send_message(chat_id, "⚠️ Timeout: nessuna risposta ricevuta.")
550
671
  self.request_manager.clear_file()
551
672
  return None
552
673
 
@@ -558,4 +679,37 @@ class TelegramBot:
558
679
 
559
680
 
560
681
  def get_bot_instance():
561
- return TelegramBot.get_instance()
682
+ return TelegramBot.get_instance()
683
+
684
+ # Esempio di utilizzo
685
+ if __name__ == "__main__":
686
+
687
+ # Usa le variabili
688
+ token = os.getenv("TOKEN_TELEGRAM")
689
+ authorized_users = os.getenv("AUTHORIZED_USER_ID")
690
+
691
+ # Controlla se le variabili sono presenti
692
+ if not token:
693
+ print("Errore: TOKEN_TELEGRAM non è definito nel file .env.")
694
+ sys.exit(1)
695
+
696
+ if not authorized_users:
697
+ print("Errore: AUTHORIZED_USER_ID non è definito nel file .env.")
698
+ sys.exit(1)
699
+
700
+ try:
701
+ TOKEN = token # Inserisci il token del tuo bot Telegram sul file .env
702
+ AUTHORIZED_USER_ID = list(map(int, authorized_users.split(","))) # Inserisci il tuo ID utente Telegram sul file .env
703
+ except ValueError as e:
704
+ print(f"Errore nella conversione degli ID autorizzati: {e}. Controlla il file .env e assicurati che gli ID siano numeri interi separati da virgole.")
705
+ sys.exit(1)
706
+
707
+ # Inizializza il bot
708
+ bot = TelegramBot.init_bot(TOKEN, AUTHORIZED_USER_ID)
709
+ bot.run()
710
+
711
+ """
712
+ start - Avvia lo script
713
+ list - Lista script attivi
714
+ get - Mostra ID utente Telegram
715
+ """