StreamingCommunity 2.9.3__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 (33) hide show
  1. StreamingCommunity/Api/Player/Helper/Vixcloud/util.py +40 -38
  2. StreamingCommunity/Api/Player/maxstream.py +3 -11
  3. StreamingCommunity/Api/Site/1337xx/site.py +1 -9
  4. StreamingCommunity/Api/Site/altadefinizione/__init__.py +61 -0
  5. StreamingCommunity/Api/Site/altadefinizione/film.py +98 -0
  6. StreamingCommunity/Api/Site/altadefinizione/series.py +164 -0
  7. StreamingCommunity/Api/Site/altadefinizione/site.py +75 -0
  8. StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py +72 -0
  9. StreamingCommunity/Api/Site/animeunity/film_serie.py +1 -1
  10. StreamingCommunity/Api/Site/animeunity/site.py +1 -9
  11. StreamingCommunity/Api/Site/cb01new/site.py +5 -16
  12. StreamingCommunity/Api/Site/ddlstreamitaly/site.py +1 -9
  13. StreamingCommunity/Api/Site/guardaserie/site.py +1 -9
  14. StreamingCommunity/Api/Site/streamingcommunity/series.py +29 -11
  15. StreamingCommunity/Api/Site/streamingcommunity/site.py +10 -10
  16. StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +38 -17
  17. StreamingCommunity/Api/Template/Class/SearchType.py +1 -1
  18. StreamingCommunity/Api/Template/Util/__init__.py +0 -1
  19. StreamingCommunity/Api/Template/Util/manage_ep.py +1 -0
  20. StreamingCommunity/Api/Template/config_loader.py +0 -4
  21. StreamingCommunity/Lib/Downloader/HLS/downloader.py +2 -2
  22. StreamingCommunity/Lib/Downloader/MP4/downloader.py +3 -2
  23. StreamingCommunity/Lib/M3U8/estimator.py +3 -3
  24. StreamingCommunity/Upload/version.py +1 -1
  25. StreamingCommunity/Util/config_json.py +0 -3
  26. StreamingCommunity/__init__.py +6 -0
  27. {StreamingCommunity-2.9.3.dist-info → streamingcommunity-2.9.4.dist-info}/METADATA +90 -7
  28. {StreamingCommunity-2.9.3.dist-info → streamingcommunity-2.9.4.dist-info}/RECORD +32 -28
  29. {StreamingCommunity-2.9.3.dist-info → streamingcommunity-2.9.4.dist-info}/WHEEL +1 -1
  30. StreamingCommunity/Api/Template/Util/get_domain.py +0 -100
  31. {StreamingCommunity-2.9.3.dist-info → streamingcommunity-2.9.4.dist-info}/LICENSE +0 -0
  32. {StreamingCommunity-2.9.3.dist-info → streamingcommunity-2.9.4.dist-info}/entry_points.txt +0 -0
  33. {StreamingCommunity-2.9.3.dist-info → streamingcommunity-2.9.4.dist-info}/top_level.txt +0 -0
@@ -11,6 +11,7 @@ class Episode:
11
11
  self.number: int = data.get('number', 1)
12
12
  self.name: str = data.get('name', '')
13
13
  self.duration: int = data.get('duration', 0)
14
+ self.url: str = data.get('url', '')
14
15
 
15
16
  def __str__(self):
16
17
  return f"Episode(id={self.id}, number={self.number}, name='{self.name}', duration={self.duration} sec)"
@@ -35,69 +36,70 @@ class EpisodeManager:
35
36
 
36
37
  Parameters:
37
38
  - index (int): The zero-based index of the episode to retrieve.
38
-
39
- Returns:
40
- Episode: The Episode object at the specified index.
41
39
  """
42
40
  return self.episodes[index]
43
41
 
44
- def length(self) -> int:
45
- """
46
- Get the number of episodes in the manager.
47
-
48
- Returns:
49
- int: Number of episodes.
50
- """
51
- return len(self.episodes)
52
-
53
42
  def clear(self) -> None:
54
43
  """
55
44
  This method clears the episodes list.
