StreamingCommunity 2.9.4__py3-none-any.whl → 2.9.6__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 (48) hide show
  1. StreamingCommunity/Api/Player/sweetpixel.py +49 -0
  2. StreamingCommunity/Api/Site/1337xx/__init__.py +26 -12
  3. StreamingCommunity/Api/Site/1337xx/site.py +5 -4
  4. StreamingCommunity/Api/Site/1337xx/title.py +4 -6
  5. StreamingCommunity/Api/Site/altadefinizione/__init__.py +64 -17
  6. StreamingCommunity/Api/Site/altadefinizione/film.py +32 -2
  7. StreamingCommunity/Api/Site/altadefinizione/series.py +54 -10
  8. StreamingCommunity/Api/Site/altadefinizione/site.py +25 -7
  9. StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py +2 -2
  10. StreamingCommunity/Api/Site/animeunity/__init__.py +53 -32
  11. StreamingCommunity/Api/Site/animeunity/film_serie.py +8 -5
  12. StreamingCommunity/Api/Site/animeunity/site.py +4 -6
  13. StreamingCommunity/Api/Site/animeworld/__init__.py +71 -0
  14. StreamingCommunity/Api/Site/animeworld/serie.py +107 -0
  15. StreamingCommunity/Api/Site/animeworld/site.py +111 -0
  16. StreamingCommunity/Api/Site/animeworld/util/ScrapeSerie.py +79 -0
  17. StreamingCommunity/Api/Site/cb01new/__init__.py +26 -14
  18. StreamingCommunity/Api/Site/cb01new/film.py +1 -1
  19. StreamingCommunity/Api/Site/cb01new/site.py +9 -7
  20. StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py +26 -15
  21. StreamingCommunity/Api/Site/ddlstreamitaly/series.py +2 -2
  22. StreamingCommunity/Api/Site/ddlstreamitaly/site.py +3 -3
  23. StreamingCommunity/Api/Site/guardaserie/__init__.py +23 -11
  24. StreamingCommunity/Api/Site/guardaserie/series.py +1 -1
  25. StreamingCommunity/Api/Site/guardaserie/site.py +5 -4
  26. StreamingCommunity/Api/Site/mostraguarda/__init__.py +27 -7
  27. StreamingCommunity/Api/Site/mostraguarda/film.py +1 -1
  28. StreamingCommunity/Api/Site/streamingcommunity/__init__.py +50 -27
  29. StreamingCommunity/Api/Site/streamingcommunity/film.py +1 -1
  30. StreamingCommunity/Api/Site/streamingcommunity/series.py +6 -3
  31. StreamingCommunity/Api/Site/streamingcommunity/site.py +7 -3
  32. StreamingCommunity/Lib/Downloader/HLS/segments.py +2 -4
  33. StreamingCommunity/Lib/Downloader/MP4/downloader.py +7 -6
  34. StreamingCommunity/Lib/Downloader/TOR/downloader.py +397 -227
  35. StreamingCommunity/Lib/FFmpeg/util.py +12 -0
  36. StreamingCommunity/Lib/M3U8/estimator.py +5 -8
  37. StreamingCommunity/Upload/version.py +1 -1
  38. StreamingCommunity/Util/config_json.py +2 -8
  39. StreamingCommunity/Util/table.py +12 -2
  40. StreamingCommunity/global_search.py +315 -0
  41. StreamingCommunity/run.py +39 -5
  42. {streamingcommunity-2.9.4.dist-info → streamingcommunity-2.9.6.dist-info}/METADATA +42 -15
  43. streamingcommunity-2.9.6.dist-info/RECORD +85 -0
  44. {streamingcommunity-2.9.4.dist-info → streamingcommunity-2.9.6.dist-info}/WHEEL +1 -1
  45. streamingcommunity-2.9.4.dist-info/RECORD +0 -79
  46. {streamingcommunity-2.9.4.dist-info → streamingcommunity-2.9.6.dist-info}/entry_points.txt +0 -0
  47. {streamingcommunity-2.9.4.dist-info → streamingcommunity-2.9.6.dist-info/licenses}/LICENSE +0 -0
  48. {streamingcommunity-2.9.4.dist-info → streamingcommunity-2.9.6.dist-info}/top_level.txt +0 -0
