StreamingCommunity 1.9.90__py3-none-any.whl → 2.0.5__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 (34) 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 +5 -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/Site/streamingcommunity/site.py +8 -7
  17. StreamingCommunity/Api/Template/Util/get_domain.py +12 -11
  18. StreamingCommunity/Lib/Downloader/HLS/downloader.py +42 -34
  19. StreamingCommunity/Lib/Downloader/HLS/segments.py +10 -11
  20. StreamingCommunity/Lib/FFmpeg/capture.py +1 -1
  21. StreamingCommunity/Lib/FFmpeg/util.py +1 -1
  22. StreamingCommunity/Lib/M3U8/decryptor.py +2 -2
  23. StreamingCommunity/Lib/M3U8/estimator.py +53 -25
  24. StreamingCommunity/Upload/update.py +2 -3
  25. StreamingCommunity/Upload/version.py +1 -1
  26. StreamingCommunity/Util/ffmpeg_installer.py +65 -28
  27. StreamingCommunity/Util/os.py +16 -25
  28. StreamingCommunity/run.py +2 -3
  29. {StreamingCommunity-1.9.90.dist-info → StreamingCommunity-2.0.5.dist-info}/METADATA +73 -44
  30. {StreamingCommunity-1.9.90.dist-info → StreamingCommunity-2.0.5.dist-info}/RECORD +34 -34
  31. {StreamingCommunity-1.9.90.dist-info → StreamingCommunity-2.0.5.dist-info}/WHEEL +1 -1
  32. {StreamingCommunity-1.9.90.dist-info → StreamingCommunity-2.0.5.dist-info}/entry_points.txt +1 -0
  33. {StreamingCommunity-1.9.90.dist-info → StreamingCommunity-2.0.5.dist-info}/LICENSE +0 -0
  34. {StreamingCommunity-1.9.90.dist-info → StreamingCommunity-2.0.5.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,3 @@
1
- # 20.02.24
2
-
3
1
  import os
4
2
  import time
5
3
  import logging
@@ -34,10 +32,13 @@ class M3U8_Ts_Estimator:
34
32
  self.now_downloaded_size = 0
35
33
  self.total_segments = total_segments
36
34
  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()
35
+ self.speed = {"upload": "N/A", "download": "N/A"}
36
+
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)
40
+ self.speed_thread.daemon = True
41
+ self.speed_thread.start()
41
42
 
42
43
  def add_ts_file(self, size: int, size_download: int, duration: float):
43
44
  """
@@ -56,43 +57,71 @@ class M3U8_Ts_Estimator:
56
57
  self.ts_file_sizes.append(size)
57
58
  self.now_downloaded_size += size_download
58
59
 
59
- def capture_speed(self, interval: float = 1):
60
+ def capture_speed(self, interval: float = 1, pid: int = None):
60
61
  """
61
- Capture the internet speed periodically and store the values.
62
+ Capture the internet speed periodically for a specific process (identified by PID)
63
+ or the entire system if no PID is provided.
62
64
  """
63
- def get_network_io():
64
- """Get network I/O counters, handle missing psutil gracefully."""
65
+
66
+ 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
+ """
65
70
  try:
66
- io_counters = psutil.net_io_counters()
67
- return io_counters
68
-
71
+ if process:
72
+ io_counters = process.io_counters()
73
+ return io_counters
74
+ else:
75
+ io_counters = psutil.net_io_counters()
76
+ return io_counters
69
77
  except Exception as e:
70
78
  logging.warning(f"Unable to access network I/O counters: {e}")
71
79
  return None
72
80
 
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
+
73
93
  while True:
74
- old_value = get_network_io()
94
+ old_value = get_network_io(process)
75
95
 
76
- if old_value is None: # If psutil is not available, continue with default values
96
+ if old_value is None: # If psutil fails, continue with the next interval
77
97
  time.sleep(interval)
78
98
  continue
79
99
 
80
100
  time.sleep(interval)
81
- new_value = get_network_io()
82
-
101
+ new_value = get_network_io(process)
102
+
83
103
  if new_value is None: # Handle again if psutil fails in the next call
84
104
  time.sleep(interval)
85
105
  continue
86
106
 
87
107
  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
108
+
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
113
+
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
90
118
 
91
119
  self.speed = {
92
120
  "upload": internet_manager.format_transfer_speed(upload_speed),
93
121
  "download": internet_manager.format_transfer_speed(download_speed)
94
122
  }
95
123
 