56
-
57
- Parameters:
58
- - self: The object instance.
59
45
  """
60
46
  self.episodes.clear()
61
47
 
48
+ def __len__(self) -> int:
49
+ """
50
+ Get the number of episodes in the manager.
51
+ """
52
+ return len(self.episodes)
53
+
62
54
  def __str__(self):
63
55
  return f"EpisodeManager(num_episodes={len(self.episodes)})"
64
56
 
65
57
 
66
- class SeasonData:
58
+ class Season:
67
59
  def __init__(self, data: Dict[str, Any]):
68
60
  self.id: int = data.get('id', 0)
69
61
  self.number: int = data.get('number', 0)
62
+ self.name: str = data.get('name', '')
63
+ self.slug: str = data.get('slug', '')
64
+ self.type: str = data.get('type', '')
65
+ self.episodes: EpisodeManager = EpisodeManager()
70
66
 
71
67
  def __str__(self):
72
- return f"SeasonData(id={self.id}, number={self.number}, name='{self.name}'"
68
+ return f"Season(id={self.id}, number={self.number}, name='{self.name}', episodes={self.episodes.length()})"
69
+
73
70
 
74
71
  class SeasonManager:
75
72
  def __init__(self):
76
- self.seasons: List[SeasonData] = []
73
+ self.seasons: List[Season] = []
77
74
 
78
- def add_season(self, season_data):
79
- season = SeasonData(season_data)
75
+ def add_season(self, season_data: Dict[str, Any]) -> Season:
76
+ """
77
+ Add a new season to the manager and return it.
78
+
79
+ Parameters:
80
+ - season_data (Dict[str, Any]): A dictionary containing data for the new season.
81
+ """
82
+ season = Season(season_data)
80
83
  self.seasons.append(season)
84
+ return season
81
85
 
82
- def get_season_by_number(self, number: int) -> Optional[Dict]:
83
- return self.seasons[number]
84
-
85
- class Season:
86
- def __init__(self, season_data: Dict[str, Union[int, str, None]]):
87
- self.season_data = season_data
88
-
89
- self.id: int = season_data.get('id', 0)
90
- self.number: int = season_data.get('number', 0)
91
- self.name: str = season_data.get('name', '')
92
- self.slug: str = season_data.get('slug', '')
93
- self.type: str = season_data.get('type', '')
94
- self.seasons_count: int = season_data.get('seasons_count', 0)
86
+ def get_season_by_number(self, number: int) -> Optional[Season]:
87
+ """
88
+ Get a season by its number.
95
89
 
