StreamingCommunity 2.9.3__py3-none-any.whl → 2.9.5__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 (45) 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/__init__.py +26 -12
  4. StreamingCommunity/Api/Site/1337xx/site.py +3 -10
  5. StreamingCommunity/Api/Site/altadefinizione/__init__.py +108 -0
  6. StreamingCommunity/Api/Site/altadefinizione/film.py +128 -0
  7. StreamingCommunity/Api/Site/altadefinizione/series.py +209 -0
  8. StreamingCommunity/Api/Site/altadefinizione/site.py +93 -0
  9. StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py +72 -0
  10. StreamingCommunity/Api/Site/animeunity/__init__.py +53 -32
  11. StreamingCommunity/Api/Site/animeunity/film_serie.py +6 -2
  12. StreamingCommunity/Api/Site/animeunity/site.py +1 -11
  13. StreamingCommunity/Api/Site/cb01new/__init__.py +26 -14
  14. StreamingCommunity/Api/Site/cb01new/site.py +7 -16
  15. StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py +26 -15
  16. StreamingCommunity/Api/Site/ddlstreamitaly/site.py +1 -9
  17. StreamingCommunity/Api/Site/guardaserie/__init__.py +23 -11
  18. StreamingCommunity/Api/Site/guardaserie/site.py +3 -10
  19. StreamingCommunity/Api/Site/mostraguarda/__init__.py +27 -7
  20. StreamingCommunity/Api/Site/streamingcommunity/__init__.py +50 -27
  21. StreamingCommunity/Api/Site/streamingcommunity/series.py +34 -12
  22. StreamingCommunity/Api/Site/streamingcommunity/site.py +14 -10
  23. StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +38 -17
  24. StreamingCommunity/Api/Template/Class/SearchType.py +1 -1
  25. StreamingCommunity/Api/Template/Util/__init__.py +0 -1
  26. StreamingCommunity/Api/Template/Util/manage_ep.py +1 -0
  27. StreamingCommunity/Api/Template/config_loader.py +0 -4
  28. StreamingCommunity/Lib/Downloader/HLS/downloader.py +2 -2
  29. StreamingCommunity/Lib/Downloader/HLS/segments.py +1 -1
  30. StreamingCommunity/Lib/Downloader/MP4/downloader.py +8 -6
  31. StreamingCommunity/Lib/M3U8/estimator.py +3 -3
  32. StreamingCommunity/Upload/version.py +1 -1
  33. StreamingCommunity/Util/config_json.py +2 -11
  34. StreamingCommunity/Util/table.py +12 -2
  35. StreamingCommunity/__init__.py +6 -0
  36. StreamingCommunity/global_search.py +315 -0
  37. StreamingCommunity/run.py +27 -3
  38. {StreamingCommunity-2.9.3.dist-info → streamingcommunity-2.9.5.dist-info}/METADATA +128 -16
  39. streamingcommunity-2.9.5.dist-info/RECORD +80 -0
  40. {StreamingCommunity-2.9.3.dist-info → streamingcommunity-2.9.5.dist-info}/WHEEL +1 -1
  41. StreamingCommunity/Api/Template/Util/get_domain.py +0 -100
  42. StreamingCommunity-2.9.3.dist-info/RECORD +0 -75
  43. {StreamingCommunity-2.9.3.dist-info → streamingcommunity-2.9.5.dist-info}/LICENSE +0 -0
  44. {StreamingCommunity-2.9.3.dist-info → streamingcommunity-2.9.5.dist-info}/entry_points.txt +0 -0
  45. {StreamingCommunity-2.9.3.dist-info → streamingcommunity-2.9.5.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):
@@ -10,10 +10,11 @@ from rich.prompt import Prompt
10
10
 
11
11
  # Internal utilities
12
12
  from StreamingCommunity.Api.Template import get_select_title
13
+ from StreamingCommunity.Api.Template.config_loader import site_constant
14
+ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
13
15
 
14
16
 
15
17
  # Logic class
16
- from StreamingCommunity.Api.Template.config_loader import site_constant
17
18
  from .site import title_search, media_search_manager, table_show_manager
18
19
  from .title import download_title
19
20
 
@@ -29,30 +30,43 @@ console = Console()
29
30
  msg = Prompt()
30
31
 
31
32
 
32
- def search(string_to_search: str = None, get_onylDatabase: bool = False):
33
+
34
+ def process_search_result(select_title):
35
+ """
36
+ Handles the search result and initiates the download for either a film or series.
37
+ """
38
+ download_title(select_title)
39
+
40
+ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None):
33
41
  """
34
- Main function of the application for film and series.
42
+ Main function of the application for search film, series and anime.
43
+
44
+ Parameters:
45
+ string_to_search (str, optional): String to search for
46
+ get_onylDatabase (bool, optional): If True, return only the database object
47
+ direct_item (dict, optional): Direct item to process (bypass search)
35
48
  """
