StreamingCommunity 1.8.0__py3-none-any.whl → 1.9.1__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 (99) hide show
  1. StreamingCommunity/{Src/Api → Api}/Player/ddl.py +3 -3
  2. StreamingCommunity/{Src/Api → Api}/Player/maxstream.py +2 -2
  3. StreamingCommunity/{Src/Api → Api}/Player/supervideo.py +2 -2
  4. StreamingCommunity/{Src/Api → Api}/Player/vixcloud.py +3 -3
  5. StreamingCommunity/{Src/Api → Api}/Site/1337xx/__init__.py +1 -1
  6. StreamingCommunity/{Src/Api → Api}/Site/1337xx/costant.py +3 -3
  7. StreamingCommunity/{Src/Api → Api}/Site/1337xx/site.py +7 -7
  8. StreamingCommunity/{Src/Api → Api}/Site/1337xx/title.py +6 -6
  9. StreamingCommunity/{Src/Api → Api}/Site/altadefinizione/__init__.py +1 -1
  10. StreamingCommunity/{Src/Api/Site/mostraguarda → Api/Site/altadefinizione}/costant.py +3 -3
  11. StreamingCommunity/{Src/Api → Api}/Site/altadefinizione/film.py +8 -8
  12. StreamingCommunity/{Src/Api → Api}/Site/altadefinizione/site.py +7 -7
  13. StreamingCommunity/{Src/Api → Api}/Site/animeunity/__init__.py +1 -1
  14. StreamingCommunity/{Src/Api/Site/altadefinizione → Api/Site/animeunity}/costant.py +3 -3
  15. StreamingCommunity/{Src/Api → Api}/Site/animeunity/film_serie.py +18 -19
  16. StreamingCommunity/{Src/Api → Api}/Site/animeunity/site.py +6 -6
  17. StreamingCommunity/{Src/Api → Api}/Site/animeunity/util/ScrapeSerie.py +3 -3
  18. StreamingCommunity/{Src/Api → Api}/Site/bitsearch/__init__.py +1 -1
  19. StreamingCommunity/{Src/Api → Api}/Site/bitsearch/costant.py +3 -3
  20. StreamingCommunity/{Src/Api → Api}/Site/bitsearch/site.py +7 -7
  21. StreamingCommunity/{Src/Api → Api}/Site/bitsearch/title.py +5 -5
  22. StreamingCommunity/{Src/Api → Api}/Site/cb01new/__init__.py +1 -1
  23. StreamingCommunity/{Src/Api → Api}/Site/cb01new/costant.py +3 -3
  24. StreamingCommunity/{Src/Api → Api}/Site/cb01new/film.py +8 -8
  25. StreamingCommunity/{Src/Api → Api}/Site/cb01new/site.py +6 -6
  26. StreamingCommunity/{Src/Api → Api}/Site/ddlstreamitaly/__init__.py +1 -1
  27. StreamingCommunity/{Src/Api → Api}/Site/ddlstreamitaly/costant.py +3 -3
  28. StreamingCommunity/{Src/Api → Api}/Site/ddlstreamitaly/series.py +11 -12
  29. StreamingCommunity/{Src/Api → Api}/Site/ddlstreamitaly/site.py +7 -7
  30. StreamingCommunity/{Src/Api → Api}/Site/ddlstreamitaly/util/ScrapeSerie.py +5 -3
  31. StreamingCommunity/{Src/Api → Api}/Site/guardaserie/__init__.py +1 -1
  32. StreamingCommunity/{Src/Api/Site/piratebays → Api/Site/guardaserie}/costant.py +3 -3
  33. StreamingCommunity/{Src/Api → Api}/Site/guardaserie/series.py +11 -11
  34. StreamingCommunity/{Src/Api → Api}/Site/guardaserie/site.py +7 -7
  35. StreamingCommunity/{Src/Api/Site/guardaserie/Player → Api/Site/guardaserie/util}/ScrapeSerie.py +2 -2
  36. StreamingCommunity/{Src/Api → Api}/Site/mostraguarda/__init__.py +2 -2
  37. StreamingCommunity/{Src/Api/Site/animeunity → Api/Site/mostraguarda}/costant.py +3 -3
  38. StreamingCommunity/{Src/Api → Api}/Site/mostraguarda/film.py +9 -9
  39. StreamingCommunity/{Src/Api → Api}/Site/piratebays/__init__.py +1 -1
  40. StreamingCommunity/{Src/Api/Site/guardaserie → Api/Site/piratebays}/costant.py +3 -3
  41. StreamingCommunity/{Src/Api → Api}/Site/piratebays/site.py +6 -6
  42. StreamingCommunity/{Src/Api → Api}/Site/piratebays/title.py +5 -5
  43. StreamingCommunity/{Src/Api → Api}/Site/streamingcommunity/__init__.py +1 -1
  44. StreamingCommunity/{Src/Api → Api}/Site/streamingcommunity/costant.py +3 -3
  45. StreamingCommunity/{Src/Api → Api}/Site/streamingcommunity/film.py +10 -10
  46. StreamingCommunity/{Src/Api → Api}/Site/streamingcommunity/series.py +20 -18
  47. StreamingCommunity/{Src/Api → Api}/Site/streamingcommunity/site.py +7 -7
  48. StreamingCommunity/{Src/Api → Api}/Site/streamingcommunity/util/ScrapeSerie.py +3 -3
  49. StreamingCommunity/{Src/Api → Api}/Template/Util/get_domain.py +3 -3
  50. StreamingCommunity/{Src/Api → Api}/Template/Util/manage_ep.py +2 -2
  51. StreamingCommunity/{Src/Api → Api}/Template/Util/recall_search.py +1 -1
  52. StreamingCommunity/{Src/Api → Api}/Template/site.py +1 -1
  53. StreamingCommunity/{Src/Lib → Lib}/Downloader/HLS/downloader.py +4 -4
  54. StreamingCommunity/{Src/Lib → Lib}/Downloader/HLS/proxyes.py +3 -3
  55. StreamingCommunity/{Src/Lib → Lib}/Downloader/HLS/segments.py +42 -44
  56. StreamingCommunity/{Src/Lib → Lib}/Downloader/MP4/downloader.py +5 -5
  57. StreamingCommunity/{Src/Lib → Lib}/Downloader/TOR/downloader.py +3 -3
  58. StreamingCommunity/{Src/Lib → Lib}/Driver/driver_1.py +1 -1
  59. StreamingCommunity/{Src/Lib → Lib}/FFmpeg/capture.py +2 -2
  60. StreamingCommunity/{Src/Lib → Lib}/FFmpeg/command.py +3 -3
  61. StreamingCommunity/{Src/Lib → Lib}/FFmpeg/util.py +1 -1
  62. StreamingCommunity/{Src/Lib → Lib}/M3U8/decryptor.py +59 -24
  63. StreamingCommunity/{Src/Lib → Lib}/M3U8/estimator.py +6 -3
  64. StreamingCommunity/{Src/Lib → Lib}/M3U8/parser.py +1 -1
  65. StreamingCommunity/{Src/Lib → Lib}/TMBD/tmdb.py +1 -1
  66. StreamingCommunity/{Src/Upload → Upload}/update.py +6 -2
  67. StreamingCommunity/{Src/Upload → Upload}/version.py +1 -1
  68. StreamingCommunity/Util/ffmpeg_installer.py +275 -0
  69. StreamingCommunity/{Src/Util → Util}/headers.py +1 -1
  70. StreamingCommunity/{Src/Util → Util}/logger.py +1 -1
  71. StreamingCommunity/{Src/Util → Util}/message.py +2 -2
  72. StreamingCommunity/{Src/Util → Util}/os.py +118 -21
  73. StreamingCommunity/run.py +18 -12
  74. {StreamingCommunity-1.8.0.dist-info → StreamingCommunity-1.9.1.dist-info}/METADATA +126 -60
  75. StreamingCommunity-1.9.1.dist-info/RECORD +95 -0
  76. {StreamingCommunity-1.8.0.dist-info → StreamingCommunity-1.9.1.dist-info}/WHEEL +1 -1
  77. StreamingCommunity/Src/Api/Site/animeunity/anime.py +0 -126
  78. StreamingCommunity/Src/Api/Site/ddlstreamitaly/Player/ScrapeSerie.py +0 -83
  79. StreamingCommunity/Src/Api/Site/guardaserie/util/ScrapeSerie.py +0 -110
  80. StreamingCommunity-1.8.0.dist-info/RECORD +0 -97
  81. /StreamingCommunity/{Src/Api → Api}/Player/Helper/Vixcloud/js_parser.py +0 -0
  82. /StreamingCommunity/{Src/Api → Api}/Player/Helper/Vixcloud/util.py +0 -0
  83. /StreamingCommunity/{Src/Api → Api}/Template/Class/SearchType.py +0 -0
  84. /StreamingCommunity/{Src/Api → Api}/Template/Util/__init__.py +0 -0
  85. /StreamingCommunity/{Src/Api → Api}/Template/__init__.py +0 -0
  86. /StreamingCommunity/{Src/Lib → Lib}/Downloader/__init__.py +0 -0
  87. /StreamingCommunity/{Src/Lib → Lib}/FFmpeg/__init__.py +0 -0
  88. /StreamingCommunity/{Src/Lib → Lib}/M3U8/__init__.py +0 -0
  89. /StreamingCommunity/{Src/Lib → Lib}/M3U8/url_fixer.py +0 -0
  90. /StreamingCommunity/{Src/Lib → Lib}/TMBD/__init__.py +0 -0
  91. /StreamingCommunity/{Src/Lib → Lib}/TMBD/obj_tmbd.py +0 -0
  92. /StreamingCommunity/{Src/Util → Util}/_jsonConfig.py +0 -0
  93. /StreamingCommunity/{Src/Util → Util}/call_stack.py +0 -0
  94. /StreamingCommunity/{Src/Util → Util}/color.py +0 -0
  95. /StreamingCommunity/{Src/Util → Util}/console.py +0 -0
  96. /StreamingCommunity/{Src/Util → Util}/table.py +0 -0
  97. {StreamingCommunity-1.8.0.dist-info → StreamingCommunity-1.9.1.dist-info}/LICENSE +0 -0
  98. {StreamingCommunity-1.8.0.dist-info → StreamingCommunity-1.9.1.dist-info}/entry_points.txt +0 -0
  99. {StreamingCommunity-1.8.0.dist-info → StreamingCommunity-1.9.1.dist-info}/top_level.txt +0 -0
