StreamingCommunity 2.9.2__py3-none-any.whl → 2.9.4__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 +40 -38
  2. StreamingCommunity/Api/Player/maxstream.py +6 -11
  3. StreamingCommunity/Api/Player/supervideo.py +4 -0
  4. StreamingCommunity/Api/Site/1337xx/site.py +1 -9
  5. StreamingCommunity/Api/Site/altadefinizione/__init__.py +61 -0
  6. StreamingCommunity/Api/Site/altadefinizione/film.py +98 -0
  7. StreamingCommunity/Api/Site/altadefinizione/series.py +164 -0
  8. StreamingCommunity/Api/Site/altadefinizione/site.py +75 -0
  9. StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py +72 -0
  10. StreamingCommunity/Api/Site/animeunity/film_serie.py +2 -2
  11. StreamingCommunity/Api/Site/animeunity/site.py +15 -41
  12. StreamingCommunity/Api/Site/cb01new/site.py +5 -16
  13. StreamingCommunity/Api/Site/ddlstreamitaly/site.py +1 -9
  14. StreamingCommunity/Api/Site/guardaserie/series.py +1 -1
  15. StreamingCommunity/Api/Site/guardaserie/site.py +1 -9
  16. StreamingCommunity/Api/Site/streamingcommunity/series.py +30 -12
  17. StreamingCommunity/Api/Site/streamingcommunity/site.py +10 -10
  18. StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +38 -17
  19. StreamingCommunity/Api/Template/Class/SearchType.py +1 -1
  20. StreamingCommunity/Api/Template/Util/__init__.py +0 -1
  21. StreamingCommunity/Api/Template/Util/manage_ep.py +43 -16
  22. StreamingCommunity/Api/Template/config_loader.py +0 -4
  23. StreamingCommunity/Api/Template/site.py +1 -1
  24. StreamingCommunity/Lib/Downloader/HLS/downloader.py +13 -2
  25. StreamingCommunity/Lib/Downloader/HLS/segments.py +37 -11
  26. StreamingCommunity/Lib/Downloader/MP4/downloader.py +5 -3
  27. StreamingCommunity/Lib/FFmpeg/command.py +2 -2
  28. StreamingCommunity/Lib/FFmpeg/util.py +11 -15
  29. StreamingCommunity/Lib/M3U8/estimator.py +4 -4
  30. StreamingCommunity/Lib/TMBD/tmdb.py +1 -1
  31. StreamingCommunity/Upload/version.py +1 -1
  32. StreamingCommunity/Util/config_json.py +0 -3
  33. StreamingCommunity/__init__.py +6 -0
  34. {StreamingCommunity-2.9.2.dist-info → streamingcommunity-2.9.4.dist-info}/METADATA +91 -7
  35. {StreamingCommunity-2.9.2.dist-info → streamingcommunity-2.9.4.dist-info}/RECORD +39 -35
  36. {StreamingCommunity-2.9.2.dist-info → streamingcommunity-2.9.4.dist-info}/WHEEL +1 -1
  37. StreamingCommunity/Api/Template/Util/get_domain.py +0 -100
  38. {StreamingCommunity-2.9.2.dist-info → streamingcommunity-2.9.4.dist-info}/LICENSE +0 -0
  39. {StreamingCommunity-2.9.2.dist-info → streamingcommunity-2.9.4.dist-info}/entry_points.txt +0 -0
  40. {StreamingCommunity-2.9.2.dist-info → streamingcommunity-2.9.4.dist-info}/top_level.txt +0 -0
@@ -74,6 +74,9 @@ class M3U8_Segments:
74
74
 
75
75
  # Sync
76
76
  self.queue = PriorityQueue()
77
+ self.buffer = {}
78
+ self.expected_index = 0
79
+
77
80
  self.stop_event = threading.Event()
78
81
  self.downloaded_segments = set()
79
82
  self.base_timeout = 0.5
@@ -94,6 +97,15 @@ class M3U8_Segments:
94
97
  self.active_retries_lock = threading.Lock()
95
98
 
96
99
  def __get_key__(self, m3u8_parser: M3U8_Parser) -> bytes:
100
+ """
101
+ Fetches the encryption key from the M3U8 playlist.
102
+
103
+ Args:
104
+ m3u8_parser (M3U8_Parser): An instance of M3U8_Parser containing parsed M3U8 data.
105
+
106
+ Returns:
107
+ bytes: The decryption key in byte format.
108
+ """
97
109
  key_uri = urljoin(self.url, m3u8_parser.keys.get('uri'))
98
110
  parsed_url = urlparse(key_uri)
99
111
  self.key_base_url = f"{parsed_url.scheme}://{parsed_url.netloc}/"
@@ -110,6 +122,12 @@ class M3U8_Segments:
110
122
  raise Exception(f"Failed to fetch key: {e}")
111
123
 
112
124
  def parse_data(self, m3u8_content: str) -> None:
125
+ """
126
+ Parses the M3U8 content and extracts necessary data.
127
+
128
+ Args:
129
+ m3u8_content (str): The raw M3U8 playlist content.
130
+ """
113
131
  m3u8_parser = M3U8_Parser()
114
132
  m3u8_parser.parse_data(uri=self.url, raw_content=m3u8_content)
115
133
 
@@ -131,6 +149,14 @@ class M3U8_Segments:
131
149
  self.class_ts_estimator.total_segments = len(self.segments)
132
150
 
133
151
  def get_info(self) -> None:
152
+ """
153
+ Retrieves M3U8 playlist information from the given URL.
154
+
155
+ If the URL is an index URL, this method:
156
+ - Sends an HTTP GET request to fetch the M3U8 playlist.
157
+ - Parses the M3U8 content using `parse_data`.
158
+ - Saves the playlist to a temporary folder.
159
+ """
134
160
  if self.is_index_url:
