StreamingCommunity 2.0.5__py3-none-any.whl → 2.3.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 (40) hide show
  1. StreamingCommunity/Api/Player/Helper/Vixcloud/util.py +15 -24
  2. StreamingCommunity/Api/Site/1337xx/site.py +9 -6
  3. StreamingCommunity/Api/Site/1337xx/title.py +2 -2
  4. StreamingCommunity/Api/Site/altadefinizione/costant.py +6 -2
  5. StreamingCommunity/Api/Site/altadefinizione/film.py +2 -2
  6. StreamingCommunity/Api/Site/altadefinizione/site.py +28 -22
  7. StreamingCommunity/Api/Site/animeunity/costant.py +6 -2
  8. StreamingCommunity/Api/Site/animeunity/film_serie.py +3 -3
  9. StreamingCommunity/Api/Site/animeunity/site.py +27 -19
  10. StreamingCommunity/Api/Site/cb01new/costant.py +6 -2
  11. StreamingCommunity/Api/Site/cb01new/film.py +2 -2
  12. StreamingCommunity/Api/Site/cb01new/site.py +20 -13
  13. StreamingCommunity/Api/Site/ddlstreamitaly/costant.py +6 -2
  14. StreamingCommunity/Api/Site/ddlstreamitaly/series.py +2 -2
  15. StreamingCommunity/Api/Site/ddlstreamitaly/site.py +9 -5
  16. StreamingCommunity/Api/Site/guardaserie/costant.py +6 -2
  17. StreamingCommunity/Api/Site/guardaserie/series.py +2 -3
  18. StreamingCommunity/Api/Site/guardaserie/site.py +10 -6
  19. StreamingCommunity/Api/Site/ilcorsaronero/costant.py +6 -2
  20. StreamingCommunity/Api/Site/ilcorsaronero/site.py +22 -13
  21. StreamingCommunity/Api/Site/ilcorsaronero/title.py +3 -3
  22. StreamingCommunity/Api/Site/mostraguarda/costant.py +6 -2
  23. StreamingCommunity/Api/Site/mostraguarda/film.py +2 -2
  24. StreamingCommunity/Api/Site/streamingcommunity/costant.py +7 -3
  25. StreamingCommunity/Api/Site/streamingcommunity/film.py +3 -3
  26. StreamingCommunity/Api/Site/streamingcommunity/series.py +2 -2
  27. StreamingCommunity/Api/Site/streamingcommunity/site.py +29 -28
  28. StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +24 -24
  29. StreamingCommunity/Api/Template/Util/get_domain.py +100 -137
  30. StreamingCommunity/Lib/Downloader/HLS/downloader.py +3 -2
  31. StreamingCommunity/Lib/Downloader/HLS/segments.py +21 -17
  32. StreamingCommunity/Lib/M3U8/estimator.py +131 -106
  33. StreamingCommunity/Upload/version.py +1 -1
  34. StreamingCommunity/Util/ffmpeg_installer.py +8 -5
  35. {StreamingCommunity-2.0.5.dist-info → StreamingCommunity-2.3.0.dist-info}/METADATA +36 -19
  36. {StreamingCommunity-2.0.5.dist-info → StreamingCommunity-2.3.0.dist-info}/RECORD +40 -40
  37. {StreamingCommunity-2.0.5.dist-info → StreamingCommunity-2.3.0.dist-info}/LICENSE +0 -0
  38. {StreamingCommunity-2.0.5.dist-info → StreamingCommunity-2.3.0.dist-info}/WHEEL +0 -0
  39. {StreamingCommunity-2.0.5.dist-info → StreamingCommunity-2.3.0.dist-info}/entry_points.txt +0 -0
  40. {StreamingCommunity-2.0.5.dist-info → StreamingCommunity-2.3.0.dist-info}/top_level.txt +0 -0