@@ -19,12 +19,12 @@ from tqdm import tqdm
19
19
 
20
20
 
21
21
  # Internal utilities
22
- from StreamingCommunity.Src.Util.console import console
23
- from StreamingCommunity.Src.Util.headers import get_headers, random_headers
24
- from StreamingCommunity.Src.Util.color import Colors
25
- from StreamingCommunity.Src.Util._jsonConfig import config_manager
26
- from StreamingCommunity.Src.Util.os import os_manager
27
- from StreamingCommunity.Src.Util.call_stack import get_call_stack
22
+ from StreamingCommunity.Util.console import console
23
+ from StreamingCommunity.Util.headers import get_headers, random_headers
24
+ from StreamingCommunity.Util.color import Colors
25
+ from StreamingCommunity.Util._jsonConfig import config_manager
26
+ from StreamingCommunity.Util.os import os_manager
27
+ from StreamingCommunity.Util.call_stack import get_call_stack
28
28
 
29
29
 
30
30
  # Logic class
@@ -39,15 +39,19 @@ from .proxyes import main_test_proxy
39
39
  # Config
40
40
  TQDM_DELAY_WORKER = config_manager.get_float('M3U8_DOWNLOAD', 'tqdm_delay')
41
41
  TQDM_USE_LARGE_BAR = config_manager.get_int('M3U8_DOWNLOAD', 'tqdm_use_large_bar')
42
+
42
43
  REQUEST_MAX_RETRY = config_manager.get_int('REQUESTS', 'max_retry')
43
44
  REQUEST_VERIFY = config_manager.get_bool('REQUESTS', 'verify_ssl')
45
+
44
46
  THERE_IS_PROXY_LIST = os_manager.check_file("list_proxy.txt")
45
47
  PROXY_START_MIN = config_manager.get_float('REQUESTS', 'proxy_start_min')
46
48
  PROXY_START_MAX = config_manager.get_float('REQUESTS', 'proxy_start_max')
49
+
47
50
  DEFAULT_VIDEO_WORKERS = config_manager.get_int('M3U8_DOWNLOAD', 'default_video_workser')
48
51
  DEFAULT_AUDIO_WORKERS = config_manager.get_int('M3U8_DOWNLOAD', 'default_audio_workser')
49
52
 
50
53
 
54
+
51
55
  # Variable
52
56
  headers_index = config_manager.get_dict('REQUESTS', 'user-agent')
53
57
  max_timeout = config_manager.get_int("REQUESTS", "timeout")
@@ -67,7 +71,8 @@ class M3U8_Segments:
67
71
  self.url = url
68
72
  self.tmp_folder = tmp_folder
69
73
  self.is_index_url = is_index_url