135
161
  try:
136
162
  client_params = {'headers': {'User-Agent': get_userAgent()}, 'timeout': MAX_TIMEOOUT}
@@ -251,9 +277,6 @@ class M3U8_Segments:
251
277
  """
252
278
  Writes segments to file with additional verification.
253
279
  """
254
- buffer = {}
255
- expected_index = 0
256
-
257
280
  with open(self.tmp_file_path, 'wb') as f:
258
281
  while not self.stop_event.is_set() or not self.queue.empty():
259
282
  if self.interrupt_flag.is_set():
@@ -267,28 +290,28 @@ class M3U8_Segments:
267
290
 
268
291
  # Handle failed segments
269
292
  if segment_content is None:
270
- if index == expected_index:
271
- expected_index += 1
293
+ if index == self.expected_index:
294
+ self.expected_index += 1
272
295
  continue
273
296
 
274
297
  # Write segment if it's the next expected one
275
- if index == expected_index:
298
+ if index == self.expected_index:
276
299
  f.write(segment_content)
277
300
  f.flush()
278
- expected_index += 1
301
+ self.expected_index += 1
279
302
 
280
303
  # Write any buffered segments that are now in order
281
- while expected_index in buffer:
282
- next_segment = buffer.pop(expected_index)
304
+ while self.expected_index in self.buffer:
305
+ next_segment = self.buffer.pop(self.expected_index)
283
306
 
284
307
  if next_segment is not None:
285
308
  f.write(next_segment)
286
309
  f.flush()
287
310
 
288
- expected_index += 1
311
+ self.expected_index += 1
289
312
 
290
313
  else:
291
- buffer[index] = segment_content
314
+ self.buffer[index] = segment_content
292
315
 
293
316
  except queue.Empty:
294
317
  self.current_timeout = min(MAX_TIMEOOUT, self.current_timeout * 1.1)
@@ -440,6 +463,9 @@ class M3U8_Segments:
440
463
  if self.info_nFailed > 0:
441
464
  self._display_error_summary()
442
465
 
466
+ self.buffer = {}
467
+ self.expected_index = 0
468
+
443
469
  def _display_error_summary(self) -> None:
444
470
  """Generate final error report."""