124
+
96
125
  def get_average_speed(self) -> float:
97
126
  """
98
127
  Calculate the average internet speed.
@@ -159,18 +188,17 @@ class M3U8_Ts_Estimator:
159
188
  units_file_downloaded = downloaded_file_size_str.split(' ')[1]
160
189
  units_file_total_size = file_total_size.split(' ')[1]
161
190
 
162
- average_internet_speed = self.get_average_speed()[0]
163
- average_internet_unit = self.get_average_speed()[1]
164
-
165
191
  # Update the progress bar's postfix
166
192
  if TQDM_USE_LARGE_BAR:
193
+ average_internet_speed = self.get_average_speed()[0]
194
+ average_internet_unit = self.get_average_speed()[1]
167
195
  progress_counter.set_postfix_str(
168
196
  f"{Colors.WHITE}[ {Colors.GREEN}{number_file_downloaded} {Colors.WHITE}< {Colors.GREEN}{number_file_total_size} {Colors.RED}{units_file_total_size} "
169
197
  f"{Colors.WHITE}| {Colors.CYAN}{average_internet_speed} {Colors.RED}{average_internet_unit}"
170
198
  )
199
+
171
200
  else:
172
201
  progress_counter.set_postfix_str(
173
202
  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
-
203
+ f"{Colors.WHITE}| {Colors.CYAN}N/A{Colors.RED} N/A"
204
+ )
@@ -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__ = '1.9.8'
2
+ __version__ = '2.1.0'
3
3
  __author__ = 'Lovi-0'
4
4
  __description__ = 'A command-line program to download film'
5
5
  __copyright__ = 'Copyright 2024'
@@ -116,21 +116,34 @@ 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
+ # Original behavior for other operating systems
144
+ for executable in executables:
145
+ exe_paths = glob.glob(os.path.join(self.base_dir, executable))
146
+ found_executables.append(exe_paths[0] if exe_paths else None)
134
147
 
135
148
  return tuple(found_executables) if len(found_executables) == 3 else (None, None, None)
136
149
 
@@ -275,37 +288,61 @@ class FFMPEGDownloader:
275
288
  def check_ffmpeg() -> Tuple[Optional[str], Optional[str], Optional[str]]:
276
289
  """
277
290
  Check for FFmpeg executables in the system and download them if not found.
291
+ Enhanced detection for macOS systems.
278
292
 
279
293
  Returns:
280
294
  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
295
  """
290
296
  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
297
+ system_platform = platform.system().lower()
298
+
299
+ # Special handling for macOS
300
+ if system_platform == 'darwin':
301
+ # Common installation paths on macOS
302
+ 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
308
+ ]
295
309
 
296
- if all([ffmpeg_path, ffprobe_path, ffplay_path]):
297
- return ffmpeg_path, ffprobe_path, ffplay_path
310
+ for path in potential_paths:
311
+ ffmpeg_path = os.path.join(path, 'ffmpeg')
312
+ ffprobe_path = os.path.join(path, 'ffprobe')
313
+ ffplay_path = os.path.join(path, 'ffplay')
314
+
315
+ if (os.path.exists(ffmpeg_path) and os.path.exists(ffprobe_path) and
316
+ os.access(ffmpeg_path, os.X_OK) and os.access(ffprobe_path, os.X_OK)):
317
+ # Return found executables, with ffplay being optional
318
+ ffplay_path = ffplay_path if os.path.exists(ffplay_path) else None
319
+ return ffmpeg_path, ffprobe_path, ffplay_path
320
+
321
+ # Windows detection
322
+ elif system_platform == 'windows':
323
+ try:
324
+ ffmpeg_path = subprocess.check_output(['where', 'ffmpeg'], text=True).strip().split('\n')[0]
325
+ ffprobe_path = subprocess.check_output(['where', 'ffprobe'], text=True).strip().split('\n')[0]
326
+ ffplay_path = subprocess.check_output(['where', 'ffplay'], text=True).strip().split('\n')[0]
327
+
328
+ if ffmpeg_path and ffprobe_path:
329
+ return ffmpeg_path, ffprobe_path, ffplay_path
330
+ except subprocess.CalledProcessError:
331
+ pass
332
+
333
+ # Linux detection
298
334
  else:
299
335
  ffmpeg_path = shutil.which('ffmpeg')
300
336
  ffprobe_path = shutil.which('ffprobe')
301
337
  ffplay_path = shutil.which('ffplay')
302
338
 
303
- if all([ffmpeg_path, ffprobe_path, ffplay_path]):
339
+ if ffmpeg_path and ffprobe_path:
304
340
  return ffmpeg_path, ffprobe_path, ffplay_path
305
-
341
+
342
+ # If executables were not found, attempt to download FFmpeg
306
343
  downloader = FFMPEGDownloader()
307
344
  return downloader.download()
308
-
345
+
309
346
  except Exception as e:
310
- logging.error(f"Error checking FFmpeg: {e}")
347
+ logging.error(f"Error checking or downloading FFmpeg executables: {e}")
311
348
  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
@@ -112,7 +112,7 @@ def initialize():
112
112
  if platform.system() == "Windows" and "7" in platform.version():
113
113
  os.system('mode 120, 40')
114
114
 
115
- """# Check python version
115
+ # Check python version
116
116
  if sys.version_info < (3, 7):