70
- self.expected_real_time = None
74
+ self.expected_real_time = None
75
+ self.max_timeout = max_timeout
71
76
 
72
77
  self.tmp_file_path = os.path.join(self.tmp_folder, "0.ts")
73
78
  os.makedirs(self.tmp_folder, exist_ok=True)
@@ -81,6 +86,8 @@ class M3U8_Segments:
81
86
  self.queue = PriorityQueue()
82
87
  self.stop_event = threading.Event()
83
88
  self.downloaded_segments = set()
89
+ self.base_timeout = 1.0
90
+ self.current_timeout = 5.0
84
91
 
85
92
  # Stopping
86
93
  self.interrupt_flag = threading.Event()
@@ -214,9 +221,12 @@ class M3U8_Segments:
214
221
  self.download_interrupted = True
215
222
  self.stop_event.set()
216
223
 
217
- signal.signal(signal.SIGINT, interrupt_handler)
224
+ if threading.current_thread() is threading.main_thread():
225
+ signal.signal(signal.SIGINT, interrupt_handler)
226
+ else:
227
+ print("Signal handler must be set in the main thread")
218
228
 
219
- def make_requests_stream(self, ts_url: str, index: int, progress_bar: tqdm, retries: int = 3, backoff_factor: float = 1.5) -> None:
229
+ def make_requests_stream(self, ts_url: str, index: int, progress_bar: tqdm, backoff_factor: float = 1.5) -> None:
220
230
  """
221
231
  Downloads a TS segment and adds it to the segment queue with retry logic.
222
232
 
@@ -226,14 +236,8 @@ class M3U8_Segments:
226
236
  - progress_bar (tqdm): Progress counter for tracking download progress.
227
237
  - retries (int): The number of times to retry on failure (default is 3).
228
238
  - backoff_factor (float): The backoff factor for exponential backoff (default is 1.5 seconds).
229
- """
230
- if self.interrupt_flag.is_set():
231
- return
232
-
233
- need_verify = REQUEST_VERIFY
234
- min_segment_size = 100 # Minimum acceptable size for a TS segment in bytes
235
-
236
- for attempt in range(retries):
239
+ """
240
+ for attempt in range(REQUEST_MAX_RETRY):
237
241
  if self.interrupt_flag.is_set():
238
242
  return
239
243
 
@@ -247,7 +251,7 @@ class M3U8_Segments:
247
251
  proxy = self.valid_proxy[index % len(self.valid_proxy)]
248
252
  logging.info(f"Use proxy: {proxy}")
249
253
 
250
- with httpx.Client(proxies=proxy, verify=need_verify) as client:
254
+ with httpx.Client(proxies=proxy, verify=REQUEST_VERIFY) as client:
251
255
  if 'key_base_url' in self.__dict__:
252
256
  response = client.get(
253
257
  url=ts_url,
@@ -265,7 +269,7 @@ class M3U8_Segments:
265
269
  )
266
270
 
267
271
  else:
268
- with httpx.Client(verify=need_verify) as client_2:
272
+ with httpx.Client(verify=REQUEST_VERIFY) as client_2:
269
273
  if 'key_base_url' in self.__dict__:
270
274
  response = client_2.get(
271
275
  url=ts_url,
@@ -286,19 +290,12 @@ class M3U8_Segments:
286
290
  response.raise_for_status()
287
291
  segment_content = response.content
288
292
  content_size = len(segment_content)
289
-
290
- # Check if segment is too small (possibly corrupted or empty)
291
- if content_size < min_segment_size:
292
- raise httpx.RequestError(f"Segment {index} too small ({content_size} bytes)")
293
-
294
293
  duration = time.time() - start_time
295
294
 
296
295
  # Decrypt if needed and verify decrypted content
297
296
  if self.decryption is not None:
298
297
  try:
299
298
  segment_content = self.decryption.decrypt(segment_content)
300
- if len(segment_content) < min_segment_size:
301
- raise Exception(f"Decrypted segment {index} too small ({len(segment_content)} bytes)")
302
299
 
303
300
  except Exception as e:
304
301
  logging.error(f"Decryption failed for segment {index}: {str(e)}")
@@ -318,10 +315,10 @@ class M3U8_Segments:
318
315
  return
319
316
 
320
317
  except Exception as e:
321
- #logging.error(f"Attempt {attempt + 1} failed for segment {index} - '{ts_url}': {e}")
318
+ logging.info(f"Attempt {attempt + 1} failed for segment {index} - '{ts_url}': {e}")
322
319
 
323
- if attempt + 1 == retries:
324
- #logging.error(f"Final retry failed for segment {index}")
320
+ if attempt + 1 == REQUEST_MAX_RETRY:
321
+ console.log(f"[red]Final retry failed for segment: {index}")
325
322
  self.queue.put((index, None)) # Marker for failed segment
326
323
  progress_bar.update(1)
327
324
  break
@@ -334,19 +331,20 @@ class M3U8_Segments:
334
331
  """
