StreamingCommunity 3.2.8__py3-none-any.whl → 3.3.0__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/Helper/Vixcloud/util.py +2 -1
- StreamingCommunity/Api/Player/hdplayer.py +2 -2
- StreamingCommunity/Api/Player/sweetpixel.py +5 -8
- StreamingCommunity/Api/Site/altadefinizione/__init__.py +32 -15
- StreamingCommunity/Api/Site/altadefinizione/film.py +10 -8
- StreamingCommunity/Api/Site/altadefinizione/series.py +9 -7
- StreamingCommunity/Api/Site/altadefinizione/site.py +1 -1
- StreamingCommunity/Api/Site/animeunity/__init__.py +31 -15
- StreamingCommunity/Api/Site/animeunity/serie.py +2 -2
- StreamingCommunity/Api/Site/animeworld/__init__.py +33 -7
- StreamingCommunity/Api/Site/animeworld/site.py +3 -5
- StreamingCommunity/Api/Site/animeworld/util/ScrapeSerie.py +8 -10
- StreamingCommunity/Api/Site/crunchyroll/__init__.py +44 -12
- StreamingCommunity/Api/Site/crunchyroll/film.py +9 -7
- StreamingCommunity/Api/Site/crunchyroll/series.py +9 -7
- StreamingCommunity/Api/Site/crunchyroll/site.py +16 -1
- StreamingCommunity/Api/Site/guardaserie/__init__.py +36 -10
- StreamingCommunity/Api/Site/guardaserie/series.py +8 -6
- StreamingCommunity/Api/Site/guardaserie/site.py +0 -3
- StreamingCommunity/Api/Site/guardaserie/util/ScrapeSerie.py +1 -2
- StreamingCommunity/Api/Site/mediasetinfinity/__init__.py +37 -12
- StreamingCommunity/Api/Site/mediasetinfinity/film.py +10 -16
- StreamingCommunity/Api/Site/mediasetinfinity/series.py +12 -18
- StreamingCommunity/Api/Site/mediasetinfinity/site.py +18 -3
- StreamingCommunity/Api/Site/mediasetinfinity/util/ScrapeSerie.py +214 -180
- StreamingCommunity/Api/Site/mediasetinfinity/util/get_license.py +2 -31
- StreamingCommunity/Api/Site/raiplay/__init__.py +47 -12
- StreamingCommunity/Api/Site/raiplay/film.py +42 -10
- StreamingCommunity/Api/Site/raiplay/series.py +53 -11
- StreamingCommunity/Api/Site/raiplay/site.py +4 -1
- StreamingCommunity/Api/Site/raiplay/util/ScrapeSerie.py +2 -1
- StreamingCommunity/Api/Site/raiplay/util/get_license.py +40 -0
- StreamingCommunity/Api/Site/streamingcommunity/__init__.py +5 -8
- StreamingCommunity/Api/Site/streamingcommunity/film.py +7 -5
- StreamingCommunity/Api/Site/streamingcommunity/series.py +9 -7
- StreamingCommunity/Api/Site/streamingcommunity/site.py +8 -3
- StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +5 -2
- StreamingCommunity/Api/Site/streamingwatch/__init__.py +43 -9
- StreamingCommunity/Api/Site/streamingwatch/film.py +7 -5
- StreamingCommunity/Api/Site/streamingwatch/series.py +8 -6
- StreamingCommunity/Api/Site/streamingwatch/site.py +3 -1
- StreamingCommunity/Api/Site/streamingwatch/util/ScrapeSerie.py +3 -3
- StreamingCommunity/Api/Template/Util/__init__.py +10 -1
- StreamingCommunity/Api/Template/Util/manage_ep.py +4 -4
- StreamingCommunity/Api/Template/__init__.py +5 -1
- StreamingCommunity/Api/Template/site.py +10 -6
- StreamingCommunity/Lib/Downloader/DASH/cdm_helpher.py +13 -12
- StreamingCommunity/Lib/Downloader/DASH/decrypt.py +1 -1
- StreamingCommunity/Lib/Downloader/DASH/downloader.py +24 -22
- StreamingCommunity/Lib/Downloader/DASH/parser.py +1 -1
- StreamingCommunity/Lib/Downloader/DASH/segments.py +4 -3
- StreamingCommunity/Lib/Downloader/HLS/downloader.py +11 -9
- StreamingCommunity/Lib/Downloader/HLS/segments.py +4 -9
- StreamingCommunity/Lib/Downloader/MP4/downloader.py +25 -6
- StreamingCommunity/Lib/Downloader/TOR/downloader.py +3 -5
- StreamingCommunity/Lib/Downloader/__init__.py +9 -1
- StreamingCommunity/Lib/FFmpeg/__init__.py +10 -1
- StreamingCommunity/Lib/FFmpeg/command.py +4 -6
- StreamingCommunity/Lib/FFmpeg/util.py +1 -1
- StreamingCommunity/Lib/M3U8/__init__.py +9 -1
- StreamingCommunity/Lib/M3U8/decryptor.py +8 -4
- StreamingCommunity/Lib/M3U8/estimator.py +0 -6
- StreamingCommunity/Lib/M3U8/parser.py +1 -1
- StreamingCommunity/Lib/M3U8/url_fixer.py +1 -1
- StreamingCommunity/Lib/TMBD/__init__.py +6 -1
- StreamingCommunity/TelegramHelp/config.json +1 -5
- StreamingCommunity/TelegramHelp/telegram_bot.py +9 -10
- StreamingCommunity/Upload/update.py +2 -2
- StreamingCommunity/Upload/version.py +1 -1
- StreamingCommunity/Util/config_json.py +139 -59
- StreamingCommunity/Util/http_client.py +201 -0
- StreamingCommunity/Util/message.py +1 -1
- StreamingCommunity/Util/os.py +8 -5
- StreamingCommunity/Util/table.py +3 -3
- StreamingCommunity/__init__.py +9 -1
- StreamingCommunity/run.py +394 -258
- {streamingcommunity-3.2.8.dist-info → streamingcommunity-3.3.0.dist-info}/METADATA +147 -45
- streamingcommunity-3.3.0.dist-info/RECORD +110 -0
- StreamingCommunity/Api/Site/cb01new/__init__.py +0 -72
- StreamingCommunity/Api/Site/cb01new/film.py +0 -62
- StreamingCommunity/Api/Site/cb01new/site.py +0 -78
- streamingcommunity-3.2.8.dist-info/RECORD +0 -111
- {streamingcommunity-3.2.8.dist-info → streamingcommunity-3.3.0.dist-info}/WHEEL +0 -0
- {streamingcommunity-3.2.8.dist-info → streamingcommunity-3.3.0.dist-info}/entry_points.txt +0 -0
- {streamingcommunity-3.2.8.dist-info → streamingcommunity-3.3.0.dist-info}/licenses/LICENSE +0 -0
- {streamingcommunity-3.2.8.dist-info → streamingcommunity-3.3.0.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 23.11.24
|
|
2
2
|
|
|
3
|
-
from typing import Dict, Any, List,
|
|
3
|
+
from typing import Dict, Any, List, Optional
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class Episode:
|
|
@@ -12,6 +12,7 @@ class Episode:
|
|
|
12
12
|
self.name: str = data.get('name', '')
|
|
13
13
|
self.duration: int = data.get('duration', 0)
|
|
14
14
|
self.url: str = data.get('url', '')
|
|
15
|
+
self.mpd_id: str = data.get('mpd_id', '')
|
|
15
16
|
|
|
16
17
|
def __str__(self):
|
|
17
18
|
return f"Episode(id={self.id}, number={self.number}, name='{self.name}', duration={self.duration} sec)"
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
import re
|
|
4
4
|
|
|
5
5
|
# External library
|
|
6
|
-
import httpx
|
|
7
6
|
from bs4 import BeautifulSoup
|
|
8
7
|
|
|
9
8
|
|
|
10
9
|
# Internal utilities
|
|
11
10
|
from StreamingCommunity.Util.headers import get_userAgent
|
|
11
|
+
from StreamingCommunity.Util.http_client import create_client
|
|
12
12
|
from StreamingCommunity.Util.config_json import config_manager
|
|
13
13
|
|
|
14
14
|
|
|
@@ -19,7 +19,7 @@ REQUEST_VERIFY = config_manager.get_bool('REQUESTS', 'verify')
|
|
|
19
19
|
|
|
20
20
|
class VideoSource:
|
|
21
21
|
def __init__(self):
|
|
22
|
-
self.client =
|
|
22
|
+
self.client = create_client(headers={'user-agent': get_userAgent()})
|
|
23
23
|
|
|
24
24
|
def extractLinkHdPlayer(self, response):
|
|
25
25
|
"""Extract iframe source from the page."""
|
|
@@ -4,12 +4,12 @@ import logging
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
# External libraries
|
|
7
|
-
import httpx
|
|
8
7
|
|
|
9
8
|
|
|
10
9
|
# Internal utilities
|
|
11
10
|
from StreamingCommunity.Util.config_json import config_manager
|
|
12
11
|
from StreamingCommunity.Util.headers import get_userAgent
|
|
12
|
+
from StreamingCommunity.Util.http_client import create_client
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
# Variable
|
|
@@ -17,21 +17,18 @@ MAX_TIMEOUT = config_manager.get_int("REQUESTS", "timeout")
|
|
|
17
17
|
REQUEST_VERIFY = config_manager.get_bool('REQUESTS', 'verify')
|
|
18
18
|
|
|
19
19
|
class VideoSource:
|
|
20
|
-
def __init__(self,
|
|
20
|
+
def __init__(self, site_url, episode_data, session_id, csrf_token):
|
|
21
21
|
"""Initialize the VideoSource with session details, episode data, and URL."""
|
|
22
22
|
self.session_id = session_id
|
|
23
23
|
self.csrf_token = csrf_token
|
|
24
24
|
self.episode_data = episode_data
|
|
25
25
|
self.number = episode_data['number']
|
|
26
|
-
self.link = episode_data['link']
|
|
26
|
+
self.link = site_url + episode_data['link']
|
|
27
27
|
|
|
28
28
|
# Create an HTTP client with session cookies, headers, and base URL.
|
|
29
|
-
self.client =
|
|
29
|
+
self.client = create_client(
|
|
30
30
|
cookies={"sessionId": session_id},
|
|
31
|
-
headers={"User-Agent": get_userAgent(), "csrf-token": csrf_token}
|
|
32
|
-
base_url=full_url,
|
|
33
|
-
timeout=MAX_TIMEOUT,
|
|
34
|
-
verify=REQUEST_VERIFY
|
|
31
|
+
headers={"User-Agent": get_userAgent(), "csrf-token": csrf_token}
|
|
35
32
|
)
|
|
36
33
|
|
|
37
34
|
def get_playlist(self):
|
|
@@ -22,6 +22,7 @@ from .site import title_search, table_show_manager, media_search_manager
|
|
|
22
22
|
from .film import download_film
|
|
23
23
|
from .series import download_series
|
|
24
24
|
|
|
25
|
+
|
|
25
26
|
# Variable
|
|
26
27
|
indice = 2
|
|
27
28
|
_useFor = "Film_&_Serie"
|
|
@@ -43,7 +44,7 @@ def get_user_input(string_to_search: str = None):
|
|
|
43
44
|
bot = get_bot_instance()
|
|
44
45
|
string_to_search = bot.ask(
|
|
45
46
|
"key_search",
|
|
46
|
-
|
|
47
|
+
"Enter the search term\nor type 'back' to return to the menu: ",
|
|
47
48
|
None
|
|
48
49
|
)
|
|
49
50
|
|
|
@@ -66,6 +67,14 @@ def process_search_result(select_title, selections=None):
|
|
|
66
67
|
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
67
68
|
{'season': season_selection, 'episode': episode_selection}
|
|
68
69
|
"""
|
|
70
|
+
if not select_title:
|
|
71
|
+
if site_constant.TELEGRAM_BOT:
|
|
72
|
+
bot = get_bot_instance()
|
|
73
|
+
bot.send_message("No title selected or selection cancelled.", None)
|
|
74
|
+
else:
|
|
75
|
+
console.print("[yellow]No title selected or selection cancelled.")
|
|
76
|
+
return
|
|
77
|
+
|
|
69
78
|
if select_title.type == 'tv':
|
|
70
79
|
season_selection = None
|
|
71
80
|
episode_selection = None
|
|
@@ -86,39 +95,47 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
|
|
|
86
95
|
|
|
87
96
|
Parameters:
|
|
88
97
|
string_to_search (str, optional): String to search for
|
|
89
|
-
|
|
98
|
+
get_onlyDatabase (bool, optional): If True, return only the database object
|
|
90
99
|
direct_item (dict, optional): Direct item to process (bypass search)
|
|
91
100
|
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
92
101
|
{'season': season_selection, 'episode': episode_selection}
|
|
93
102
|
"""
|
|
103
|
+
bot = None
|
|
104
|
+
if site_constant.TELEGRAM_BOT:
|
|
105
|
+
bot = get_bot_instance()
|
|
106
|
+
|
|
94
107
|
if direct_item:
|
|
95
108
|
select_title = MediaItem(**direct_item)
|
|
96
109
|
process_search_result(select_title, selections)
|
|
97
110
|
return
|
|
98
111
|
|
|
99
112
|
# Get the user input for the search term
|
|
100
|
-
|
|
113
|
+
actual_search_query = get_user_input(string_to_search)
|
|
114
|
+
|
|
115
|
+
# Handle cases where user input is empty, or 'back' was handled (sys.exit or None return)
|
|
116
|
+
if not actual_search_query:
|
|
117
|
+
if bot:
|
|
118
|
+
if actual_search_query is None: # Specifically for timeout from bot.ask or failed restart
|
|
119
|
+
bot.send_message("Search term not provided or operation cancelled. Returning.", None)
|
|
120
|
+
return
|
|
101
121
|
|
|
102
122
|
# Perform the database search
|
|
103
|
-
len_database = title_search(quote_plus(
|
|
123
|
+
len_database = title_search(quote_plus(actual_search_query))
|
|
104
124
|
|
|
105
125
|
# If only the database is needed, return the manager
|
|
106
126
|
if get_onlyDatabase:
|
|
107
127
|
return media_search_manager
|
|
108
|
-
|
|
109
|
-
if site_constant.TELEGRAM_BOT:
|
|
110
|
-
bot = get_bot_instance()
|
|
111
|
-
|
|
128
|
+
|
|
112
129
|
if len_database > 0:
|
|
113
130
|
select_title = get_select_title(table_show_manager, media_search_manager, len_database)
|
|
114
131
|
process_search_result(select_title, selections)
|
|
115
132
|
|
|
116
133
|
else:
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
134
|
+
if bot:
|
|
135
|
+
bot.send_message(f"No results found for: '{actual_search_query}'", None)
|
|
136
|
+
else:
|
|
137
|
+
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{actual_search_query}")
|
|
121
138
|
|
|
122
|
-
#
|
|
123
|
-
|
|
124
|
-
|
|
139
|
+
# Do not call search() recursively here to avoid infinite loops on no results.
|
|
140
|
+
# The flow should return to the caller (e.g., main menu in run.py).
|
|
141
|
+
return
|
|
@@ -5,7 +5,6 @@ import re
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
# External library
|
|
8
|
-
import httpx
|
|
9
8
|
from bs4 import BeautifulSoup
|
|
10
9
|
from rich.console import Console
|
|
11
10
|
|
|
@@ -13,6 +12,7 @@ from rich.console import Console
|
|
|
13
12
|
# Internal utilities
|
|
14
13
|
from StreamingCommunity.Util.os import os_manager
|
|
15
14
|
from StreamingCommunity.Util.headers import get_headers
|
|
15
|
+
from StreamingCommunity.Util.http_client import create_client
|
|
16
16
|
from StreamingCommunity.Util.message import start_message
|
|
17
17
|
from StreamingCommunity.Util.config_json import config_manager
|
|
18
18
|
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance, TelegramSession
|
|
@@ -60,7 +60,7 @@ def download_film(select_title: MediaItem) -> str:
|
|
|
60
60
|
|
|
61
61
|
# Extract mostraguarda URL
|
|
62
62
|
try:
|
|
63
|
-
response =
|
|
63
|
+
response = create_client(headers=get_headers()).get(select_title.url)
|
|
64
64
|
response.raise_for_status()
|
|
65
65
|
|
|
66
66
|
soup = BeautifulSoup(response.text, 'html.parser')
|
|
@@ -74,7 +74,7 @@ def download_film(select_title: MediaItem) -> str:
|
|
|
74
74
|
# Extract supervideo URL
|
|
75
75
|
supervideo_url = None
|
|
76
76
|
try:
|
|
77
|
-
response =
|
|
77
|
+
response = create_client(headers=get_headers()).get(mostraguarda)
|
|
78
78
|
response.raise_for_status()
|
|
79
79
|
|
|
80
80
|
soup = BeautifulSoup(response.text, 'html.parser')
|
|
@@ -96,7 +96,7 @@ def download_film(select_title: MediaItem) -> str:
|
|
|
96
96
|
mp4_path = os.path.join(site_constant.MOVIE_FOLDER, title_name.replace(".mp4", ""))
|
|
97
97
|
|
|
98
98
|
# Download the film using the m3u8 playlist, and output filename
|
|
99
|
-
|
|
99
|
+
hls_process = HLS_Downloader(
|
|
100
100
|
m3u8_url=master_playlist,
|
|
101
101
|
output_path=os.path.join(mp4_path, title_name)
|
|
102
102
|
).start()
|
|
@@ -108,8 +108,10 @@ def download_film(select_title: MediaItem) -> str:
|
|
|
108
108
|
if script_id != "unknown":
|
|
109
109
|
TelegramSession.deleteScriptId(script_id)
|
|
110
110
|
|
|
111
|
-
if
|
|
112
|
-
try:
|
|
113
|
-
|
|
111
|
+
if hls_process['error'] is not None:
|
|
112
|
+
try:
|
|
113
|
+
os.remove(hls_process['path'])
|
|
114
|
+
except Exception:
|
|
115
|
+
pass
|
|
114
116
|
|
|
115
|
-
return
|
|
117
|
+
return hls_process['path']
|
|
@@ -54,7 +54,7 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
|
|
|
54
54
|
|
|
55
55
|
# Get episode information
|
|
56
56
|
obj_episode = scrape_serie.selectEpisode(index_season_selected, index_episode_selected-1)
|
|
57
|
-
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")
|
|
57
|
+
console.print(f"[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [cyan]{scrape_serie.series_name}[/cyan] \\ [bold magenta]{obj_episode.name}[/bold magenta] ([cyan]S{index_season_selected}E{index_episode_selected}[/cyan]) \n")
|
|
58
58
|
|
|
59
59
|
# Telegram integration
|
|
60
60
|
if site_constant.TELEGRAM_BOT:
|
|
@@ -81,16 +81,18 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
|
|
|
81
81
|
master_playlist = video_source.get_playlist()
|
|
82
82
|
|
|
83
83
|
# Download the episode
|
|
84
|
-
|
|
84
|
+
hls_process = HLS_Downloader(
|
|
85
85
|
m3u8_url=master_playlist,
|
|
86
86
|
output_path=os.path.join(mp4_path, mp4_name)
|
|
87
87
|
).start()
|
|
88
88
|
|
|
89
|
-
if
|
|
90
|
-
try:
|
|
91
|
-
|
|
89
|
+
if hls_process['error'] is not None:
|
|
90
|
+
try:
|
|
91
|
+
os.remove(hls_process['path'])
|
|
92
|
+
except Exception:
|
|
93
|
+
pass
|
|
92
94
|
|
|
93
|
-
return
|
|
95
|
+
return hls_process['path'], hls_process['stopped']
|
|
94
96
|
|
|
95
97
|
|
|
96
98
|
def download_episode(index_season_selected: int, scrape_serie: GetSerieInfo, download_all: bool = False, episode_selection: str = None) -> None:
|
|
@@ -196,7 +198,7 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
|
|
|
196
198
|
download_episode(i_season, scrape_serie, download_all=False, episode_selection=episode_selection)
|
|
197
199
|
|
|
198
200
|
if site_constant.TELEGRAM_BOT:
|
|
199
|
-
bot.send_message(
|
|
201
|
+
bot.send_message("Finito di scaricare tutte le serie e episodi", None)
|
|
200
202
|
|
|
201
203
|
# Get script_id
|
|
202
204
|
script_id = TelegramSession.get_session()
|
|
@@ -93,7 +93,7 @@ def title_search(query: str) -> int:
|
|
|
93
93
|
|
|
94
94
|
if site_constant.TELEGRAM_BOT:
|
|
95
95
|
if choices:
|
|
96
|
-
bot.send_message(
|
|
96
|
+
bot.send_message("Lista dei risultati:", choices)
|
|
97
97
|
|
|
98
98
|
# Return the number of titles found
|
|
99
99
|
return media_search_manager.get_length()
|
|
@@ -43,7 +43,7 @@ def get_user_input(string_to_search: str = None):
|
|
|
43
43
|
bot = get_bot_instance()
|
|
44
44
|
string_to_search = bot.ask(
|
|
45
45
|
"key_search",
|
|
46
|
-
|
|
46
|
+
"Enter the search term\nor type 'back' to return to the menu: ",
|
|
47
47
|
None
|
|
48
48
|
)
|
|
49
49
|
|
|
@@ -66,6 +66,14 @@ def process_search_result(select_title, selections=None):
|
|
|
66
66
|
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
67
67
|
{'season': season_selection, 'episode': episode_selection}
|
|
68
68
|
"""
|
|
69
|
+
if not select_title:
|
|
70
|
+
if site_constant.TELEGRAM_BOT:
|
|
71
|
+
bot = get_bot_instance()
|
|
72
|
+
bot.send_message("No title selected or selection cancelled.", None)
|
|
73
|
+
else:
|
|
74
|
+
console.print("[yellow]No title selected or selection cancelled.")
|
|
75
|
+
return
|
|
76
|
+
|
|
69
77
|
if select_title.type == 'Movie':
|
|
70
78
|
download_film(select_title)
|
|
71
79
|
|
|
@@ -90,34 +98,42 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
|
|
|
90
98
|
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
91
99
|
{'season': season_selection, 'episode': episode_selection}
|
|
92
100
|
"""
|
|
101
|
+
bot = None
|
|
102
|
+
if site_constant.TELEGRAM_BOT:
|
|
103
|
+
bot = get_bot_instance()
|
|
104
|
+
|
|
93
105
|
if direct_item:
|
|
94
106
|
select_title = MediaItem(**direct_item)
|
|
95
107
|
process_search_result(select_title, selections)
|
|
96
108
|
return
|
|
97
|
-
|
|
109
|
+
|
|
98
110
|
# Get the user input for the search term
|
|
99
|
-
|
|
111
|
+
actual_search_query = get_user_input(string_to_search)
|
|
100
112
|
|
|
113
|
+
# Handle cases where user input is empty, or 'back' was handled (sys.exit or None return)
|
|
114
|
+
if not actual_search_query:
|
|
115
|
+
if bot:
|
|
116
|
+
if actual_search_query is None: # Specifically for timeout from bot.ask or failed restart
|
|
117
|
+
bot.send_message("Search term not provided or operation cancelled. Returning.", None)
|
|
118
|
+
return
|
|
119
|
+
|
|
101
120
|
# Perform the database search
|
|
102
|
-
len_database = title_search(
|
|
121
|
+
len_database = title_search(actual_search_query)
|
|
103
122
|
|
|
104
123
|
# If only the database is needed, return the manager
|
|
105
124
|
if get_onlyDatabase:
|
|
106
125
|
return media_search_manager
|
|
107
|
-
|
|
108
|
-
if site_constant.TELEGRAM_BOT:
|
|
109
|
-
bot = get_bot_instance()
|
|
110
126
|
|
|
111
127
|
if len_database > 0:
|
|
112
|
-
select_title = get_select_title(table_show_manager, media_search_manager,len_database)
|
|
128
|
+
select_title = get_select_title(table_show_manager, media_search_manager, len_database)
|
|
113
129
|
process_search_result(select_title, selections)
|
|
114
130
|
|
|
115
131
|
else:
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
132
|
+
if bot:
|
|
133
|
+
bot.send_message(f"No results found for: '{actual_search_query}'", None)
|
|
134
|
+
else:
|
|
135
|
+
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{actual_search_query}")
|
|
120
136
|
|
|
121
|
-
#
|
|
122
|
-
|
|
123
|
-
|
|
137
|
+
# Do not call search() recursively here to avoid infinite loops on no results.
|
|
138
|
+
# The flow should return to the caller (e.g., main menu in run.py).
|
|
139
|
+
return
|
|
@@ -109,7 +109,7 @@ def download_series(select_title: MediaItem, season_selection: str = None, episo
|
|
|
109
109
|
# Telegram bot integration
|
|
110
110
|
if episode_selection is None:
|
|
111
111
|
if site_constant.TELEGRAM_BOT:
|
|
112
|
-
console.print(
|
|
112
|
+
console.print("\n[cyan]Insert media [red]index [yellow]or [red]* [cyan]to download all media [yellow]or [red]1-2 [cyan]or [red]3-* [cyan]for a range of media")
|
|
113
113
|
bot.send_message(f"Episodi trovati: {episoded_count}", None)
|
|
114
114
|
|
|
115
115
|
last_command = bot.ask(
|
|
@@ -145,7 +145,7 @@ def download_series(select_title: MediaItem, season_selection: str = None, episo
|
|
|
145
145
|
_, kill_handler = download_episode(i_episode-1, scrape_serie, video_source)
|
|
146
146
|
|
|
147
147
|
if site_constant.TELEGRAM_BOT:
|
|
148
|
-
bot.send_message(
|
|
148
|
+
bot.send_message("Finito di scaricare tutte le serie e episodi", None)
|
|
149
149
|
|
|
150
150
|
# Get script_id
|
|
151
151
|
script_id = TelegramSession.get_session()
|
|
@@ -9,6 +9,7 @@ from rich.prompt import Prompt
|
|
|
9
9
|
from StreamingCommunity.Api.Template import get_select_title
|
|
10
10
|
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
11
11
|
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
12
|
+
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
# Logic class
|
|
@@ -38,6 +39,14 @@ def process_search_result(select_title, selections=None):
|
|
|
38
39
|
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
39
40
|
{'season': season_selection, 'episode': episode_selection}
|
|
40
41
|
"""
|
|
42
|
+
if not select_title:
|
|
43
|
+
if site_constant.TELEGRAM_BOT:
|
|
44
|
+
bot = get_bot_instance()
|
|
45
|
+
bot.send_message("No title selected or selection cancelled.", None)
|
|
46
|
+
else:
|
|
47
|
+
console.print("[yellow]No title selected or selection cancelled.")
|
|
48
|
+
return
|
|
49
|
+
|
|
41
50
|
if select_title.type == "TV":
|
|
42
51
|
episode_selection = None
|
|
43
52
|
if selections:
|
|
@@ -58,6 +67,10 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
|
|
|
58
67
|
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
59
68
|
{'season': season_selection, 'episode': episode_selection}
|
|
60
69
|
"""
|
|
70
|
+
bot = None
|
|
71
|
+
if site_constant.TELEGRAM_BOT:
|
|
72
|
+
bot = get_bot_instance()
|
|
73
|
+
|
|
61
74
|
if direct_item:
|
|
62
75
|
select_title = MediaItem(**direct_item)
|
|
63
76
|
process_search_result(select_title, selections)
|
|
@@ -65,20 +78,33 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
|
|
|
65
78
|
|
|
66
79
|
# Get the user input for the search term
|
|
67
80
|
if string_to_search is None:
|
|
68
|
-
|
|
81
|
+
actual_search_query = msg.ask(f"\n[purple]Insert a word to search in [green]{site_constant.SITE_NAME}").strip()
|
|
82
|
+
else:
|
|
83
|
+
actual_search_query = string_to_search
|
|
69
84
|
|
|
70
85
|
# Perform the database search
|
|
71
|
-
|
|
86
|
+
if not actual_search_query:
|
|
87
|
+
if bot:
|
|
88
|
+
if actual_search_query is None:
|
|
89
|
+
bot.send_message("Search term not provided or operation cancelled. Returning.", None)
|
|
90
|
+
return
|
|
91
|
+
|
|
92
|
+
len_database = title_search(actual_search_query)
|
|
72
93
|
|
|
73
94
|
# If only the database is needed, return the manager
|
|
74
95
|
if get_onlyDatabase:
|
|
75
96
|
return media_search_manager
|
|
76
97
|
|
|
77
98
|
if len_database > 0:
|
|
78
|
-
select_title = get_select_title(table_show_manager, media_search_manager,len_database)
|
|
99
|
+
select_title = get_select_title(table_show_manager, media_search_manager, len_database)
|
|
79
100
|
process_search_result(select_title, selections)
|
|
80
|
-
|
|
101
|
+
|
|
81
102
|
else:
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
103
|
+
if bot:
|
|
104
|
+
bot.send_message(f"No results found for: '{actual_search_query}'", None)
|
|
105
|
+
else:
|
|
106
|
+
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{actual_search_query}")
|
|
107
|
+
|
|
108
|
+
# Do not call search() recursively here to avoid infinite loops on no results.
|
|
109
|
+
# The flow should return to the caller (e.g., main menu in run.py).
|
|
110
|
+
return
|
|
@@ -11,6 +11,7 @@ from rich.console import Console
|
|
|
11
11
|
# Internal utilities
|
|
12
12
|
from StreamingCommunity.Util.config_json import config_manager
|
|
13
13
|
from StreamingCommunity.Util.headers import get_userAgent, get_headers
|
|
14
|
+
from StreamingCommunity.Util.http_client import create_client
|
|
14
15
|
from StreamingCommunity.Util.table import TVShowManager
|
|
15
16
|
|
|
16
17
|
|
|
@@ -31,11 +32,8 @@ def get_session_and_csrf() -> dict:
|
|
|
31
32
|
Get the session ID and CSRF token from the website's cookies and HTML meta data.
|
|
32
33
|
"""
|
|
33
34
|
# Send an initial GET request to the website
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
headers=get_headers(),
|
|
37
|
-
verify=False
|
|
38
|
-
)
|
|
35
|
+
client = create_client(headers=get_headers())
|
|
36
|
+
response = client.get(site_constant.FULL_URL)
|
|
39
37
|
|
|
40
38
|
# Extract the sessionId from the cookies
|
|
41
39
|
session_id = response.cookies.get('sessionId')
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
# External libraries
|
|
6
|
-
import httpx
|
|
7
7
|
from bs4 import BeautifulSoup
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
# Internal utilities
|
|
11
11
|
from StreamingCommunity.Util.headers import get_userAgent
|
|
12
|
+
from StreamingCommunity.Util.http_client import create_client
|
|
12
13
|
from StreamingCommunity.Util.config_json import config_manager
|
|
13
14
|
from StreamingCommunity.Util.os import os_manager
|
|
14
15
|
|
|
@@ -23,24 +24,21 @@ max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
class ScrapSerie:
|
|
26
|
-
def __init__(self, url,
|
|
27
|
+
def __init__(self, url, site_url):
|
|
27
28
|
"""Initialize the ScrapSerie object with the provided URL and setup the HTTP client."""
|
|
28
29
|
self.url = url
|
|
29
|
-
self.link = httpx.URL(url).path
|
|
30
30
|
self.session_id, self.csrf_token = get_session_and_csrf()
|
|
31
|
-
self.client =
|
|
31
|
+
self.client = create_client(
|
|
32
32
|
cookies={"sessionId": self.session_id},
|
|
33
|
-
headers={"User-Agent": get_userAgent(), "csrf-token": self.csrf_token}
|
|
34
|
-
base_url=full_url,
|
|
35
|
-
verify=False
|
|
33
|
+
headers={"User-Agent": get_userAgent(), "csrf-token": self.csrf_token}
|
|
36
34
|
)
|
|
37
35
|
|
|
38
36
|
try:
|
|
39
|
-
self.response = self.client.get(self.
|
|
37
|
+
self.response = self.client.get(self.url, timeout=max_timeout, follow_redirects=True)
|
|
40
38
|
self.response.raise_for_status()
|
|
41
39
|
|
|
42
|
-
except:
|
|
43
|
-
raise Exception(f"Failed to retrieve anime page
|
|
40
|
+
except Exception as e:
|
|
41
|
+
raise Exception(f"Failed to retrieve anime page: {str(e)}")
|
|
44
42
|
|
|
45
43
|
def get_name(self):
|
|
46
44
|
"""Extract and return the name of the anime series."""
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# 16.03.25
|
|
2
2
|
|
|
3
|
-
import sys
|
|
4
|
-
import subprocess
|
|
5
3
|
from urllib.parse import quote_plus
|
|
6
4
|
|
|
7
5
|
|
|
@@ -14,6 +12,7 @@ from rich.prompt import Prompt
|
|
|
14
12
|
from StreamingCommunity.Api.Template import get_select_title
|
|
15
13
|
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
16
14
|
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
15
|
+
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
|
|
17
16
|
|
|
18
17
|
|
|
19
18
|
# Logic class
|
|
@@ -21,11 +20,12 @@ from .site import title_search, table_show_manager, media_search_manager
|
|
|
21
20
|
from .film import download_film
|
|
22
21
|
from .series import download_series
|
|
23
22
|
|
|
23
|
+
|
|
24
24
|
# Variable
|
|
25
25
|
indice = 8
|
|
26
26
|
_useFor = "Anime"
|
|
27
27
|
_priority = 0
|
|
28
|
-
_engineDownload = "
|
|
28
|
+
_engineDownload = "dash"
|
|
29
29
|
_deprecate = False
|
|
30
30
|
|
|
31
31
|
msg = Prompt()
|
|
@@ -51,6 +51,14 @@ def process_search_result(select_title, selections=None):
|
|
|
51
51
|
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
52
52
|
{'season': season_selection, 'episode': episode_selection}
|
|
53
53
|
"""
|
|
54
|
+
if not select_title:
|
|
55
|
+
if site_constant.TELEGRAM_BOT:
|
|
56
|
+
bot = get_bot_instance()
|
|
57
|
+
bot.send_message("No title selected or selection cancelled.", None)
|
|
58
|
+
else:
|
|
59
|
+
console.print("[yellow]No title selected or selection cancelled.")
|
|
60
|
+
return
|
|
61
|
+
|
|
54
62
|
if select_title.type == 'tv':
|
|
55
63
|
season_selection = None
|
|
56
64
|
episode_selection = None
|
|
@@ -71,33 +79,57 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
|
|
|
71
79
|
|
|
72
80
|
Parameters:
|
|
73
81
|
string_to_search (str, optional): String to search for
|
|
74
|
-
|
|
82
|
+
get_onlyDatabase (bool, optional): If True, return only the database object
|
|
83
|
+
direct_item (dict, optional): Direct item to process (bypass search)
|
|
84
|
+
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
85
|
+
{'season': season_selection, 'episode': episode_selection}
|
|
86
|
+
"""
|
|
87
|
+
"""
|
|
88
|
+
Main function of the application for search.
|
|
89
|
+
|
|
90
|
+
Parameters:
|
|
91
|
+
string_to_search (str, optional): String to search for
|
|
92
|
+
get_onlyDatabase (bool, optional): If True, return only the database object
|
|
75
93
|
direct_item (dict, optional): Direct item to process (bypass search)
|
|
76
94
|
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
77
95
|
{'season': season_selection, 'episode': episode_selection}
|
|
78
96
|
"""
|
|
97
|
+
bot = None
|
|
98
|
+
if site_constant.TELEGRAM_BOT:
|
|
99
|
+
bot = get_bot_instance()
|
|
100
|
+
|
|
79
101
|
if direct_item:
|
|
80
102
|
select_title = MediaItem(**direct_item)
|
|
81
103
|
process_search_result(select_title, selections)
|
|
82
104
|
return
|
|
83
105
|
|
|
84
106
|
# Get the user input for the search term
|
|
85
|
-
|
|
107
|
+
actual_search_query = get_user_input(string_to_search)
|
|
108
|
+
|
|
109
|
+
# Handle cases where user input is empty, or 'back' was handled (sys.exit or None return)
|
|
110
|
+
if not actual_search_query:
|
|
111
|
+
if bot:
|
|
112
|
+
if actual_search_query is None: # Specifically for timeout from bot.ask or failed restart
|
|
113
|
+
bot.send_message("Search term not provided or operation cancelled. Returning.", None)
|
|
114
|
+
return
|
|
86
115
|
|
|
87
116
|
# Perform the database search
|
|
88
|
-
len_database = title_search(quote_plus(
|
|
117
|
+
len_database = title_search(quote_plus(actual_search_query))
|
|
89
118
|
|
|
90
119
|
# If only the database is needed, return the manager
|
|
91
120
|
if get_onlyDatabase:
|
|
92
121
|
return media_search_manager
|
|
93
|
-
|
|
122
|
+
|
|
94
123
|
if len_database > 0:
|
|
95
124
|
select_title = get_select_title(table_show_manager, media_search_manager, len_database)
|
|
96
125
|
process_search_result(select_title, selections)
|
|
97
126
|
|
|
98
127
|
else:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
128
|
+
if bot:
|
|
129
|
+
bot.send_message(f"No results found for: '{actual_search_query}'", None)
|
|
130
|
+
else:
|
|
131
|
+
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{actual_search_query}")
|
|
132
|
+
|
|
133
|
+
# Do not call search() recursively here to avoid infinite loops on no results.
|
|
134
|
+
# The flow should return to the caller (e.g., main menu in run.py).
|
|
135
|
+
return
|