@@ -194,23 +194,28 @@ class M3U8_Segments:
194
194
  """
195
195
  if self.is_index_url:
196
196
 
197
- # Send a GET request to retrieve the index M3U8 file
198
- response = httpx.get(
199
- self.url,
200
- headers={'User-Agent': get_headers()},
201
- timeout=max_timeout
202
- )
203
- response.raise_for_status()
197
+ try:
204
198
 
205
- # Save the M3U8 file to the temporary folder
206
- path_m3u8_file = os.path.join(self.tmp_folder, "playlist.m3u8")
207
- open(path_m3u8_file, "w+").write(response.text)
199
+ # Send a GET request to retrieve the index M3U8 file
200
+ response = httpx.get(
201
+ self.url,
202
+ headers={'User-Agent': get_headers()},
203
+ timeout=max_timeout,
204
+ follow_redirects=True
205
+ )
206
+ response.raise_for_status()
208
207
 
209
- # Parse the text from the M3U8 index file
210
- self.parse_data(response.text)
208
+ # Save the M3U8 file to the temporary folder
209
+ path_m3u8_file = os.path.join(self.tmp_folder, "playlist.m3u8")
210
+ open(path_m3u8_file, "w+").write(response.text)
211
211
 
212
- else:
212
+ # Parse the text from the M3U8 index file
213
+ self.parse_data(response.text)
213
214
 
215
+ except Exception as e:
216
+ print(f"Error during M3U8 index request: {e}")
217
+
218
+ else:
214
219
  # Parser data of content of index pass in input to class
215
220
  self.parse_data(self.url)
216
221
 
@@ -385,7 +390,7 @@ class M3U8_Segments:
385
390
  buffer[index] = segment_content
386
391
 
387
392
  except queue.Empty:
388
- self.current_timeout = min(self.max_timeout, self.current_timeout * 1.5)
393
+ self.current_timeout = min(self.max_timeout, self.current_timeout * 1.25)
389
394
 
390
395
  if self.stop_event.is_set():
391
396
  break
@@ -545,15 +550,14 @@ class M3U8_Segments:
545
550
  if file_size == 0:
546
551
  raise Exception("Output file is empty")
547
552
 
548
- # Display additional info only if there is failed segments
549
- if self.info_nFailed > 0:
553
+ # Display additional
554
+ if self.info_nRetry >= len(self.segments) * 0.3:
550
555
 
551
556
  # Get expected time
552
557
  ex_hours, ex_minutes, ex_seconds = format_duration(self.expected_real_time_s)
553
558
  ex_formatted_duration = f"[yellow]{int(ex_hours)}[red]h [yellow]{int(ex_minutes)}[red]m [yellow]{int(ex_seconds)}[red]s"
554
559
  console.print(f"[cyan]Max retry per URL[white]: [green]{self.info_maxRetry}[green] [white]| [cyan]Total retry done[white]: [green]{self.info_nRetry}[green] [white]| [cyan]Missing TS: [red]{self.info_nFailed} [white]| [cyan]Duration: {print_duration_table(self.tmp_file_path, None, True)} [white]| [cyan]Expected duation: {ex_formatted_duration} \n")
555
560
 
556
- if self.info_nRetry >= len(self.segments) * (1/3.33):
557
561
  console.print("[yellow]⚠ Warning:[/yellow] Too many retries detected! Consider reducing the number of [cyan]workers[/cyan] in the [magenta]config.json[/magenta] file. This will impact [bold]performance[/bold]. \n")
558
562
 
559
563
  # Info to return
@@ -1,3 +1,5 @@
1
+ # 21.04.25
2
+
1
3
  import os
2
4
  import time
3
5
  import logging
@@ -24,7 +26,7 @@ class M3U8_Ts_Estimator:
24
26
  def __init__(self, total_segments: int):
25
27
  """
26
28
  Initialize the M3U8_Ts_Estimator object.
27
-
29
+
28
30
  Parameters:
29
31
  - total_segments (int): Length of total segments to download.