335
332
  Writes segments to file with additional verification.
336
333
  """
334
+ buffer = {}
335
+ expected_index = 0
336
+ segments_written = set()
337
+
337
338
  with open(self.tmp_file_path, 'wb') as f:
338
- expected_index = 0
339
- buffer = {}
340
- total_written = 0
341
- segments_written = set()
342
-
343
339
  while not self.stop_event.is_set() or not self.queue.empty():
344
-
345
340
  if self.interrupt_flag.is_set():
346
341
  break
347
342
 
348
343
  try:
349
- index, segment_content = self.queue.get(timeout=1)
344
+ index, segment_content = self.queue.get(timeout=self.current_timeout)
345
+
346
+ # Successful queue retrieval: reduce timeout
347
+ self.current_timeout = max(self.base_timeout, self.current_timeout / 2)
350
348
 
351
349
  # Handle failed segments
352
350
  if segment_content is None:
@@ -357,7 +355,6 @@ class M3U8_Segments:
357
355
  # Write segment if it's the next expected one
358
356
  if index == expected_index:
359
357
  f.write(segment_content)
360
- total_written += len(segment_content)
361
358
  segments_written.add(index)
362
359
  f.flush()
363
360
  expected_index += 1
@@ -365,26 +362,25 @@ class M3U8_Segments:
365
362
  # Write any buffered segments that are now in order
366
363
  while expected_index in buffer:
367
364
  next_segment = buffer.pop(expected_index)
365
+
368
366
  if next_segment is not None:
369
367
  f.write(next_segment)
370
- total_written += len(next_segment)
371
368
  segments_written.add(expected_index)
372
369
  f.flush()
370
+
373
371
  expected_index += 1
372
+
374
373
  else:
375
374
  buffer[index] = segment_content
376
375
 
377
376
  except queue.Empty:
377
+ self.current_timeout = min(self.max_timeout, self.current_timeout * 1.5)
378
+
378
379
  if self.stop_event.is_set():
379
380
  break
380
- continue
381
+
381
382
  except Exception as e:
382
383
  logging.error(f"Error writing segment {index}: {str(e)}")
383
- continue
384
-
385
- # Final verification
386
- if total_written == 0:
387
- raise Exception("No data written to file")
388
384
 
389
385
  def download_streams(self, add_desc):
390
386
  """
@@ -493,8 +489,10 @@ class M3U8_Segments:
493
489
  for index in missing_segments:
494
490
  if self.interrupt_flag.is_set():
495
491
  break
492
+
496
493
  try:
497
494
  self.make_requests_stream(self.segments[index], index, progress_bar)
495
+
498
496
  except Exception as e:
499
497
  logging.error(f"Failed to retry segment {index}: {str(e)}")
500
498
 
@@ -13,11 +13,11 @@ from tqdm import tqdm
13
13
 
14
14
 
15
15
  # Internal utilities