@@ -27,12 +27,12 @@ table_show_manager = TVShowManager()
27
27
  max_timeout = config_manager.get_int("REQUESTS", "timeout")
28
28
 
29
29
 
30
- def title_search(word_to_search: str) -> int:
30
+ def title_search(query: str) -> int:
31
31
  """
32
32
  Search for titles based on a search query.
33
33
 
34
34
  Parameters:
35
- - title_search (str): The title to search for.
35
+ - query (str): The query to search for.
36
36
 
37
37
  Returns:
38
38
  - int: The number of titles found.
@@ -40,7 +40,7 @@ def title_search(word_to_search: str) -> int:
40
40
  media_search_manager.clear()
41
41
  table_show_manager.clear()
42
42
 
43
- search_url = f"{site_constant.FULL_URL}/?story={word_to_search}&do=search&subaction=search"
43
+ search_url = f"{site_constant.FULL_URL}/?s={query}"
44
44
  console.print(f"[cyan]Search url: [yellow]{search_url}")
45
45
 
46
46
  try:
@@ -54,14 +54,16 @@ def title_search(word_to_search: str) -> int:
54
54
  # Create soup and find table
55
55
  soup = BeautifulSoup(response.text, "html.parser")
56
56
 
57
- for div in soup.find_all("div", class_ = "short-main"):
57
+ for card in soup.find_all("div", class_=["card", "mp-post", "horizontal"]):
58
58
  try:
59
- url = div.find("a").get("href")
60
- title = div.find("a").get_text(strip=True)
59
+ title_tag = card.find("h3", class_="card-title").find("a")
60
+ url = title_tag.get("href")
61
+ title = title_tag.get_text(strip=True)
61
62
 
62
63
  title_info = {
63
64
  'name': title,
64
- 'url': url
65
+ 'url': url,
66
+ 'type': 'film'
65
67
  }
66
68
 
67
69
  media_search_manager.add_media(title_info)
@@ -12,6 +12,7 @@ from rich.prompt import Prompt
12
12
  # Internal utilities
13
13
  from StreamingCommunity.Api.Template import get_select_title
14
14
  from StreamingCommunity.Api.Template.config_loader import site_constant
15
+ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
15
16
 
16
17
 
17
18
  # Logic class
@@ -30,10 +31,28 @@ msg = Prompt()
30
31
  console = Console()
31
32
 
32
33
 
33
- def search(string_to_search: str = None, get_onylDatabase: bool = False):
34
+ def process_search_result(select_title):
34
35
  """
35
- Main function of the application for film and series.
36
+ Handles the search result and initiates the download for either a film or series.
36
37
  """
38
+ if "Serie TV" in str(select_title.type):
39
+ download_thread(select_title)
40
+ else:
41
+ logging.error(f"Not supported: {select_title.type}")
42
+
43
+ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None):
44
+ """
45
+ Main function of the application for search film, series and anime.
46
+
47
+ Parameters:
48
+ string_to_search (str, optional): String to search for
49
+ get_onylDatabase (bool, optional): If True, return only the database object
50
+ direct_item (dict, optional): Direct item to process (bypass search)
51
+ """
52
+ if direct_item:
53
+ select_title = MediaItem(**direct_item)
54
+ process_search_result(select_title)
55
+ return
37
56
 
38
57
  if string_to_search is None:
39
58
  string_to_search = msg.ask(f"\n[purple]Insert word to search in [green]{site_constant.SITE_NAME}").strip()
@@ -41,24 +60,16 @@ def search(string_to_search: str = None, get_onylDatabase: bool = False):
41
60
  # Search on database
42
61
  len_database = title_search(quote_plus(string_to_search))
43
62
 
44
- # Return list of elements
45
- if get_onylDatabase:
63
+ # If only the database is needed, return the manager
64
+ if get_onlyDatabase:
46
65
  return media_search_manager
47
66
 
48
67
  if len_database > 0:
49
-
50
- # Select title from list
51
68
  select_title = get_select_title(table_show_manager, media_search_manager)
52
-
53
- # Download only film
54
- if "Serie TV" in str(select_title.type):
55
- download_thread(select_title)
56
-
57
- else:
58
- logging.error(f"Not supported: {select_title.type}")
69
+ process_search_result(select_title)
59
70
 
60
71
  else:
72
+
73
+ # If no results are found, ask again
61
74
  console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
62
-
63
- # Retry
64
75
  search()
@@ -51,8 +51,8 @@ def download_video(index_episode_selected: int, scape_info_serie: GetSerieInfo,
51
51
 
52
52
  # Get info about episode
53
53
  obj_episode = scape_info_serie.list_episodes[index_episode_selected - 1]
54
- console.print(f"[yellow]Download: [red]{obj_episode.get('name')}\n")
55
-
54
+ console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [bold magenta]{obj_episode.get('name')}[/bold magenta] ([cyan]E{index_episode_selected}[/cyan]) \n")
55
+
56
56
  # Define filename and path for the downloaded video
57
57
  title_name = os_manager.get_sanitize_file(
58
58
  f"{map_episode_title(scape_info_serie.tv_name, None, index_episode_selected, obj_episode.get('name'))}.mp4"
@@ -28,12 +28,12 @@ table_show_manager = TVShowManager()
28
28
  max_timeout = config_manager.get_int("REQUESTS", "timeout")
29
29
 
30
30
 
31
- def title_search(word_to_search: str) -> int:
31
+ def title_search(query: str) -> int:
32
32
  """