445
471
  console.print(f"\n[cyan]Retry Summary: "
@@ -30,7 +30,8 @@ from ...FFmpeg import print_duration_table
30
30
 
31
31
 
32
32
  # Config
33
- REQUEST_VERIFY = config_manager.get_int('REQUESTS', 'verify')
33
+ REQUEST_VERIFY = config_manager.get_bool('REQUESTS', 'verify')
34
+ REQUEST_HTTP2 = config_manager.get_bool('REQUESTS', 'http2')
34
35
  GET_ONLY_LINK = config_manager.get_bool('M3U8_PARSER', 'get_only_link')
35
36
  REQUEST_TIMEOUT = config_manager.get_float('REQUESTS', 'timeout')
36
37
  TELEGRAM_BOT = config_manager.get_bool('DEFAULT', 'telegram_bot')
@@ -87,7 +88,8 @@ def MP4_downloader(url: str, path: str, referer: str = None, headers_: dict = No
87
88
  return None, False
88
89
 
89
90
  if GET_ONLY_LINK:
90
- return {'path': path, 'url': url}
91
+ console.print(f"URL: {url}[/bold red]")
92
+ return path, True
91
93
 
92
94
  if not (url.lower().startswith('http://') or url.lower().startswith('https://')):
93
95
  logging.error(f"Invalid URL: {url}")
@@ -110,7 +112,7 @@ def MP4_downloader(url: str, path: str, referer: str = None, headers_: dict = No
110
112
  original_handler = signal.signal(signal.SIGINT, partial(signal_handler, interrupt_handler=interrupt_handler, original_handler=signal.getsignal(signal.SIGINT)))
111
113
 
112
114
  try:
113
- transport = httpx.HTTPTransport(verify=REQUEST_VERIFY, http2=True)
115
+ transport = httpx.HTTPTransport(verify=REQUEST_VERIFY, http2=REQUEST_HTTP2)
114
116
 
115
117
  with httpx.Client(transport=transport, timeout=httpx.Timeout(60)) as client:
116
118
  with client.stream("GET", url, headers=headers, timeout=REQUEST_TIMEOUT) as response:
@@ -180,7 +180,7 @@ def join_audios(video_path: str, audio_tracks: List[Dict[str, str]], out_path: s
180
180
  Each dictionary should contain the 'path' key with the path to the audio file.
181
181
  - out_path (str): The path to save the output file.
182
182
  """
183
- video_audio_same_duration = check_duration_v_a(video_path, audio_tracks[0].get('path'))
183
+ video_audio_same_duration, duration_diff = check_duration_v_a(video_path, audio_tracks[0].get('path'))
184
184
 
185
185
  # Start command with locate ffmpeg
186
186
  ffmpeg_cmd = [get_ffmpeg_path()]
@@ -242,7 +242,7 @@ def join_audios(video_path: str, audio_tracks: List[Dict[str, str]], out_path: s
242
242
 
243
243
  # Use shortest input path for video and audios
244
244
  if not video_audio_same_duration:
245
- console.log("[red]Use shortest input ...")
245
+ console.log(f"[red]Use shortest input (Duration difference: {duration_diff:.2f} seconds)...")
246
246
  ffmpeg_cmd.extend(['-shortest', '-strict', 'experimental'])
247
247
 
248
248
  # Overwrite
@@ -57,7 +57,6 @@ def get_video_duration(file_path: str) -> float:
57
57
  Returns:
58
58
  (float): The duration of the video in seconds if successful, None if there's an error.
59
59
  """
60
-
61
60
  try:
62
61
  ffprobe_cmd = [get_ffprobe_path(), '-v', 'error', '-show_format', '-print_format', 'json', file_path]
63
62
  logging.info(f"FFmpeg command: {ffprobe_cmd}")
@@ -95,7 +94,6 @@ def format_duration(seconds: float) -> Tuple[int, int, int]:
95
94
  Returns:
96
95
  list[int, int, int]: List containing hours, minutes, and seconds.
97
96
  """
98
-
99
97
  hours, remainder = divmod(seconds, 3600)
100
98
  minutes, seconds = divmod(remainder, 60)
101
99
 
@@ -157,11 +155,7 @@ def get_ffprobe_info(file_path):
157
155
  'codec_names': codec_names
158
156
  }
159
157
 
160
- except subprocess.CalledProcessError as e:
161
- logging.error(f"ffprobe failed for file {file_path}: {e}")
162
- return None
163
-
164
- except json.JSONDecodeError as e:
158
+ except Exception as e:
165
159
  logging.error(f"Failed to parse JSON output from ffprobe for file {file_path}: {e}")
166
160
  return None
167
161
 
@@ -198,23 +192,25 @@ def need_to_force_to_ts(file_path):
198
192
  return False
199
193
 
200
194
 
201
- def check_duration_v_a(video_path, audio_path):
195
+ def check_duration_v_a(video_path, audio_path, tolerance=1.0):
202
196
  """
203
197
  Check if the duration of the video and audio matches.
204
198
 
205
199
  Parameters:
206
200
  - video_path (str): Path to the video file.
207
201
  - audio_path (str): Path to the audio file.
202
+ - tolerance (float): Allowed tolerance for the duration difference (in seconds).
208
203
 
209
204
  Returns:
210
- - bool: True if the duration of the video and audio matches, False otherwise.
205
+ - tuple: (bool, float) -> True if the duration of the video and audio matches, False otherwise, along with the difference in duration.
211
206
  """
212
-
213
- # Ottieni la durata del video
214
207
  video_duration = get_video_duration(video_path)
215
-
216
- # Ottieni la durata dell'audio
217
208
  audio_duration = get_video_duration(audio_path)
218
209
 
219
- # Verifica se le durate corrispondono
220
- return video_duration == audio_duration
210
+ duration_difference = abs(video_duration - audio_duration)
211
+
212
+ # Check if the duration difference is within the tolerance
213
+ if duration_difference <= tolerance:
214
+ return True, duration_difference
215
+ else:
216
+ return False, duration_difference
@@ -52,7 +52,7 @@ class M3U8_Ts_Estimator:
52
52
  self.now_downloaded_size += size_download
53
53
  logging.debug(f"Current total downloaded size: {self.now_downloaded_size}")
54
54
 
55
- def capture_speed(self, interval: float = 1):
55
+ def capture_speed(self, interval: float = 1.5):
56
56
  """Capture the internet speed periodically."""
57
57
  last_upload, last_download = 0, 0
58
58
  speed_buffer = deque(maxlen=3)
@@ -119,15 +119,15 @@ class M3U8_Ts_Estimator:
119
119
 
120
120
  retry_count = self.segments_instance.active_retries if self.segments_instance else 0
121
121
  progress_str = (
122
- f"{Colors.GREEN}{number_file_total_size} {Colors.WHITE}< {Colors.RED}{units_file_total_size}"
123
- f"{Colors.WHITE} {Colors.CYAN}{average_internet_speed} {Colors.RED}{average_internet_unit}"
122
+ f"{Colors.GREEN}{number_file_total_size} {Colors.RED}{units_file_total_size}"
123
+ f"{Colors.WHITE}, {Colors.CYAN}{average_internet_speed} {Colors.RED}{average_internet_unit}"
124
124
  f"{Colors.WHITE}, {Colors.GREEN}CRR {Colors.RED}{retry_count} "
125
125
  )
126
126
 
127
127
  else:
128
128
  retry_count = self.segments_instance.active_retries if self.segments_instance else 0
129
129
  progress_str = (
130
- f"{Colors.GREEN}{number_file_total_size} {Colors.WHITE}< {Colors.RED}{units_file_total_size}"
130
+ f"{Colors.GREEN}{number_file_total_size} {Colors.RED}{units_file_total_size}"
131
131
  f"{Colors.WHITE}, {Colors.GREEN}CRR {Colors.RED}{retry_count} "
132
132
  )
133
133
 
@@ -73,7 +73,7 @@ def get_select_title(table_show_manager, generic_obj):
73
73
 
74
74
  # Handle user's quit command
75
75
  if last_command == "q" or last_command == "quit":
76
- console.print("\n[red]Quit [white]...")
76
+ console.print("\n[red]Quit ...")
77
77
  sys.exit(0)
78
78
 
79
79
  # Check if the selected index is within range
@@ -1,5 +1,5 @@
1
1
  __title__ = 'StreamingCommunity'
2
- __version__ = '2.9.2'
2
+ __version__ = '2.9.4'
3
3
  __author__ = 'Arrowar'
4
4
  __description__ = 'A command-line program to download film'
5
5
  __copyright__ = 'Copyright 2024'
@@ -421,9 +421,6 @@ class ConfigManager:
421
421
  config_manager = ConfigManager()
422
422
  config_manager.read_config()
423
423
 
424
-
425
- import sys
426
-
427
424
  def get_use_large_bar():
428
425
  """
429
426
  Determines whether the large bar feature should be enabled.
@@ -0,0 +1,6 @@
1
+ # 11.03.25
2
+
3
+ from .run import main
4
+ from .Lib.Downloader.HLS.downloader import HLS_Downloader
5
+ from .Lib.Downloader.MP4.downloader import MP4_downloader
6
+ from .Lib.Downloader.TOR.downloader import TOR_downloader
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: StreamingCommunity
3
- Version: 2.9.2
3
+ Version: 2.9.4
4
4
  Home-page: https://github.com/Lovi-0/StreamingCommunity
5
5
  Author: Lovi-0
6
6
  Project-URL: Bug Reports, https://github.com/Lovi-0/StreamingCommunity/issues
@@ -23,6 +23,14 @@ Requires-Dist: pycryptodomex
23
23
  Requires-Dist: ua-generator
24
24
  Requires-Dist: qbittorrent-api
25
25
  Requires-Dist: pyTelegramBotAPI
26
+ Dynamic: author
27
+ Dynamic: description
28
+ Dynamic: description-content-type
29
+ Dynamic: home-page
30
+ Dynamic: keywords
31
+ Dynamic: project-url
32
+ Dynamic: requires-dist
33
+ Dynamic: requires-python
26
34
 
27
35
  <p align="center">
28
36
  <img src="https://i.ibb.co/v6RnT0wY/s2.jpg" alt="Project Logo" width="700"/>
@@ -72,6 +80,7 @@ Requires-Dist: pyTelegramBotAPI
72
80
  - 🔍 [Parser](#m3u8_parser-settings)
73
81
  - 📝 [Command](#command)
74
82
  - 💻 [Examples of terminal](#examples-of-terminal-usage)
83
+ - 🔧 [Manual domain configuration](#update-domains)
75
84
  - 🐳 [Docker](#docker)
76
85
  - 📝 [Telegram Usage](#telegram-usage)
77
86
  - 🎓 [Tutorial](#tutorials)
@@ -104,9 +113,15 @@ Install directly from PyPI:
104
113
  pip install StreamingCommunity
105
114
  ```
106
115
 
107
- ### Creating a Run Script
116
+ Update to the latest version:
108
117
 
109
- Create `run_streaming.py`:
118
+ ```bash
119
+ pip install --upgrade StreamingCommunity
120
+ ```
121
+
122
+ ## Quick Start
123
+
124
+ Create a simple script (`run_streaming.py`) to launch the main application:
110
125
 
111
126
  ```python
112
127
  from StreamingCommunity.run import main
@@ -116,16 +131,85 @@ if __name__ == "__main__":
116
131
  ```
117
132
 
118
133
  Run the script:
134
+
119
135
  ```bash
120
136
  python run_streaming.py
121
137
  ```
122
138
 
123
- ### Updating via PyPI
139
+ ## Modules
124
140
 
125
- ```bash
126
- pip install --upgrade StreamingCommunity
141
+ ### HLS Downloader
142
+
143
+ Download HTTP Live Streaming (HLS) content from m3u8 URLs.
144
+
145
+ ```python
146
+ from StreamingCommunity.Download import HLS_Downloader
147
+
148
+ # Initialize with m3u8 URL and optional output path
149
+ downloader = HLS_Downloader(
150
+ m3u8_url="https://example.com/stream.m3u8",
151
+ output_path="/downloads/video.mp4" # Optional
152
+ )
153
+
154
+ # Start the download
155
+ downloader.download()
127
156
  ```
128
157
 
158
+ See [HLS example](./Test/Download/HLS.py) for complete usage.
159
+
160
+ ### MP4 Downloader
161
+
162
+ Direct MP4 file downloader with support for custom headers and referrer.
163
+
164
+ ```python
165
+ from StreamingCommunity.Download import MP4_downloader
166
+
167
+ # Basic usage
168
+ downloader = MP4_downloader(
169
+ url="https://example.com/video.mp4",
170
+ path="/downloads/saved_video.mp4"
171
+ )
172
+
173
+ # Advanced usage with custom headers and referrer
174
+ headers = {
175
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
176
+ }
177
+ downloader = MP4_downloader(
178
+ url="https://example.com/video.mp4",
179
+ path="/downloads/saved_video.mp4",
180
+ referer="https://example.com",
181
+ headers_=headers
182
+ )
183
+
184
+ # Start download
185
+ downloader.download()
186
+ ```
187
+
188
+ See [MP4 example](./Test/Download/MP4.py) for complete usage.
189
+
190
+ ### Torrent Client
191
+
192
+ Download content via torrent magnet links.
193
+
194
+ ```python
195
+ from StreamingCommunity.Download import TOR_downloader
196
+
197
+ # Initialize torrent client
198
+ client = TOR_downloader()
199
+
200
+ # Add magnet link
201
+ client.add_magnet_link("magnet:?xt=urn:btih:example_hash&dn=example_name")
202
+
203
+ # Start download
204
+ client.start_download()
205
+
206
+ # Move downloaded files to specific location
207
+ client.move_downloaded_files("/downloads/torrents/")
208
+ ```
209
+
210
+ See [Torrent example](./Test/Download/TOR.py) for complete usage.
211
+
212
+
129
213
  ## 2. Automatic Installation
130
214
 
131
215
  ### Supported Operating Systems 💿
@@ -1,75 +1,79 @@
1
- StreamingCommunity/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1
+ StreamingCommunity/__init__.py,sha256=Cw-N0VCg7sef1WqdtvVwrhs1zc4LoUhs5C8k7vpM1lQ,207
2
2
  StreamingCommunity/run.py,sha256=AbEL0cyAaRgaG5qE1c7Z6SVZ4Wu7WIH9pZmwC4FDWW8,12076
3
3
  StreamingCommunity/Api/Player/ddl.py,sha256=M_ePETCMBpIHr5K5Yb7EML5VXwqkR7vJHQcGIv4AEQw,2261
4
- StreamingCommunity/Api/Player/maxstream.py,sha256=lQ6sbhBqMR9e6N-03nWZ3qsUlRT9l68d8dTA0th1XVQ,4984
5
- StreamingCommunity/Api/Player/supervideo.py,sha256=owyoSkLDJwASNYQw77ZbJ5ptCXOFsAC5ghN-o0RaML0,5001
4
+ StreamingCommunity/Api/Player/maxstream.py,sha256=WXg8xncFXFiaUmTVXxB3NyknQtbvd0sF1eRaoDO24bU,4822
5
+ StreamingCommunity/Api/Player/supervideo.py,sha256=hr9QViI-XD0Dqhcx90oaH8_j0d6cxpVaf-EuCjMs6hI,5199
6
6
  StreamingCommunity/Api/Player/vixcloud.py,sha256=NOZhW59hyBnG5FfmppcnIudAztr7seWzQBzAN3KC_3M,6317
7
7
  StreamingCommunity/Api/Player/Helper/Vixcloud/js_parser.py,sha256=U-8QlD5kGzIk3-4t4D6QyYmiDe8UBrSuVi1YHRQb7AU,4295
8
- StreamingCommunity/Api/Player/Helper/Vixcloud/util.py,sha256=dnyVxZTjjV3C6PUCu2OMeHI4NbiioBWhixlY2Ol9I74,5206
8
+ StreamingCommunity/Api/Player/Helper/Vixcloud/util.py,sha256=QLUgbwQrpuPIVNzdBlAiEJXnd-eCj_JQFckZZEEL55w,5214
9
9
  StreamingCommunity/Api/Site/1337xx/__init__.py,sha256=pyaQ3QlLdiqLcyNyfE6jKhOR5BXUiKLfPcIBHbk8U8U,1378
10
- StreamingCommunity/Api/Site/1337xx/site.py,sha256=u6a453wVy3vJrGcLlSUhErKzr63lv-o9cx36RjFpPRs,2647
10
+ StreamingCommunity/Api/Site/1337xx/site.py,sha256=MJzxNLhx6PDsnTTyJebDjzFPpqep54u2Q4VFf9sa23M,2212
11
11
  StreamingCommunity/Api/Site/1337xx/title.py,sha256=lGb-IbWEIfg9Eu3XIu6IfxTOjvXkFL_NO9UEZcxOAfE,1831
12
+ StreamingCommunity/Api/Site/altadefinizione/__init__.py,sha256=cQGI_p64kOwyDHiV-Jj5dSTnRCnEl-HyBHDUa0o1PTM,1484
13
+ StreamingCommunity/Api/Site/altadefinizione/film.py,sha256=LiHaKjB4lt3hcLx9kbJvndyZmkOc0yuRWYopD9PkxGI,2930
14
+ StreamingCommunity/Api/Site/altadefinizione/series.py,sha256=fYBIiCP9P422-bfJJ2ualFz3MwKiNsDBoMFXvovadiQ,5581
15
+ StreamingCommunity/Api/Site/altadefinizione/site.py,sha256=8wiC6NOSgPSWWpmGFyg2eZ4gZNXYe_UqTonp2fIdLzc,2089
16
+ StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py,sha256=NcH8bH7WsBqfLUZCMm5163rBuSPBCb8DgRysI558yFM,2525
12
17
  StreamingCommunity/Api/Site/animeunity/__init__.py,sha256=Lz9trBzQZL11wGyIT2Y4CWe3JxOkDUPzTQXXO76s0oQ,2278
13
- StreamingCommunity/Api/Site/animeunity/film_serie.py,sha256=noYqH5NHUk_JO6GeqN7-PQy3tplDRKYWYI_cgT1SzqI,5771
14
- StreamingCommunity/Api/Site/animeunity/site.py,sha256=7NX59B89xpZ6Tj96a_ZCsVMDwOq8fxdw81vrlnvNjn4,5912
18
+ StreamingCommunity/Api/Site/animeunity/film_serie.py,sha256=Nt6j-4wT00SFufjIK9-nkauTVnyfISbUyMfvZk8Z0Lc,5768
19
+ StreamingCommunity/Api/Site/animeunity/site.py,sha256=2M91AZMaOrbUoZUjyB0L6y0g_-67ywfxbPUq37g65J8,4964
15
20
  StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py,sha256=6Vbw5KVwUbgooGjUIRAuXr9cWSkHDkAFP7EiXF2T4OM,2709
16
21
  StreamingCommunity/Api/Site/cb01new/__init__.py,sha256=jw-eyJunemd3uNwpow75_8s7TX8bYyiRA-zkF5NZ75w,1393
17
22
  StreamingCommunity/Api/Site/cb01new/film.py,sha256=trrEGcklB6FhqpJvGaEwHI0EThK__e9O6DuknKAFNHw,1628
18
- StreamingCommunity/Api/Site/cb01new/site.py,sha256=q9bHKgHkXWE0vOcfQ9bKU0QDzbLassfSN2im2O4EYiI,2523
23
+ StreamingCommunity/Api/Site/cb01new/site.py,sha256=pZy-skUUzTql3sP7j6kaw1m7JjLe-xFjUiP48EHABMY,2009
19
24
  StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py,sha256=XkpTFeb-yFI_bJCIph72cVE8GVoJP7Tby-NqkZNNDM4,1533
20
25
  StreamingCommunity/Api/Site/ddlstreamitaly/series.py,sha256=z3te51do5C_O77rDTR1N01aQ76BIGe5pm5i_PWJepQ4,3369
21
- StreamingCommunity/Api/Site/ddlstreamitaly/site.py,sha256=_I4fZuzE5DnwAGOBOJK_IYW04RETwl3N2J0FUJAjQqg,2913
26
+ StreamingCommunity/Api/Site/ddlstreamitaly/site.py,sha256=ZbzGqu24jqKPARKPfyXt5wB6QPRiygXitbgVRb9B2zk,2476
22
27
  StreamingCommunity/Api/Site/ddlstreamitaly/util/ScrapeSerie.py,sha256=HY8YEvzWp3sy1q07rFLXLZhGYvapA1amMZByYvs0iJM,2553
23
28
  StreamingCommunity/Api/Site/guardaserie/__init__.py,sha256=NjMn1EFWdFi9P89qpKNg3Dc84DDOSyuSBX0V5K24OjQ,1385
24
- StreamingCommunity/Api/Site/guardaserie/series.py,sha256=52OjjItPuVglqlpFFVeJiSXrUL5WFhC-GfyRo7yWnsM,5665
25
- StreamingCommunity/Api/Site/guardaserie/site.py,sha256=5Y5svAT4QYZrNDPM9couf6M94g0g320NfoAuJt4dp94,2538
29
+ StreamingCommunity/Api/Site/guardaserie/series.py,sha256=xXuMR9NiAtXkHrErsmXRY9IkE2FVGuhqjATYEfapb0Y,5670
30
+ StreamingCommunity/Api/Site/guardaserie/site.py,sha256=0amgeVNguQP_5tD0ajhQX17GbSptE_r5_9JPNCd-caw,2101
26
31
  StreamingCommunity/Api/Site/guardaserie/util/ScrapeSerie.py,sha256=4sZRWm8r5X80q285hemRf7MAWeaN5yfOU6i1SjKU4Tg,3268
27
32
  StreamingCommunity/Api/Site/mostraguarda/__init__.py,sha256=6oGv_Q6pXFERkbpKjYjFJFblvDYSfe1zZph6_Ch8gNY,1234
28
33
  StreamingCommunity/Api/Site/mostraguarda/film.py,sha256=dA7Vo9bU7g8eY8Vaj06_n2MHlKBMHh4B_MIw2sO872A,2719
29
34
  StreamingCommunity/Api/Site/streamingcommunity/__init__.py,sha256=FV3ch-farw3tN_-Ay3JV_-TIoHzgQzxEJWPlFibE62Y,2351
30
35
  StreamingCommunity/Api/Site/streamingcommunity/film.py,sha256=LaZzEQms9t7r30_PjHPgIOUkVDyotX0qFDBMKMVNSWo,2530
31
- StreamingCommunity/Api/Site/streamingcommunity/series.py,sha256=T4Yw-cjdQ8GsOLPJwd8iDIcTND1olg81MopsaSDd1Ik,7921
32
- StreamingCommunity/Api/Site/streamingcommunity/site.py,sha256=OID6QB_WMydwVCYD0SupHpEP0VwHIBmwifwuIHW9HaE,2973
33
- StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py,sha256=YYetljW4yr6eoiLe6nDUuFZ9NI8K85tF6859ikITmsY,3571
36
+ StreamingCommunity/Api/Site/streamingcommunity/series.py,sha256=AxRxb7MmWS9AfmibK2iZca7ClzzU91e3p3E9ap3LcQI,8211
37
+ StreamingCommunity/Api/Site/streamingcommunity/site.py,sha256=Z0tOcF3a6JzXwwsfCh1_qUDLW5PdeTFQsVZrCxyMeGg,2722
38
+ StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py,sha256=4WU0YFPXcsBpEANMGpAsbtffu3HxCqLsiC0K6_4OlHM,4525
34
39
  StreamingCommunity/Api/Template/__init__.py,sha256=oyfd_4_g5p5q6mxb_rKwSsudZnTM3W3kg1tLwxg-v-Q,46
35
- StreamingCommunity/Api/Template/config_loader.py,sha256=seJjLi05_8xrs4tdt4zXNCPa9TLp7n5FufFM2XErokI,2166
36
- StreamingCommunity/Api/Template/site.py,sha256=MJF8oc4iW29nU8SF_J94UaSjanTVBMhKiRl3xrA0qBA,2849
37
- StreamingCommunity/Api/Template/Class/SearchType.py,sha256=FtO8xDUGEeJgMWsK2Ab7ZzAFsncalTYL2oEYi8uCnuk,2531
38
- StreamingCommunity/Api/Template/Util/__init__.py,sha256=GZZgT816VwTYekPOwLExHenpak0gO-V3LLGTYIElt3A,234
39
- StreamingCommunity/Api/Template/Util/get_domain.py,sha256=tWQKWs5LJZna4a2P0IfxlSZDbZTDjiqq9SmHTbK-PyU,2763
40
- StreamingCommunity/Api/Template/Util/manage_ep.py,sha256=xYDC3tlx6gjQqCqcyKCfQVQeE6aWU5sdrovj8uuvbd8,8118
40
+ StreamingCommunity/Api/Template/config_loader.py,sha256=2RT_0mqQmWzXM4rYaqss-yhXztYAcfNkTalFPjzv270,2056
41
+ StreamingCommunity/Api/Template/site.py,sha256=lD7FCp-xHCTwTam51MYtI-JKRuw1VLsY9KQDtsk3MYE,2842
42
+ StreamingCommunity/Api/Template/Class/SearchType.py,sha256=LOlE8UgraEM0UAVeNCThDGi8bleei31p7KpryuZm3VE,2530
43
+ StreamingCommunity/Api/Template/Util/__init__.py,sha256=ZWQQd6iymNFDol9HaKPhVBoRX1W-xHJZgU_mZvLVdsM,196
44
+ StreamingCommunity/Api/Template/Util/manage_ep.py,sha256=FYe2DC9SXIXzlRYI7fW4ieBpfrxYzsUgt2C47tYRk7U,9252
41
45
  StreamingCommunity/Lib/Downloader/__init__.py,sha256=JhbBh5hOnSM7VmtkxJ7zZ_FtWEC1JdnKThsSBjLV5FY,140
42
- StreamingCommunity/Lib/Downloader/HLS/downloader.py,sha256=h-44aunSdcCbG4CXPeZP2LWypA9T905E4RnTP4kSyZ0,21168
43
- StreamingCommunity/Lib/Downloader/HLS/segments.py,sha256=4D-B_KfwiQq6suMgJxL_aMrOqqX5RVc4Vy0Ktc7tFKM,17609
44
- StreamingCommunity/Lib/Downloader/MP4/downloader.py,sha256=KTNivIvVwn72rA34fNPxT5Q88u7IS3vHLn_Y_jdrZww,7434
46
+ StreamingCommunity/Lib/Downloader/HLS/downloader.py,sha256=s3ZXyKsuBN3wE4Y0Y9xXuDauBPbaI9Qhgoy83IeMnbs,21590
47
+ StreamingCommunity/Lib/Downloader/HLS/segments.py,sha256=eVQzB06EochPM1E0VNWgfvEyc5wGDq_yG6Fqo7WPNic,18468
48
+ StreamingCommunity/Lib/Downloader/MP4/downloader.py,sha256=MiKBICNnMPJEz0ICiEfKYFs0LhKKfTSMfm9gGWolR74,7537
45
49
  StreamingCommunity/Lib/Downloader/TOR/downloader.py,sha256=KVZxCl1VB1-OuTjUhVS5Ycog_P0vCGTfRzhZPv8O7Ps,11267
46
50
  StreamingCommunity/Lib/FFmpeg/__init__.py,sha256=6PBsZdE1jrD2EKOVyx3JEHnyDZzVeKlPkH5T0zyfOgU,130
47
51
  StreamingCommunity/Lib/FFmpeg/capture.py,sha256=73BEpTijksErZOu46iRxwl3idKzZ-sVXXRr4nocIGY0,5168
48
- StreamingCommunity/Lib/FFmpeg/command.py,sha256=fVBm1wmzxIPzZEl4oPJG_u0nmlgxuk01hLSO4RB_TnM,10642
49
- StreamingCommunity/Lib/FFmpeg/util.py,sha256=Yyo-z9TOPGFdD_VscWi35Kcw88y4loGNLpNOzy7ADm8,7063
52
+ StreamingCommunity/Lib/FFmpeg/command.py,sha256=ubpffE02nsZM7xch5gbwGlEiUzecpxcFOd63n2cqM1k,10708
53
+ StreamingCommunity/Lib/FFmpeg/util.py,sha256=6QzTbk5BNxKYsTl-cJgOO2XGQTWUdMloWMyrGGBs6eU,7168
50
54
  StreamingCommunity/Lib/M3U8/__init__.py,sha256=H_KS2eDd3kVXMziFJnD0FCPvPHEizaqfoA36ElTv_r8,170
51
55
  StreamingCommunity/Lib/M3U8/decryptor.py,sha256=kuxxsd3eN0VGRrMJWXzHo8gCpT0u3fSZs_lwxlE5Fqs,2948
52
- StreamingCommunity/Lib/M3U8/estimator.py,sha256=5Qevboxu1h5Q-72bkHy0-Vess9pOIaUrpFYfBVWNDN8,5709
56
+ StreamingCommunity/Lib/M3U8/estimator.py,sha256=ueb2at6Ueow3TUsAyd43aIy0UzKG2-PEgnYysHRMkZ0,5680
53
57
  StreamingCommunity/Lib/M3U8/parser.py,sha256=xN16pQZSCN9mQl_s7OcuH07-mNgVMpAS_hERq6zp7XM,21558
54
58
  StreamingCommunity/Lib/M3U8/url_fixer.py,sha256=zldE4yOuNBV6AAvL1KI6p7XdRI_R5YZRscbDgT1564M,1735
55
59
  StreamingCommunity/Lib/TMBD/__init__.py,sha256=XzE42tw3Ws59DD1PF8WmGtZ0D4D7Hk3Af8QthNE-22U,66
56
60
  StreamingCommunity/Lib/TMBD/obj_tmbd.py,sha256=dRSvJFS5yqmsBZcw2wqbStcBtXNjU_3n5czMyremAtU,1187
57
- StreamingCommunity/Lib/TMBD/tmdb.py,sha256=LjO21d7iexnSwKBYjgXFECojVSE8WCspQszJJcaZexU,10692
61
+ StreamingCommunity/Lib/TMBD/tmdb.py,sha256=byg0EFnlmd9JeLvn1N9K3QkB1KEfeMuFa7OVfGqks1Y,10685
58
62
  StreamingCommunity/TelegramHelp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
63
  StreamingCommunity/TelegramHelp/telegram_bot.py,sha256=Qe1__aoK4PpDuing8JtWgdHzLee8LuYYyfeLNA7yADU,26307
60
64
  StreamingCommunity/Upload/update.py,sha256=TXWAOfvZr1So_oME11YvX_L5zRy2tM-ijF-_g1jf87o,2548
61
- StreamingCommunity/Upload/version.py,sha256=19h6dsdmBu3Dx_-ippgpAeTPW1Xq3eP7nA0tCWVk3V4,171
65
+ StreamingCommunity/Upload/version.py,sha256=hDKhBLXzbE1tM986tfsuk7r0PhDnn-z8ib3Txve_wmc,171
62
66
  StreamingCommunity/Util/color.py,sha256=NvD0Eni-25oOOkY-szCEoc0lGvzQxyL7xhM0RE4EvUM,458
63
- StreamingCommunity/Util/config_json.py,sha256=dmo7FTboEuEs1nYf17RYaTyT03qRvOLJzGgBitYHXs4,19379
67
+ StreamingCommunity/Util/config_json.py,sha256=pbXfxBx_SP6eWo-5MYNwLRKRFRF-RT9MMRMLXKP5mM4,19366
64
68
  StreamingCommunity/Util/ffmpeg_installer.py,sha256=q5yb_ZXKe9PhcG7JbKLfo1AZa8DNukgHqymPbudDuAY,13585
65
69
  StreamingCommunity/Util/headers.py,sha256=TItkaFMx1GqsVNEIS3Tr0BGU5EHyF-HkZVliHORT3P8,308
66
70
  StreamingCommunity/Util/logger.py,sha256=9kGD6GmWj2pM8ADpJc85o7jm8DD0c5Aguqnq-9kmxos,3314
67
71
  StreamingCommunity/Util/message.py,sha256=SJaIPLvWeQqsIODVUKw3TgYRmBChovmlbcF6OUxqMI8,1425
68
72
  StreamingCommunity/Util/os.py,sha256=MUGJKQbNMWeoUrnJ2Ug3hoyYlrPDqU9BY94UmiUbxfA,14858
69
73
  StreamingCommunity/Util/table.py,sha256=X1t9VPYl9GemLMk_-x_WfpysQ-3Iv8vh0aTIJKm0fK0,8565
70
- StreamingCommunity-2.9.2.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
71
- StreamingCommunity-2.9.2.dist-info/METADATA,sha256=dVNxX8cApTrcnubwEphjTfjaai2YBqz2KnzNBPPlnn4,21498
72
- StreamingCommunity-2.9.2.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
73
- StreamingCommunity-2.9.2.dist-info/entry_points.txt,sha256=Qph9XYfDC8n4LfDLOSl6gJGlkb9eFb5f-JOr_Wb_5rk,67
74
- StreamingCommunity-2.9.2.dist-info/top_level.txt,sha256=YsOcxKP-WOhWpIWgBlh0coll9XUx7aqmRPT7kmt3fH0,19
75
- StreamingCommunity-2.9.2.dist-info/RECORD,,
74
+ streamingcommunity-2.9.4.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
75
+ streamingcommunity-2.9.4.dist-info/METADATA,sha256=Jc62h_lSuJU_KKWjfGXMUJ_kXnyUrddv2CFe6UzoqzE,23425
76
+ streamingcommunity-2.9.4.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
77
+ streamingcommunity-2.9.4.dist-info/entry_points.txt,sha256=Qph9XYfDC8n4LfDLOSl6gJGlkb9eFb5f-JOr_Wb_5rk,67
78
+ streamingcommunity-2.9.4.dist-info/top_level.txt,sha256=YsOcxKP-WOhWpIWgBlh0coll9XUx7aqmRPT7kmt3fH0,19
79
+ streamingcommunity-2.9.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.45.1)
2
+ Generator: setuptools (76.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,100 +0,0 @@
1
- # 18.06.24
2
-
3
- import certifi
4
- from urllib.parse import urlparse, unquote
5
-
6
-
7
- # External libraries
8
- import httpx
9
- from rich.console import Console
10
-
11
-
12
- # Internal utilities
13
- from StreamingCommunity.Util.headers import get_headers
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")
21
-
22
-
23
- def get_tld(url_str):
24
- """Extract the TLD (Top-Level Domain) from the URL."""
25
- try:
26
- url_str = unquote(url_str)
27
- parsed = urlparse(url_str)
28
- domain = parsed.netloc.lower()
29
-
30
- if domain.startswith('www.'):
31
- domain = domain[4:]
32
- parts = domain.split('.')
33
-
34
- return parts[-1] if len(parts) >= 2 else None
35
-
36
- except Exception:
37
- return None
38
-
39
- def get_base_domain(url_str):
40
- """Extract base domain without protocol, www and path."""
41
- try:
42
- parsed = urlparse(url_str)
43
- domain = parsed.netloc.lower()
44
- if domain.startswith('www.'):
45
- domain = domain[4:]
46
-
47
- # Check if domain has multiple parts separated by dots
48
- parts = domain.split('.')
49
- if len(parts) > 2:
50
- return '.'.join(parts[:-1])
51
-
52
- return parts[0]
53
-
54
- except Exception:
55
- return None
56
-
57
- def validate_url(url, base_url):
58
- """Validate if URL is accessible and matches expected base domain."""
59
- console.print(f"\n[cyan]Starting validation for URL[white]: [yellow]{url}")
60
-
61
- # Verify URL structure matches base_url structure
62
- base_domain = get_base_domain(base_url)
63
- url_domain = get_base_domain(url)
64
-
65
- if base_domain != url_domain:
66
- console.print(f"[red]Domain structure mismatch: {url_domain} != {base_domain}")
67
- return False, None
68
-
69
- client = httpx.Client(
70
- http1=True,
71
- verify=certifi.where(),
72
- headers=get_headers(),
73
- timeout=MAX_TIMEOUT
74
- )
75
-
76
- # Make request to web site
77
- response = client.get(url, follow_redirects=False)
78
-
79
- if response.status_code >= 400:
80
- console.print(f"[red]Check failed: HTTP {response.status_code}")
81
- console.print(f"[red]Response content: {response.text}")
82
- return False, None
83
-
84
- return True, base_domain
85
-
86
- def search_domain(base_url: str):
87
- """Search for valid domain matching site name and base URL."""
88
- try:
89
- is_correct, redirect_tld = validate_url(base_url, base_url)
90
-
91
- if is_correct:
92
- tld = redirect_tld or get_tld(base_url)
93
- return tld, base_url
94
-
95
- else:
96
- return None, None
97
-
98
- except Exception as e:
99
- console.print(f"[red]Error testing initial URL: {str(e)}")
100
- return None, None