16
- from StreamingCommunity.Src.Util.headers import get_headers
17
- from StreamingCommunity.Src.Util.color import Colors
18
- from StreamingCommunity.Src.Util.console import console, Panel
19
- from StreamingCommunity.Src.Util._jsonConfig import config_manager
20
- from StreamingCommunity.Src.Util.os import internet_manager
16
+ from StreamingCommunity.Util.headers import get_headers
17
+ from StreamingCommunity.Util.color import Colors
18
+ from StreamingCommunity.Util.console import console, Panel
19
+ from StreamingCommunity.Util._jsonConfig import config_manager
20
+ from StreamingCommunity.Util.os import internet_manager
21
21
 
22
22
 
23
23
  # Logic class
@@ -8,9 +8,9 @@ import logging
8
8
 
9
9
 
10
10
  # Internal utilities
11
- from StreamingCommunity.Src.Util.color import Colors
12
- from StreamingCommunity.Src.Util.os import internet_manager
13
- from StreamingCommunity.Src.Util._jsonConfig import config_manager
11
+ from StreamingCommunity.Util.color import Colors
12
+ from StreamingCommunity.Util.os import internet_manager
13
+ from StreamingCommunity.Util._jsonConfig import config_manager
14
14
 
15
15
 
16
16
  # External libraries
@@ -10,7 +10,7 @@ from seleniumbase import Driver
10
10
 
11
11
 
12
12
  # Internal utilities
13
- from StreamingCommunity.Src.Util._jsonConfig import config_manager
13
+ from StreamingCommunity.Util._jsonConfig import config_manager
14
14
 
15
15
 
16
16
  # Config
@@ -7,8 +7,8 @@ import subprocess
7
7
 
8
8
 
9
9
  # Internal utilities
10
- from StreamingCommunity.Src.Util.console import console
11
- from StreamingCommunity.Src.Util.os import internet_manager
10
+ from StreamingCommunity.Util.console import console
11
+ from StreamingCommunity.Util.os import internet_manager
12
12
 
13
13
 
14
14
  # Variable
@@ -8,9 +8,9 @@ from typing import List, Dict
8
8
 
9
9
 
10
10
  # Internal utilities
11
- from StreamingCommunity.Src.Util._jsonConfig import config_manager
12
- from StreamingCommunity.Src.Util.os import os_manager, suppress_output
13
- from StreamingCommunity.Src.Util.console import console
11
+ from StreamingCommunity.Util._jsonConfig import config_manager
12
+ from StreamingCommunity.Util.os import os_manager, suppress_output
13
+ from StreamingCommunity.Util.console import console
14
14
  from .util import need_to_force_to_ts, check_duration_v_a
15
15
  from .capture import capture_ffmpeg_real_time
16
16
  from ..M3U8 import M3U8_Codec
@@ -9,7 +9,7 @@ from typing import Tuple
9
9
 
10
10
 
11
11
  # Internal utilities
12
- from StreamingCommunity.Src.Util.console import console
12
+ from StreamingCommunity.Util.console import console
13
13
 
14
14
 
15
15
  def has_audio_stream(video_path: str) -> bool:
@@ -1,13 +1,14 @@
1
1
  # 03.04.24
2
2
 
3
3
  import sys
4
+ import time
4
5
  import logging
5
6
  import subprocess
6
7
  import importlib.util
7
8
 
8
9
 
9
10
  # Internal utilities
10
- from StreamingCommunity.Src.Util.console import console
11
+ from StreamingCommunity.Util.console import console
11
12
 
12
13
 
13
14
  # Check if Crypto module is installed
@@ -17,8 +18,8 @@ crypto_installed = crypto_spec is not None
17
18
 
18
19
  if crypto_installed:
19
20
  logging.info("Decrypy use: Crypto")
20
- from Crypto.Cipher import AES # type: ignore
21
- from Crypto.Util.Padding import unpad # type: ignore
21
+ from Crypto.Cipher import AES # type: ignore
22
+ from Crypto.Util.Padding import unpad # type: ignore
22
23
 
23
24
  class M3U8_Decryption:
24
25
  """
@@ -34,12 +35,20 @@ if crypto_installed:
34
35
  - method (str): The encryption method.
35
36
  """
36
37
  self.key = key
37
- if "0x" in str(iv):
38
+ self.iv = iv
39
+ if "0x" in str(iv):
38
40
  self.iv = bytes.fromhex(iv.replace("0x", ""))
39
- else:
40
- self.iv = iv
41
41
  self.method = method
