StreamingCommunity 2.0.0__py3-none-any.whl → 2.2.0__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 (33) hide show
  1. StreamingCommunity/Api/Site/1337xx/__init__.py +1 -1
  2. StreamingCommunity/Api/Site/altadefinizione/__init__.py +1 -1
  3. StreamingCommunity/Api/Site/animeunity/__init__.py +1 -1
  4. StreamingCommunity/Api/Site/cb01new/__init__.py +1 -1
  5. StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py +1 -3
  6. StreamingCommunity/Api/Site/ddlstreamitaly/series.py +1 -1
  7. StreamingCommunity/Api/Site/guardaserie/__init__.py +1 -3
  8. StreamingCommunity/Api/Site/guardaserie/series.py +2 -2
  9. StreamingCommunity/Api/Site/ilcorsaronero/__init__.py +1 -1
  10. StreamingCommunity/Api/Site/ilcorsaronero/util/ilCorsarScraper.py +14 -6
  11. StreamingCommunity/Api/Site/mostraguarda/__init__.py +1 -1
  12. StreamingCommunity/Api/Site/mostraguarda/film.py +1 -3
  13. StreamingCommunity/Api/Site/streamingcommunity/__init__.py +1 -1
  14. StreamingCommunity/Api/Site/streamingcommunity/film.py +1 -1
  15. StreamingCommunity/Api/Site/streamingcommunity/series.py +1 -1
  16. StreamingCommunity/Api/Template/Util/get_domain.py +12 -11
  17. StreamingCommunity/Lib/Downloader/HLS/downloader.py +42 -34
  18. StreamingCommunity/Lib/Downloader/HLS/segments.py +9 -11
  19. StreamingCommunity/Lib/FFmpeg/capture.py +1 -1
  20. StreamingCommunity/Lib/FFmpeg/util.py +1 -1
  21. StreamingCommunity/Lib/M3U8/decryptor.py +2 -2
  22. StreamingCommunity/Lib/M3U8/estimator.py +143 -90
  23. StreamingCommunity/Upload/update.py +2 -3
  24. StreamingCommunity/Upload/version.py +1 -1
  25. StreamingCommunity/Util/ffmpeg_installer.py +68 -28
  26. StreamingCommunity/Util/os.py +16 -25
  27. StreamingCommunity/run.py +0 -1
  28. {StreamingCommunity-2.0.0.dist-info → StreamingCommunity-2.2.0.dist-info}/METADATA +12 -9
  29. {StreamingCommunity-2.0.0.dist-info → StreamingCommunity-2.2.0.dist-info}/RECORD +33 -33
  30. {StreamingCommunity-2.0.0.dist-info → StreamingCommunity-2.2.0.dist-info}/WHEEL +1 -1
  31. {StreamingCommunity-2.0.0.dist-info → StreamingCommunity-2.2.0.dist-info}/entry_points.txt +1 -0
  32. {StreamingCommunity-2.0.0.dist-info → StreamingCommunity-2.2.0.dist-info}/LICENSE +0 -0
  33. {StreamingCommunity-2.0.0.dist-info → StreamingCommunity-2.2.0.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
1
- # 20.02.24
1
+ # 21.04.25
2
2
 
3
3
  import os
4
4
  import time
@@ -26,7 +26,7 @@ class M3U8_Ts_Estimator:
26
26
  def __init__(self, total_segments: int):
27
27
  """
28
28
  Initialize the M3U8_Ts_Estimator object.
29
-
29
+
30
30
  Parameters:
31
31
  - total_segments (int): Length of total segments to download.
32
32
  """
@@ -34,73 +34,120 @@ class M3U8_Ts_Estimator:
34
34
  self.now_downloaded_size = 0
35
35
  self.total_segments = total_segments
36
36
  self.lock = threading.Lock()
37
- self.speed = {"upload": "N/A", "download": "N/A"} # Default to N/A
38
- self.speed_thread = threading.Thread(target=self.capture_speed)
39
- self.speed_thread.daemon = True
40
- self.speed_thread.start()
37
+ self.speed = {"upload": "N/A", "download": "N/A"}
38
+ self.process_pid = os.getpid() # Get current process PID
39
+ logging.debug(f"Initializing M3U8_Ts_Estimator with PID: {self.process_pid}")
41
40
 
42
- def add_ts_file(self, size: int, size_download: int, duration: float):
43
- """
44
- Add a file size to the list of file sizes.
41
+ # Start the speed capture thread if TQDM_USE_LARGE_BAR is True
42
+ if TQDM_USE_LARGE_BAR:
43
+ logging.debug("TQDM_USE_LARGE_BAR is True, starting speed capture thread")
44
+ self.speed_thread = threading.Thread(target=self.capture_speed, args=(1, self.process_pid))
45
+ self.speed_thread.daemon = True
46
+ self.speed_thread.start()
45
47
 
46
- Parameters:
47
- - size (int): The size of the ts file to be added.
48
- - size_download (int): Single size of the ts file.
49
- - duration (float): Time to download segment file.
50
- """
48
+ else:
49
+ logging.debug("TQDM_USE_LARGE_BAR is False, speed capture thread not started")
50
+
51
+ def add_ts_file(self, size: int, size_download: int, duration: float):
52
+ """Add a file size to the list of file sizes."""
53
+ logging.debug(f"Adding ts file - size: {size}, download size: {size_download}, duration: {duration}")
54
+
51
55
  if size <= 0 or size_download <= 0 or duration <= 0:
52
- logging.error("Invalid input values: size=%d, size_download=%d, duration=%f", size, size_download, duration)
56
+ logging.error(f"Invalid input values: size={size}, size_download={size_download}, duration={duration}")
53
57
  return
54
58
 
55
- # Add total size bytes
56
59
  self.ts_file_sizes.append(size)
57
60
  self.now_downloaded_size += size_download
61
+ logging.debug(f"Current total downloaded size: {self.now_downloaded_size}")
58
62
 
59
- def capture_speed(self, interval: float = 1):
60
- """
61
- Capture the internet speed periodically and store the values.
62
- """
63
- def get_network_io():
64
- """Get network I/O counters, handle missing psutil gracefully."""
63
+ def capture_speed(self, interval: float = 1, pid: int = None):
64
+ """Capture the internet speed periodically."""
65
+ logging.debug(f"Starting speed capture with interval {interval}s for PID: {pid}")
66
+
67
+ def get_network_io(process=None):
65
68
  try:
66
- io_counters = psutil.net_io_counters()
67
- return io_counters
68
-
69
+ if process:
70
+
71
+ # For process-specific monitoring
72
+ connections = process.connections(kind='inet')
73
+ if connections:
74
+ io_counters = process.io_counters()
75
+ logging.debug(f"Process IO counters: {io_counters}")
76
+ return io_counters
77
+
78
+ else:
79
+ logging.debug("No active internet connections found for process")
80
+ return None
81
+ else:
82
+
83
+ # For system-wide monitoring
84
+ io_counters = psutil.net_io_counters()
85
+ logging.debug(f"System IO counters: {io_counters}")
86
+ return io_counters
87
+
69
88
  except Exception as e:
70
- logging.warning(f"Unable to access network I/O counters: {e}")
89
+ logging.error(f"Error getting network IO: {str(e)}")
71
90
  return None
72
91
 
73
- while True:
74
- old_value = get_network_io()
75
-
76
- if old_value is None: # If psutil is not available, continue with default values
77
- time.sleep(interval)
78
- continue
79
-
80
- time.sleep(interval)
81
- new_value = get_network_io()
82
-
83
- if new_value is None: # Handle again if psutil fails in the next call
84
- time.sleep(interval)
85
- continue
92
+ try:
93
+ process = psutil.Process(pid) if pid else None
94
+ logging.debug(f"Monitoring process: {process}")
86
95
 
87
- with self.lock:
88
- upload_speed = (new_value.bytes_sent - old_value.bytes_sent) / interval
89
- download_speed = (new_value.bytes_recv - old_value.bytes_recv) / interval
96
+ except Exception as e:
97
+ logging.error(f"Failed to get process with PID {pid}: {str(e)}")
98
+ process = None
90
99
 
91
- self.speed = {
92
- "upload": internet_manager.format_transfer_speed(upload_speed),
93
- "download": internet_manager.format_transfer_speed(download_speed)
94
- }
100
+ last_upload = None
101
+ last_download = None
102
+ first_run = True
103
+
104
+ # Buffer circolare per le ultime N misurazioni
105
+ speed_buffer_size = 3
106
+ speed_buffer = deque(maxlen=speed_buffer_size)
95
107
 
96
- def get_average_speed(self) -> float:
97
- """
98
- Calculate the average internet speed.
108
+ while True:
109
+ try:
110
+ io_counters = get_network_io()
111
+
112
+ if io_counters:
113
+ current_upload = io_counters.bytes_sent
114
+ current_download = io_counters.bytes_recv
115
+
116
+ if not first_run and last_upload is not None and last_download is not None:
117
+
118
+ # Calcola la velocità istantanea
119
+ upload_speed = max(0, (current_upload - last_upload) / interval)
120
+ download_speed = max(0, (current_download - last_download) / interval)
121
+
122
+ # Aggiungi al buffer
123
+ speed_buffer.append(download_speed)
124
+
125
+ # Calcola la media mobile delle velocità
126
+ if len(speed_buffer) > 0:
127
+ avg_download_speed = sum(speed_buffer) / len(speed_buffer)
128
+
129
+ if avg_download_speed > 0:
130
+ with self.lock:
131
+ self.speed = {
132
+ "upload": internet_manager.format_transfer_speed(upload_speed),
133
+ "download": internet_manager.format_transfer_speed(avg_download_speed)
134
+ }
135
+ logging.debug(f"Updated speeds - Upload: {self.speed['upload']}, Download: {self.speed['download']}")
136
+
137
+ last_upload = current_upload
138
+ last_download = current_download
139
+ first_run = False
140
+
141
+ time.sleep(interval)
142
+ except Exception as e:
143
+ logging.error(f"Error in speed capture loop: {str(e)}")
144
+ logging.exception("Full traceback:")
145
+ logging.sleep(interval)
99
146
 
100
- Returns:
101
- float: The average internet speed in Mbps.
102
- """
147
+ def get_average_speed(self) -> list:
148
+ """Calculate the average internet speed."""
103
149
  with self.lock:
150
+ logging.debug(f"Current speed data: {self.speed}")
104
151
  return self.speed['download'].split(" ")
105
152
 
106
153
  def calculate_total_size(self) -> str:
@@ -127,7 +174,7 @@ class M3U8_Ts_Estimator:
127
174
  except Exception as e:
128
175
  logging.error("An unexpected error occurred: %s", e)
129
176
  return "Error"
130
-
177
+
131
178
  def get_downloaded_size(self) -> str:
132
179
  """
133
180
  Get the total downloaded size formatted as a human-readable string.
@@ -136,41 +183,47 @@ class M3U8_Ts_Estimator:
136
183
  str: The total downloaded size as a human-readable string.
137
184
  """
138
185
  return internet_manager.format_file_size(self.now_downloaded_size)
139
-
186
+
140
187
  def update_progress_bar(self, total_downloaded: int, duration: float, progress_counter: tqdm) -> None:
141
- """
142
- Updates the progress bar with information about the TS segment download.
143
-
144
- Parameters:
145
- total_downloaded (int): The length of the content of the downloaded TS segment.
146
- duration (float): The duration of the segment download in seconds.
147
- progress_counter (tqdm): The tqdm object representing the progress bar.
148
- """
149
- # Add the size of the downloaded segment to the estimator
150
- self.add_ts_file(total_downloaded * self.total_segments, total_downloaded, duration)
151
-
152
- # Get downloaded size and total estimated size
153
- downloaded_file_size_str = self.get_downloaded_size()
154
- file_total_size = self.calculate_total_size()
155
-
156
- # Fix parameter for prefix
157
- number_file_downloaded = downloaded_file_size_str.split(' ')[0]
158
- number_file_total_size = file_total_size.split(' ')[0]
159
- units_file_downloaded = downloaded_file_size_str.split(' ')[1]
160
- units_file_total_size = file_total_size.split(' ')[1]
161
-
162
- average_internet_speed = self.get_average_speed()[0]
163
- average_internet_unit = self.get_average_speed()[1]
164
-
165
- # Update the progress bar's postfix
166
- if TQDM_USE_LARGE_BAR:
167
- progress_counter.set_postfix_str(
168
- f"{Colors.WHITE}[ {Colors.GREEN}{number_file_downloaded} {Colors.WHITE}< {Colors.GREEN}{number_file_total_size} {Colors.RED}{units_file_total_size} "
169
- f"{Colors.WHITE}| {Colors.CYAN}{average_internet_speed} {Colors.RED}{average_internet_unit}"
170
- )
171
- else:
172
- progress_counter.set_postfix_str(
173
- f"{Colors.WHITE}[ {Colors.GREEN}{number_file_downloaded}{Colors.RED} {units_file_downloaded} "
174
- f"{Colors.WHITE}| {Colors.CYAN}{average_internet_speed} {Colors.RED}{average_internet_unit}"
175
- )
176
-
188
+ """Updates the progress bar with download information."""
189
+ try:
190
+ self.add_ts_file(total_downloaded * self.total_segments, total_downloaded, duration)
191
+
192
+ downloaded_file_size_str = self.get_downloaded_size()
193
+ file_total_size = self.calculate_total_size()
194
+
195
+ number_file_downloaded = downloaded_file_size_str.split(' ')[0]
196
+ number_file_total_size = file_total_size.split(' ')[0]
197
+ units_file_downloaded = downloaded_file_size_str.split(' ')[1]
198
+ units_file_total_size = file_total_size.split(' ')[1]
199
+
200
+ if TQDM_USE_LARGE_BAR:
201
+ speed_data = self.get_average_speed()
202
+ logging.debug(f"Speed data for progress bar: {speed_data}")
203
+
204
+ if len(speed_data) >= 2:
205
+ average_internet_speed = speed_data[0]
206
+ average_internet_unit = speed_data[1]
207
+
208
+ else:
209
+ logging.warning(f"Invalid speed data format: {speed_data}")
210
+ average_internet_speed = "N/A"
211
+ average_internet_unit = ""
212
+
213
+ progress_str = (
214
+ f"{Colors.WHITE}[ {Colors.GREEN}{number_file_downloaded} {Colors.WHITE}< "
215
+ f"{Colors.GREEN}{number_file_total_size} {Colors.RED}{units_file_total_size} "
216
+ f"{Colors.WHITE}| {Colors.CYAN}{average_internet_speed} {Colors.RED}{average_internet_unit}"
217
+ )
218
+
219
+ else:
220
+ progress_str = (
221
+ f"{Colors.WHITE}[ {Colors.GREEN}{number_file_downloaded} {Colors.WHITE}< "
222
+ f"{Colors.GREEN}{number_file_total_size} {Colors.RED}{units_file_total_size}"
223
+ )
224
+
225
+ progress_counter.set_postfix_str(progress_str)
226
+ logging.debug(f"Updated progress bar: {progress_str}")
227
+
228
+ except Exception as e:
229
+ logging.error(f"Error updating progress bar: {str(e)}")
@@ -57,11 +57,10 @@ def update():
57
57
 
58
58
  # Check installed version
59
59
  if str(__version__).replace('v', '') != str(last_version).replace('v', '') :
60
- console.print(f"[red]New version available: [yellow]{last_version}")
60
+ console.print(f"[red]New version available: [yellow]{last_version} \n")
61
61
  else:
62
- console.print(f"[red]Everything is up to date")
62
+ console.print(f" [yellow]Everything is up to date \n")
63
63
 
64
- console.print("\n")
65
64
  console.print(f"[red]{__title__} has been downloaded [yellow]{total_download_count} [red]times, but only [yellow]{percentual_stars}% [red]of users have starred it.\n\
66
65
  [cyan]Help the repository grow today by leaving a [yellow]star [cyan]and [yellow]sharing [cyan]it with others online!")
67
66
 
@@ -1,5 +1,5 @@
1
1
  __title__ = 'StreamingCommunity'
2
- __version__ = '2.0.0'
2
+ __version__ = '2.2.0'
3
3
  __author__ = 'Lovi-0'
4
4
  __description__ = 'A command-line program to download film'
5
5
  __copyright__ = 'Copyright 2024'
@@ -116,21 +116,35 @@ class FFMPEGDownloader:
116
116
  def _check_existing_binaries(self) -> Tuple[Optional[str], Optional[str], Optional[str]]:
117
117
  """
118
118
  Check if FFmpeg binaries already exist in the base directory.
119
-
120
- Returns:
121
- Tuple[Optional[str], Optional[str], Optional[str]]: Paths to ffmpeg, ffprobe, and ffplay executables.
122
- Returns None for each executable that is not found.
119
+ Enhanced to check both the binary directory and system paths on macOS.
123
120
  """
124
121
  config = FFMPEG_CONFIGURATION[self.os_name]
125
122
  executables = config['executables']
126
123
  found_executables = []
127
124
 
128
- for executable in executables:
129
- exe_paths = glob.glob(os.path.join(self.base_dir, executable))
130
- if exe_paths:
131
- found_executables.append(exe_paths[0])
132
- else:
133
- found_executables.append(None)
125
+ # For macOS, check both binary directory and system paths
126
+ if self.os_name == 'darwin':
127
+ potential_paths = [
128
+ '/usr/local/bin',
129
+ '/opt/homebrew/bin',
130
+ '/usr/bin',
131
+ self.base_dir
132
+ ]
133
+
134
+ for executable in executables:
135
+ found = None
136
+ for path in potential_paths:
137
+ full_path = os.path.join(path, executable)
138
+ if os.path.exists(full_path) and os.access(full_path, os.X_OK):
139
+ found = full_path
140
+ break
141
+ found_executables.append(found)
142
+ else:
143
+
144
+ # Original behavior for other operating systems
145
+ for executable in executables:
146
+ exe_paths = glob.glob(os.path.join(self.base_dir, executable))
147
+ found_executables.append(exe_paths[0] if exe_paths else None)
134
148
 
135
149
  return tuple(found_executables) if len(found_executables) == 3 else (None, None, None)
136
150
 
@@ -275,37 +289,63 @@ class FFMPEGDownloader:
275
289
  def check_ffmpeg() -> Tuple[Optional[str], Optional[str], Optional[str]]:
276
290
  """
277
291
  Check for FFmpeg executables in the system and download them if not found.
292
+ Enhanced detection for macOS systems.
278
293
 
279
294
  Returns:
280
295
  Tuple[Optional[str], Optional[str], Optional[str]]: Paths to ffmpeg, ffprobe, and ffplay executables.
281
- Returns None for each executable that couldn't be found or downloaded.
282
-
283
- The function first checks if FFmpeg executables are available in the system PATH:
284
- - On Windows, uses the 'where' command
285
- - On Unix-like systems, uses 'which'
286
-
287
- If the executables are not found in PATH, it attempts to download and install them
288
- using the FFMPEGDownloader class.
289
296
  """
290
297
  try:
291
- if platform.system().lower() == 'windows':
292
- ffmpeg_path = subprocess.check_output(['where', 'ffmpeg'], text=True).strip().split('\n')[0] if subprocess.call(['where', 'ffmpeg'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0 else None
293
- ffprobe_path = subprocess.check_output(['where', 'ffprobe'], text=True).strip().split('\n')[0] if subprocess.call(['where', 'ffprobe'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0 else None
294
- ffplay_path = subprocess.check_output(['where', 'ffplay'], text=True).strip().split('\n')[0] if subprocess.call(['where', 'ffplay'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0 else None
298
+ system_platform = platform.system().lower()
299
+
300
+ # Special handling for macOS
301
+ if system_platform == 'darwin':
302
+
303
+ # Common installation paths on macOS
304
+ potential_paths = [
305
+ '/usr/local/bin', # Homebrew default
306
+ '/opt/homebrew/bin', # Apple Silicon Homebrew
307
+ '/usr/bin', # System default
308
+ os.path.expanduser('~/Applications/binary'), # Custom installation
309
+ '/Applications/binary' # Custom installation
310
+ ]
295
311
 
296
- if all([ffmpeg_path, ffprobe_path, ffplay_path]):
297
- return ffmpeg_path, ffprobe_path, ffplay_path
312
+ for path in potential_paths:
313
+ ffmpeg_path = os.path.join(path, 'ffmpeg')
314
+ ffprobe_path = os.path.join(path, 'ffprobe')
315
+ ffplay_path = os.path.join(path, 'ffplay')
316
+
317
+ if (os.path.exists(ffmpeg_path) and os.path.exists(ffprobe_path) and
318
+ os.access(ffmpeg_path, os.X_OK) and os.access(ffprobe_path, os.X_OK)):
319
+
320
+ # Return found executables, with ffplay being optional
321
+ ffplay_path = ffplay_path if os.path.exists(ffplay_path) else None
322
+ return ffmpeg_path, ffprobe_path, ffplay_path
323
+
324
+ # Windows detection
325
+ elif system_platform == 'windows':
326
+ try:
327
+ ffmpeg_path = subprocess.check_output(['where', 'ffmpeg'], text=True).strip().split('\n')[0]
328
+ ffprobe_path = subprocess.check_output(['where', 'ffprobe'], text=True).strip().split('\n')[0]
329
+ ffplay_path = subprocess.check_output(['where', 'ffplay'], text=True).strip().split('\n')[0]
330
+
331
+ if ffmpeg_path and ffprobe_path:
332
+ return ffmpeg_path, ffprobe_path, ffplay_path
333
+ except subprocess.CalledProcessError:
334
+ pass
335
+
336
+ # Linux detection
298
337
  else:
299
338
  ffmpeg_path = shutil.which('ffmpeg')
300
339
  ffprobe_path = shutil.which('ffprobe')
301
340
  ffplay_path = shutil.which('ffplay')
302
341
 
303
- if all([ffmpeg_path, ffprobe_path, ffplay_path]):
342
+ if ffmpeg_path and ffprobe_path:
304
343
  return ffmpeg_path, ffprobe_path, ffplay_path
305
-
344
+
345
+ # If executables were not found, attempt to download FFmpeg
306
346
  downloader = FFMPEGDownloader()
307
347
  return downloader.download()
308
-
348
+
309
349
  except Exception as e:
310
- logging.error(f"Error checking FFmpeg: {e}")
350
+ logging.error(f"Error checking or downloading FFmpeg executables: {e}")
311
351
  return None, None, None
@@ -317,16 +317,13 @@ class InternManager():
317
317
  def check_internet():
318
318
  while True:
319
319
  try:
320
- httpx.get("https://www.google.com")
321
- #console.log("[bold green]Internet is available![/bold green]")
320
+ httpx.get("https://www.google.com", timeout=15)
322
321
  break
323
322
 
324
323
  except urllib.error.URLError:
325
324
  console.log("[bold red]Internet is not available. Waiting...[/bold red]")
326
325
  time.sleep(5)
327
326
 
328
- print()
329
-
330
327
 
331
328
  class OsSummary:
332
329
 
@@ -353,20 +350,17 @@ class OsSummary:
353
350
  console.print(f"{command[0]} not found", style="bold red")
354
351
  sys.exit(0)
355
352
 
356
- def check_ffmpeg_location(self, command: list):
353
+ def check_ffmpeg_location(self, command: list) -> str:
357
354
  """
358
- Run 'where ffmpeg' command to check FFmpeg's location.
359
-
360
- Returns:
361
- str: Location of FFmpeg executable or None if not found
355
+ Check if a specific executable (ffmpeg or ffprobe) is located using the given command.
356
+ Returns the path of the executable or None if not found.
362
357
  """
363
358
  try:
364
- result = subprocess.check_output(command, stderr=subprocess.STDOUT, text=True).strip()
365
- return result
359
+ result = subprocess.check_output(command, text=True).strip()
360
+ return result.split('\n')[0] if result else None
366
361
 
367
362
  except subprocess.CalledProcessError:
368
- console.print("FFmpeg not found in system PATH", style="bold red")
369
- sys.exit(0)
363
+ return None
370
364
 
371
365
  def get_library_version(self, lib_name: str):
372
366
  """
@@ -467,27 +461,24 @@ class OsSummary:
467
461
  console.print(f"[cyan]Python[white]: [bold red]{python_version} ({python_implementation} {arch}) - {os_info} ({glibc_version})[/bold red]")
468
462
  logging.info(f"Python: {python_version} ({python_implementation} {arch}) - {os_info} ({glibc_version})")
469
463
 
470
- # Usa il comando 'where' su Windows
471
- if platform.system() == "Windows":
472
- command = 'where'
473
-
474
- # Usa il comando 'which' su Unix/Linux
475
- else:
476
- command = 'which'
464
+ # Use the 'where' command on Windows and 'which' command on Unix-like systems
465
+ system_platform = platform.system().lower()
466
+ command = 'where' if system_platform == 'windows' else 'which'
477
467
 
478
- # Locate ffmpeg and ffprobe from path enviroment
479
- if self.ffmpeg_path != None and "binary" not in self.ffmpeg_path:
468
+ # Locate ffmpeg and ffprobe from the PATH environment
469
+ if self.ffmpeg_path is not None and "binary" not in self.ffmpeg_path:
480
470
  self.ffmpeg_path = self.check_ffmpeg_location([command, 'ffmpeg'])
481
471
 
482
- if self.ffprobe_path != None and "binary" not in self.ffprobe_path:
472
+ if self.ffprobe_path is not None and "binary" not in self.ffprobe_path:
483
473
  self.ffprobe_path = self.check_ffmpeg_location([command, 'ffprobe'])
484
474
 
485
- # Locate ffmpeg from bin installation
475
+ # If ffmpeg or ffprobe is not located, fall back to using the check_ffmpeg function
486
476
  if self.ffmpeg_path is None or self.ffprobe_path is None:
487
477
  self.ffmpeg_path, self.ffprobe_path, self.ffplay_path = check_ffmpeg()
488
478
 
479
+ # If still not found, print error and exit
489
480
  if self.ffmpeg_path is None or self.ffprobe_path is None:
490
- console.log("[red]Cant locate ffmpeg or ffprobe")
481
+ console.log("[red]Can't locate ffmpeg or ffprobe")
491
482
  sys.exit(0)
492
483
 
493
484
  ffmpeg_version = self.get_executable_version([self.ffprobe_path, '-version'])
StreamingCommunity/run.py CHANGED
@@ -120,7 +120,6 @@ def initialize():
120
120
  # Attempting GitHub update
121
121
  try:
122
122
  git_update()
123
- print()
124
123
  except:
125
124
  console.log("[red]Error with loading github.")
126
125
 
@@ -1,17 +1,17 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: StreamingCommunity
3
- Version: 2.0.0
4
- Summary: A streaming community package
3
+ Version: 2.2.0
4
+ Summary: UNKNOWN
5
5
  Home-page: https://github.com/Lovi-0/StreamingCommunity
6
6
  Author: Lovi-0
7
+ License: UNKNOWN
7
8
  Project-URL: Bug Reports, https://github.com/Lovi-0/StreamingCommunity/issues
8
9
  Project-URL: Source, https://github.com/Lovi-0/StreamingCommunity
9
- Keywords: Streaming Community
10
+ Keywords: streaming community
11
+ Platform: UNKNOWN
10
12
  Requires-Python: >=3.8
11
13
  Description-Content-Type: text/markdown
12
- License-File: LICENSE
13
14
  Requires-Dist: httpx
14
- Requires-Dist: cffi
15
15
  Requires-Dist: bs4
16
16
  Requires-Dist: rich
17
17
  Requires-Dist: tqdm
@@ -255,7 +255,7 @@ The configuration file is divided into several main sections:
255
255
  * `%(episode)` : Is the number of the episode
256
256
  * `%(episode_name)` : Is the name of the episode
257
257
  `<br/><br/>`
258
-
258
+
259
259
  - `not_close`: If true, continues running after downloading
260
260
 
261
261
  ### qBittorrent Configuration
@@ -307,6 +307,9 @@ The configuration file is divided into several main sections:
307
307
  - `default_audio_workser`: Number of threads for audio download
308
308
  - `cleanup_tmp_folder`: Remove temporary .ts files after download
309
309
 
310
+ > [!IMPORTANT]
311
+ > Set `tqdm_use_large_bar` to `false` when using Termux or terminals with limited width to prevent display issues
312
+
310
313
 
311
314
  <br>
312
315
 
@@ -359,10 +362,8 @@ forced-ita hin - Hindi pol - Polish tur - Turkish
359
362
 
360
363
  <br>
361
364
 
362
-
363
365
  # COMMAND
364
366
 
365
-
366
367
  - Download a specific season by entering its number.
367
368
  * **Example:** `1` will download *Season 1* only.
368
369
 
@@ -433,7 +434,7 @@ The `run-container` command mounts also the `config.json` file, so any change to
433
434
 
434
435
  # To Do
435
436
 
436
- - Create website API -> https://github.com/Lovi-0/StreamingCommunity/tree/test_gui_1
437
+ - Finish [website API](https://github.com/Lovi-0/StreamingCommunity/tree/test_gui_1)
437
438
 
438
439
  # Contributing
439
440
 
@@ -454,3 +455,5 @@ This software is provided "as is", without warranty of any kind, express or impl
454
455
  <a href="https://github.com/Lovi-0/StreamingCommunity/graphs/contributors" alt="View Contributors">
455
456
  <img src="https://contrib.rocks/image?repo=Lovi-0/StreamingCommunity&max=1000&columns=10" alt="Contributors" />
456
457
  </a>
458
+
459
+