49
+ if direct_item:
50
+ select_title = MediaItem(**direct_item)
51
+ process_search_result(select_title)
52
+ return
53
+
36
54
  if string_to_search is None:
37
55
  string_to_search = msg.ask(f"\n[purple]Insert word to search in [green]{site_constant.SITE_NAME}").strip()
38
56
 
39
- # Search on database
57
+ # Perform the database search
40
58
  len_database = title_search(quote_plus(string_to_search))
41
59
 
42
- # Return list of elements
43
- if get_onylDatabase:
60
+ # If only the database is needed, return the manager
61
+ if get_onlyDatabase:
44
62
  return media_search_manager
45
63
 
46
64
  if len_database > 0:
47
-
48
- # Select title from list
49
65
  select_title = get_select_title(table_show_manager, media_search_manager)
50
-
51
- # Download title
52
66
  download_title(select_title)
53
67
 
54
68
  else:
55
- console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
56
69
 
57
- # Retry
70
+ # If no results are found, ask again
71
+ console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
58
72
  search()
@@ -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")
@@ -70,7 +62,8 @@ def title_search(word_to_search: str) -> int:
70
62
  'seader': tr.find_all("td")[-5].get_text(strip=True),
71
63
  'leacher': tr.find_all("td")[-4].get_text(strip=True),
72
64
  'date': tr.find_all("td")[-3].get_text(strip=True).replace("'", ""),
73
- 'size': tr.find_all("td")[-2].get_text(strip=True)
65
+ 'size': tr.find_all("td")[-2].get_text(strip=True),
66
+ 'type': 'torrent'
74
67
  }
75
68
  media_search_manager.add_media(title_info)
76
69
 
