StreamingCommunity 1.9.1__py3-none-any.whl → 1.9.2__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 (96) hide show
  1. StreamingCommunity/run.py +2 -3
  2. {StreamingCommunity-1.9.1.dist-info → StreamingCommunity-1.9.2.dist-info}/METADATA +32 -4
  3. StreamingCommunity-1.9.2.dist-info/RECORD +7 -0
  4. {StreamingCommunity-1.9.1.dist-info → StreamingCommunity-1.9.2.dist-info}/WHEEL +1 -1
  5. {StreamingCommunity-1.9.1.dist-info → StreamingCommunity-1.9.2.dist-info}/entry_points.txt +1 -0
  6. StreamingCommunity/Api/Player/Helper/Vixcloud/js_parser.py +0 -143
  7. StreamingCommunity/Api/Player/Helper/Vixcloud/util.py +0 -166
  8. StreamingCommunity/Api/Player/ddl.py +0 -89
  9. StreamingCommunity/Api/Player/maxstream.py +0 -151
  10. StreamingCommunity/Api/Player/supervideo.py +0 -194
  11. StreamingCommunity/Api/Player/vixcloud.py +0 -224
  12. StreamingCommunity/Api/Site/1337xx/__init__.py +0 -50
  13. StreamingCommunity/Api/Site/1337xx/costant.py +0 -15
  14. StreamingCommunity/Api/Site/1337xx/site.py +0 -84
  15. StreamingCommunity/Api/Site/1337xx/title.py +0 -66
  16. StreamingCommunity/Api/Site/altadefinizione/__init__.py +0 -50
  17. StreamingCommunity/Api/Site/altadefinizione/costant.py +0 -15
  18. StreamingCommunity/Api/Site/altadefinizione/film.py +0 -69
  19. StreamingCommunity/Api/Site/altadefinizione/site.py +0 -86
  20. StreamingCommunity/Api/Site/animeunity/__init__.py +0 -50
  21. StreamingCommunity/Api/Site/animeunity/costant.py +0 -15
  22. StreamingCommunity/Api/Site/animeunity/film_serie.py +0 -130
  23. StreamingCommunity/Api/Site/animeunity/site.py +0 -165
  24. StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py +0 -97
  25. StreamingCommunity/Api/Site/bitsearch/__init__.py +0 -51
  26. StreamingCommunity/Api/Site/bitsearch/costant.py +0 -15
  27. StreamingCommunity/Api/Site/bitsearch/site.py +0 -84
  28. StreamingCommunity/Api/Site/bitsearch/title.py +0 -47
  29. StreamingCommunity/Api/Site/cb01new/__init__.py +0 -51
  30. StreamingCommunity/Api/Site/cb01new/costant.py +0 -15
  31. StreamingCommunity/Api/Site/cb01new/film.py +0 -69
  32. StreamingCommunity/Api/Site/cb01new/site.py +0 -74
  33. StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py +0 -57
  34. StreamingCommunity/Api/Site/ddlstreamitaly/costant.py +0 -16
  35. StreamingCommunity/Api/Site/ddlstreamitaly/series.py +0 -141
  36. StreamingCommunity/Api/Site/ddlstreamitaly/site.py +0 -93
  37. StreamingCommunity/Api/Site/ddlstreamitaly/util/ScrapeSerie.py +0 -85
  38. StreamingCommunity/Api/Site/guardaserie/__init__.py +0 -52
  39. StreamingCommunity/Api/Site/guardaserie/costant.py +0 -15
  40. StreamingCommunity/Api/Site/guardaserie/series.py +0 -195
  41. StreamingCommunity/Api/Site/guardaserie/site.py +0 -84
  42. StreamingCommunity/Api/Site/guardaserie/util/ScrapeSerie.py +0 -110
  43. StreamingCommunity/Api/Site/mostraguarda/__init__.py +0 -48
  44. StreamingCommunity/Api/Site/mostraguarda/costant.py +0 -15
  45. StreamingCommunity/Api/Site/mostraguarda/film.py +0 -94
  46. StreamingCommunity/Api/Site/piratebays/__init__.py +0 -50
  47. StreamingCommunity/Api/Site/piratebays/costant.py +0 -15
  48. StreamingCommunity/Api/Site/piratebays/site.py +0 -89
  49. StreamingCommunity/Api/Site/piratebays/title.py +0 -45
  50. StreamingCommunity/Api/Site/streamingcommunity/__init__.py +0 -55
  51. StreamingCommunity/Api/Site/streamingcommunity/costant.py +0 -15
  52. StreamingCommunity/Api/Site/streamingcommunity/film.py +0 -70
  53. StreamingCommunity/Api/Site/streamingcommunity/series.py +0 -205
  54. StreamingCommunity/Api/Site/streamingcommunity/site.py +0 -126
  55. StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +0 -113
  56. StreamingCommunity/Api/Template/Class/SearchType.py +0 -101
  57. StreamingCommunity/Api/Template/Util/__init__.py +0 -5
  58. StreamingCommunity/Api/Template/Util/get_domain.py +0 -137
  59. StreamingCommunity/Api/Template/Util/manage_ep.py +0 -153
  60. StreamingCommunity/Api/Template/Util/recall_search.py +0 -37
  61. StreamingCommunity/Api/Template/__init__.py +0 -3
  62. StreamingCommunity/Api/Template/site.py +0 -87
  63. StreamingCommunity/Lib/Downloader/HLS/downloader.py +0 -968
  64. StreamingCommunity/Lib/Downloader/HLS/proxyes.py +0 -110
  65. StreamingCommunity/Lib/Downloader/HLS/segments.py +0 -538
  66. StreamingCommunity/Lib/Downloader/MP4/downloader.py +0 -156
  67. StreamingCommunity/Lib/Downloader/TOR/downloader.py +0 -222
  68. StreamingCommunity/Lib/Downloader/__init__.py +0 -5
  69. StreamingCommunity/Lib/Driver/driver_1.py +0 -76
  70. StreamingCommunity/Lib/FFmpeg/__init__.py +0 -4
  71. StreamingCommunity/Lib/FFmpeg/capture.py +0 -170
  72. StreamingCommunity/Lib/FFmpeg/command.py +0 -292
  73. StreamingCommunity/Lib/FFmpeg/util.py +0 -242
  74. StreamingCommunity/Lib/M3U8/__init__.py +0 -6
  75. StreamingCommunity/Lib/M3U8/decryptor.py +0 -164
  76. StreamingCommunity/Lib/M3U8/estimator.py +0 -176
  77. StreamingCommunity/Lib/M3U8/parser.py +0 -666
  78. StreamingCommunity/Lib/M3U8/url_fixer.py +0 -52
  79. StreamingCommunity/Lib/TMBD/__init__.py +0 -2
  80. StreamingCommunity/Lib/TMBD/obj_tmbd.py +0 -39
  81. StreamingCommunity/Lib/TMBD/tmdb.py +0 -346
  82. StreamingCommunity/Upload/update.py +0 -68
  83. StreamingCommunity/Upload/version.py +0 -5
  84. StreamingCommunity/Util/_jsonConfig.py +0 -204
  85. StreamingCommunity/Util/call_stack.py +0 -42
  86. StreamingCommunity/Util/color.py +0 -20
  87. StreamingCommunity/Util/console.py +0 -12
  88. StreamingCommunity/Util/ffmpeg_installer.py +0 -275
  89. StreamingCommunity/Util/headers.py +0 -147
  90. StreamingCommunity/Util/logger.py +0 -53
  91. StreamingCommunity/Util/message.py +0 -46
  92. StreamingCommunity/Util/os.py +0 -514
  93. StreamingCommunity/Util/table.py +0 -163
  94. StreamingCommunity-1.9.1.dist-info/RECORD +0 -95
  95. {StreamingCommunity-1.9.1.dist-info → StreamingCommunity-1.9.2.dist-info}/LICENSE +0 -0
  96. {StreamingCommunity-1.9.1.dist-info → StreamingCommunity-1.9.2.dist-info}/top_level.txt +0 -0