30
32
  """
@@ -33,103 +35,119 @@ class M3U8_Ts_Estimator:
33
35
  self.total_segments = total_segments
34
36
  self.lock = threading.Lock()
35
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}")
36
40
 
37
- # Only start the speed capture thread if TQDM_USE_LARGE_BAR is True
38
- if not TQDM_USE_LARGE_BAR:
39
- self.speed_thread = threading.Thread(target=self.capture_speed)
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))
40
45
  self.speed_thread.daemon = True
41
46
  self.speed_thread.start()
42
47
 
43
- def add_ts_file(self, size: int, size_download: int, duration: float):
44
- """
45
- Add a file size to the list of file sizes.
48
+ else:
49
+ logging.debug("TQDM_USE_LARGE_BAR is False, speed capture thread not started")
46
50
 
47
- Parameters:
48
- - size (int): The size of the ts file to be added.
49
- - size_download (int): Single size of the ts file.
50
- - duration (float): Time to download segment file.
51
- """
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
+
52
55
  if size <= 0 or size_download <= 0 or duration <= 0:
53
- 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}")
54
57
  return
55
58
 
56
- # Add total size bytes
57
59
  self.ts_file_sizes.append(size)
58
60
  self.now_downloaded_size += size_download
61
+ logging.debug(f"Current total downloaded size: {self.now_downloaded_size}")
59
62
 
60
63
  def capture_speed(self, interval: float = 1, pid: int = None):
61
- """
62
- Capture the internet speed periodically for a specific process (identified by PID)
63
- or the entire system if no PID is provided.
64
- """
64
+ """Capture the internet speed periodically."""
65
+ logging.debug(f"Starting speed capture with interval {interval}s for PID: {pid}")
65
66
 
66
67
  def get_network_io(process=None):
67
- """
68
- Get network I/O counters for a specific process or system-wide if no process is specified.
69
- """
70
68
  try:
71
69
  if process:
72
- io_counters = process.io_counters()
73
- return io_counters
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
74
81
  else:
82
+
83
+ # For system-wide monitoring
75
84
  io_counters = psutil.net_io_counters()
85
+ logging.debug(f"System IO counters: {io_counters}")
76
86
  return io_counters
87
+
77
88
  except Exception as e:
78
- logging.warning(f"Unable to access network I/O counters: {e}")
89
+ logging.error(f"Error getting network IO: {str(e)}")
79
90
  return None
80
91
 
81
- # If a PID is provided, attempt to attach to the corresponding process
82
- process = None
83
- if pid is not None:
84
- try:
85
- process = psutil.Process(pid)
86
- except psutil.NoSuchProcess:
87
- logging.error(f"Process with PID {pid} does not exist.")
88
- return
89
- except Exception as e:
90
- logging.error(f"Failed to attach to process with PID {pid}: {e}")
91
- return
92
-
93
- while True:
94
- old_value = get_network_io(process)
95
-
96
- if old_value is None: # If psutil fails, continue with the next interval
97
- time.sleep(interval)
98
- continue
99
-
100
- time.sleep(interval)
101
- new_value = get_network_io(process)
92
+ try:
93
+ process = psutil.Process(pid) if pid else None
94
+ logging.debug(f"Monitoring process: {process}")
102
95
 
103
- if new_value is None: # Handle again if psutil fails in the next call
104
- time.sleep(interval)
105
- continue
96
+ except Exception as e:
97
+ logging.error(f"Failed to get process with PID {pid}: {str(e)}")
98
+ process = None
106
99
 
107
- with self.lock:
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)
108
107
 
109
- # Calculate speed based on process-specific counters if process is specified
110
- if process:
111
- upload_speed = (new_value.write_bytes - old_value.write_bytes) / interval
112
- download_speed = (new_value.read_bytes - old_value.read_bytes) / interval
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
113
115
 
114
- else:
115
- # System-wide counters
116
- upload_speed = (new_value.bytes_sent - old_value.bytes_sent) / interval
117
- download_speed = (new_value.bytes_recv - old_value.bytes_recv) / interval
118
-
119
- self.speed = {
120
- "upload": internet_manager.format_transfer_speed(upload_speed),
121
- "download": internet_manager.format_transfer_speed(download_speed)
122
- }
123
-
124
-
125
- def get_average_speed(self) -> float:
126
- """
127
- Calculate the average internet speed.
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)
128
146
 