@@ -0,0 +1,108 @@
1
+ # 16.03.25
2
+
3
+ import sys
4
+ import subprocess
5
+ from urllib.parse import quote_plus
6
+
7
+
8
+ # External library
9
+ from rich.console import Console
10
+ from rich.prompt import Prompt
11
+
12
+
13
+ # Internal utilities
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
17
+ from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
18
+
19
+
20
+ # Logic class
21
+ from .site import title_search, table_show_manager, media_search_manager
22
+ from .film import download_film
23
+ from .series import download_series
24
+
25
+ # Variable
26
+ indice = 2
27
+ _useFor = "film_serie"
28
+ _deprecate = False
29
+ _priority = 1
30
+ _engineDownload = "hls"
31
+
32
+ msg = Prompt()
33
+ console = Console()
34
+
35
+
36
+ def get_user_input(string_to_search: str = None):
37
+ """
38
+ Asks the user to input a search term.
39
+ Handles both Telegram bot input and direct input.
40
+ """
41
+ if string_to_search is None:
42
+ if site_constant.TELEGRAM_BOT:
43
+ bot = get_bot_instance()
44
+ string_to_search = bot.ask(
45
+ "key_search",
46
+ f"Enter the search term\nor type 'back' to return to the menu: ",
47
+ None
48
+ )
49
+
50
+ if string_to_search == 'back':
51
+
52
+ # Restart the script
53
+ subprocess.Popen([sys.executable] + sys.argv)
54
+ sys.exit()
55
+ else:
56
+ string_to_search = msg.ask(f"\n[purple]Insert a word to search in [green]{site_constant.SITE_NAME}").strip()
57
+
58
+ return string_to_search
59
+
60
+ def process_search_result(select_title):
61
+ """
62
+ Handles the search result and initiates the download for either a film or series.
63
+ """
64
+ if select_title.type == 'tv':
65
+ download_series(select_title)
66
+ else:
67
+ download_film(select_title)
68
+
69
+ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None):
70
+ """
71
+ Main function of the application for search film, series and anime.
72
+
73
+ Parameters:
74
+ string_to_search (str, optional): String to search for
75
+ get_onylDatabase (bool, optional): If True, return only the database object
76
+ direct_item (dict, optional): Direct item to process (bypass search)
77
+ """
78
+ if direct_item:
79
+ select_title = MediaItem(**direct_item)
80
+ process_search_result(select_title)
81
+ return
82
+
83
+ # Get the user input for the search term
84
+ string_to_search = get_user_input(string_to_search)
85
+
86
+ # Perform the database search
87
+ len_database = title_search(quote_plus(string_to_search))
88
+
89
+ # If only the database is needed, return the manager
90
+ if get_onlyDatabase:
91
+ return media_search_manager
92
+
93
+ if site_constant.TELEGRAM_BOT:
94
+ bot = get_bot_instance()
95
+
96
+ if len_database > 0:
97
+ select_title = get_select_title(table_show_manager, media_search_manager)
98
+ process_search_result(select_title)
99
+
100
+ else:
101
+ console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
102
+
103
+ if site_constant.TELEGRAM_BOT:
104
+ bot.send_message(f"No results found, please try again", None)
105
+
106
+ # If no results are found, ask again
107
+ string_to_search = get_user_input()
108
+ search()
@@ -0,0 +1,128 @@
1
+ # 16.03.25
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
+ from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance, TelegramSession
19
+
20
+
21
+ # Logic class
22
+ from StreamingCommunity.Api.Template.config_loader import site_constant
23
+ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
24
+
25
+
26
+ # Player
27
+ from StreamingCommunity.Api.Player.supervideo import VideoSource
28
+
29
+
30
+ # Variable
31
+ console = Console()
32
+ max_timeout = config_manager.get_int("REQUESTS", "timeout")
33
+
34
+
35
+ def download_film(select_title: MediaItem) -> str:
36
+ """
37
+ Downloads a film using the provided film ID, title name, and domain.
38
+
39
+ Parameters:
40
+ - select_title (MediaItem): The selected media item.
41
+
42
+ Return:
43
+ - str: output path if successful, otherwise None
44
+ """
45
+
46
+ if site_constant.TELEGRAM_BOT:
47
+ bot = get_bot_instance()
48
+ bot.send_message(f"Download in corso:\n{select_title.name}", None)
49
+
50
+ # Viene usato per lo screen
51
+ console.print(f"## Download: [red]{select_title.name} ##")
52
+
53
+ # Get script_id
54
+ script_id = TelegramSession.get_session()
55
+ if script_id != "unknown":
56
+ TelegramSession.updateScriptId(script_id, select_title.name)
57
+
58
+ start_message()
59
+ console.print(f"[yellow]Download: [red]{select_title.name} \n")
60
+
61
+ # Extract mostraguarda link
62
+ try:
63
+ response = httpx.get(select_title.url, headers=get_headers(), timeout=10)
64
+ response.raise_for_status()
65
+
66
+ except Exception as e:
67
+ console.print(f"[red]Error fetching the page: {e}")
68
+
69
+ if site_constant.TELEGRAM_BOT:
70
+ bot.send_message(f"ERRORE\n\nErrore durante il recupero della pagina.\n\n{e}", None)
71
+ return None
72
+
73
+ # Create mostraguarda url
74
+ soup = BeautifulSoup(response.text, "html.parser")
75
+ iframe_tag = soup.find_all("iframe")
76
+ url_mostraGuarda = iframe_tag[0].get('data-src')
77
+ if not url_mostraGuarda:
78
+ console.print("Error: data-src attribute not found in iframe.")
79
+ if site_constant.TELEGRAM_BOT:
80
+ bot.send_message(f"ERRORE\n\nErrore: attributo data-src non trovato nell'iframe", None)
81
+
82
+ # Extract supervideo URL
83
+ try:
84
+ response = httpx.get(url_mostraGuarda, headers=get_headers(), timeout=10)
85
+ response.raise_for_status()
86
+
87
+ except Exception as e:
88
+ console.print(f"[red]Error fetching mostraguarda link: {e}")
89
+ console.print("[yellow]Missing access credentials. This part of the code is still under development.")
90
+ if site_constant.TELEGRAM_BOT:
91
+ bot.send_message(f"ERRORE\n\nErrore durante il recupero del link mostra/guarda.\n\n{e}", None)
92
+ bot.send_message(f"ERRORE\n\nCredenziali di accesso mancanti.\nQuesta parte del codice è ancora in fase di sviluppo.", None)
93
+ return None
94
+
95
+ # Create supervio URL
96
+ soup = BeautifulSoup(response.text, "html.parser")
97
+ player_links = soup.find("ul", class_="_player-mirrors")
98
+ player_items = player_links.find_all("li")
99
+ supervideo_url = "https:" + player_items[0].get("data-link")
100
+ if not supervideo_url:
101
+ return None
102
+
103
+ # Init class
104
+ video_source = VideoSource(url=supervideo_url)
105
+ master_playlist = video_source.get_playlist()
106
+
107
+ # Define the filename and path for the downloaded film
108
+ title_name = os_manager.get_sanitize_file(select_title.name) + ".mp4"
109
+ mp4_path = os.path.join(site_constant.MOVIE_FOLDER, title_name.replace(".mp4", ""))
110
+
111
+ # Download the film using the m3u8 playlist, and output filename
112
+ r_proc = HLS_Downloader(
113
+ m3u8_url=master_playlist,
114
+ output_path=os.path.join(mp4_path, title_name)
115
+ ).start()
116
+
117
+ if site_constant.TELEGRAM_BOT:
118
+
119
+ # Delete script_id
120
+ script_id = TelegramSession.get_session()
121
+ if script_id != "unknown":
122
+ TelegramSession.deleteScriptId(script_id)
123
+
124
+ if r_proc['error'] is not None:
125
+ try: os.remove(r_proc['path'])
126
+ except: pass
127
+
128
+ return r_proc['path']