StreamingCommunity 2.6.1__py3-none-any.whl → 2.8.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 (76) hide show
  1. StreamingCommunity/Api/Player/ddl.py +4 -4
  2. StreamingCommunity/Api/Player/maxstream.py +10 -16
  3. StreamingCommunity/Api/Player/supervideo.py +9 -35
  4. StreamingCommunity/Api/Player/vixcloud.py +18 -92
  5. StreamingCommunity/Api/Site/1337xx/__init__.py +8 -1
  6. StreamingCommunity/Api/Site/1337xx/site.py +16 -15
  7. StreamingCommunity/Api/Site/1337xx/title.py +7 -5
  8. StreamingCommunity/Api/Site/animeunity/__init__.py +9 -2
  9. StreamingCommunity/Api/Site/animeunity/film_serie.py +12 -5
  10. StreamingCommunity/Api/Site/animeunity/site.py +14 -10
  11. StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py +9 -10
  12. StreamingCommunity/Api/Site/cb01new/__init__.py +8 -1
  13. StreamingCommunity/Api/Site/cb01new/film.py +7 -1
  14. StreamingCommunity/Api/Site/cb01new/site.py +24 -15
  15. StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py +9 -2
  16. StreamingCommunity/Api/Site/ddlstreamitaly/series.py +7 -1
  17. StreamingCommunity/Api/Site/ddlstreamitaly/site.py +16 -15
  18. StreamingCommunity/Api/Site/ddlstreamitaly/util/ScrapeSerie.py +3 -3
  19. StreamingCommunity/Api/Site/guardaserie/__init__.py +9 -2
  20. StreamingCommunity/Api/Site/guardaserie/series.py +9 -1
  21. StreamingCommunity/Api/Site/guardaserie/site.py +23 -22
  22. StreamingCommunity/Api/Site/guardaserie/util/ScrapeSerie.py +5 -4
  23. StreamingCommunity/Api/Site/mostraguarda/__init__.py +6 -2
  24. StreamingCommunity/Api/Site/mostraguarda/film.py +10 -6
  25. StreamingCommunity/Api/Site/streamingcommunity/__init__.py +9 -2
  26. StreamingCommunity/Api/Site/streamingcommunity/film.py +9 -2
  27. StreamingCommunity/Api/Site/streamingcommunity/series.py +15 -6
  28. StreamingCommunity/Api/Site/streamingcommunity/site.py +16 -14
  29. StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +10 -11
  30. StreamingCommunity/Api/Template/Util/__init__.py +0 -1
  31. StreamingCommunity/Api/Template/Util/get_domain.py +31 -134
  32. StreamingCommunity/Api/Template/Util/manage_ep.py +10 -5
  33. StreamingCommunity/Api/Template/config_loader.py +14 -10
  34. StreamingCommunity/Api/Template/site.py +3 -6
  35. StreamingCommunity/Lib/Downloader/HLS/downloader.py +12 -15
  36. StreamingCommunity/Lib/Downloader/HLS/segments.py +14 -34
  37. StreamingCommunity/Lib/Downloader/MP4/downloader.py +14 -11
  38. StreamingCommunity/Lib/Downloader/TOR/downloader.py +109 -101
  39. StreamingCommunity/Lib/FFmpeg/__init__.py +1 -1
  40. StreamingCommunity/Lib/FFmpeg/capture.py +10 -12
  41. StreamingCommunity/Lib/FFmpeg/command.py +15 -14
  42. StreamingCommunity/Lib/FFmpeg/util.py +9 -38
  43. StreamingCommunity/Lib/M3U8/decryptor.py +72 -146
  44. StreamingCommunity/Lib/M3U8/estimator.py +8 -16
  45. StreamingCommunity/Lib/M3U8/parser.py +1 -17
  46. StreamingCommunity/Lib/M3U8/url_fixer.py +1 -4
  47. StreamingCommunity/Lib/TMBD/__init__.py +2 -0
  48. StreamingCommunity/Lib/TMBD/obj_tmbd.py +3 -17
  49. StreamingCommunity/Lib/TMBD/tmdb.py +4 -9
  50. StreamingCommunity/TelegramHelp/telegram_bot.py +50 -50
  51. StreamingCommunity/Upload/update.py +6 -5
  52. StreamingCommunity/Upload/version.py +1 -1
  53. StreamingCommunity/Util/color.py +1 -1
  54. StreamingCommunity/Util/config_json.py +435 -0
  55. StreamingCommunity/Util/headers.py +7 -36
  56. StreamingCommunity/Util/logger.py +72 -42
  57. StreamingCommunity/Util/message.py +8 -3
  58. StreamingCommunity/Util/os.py +41 -93
  59. StreamingCommunity/Util/table.py +8 -17
  60. StreamingCommunity/run.py +39 -43
  61. {StreamingCommunity-2.6.1.dist-info → StreamingCommunity-2.8.0.dist-info}/METADATA +203 -114
  62. StreamingCommunity-2.8.0.dist-info/RECORD +75 -0
  63. StreamingCommunity/Api/Site/ilcorsaronero/__init__.py +0 -53
  64. StreamingCommunity/Api/Site/ilcorsaronero/site.py +0 -64
  65. StreamingCommunity/Api/Site/ilcorsaronero/title.py +0 -42
  66. StreamingCommunity/Api/Site/ilcorsaronero/util/ilCorsarScraper.py +0 -149
  67. StreamingCommunity/Api/Template/Util/recall_search.py +0 -37
  68. StreamingCommunity/Lib/Downloader/HLS/proxyes.py +0 -110
  69. StreamingCommunity/Util/_jsonConfig.py +0 -241
  70. StreamingCommunity/Util/call_stack.py +0 -42
  71. StreamingCommunity/Util/console.py +0 -12
  72. StreamingCommunity-2.6.1.dist-info/RECORD +0 -83
  73. {StreamingCommunity-2.6.1.dist-info → StreamingCommunity-2.8.0.dist-info}/LICENSE +0 -0
  74. {StreamingCommunity-2.6.1.dist-info → StreamingCommunity-2.8.0.dist-info}/WHEEL +0 -0
  75. {StreamingCommunity-2.6.1.dist-info → StreamingCommunity-2.8.0.dist-info}/entry_points.txt +0 -0
  76. {StreamingCommunity-2.6.1.dist-info → StreamingCommunity-2.8.0.dist-info}/top_level.txt +0 -0
@@ -1,14 +1,16 @@
1
1
  # 10.12.23
2
2
 
3
+ import sys
4
+
3
5
 
4
6
  # External libraries
5
7
  import httpx
8
+ from rich.console import Console
6
9
 
7
10
 
8
11
  # Internal utilities
9
- from StreamingCommunity.Util.console import console
10
- from StreamingCommunity.Util._jsonConfig import config_manager
11
- from StreamingCommunity.Util.headers import get_headers
12
+ from StreamingCommunity.Util.config_json import config_manager
13
+ from StreamingCommunity.Util.headers import get_userAgent
12
14
  from StreamingCommunity.Util.table import TVShowManager
13
15
  from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
14
16
 
@@ -19,12 +21,11 @@ from StreamingCommunity.Api.Template.Util import search_domain
19
21
  from StreamingCommunity.Api.Template.Class.SearchType import MediaManager
20
22
 
21
23
 
22
-
23
24
  # Variable
25
+ console = Console()
24
26
  media_search_manager = MediaManager()
25
27
  table_show_manager = TVShowManager()
26
28
  max_timeout = config_manager.get_int("REQUESTS", "timeout")
27
- disable_searchDomain = config_manager.get_bool("DEFAULT", "disable_searchDomain")
28
29
 
29
30
 
30
31
  def title_search(title_search: str) -> int:
@@ -37,23 +38,24 @@ def title_search(title_search: str) -> int:
37
38
  Returns:
38
39
  int: The number of titles found.