129
- Returns:
130
- float: The average internet speed in Mbps.
131
- """
147
+ def get_average_speed(self) -> list:
148
+ """Calculate the average internet speed."""
132
149
  with self.lock:
150
+ logging.debug(f"Current speed data: {self.speed}")
133
151
  return self.speed['download'].split(" ")
134
152
 
135
153
  def calculate_total_size(self) -> str:
@@ -156,7 +174,7 @@ class M3U8_Ts_Estimator:
156
174
  except Exception as e:
157
175
  logging.error("An unexpected error occurred: %s", e)
158
176
  return "Error"
159
-
177
+
160
178
  def get_downloaded_size(self) -> str:
161
179
  """
162
180
  Get the total downloaded size formatted as a human-readable string.
@@ -165,40 +183,47 @@ class M3U8_Ts_Estimator:
165
183
  str: The total downloaded size as a human-readable string.
166
184
  """
167
185
  return internet_manager.format_file_size(self.now_downloaded_size)
168
-
186
+
169
187
  def update_progress_bar(self, total_downloaded: int, duration: float, progress_counter: tqdm) -> None:
170
- """
171
- Updates the progress bar with information about the TS segment download.
172
-
173
- Parameters:
174
- total_downloaded (int): The length of the content of the downloaded TS segment.
175
- duration (float): The duration of the segment download in seconds.
176
- progress_counter (tqdm): The tqdm object representing the progress bar.
177
- """
178
- # Add the size of the downloaded segment to the estimator
179
- self.add_ts_file(total_downloaded * self.total_segments, total_downloaded, duration)
180
-
181
- # Get downloaded size and total estimated size
182
- downloaded_file_size_str = self.get_downloaded_size()
183
- file_total_size = self.calculate_total_size()
184
-
185
- # Fix parameter for prefix
186
- number_file_downloaded = downloaded_file_size_str.split(' ')[0]
187
- number_file_total_size = file_total_size.split(' ')[0]
188
- units_file_downloaded = downloaded_file_size_str.split(' ')[1]
189
- units_file_total_size = file_total_size.split(' ')[1]
190
-
191
- # Update the progress bar's postfix
192
- if TQDM_USE_LARGE_BAR:
193
- average_internet_speed = self.get_average_speed()[0]
194
- average_internet_unit = self.get_average_speed()[1]
195
- progress_counter.set_postfix_str(
196
- f"{Colors.WHITE}[ {Colors.GREEN}{number_file_downloaded} {Colors.WHITE}< {Colors.GREEN}{number_file_total_size} {Colors.RED}{units_file_total_size} "
197
- f"{Colors.WHITE}| {Colors.CYAN}{average_internet_speed} {Colors.RED}{average_internet_unit}"
198
- )
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]
199
207
 
200
- else:
201
- progress_counter.set_postfix_str(
202
- f"{Colors.WHITE}[ {Colors.GREEN}{number_file_downloaded}{Colors.RED} {units_file_downloaded} "
203
- f"{Colors.WHITE}| {Colors.CYAN}N/A{Colors.RED} N/A"
204
- )
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)}")
@@ -1,5 +1,5 @@
1
1
  __title__ = 'StreamingCommunity'
2
- __version__ = '2.1.0'
2
+ __version__ = '2.3.0'
3
3
  __author__ = 'Lovi-0'
4
4
  __description__ = 'A command-line program to download film'
5
5
  __copyright__ = 'Copyright 2024'
@@ -140,6 +140,7 @@ class FFMPEGDownloader:
140
140
  break
141
141
  found_executables.append(found)
142
142
  else:
143
+
143
144
  # Original behavior for other operating systems
144
145
  for executable in executables:
145
146
  exe_paths = glob.glob(os.path.join(self.base_dir, executable))
@@ -298,13 +299,14 @@ def check_ffmpeg() -> Tuple[Optional[str], Optional[str], Optional[str]]:
298
299
 
299
300
  # Special handling for macOS
300
301
  if system_platform == 'darwin':
302
+
301
303
  # Common installation paths on macOS
302
304
  potential_paths = [
303
- '/usr/local/bin', # Homebrew default
304
- '/opt/homebrew/bin', # Apple Silicon Homebrew
305
- '/usr/bin', # System default
306
- os.path.expanduser('~/Applications/binary'), # Custom installation
307
- '/Applications/binary' # Custom installation
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
308
310
  ]
309
311
 
310
312
  for path in potential_paths:
@@ -314,6 +316,7 @@ def check_ffmpeg() -> Tuple[Optional[str], Optional[str], Optional[str]]:
314
316
 
315
317
  if (os.path.exists(ffmpeg_path) and os.path.exists(ffprobe_path) and
316
318
  os.access(ffmpeg_path, os.X_OK) and os.access(ffprobe_path, os.X_OK)):
319
+
317
320
  # Return found executables, with ffplay being optional
318
321
  ffplay_path = ffplay_path if os.path.exists(ffplay_path) else None
319
322
  return ffmpeg_path, ffprobe_path, ffplay_path
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: StreamingCommunity
3
- Version: 2.0.5
3
+ Version: 2.3.0
4
4
  Summary: UNKNOWN
5
5
  Home-page: https://github.com/Lovi-0/StreamingCommunity
6
6
  Author: Lovi-0
@@ -34,9 +34,6 @@ Requires-Dist: googlesearch-python
34
34
  <a href="https://pypi.org/project/streamingcommunity">
35
35
  <img src="https://img.shields.io/pypi/v/streamingcommunity?logo=pypi&labelColor=555555&style=for-the-badge" alt="PyPI"/>
36
36
  </a>
37
- <a href="https://www.python.org">
38
- <img src="https://img.shields.io/badge/Python->=3.8-3776AB?style=for-the-badge&logo=python&logoColor=white" alt="Python"/>
39
- </a>
40
37
  <a href="https://www.paypal.com/donate/?hosted_button_id=UXTWMT8P6HE2C">
41
38
  <img src="https://img.shields.io/badge/_-Donate-red.svg?logo=githubsponsors&labelColor=555555&style=for-the-badge" alt="Donate"/>
42
39
  </a>
@@ -90,6 +87,22 @@ Requires-Dist: googlesearch-python
90
87
 
91
88
  # Installation
92
89
 
90
+ <p align="center">
91
+ <a href="https://github.com/Lovi-0/StreamingCommunity/releases/latest/download/StreamingCommunity.exe">
92
+ <img src="https://img.shields.io/badge/-Windows_x64-blue.svg?style=for-the-badge&logo=windows" alt="Windows">
93
+ </a>
94
+ <a href="https://pypi.org/project/StreamingCommunity">
95
+ <img src="https://img.shields.io/badge/-PyPI-blue.svg?logo=pypi&labelColor=555555&style=for-the-badge" alt="PyPI">
96
+ </a>
97
+ <a href="https://github.com/Lovi-0/StreamingCommunity/releases/latest/download/StreamingCommunity.zip">
98
+ <img src="https://img.shields.io/badge/-Source_tar-green.svg?style=for-the-badge" alt="Source Tarball">
99
+ </a>
100
+ <a href="https://github.com/Lovi-0/StreamingCommunity/releases">
101
+ <img src="https://img.shields.io/badge/-All_Versions-lightgrey.svg?style=for-the-badge" alt="All Versions">
102
+ </a>
103
+ </p>
104
+
105
+
93
106
  ## 1. PyPI Installation
94
107
 
95
108
  Install directly from PyPI:
@@ -229,6 +242,8 @@ The configuration file is divided into several main sections:
229
242
  "movie_folder_name": "Movie",
230
243
  "serie_folder_name": "TV",
231
244
  "map_episode_name": "%(tv_name)_S%(season)E%(episode)_%(episode_name)",
245
+ "add_siteName": false,
246
+ "disable_searchDomain": false,
232
247
  "not_close": false
233
248
  }
234
249
  ```
@@ -256,7 +271,10 @@ The configuration file is divided into several main sections:
256
271
  * `%(episode_name)` : Is the name of the episode
257
272
  `<br/><br/>`
258
273
 
259
- - `not_close`: If true, continues running after downloading
274
+ - `add_siteName`: If set to true, appends the site_name to the root path before the movie and serie folders.
275
+ - `disable_searchDomain`: If set to true, disables the search for a new domain for all sites.
276
+ - `not_close`: If set to true, keeps the program running after the download is complete.
277
+
260
278
 
261
279
  ### qBittorrent Configuration
262
280
 
@@ -273,7 +291,6 @@ The configuration file is divided into several main sections:
273
291
 
274
292
  To enable qBittorrent integration, follow the setup guide [here](https://github.com/lgallard/qBittorrent-Controller/wiki/How-to-enable-the-qBittorrent-Web-UI).
275
293
 
276
- <br>
277
294
 
278
295
  ## REQUESTS Settings
279
296
 
@@ -287,7 +304,6 @@ The configuration file is divided into several main sections:
287
304
  - `timeout`: Maximum timeout (in seconds) for each request
288
305
  - `max_retry`: Number of retry attempts per segment during M3U8 index download
289
306
 
290
- <br>
291
307
 
292
308
  ## M3U8_DOWNLOAD Settings
293
309
 
@@ -307,8 +323,10 @@ The configuration file is divided into several main sections:
307
323
  - `default_audio_workser`: Number of threads for audio download
308
324
  - `cleanup_tmp_folder`: Remove temporary .ts files after download
309
325
 
326
+ > [!IMPORTANT]
327
+ > Set `tqdm_use_large_bar` to `false` when using Termux or terminals with limited width to prevent network monitoring issues
328
+
310
329
 
311
- <br>
312
330
 
313
331
  ### Language Settings
314
332
 
@@ -357,7 +375,6 @@ forced-ita hin - Hindi pol - Polish tur - Turkish
357
375
  - `force_resolution`: Force specific resolution (-1 for best available, or specify 1080, 720, 360)
358
376
  - `get_only_link`: Return M3U8 playlist/index URL instead of downloading
359
377
 
360
- <br>
361
378
 
362
379
  # COMMAND
363
380
 
@@ -373,7 +390,6 @@ forced-ita hin - Hindi pol - Polish tur - Turkish
373
390
  - Enter a season number followed by `-*` to download from that season to the end.
374
391
  * **Example:** `3-*` will download from *Season 3* to the final season.
375
392
 
376
- <br>
377
393
 
378
394
  # Docker
379
395
 
@@ -412,15 +428,16 @@ The `run-container` command mounts also the `config.json` file, so any change to
412
428
 
413
429
  | Website | Status |
414
430
  |:-------------------|:------:|
415
- | 1337xx | ✅ |
416
- | Altadefinizione | ✅ |
417
- | AnimeUnity | ✅ |
418
- | Ilcorsaronero | ✅ |
419
- | CB01New | ✅ |
420
- | DDLStreamItaly | ✅ |
421
- | GuardaSerie | ✅ |
422
- | MostraGuarda | ✅ |
423
- | StreamingCommunity | ✅ |
431
+ | [1337xx](https://1337xx.to/) | ✅ |
432
+ | [Altadefinizione](https://altadefinizione.prof/) | ✅ |
433
+ | [AnimeUnity](https://animeunity.so/) | ✅ |
434
+ | [Ilcorsaronero](https://ilcorsaronero.link/) | ✅ |
435
+ | [CB01New](https://cb01new.pics/) | ✅ |
436
+ | [DDLStreamItaly](https://ddlstreamitaly.co/) | ✅ |
437
+ | [GuardaSerie](https://guardaserie.academy/) | ✅ |
438
+ | [MostraGuarda](https://mostraguarda.stream/) | ✅ |
439
+ | [StreamingCommunity](https://streamingcommunity.prof/) | ✅ |
440
+
424
441
 
425
442
  # Tutorials
426
443