42
- logging.info(f"Decrypt add: ('key': {self.key}, 'iv': {self.iv}, 'method': {self.method})")
42
+
43
+ # Precreate cipher based on encryption method
44
+ if self.method == "AES":
45
+ self.cipher = AES.new(self.key, AES.MODE_ECB)
46
+ elif self.method == "AES-128":
47
+ self.cipher = AES.new(self.key[:16], AES.MODE_CBC, iv=self.iv)
48
+ elif self.method == "AES-128-CTR":
49
+ self.cipher = AES.new(self.key[:16], AES.MODE_CTR, nonce=self.iv)
50
+ else:
51
+ raise ValueError("Invalid or unsupported method")
43
52
 
44
53
  def decrypt(self, ciphertext: bytes) -> bytes:
45
54
  """
@@ -51,23 +60,34 @@ if crypto_installed:
51
60
  Returns:
52
61
  bytes: The decrypted content.
53
62
  """
54
- if self.method == "AES":
55
- cipher = AES.new(self.key, AES.MODE_ECB)
56
- decrypted_data = cipher.decrypt(ciphertext)
57
- return unpad(decrypted_data, AES.block_size)
58
-
59
- elif self.method == "AES-128":
60
- cipher = AES.new(self.key[:16], AES.MODE_CBC, iv=self.iv)
61
- decrypted_data = cipher.decrypt(ciphertext)
62
- return unpad(decrypted_data, AES.block_size)
63
+ start = time.perf_counter_ns()
63
64
 
65
+ # Decrypt based on encryption method
66
+ if self.method in {"AES", "AES-128"}:
67
+ decrypted_data = self.cipher.decrypt(ciphertext)
68
+ decrypted_content = unpad(decrypted_data, AES.block_size)
69
+
64
70
  elif self.method == "AES-128-CTR":
65
- cipher = AES.new(self.key[:16], AES.MODE_CTR, nonce=self.iv)
66
- return cipher.decrypt(ciphertext)
67
-
71
+ decrypted_content = self.cipher.decrypt(ciphertext)
68
72
  else:
69
73
  raise ValueError("Invalid or unsupported method")
70
74
 
75
+ end = time.perf_counter_ns()
76
+
77
+ # Calculate elapsed time with high precision
78
+ elapsed_nanoseconds = end - start
79
+ elapsed_milliseconds = elapsed_nanoseconds / 1_000_000
80
+ elapsed_seconds = elapsed_nanoseconds / 1_000_000_000
81
+
82
+ # Print performance metrics
83
+ logging.info(f"[Crypto Decryption Performance]")
84
+ logging.info(f"Method: {self.method}")
85
+ logging.info(f"Decryption Time: {elapsed_milliseconds:.4f} ms ({elapsed_seconds:.6f} s)")
86
+ logging.info(f"Decrypted Content Length: {len(decrypted_content)} bytes")
87
+
88
+ return decrypted_content
89
+
90
+
71
91
  else:
72
92
 
73
93
  # Check if openssl command is available
@@ -95,10 +115,9 @@ else:
95
115
  - method (str): The encryption method.
96
116
  """
97
117
  self.key = key
98
- if "0x" in str(iv):
118
+ self.iv = iv
119
+ if "0x" in str(iv):
99
120
  self.iv = bytes.fromhex(iv.replace("0x", ""))
100
- else:
101
- self.iv = iv
102
121
  self.method = method
103
122
  logging.info(f"Decrypt add: ('key': {self.key}, 'iv': {self.iv}, 'method': {self.method})")
104
123
 
@@ -112,6 +131,9 @@ else:
112
131
  Returns:
113
132
  bytes: The decrypted content.
114
133
  """
134
+ start = time.perf_counter_ns()
135
+
136
+ # Construct OpenSSL command based on encryption method
115
137
  if self.method == "AES":
116
138
  openssl_cmd = f'openssl enc -d -aes-256-ecb -K {self.key.hex()} -nosalt'
117
139
  elif self.method == "AES-128":
@@ -122,8 +144,21 @@ else:
122
144
  raise ValueError("Invalid or unsupported method")
123
145
 
124
146
  try:
125
- decrypted_data = subprocess.check_output(openssl_cmd.split(), input=ciphertext, stderr=subprocess.STDOUT)
147
+ decrypted_content = subprocess.check_output(openssl_cmd.split(), input=ciphertext, stderr=subprocess.STDOUT)
126
148
  except subprocess.CalledProcessError as e:
127
149
  raise ValueError(f"Decryption failed: {e.output.decode()}")
128
150
 
129
- return decrypted_data
151
+ end = time.perf_counter_ns()
152
+
153
+ # Calculate elapsed time with high precision
154
+ elapsed_nanoseconds = end - start
155
+ elapsed_milliseconds = elapsed_nanoseconds / 1_000_000
156
+ elapsed_seconds = elapsed_nanoseconds / 1_000_000_000
157
+
158
+ # Print performance metrics
159
+ logging.info(f"[OpenSSL Decryption Performance]")
160
+ logging.info(f"Method: {self.method}")
161
+ logging.info(f"Decryption Time: {elapsed_milliseconds:.4f} ms ({elapsed_seconds:.6f} s)")
162
+ logging.info(f"Decrypted Content Length: {len(decrypted_content)} bytes")
163
+
164
+ return decrypted_content
@@ -13,9 +13,9 @@ from tqdm import tqdm
13
13
 
14
14
 
15
15
  # Internal utilities
16
- from StreamingCommunity.Src.Util.color import Colors
17
- from StreamingCommunity.Src.Util.os import internet_manager
18
- from StreamingCommunity.Src.Util._jsonConfig import config_manager
16
+ from StreamingCommunity.Util.color import Colors
17
+ from StreamingCommunity.Util.os import internet_manager
18
+ from StreamingCommunity.Util._jsonConfig import config_manager
19
19
 
20
20
 
21
21
  # Variable
@@ -65,18 +65,21 @@ class M3U8_Ts_Estimator:
65
65
  try:
66
66
  io_counters = psutil.net_io_counters()
67
67
  return io_counters
68
+
68
69
  except Exception as e:
69
70
  logging.warning(f"Unable to access network I/O counters: {e}")
70
71
  return None
71
72
 
72
73
  while True:
73
74
  old_value = get_network_io()
75
+
74
76
  if old_value is None: # If psutil is not available, continue with default values
75
77
  time.sleep(interval)
76
78
  continue
77
79
 
78
80
  time.sleep(interval)
79
81
  new_value = get_network_io()
82
+
80
83
  if new_value is None: # Handle again if psutil fails in the next call
81
84
  time.sleep(interval)
82
85
  continue
@@ -6,7 +6,7 @@ import logging
6
6
 
7
7
  # Internal utilities
8
8
  from m3u8 import loads
9
- from StreamingCommunity.Src.Util.os import internet_manager
9
+ from StreamingCommunity.Util.os import internet_manager
10
10
 
11
11
 
12
12
  # External libraries
@@ -11,7 +11,7 @@ from rich.console import Console
11
11
 
12
12
  # Internal utilities
13
13
  from .obj_tmbd import Json_film
14
- from StreamingCommunity.Src.Util.table import TVShowManager
14
+ from StreamingCommunity.Util.table import TVShowManager
15
15
 
16
16
 
17
17
  # Variable
@@ -1,12 +1,13 @@
1
1
  # 01.03.2023
2
2
 
3
3
  import os
4
+ import sys
4
5
  import time
5
6
 
6
7
 
7
8
  # Internal utilities
8
9
  from .version import __version__, __author__, __title__
9
- from StreamingCommunity.Src.Util.console import console
10
+ from StreamingCommunity.Util.console import console
10
11
 
11
12
 
12
13
  # External library
@@ -14,7 +15,10 @@ import httpx
14
15
 
15
16
 
16
17
  # Variable
17
- main = os.path.abspath(os.path.dirname(__file__))
18
+ if getattr(sys, 'frozen', False): # Modalità PyInstaller
19
+ base_path = os.path.join(sys._MEIPASS, "StreamingCommunity")
20
+ else:
21
+ base_path = os.path.dirname(__file__)
18
22
 
19
23
 
20
24
  def update():
@@ -1,5 +1,5 @@
1
1
  __title__ = 'StreamingCommunity'
2
- __version__ = 'v1.8.0'
2
+ __version__ = 'v1.9.0'
3
3
  __author__ = 'Lovi-0'
4
4
  __description__ = 'A command-line program to download film'
5
5
  __copyright__ = 'Copyright 2024'