39
40
  """
40
- domain_to_use = site_constant
41
+ domain_to_use, base_url = search_domain(site_constant.SITE_NAME, site_constant.FULL_URL)
41
42
 
42
- if not disable_searchDomain:
43
- domain_to_use, base_url = search_domain(site_constant.SITE_NAME, f"https://{site_constant.SITE_NAME}.{site_constant.DOMAIN_NOW}")
43
+ if domain_to_use is None or base_url is None:
44
+ console.print("[bold red]Error: Unable to determine valid domain or base URL.[/bold red]")
45
+ console.print("[yellow]The service might be temporarily unavailable or the domain may have changed.[/yellow]")
46
+ sys.exit(1)
44
47
 
45
48
  if site_constant.TELEGRAM_BOT:
46
49
  bot = get_bot_instance()
47
50
 
48
51
  media_search_manager.clear()
49
52
  table_show_manager.clear()
50
-
53
+
54
+ search_url = f"{site_constant.FULL_URL}/api/search?q={title_search}"
55
+ console.print(f"[cyan]Search url: [yellow]{search_url}")
56
+
51
57
  try:
52
- response = httpx.get(
53
- url=f"https://{site_constant.SITE_NAME}.{domain_to_use}/api/search?q={title_search.replace(' ', '+')}",
54
- headers={'user-agent': get_headers()},
55
- timeout=max_timeout
56
- )
58
+ response = httpx.get(search_url, headers={'user-agent': get_userAgent()}, timeout=max_timeout, follow_redirects=True)
57
59
  response.raise_for_status()
58
60
 
59
61
  except Exception as e:
@@ -10,8 +10,8 @@ from bs4 import BeautifulSoup
10
10
 
11
11
 
12
12
  # Internal utilities
13
- from StreamingCommunity.Util.headers import get_headers
14
- from StreamingCommunity.Util._jsonConfig import config_manager
13
+ from StreamingCommunity.Util.headers import get_userAgent
14
+ from StreamingCommunity.Util.config_json import config_manager
15
15
  from StreamingCommunity.Api.Player.Helper.Vixcloud.util import Season, EpisodeManager
16
16
 
17
17
 
@@ -19,18 +19,17 @@ from StreamingCommunity.Api.Player.Helper.Vixcloud.util import Season, EpisodeMa
19
19
  max_timeout = config_manager.get_int("REQUESTS", "timeout")
20
20
 
21
21
 
22
- class ScrapeSerie:
23
- def __init__(self, site_name: str):
22
+ class GetSerieInfo:
23
+ def __init__(self, url):
24
24
  """
25
25
  Initialize the ScrapeSerie class for scraping TV series information.
26
26
 
27
27
  Args:
28
- site_name (str): Name of the streaming site to scrape from
28
+ - url (str): The URL of the streaming site.
29
29
  """
30
30
  self.is_series = False
31
- self.headers = {'user-agent': get_headers()}
32
- self.base_name = site_name
33
- self.domain = config_manager.get_dict('SITE', self.base_name)['domain']
31
+ self.headers = {'user-agent': get_userAgent()}
32
+ self.url = url
34
33
 
35
34
  def setup(self, media_id: int = None, series_name: str = None):
36
35
  """
@@ -58,7 +57,7 @@ class ScrapeSerie:
58
57
  """
59
58
  try:
60
59
  response = httpx.get(
61
- url=f"https://{self.base_name}.{self.domain}/titles/{self.media_id}-{self.series_name}",
60
+ url=f"{self.url}/titles/{self.media_id}-{self.series_name}",
62
61
  headers=self.headers,
63
62
  timeout=max_timeout
64
63
  )
@@ -88,9 +87,9 @@ class ScrapeSerie:
88
87
  """
89
88
  try:
90
89
  response = httpx.get(
91
- url=f'https://{self.base_name}.{self.domain}/titles/{self.media_id}-{self.series_name}/stagione-{number_season}',
90
+ url=f'{self.url}/titles/{self.media_id}-{self.series_name}/stagione-{number_season}',
92
91
  headers={
93
- 'User-Agent': get_headers(),
92
+ 'User-Agent': get_userAgent(),
94
93
  'x-inertia': 'true',
95
94
  'x-inertia-version': self.version,
96
95
  },
@@ -1,6 +1,5 @@
1
1
  # 23.11.24
2
2
 
3
- from .recall_search import execute_search
4
3
  from .get_domain import search_domain
5
4
  from .manage_ep import (
6
5
  manage_selection,
@@ -1,35 +1,23 @@
1
1
  # 18.06.24
2
2
 
3
- import ssl
4
- import time
3
+ import certifi
5
4
  from urllib.parse import urlparse, unquote
6
5
 
7
6
 
8
7
  # External libraries
9
8
  import httpx
10
- from googlesearch import search
9
+ from rich.console import Console
11
10
 
12
11
 
13
12
  # Internal utilities
14
13
  from StreamingCommunity.Util.headers import get_headers
15
- from StreamingCommunity.Util.console import console, msg
16
- from StreamingCommunity.Util._jsonConfig import config_manager
17
-
18
- base_headers = {
19
- 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
20
- 'accept-language': 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7',
21
- 'dnt': '1',
22
- 'priority': 'u=0, i',
23
- 'referer': '',
24
- 'sec-ch-ua-mobile': '?0',
25
- 'sec-ch-ua-platform': '"Windows"',
26
- 'sec-fetch-dest': 'document',
27
- 'sec-fetch-mode': 'navigate',
28
- 'sec-fetch-site': 'same-origin',
29
- 'sec-fetch-user': '?1',
30
- 'upgrade-insecure-requests': '1',
31
- 'user-agent': ''
32
- }
14
+ from StreamingCommunity.Util.config_json import config_manager
15
+
16
+
17
+ # Variable
18
+ console = Console()
19
+ VERIFY = config_manager.get("REQUESTS", "verify")
20
+ MAX_TIMEOUT = config_manager.get_int("REQUESTS", "timeout")
33
21
 
34
22
 
35
23
  def get_tld(url_str):
@@ -58,24 +46,15 @@ def get_base_domain(url_str):
58
46
 
59
47
  # Check if domain has multiple parts separated by dots
60
48
  parts = domain.split('.')
61
- if len(parts) > 2: # Handle subdomains
62
- return '.'.join(parts[:-1]) # Return everything except TLD
49
+ if len(parts) > 2:
50
+ return '.'.join(parts[:-1])
63
51
 
64
- return parts[0] # Return base domain
52
+ return parts[0]
65
53
 
66
54
  except Exception:
67
55
  return None
68
56
 
69
- def get_base_url(url_str):
70
- """Extract base URL including protocol and domain, removing path and query parameters."""
71
- try:
72
- parsed = urlparse(url_str)
73
- return f"{parsed.scheme}://{parsed.netloc}"
74
-
75
- except Exception:
76
- return None
77
-
78
- def validate_url(url, base_url, max_timeout, max_retries=2, sleep=1):
57
+ def validate_url(url, base_url):
79
58
  """Validate if URL is accessible and matches expected base domain."""
80
59
  console.print(f"\n[cyan]Starting validation for URL[white]: [yellow]{url}")
81
60
 
@@ -83,120 +62,38 @@ def validate_url(url, base_url, max_timeout, max_retries=2, sleep=1):
83
62
  base_domain = get_base_domain(base_url)
84
63
  url_domain = get_base_domain(url)
85
64
 
86
- base_headers['referer'] = url
87
- base_headers['user-agent'] = get_headers()
88
-
89
65
  if base_domain != url_domain:
90
66
  console.print(f"[red]Domain structure mismatch: {url_domain} != {base_domain}")
91
67
  return False, None
92
68
 
93
- # Count dots to ensure we don't have extra subdomains
94
- base_dots = base_url.count('.')
95
- url_dots = url.count('.')
96
- if url_dots > base_dots + 1: # Allow for one extra dot for TLD change
97
- console.print(f"[red]Too many subdomains in URL")
98
- return False, None
99
-
100
69
  client = httpx.Client(
101
- verify=False,
102
- headers=base_headers,
103
- timeout=max_timeout
70
+ verify=VERIFY,
71
+ headers=get_headers(),
72
+ timeout=MAX_TIMEOUT
104
73
  )
105
74
 
106
- for retry in range(max_retries):
107
- try:
108
- time.sleep(sleep)
109
-
110
- # Initial check without redirects
111
- response = client.get(url, follow_redirects=False)
112
- if response.status_code == 403:
113
- console.print(f"[red]Check failed (403) - Attempt {retry + 1}/{max_retries}")
114
- continue
115
-
116
- if response.status_code >= 400:
117
- console.print(f"[red]Check failed: HTTP {response.status_code}")
118
- return False, None
119
-
120
- # Follow redirects and verify final domain
121
- final_response = client.get(url, follow_redirects=True)
122
- final_domain = get_base_domain(str(final_response.url))
123
- console.print(f"[cyan]Redirect url: [red]{final_response.url}")
124
-
125
- if final_domain != base_domain:
126
- console.print(f"[red]Final domain mismatch: {final_domain} != {base_domain}")
127
- return False, None
128
-
129
- new_tld = get_tld(str(final_response.url))
130
- if new_tld != get_tld(url):
131
- return True, new_tld
132
-
133
- return True, None
134
-
135
- except (httpx.RequestError, ssl.SSLError) as e:
136
- console.print(f"[red]Connection error: {str(e)}")
137
- time.sleep(sleep)
138
- continue
139
-
140
- return False, None
75
+ # Make request to web site
76
+ response = client.get(url, follow_redirects=False)
77
+
78
+ if response.status_code >= 400:
79
+ console.print(f"[red]Check failed: HTTP {response.status_code}")
80
+ console.print(f"[red]Response content: {response.text}")
81
+ return False, None
82
+
83
+ return True, base_domain
141
84
 
142
85
  def search_domain(site_name: str, base_url: str, get_first: bool = False):
143
- """Search for valid domain matching site name and base URL."""
144
- max_timeout = config_manager.get_int("REQUESTS", "timeout")
145
- domain = str(config_manager.get_dict("SITE", site_name)['domain'])
146
-
147
- # Test initial URL
86
+ """Search for valid domain matching site name and base URL."""
148
87
  try:
149
- is_correct, redirect_tld = validate_url(base_url, base_url, max_timeout)
88
+ is_correct, redirect_tld = validate_url(base_url, base_url)
150
89
 
151
90
  if is_correct:
152
91
  tld = redirect_tld or get_tld(base_url)
153
- config_manager.config['SITE'][site_name]['domain'] = tld
154
- config_manager.write_config()
155
- console.print(f"[green]Successfully validated initial URL")
156
92
  return tld, base_url
157
93
 
158
- except Exception as e:
159
- console.print(f"[red]Error testing initial URL: {str(e)}")
160
-
161
- # Google search phase
162
- base_domain = get_base_domain(base_url)
163
- console.print(f"\n[cyan]Searching for alternate domains for[white]: [yellow]{base_domain}")
164
-
165
- try:
166
- search_results = list(search(base_domain, num_results=20, lang="it"))
167
-
168
- base_urls = set()
169
- for url in search_results:
170
- element_url = get_base_url(url)
171
- if element_url:
172
- base_urls.add(element_url)
94
+ else:
95
+ return None, None
173
96
 
174
- # Filter URLs based on domain matching and subdomain count
175
- filtered_results = [
176
- url for url in base_urls
177
- if get_base_domain(url) == base_domain
178
- and url.count('.') <= base_url.count('.') + 1
179
- ]
180
-
181
- for idx, result_url in enumerate(filtered_results, 1):
182
- console.print(f"\n[cyan]Checking result {idx}/{len(filtered_results)}[white]: [yellow]{result_url}")
183
-
184
- is_valid, new_tld = validate_url(result_url, base_url, max_timeout)
185
- if is_valid:
186
- final_tld = new_tld or get_tld(result_url)
187
-
188
- if get_first or msg.ask(
189
- f"\n[cyan]Update site[white] [red]'{site_name}'[cyan] with domain[white] [red]'{final_tld}'",
190
- choices=["y", "n"],
191
- default="y"
192
- ).lower() == "y":
193
-
194
- config_manager.config['SITE'][site_name]['domain'] = final_tld
195
- config_manager.write_config()
196
- return final_tld, f"{base_url}.{final_tld}"
197
-
198
97
  except Exception as e:
199
- console.print(f"[red]Error during search: {str(e)}")
200
-
201
- console.print("[bold red]No valid URLs found matching the base URL.")
202
- return domain, f"{base_url}.{domain}"
98
+ console.print(f"[red]Error testing initial URL: {str(e)}")
99
+ return None, None
@@ -5,15 +5,21 @@ import logging
5
5
  from typing import List
6
6
 
7
7
 
8
+ # External library
9
+ from rich.console import Console
10
+ from rich.prompt import Prompt
11
+
12
+
8
13
  # Internal utilities
9
- from StreamingCommunity.Util.console import console, msg
10
14
  from StreamingCommunity.Util.os import os_manager
11
- from StreamingCommunity.Util._jsonConfig import config_manager
15
+ from StreamingCommunity.Util.config_json import config_manager
12
16
  from StreamingCommunity.Util.table import TVShowManager
13
17
 
14
18
 
15
- # Config
16
- MAP_EPISODE = config_manager.get('DEFAULT', 'map_episode_name')
19
+ # Variable
20
+ msg = Prompt()
21
+ console = Console()
22
+ MAP_EPISODE = config_manager.get('OUT_FOLDER', 'map_episode_name')
17
23
 
18
24
 
19
25
  def dynamic_format_number(n: int) -> str:
@@ -195,7 +201,6 @@ def display_episodes_list(episodes_manager) -> str:
195
201
  """
196
202
  # Set up table for displaying episodes
197
203
  table_show_manager = TVShowManager()
198
- table_show_manager.set_slice_end(10)
199
204
 
200
205
  # Add columns to the table
201
206
  column_info = {
@@ -5,7 +5,7 @@ import inspect
5
5
 
6
6
 
7
7
  # Internal utilities
8
- from StreamingCommunity.Util._jsonConfig import config_manager
8
+ from StreamingCommunity.Util.config_json import config_manager
9
9
 
10
10
 
11
11
  def get_site_name_from_stack():
@@ -29,37 +29,41 @@ class SiteConstant:
29
29
 
30
30
  @property
31
31
  def ROOT_PATH(self):
32
- return config_manager.get('DEFAULT', 'root_path')
32
+ return config_manager.get('OUT_FOLDER', 'root_path')
33
33
 
34
34
  @property
35
35
  def DOMAIN_NOW(self):
36
- return config_manager.get_dict('SITE', self.SITE_NAME)['domain']
36
+ return config_manager.get_site(self.SITE_NAME, 'domain')
37
+
38
+ @property
39
+ def FULL_URL(self):
40
+ return config_manager.get_site(self.SITE_NAME, 'full_url').rstrip('/')
37
41
 
38
42
  @property
39
43
  def SERIES_FOLDER(self):
40
44
  base_path = self.ROOT_PATH
41
- if config_manager.get_bool("DEFAULT", "add_siteName"):
45
+ if config_manager.get_bool("OUT_FOLDER", "add_siteName"):
42
46
  base_path = os.path.join(base_path, self.SITE_NAME)
43
- return os.path.join(base_path, config_manager.get('DEFAULT', 'serie_folder_name'))
47
+ return os.path.join(base_path, config_manager.get('OUT_FOLDER', 'serie_folder_name'))
44
48
 
45
49
  @property
46
50
  def MOVIE_FOLDER(self):
47
51
  base_path = self.ROOT_PATH
48
- if config_manager.get_bool("DEFAULT", "add_siteName"):
52
+ if config_manager.get_bool("OUT_FOLDER", "add_siteName"):
49
53
  base_path = os.path.join(base_path, self.SITE_NAME)
50
- return os.path.join(base_path, config_manager.get('DEFAULT', 'movie_folder_name'))
54
+ return os.path.join(base_path, config_manager.get('OUT_FOLDER', 'movie_folder_name'))
51
55
 
52
56
  @property
53
57
  def ANIME_FOLDER(self):
54
58
  base_path = self.ROOT_PATH
55
- if config_manager.get_bool("DEFAULT", "add_siteName"):
59
+ if config_manager.get_bool("OUT_FOLDER", "add_siteName"):
56
60
  base_path = os.path.join(base_path, self.SITE_NAME)
57
- return os.path.join(base_path, config_manager.get('DEFAULT', 'anime_folder_name'))
61
+ return os.path.join(base_path, config_manager.get('OUT_FOLDER', 'anime_folder_name'))
58
62
 
59
63
  @property
60
64
  def COOKIE(self):
61
65
  try:
62
- return config_manager.get_dict('SITE', self.SITE_NAME)['extra']
66
+ return config_manager.get_dict('SITE_EXTRA', self.SITE_NAME)
63
67
  except KeyError:
64
68
  return None
65
69
 
@@ -3,11 +3,12 @@
3
3
  import sys
4
4
 
5
5
 
6
- # Internal utilities
7
- from StreamingCommunity.Util.console import console
6
+ # External library
7
+ from rich.console import Console
8
8
 
9
9
 
10
10
  # Variable
11
+ console = Console()
11
12
  available_colors = ['red', 'magenta', 'yellow', 'cyan', 'green', 'blue', 'white']
12
13
  column_to_hide = ['Slug', 'Sub_ita', 'Last_air_date', 'Seasons_count', 'Url']
13
14
 
@@ -19,10 +20,6 @@ def get_select_title(table_show_manager, media_search_manager):
19
20
  Returns:
20
21
  MediaItem: The selected media item.
21
22
  """
22
-
23
- # Set up table for displaying titles
24
- table_show_manager.set_slice_end(10)
25
-
26
23
  # Determine column_info dynamically for (search site)
27
24
  if not media_search_manager.media_list:
28
25
  console.print("\n[red]No media items available.")
@@ -10,17 +10,14 @@ from typing import Any, Dict, List, Optional
10
10
 
11
11
  # External libraries
12
12
  import httpx
13
+ from rich.console import Console
14
+ from rich.panel import Panel
13
15
 
14
16
 
15
17
  # Internal utilities
16
- from StreamingCommunity.Util._jsonConfig import config_manager
17
- from StreamingCommunity.Util.headers import get_headers
18
- from StreamingCommunity.Util.console import console, Panel
19
- from StreamingCommunity.Util.os import (
20
- compute_sha1_hash,
21
- os_manager,
22
- internet_manager
23
- )
18
+ from StreamingCommunity.Util.config_json import config_manager
19
+ from StreamingCommunity.Util.headers import get_userAgent
20
+ from StreamingCommunity.Util.os import compute_sha1_hash, os_manager, internet_manager
24
21
  from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
25
22
 
26
23
 
@@ -47,15 +44,15 @@ FILTER_CUSTOM_REOLUTION = str(config_manager.get('M3U8_PARSER', 'force_resolutio
47
44
  GET_ONLY_LINK = config_manager.get_bool('M3U8_PARSER', 'get_only_link')
48
45
  RETRY_LIMIT = config_manager.get_int('REQUESTS', 'max_retry')
49
46
  MAX_TIMEOUT = config_manager.get_int("REQUESTS", "timeout")
50
-
51
47
  TELEGRAM_BOT = config_manager.get_bool('DEFAULT', 'telegram_bot')
52
48
 
49
+ console = Console()
53
50
 
54
51
 
55
52
  class HLSClient:
56
53
  """Client for making HTTP requests to HLS endpoints with retry mechanism."""
57
54
  def __init__(self):
58
- self.headers = {'User-Agent': get_headers()}
55
+ self.headers = {'User-Agent': get_userAgent()}
59
56
 
60
57
  def request(self, url: str, return_content: bool = False) -> Optional[httpx.Response]:
61
58
  """
@@ -100,7 +97,7 @@ class PathManager:
100
97
  Creates a hash-based filename if no path is provided.
101
98
  """
102
99
  if not path:
103
- root = config_manager.get('DEFAULT', 'root_path')
100
+ root = config_manager.get('OUT_FOLDER', 'root_path')
104
101
  hash_name = compute_sha1_hash(self.m3u8_url) + ".mp4"
105
102
  return os.path.join(root, "undefined", hash_name)
106
103
 
@@ -193,7 +190,7 @@ class M3U8Manager:
193
190
  list_available_resolution = [f"{r[0]}x{r[1]}" for r in tuple_available_resolution]
194
191
 
195
192
  console.print(
196
- f"[cyan bold]Video [/cyan bold] [green]Available:[/green] [purple]{', '.join(list_available_resolution)}[/purple] | "
193
+ f"[cyan bold]Video [/cyan bold] [green]Available:[/green] [purple]{', '.join(list_available_resolution)}[/purple] | "
197
194
  f"[red]Set:[/red] [purple]{FILTER_CUSTOM_REOLUTION}[/purple] | "
198
195
  f"[yellow]Downloadable:[/yellow] [purple]{self.video_res[0]}x{self.video_res[1]}[/purple]"
199
196
  )
@@ -208,7 +205,7 @@ class M3U8Manager:
208
205
  set_codec_info = available_codec_info if config_manager.get_bool("M3U8_CONVERSION", "use_codec") else "[purple]copy[/purple]"
209
206
 
210
207
  console.print(
211
- f"[bold cyan]Codec [/bold cyan] [green]Available:[/green] {available_codec_info} | "
208
+ f"[bold cyan]Codec [/bold cyan] [green]Available:[/green] {available_codec_info} | "
212
209
  f"[red]Set:[/red] {set_codec_info}"
213
210
  )
214
211
 
@@ -217,7 +214,7 @@ class M3U8Manager:
217
214
  downloadable_sub_languages = list(set(available_sub_languages) & set(DOWNLOAD_SPECIFIC_SUBTITLE))
218
215
  if available_sub_languages:
219
216
  console.print(
220
- f"[cyan bold]Subtitle [/cyan bold] [green]Available:[/green] [purple]{', '.join(available_sub_languages)}[/purple] | "
217
+ f"[cyan bold]Subtitle [/cyan bold] [green]Available:[/green] [purple]{', '.join(available_sub_languages)}[/purple] | "
221
218
  f"[red]Set:[/red] [purple]{', '.join(DOWNLOAD_SPECIFIC_SUBTITLE)}[/purple] | "
222
219
  f"[yellow]Downloadable:[/yellow] [purple]{', '.join(downloadable_sub_languages)}[/purple]"
223
220
  )
@@ -227,7 +224,7 @@ class M3U8Manager:
227
224
  downloadable_audio_languages = list(set(available_audio_languages) & set(DOWNLOAD_SPECIFIC_AUDIO))
228
225
  if available_audio_languages:
229
226
  console.print(
230
- f"[cyan bold]Audio [/cyan bold] [green]Available:[/green] [purple]{', '.join(available_audio_languages)}[/purple] | "
227
+ f"[cyan bold]Audio [/cyan bold] [green]Available:[/green] [purple]{', '.join(available_audio_languages)}[/purple] | "
231
228
  f"[red]Set:[/red] [purple]{', '.join(DOWNLOAD_SPECIFIC_AUDIO)}[/purple] | "
232
229
  f"[yellow]Downloadable:[/yellow] [purple]{', '.join(downloadable_audio_languages)}[/purple]"
233
230
  )