33
33
  Search for titles based on a search query.
34
34
 
35
35
  Parameters:
36
- - title_search (str): The title to search for.
36
+ - query (str): The query to search for.
37
37
 
38
38
  Returns:
39
39
  - int: The number of titles found.
@@ -41,7 +41,7 @@ def title_search(word_to_search: str) -> int:
41
41
  media_search_manager.clear()
42
42
  table_show_manager.clear()
43
43
 
44
- search_url = f"{site_constant.FULL_URL}/search/?&q={word_to_search}&quick=1&type=videobox_video&nodes=11"
44
+ search_url = f"{site_constant.FULL_URL}/search/?&q={query}&quick=1&type=videobox_video&nodes=11"
45
45
  console.print(f"[cyan]Search url: [yellow]{search_url}")
46
46
 
47
47
  try:
@@ -11,6 +11,7 @@ from rich.prompt import Prompt
11
11
  # Internal utilities
12
12
  from StreamingCommunity.Api.Template import get_select_title
13
13
  from StreamingCommunity.Api.Template.config_loader import site_constant
14
+ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
14
15
 
15
16
 
16
17
  # Logic class
@@ -29,10 +30,25 @@ msg = Prompt()
29
30
  console = Console()
30
31
 
31
32
 
32
- def search(string_to_search: str = None, get_onylDatabase: bool = False):
33
+ def process_search_result(select_title):
33
34
  """
34
- Main function of the application for film and series.
35
+ Handles the search result and initiates the download for either a film or series.
35
36
  """
37
+ download_series(select_title)
38
+
39
+ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None):
40
+ """
41
+ Main function of the application for search film, series and anime.
42
+
43
+ Parameters:
44
+ string_to_search (str, optional): String to search for
45
+ get_onylDatabase (bool, optional): If True, return only the database object
46
+ direct_item (dict, optional): Direct item to process (bypass search)
47
+ """
48
+ if direct_item:
49
+ select_title = MediaItem(**direct_item)
50
+ process_search_result(select_title)
51
+ return
36
52
 
37
53
  if string_to_search is None:
38
54
  string_to_search = msg.ask(f"\n[purple]Insert word to search in [green]{site_constant.SITE_NAME}").strip()
@@ -40,20 +56,16 @@ def search(string_to_search: str = None, get_onylDatabase: bool = False):
40
56
  # Search on database
41
57
  len_database = title_search(quote_plus(string_to_search))
42
58
 
43
- # Return list of elements
44
- if get_onylDatabase:
59
+ # If only the database is needed, return the manager
60
+ if get_onlyDatabase:
45
61
  return media_search_manager
46
62
 
47
63
  if len_database > 0:
48
-
49
- # Select title from list
50
64
  select_title = get_select_title(table_show_manager, media_search_manager)
51
-
52
- # Download only film
53
- download_series(select_title)
65
+ process_search_result(select_title)
54
66
 
55
67
  else:
56
- console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
57
68
 
58
- # Retry
69
+ # If no results are found, ask again
70
+ console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
59
71
  search()