@@ -1,113 +0,0 @@
1
- # 01.03.24
2
-
3
- import logging
4
-
5
-
6
- # External libraries
7
- import httpx
8
-
9
-
10
- # Internal utilities
11
- from StreamingCommunity.Util.headers import get_headers
12
- from StreamingCommunity.Util._jsonConfig import config_manager
13
- from StreamingCommunity.Api.Player.Helper.Vixcloud.util import SeasonManager, EpisodeManager
14
-
15
-
16
- # Variable
17
- max_timeout = config_manager.get_int("REQUESTS", "timeout")
18
-
19
-
20
- class ScrapeSerie:
21
- def __init__(self, site_name: str):
22
- """
23
- Initialize the ScrapeSerie class for scraping TV series information.
24
-
25
- Args:
26
- site_name (str): Name of the streaming site to scrape from
27
- """
28
- self.is_series = False
29
- self.headers = {'user-agent': get_headers()}
30
- self.base_name = site_name
31
- self.domain = config_manager.get_dict('SITE', self.base_name)['domain']
32
-
33
- def setup(self, version: str = None, media_id: int = None, series_name: str = None):
34
- """
35
- Set up the scraper with specific media details.
36
-
37
- Args:
38
- version (str, optional): Site version for request headers
39
- media_id (int, optional): Unique identifier for the media
40
- series_name (str, optional): Name of the TV series
41
- """
42
- self.version = version
43
- self.media_id = media_id
44
-
45
- # If series name is provided, initialize series-specific managers
46
- if series_name is not None:
47
- self.is_series = True
48
- self.series_name = series_name
49
- self.obj_season_manager: SeasonManager = SeasonManager()
50
- self.obj_episode_manager: EpisodeManager = EpisodeManager()
51
-
52
- def collect_info_seasons(self) -> None:
53
- """
54
- Retrieve season information for a TV series from the streaming site.
55
-
56
- Raises:
57
- Exception: If there's an error fetching season information
58
- """
59
- self.headers = {
60
- 'user-agent': get_headers(),
61
- 'x-inertia': 'true',
62
- 'x-inertia-version': self.version,
63
- }
64
-
65
- try:
66
-
67
- response = httpx.get(
68
- url=f"https://{self.base_name}.{self.domain}/titles/{self.media_id}-{self.series_name}",
69
- headers=self.headers,
70
- timeout=max_timeout
71
- )
72
- response.raise_for_status()
73
-
74
- # Extract seasons from JSON response
75
- json_response = response.json().get('props', {}).get('title', {}).get('seasons', [])
76
-
77
- # Add each season to the season manager
78
- for dict_season in json_response:
79
- self.obj_season_manager.add_season(dict_season)
80
-
81
- except Exception as e:
82
- logging.error(f"Error collecting season info: {e}")
83
- raise
84
-
85
- def collect_title_season(self, number_season: int) -> None:
86
- """
87
- Retrieve episode information for a specific season.
88
-
89
- Args:
90
- number_season (int): Season number to fetch episodes for
91
-
92
- Raises:
93
- Exception: If there's an error fetching episode information
94
- """
95
- try:
96
-
97
- response = httpx.get(
98
- url=f'https://{self.base_name}.{self.domain}/titles/{self.media_id}-{self.series_name}/stagione-{number_season}',
99
- headers=self.headers,
100
- timeout=max_timeout
101
- )
102
- response.raise_for_status()
103
-
104
- # Extract episodes from JSON response
105
- json_response = response.json().get('props', {}).get('loadedSeason', {}).get('episodes', [])
106
-
107
- # Add each episode to the episode manager
108
- for dict_episode in json_response:
109
- self.obj_episode_manager.add_episode(dict_episode)
110
-
111
- except Exception as e:
112
- logging.error(f"Error collecting title season info: {e}")
113
- raise
@@ -1,101 +0,0 @@
1
- # 07.07.24
2
-
3
- from typing import List, TypedDict
4
-
5
-
6
- class MediaItemData(TypedDict, total=False):
7
- id: int # GENERAL
8
- name: str # GENERAL
9
- type: str # GENERAL
10
- url: str # GENERAL
11
- size: str # GENERAL
12
- score: str # GENERAL
13
- date: str # GENERAL
14
- desc: str # GENERAL
15
-
16
- seeder: int # TOR
17
- leecher: int # TOR
18
-
19
- slug: str # SC
20
-
21
-
22
-
23
- class MediaItemMeta(type):
24
- def __new__(cls, name, bases, dct):
25
- def init(self, **kwargs):
26
- for key, value in kwargs.items():
27
- setattr(self, key, value)
28
-
29
- dct['__init__'] = init
30
-
31
- def get_attr(self, item):
32
- return self.__dict__.get(item, None)
33
-
34
- dct['__getattr__'] = get_attr
35
-
36
- def set_attr(self, key, value):
37
- self.__dict__[key] = value
38
-
39
- dct['__setattr__'] = set_attr
40
-
41
- return super().__new__(cls, name, bases, dct)
42
-
43
-
44
- class MediaItem(metaclass=MediaItemMeta):
45
- id: int # GENERAL
46
- name: str # GENERAL
47
- type: str # GENERAL
48
- url: str # GENERAL
49
- size: str # GENERAL
50
- score: str # GENERAL
51
- date: str # GENERAL
52
- desc: str # GENERAL
53
-
54
- seeder: int # TOR
55
- leecher: int # TOR
56
-
57
- slug: str # SC
58
-
59
-
60
- class MediaManager:
61
- def __init__(self):
62
- self.media_list: List[MediaItem] = []
63
-
64
- def add_media(self, data: dict) -> None:
65
- """
66
- Add media to the list.
67
-
68
- Args:
69
- data (dict): Media data to add.
70
- """
71
- self.media_list.append(MediaItem(**data))
72
-
73
- def get(self, index: int) -> MediaItem:
74
- """
75
- Get a media item from the list by index.
76
-
77
- Args:
78
- index (int): The index of the media item to retrieve.
79
-
80
- Returns:
81
- MediaItem: The media item at the specified index.
82
- """
83
- return self.media_list[index]
84
-
85
- def get_length(self) -> int:
86
- """
87
- Get the number of media items in the list.
88
-
89
- Returns:
90
- int: Number of media items.
91
- """
92
- return len(self.media_list)
93
-
94
- def clear(self) -> None:
95
- """
96
- This method clears the media list.
97
- """
98
- self.media_list.clear()
99
-
100
- def __str__(self):
101
- return f"MediaManager(num_media={len(self.media_list)})"
@@ -1,5 +0,0 @@
1
- # 23.11.24
2
-
3
- from .recall_search import execute_search
4
- from .get_domain import search_domain
5
- from .manage_ep import manage_selection, map_episode_title, validate_episode_selection, validate_selection
@@ -1,137 +0,0 @@
1
- # 18.06.24
2
-
3
- import sys
4
- from urllib.parse import urlparse
5
-
6
-
7
- # External libraries
8
- import httpx
9
- from googlesearch import search
10
-
11
-
12
- # Internal utilities
13
- from StreamingCommunity.Util.headers import get_headers
14
- from StreamingCommunity.Util.console import console, msg
15
- from StreamingCommunity.Util._jsonConfig import config_manager
16
-
17
-
18
- def google_search(query):
19
- """
20
- Perform a Google search and return the first result.
21
-
22
- Args:
23
- query (str): The search query to execute on Google.
24
-
25
- Returns:
26
- str: The first URL result from the search, or None if no result is found.
27
- """
28
- # Perform the search on Google and limit to 1 result
29
- search_results = search(query, num_results=1)
30
-
31
- # Extract the first result
32
- first_result = next(search_results, None)
33
-
34
- if not first_result:
35
- console.print("[red]No results found.[/red]")
36
-
37
- return first_result
38
-
39
- def get_final_redirect_url(initial_url, max_timeout):
40
- """
41
- Follow redirects from the initial URL and return the final URL after all redirects.
42
-
43
- Args:
44
- initial_url (str): The URL to start with and follow redirects.
45
-
46
- Returns:
47
- str: The final URL after all redirects are followed.
48
- """
49
-
50
- # Create a client with redirects enabled
51
- try:
52
- with httpx.Client(follow_redirects=True, timeout=max_timeout, headers={'user-agent': get_headers()}) as client:
53
- response = client.get(initial_url)
54
- response.raise_for_status()
55
-
56
- # Capture the final URL after all redirects
57
- final_url = response.url
58
-
59
- return final_url
60
-
61
- except Exception as e:
62
- console.print(f"[cyan]Test url[white]: [red]{initial_url}, [cyan]error[white]: [red]{e}")
63
- return None
64
-
65
- def search_domain(site_name: str, base_url: str):
66
- """
67
- Search for a valid domain for the given site name and base URL.
68
-
69
- Parameters:
70
- - site_name (str): The name of the site to search the domain for.
71
- - base_url (str): The base URL to construct complete URLs.
72
- - follow_redirects (bool): To follow redirect url or not.
73
-
74
- Returns:
75
- tuple: The found domain and the complete URL.
76
- """
77
-
78
- # Extract config domain
79
- max_timeout = config_manager.get_int("REQUESTS", "timeout")
80
- domain = str(config_manager.get_dict("SITE", site_name)['domain'])
81
-
82
- try:
83
-
84
- # Test the current domain
85
- response_follow = httpx.get(f"{base_url}.{domain}", headers={'user-agent': get_headers()}, timeout=max_timeout, follow_redirects=True)
86
- response_follow.raise_for_status()
87
-
88
- except Exception as e:
89
-
90
- query = base_url.split("/")[-1]
91
- first_url = google_search(query)
92
- console.print(f"[green]First url from google seach[white]: [red]{first_url}")
93
-
94
- if first_url:
95
- final_url = get_final_redirect_url(first_url, max_timeout)
96
-
97
- if final_url != None:
98
- console.print(f"\n[bold yellow]Suggestion:[/bold yellow] [white](Experimental)\n"
99
- f"[cyan]New final URL[white]: [green]{final_url}")
100
-
101
- def extract_domain(url):
102
- parsed_url = urlparse(url)
103
- domain = parsed_url.netloc
104
- return domain.split(".")[-1]
105
-
106
- new_domain_extract = extract_domain(str(final_url))
107
-
108
- if msg.ask(f"[red]Do you want to auto update config.json - '[green]{site_name}[red]' with domain: [green]{new_domain_extract}", choices=["y", "n"], default="y").lower() == "y":
109
-
110
- # Update domain in config.json
111
- config_manager.config['SITE'][site_name]['domain'] = new_domain_extract
112
- config_manager.write_config()
113
-
114
- # Return config domain
115
- #console.print(f"[cyan]Return domain: [red]{new_domain_extract} \n")
116
- return new_domain_extract, f"{base_url}.{new_domain_extract}"
117
-
118
- else:
119
- console.print("[bold red]\nManually change the domain in the JSON file.[/bold red]")
120
- raise
121
-
122
- else:
123
- console.print("[bold red]No valid URL to follow redirects.[/bold red]")
124
-
125
- # Ensure the URL is in string format before parsing
126
- parsed_url = urlparse(str(response_follow.url))
127
- parse_domain = parsed_url.netloc
128
- tld = parse_domain.split('.')[-1]
129
-
130
- if tld is not None:
131
-
132
- # Update domain in config.json
133
- config_manager.config['SITE'][site_name]['domain'] = tld
134
- config_manager.write_config()
135
-
136
- # Return config domain
137
- return tld, f"{base_url}.{tld}"
@@ -1,153 +0,0 @@
1
- # 19.06.24
2
-
3
- import logging
4
- from typing import List
5
-
6
-
7
- # Internal utilities
8
- from StreamingCommunity.Util._jsonConfig import config_manager
9
- from StreamingCommunity.Util.os import os_manager
10
-
11
-
12
- # Config
13
- MAP_EPISODE = config_manager.get('DEFAULT', 'map_episode_name')
14
-
15
-
16
- def dynamic_format_number(n: int) -> str:
17
- """
18
- Formats a number by adding a leading zero if it is less than 9.
19
- The width of the resulting string is dynamic, calculated as the number of digits in the number plus one
20
- for numbers less than 9, otherwise the width remains the same.
21
-
22
- Parameters:
23
- - n (int): The number to format.
24
-
25
- Returns:
26
- - str: The formatted number as a string with a leading zero if the number is less than 9.
27
- """
28
- if n < 10:
29
- width = len(str(n)) + 1
30
- else:
31
- width = len(str(n))
32
-
33
- return str(n).zfill(width)
34
-
35
-
36
- def manage_selection(cmd_insert: str, max_count: int) -> List[int]:
37
- """
38
- Manage user selection for seasons or episodes to download.
39
-
40
- Parameters:
41
- - cmd_insert (str): User input for selection.
42
- - max_count (int): Maximum count available.
43
-
44
- Returns:
45
- list_selection (List[int]): List of selected items.
46
- """
47
- list_selection = []
48
- logging.info(f"Command insert: {cmd_insert}, end index: {max_count + 1}")
49
-
50
- # For a single number (e.g., '5')
51
- if cmd_insert.isnumeric():
52
- list_selection.append(int(cmd_insert))
53
-
54
- # For a range (e.g., '5-12')
55
- elif "-" in cmd_insert:
56
- start, end = map(str.strip, cmd_insert.split('-'))
57
- start = int(start)
58
- end = int(end) if end.isnumeric() else max_count
59
-
60
- list_selection = list(range(start, end + 1))
61
-
62
- # For all items ('*')
63
- elif cmd_insert == "*":
64
- list_selection = list(range(1, max_count + 1))
65
-
66
- else:
67
- raise ValueError("Invalid input format")
68
-
69
- logging.info(f"List return: {list_selection}")
70
- return list_selection
71
-
72
-
73
- def map_episode_title(tv_name: str, number_season: int, episode_number: int, episode_name: str) -> str:
74
- """
75
- Maps the episode title to a specific format.
76
-
77
- Parameters:
78
- tv_name (str): The name of the TV show.
79
- number_season (int): The season number.
80
- episode_number (int): The episode number.
81
- episode_name (str): The original name of the episode.
82
-
83
- Returns:
84
- str: The mapped episode title.
85
- """
86
- map_episode_temp = MAP_EPISODE
87
-
88
- if tv_name != None:
89
- map_episode_temp = map_episode_temp.replace("%(tv_name)", os_manager.get_sanitize_file(tv_name))
90
-
91
- if number_season != None:
92
- map_episode_temp = map_episode_temp.replace("%(season)", dynamic_format_number(number_season))
93
- else:
94
- map_episode_temp = map_episode_temp.replace("%(season)", dynamic_format_number(0))
95
-
96
- if episode_number != None:
97
- map_episode_temp = map_episode_temp.replace("%(episode)", dynamic_format_number(episode_number))
98
- else:
99
- map_episode_temp = map_episode_temp.replace("%(episode)", dynamic_format_number(0))
100
-
101
- if episode_name != None:
102
- map_episode_temp = map_episode_temp.replace("%(episode_name)", os_manager.get_sanitize_file(episode_name))
103
-
104
- logging.info(f"Map episode string return: {map_episode_temp}")
105
- return map_episode_temp
106
-
107
-
108
- # --> for season
109
- def validate_selection(list_season_select: List[int], seasons_count: int) -> List[int]:
110
- """
111
- Validates and adjusts the selected seasons based on the available seasons.
112
-
113
- Parameters:
114
- - list_season_select (List[int]): List of seasons selected by the user.
115
- - seasons_count (int): Total number of available seasons.
116
-
117
- Returns:
118
- - List[int]: Adjusted list of valid season numbers.
119
- """
120
-
121
- # Remove any seasons greater than the available seasons
122
- valid_seasons = [season for season in list_season_select if 1 <= season <= seasons_count]
123
-
124
- # If the list is empty, the input was completely invalid
125
- if not valid_seasons:
126
- print()
127
- raise ValueError(f"Invalid selection: The selected seasons are outside the available range (1-{seasons_count}).")
128
-
129
- return valid_seasons
130
-
131
-
132
- # --> for episode
133
- def validate_episode_selection(list_episode_select: List[int], episodes_count: int) -> List[int]:
134
- """
135
- Validates and adjusts the selected episodes based on the available episodes.
136
-
137
- Parameters:
138
- - list_episode_select (List[int]): List of episodes selected by the user.
139
- - episodes_count (int): Total number of available episodes in the season.
140
-
141
- Returns:
142
- - List[int]: Adjusted list of valid episode numbers.
143
- """
144
-
145
- # Remove any episodes greater than the available episodes
146
- valid_episodes = [episode for episode in list_episode_select if 1 <= episode <= episodes_count]
147
-
148
- # If the list is empty, the input was completely invalid
149
- if not valid_episodes:
150
- print()
151
- raise ValueError(f"Invalid selection: The selected episodes are outside the available range (1-{episodes_count}).")
152
-
153
- return valid_episodes
@@ -1,37 +0,0 @@
1
- # 19.10.24
2
-
3
- import os
4
- import sys
5
-
6
- def execute_search(info):
7
- """
8
- Dynamically imports and executes a specified function from a module defined in the info dictionary.
9
-
10
- Parameters:
11
- info (dict): A dictionary containing the function name, folder, and module information.
12
- """
13
-
14
- # Define the project path using the folder from the info dictionary
15
- project_path = os.path.dirname(info['folder']) # Get the base path for the project
16
-
17
- # Add the project path to sys.path
18
- if project_path not in sys.path:
19
- sys.path.append(project_path)
20
-
21
- # Attempt to import the specified function from the module
22
- try:
23
- # Construct the import statement dynamically
24
- module_path = f"StreamingCommunity.Api.Site{info['folder_base']}"
25
- exec(f"from {module_path} import {info['function']}")
26
-
27
- # Call the specified function
28
- eval(info['function'])() # Calls the search function
29
-
30
- except ModuleNotFoundError as e:
31
- print(f"ModuleNotFoundError: {e}")
32
-
33
- except ImportError as e:
34
- print(f"ImportError: {e}")
35
-
36
- except Exception as e:
37
- print(f"An error occurred: {e}")
@@ -1,3 +0,0 @@
1
- # 19.06.24
2
-
3
- from .site import get_select_title
@@ -1,87 +0,0 @@
1
- # 19.06.24
2
-
3
- import sys
4
-
5
-
6
- # Internal utilities
7
- from StreamingCommunity.Util.console import console
8
-
9
-
10
- # Variable
11
- available_colors = ['red', 'magenta', 'yellow', 'cyan', 'green', 'blue', 'white']
12
- column_to_hide = ['Slug', 'Sub_ita', 'Last_air_date', 'Seasons_count', 'Url']
13
-
14
-
15
- def get_select_title(table_show_manager, media_search_manager):
16
- """
17
- Display a selection of titles and prompt the user to choose one.
18
-
19
- Returns:
20
- MediaItem: The selected media item.
21
- """
22
-
23
- # Set up table for displaying titles
24
- table_show_manager.set_slice_end(10)
25
-
26
- # Determine column_info dynamically for (search site)
27
- if not media_search_manager.media_list:
28
- console.print("\n[red]No media items available.")
29
- return None
30
-
31
- # Example of available colors for columns
32
- available_colors = ['red', 'magenta', 'yellow', 'cyan', 'green', 'blue', 'white']
33
-
34
- # Retrieve the keys of the first media item as column headers
35
- first_media_item = media_search_manager.media_list[0]
36
- column_info = {"Index": {'color': available_colors[0]}} # Always include Index with a fixed color
37
-
38
- # Assign colors to the remaining keys dynamically
39
- color_index = 1
40
- for key in first_media_item.__dict__.keys():
41
-
42
- if key.capitalize() in column_to_hide:
43
- continue
44
-
45
- if key in ('id', 'type', 'name', 'score'): # Custom prioritization of colors
46
- if key == 'type':
47
- column_info["Type"] = {'color': 'yellow'}
48
- elif key == 'name':
49
- column_info["Name"] = {'color': 'magenta'}
50
- elif key == 'score':
51
- column_info["Score"] = {'color': 'cyan'}
52
-
53
- else:
54
- column_info[key.capitalize()] = {'color': available_colors[color_index % len(available_colors)]}
55
- color_index += 1
56
-
57
- table_show_manager.add_column(column_info)
58
-
59
- # Populate the table with title information
60
- for i, media in enumerate(media_search_manager.media_list):
61
- media_dict = {'Index': str(i)}
62
-
63
- for key in first_media_item.__dict__.keys():
64
- if key.capitalize() in column_to_hide:
65
- continue
66
-
67
- # Ensure all values are strings for rich add table
68
- media_dict[key.capitalize()] = str(getattr(media, key))
69
-
70
- table_show_manager.add_tv_show(media_dict)
71
-
72
- # Run the table and handle user input
73
- last_command = table_show_manager.run(force_int_input=True, max_int_input=len(media_search_manager.media_list))
74
- table_show_manager.clear()
75
-
76
- # Handle user's quit command
77
- if last_command == "q":
78
- console.print("\n[red]Quit [white]...")
79
- sys.exit(0)
80
-
81
- # Check if the selected index is within range
82
- if 0 <= int(last_command) < len(media_search_manager.media_list):
83
- return media_search_manager.get(int(last_command))
84
-
85
- else:
86
- console.print("\n[red]Wrong index")
87
- sys.exit(0)