96
- self.episodes: EpisodeManager = EpisodeManager()
97
-
98
- self.seasonsData: SeasonManager = SeasonManager()
99
- for element in season_data['seasons']:
100
- self.seasonsData.add_season(element)
90
+ Parameters:
91
+ - number (int): The season number (1-based index)
92
+ """
93
+ for season in self.seasons:
94
+ if season.number == number:
95
+ return season
96
+ return None
97
+
98
+ def __len__(self) -> int:
99
+ """
100
+ Return the number of seasons managed.
101
+ """
102
+ return len(self.seasons)
101
103
 
102
104
 
103
105
  class Stream:
@@ -48,11 +48,7 @@ class VideoSource:
48
48
 
49
49
  return self.redirect_url
50
50
 
51
- except httpx.RequestError as e:
52
- logging.error(f"Error during the initial request: {e}")
53
- raise
54
-
55
- except AttributeError as e:
51
+ except Exception as e:
56
52
  logging.error(f"Error parsing HTML: {e}")
57
53
  raise
58
54
 
@@ -98,12 +94,8 @@ class VideoSource:
98
94
 
99
95
  return self.maxstream_url
100
96
 
101
- except httpx.RequestError as e:
102
- logging.error(f"Error during the request to the redirect URL: {e}")
103
- raise
104
-
105
- except AttributeError as e:
106
- logging.error(f"Error parsing HTML: {e}")
97
+ except Exception as e:
98
+ logging.error(f"Error during the request: {e}")
107
99
  raise
108
100
 
109
101
  def get_m3u8_url(self):
@@ -16,7 +16,6 @@ from StreamingCommunity.Util.table import TVShowManager
16
16
 
17
17
  # Logic class
18
18
  from StreamingCommunity.Api.Template.config_loader import site_constant
19
- from StreamingCommunity.Api.Template.Util import search_domain
20
19
  from StreamingCommunity.Api.Template.Class.SearchType import MediaManager
21
20
 
22
21
 
@@ -40,14 +39,6 @@ def title_search(word_to_search: str) -> int:
40
39
  media_search_manager.clear()
41
40
  table_show_manager.clear()
42
41
 
43
- # Check if domain is working
44
- domain_to_use, base_url = search_domain(site_constant.FULL_URL)
45
-
46
- if domain_to_use is None or base_url is None:
47
- console.log("[bold red]Error: Unable to determine valid domain or base URL.[/bold red]")
48
- console.print("[yellow]The service might be temporarily unavailable or the domain may have changed.[/yellow]")
49
- sys.exit(1)
50
-
51
42
  search_url = f"{site_constant.FULL_URL}/search/{word_to_search}/1/"
52
43
  console.print(f"[cyan]Search url: [yellow]{search_url}")
53
44
 
@@ -57,6 +48,7 @@ def title_search(word_to_search: str) -> int:
57
48
 
58
49
  except Exception as e:
59
50
  console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
51
+ return 0
60
52
 
61
53
  # Create soup and find table
62
54
  soup = BeautifulSoup(response.text, "html.parser")
@@ -0,0 +1,61 @@
1
+ # 21.05.24
2
+
3
+ from urllib.parse import quote_plus
4
+
5
+
6
+ # External library
7
+ from rich.console import Console
8
+ from rich.prompt import Prompt
9
+
10
+
11
+ # Internal utilities
12
+ from StreamingCommunity.Api.Template import get_select_title
13
+
14
+
15
+ # Logic class
16
+ from StreamingCommunity.Api.Template.config_loader import site_constant
17
+ from .site import title_search, table_show_manager, media_search_manager
18
+ from .film import download_film
19
+ from .series import download_series
20
+
21
+
22
+ # Variable
23
+ indice = 2
24
+ _useFor = "film_serie"
25
+ _deprecate = False
26
+ _priority = 1
27
+ _engineDownload = "hls"
28
+
29
+ msg = Prompt()
30
+ console = Console()
31
+
32
+
33
+ def search(string_to_search: str = None, get_onylDatabase: bool = False):
34
+ """
35
+ Main function of the application for film and series.
36
+ """
37
+ if string_to_search is None:
38
+ string_to_search = msg.ask(f"\n[purple]Insert word to search in [green]{site_constant.SITE_NAME}").strip()
39
+
40
+ len_database = title_search(quote_plus(string_to_search))
41
+
42
+ # Return list of elements
43
+ if get_onylDatabase:
44
+ return media_search_manager
45
+
46
+ if len_database > 0:
47
+
48
+ # Select title from list
49
+ select_title = get_select_title(table_show_manager, media_search_manager)
50
+
51
+ if select_title.type == 'tv':
52
+ download_series(select_title)
53
+
54
+ else:
55
+ download_film(select_title)
56
+
57
+ else:
58
+ console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
59
+
60
+ # Retry
61
+ search()
@@ -0,0 +1,98 @@
1
+ # 3.12.23
2
+
3
+ import os
4
+
5
+
6
+ # External library
7
+ import httpx
8
+ from bs4 import BeautifulSoup
9
+ from rich.console import Console
10
+
11
+
12
+ # Internal utilities
13
+ from StreamingCommunity.Util.os import os_manager
14
+ from StreamingCommunity.Util.message import start_message
15
+ from StreamingCommunity.Util.headers import get_headers
16
+ from StreamingCommunity.Util.config_json import config_manager
17
+ from StreamingCommunity.Lib.Downloader import HLS_Downloader
18
+
19
+
20
+ # Logic class
21
+ from StreamingCommunity.Api.Template.config_loader import site_constant
22
+ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
23
+
24
+
25
+ # Player
26
+ from StreamingCommunity.Api.Player.supervideo import VideoSource
27
+
28
+
29
+ # Variable
30
+ console = Console()
31
+ max_timeout = config_manager.get_int("REQUESTS", "timeout")
32
+
33
+
34
+ def download_film(select_title: MediaItem) -> str:
35
+ """
36
+ Downloads a film using the provided film ID, title name, and domain.
37
+
38
+ Parameters:
39
+ - select_title (MediaItem): The selected media item.
40
+
41
+ Return:
42
+ - str: output path if successful, otherwise None
43
+ """
44
+ start_message()
45
+ console.print(f"[yellow]Download: [red]{select_title.name} \n")
46
+
47
+ # Extract mostraguarda link
48
+ try:
49
+ response = httpx.get(select_title.url, headers=get_headers(), timeout=10)
50
+ response.raise_for_status()
51
+
52
+ except Exception as e:
53
+ console.print(f"[red]Error fetching the page: {e}")
54
+ return None
55
+
56
+ # Create mostraguarda url
57
+ soup = BeautifulSoup(response.text, "html.parser")
58
+ iframe_tag = soup.find_all("iframe")
59
+ url_mostraGuarda = iframe_tag[0].get('data-src')
60
+ if not url_mostraGuarda:
61
+ console.print("Error: data-src attribute not found in iframe.")
62
+
63
+ # Extract supervideo URL
64
+ try:
65
+ response = httpx.get(url_mostraGuarda, headers=get_headers(), timeout=10)
66
+ response.raise_for_status()
67
+
68
+ except Exception as e:
69
+ console.print(f"[red]Error fetching mostraguarda link: {e}")
70
+ return None
71
+
72
+ # Create supervio URL
73
+ soup = BeautifulSoup(response.text, "html.parser")
74
+ player_links = soup.find("ul", class_="_player-mirrors")
75
+ player_items = player_links.find_all("li")
76
+ supervideo_url = "https:" + player_items[0].get("data-link")
77
+ if not supervideo_url:
78
+ return None
79
+
80
+ # Init class
81
+ video_source = VideoSource(url=supervideo_url)
82
+ master_playlist = video_source.get_playlist()
83
+
84
+ # Define the filename and path for the downloaded film
85
+ title_name = os_manager.get_sanitize_file(select_title.name) + ".mp4"
86
+ mp4_path = os.path.join(site_constant.MOVIE_FOLDER, title_name.replace(".mp4", ""))
87
+
88
+ # Download the film using the m3u8 playlist, and output filename
89
+ r_proc = HLS_Downloader(
90
+ m3u8_url=master_playlist,
91
+ output_path=os.path.join(mp4_path, title_name)
92
+ ).start()
93
+
94
+ if r_proc['error'] is not None:
95
+ try: os.remove(r_proc['path'])
96
+ except: pass
97
+
98
+ return r_proc['path']
@@ -0,0 +1,164 @@
1
+ # 3.12.23
2
+
3
+ import os
4
+ from typing import Tuple
5
+
6
+
7
+ # External library
8
+ from rich.console import Console
9
+ from rich.prompt import Prompt
10
+
11
+
12
+ # Internal utilities
13
+ from StreamingCommunity.Util.message import start_message
14
+ from StreamingCommunity.Lib.Downloader import HLS_Downloader
15
+
16
+ # Logic class
17
+ from .util.ScrapeSerie import GetSerieInfo
18
+ from StreamingCommunity.Api.Template.Util import (
19
+ manage_selection,
20
+ map_episode_title,
21
+ dynamic_format_number,
22
+ validate_selection,
23
+ validate_episode_selection,
24
+ display_episodes_list
25
+ )
26
+ from StreamingCommunity.Api.Template.config_loader import site_constant
27
+ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
28
+
29
+
30
+ # Player
31
+ from StreamingCommunity.Api.Player.supervideo import VideoSource
32
+
33
+
34
+ # Variable
35
+ msg = Prompt()
36
+ console = Console()
37
+
38
+
39
+ def download_video(index_season_selected: int, index_episode_selected: int, scrape_serie: GetSerieInfo) -> Tuple[str,bool]:
40
+ """
41
+ Download a single episode video.
42
+
43
+ Parameters:
44
+ - index_season_selected (int): Index of the selected season.
45
+ - index_episode_selected (int): Index of the selected episode.
46
+
47
+ Return:
48
+ - str: output path
49
+ - bool: kill handler status
50
+ """
51
+ start_message()
52
+ index_season_selected = dynamic_format_number(str(index_season_selected))
53
+
54
+ # Get info about episode
55
+ obj_episode = scrape_serie.seasons_manager.get_season_by_number(int(index_season_selected)).episodes.get(index_episode_selected-1)
56
+ console.print(f"[yellow]Download: [red]{index_season_selected}:{index_episode_selected} {obj_episode.name}")
57
+ print()
58
+
59
+ # Define filename and path for the downloaded video
60
+ mp4_name = f"{map_episode_title(scrape_serie.serie_name, index_season_selected, index_episode_selected, obj_episode.name)}.mp4"
61
+ mp4_path = os.path.join(site_constant.SERIES_FOLDER, scrape_serie.serie_name, f"S{index_season_selected}")
62
+
63
+ # Retrieve scws and if available master playlist
64
+ video_source = VideoSource(obj_episode.url)
65
+ video_source.make_request(obj_episode.url)
66
+ master_playlist = video_source.get_playlist()
67
+
68
+ # Download the episode
69
+ r_proc = HLS_Downloader(
70
+ m3u8_url=master_playlist,
71
+ output_path=os.path.join(mp4_path, mp4_name)
72
+ ).start()
73
+
74
+ if r_proc['error'] is not None:
75
+ try: os.remove(r_proc['path'])
76
+ except: pass
77
+
78
+ return r_proc['path'], r_proc['stopped']
79
+
80
+
81
+ def download_episode(index_season_selected: int, scrape_serie: GetSerieInfo, download_all: bool = False) -> None:
82
+ """
83
+ Download episodes of a selected season.
84
+
85
+ Parameters:
86
+ - index_season_selected (int): Index of the selected season.
87
+ - download_all (bool): Download all episodes in the season.
88
+ """
89
+ start_message()
90
+ obj_episodes = scrape_serie.seasons_manager.get_season_by_number(index_season_selected).episodes
91
+ episodes_count = len(obj_episodes.episodes)
92
+
93
+ if download_all:
94
+
95
+ # Download all episodes without asking
96
+ for i_episode in range(1, episodes_count + 1):
97
+ path, stopped = download_video(index_season_selected, i_episode, scrape_serie)
98
+
99
+ if stopped:
100
+ break
101
+
102
+ console.print(f"\n[red]End downloaded [yellow]season: [red]{index_season_selected}.")
103
+
104
+ else:
105
+
106
+ # Display episodes list and manage user selection
107
+ last_command = display_episodes_list(obj_episodes.episodes)
108
+ list_episode_select = manage_selection(last_command, episodes_count)
109
+
110
+ try:
111
+ list_episode_select = validate_episode_selection(list_episode_select, episodes_count)
112
+ except ValueError as e:
113
+ console.print(f"[red]{str(e)}")
114
+ return
115
+
116
+ # Download selected episodes if not stopped
117
+ for i_episode in list_episode_select:
118
+ path, stopped = download_video(index_season_selected, i_episode, scrape_serie)
119
+
120
+ if stopped:
121
+ break
122
+
123
+ def download_series(select_season: MediaItem) -> None:
124
+ """
125
+ Download episodes of a TV series based on user selection.
126
+
127
+ Parameters:
128
+ - select_season (MediaItem): Selected media item (TV series).
129
+ """
130
+ start_message()
131
+
132
+ # Init class
133
+ scrape_serie = GetSerieInfo(select_season.url)
134
+
135
+ # Collect information about seasons
136
+ scrape_serie.collect_season()
137
+ seasons_count = len(scrape_serie.seasons_manager)
138
+
139
+ # Prompt user for season selection and download episodes
140
+ console.print(f"\n[green]Seasons found: [red]{seasons_count}")
141
+ index_season_selected = msg.ask(
142
+ "\n[cyan]Insert season number [yellow](e.g., 1), [red]* [cyan]to download all seasons, "
143
+ "[yellow](e.g., 1-2) [cyan]for a range of seasons, or [yellow](e.g., 3-*) [cyan]to download from a specific season to the end"
144
+ )
145
+
146
+ # Manage and validate the selection
147
+ list_season_select = manage_selection(index_season_selected, seasons_count)
148
+
149
+ try:
150
+ list_season_select = validate_selection(list_season_select, seasons_count)
151
+ except ValueError as e:
152
+ console.print(f"[red]{str(e)}")
153
+ return
154
+
155
+ # Loop through the selected seasons and download episodes
156
+ for i_season in list_season_select:
157
+ if len(list_season_select) > 1 or index_season_selected == "*":
158
+
159
+ # Download all episodes if multiple seasons are selected or if '*' is used
160
+ download_episode(i_season, scrape_serie, download_all=True)
161
+ else:
162
+
163
+ # Otherwise, let the user select specific episodes for the single season
164
+ download_episode(i_season, scrape_serie, download_all=False)
@@ -0,0 +1,75 @@
1
+ # 10.12.23
2
+
3
+
4
+ # External libraries
5
+ import httpx
6
+ from bs4 import BeautifulSoup
7
+ from rich.console import Console
8
+
9
+
10
+ # Internal utilities
11
+ from StreamingCommunity.Util.config_json import config_manager
12
+ from StreamingCommunity.Util.headers import get_userAgent
13
+ from StreamingCommunity.Util.table import TVShowManager
14
+
15
+
16
+ # Logic class
17
+ from StreamingCommunity.Api.Template.config_loader import site_constant
18
+ from StreamingCommunity.Api.Template.Class.SearchType import MediaManager
19
+
20
+
21
+ # Variable
22
+ console = Console()
23
+ media_search_manager = MediaManager()
24
+ table_show_manager = TVShowManager()
25
+ max_timeout = config_manager.get_int("REQUESTS", "timeout")
26
+
27
+
28
+ def title_search(title_search: str) -> int:
29
+ """
30
+ Search for titles based on a search query.
31
+
32
+ Parameters:
33
+ - title_search (str): The title to search for.
34
+
35
+ Returns:
36
+ int: The number of titles found.
37
+ """
38
+ media_search_manager.clear()
39
+ table_show_manager.clear()
40
+
41
+ search_url = f"{site_constant.FULL_URL}/?story={title_search}&do=search&subaction=search"
42
+ console.print(f"[cyan]Search url: [yellow]{search_url}")
43
+
44
+ try:
45
+ response = httpx.post(search_url, headers={'user-agent': get_userAgent()}, timeout=max_timeout, follow_redirects=True)
46
+ response.raise_for_status()
47
+
48
+ except Exception as e:
49
+ console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
50
+ return 0
51
+
52
+ # Create soup istance
53
+ soup = BeautifulSoup(response.text, "html.parser")
54
+
55
+ # Collect data from soup
56
+ for movie_div in soup.find_all("div", class_="movie"):
57
+
58
+ title_tag = movie_div.find("h2", class_="movie-title")
59
+ title = title_tag.find("a").get_text(strip=True)
60
+ url = title_tag.find("a").get("href")
61
+
62
+ # Define typo
63
+ if "/serie-tv/" in url:
64
+ tipo = "tv"
65
+ else:
66
+ tipo = "film"
67
+
68
+ media_search_manager.add_media({
69
+ 'url': url,
70
+ 'name': title,
71
+ 'type': tipo
72
+ })
73
+
74
+ # Return the number of titles found
75
+ return media_search_manager.get_length()
@@ -0,0 +1,72 @@
1
+ # 01.03.24
2
+
3
+ # External libraries
4
+ import httpx
5
+ from bs4 import BeautifulSoup
6
+
7
+
8
+ # Internal utilities
9
+ from StreamingCommunity.Util.headers import get_userAgent
10
+ from StreamingCommunity.Util.config_json import config_manager
11
+ from StreamingCommunity.Api.Player.Helper.Vixcloud.util import SeasonManager
12
+
13
+
14
+ # Variable
15
+ max_timeout = config_manager.get_int("REQUESTS", "timeout")
16
+
17
+
18
+
19
+ class GetSerieInfo:
20
+ def __init__(self, url):
21
+ """
22
+ Initialize the GetSerieInfo class for scraping TV series information.
23
+
24
+ Args:
25
+ - url (str): The URL of the streaming site.
26
+ """
27
+ self.headers = {'user-agent': get_userAgent()}
28
+ self.url = url
29
+ self.seasons_manager = SeasonManager()
30
+
31
+ def collect_season(self) -> None:
32
+ """
33
+ Retrieve all episodes for all seasons
34
+ """
35
+ response = httpx.get(self.url, headers=self.headers)
36
+ soup = BeautifulSoup(response.text, "html.parser")
37
+ self.serie_name = soup.find("title").get_text(strip=True).split(" - ")[0]
38
+
39
+ # Process all seasons
40
+ season_items = soup.find_all('div', class_='accordion-item')
41
+
42
+ for season_idx, season_item in enumerate(season_items, 1):
43
+ season_header = season_item.find('div', class_='accordion-header')
44
+ if not season_header:
45
+ continue
46
+
47
+ season_name = season_header.get_text(strip=True)
48
+
49
+ # Create a new season and get a reference to it
50
+ current_season = self.seasons_manager.add_season({
51
+ 'number': season_idx,
52
+ 'name': season_name
53
+ })
54
+
55
+ # Find episodes for this season
56
+ episode_divs = season_item.find_all('div', class_='down-episode')
57
+ for ep_idx, ep_div in enumerate(episode_divs, 1):
58
+ episode_name_tag = ep_div.find('b')
59
+ if not episode_name_tag:
60
+ continue
61
+
62
+ episode_name = episode_name_tag.get_text(strip=True)
63
+ link_tag = ep_div.find('a', string=lambda text: text and "Supervideo" in text)
64
+ episode_url = link_tag['href'] if link_tag else None
65
+
66
+ # Add episode to the season
67
+ if current_season:
68
+ current_season.episodes.add({
69
+ 'number': ep_idx,
70
+ 'name': episode_name,
71
+ 'url': episode_url
72
+ })
@@ -137,7 +137,7 @@ def download_series(select_title: MediaItem):
137
137
 
138
138
  # Download selected episodes
139
139
  if len(list_episode_select) == 1 and last_command != "*":
140
- path, _ = download_episode(list_episode_select[0]-1, scrape_serie, video_source)[0]
140
+ path, _ = download_episode(list_episode_select[0]-1, scrape_serie, video_source)
141
141
  return path
142
142
 
143
143
  # Download all other episodes selecter
@@ -19,7 +19,6 @@ from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
19
19
 
20
20
  # Logic class
21
21
  from StreamingCommunity.Api.Template.config_loader import site_constant
22
- from StreamingCommunity.Api.Template.Util import search_domain
23
22
  from StreamingCommunity.Api.Template.Class.SearchType import MediaManager
24
23
 
25
24
 
@@ -102,14 +101,6 @@ def title_search(title: str) -> int:
102
101
  media_search_manager.clear()
103
102
  table_show_manager.clear()
104
103
 
105
- # Check if domain is working
106
- domain_to_use, base_url = search_domain(site_constant.FULL_URL)
107
-
108
- if domain_to_use is None or base_url is None:
109
- console.print("[bold red]Error: Unable to determine valid domain or base URL.[/bold red]")
110
- console.print("[yellow]The service might be temporarily unavailable or the domain may have changed.[/yellow]")
111
- sys.exit(1)
112
-
113
104
  # Create parameter for request
114
105
  data = get_token()
115
106
  cookies = {'animeunity_session': data.get('animeunity_session')}
@@ -132,6 +123,7 @@ def title_search(title: str) -> int:
132
123
 
133
124
  except Exception as e:
134
125
  console.print(f"Site: {site_constant.SITE_NAME}, request search error: {e}")
126
+ return 0
135
127
 
136
128
  # Inizializza la lista delle scelte
137
129
  if site_constant.TELEGRAM_BOT: