StreamingCommunity 3.0.6__py3-none-any.whl → 3.0.7__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.
- StreamingCommunity/Api/Player/maxstream.py +141 -0
- StreamingCommunity/Api/Player/vixcloud.py +5 -3
- StreamingCommunity/Api/Site/1337xx/__init__.py +2 -2
- StreamingCommunity/Api/Site/altadefinizione/__init__.py +2 -2
- StreamingCommunity/Api/Site/altadefinizione/film.py +15 -35
- StreamingCommunity/Api/Site/animeunity/__init__.py +1 -1
- StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py +21 -23
- StreamingCommunity/Api/Site/animeworld/__init__.py +1 -1
- StreamingCommunity/Api/Site/cb01new/__init__.py +72 -0
- StreamingCommunity/Api/Site/cb01new/film.py +62 -0
- StreamingCommunity/Api/Site/cb01new/site.py +78 -0
- StreamingCommunity/Api/Site/guardaserie/__init__.py +1 -1
- StreamingCommunity/Api/Site/raiplay/__init__.py +1 -1
- StreamingCommunity/Api/Site/streamingcommunity/__init__.py +86 -52
- StreamingCommunity/Api/Site/streamingcommunity/film.py +2 -2
- StreamingCommunity/Api/Site/streamingcommunity/series.py +4 -4
- StreamingCommunity/Api/Site/streamingcommunity/site.py +7 -4
- StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +6 -3
- StreamingCommunity/Api/Site/streamingwatch/__init__.py +10 -4
- StreamingCommunity/Api/Site/streamingwatch/site.py +12 -5
- StreamingCommunity/Api/Template/site.py +103 -58
- StreamingCommunity/Lib/Proxies/proxy.py +14 -174
- StreamingCommunity/TelegramHelp/config.json +62 -0
- StreamingCommunity/TelegramHelp/telegram_bot.py +4 -0
- StreamingCommunity/Upload/version.py +1 -1
- StreamingCommunity/run.py +2 -2
- {streamingcommunity-3.0.6.dist-info → streamingcommunity-3.0.7.dist-info}/METADATA +30 -12
- {streamingcommunity-3.0.6.dist-info → streamingcommunity-3.0.7.dist-info}/RECORD +32 -27
- {streamingcommunity-3.0.6.dist-info → streamingcommunity-3.0.7.dist-info}/WHEEL +1 -1
- {streamingcommunity-3.0.6.dist-info → streamingcommunity-3.0.7.dist-info}/entry_points.txt +0 -0
- {streamingcommunity-3.0.6.dist-info → streamingcommunity-3.0.7.dist-info}/licenses/LICENSE +0 -0
- {streamingcommunity-3.0.6.dist-info → streamingcommunity-3.0.7.dist-info}/top_level.txt +0 -0
|
@@ -12,6 +12,7 @@ from rich.prompt import Prompt
|
|
|
12
12
|
|
|
13
13
|
# Internal utilities
|
|
14
14
|
from StreamingCommunity.Api.Template import get_select_title
|
|
15
|
+
from StreamingCommunity.Lib.Proxies.proxy import ProxyFinder
|
|
15
16
|
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
16
17
|
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
17
18
|
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
|
|
@@ -25,48 +26,72 @@ from .series import download_series
|
|
|
25
26
|
|
|
26
27
|
# Variable
|
|
27
28
|
indice = 0
|
|
28
|
-
_useFor = "Film_&_Serie"
|
|
29
|
+
_useFor = "Film_&_Serie" # "Movies_&_Series"
|
|
29
30
|
_priority = 0
|
|
30
31
|
_engineDownload = "hls"
|
|
31
32
|
_deprecate = False
|
|
32
33
|
|
|
33
34
|
msg = Prompt()
|
|
34
35
|
console = Console()
|
|
36
|
+
proxy = None
|
|
35
37
|
|
|
36
38
|
|
|
37
39
|
def get_user_input(string_to_search: str = None):
|
|
38
40
|
"""
|
|
39
41
|
Asks the user to input a search term.
|
|
40
42
|
Handles both Telegram bot input and direct input.
|
|
43
|
+
If string_to_search is provided, it's returned directly (after stripping).
|
|
41
44
|
"""
|
|
42
|
-
if string_to_search is None:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
if string_to_search is not None:
|
|
46
|
+
return string_to_search.strip()
|
|
47
|
+
|
|
48
|
+
if site_constant.TELEGRAM_BOT:
|
|
49
|
+
bot = get_bot_instance()
|
|
50
|
+
user_response = bot.ask(
|
|
51
|
+
"key_search", # Request type
|
|
52
|
+
"Enter the search term\nor type 'back' to return to the menu: ",
|
|
53
|
+
None
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
if user_response is None:
|
|
57
|
+
bot.send_message("Timeout: No search term entered.", None)
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
if user_response.lower() == 'back':
|
|
61
|
+
bot.send_message("Returning to the main menu...", None)
|
|
62
|
+
|
|
63
|
+
try:
|
|
53
64
|
# Restart the script
|
|
54
65
|
subprocess.Popen([sys.executable] + sys.argv)
|
|
55
66
|
sys.exit()
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
67
|
+
|
|
68
|
+
except Exception as e:
|
|
69
|
+
bot.send_message(f"Error during restart attempt: {e}", None)
|
|
70
|
+
return None # Return None if restart fails
|
|
71
|
+
|
|
72
|
+
return user_response.strip()
|
|
73
|
+
|
|
74
|
+
else:
|
|
75
|
+
return msg.ask(f"\n[purple]Insert a word to search in [green]{site_constant.SITE_NAME}").strip()
|
|
60
76
|
|
|
61
|
-
def process_search_result(select_title, selections=None):
|
|
77
|
+
def process_search_result(select_title, selections=None, proxy=None):
|
|
62
78
|
"""
|
|
63
79
|
Handles the search result and initiates the download for either a film or series.
|
|
64
80
|
|
|
65
81
|
Parameters:
|
|
66
|
-
select_title (MediaItem): The selected media item
|
|
82
|
+
select_title (MediaItem): The selected media item. Can be None if selection fails.
|
|
67
83
|
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
68
|
-
{'season': season_selection, 'episode': episode_selection}
|
|
84
|
+
e.g., {'season': season_selection, 'episode': episode_selection}
|
|
85
|
+
proxy (str, optional): The proxy to use for downloads.
|
|
69
86
|
"""
|
|
87
|
+
if not select_title:
|
|
88
|
+
if site_constant.TELEGRAM_BOT:
|
|
89
|
+
bot = get_bot_instance()
|
|
90
|
+
bot.send_message("No title selected or selection cancelled.", None)
|
|
91
|
+
else:
|
|
92
|
+
console.print("[yellow]No title selected or selection cancelled.")
|
|
93
|
+
return
|
|
94
|
+
|
|
70
95
|
if select_title.type == 'tv':
|
|
71
96
|
season_selection = None
|
|
72
97
|
episode_selection = None
|
|
@@ -75,56 +100,65 @@ def process_search_result(select_title, selections=None):
|
|
|
75
100
|
season_selection = selections.get('season')
|
|
76
101
|
episode_selection = selections.get('episode')
|
|
77
102
|
|
|
78
|
-
download_series(select_title, season_selection, episode_selection)
|
|
79
|
-
|
|
103
|
+
download_series(select_title, season_selection, episode_selection, proxy)
|
|
104
|
+
|
|
80
105
|
else:
|
|
81
|
-
download_film(select_title)
|
|
106
|
+
download_film(select_title, proxy)
|
|
82
107
|
|
|
83
108
|
def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None, selections: dict = None):
|
|
84
109
|
"""
|
|
85
110
|
Main function of the application for search.
|
|
86
111
|
|
|
87
112
|
Parameters:
|
|
88
|
-
string_to_search (str, optional): String to search for
|
|
89
|
-
|
|
90
|
-
|
|
113
|
+
string_to_search (str, optional): String to search for. Can be passed from run.py.
|
|
114
|
+
If 'back', special handling might occur in get_user_input.
|
|
115
|
+
get_onlyDatabase (bool, optional): If True, return only the database search manager object.
|
|
116
|
+
direct_item (dict, optional): Direct item to process (bypasses search).
|
|
91
117
|
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
92
|
-
|
|
118
|
+
for series (season/episode).
|
|
93
119
|
"""
|
|
120
|
+
bot = None
|
|
121
|
+
if site_constant.TELEGRAM_BOT:
|
|
122
|
+
bot = get_bot_instance()
|
|
123
|
+
|
|
94
124
|
if direct_item:
|
|
95
|
-
|
|
96
|
-
process_search_result(
|
|
125
|
+
select_title_obj = MediaItem(**direct_item)
|
|
126
|
+
process_search_result(select_title_obj, selections, proxy)
|
|
97
127
|
return
|
|
128
|
+
|
|
129
|
+
# Check proxy if not already set
|
|
130
|
+
finder = ProxyFinder(site_constant.FULL_URL)
|
|
131
|
+
proxy = finder.find_fast_proxy()
|
|
98
132
|
|
|
99
|
-
|
|
100
|
-
if site_constant.TELEGRAM_BOT:
|
|
101
|
-
bot = get_bot_instance()
|
|
102
|
-
string_to_search = bot.ask(
|
|
103
|
-
"key_search",
|
|
104
|
-
f"Enter the search term\nor type 'back' to return to the menu: ",
|
|
105
|
-
None
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
if string_to_search == 'back':
|
|
133
|
+
actual_search_query = get_user_input(string_to_search)
|
|
109
134
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
135
|
+
# Handle cases where user input is empty, or 'back' was handled (sys.exit or None return)
|
|
136
|
+
if not actual_search_query:
|
|
137
|
+
if bot:
|
|
138
|
+
if actual_search_query is None: # Specifically for timeout from bot.ask or failed restart
|
|
139
|
+
bot.send_message("Search term not provided or operation cancelled. Returning.", None)
|
|
140
|
+
return
|
|
115
141
|
|
|
116
|
-
#
|
|
117
|
-
|
|
142
|
+
# Perform search on the database using the obtained query
|
|
143
|
+
finder = ProxyFinder(site_constant.FULL_URL)
|
|
144
|
+
proxy = finder.find_fast_proxy()
|
|
145
|
+
len_database = title_search(string_to_search, proxy)
|
|
118
146
|
|
|
119
|
-
# If only the database
|
|
147
|
+
# If only the database object (media_search_manager populated by title_search) is needed
|
|
120
148
|
if get_onlyDatabase:
|
|
121
|
-
return media_search_manager
|
|
149
|
+
return media_search_manager
|
|
122
150
|
|
|
123
151
|
if len_database > 0:
|
|
124
|
-
select_title = get_select_title(table_show_manager, media_search_manager)
|
|
125
|
-
process_search_result(select_title, selections)
|
|
152
|
+
select_title = get_select_title(table_show_manager, media_search_manager, len_database)
|
|
153
|
+
process_search_result(select_title, selections, proxy)
|
|
126
154
|
|
|
127
155
|
else:
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
156
|
+
no_results_message = f"No results found for: '{actual_search_query}'"
|
|
157
|
+
if bot:
|
|
158
|
+
bot.send_message(no_results_message, None)
|
|
159
|
+
else:
|
|
160
|
+
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{actual_search_query}")
|
|
161
|
+
|
|
162
|
+
# Do not call search() recursively here to avoid infinite loops on no results.
|
|
163
|
+
# The flow should return to the caller (e.g., main menu in run.py).
|
|
164
|
+
return
|
|
@@ -27,7 +27,7 @@ from StreamingCommunity.Api.Player.vixcloud import VideoSource
|
|
|
27
27
|
console = Console()
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
def download_film(select_title: MediaItem) -> str:
|
|
30
|
+
def download_film(select_title: MediaItem, proxy: str = None) -> str:
|
|
31
31
|
"""
|
|
32
32
|
Downloads a film using the provided film ID, title name, and domain.
|
|
33
33
|
|
|
@@ -55,7 +55,7 @@ def download_film(select_title: MediaItem) -> str:
|
|
|
55
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
|
-
video_source = VideoSource(f"{site_constant.FULL_URL}/it", False, select_title.id)
|
|
58
|
+
video_source = VideoSource(f"{site_constant.FULL_URL}/it", False, select_title.id, proxy)
|
|
59
59
|
|
|
60
60
|
# Retrieve scws and if available master playlist
|
|
61
61
|
video_source.get_iframe(select_title.id)
|
|
@@ -142,7 +142,7 @@ def download_episode(index_season_selected: int, scrape_serie: GetSerieInfo, vid
|
|
|
142
142
|
break
|
|
143
143
|
|
|
144
144
|
|
|
145
|
-
def download_series(select_season: MediaItem, season_selection: str = None, episode_selection: str = None) -> None:
|
|
145
|
+
def download_series(select_season: MediaItem, season_selection: str = None, episode_selection: str = None, proxy = None) -> None:
|
|
146
146
|
"""
|
|
147
147
|
Handle downloading a complete series.
|
|
148
148
|
|
|
@@ -154,8 +154,8 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
|
|
|
154
154
|
start_message()
|
|
155
155
|
|
|
156
156
|
# Init class
|
|
157
|
-
video_source = VideoSource(f"{site_constant.FULL_URL}/it", True, select_season.id)
|
|
158
|
-
scrape_serie = GetSerieInfo(f"{site_constant.FULL_URL}/it", select_season.id, select_season.slug)
|
|
157
|
+
video_source = VideoSource(f"{site_constant.FULL_URL}/it", True, select_season.id, proxy)
|
|
158
|
+
scrape_serie = GetSerieInfo(f"{site_constant.FULL_URL}/it", select_season.id, select_season.slug, proxy)
|
|
159
159
|
|
|
160
160
|
# Collect information about season
|
|
161
161
|
scrape_serie.getNumberSeason()
|
|
@@ -219,4 +219,4 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
|
|
|
219
219
|
# Get script_id
|
|
220
220
|
script_id = TelegramSession.get_session()
|
|
221
221
|
if script_id != "unknown":
|
|
222
|
-
TelegramSession.deleteScriptId(script_id)
|
|
222
|
+
TelegramSession.deleteScriptId(script_id)
|
|
@@ -28,7 +28,7 @@ table_show_manager = TVShowManager()
|
|
|
28
28
|
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
def title_search(query: str) -> int:
|
|
31
|
+
def title_search(query: str, proxy: str) -> int:
|
|
32
32
|
"""
|
|
33
33
|
Search for titles based on a search query.
|
|
34
34
|
|
|
@@ -48,7 +48,8 @@ def title_search(query: str) -> int:
|
|
|
48
48
|
response = httpx.get(
|
|
49
49
|
f"{site_constant.FULL_URL}/it",
|
|
50
50
|
headers={'user-agent': get_userAgent()},
|
|
51
|
-
timeout=max_timeout
|
|
51
|
+
timeout=max_timeout,
|
|
52
|
+
proxy=proxy
|
|
52
53
|
)
|
|
53
54
|
response.raise_for_status()
|
|
54
55
|
|
|
@@ -56,6 +57,7 @@ def title_search(query: str) -> int:
|
|
|
56
57
|
version = json.loads(soup.find('div', {'id': "app"}).get("data-page"))['version']
|
|
57
58
|
|
|
58
59
|
except Exception as e:
|
|
60
|
+
if "WinError" in str(e) or "Errno" in str(e): console.print("\n[bold yellow]Please make sure you have enabled and configured a valid proxy.[/bold yellow]")
|
|
59
61
|
console.print(f"[red]Site: {site_constant.SITE_NAME} version, request error: {e}")
|
|
60
62
|
return 0
|
|
61
63
|
|
|
@@ -71,7 +73,8 @@ def title_search(query: str) -> int:
|
|
|
71
73
|
'x-inertia': 'true',
|
|
72
74
|
'x-inertia-version': version
|
|
73
75
|
},
|
|
74
|
-
timeout=max_timeout
|
|
76
|
+
timeout=max_timeout,
|
|
77
|
+
proxy=proxy
|
|
75
78
|
)
|
|
76
79
|
response.raise_for_status()
|
|
77
80
|
|
|
@@ -117,4 +120,4 @@ def title_search(query: str) -> int:
|
|
|
117
120
|
bot.send_message(f"Lista dei risultati:", choices)
|
|
118
121
|
|
|
119
122
|
# Return the number of titles found
|
|
120
|
-
return media_search_manager.get_length()
|
|
123
|
+
return media_search_manager.get_length()
|
|
@@ -20,7 +20,7 @@ max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class GetSerieInfo:
|
|
23
|
-
def __init__(self, url, media_id: int = None, series_name: str = None):
|
|
23
|
+
def __init__(self, url, media_id: int = None, series_name: str = None, proxy = None):
|
|
24
24
|
"""
|
|
25
25
|
Initialize the GetSerieInfo class for scraping TV series information.
|
|
26
26
|
|
|
@@ -32,6 +32,7 @@ class GetSerieInfo:
|
|
|
32
32
|
self.is_series = False
|
|
33
33
|
self.headers = {'user-agent': get_userAgent()}
|
|
34
34
|
self.url = url
|
|
35
|
+
self.proxy = proxy
|
|
35
36
|
self.media_id = media_id
|
|
36
37
|
self.seasons_manager = SeasonManager()
|
|
37
38
|
|
|
@@ -50,7 +51,8 @@ class GetSerieInfo:
|
|
|
50
51
|
response = httpx.get(
|
|
51
52
|
url=f"{self.url}/titles/{self.media_id}-{self.series_name}",
|
|
52
53
|
headers=self.headers,
|
|
53
|
-
timeout=max_timeout
|
|
54
|
+
timeout=max_timeout,
|
|
55
|
+
proxy=self.proxy
|
|
54
56
|
)
|
|
55
57
|
response.raise_for_status()
|
|
56
58
|
|
|
@@ -104,7 +106,8 @@ class GetSerieInfo:
|
|
|
104
106
|
'x-inertia': 'true',
|
|
105
107
|
'x-inertia-version': self.version,
|
|
106
108
|
},
|
|
107
|
-
timeout=max_timeout
|
|
109
|
+
timeout=max_timeout,
|
|
110
|
+
proxy=self.proxy
|
|
108
111
|
)
|
|
109
112
|
|
|
110
113
|
# Extract episodes from JSON response
|
|
@@ -21,12 +21,13 @@ from .series import download_series
|
|
|
21
21
|
# Variable
|
|
22
22
|
indice = 7
|
|
23
23
|
_useFor = "Film_&_Serie"
|
|
24
|
-
_priority =
|
|
24
|
+
_priority = 0
|
|
25
25
|
_engineDownload = "hls"
|
|
26
26
|
_deprecate = False
|
|
27
27
|
|
|
28
28
|
msg = Prompt()
|
|
29
29
|
console = Console()
|
|
30
|
+
proxy = None
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
def get_user_input(string_to_search: str = None):
|
|
@@ -74,20 +75,25 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
|
|
|
74
75
|
select_title = MediaItem(**direct_item)
|
|
75
76
|
process_search_result(select_title, selections) # DONT SUPPORT PROXY FOR NOW
|
|
76
77
|
return
|
|
78
|
+
|
|
79
|
+
# Check proxy if not already set
|
|
80
|
+
finder = ProxyFinder(site_constant.FULL_URL)
|
|
81
|
+
proxy = finder.find_fast_proxy()
|
|
77
82
|
|
|
78
83
|
if string_to_search is None:
|
|
79
84
|
string_to_search = msg.ask(f"\n[purple]Insert a word to search in [green]{site_constant.SITE_NAME}").strip()
|
|
80
85
|
|
|
86
|
+
# Perform search on the database using the obtained query
|
|
81
87
|
finder = ProxyFinder(url=f"{site_constant.FULL_URL}/serie/euphoria/")
|
|
82
|
-
proxy
|
|
83
|
-
len_database = title_search(string_to_search,
|
|
88
|
+
proxy = finder.find_fast_proxy()
|
|
89
|
+
len_database = title_search(string_to_search, proxy)
|
|
84
90
|
|
|
85
91
|
# If only the database is needed, return the manager
|
|
86
92
|
if get_onlyDatabase:
|
|
87
93
|
return media_search_manager
|
|
88
94
|
|
|
89
95
|
if len_database > 0:
|
|
90
|
-
select_title = get_select_title(table_show_manager, media_search_manager)
|
|
96
|
+
select_title = get_select_title(table_show_manager, media_search_manager,len_database)
|
|
91
97
|
process_search_result(select_title, selections, proxy)
|
|
92
98
|
|
|
93
99
|
else:
|
|
@@ -27,9 +27,16 @@ table_show_manager = TVShowManager()
|
|
|
27
27
|
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
def extract_nonce(
|
|
30
|
+
def extract_nonce(proxy) -> str:
|
|
31
31
|
"""Extract nonce value from the page script"""
|
|
32
|
-
|
|
32
|
+
response = httpx.get(
|
|
33
|
+
site_constant.FULL_URL,
|
|
34
|
+
headers={'user-agent': get_userAgent()},
|
|
35
|
+
timeout=max_timeout,
|
|
36
|
+
proxy=proxy
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
soup = BeautifulSoup(response.content, 'html.parser')
|
|
33
40
|
script = soup.find('script', id='live-search-js-extra')
|
|
34
41
|
if script:
|
|
35
42
|
match = re.search(r'"admin_ajax_nonce":"([^"]+)"', script.text)
|
|
@@ -38,7 +45,7 @@ def extract_nonce(response_) -> str:
|
|
|
38
45
|
return ""
|
|
39
46
|
|
|
40
47
|
|
|
41
|
-
def title_search(query: str,
|
|
48
|
+
def title_search(query: str, proxy: str) -> int:
|
|
42
49
|
"""
|
|
43
50
|
Search for titles based on a search query.
|
|
44
51
|
|
|
@@ -51,12 +58,11 @@ def title_search(query: str, additionalData: list) -> int:
|
|
|
51
58
|
media_search_manager.clear()
|
|
52
59
|
table_show_manager.clear()
|
|
53
60
|
|
|
54
|
-
proxy, response_serie = additionalData
|
|
55
61
|
search_url = f"{site_constant.FULL_URL}/wp-admin/admin-ajax.php"
|
|
56
62
|
console.print(f"[cyan]Search url: [yellow]{search_url}")
|
|
57
63
|
|
|
58
64
|
try:
|
|
59
|
-
_wpnonce = extract_nonce(
|
|
65
|
+
_wpnonce = extract_nonce(proxy)
|
|
60
66
|
|
|
61
67
|
if not _wpnonce:
|
|
62
68
|
console.print("[red]Error: Failed to extract nonce")
|
|
@@ -82,6 +88,7 @@ def title_search(query: str, additionalData: list) -> int:
|
|
|
82
88
|
soup = BeautifulSoup(response.text, 'html.parser')
|
|
83
89
|
|
|
84
90
|
except Exception as e:
|
|
91
|
+
if "WinError" in str(e) or "Errno" in str(e): console.print("\n[bold yellow]Please make sure you have enabled and configured a valid proxy.[/bold yellow]")
|
|
85
92
|
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
86
93
|
return 0
|
|
87
94
|
|
|
@@ -7,78 +7,123 @@ import sys
|
|
|
7
7
|
from rich.console import Console
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
# Internal utilities
|
|
11
|
+
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
12
|
+
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
|
|
13
|
+
|
|
10
14
|
# Variable
|
|
11
15
|
console = Console()
|
|
12
16
|
available_colors = ['red', 'magenta', 'yellow', 'cyan', 'green', 'blue', 'white']
|
|
13
17
|
column_to_hide = ['Slug', 'Sub_ita', 'Last_air_date', 'Seasons_count', 'Url', 'Image', 'Path_id']
|
|
14
18
|
|
|
15
19
|
|
|
16
|
-
def get_select_title(table_show_manager, media_search_manager):
|
|
20
|
+
def get_select_title(table_show_manager, media_search_manager, num_results_available):
|
|
17
21
|
"""
|
|
18
22
|
Display a selection of titles and prompt the user to choose one.
|
|
23
|
+
Handles both console and Telegram bot input.
|
|
24
|
+
|
|
25
|
+
Parameters:
|
|
26
|
+
table_show_manager: Manager for console table display.
|
|
27
|
+
media_search_manager: Manager holding the list of media items.
|
|
28
|
+
num_results_available (int): The number of media items available for selection.
|
|
19
29
|
|
|
20
30
|
Returns:
|
|
21
|
-
MediaItem: The selected media item.
|
|
31
|
+
MediaItem: The selected media item, or None if no selection is made or an error occurs.
|
|
22
32
|
"""
|
|
23
|
-
# Determine column_info dynamically for (search site)
|
|
24
33
|
if not media_search_manager.media_list:
|
|
25
|
-
|
|
34
|
+
|
|
35
|
+
# console.print("\n[red]No media items available.")
|
|
26
36
|
return None
|
|
27
|
-
|
|
28
|
-
# Example of available colors for columns
|
|
29
|
-
available_colors = ['red', 'magenta', 'yellow', 'cyan', 'green', 'blue', 'white']
|
|
30
|
-
|
|
31
|
-
# Retrieve the keys of the first media item as column headers
|
|
32
|
-
first_media_item = media_search_manager.media_list[0]
|
|
33
|
-
column_info = {"Index": {'color': available_colors[0]}} # Always include Index with a fixed color
|
|
34
|
-
|
|
35
|
-
# Assign colors to the remaining keys dynamically
|
|
36
|
-
color_index = 1
|
|
37
|
-
for key in first_media_item.__dict__.keys():
|
|
38
|
-
|
|
39
|
-
if key.capitalize() in column_to_hide:
|
|
40
|
-
continue
|
|
41
|
-
|
|
42
|
-
if key in ('id', 'type', 'name', 'score'): # Custom prioritization of colors
|
|
43
|
-
if key == 'type':
|
|
44
|
-
column_info["Type"] = {'color': 'yellow'}
|
|
45
|
-
elif key == 'name':
|
|
46
|
-
column_info["Name"] = {'color': 'magenta'}
|
|
47
|
-
elif key == 'score':
|
|
48
|
-
column_info["Score"] = {'color': 'cyan'}
|
|
49
|
-
|
|
50
|
-
else:
|
|
51
|
-
column_info[key.capitalize()] = {'color': available_colors[color_index % len(available_colors)]}
|
|
52
|
-
color_index += 1
|
|
53
|
-
|
|
54
|
-
table_show_manager.add_column(column_info)
|
|
55
|
-
|
|
56
|
-
# Populate the table with title information
|
|
57
|
-
for i, media in enumerate(media_search_manager.media_list):
|
|
58
|
-
media_dict = {'Index': str(i)}
|
|
59
37
|
|
|
38
|
+
if site_constant.TELEGRAM_BOT:
|
|
39
|
+
bot = get_bot_instance()
|
|
40
|
+
prompt_message = f"Inserisci il numero del titolo che vuoi selezionare (da 0 a {num_results_available - 1}):"
|
|
41
|
+
|
|
42
|
+
user_input_str = bot.ask(
|
|
43
|
+
"select_title_from_list_number",
|
|
44
|
+
prompt_message,
|
|
45
|
+
None
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
if user_input_str is None:
|
|
49
|
+
bot.send_message("Timeout: nessuna selezione ricevuta.", None)
|
|
50
|
+
return None
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
chosen_index = int(user_input_str)
|
|
54
|
+
if 0 <= chosen_index < num_results_available:
|
|
55
|
+
selected_item = media_search_manager.get(chosen_index)
|
|
56
|
+
if selected_item:
|
|
57
|
+
return selected_item
|
|
58
|
+
|
|
59
|
+
else:
|
|
60
|
+
bot.send_message(f"Errore interno: Impossibile recuperare il titolo con indice {chosen_index}.", None)
|
|
61
|
+
return None
|
|
62
|
+
else:
|
|
63
|
+
bot.send_message(f"Selezione '{chosen_index}' non valida. Inserisci un numero compreso tra 0 e {num_results_available - 1}.", None)
|
|
64
|
+
return None
|
|
65
|
+
|
|
66
|
+
except ValueError:
|
|
67
|
+
bot.send_message(f"Input '{user_input_str}' non valido. Devi inserire un numero.", None)
|
|
68
|
+
return None
|
|
69
|
+
|
|
70
|
+
except Exception as e:
|
|
71
|
+
bot.send_message(f"Si è verificato un errore durante la selezione: {e}", None)
|
|
72
|
+
return None
|
|
73
|
+
|
|
74
|
+
else:
|
|
75
|
+
|
|
76
|
+
# Logica originale per la console
|
|
77
|
+
if not media_search_manager.media_list:
|
|
78
|
+
console.print("\n[red]No media items available.")
|
|
79
|
+
return None
|
|
80
|
+
|
|
81
|
+
first_media_item = media_search_manager.media_list[0]
|
|
82
|
+
column_info = {"Index": {'color': available_colors[0]}}
|
|
83
|
+
|
|
84
|
+
color_index = 1
|
|
60
85
|
for key in first_media_item.__dict__.keys():
|
|
61
86
|
if key.capitalize() in column_to_hide:
|
|
62
87
|
continue
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
88
|
+
if key in ('id', 'type', 'name', 'score'):
|
|
89
|
+
if key == 'type': column_info["Type"] = {'color': 'yellow'}
|
|
90
|
+
elif key == 'name': column_info["Name"] = {'color': 'magenta'}
|
|
91
|
+
elif key == 'score': column_info["Score"] = {'color': 'cyan'}
|
|
92
|
+
else:
|
|
93
|
+
column_info[key.capitalize()] = {'color': available_colors[color_index % len(available_colors)]}
|
|
94
|
+
color_index += 1
|
|
95
|
+
|
|
96
|
+
table_show_manager.clear()
|
|
97
|
+
table_show_manager.add_column(column_info)
|
|
98
|
+
|
|
99
|
+
for i, media in enumerate(media_search_manager.media_list):
|
|
100
|
+
media_dict = {'Index': str(i)}
|
|
101
|
+
for key in first_media_item.__dict__.keys():
|
|
102
|
+
if key.capitalize() in column_to_hide:
|
|
103
|
+
continue
|
|
104
|
+
media_dict[key.capitalize()] = str(getattr(media, key))
|
|
105
|
+
table_show_manager.add_tv_show(media_dict)
|
|
106
|
+
|
|
107
|
+
last_command_str = table_show_manager.run(force_int_input=True, max_int_input=len(media_search_manager.media_list))
|
|
108
|
+
table_show_manager.clear()
|
|
109
|
+
|
|
110
|
+
if last_command_str is None or last_command_str.lower() in ["q", "quit"]:
|
|
111
|
+
console.print("\n[red]Selezione annullata o uscita.")
|
|
112
|
+
return None
|
|
113
|
+
|
|
114
|
+
try:
|
|
115
|
+
|
|
116
|
+
selected_index = int(last_command_str)
|
|
117
|
+
|
|
118
|
+
if 0 <= selected_index < len(media_search_manager.media_list):
|
|
119
|
+
return media_search_manager.get(selected_index)
|
|
120
|
+
|
|
121
|
+
else:
|
|
122
|
+
console.print("\n[red]Indice errato o non valido.")
|
|
123
|
+
# sys.exit(0)
|
|
124
|
+
return None
|
|
125
|
+
|
|
126
|
+
except ValueError:
|
|
127
|
+
console.print("\n[red]Input non numerico ricevuto dalla tabella.")
|
|
128
|
+
# sys.exit(0)
|
|
129
|
+
return None
|