StreamingCommunity 3.2.9__py3-none-any.whl → 3.3.1__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/Site/altadefinizione/__init__.py +67 -30
- StreamingCommunity/Api/Site/animeunity/__init__.py +65 -29
- StreamingCommunity/Api/Site/animeworld/__init__.py +80 -10
- StreamingCommunity/Api/Site/crunchyroll/__init__.py +75 -15
- StreamingCommunity/Api/Site/crunchyroll/site.py +7 -1
- StreamingCommunity/Api/Site/guardaserie/__init__.py +80 -10
- StreamingCommunity/Api/Site/mediasetinfinity/__init__.py +78 -15
- StreamingCommunity/Api/Site/mediasetinfinity/film.py +1 -1
- StreamingCommunity/Api/Site/mediasetinfinity/site.py +12 -2
- StreamingCommunity/Api/Site/mediasetinfinity/util/ScrapeSerie.py +6 -7
- StreamingCommunity/Api/Site/mediasetinfinity/util/get_license.py +162 -0
- StreamingCommunity/Api/Site/raiplay/__init__.py +78 -12
- StreamingCommunity/Api/Site/raiplay/film.py +2 -1
- StreamingCommunity/Api/Site/raiplay/series.py +21 -7
- StreamingCommunity/Api/Site/streamingcommunity/__init__.py +12 -9
- StreamingCommunity/Api/Site/streamingcommunity/site.py +4 -1
- StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +5 -2
- StreamingCommunity/Api/Site/streamingwatch/__init__.py +76 -12
- StreamingCommunity/Lib/Downloader/DASH/cdm_helpher.py +8 -0
- StreamingCommunity/Lib/Downloader/DASH/downloader.py +109 -75
- StreamingCommunity/Lib/Downloader/HLS/downloader.py +18 -6
- StreamingCommunity/Lib/Downloader/HLS/segments.py +1 -1
- StreamingCommunity/Lib/Downloader/MP4/downloader.py +21 -3
- StreamingCommunity/Lib/FFmpeg/command.py +66 -7
- StreamingCommunity/Lib/FFmpeg/util.py +16 -13
- StreamingCommunity/Upload/update.py +2 -2
- StreamingCommunity/Upload/version.py +2 -2
- StreamingCommunity/Util/os.py +4 -1
- StreamingCommunity/run.py +4 -4
- {streamingcommunity-3.2.9.dist-info → streamingcommunity-3.3.1.dist-info}/METADATA +2 -7
- {streamingcommunity-3.2.9.dist-info → streamingcommunity-3.3.1.dist-info}/RECORD +35 -38
- StreamingCommunity/Api/Site/cb01new/__init__.py +0 -72
- StreamingCommunity/Api/Site/cb01new/film.py +0 -64
- StreamingCommunity/Api/Site/cb01new/site.py +0 -78
- {streamingcommunity-3.2.9.dist-info → streamingcommunity-3.3.1.dist-info}/WHEEL +0 -0
- {streamingcommunity-3.2.9.dist-info → streamingcommunity-3.3.1.dist-info}/entry_points.txt +0 -0
- {streamingcommunity-3.2.9.dist-info → streamingcommunity-3.3.1.dist-info}/licenses/LICENSE +0 -0
- {streamingcommunity-3.2.9.dist-info → streamingcommunity-3.3.1.dist-info}/top_level.txt +0 -0
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# 21.05.24
|
|
2
2
|
|
|
3
|
+
import sys
|
|
4
|
+
import subprocess
|
|
5
|
+
|
|
3
6
|
|
|
4
7
|
# External library
|
|
5
8
|
from rich.console import Console
|
|
@@ -10,6 +13,7 @@ from rich.prompt import Prompt
|
|
|
10
13
|
from StreamingCommunity.Api.Template import get_select_title
|
|
11
14
|
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
12
15
|
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
16
|
+
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
|
|
13
17
|
|
|
14
18
|
|
|
15
19
|
# Logic class
|
|
@@ -32,8 +36,40 @@ console = Console()
|
|
|
32
36
|
def get_user_input(string_to_search: str = None):
|
|
33
37
|
"""
|
|
34
38
|
Asks the user to input a search term.
|
|
39
|
+
Handles both Telegram bot input and direct input.
|
|
40
|
+
If string_to_search is provided, it's returned directly (after stripping).
|
|
35
41
|
"""
|
|
36
|
-
|
|
42
|
+
if string_to_search is not None:
|
|
43
|
+
return string_to_search.strip()
|
|
44
|
+
|
|
45
|
+
if site_constant.TELEGRAM_BOT:
|
|
46
|
+
bot = get_bot_instance()
|
|
47
|
+
user_response = bot.ask(
|
|
48
|
+
"key_search", # Request type
|
|
49
|
+
"Enter the search term\nor type 'back' to return to the menu: ",
|
|
50
|
+
None
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
if user_response is None:
|
|
54
|
+
bot.send_message("Timeout: No search term entered.", None)
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
if user_response.lower() == 'back':
|
|
58
|
+
bot.send_message("Returning to the main menu...", None)
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
# Restart the script
|
|
62
|
+
subprocess.Popen([sys.executable] + sys.argv)
|
|
63
|
+
sys.exit()
|
|
64
|
+
|
|
65
|
+
except Exception as e:
|
|
66
|
+
bot.send_message(f"Error during restart attempt: {e}", None)
|
|
67
|
+
return None # Return None if restart fails
|
|
68
|
+
|
|
69
|
+
return user_response.strip()
|
|
70
|
+
|
|
71
|
+
else:
|
|
72
|
+
return msg.ask(f"\n[purple]Insert a word to search in [green]{site_constant.SITE_NAME}").strip()
|
|
37
73
|
|
|
38
74
|
def process_search_result(select_title, selections=None):
|
|
39
75
|
"""
|
|
@@ -43,7 +79,18 @@ def process_search_result(select_title, selections=None):
|
|
|
43
79
|
select_title (MediaItem): The selected media item
|
|
44
80
|
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
45
81
|
{'season': season_selection, 'episode': episode_selection}
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
bool: True if processing was successful, False otherwise
|
|
46
85
|
"""
|
|
86
|
+
if not select_title:
|
|
87
|
+
if site_constant.TELEGRAM_BOT:
|
|
88
|
+
bot = get_bot_instance()
|
|
89
|
+
bot.send_message("No title selected or selection cancelled.", None)
|
|
90
|
+
else:
|
|
91
|
+
console.print("[yellow]No title selected or selection cancelled.")
|
|
92
|
+
return False
|
|
93
|
+
|
|
47
94
|
if select_title.type == 'tv':
|
|
48
95
|
season_selection = None
|
|
49
96
|
episode_selection = None
|
|
@@ -53,9 +100,11 @@ def process_search_result(select_title, selections=None):
|
|
|
53
100
|
episode_selection = selections.get('episode')
|
|
54
101
|
|
|
55
102
|
download_series(select_title, season_selection, episode_selection)
|
|
103
|
+
return True
|
|
56
104
|
|
|
57
105
|
else:
|
|
58
106
|
download_film(select_title)
|
|
107
|
+
return True
|
|
59
108
|
|
|
60
109
|
def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None, selections: dict = None):
|
|
61
110
|
"""
|
|
@@ -68,26 +117,43 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
|
|
|
68
117
|
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
69
118
|
{'season': season_selection, 'episode': episode_selection}
|
|
70
119
|
"""
|
|
120
|
+
bot = None
|
|
121
|
+
if site_constant.TELEGRAM_BOT:
|
|
122
|
+
bot = get_bot_instance()
|
|
123
|
+
|
|
71
124
|
if direct_item:
|
|
72
125
|
select_title = MediaItem(**direct_item)
|
|
73
126
|
process_search_result(select_title, selections)
|
|
127
|
+
return True
|
|
128
|
+
|
|
129
|
+
# Get the user input for the search term
|
|
130
|
+
actual_search_query = get_user_input(string_to_search)
|
|
131
|
+
|
|
132
|
+
# Handle cases where user input is empty, or 'back' was handled (sys.exit or None return)
|
|
133
|
+
if not actual_search_query:
|
|
134
|
+
if bot:
|
|
135
|
+
if actual_search_query is None: # Specifically for timeout from bot.ask or failed restart
|
|
136
|
+
bot.send_message("Search term not provided or operation cancelled. Returning.", None)
|
|
74
137
|
return
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
# Search on database
|
|
80
|
-
len_database = title_search(string_to_search)
|
|
138
|
+
|
|
139
|
+
# Perform the database search
|
|
140
|
+
len_database = title_search(actual_search_query)
|
|
81
141
|
|
|
82
142
|
# If only the database is needed, return the manager
|
|
83
143
|
if get_onlyDatabase:
|
|
84
144
|
return media_search_manager
|
|
85
|
-
|
|
145
|
+
|
|
86
146
|
if len_database > 0:
|
|
87
|
-
select_title = get_select_title(table_show_manager, media_search_manager,len_database)
|
|
147
|
+
select_title = get_select_title(table_show_manager, media_search_manager, len_database)
|
|
88
148
|
process_search_result(select_title, selections)
|
|
149
|
+
return True
|
|
89
150
|
|
|
90
151
|
else:
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
152
|
+
if bot:
|
|
153
|
+
bot.send_message(f"No results found for: '{actual_search_query}'", None)
|
|
154
|
+
else:
|
|
155
|
+
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{actual_search_query}")
|
|
156
|
+
|
|
157
|
+
# Do not call search() recursively here to avoid infinite loops on no results.
|
|
158
|
+
# The flow should return to the caller (e.g., main menu in run.py).
|
|
159
|
+
return
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# 21.05.24
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
|
+
import sys
|
|
4
5
|
from typing import Tuple
|
|
5
6
|
|
|
6
7
|
|
|
@@ -68,7 +69,7 @@ def download_film(select_title: MediaItem) -> Tuple[str, bool]:
|
|
|
68
69
|
cdm_device_path = get_wvd_path()
|
|
69
70
|
if not cdm_device_path or not isinstance(cdm_device_path, (str, bytes, os.PathLike)) or not os.path.isfile(cdm_device_path):
|
|
70
71
|
console.print(f"[bold red] CDM file not found or invalid path: {cdm_device_path}[/bold red]")
|
|
71
|
-
|
|
72
|
+
sys.exit(0)
|
|
72
73
|
|
|
73
74
|
license_url = generate_license_url(select_title.mpd_id)
|
|
74
75
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# 21.05.24
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
|
+
import sys
|
|
4
5
|
from typing import Tuple
|
|
5
6
|
|
|
6
7
|
|
|
@@ -10,7 +11,7 @@ from rich.prompt import Prompt
|
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
# Internal utilities
|
|
13
|
-
from StreamingCommunity.Util.headers import get_headers
|
|
14
|
+
from StreamingCommunity.Util.headers import get_headers, get_userAgent
|
|
14
15
|
from StreamingCommunity.Util.os import get_wvd_path
|
|
15
16
|
from StreamingCommunity.Util.message import start_message
|
|
16
17
|
|
|
@@ -57,7 +58,7 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
|
|
|
57
58
|
|
|
58
59
|
# Get episode information
|
|
59
60
|
obj_episode = scrape_serie.selectEpisode(index_season_selected, index_episode_selected-1)
|
|
60
|
-
console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [
|
|
61
|
+
console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [bold magenta]{obj_episode.name}[/bold magenta] ([cyan]S{index_season_selected}E{index_episode_selected}[/cyan]) \n")
|
|
61
62
|
|
|
62
63
|
# Define filename and path
|
|
63
64
|
mp4_name = f"{map_episode_title(scrape_serie.series_name, index_season_selected, index_episode_selected, obj_episode.name)}.mp4"
|
|
@@ -66,6 +67,15 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
|
|
|
66
67
|
# Get streaming URL
|
|
67
68
|
master_playlist = VideoSource.extract_m3u8_url(obj_episode.url)
|
|
68
69
|
|
|
70
|
+
# HLS
|
|
71
|
+
if ".mpd" not in master_playlist:
|
|
72
|
+
r_proc = HLS_Downloader(
|
|
73
|
+
m3u8_url=master_playlist,
|
|
74
|
+
output_path=os.path.join(mp4_path, mp4_name)
|
|
75
|
+
).start()
|
|
76
|
+
# Get streaming URL
|
|
77
|
+
master_playlist = VideoSource.extract_m3u8_url(obj_episode.url)
|
|
78
|
+
|
|
69
79
|
# HLS
|
|
70
80
|
if ".mpd" not in master_playlist:
|
|
71
81
|
r_proc = HLS_Downloader(
|
|
@@ -80,19 +90,23 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
|
|
|
80
90
|
cdm_device_path = get_wvd_path()
|
|
81
91
|
if not cdm_device_path or not isinstance(cdm_device_path, (str, bytes, os.PathLike)) or not os.path.isfile(cdm_device_path):
|
|
82
92
|
console.print(f"[bold red] CDM file not found or invalid path: {cdm_device_path}[/bold red]")
|
|
83
|
-
|
|
93
|
+
sys.exit(0)
|
|
84
94
|
|
|
85
|
-
|
|
95
|
+
full_license_url = generate_license_url(obj_episode.mpd_id)
|
|
96
|
+
license_headers = {
|
|
97
|
+
'nv-authorizations': full_license_url.split("?")[1].split("=")[1],
|
|
98
|
+
'user-agent': get_userAgent(),
|
|
99
|
+
}
|
|
86
100
|
|
|
87
101
|
dash_process = DASH_Downloader(
|
|
88
102
|
cdm_device=cdm_device_path,
|
|
89
|
-
license_url=
|
|
103
|
+
license_url=full_license_url.split("?")[0],
|
|
90
104
|
mpd_url=master_playlist,
|
|
91
105
|
output_path=os.path.join(mp4_path, mp4_name),
|
|
92
106
|
)
|
|
93
107
|
dash_process.parse_manifest(custom_headers=get_headers())
|
|
94
108
|
|
|
95
|
-
if dash_process.download_and_decrypt():
|
|
109
|
+
if dash_process.download_and_decrypt(custom_headers=license_headers):
|
|
96
110
|
dash_process.finalize_output()
|
|
97
111
|
|
|
98
112
|
# Get final output path and status
|
|
@@ -192,4 +206,4 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
|
|
|
192
206
|
if len(list_season_select) > 1 or index_season_selected == "*":
|
|
193
207
|
download_episode(season_number, scrape_serie, download_all=True)
|
|
194
208
|
else:
|
|
195
|
-
download_episode(season_number, scrape_serie, download_all=False, episode_selection=episode_selection)
|
|
209
|
+
download_episode(season_number, scrape_serie, download_all=False, episode_selection=episode_selection)
|
|
@@ -15,7 +15,6 @@ from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
|
15
15
|
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
16
16
|
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
|
|
17
17
|
|
|
18
|
-
|
|
19
18
|
# Logic class
|
|
20
19
|
from .site import title_search, table_show_manager, media_search_manager
|
|
21
20
|
from .film import download_film
|
|
@@ -24,7 +23,7 @@ from .series import download_series
|
|
|
24
23
|
|
|
25
24
|
# Variable
|
|
26
25
|
indice = 0
|
|
27
|
-
_useFor = "Film_&_Serie"
|
|
26
|
+
_useFor = "Film_&_Serie"
|
|
28
27
|
_priority = 0
|
|
29
28
|
_engineDownload = "hls"
|
|
30
29
|
_deprecate = False
|
|
@@ -79,6 +78,8 @@ def process_search_result(select_title, selections=None):
|
|
|
79
78
|
select_title (MediaItem): The selected media item. Can be None if selection fails.
|
|
80
79
|
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
81
80
|
e.g., {'season': season_selection, 'episode': episode_selection}
|
|
81
|
+
Returns:
|
|
82
|
+
bool: True if processing was successful, False otherwise
|
|
82
83
|
"""
|
|
83
84
|
if not select_title:
|
|
84
85
|
if site_constant.TELEGRAM_BOT:
|
|
@@ -86,7 +87,7 @@ def process_search_result(select_title, selections=None):
|
|
|
86
87
|
bot.send_message("No title selected or selection cancelled.", None)
|
|
87
88
|
else:
|
|
88
89
|
console.print("[yellow]No title selected or selection cancelled.")
|
|
89
|
-
return
|
|
90
|
+
return False
|
|
90
91
|
|
|
91
92
|
if select_title.type == 'tv':
|
|
92
93
|
season_selection = None
|
|
@@ -97,9 +98,11 @@ def process_search_result(select_title, selections=None):
|
|
|
97
98
|
episode_selection = selections.get('episode')
|
|
98
99
|
|
|
99
100
|
download_series(select_title, season_selection, episode_selection)
|
|
101
|
+
return True
|
|
100
102
|
|
|
101
103
|
else:
|
|
102
104
|
download_film(select_title)
|
|
105
|
+
return True
|
|
103
106
|
|
|
104
107
|
def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None, selections: dict = None):
|
|
105
108
|
"""
|
|
@@ -120,14 +123,14 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
|
|
|
120
123
|
if direct_item:
|
|
121
124
|
select_title_obj = MediaItem(**direct_item)
|
|
122
125
|
process_search_result(select_title_obj, selections)
|
|
123
|
-
return
|
|
126
|
+
return True
|
|
124
127
|
|
|
125
128
|
actual_search_query = get_user_input(string_to_search)
|
|
126
129
|
|
|
127
130
|
# Handle cases where user input is empty, or 'back' was handled (sys.exit or None return)
|
|
128
|
-
if not actual_search_query:
|
|
131
|
+
if not actual_search_query:
|
|
129
132
|
if bot:
|
|
130
|
-
|
|
133
|
+
if actual_search_query is None: # Specifically for timeout from bot.ask or failed restart
|
|
131
134
|
bot.send_message("Search term not provided or operation cancelled. Returning.", None)
|
|
132
135
|
return
|
|
133
136
|
|
|
@@ -136,16 +139,16 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
|
|
|
136
139
|
|
|
137
140
|
# If only the database object (media_search_manager populated by title_search) is needed
|
|
138
141
|
if get_onlyDatabase:
|
|
139
|
-
return media_search_manager
|
|
142
|
+
return media_search_manager
|
|
140
143
|
|
|
141
144
|
if len_database > 0:
|
|
142
145
|
select_title = get_select_title(table_show_manager, media_search_manager, len_database)
|
|
143
146
|
process_search_result(select_title, selections)
|
|
147
|
+
return True
|
|
144
148
|
|
|
145
149
|
else:
|
|
146
|
-
no_results_message = f"No results found for: '{actual_search_query}'"
|
|
147
150
|
if bot:
|
|
148
|
-
bot.send_message(
|
|
151
|
+
bot.send_message(f"No results found for: '{actual_search_query}'", None)
|
|
149
152
|
else:
|
|
150
153
|
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{actual_search_query}")
|
|
151
154
|
|
|
@@ -26,6 +26,7 @@ console = Console()
|
|
|
26
26
|
media_search_manager = MediaManager()
|
|
27
27
|
table_show_manager = TVShowManager()
|
|
28
28
|
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
29
|
+
ssl_verify = config_manager.get_bool("REQUESTS", "verify")
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
def title_search(query: str) -> int:
|
|
@@ -49,6 +50,7 @@ def title_search(query: str) -> int:
|
|
|
49
50
|
f"{site_constant.FULL_URL}/it",
|
|
50
51
|
headers={'user-agent': get_userAgent()},
|
|
51
52
|
timeout=max_timeout,
|
|
53
|
+
verify=ssl_verify,
|
|
52
54
|
follow_redirects=True
|
|
53
55
|
)
|
|
54
56
|
response.raise_for_status()
|
|
@@ -75,7 +77,8 @@ def title_search(query: str) -> int:
|
|
|
75
77
|
'x-inertia': 'true',
|
|
76
78
|
'x-inertia-version': version
|
|
77
79
|
},
|
|
78
|
-
timeout=max_timeout
|
|
80
|
+
timeout=max_timeout,
|
|
81
|
+
verify=ssl_verify
|
|
79
82
|
)
|
|
80
83
|
response.raise_for_status()
|
|
81
84
|
|
|
@@ -17,6 +17,7 @@ from StreamingCommunity.Api.Player.Helper.Vixcloud.util import SeasonManager
|
|
|
17
17
|
|
|
18
18
|
# Variable
|
|
19
19
|
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
20
|
+
ssl_verify = config_manager.get_bool("REQUESTS", "verify")
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
class GetSerieInfo:
|
|
@@ -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
|
+
verify=ssl_verify
|
|
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
|
+
verify=ssl_verify
|
|
108
111
|
)
|
|
109
112
|
|
|
110
113
|
# Extract episodes from JSON response
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# 29.04.25
|
|
2
2
|
|
|
3
|
+
import sys
|
|
4
|
+
import subprocess
|
|
5
|
+
|
|
3
6
|
# External library
|
|
4
7
|
from rich.console import Console
|
|
5
8
|
from rich.prompt import Prompt
|
|
@@ -9,6 +12,7 @@ from rich.prompt import Prompt
|
|
|
9
12
|
from StreamingCommunity.Api.Template import get_select_title
|
|
10
13
|
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
11
14
|
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
15
|
+
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
|
|
12
16
|
|
|
13
17
|
|
|
14
18
|
# Logic class
|
|
@@ -32,9 +36,39 @@ def get_user_input(string_to_search: str = None):
|
|
|
32
36
|
"""
|
|
33
37
|
Asks the user to input a search term.
|
|
34
38
|
Handles both Telegram bot input and direct input.
|
|
39
|
+
If string_to_search is provided, it's returned directly (after stripping).
|
|
35
40
|
"""
|
|
36
|
-
string_to_search
|
|
37
|
-
|
|
41
|
+
if string_to_search is not None:
|
|
42
|
+
return string_to_search.strip()
|
|
43
|
+
|
|
44
|
+
if site_constant.TELEGRAM_BOT:
|
|
45
|
+
bot = get_bot_instance()
|
|
46
|
+
user_response = bot.ask(
|
|
47
|
+
"key_search", # Request type
|
|
48
|
+
"Enter the search term\nor type 'back' to return to the menu: ",
|
|
49
|
+
None
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
if user_response is None:
|
|
53
|
+
bot.send_message("Timeout: No search term entered.", None)
|
|
54
|
+
return None
|
|
55
|
+
|
|
56
|
+
if user_response.lower() == 'back':
|
|
57
|
+
bot.send_message("Returning to the main menu...", None)
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
# Restart the script
|
|
61
|
+
subprocess.Popen([sys.executable] + sys.argv)
|
|
62
|
+
sys.exit()
|
|
63
|
+
|
|
64
|
+
except Exception as e:
|
|
65
|
+
bot.send_message(f"Error during restart attempt: {e}", None)
|
|
66
|
+
return None # Return None if restart fails
|
|
67
|
+
|
|
68
|
+
return user_response.strip()
|
|
69
|
+
|
|
70
|
+
else:
|
|
71
|
+
return msg.ask(f"\n[purple]Insert a word to search in [green]{site_constant.SITE_NAME}").strip()
|
|
38
72
|
|
|
39
73
|
def process_search_result(select_title, selections=None):
|
|
40
74
|
"""
|
|
@@ -44,7 +78,18 @@ def process_search_result(select_title, selections=None):
|
|
|
44
78
|
select_title (MediaItem): The selected media item
|
|
45
79
|
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
46
80
|
{'season': season_selection, 'episode': episode_selection}
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
bool: True if processing was successful, False otherwise
|
|
47
84
|
"""
|
|
85
|
+
if not select_title:
|
|
86
|
+
if site_constant.TELEGRAM_BOT:
|
|
87
|
+
bot = get_bot_instance()
|
|
88
|
+
bot.send_message("No title selected or selection cancelled.", None)
|
|
89
|
+
else:
|
|
90
|
+
console.print("[yellow]No title selected or selection cancelled.")
|
|
91
|
+
return False
|
|
92
|
+
|
|
48
93
|
if select_title.type == 'tv':
|
|
49
94
|
season_selection = None
|
|
50
95
|
episode_selection = None
|
|
@@ -54,9 +99,11 @@ def process_search_result(select_title, selections=None):
|
|
|
54
99
|
episode_selection = selections.get('episode')
|
|
55
100
|
|
|
56
101
|
download_series(select_title, season_selection, episode_selection)
|
|
102
|
+
return True
|
|
57
103
|
|
|
58
104
|
else:
|
|
59
105
|
download_film(select_title)
|
|
106
|
+
return True
|
|
60
107
|
|
|
61
108
|
def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None, selections: dict = None):
|
|
62
109
|
"""
|
|
@@ -69,26 +116,43 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
|
|
|
69
116
|
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
70
117
|
{'season': season_selection, 'episode': episode_selection}
|
|
71
118
|
"""
|
|
119
|
+
bot = None
|
|
120
|
+
if site_constant.TELEGRAM_BOT:
|
|
121
|
+
bot = get_bot_instance()
|
|
122
|
+
|
|
72
123
|
if direct_item:
|
|
73
124
|
select_title = MediaItem(**direct_item)
|
|
74
125
|
process_search_result(select_title, selections)
|
|
75
|
-
return
|
|
126
|
+
return True
|
|
76
127
|
|
|
77
|
-
|
|
78
|
-
|
|
128
|
+
# Get the user input for the search term
|
|
129
|
+
actual_search_query = get_user_input(string_to_search)
|
|
130
|
+
|
|
131
|
+
# Handle cases where user input is empty, or 'back' was handled (sys.exit or None return)
|
|
132
|
+
if not actual_search_query:
|
|
133
|
+
if bot:
|
|
134
|
+
if actual_search_query is None: # Specifically for timeout from bot.ask or failed restart
|
|
135
|
+
bot.send_message("Search term not provided or operation cancelled. Returning.", None)
|
|
136
|
+
return
|
|
79
137
|
|
|
80
|
-
# Perform
|
|
81
|
-
len_database = title_search(
|
|
138
|
+
# Perform the database search
|
|
139
|
+
len_database = title_search(actual_search_query)
|
|
82
140
|
|
|
83
141
|
# If only the database is needed, return the manager
|
|
84
142
|
if get_onlyDatabase:
|
|
85
143
|
return media_search_manager
|
|
86
|
-
|
|
144
|
+
|
|
87
145
|
if len_database > 0:
|
|
88
|
-
select_title = get_select_title(table_show_manager, media_search_manager,len_database)
|
|
146
|
+
select_title = get_select_title(table_show_manager, media_search_manager, len_database)
|
|
89
147
|
process_search_result(select_title, selections)
|
|
148
|
+
return True
|
|
90
149
|
|
|
91
150
|
else:
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
151
|
+
if bot:
|
|
152
|
+
bot.send_message(f"No results found for: '{actual_search_query}'", None)
|
|
153
|
+
else:
|
|
154
|
+
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{actual_search_query}")
|
|
155
|
+
|
|
156
|
+
# Do not call search() recursively here to avoid infinite loops on no results.
|
|
157
|
+
# The flow should return to the caller (e.g., main menu in run.py).
|
|
158
|
+
return
|
|
@@ -62,6 +62,14 @@ def get_widevine_keys(pssh, license_url, cdm_device_path, headers=None, payload=
|
|
|
62
62
|
|
|
63
63
|
if response.status_code != 200:
|
|
64
64
|
console.print(f"[bold red]License error:[/bold red] {response.status_code}, {response.text}")
|
|
65
|
+
console.print({
|
|
66
|
+
"url": license_url,
|
|
67
|
+
"headers": req_headers,
|
|
68
|
+
"content": payload,
|
|
69
|
+
"session_id": session_id.hex(),
|
|
70
|
+
"pssh": pssh
|
|
71
|
+
})
|
|
72
|
+
|
|
65
73
|
return None
|
|
66
74
|
|
|
67
75
|
# Handle (JSON) or classic (binary) license response
|