@@ -55,7 +55,7 @@ def download_video(index_season_selected: int, index_episode_selected: int, scap
55
55
 
56
56
  # Get info about episode
57
57
  obj_episode = scape_info_serie.list_episodes[index_episode_selected - 1]
58
- console.print(f"[yellow]Download: [red]{index_season_selected}:{index_episode_selected} {obj_episode.get('name')}\n")
58
+ console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [bold magenta]{obj_episode.get('name')}[/bold magenta] ([cyan]S{index_season_selected}E{index_episode_selected}[/cyan]) \n")
59
59
 
60
60
  # Define filename and path for the downloaded video
61
61
  mp4_name = f"{map_episode_title(scape_info_serie.tv_name, index_season_selected, index_episode_selected, obj_episode.get('name'))}.mp4"
@@ -27,12 +27,12 @@ max_timeout = config_manager.get_int("REQUESTS", "timeout")
27
27
 
28
28
 
29
29
 
30
- def title_search(word_to_search: str) -> int:
30
+ def title_search(query: str) -> int:
31
31
  """
32
32
  Search for titles based on a search query.
33
33
 
34
34
  Parameters:
35
- - title_search (str): The title to search for.
35
+ - query (str): The query to search for.
36
36
 
37
37
  Returns:
38
38
  - int: The number of titles found.
@@ -40,7 +40,7 @@ def title_search(word_to_search: str) -> int:
40
40
  media_search_manager.clear()
41
41
  table_show_manager.clear()
42
42
 
43
- search_url = f"{site_constant.FULL_URL}/?story={word_to_search}&do=search&subaction=search"
43
+ search_url = f"{site_constant.FULL_URL}/?story={query}&do=search&subaction=search"
44
44
  console.print(f"[cyan]Search url: [yellow]{search_url}")
45
45
 
46
46
  try:
@@ -63,7 +63,8 @@ def title_search(word_to_search: str) -> int:
63
63
 
64
64
  serie_info = {
65
65
  'name': title,
66
- 'url': link
66
+ 'url': link,
67
+ 'type': 'tv'
67
68
  }
68
69
 
69
70
  media_search_manager.add_media(serie_info)
@@ -5,12 +5,16 @@ from urllib.parse import quote_plus
5
5
 
6
6
  # External library
7
7
  from rich.console import Console
8
- from rich.prompt import Prompt, Confirm
8
+ from rich.prompt import Prompt
9
9
 
10
10
 
11
- # Logic class
11
+ # Internal utilities
12
12
  from StreamingCommunity.Api.Template.config_loader import site_constant
13
+ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
13
14
  from StreamingCommunity.Lib.TMBD import tmdb, Json_film
15
+
16
+
17
+ # Logic class
14
18
  from .film import download_film
15
19
 
16
20
 
@@ -25,16 +29,32 @@ msg = Prompt()
25
29
  console = Console()
26
30
 
27
31
 
28
- def search(string_to_search: str = None, get_onylDatabase: bool = False):
32
+ def process_search_result(select_title):
29
33
  """
30
- Main function of the application for film and series.
34
+ Handles the search result and initiates the download for either a film or series.
31
35
  """
36
+ download_film(select_title)
37
+
38
+
39
+ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None):
40
+ """
41
+ Main function of the application for search film, series and anime.
42
+
43
+ Parameters:
44
+ string_to_search (str, optional): String to search for
45
+ get_onylDatabase (bool, optional): If True, return only the database object
46
+ direct_item (dict, optional): Direct item to process (bypass search)
47
+ """
48
+ if direct_item:
49
+ select_title = MediaItem(**direct_item)
50
+ process_search_result(select_title)
51
+ return
32
52
 
33
53
  if string_to_search is None:
34
54
  string_to_search = msg.ask(f"\n[purple]Insert word to search in [green]{site_constant.SITE_NAME}").strip()
35
55
 
36
56
  # Not available for the moment
37
- if get_onylDatabase:
57
+ if get_onlyDatabase:
38
58
  return 0
39
59
 
40
60
  # Search on database
@@ -47,7 +67,7 @@ def search(string_to_search: str = None, get_onylDatabase: bool = False):
47
67
  download_film(movie_details)
48
68
 
49
69
  else:
50
- console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
51
70
 
52
- # Retry
71
+ # If no results are found, ask again
72
+ console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
53
73
  search()
@@ -44,7 +44,7 @@ def download_film(movie_details: Json_film) -> str:
44
44
 
45
45
  # Start message and display film information
46
46
  start_message()
47
- console.print(f"[yellow]Download: [red]{movie_details.title} \n")
47
+ console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [cyan]{movie_details.title}[/cyan] \n")
48
48
 
49
49
  # Make request to main site
50
50
  try:
@@ -12,11 +12,12 @@ from rich.prompt import Prompt
12
12
 
13
13
  # Internal utilities
14
14
  from StreamingCommunity.Api.Template import get_select_title
15
+ from StreamingCommunity.Api.Template.config_loader import site_constant
16
+ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
15
17
  from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
16
18
 
17
19
 
18
20
  # Logic class
19
- from StreamingCommunity.Api.Template.config_loader import site_constant
20
21
  from .site import title_search, table_show_manager, media_search_manager
21
22
  from .film import download_film
22
23
  from .series import download_series
@@ -33,54 +34,76 @@ msg = Prompt()
33
34
  console = Console()
34
35
 
35
36
 
36
- def search(string_to_search: str = None, get_onylDatabase: bool = False):
37
+ def get_user_input(string_to_search: str = None):
37
38
  """
38
- Main function of the application for film and series.
39
+ Asks the user to input a search term.
40
+ Handles both Telegram bot input and direct input.
39
41
  """
40
- if site_constant.TELEGRAM_BOT:
41
- bot = get_bot_instance()
42
-
43
- if string_to_search is None:
44
-
45
- # Chiedi la scelta all'utente con il bot Telegram
42
+ if string_to_search is None:
43
+ if site_constant.TELEGRAM_BOT:
44
+ bot = get_bot_instance()
46
45
  string_to_search = bot.ask(
47
46
  "key_search",
48
- f"Inserisci la parola da cercare\noppure back per tornare alla scelta: ",
47
+ f"Enter the search term\nor type 'back' to return to the menu: ",
49
48
  None
50
49
  )
51
50
 
52
51
  if string_to_search == 'back':
53
- # Riavvia lo script
54
- # Chiude il processo attuale e avvia una nuova istanza dello script
52
+
53
+ # Restart the script
55
54
  subprocess.Popen([sys.executable] + sys.argv)
56
55
  sys.exit()
57
-
56
+ else:
57
+ string_to_search = msg.ask(f"\n[purple]Insert a word to search in [green]{site_constant.SITE_NAME}").strip()
58
+
59
+ return string_to_search
60
+
61
+ def process_search_result(select_title):
62
+ """
63
+ Handles the search result and initiates the download for either a film or series.
64
+ """
65
+ if select_title.type == 'tv':
66
+ download_series(select_title)
58
67
  else:
59
- if string_to_search is None:
60
- string_to_search = msg.ask(f"\n[purple]Insert word to search in [green]{site_constant.SITE_NAME}").strip()
68
+ download_film(select_title)
61
69
 
70
+ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None):
71
+ """
72
+ Main function of the application for search film, series and anime.
73
+
74
+ Parameters:
75
+ string_to_search (str, optional): String to search for
76
+ get_onylDatabase (bool, optional): If True, return only the database object
77
+ direct_item (dict, optional): Direct item to process (bypass search)
78
+ """
79
+ if direct_item:
80
+ select_title = MediaItem(**direct_item)
81
+ process_search_result(select_title)
82
+ return
83
+
84
+ # Get the user input for the search term
85
+ string_to_search = get_user_input(string_to_search)
86
+
87
+ # Perform the database search
62
88
  len_database = title_search(quote_plus(string_to_search))
63
89
 
64
- # Return list of elements
65
- if get_onylDatabase:
90
+ # If only the database is needed, return the manager
91
+ if get_onlyDatabase:
66
92
  return media_search_manager
67
93
 
94
+ if site_constant.TELEGRAM_BOT:
95
+ bot = get_bot_instance()
96
+
68
97
  if len_database > 0:
69
-
70
- # Select title from list
71
98
  select_title = get_select_title(table_show_manager, media_search_manager)
72
-
73
- if select_title.type == 'tv':
74
- download_series(select_title)
75
-
76
- else:
77
- download_film(select_title)
99
+ process_search_result(select_title)
78
100
 
79
101
  else:
80
102
  console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
81
103
 
82
104
  if site_constant.TELEGRAM_BOT:
83
- bot.send_message(f"Nessun risultato trovato riprova", None)
105
+ bot.send_message(f"No results found, please try again", None)
84
106
 
85
- # Retry
107
+ # If no results are found, ask again
108
+ string_to_search = get_user_input()
86
109
  search()
@@ -52,7 +52,7 @@ def download_film(select_title: MediaItem) -> str:
52
52
 
53
53
  # Start message and display film information
54
54
  start_message()
55
- console.print(f"[yellow]Download: [red]{select_title.name} \n")
55
+ console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [cyan]{select_title.name}[/cyan] \n")
56
56
 
57
57
  # Init class
58
58
  video_source = VideoSource(site_constant.FULL_URL, False)
@@ -61,8 +61,7 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
61
61
 
62
62
  # Get info about episode
63
63
  obj_episode = season.episodes.get(index_episode_selected - 1)
64
- console.print(f"[yellow]Download: [red]{index_season_selected}:{index_episode_selected} {obj_episode.name}")
65
- print()
64
+ console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [bold magenta]{obj_episode.name}[/bold magenta] ([cyan]S{index_season_selected}E{index_episode_selected}[/cyan]) \n")
66
65
 
67
66
  if site_constant.TELEGRAM_BOT:
68
67
  bot = get_bot_instance()
@@ -185,7 +184,11 @@ def download_series(select_season: MediaItem) -> None:
185
184
 
186
185
  index_season_selected = bot.ask(
187
186
  "select_title_episode",
188
- "Inserisci il numero della stagione (es. 1), * per scaricare tutte le stagioni, (es. 1-2) per un intervallo di stagioni, o (es. 3-*) per scaricare dalla stagione specificata fino alla fine",
187
+ "Menu di selezione delle stagioni\n\n"
188
+ "- Inserisci il numero della stagione (ad esempio, 1)\n"
189
+ "- Inserisci * per scaricare tutte le stagioni\n"
190
+ "- Inserisci un intervallo di stagioni (ad esempio, 1-2) per scaricare da una stagione all'altra\n"
191
+ "- Inserisci (ad esempio, 3-*) per scaricare dalla stagione specificata fino alla fine della serie",
189
192
  None
190
193
  )
191
194
 
@@ -27,12 +27,12 @@ table_show_manager = TVShowManager()
27
27
  max_timeout = config_manager.get_int("REQUESTS", "timeout")
28
28
 
29
29
 
30
- def title_search(title_search: str) -> int:
30
+ def title_search(query: str) -> int:
31
31
  """
32
32
  Search for titles based on a search query.
33
33
 
34
34
  Parameters:
35
- - title_search (str): The title to search for.
35
+ - query (str): The query to search for.
36
36
 
37
37
  Returns:
38
38
  int: The number of titles found.
@@ -43,7 +43,7 @@ def title_search(title_search: str) -> int:
43
43
  media_search_manager.clear()
44
44
  table_show_manager.clear()
45
45
 
46
- search_url = f"{site_constant.FULL_URL}/api/search?q={title_search}"
46
+ search_url = f"{site_constant.FULL_URL}/api/search?q={query}"
47
47
  console.print(f"[cyan]Search url: [yellow]{search_url}")
48
48
 
49
49
  try:
@@ -52,6 +52,8 @@ def title_search(title_search: str) -> int:
52
52
 
53
53
  except Exception as e:
54
54
  console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
55
+ if site_constant.TELEGRAM_BOT:
56
+ bot.send_message(f"ERRORE\n\nErrore nella richiesta di ricerca:\n\n{e}", None)
55
57
  return 0
56
58
 
57
59
  # Prepara le scelte per l'utente
@@ -82,6 +84,8 @@ def title_search(title_search: str) -> int:
82
84
 
83
85
  except Exception as e:
84
86
  print(f"Error parsing a film entry: {e}")
87
+ if site_constant.TELEGRAM_BOT:
88
+ bot.send_message(f"ERRORE\n\nErrore nell'analisi del film:\n\n{e}", None)
85
89
 
86
90
  if site_constant.TELEGRAM_BOT:
87
91
  if choices:
@@ -37,7 +37,7 @@ from ...M3U8 import (
37
37
  # Config
38
38
  TQDM_DELAY_WORKER = config_manager.get_float('M3U8_DOWNLOAD', 'tqdm_delay')
39
39
  REQUEST_MAX_RETRY = config_manager.get_int('REQUESTS', 'max_retry')
40
- REQUEST_VERIFY = config_manager.get_int('REQUESTS', 'verify')
40
+ REQUEST_VERIFY = config_manager.get_bool('REQUESTS', 'verify')
41
41
  DEFAULT_VIDEO_WORKERS = config_manager.get_int('M3U8_DOWNLOAD', 'default_video_workser')
42
42
  DEFAULT_AUDIO_WORKERS = config_manager.get_int('M3U8_DOWNLOAD', 'default_audio_workser')
43
43
  MAX_TIMEOOUT = config_manager.get_int("REQUESTS", "timeout")
@@ -223,14 +223,12 @@ class M3U8_Segments:
223
223
 
224
224
  try:
225
225
  with self._get_http_client() as client:
226
- start_time = time.time()
227
226
  response = client.get(ts_url)
228
227
 
229
228
  # Validate response and content
230
229
  response.raise_for_status()
231
230
  segment_content = response.content
232
231
  content_size = len(segment_content)
233
- duration = time.time() - start_time
234
232
 
235
233
  # Decrypt if needed and verify decrypted content
236
234
  if self.decryption is not None:
@@ -243,7 +241,7 @@ class M3U8_Segments:
243
241
  self.stop_event.set() # Trigger the stopping event for all threads
244
242
  break # Stop the current task immediately
245
243
 
246
- self.class_ts_estimator.update_progress_bar(content_size, duration, progress_bar)
244
+ self.class_ts_estimator.update_progress_bar(content_size, progress_bar)
247
245
  self.queue.put((index, segment_content))
248
246
  self.downloaded_segments.add(index)
249
247
  progress_bar.update(1)
@@ -31,7 +31,6 @@ from ...FFmpeg import print_duration_table
31
31
 
32
32
  # Config
33
33
  REQUEST_VERIFY = config_manager.get_bool('REQUESTS', 'verify')
34
- REQUEST_HTTP2 = config_manager.get_bool('REQUESTS', 'http2')
35
34
  GET_ONLY_LINK = config_manager.get_bool('M3U8_PARSER', 'get_only_link')
36
35
  REQUEST_TIMEOUT = config_manager.get_float('REQUESTS', 'timeout')
37
36
  TELEGRAM_BOT = config_manager.get_bool('DEFAULT', 'telegram_bot')
@@ -111,11 +110,12 @@ def MP4_downloader(url: str, path: str, referer: str = None, headers_: dict = No
111
110
  interrupt_handler = InterruptHandler()
112
111
  original_handler = signal.signal(signal.SIGINT, partial(signal_handler, interrupt_handler=interrupt_handler, original_handler=signal.getsignal(signal.SIGINT)))
113
112
 
113
+ # Ensure the output directory exists
114
+ os.makedirs(os.path.dirname(path), exist_ok=True)
115
+
114
116
  try:
115
- transport = httpx.HTTPTransport(verify=REQUEST_VERIFY, http2=REQUEST_HTTP2)
116
-
117
- with httpx.Client(transport=transport, timeout=httpx.Timeout(60)) as client:
118
- with client.stream("GET", url, headers=headers, timeout=REQUEST_TIMEOUT) as response:
117
+ with httpx.Client() as client:
118
+ with client.stream("GET", url, headers=headers) as response:
119
119
  response.raise_for_status()
120
120
  total = int(response.headers.get('content-length', 0))
121
121
 
@@ -123,6 +123,7 @@ def MP4_downloader(url: str, path: str, referer: str = None, headers_: dict = No
123
123
  console.print("[bold red]No video stream found.[/bold red]")
124
124
  return None, False
125
125
 
126
+ # Create a fancy progress bar
126
127
  progress_bar = tqdm(
127
128
  total=total,
128
129
  ascii='░▒█',
@@ -135,7 +136,7 @@ def MP4_downloader(url: str, path: str, referer: str = None, headers_: dict = No
135
136
  unit_scale=True,
136
137
  desc='Downloading',
137
138
  mininterval=0.05,
138
- file=sys.stdout # Using file=sys.stdout to force in-place updates because sys.stderr may not support carriage returns in this environment.
139
+ file=sys.stdout # Using file=sys.stdout to force in-place updates because sys.stderr may not support carriage returns in this environment.
139
140
  )
140
141
 
141
142
  downloaded = 0