117
117
  console.log("[red]Install python version > 3.7.16")
118
118
  sys.exit(0)
@@ -120,9 +120,8 @@ def initialize():
120
120
  # Attempting GitHub update
121
121
  try:
122
122
  git_update()
123
- print()
124
123
  except:
125
- console.log("[red]Error with loading github.")"""
124
+ console.log("[red]Error with loading github.")
126
125
 
127
126
 
128
127
  def main():
@@ -1,17 +1,17 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: StreamingCommunity
3
- Version: 1.9.90
4
- Summary: A streaming community package
3
+ Version: 2.0.5
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
@@ -26,38 +26,67 @@ Requires-Dist: qbittorrent-api
26
26
  Requires-Dist: python-qbittorrent
27
27
  Requires-Dist: googlesearch-python
28
28
 
29
- # StreamingCommunity Downloader
30
-
31
- ![Project Logo](https://i.ibb.co/f4h5Y2m/min-logo.png)
32
-
33
- A versatile script designed to download films and series from various supported streaming platforms.
34
-
35
- # 🤝 Join our Community
36
-
37
- Chat, contribute, and have fun in our **Git_StreamingCommunity** Discord [Server](https://discord.com/invite/8vV68UGRc7)
29
+ <p align="center">
30
+ <img src="https://i.ibb.co/PFnjvBc/immagine-2024-12-26-180318047.png" alt="Project Logo" width="700"/>
31
+ </p>
32
+
33
+ <p align="center">
34
+ <a href="https://pypi.org/project/streamingcommunity">
35
+ <img src="https://img.shields.io/pypi/v/streamingcommunity?logo=pypi&labelColor=555555&style=for-the-badge" alt="PyPI"/>
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
+ <a href="https://www.paypal.com/donate/?hosted_button_id=UXTWMT8P6HE2C">
41
+ <img src="https://img.shields.io/badge/_-Donate-red.svg?logo=githubsponsors&labelColor=555555&style=for-the-badge" alt="Donate"/>
42
+ </a>
43
+ <a href="https://github.com/Lovi-0/StreamingCommunity/blob/main/LICENSE">
44
+ <img src="https://img.shields.io/badge/License-GPL_3.0-blue.svg?style=for-the-badge" alt="License"/>
45
+ </a>
46
+ <a href="https://github.com/Lovi-0/StreamingCommunity/commits">
47
+ <img src="https://img.shields.io/github/commit-activity/m/Lovi-0/StreamingCommunity?label=commits&style=for-the-badge" alt="Commits"/>
48
+ </a>
49
+ <a href="https://github.com/Lovi-0/StreamingCommunity/commits">
50
+ <img src="https://img.shields.io/github/last-commit/Lovi-0/StreamingCommunity/main?label=&style=for-the-badge&display_timestamp=committer" alt="Last Commit"/>
51
+ </a>
52
+ </p>
53
+
54
+ <p align="center">
55
+ <a href="https://pypi.org/project/streamingcommunity">
56
+ <img src="https://img.shields.io/pypi/dm/streamingcommunity?style=for-the-badge" alt="PyPI Downloads"/>
57
+ </a>
58
+ <a href="https://github.com/Lovi-0/StreamingCommunity/network/members">
59
+ <img src="https://img.shields.io/github/forks/Lovi-0/StreamingCommunity?style=for-the-badge" alt="Forks"/>
60
+ </a>
61
+ <a href="https://github.com/Lovi-0/StreamingCommunity">
62
+ <img src="https://img.shields.io/github/languages/code-size/Lovi-0/StreamingCommunity?style=for-the-badge" alt="Code Size"/>
63
+ </a>
64
+ <a href="https://github.com/Lovi-0/StreamingCommunity">
65
+ <img src="https://img.shields.io/github/repo-size/Lovi-0/StreamingCommunity?style=for-the-badge" alt="Repo Size"/>
66
+ </a>
67
+ </p>
38
68
 
39
69
  # 📋 Table of Contents
40
70
 
41
- - [Website available](#website-status)
42
- - [Installation](#installation)
43
- - [PyPI Installation](#1-pypi-installation)
44
- - [Automatic Installation](#2-automatic-installation)
45
- - [Manual Installation](#3-manual-installation)
46
- - [Win 7](https://github.com/Ghost6446/StreamingCommunity_api/wiki/Installation#win-7)
47
- - [Termux](https://github.com/Ghost6446/StreamingCommunity_api/wiki/Termux)
48
- - [Configuration](#configuration)
49
- - [Default](#default-settings)
50
- - [Request](#requests-settings)
51
- - [Download](#m3u8_download-settings)
52
- - [Parser](#m3u8_parser-settings)
53
- - [Docker](#docker)
54
- - [Tutorial](#tutorials)
55
- - [To Do](#to-do)
56
- - [Support](#support)
57
- - [Contribute](#contributing)
58
- - [Disclamer](#disclaimer)
59
-
60
-
71
+ - 🌐 [Website available](#website-status)
72
+ - 🛠️ [Installation](#installation)
73
+ - 📦 [PyPI Installation](#1-pypi-installation)
74
+ - 🔄 [Automatic Installation](#2-automatic-installation)
75
+ - 📝 [Manual Installation](#3-manual-installation)
76
+ - 💻 [Win 7](https://github.com/Ghost6446/StreamingCommunity_api/wiki/Installation#win-7)
77
+ - 📱 [Termux](https://github.com/Ghost6446/StreamingCommunity_api/wiki/Termux)
78
+ - ⚙️ [Configuration](#configuration)
79
+ - 🔧 [Default](#default-settings)
80
+ - 📩 [Request](#requests-settings)
81
+ - 📥 [Download](#m3u8_download-settings)
82
+ - 🔍 [Parser](#m3u8_parser-settings)
83
+ - 🐳 [Docker](#docker)
84
+ - 🎓 [Tutorial](#tutorials)
85
+ - 📝 [To do](#to-do)
86
+ - 💬 [Support](#support)
87
+ - 🤝 [Contribute](#contributing)
88
+ - ⚠️ [Disclaimer](#disclaimer)
89
+ - ⚡ [Contributors](#contributors)
61
90
 
62
91
  # Installation
63
92
 
@@ -226,7 +255,7 @@ The configuration file is divided into several main sections:
226
255
  * `%(episode)` : Is the number of the episode
227
256
  * `%(episode_name)` : Is the name of the episode
228
257
  `<br/><br/>`
229
-
258
+
230
259
  - `not_close`: If true, continues running after downloading
231
260
 
232
261
  ### qBittorrent Configuration
@@ -330,10 +359,8 @@ forced-ita hin - Hindi pol - Polish tur - Turkish
330
359
 
331
360
  <br>
332
361
 
333
-
334
362
  # COMMAND
335
363
 
336
-
337
364
  - Download a specific season by entering its number.
338
365
  * **Example:** `1` will download *Season 1* only.
339
366
 
@@ -404,13 +431,7 @@ The `run-container` command mounts also the `config.json` file, so any change to
404
431
 
405
432
  # To Do
406
433
 
407
- - Create website API -> https://github.com/Lovi-0/StreamingCommunity/tree/test_gui_1
408
-
409
- # Support
410
-
411
- If you'd like to support this project, consider making a donation!
412
-
413
- [![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/donate/?hosted_button_id=UXTWMT8P6HE2C)
434
+ - Finish [website API](https://github.com/Lovi-0/StreamingCommunity/tree/test_gui_1)
414
435
 
415
436
  # Contributing
416
437
 
@@ -425,3 +446,11 @@ Contributions are welcome! Steps:
425
446
  # Disclaimer
426
447
 
427
448
  This software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
449
+
450
+ ## Contributors
451
+
452
+ <a href="https://github.com/Lovi-0/StreamingCommunity/graphs/contributors" alt="View Contributors">
453
+ <img src="https://contrib.rocks/image?repo=Lovi-0/StreamingCommunity&max=1000&columns=10" alt="Contributors" />
454
+ </a>
455
+
456
+