StreamingCommunity 2.9.8__tar.gz → 3.0.0__tar.gz
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-2.9.8/StreamingCommunity.egg-info → streamingcommunity-3.0.0}/PKG-INFO +1 -1
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Player/ddl.py +2 -10
- streamingcommunity-3.0.0/StreamingCommunity/Api/Player/mediapolisvod.py +64 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Player/sweetpixel.py +3 -3
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Player/vixcloud.py +4 -9
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/1337xx/__init__.py +2 -3
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/1337xx/site.py +6 -1
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/altadefinizione/__init__.py +24 -9
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/altadefinizione/film.py +0 -1
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/altadefinizione/series.py +66 -70
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/altadefinizione/site.py +8 -2
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py +37 -2
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/animeunity/__init__.py +30 -12
- streamingcommunity-3.0.0/StreamingCommunity/Api/Site/animeunity/film.py +40 -0
- streamingcommunity-3.0.0/StreamingCommunity/Api/Site/animeunity/serie.py +153 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/animeunity/site.py +64 -37
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py +41 -22
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/animeworld/__init__.py +26 -14
- streamingcommunity-3.0.0/StreamingCommunity/Api/Site/animeworld/film.py +63 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/animeworld/serie.py +25 -22
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/animeworld/site.py +8 -2
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/animeworld/util/ScrapeSerie.py +32 -5
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/cb01new/__init__.py +2 -3
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/cb01new/site.py +7 -1
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py +2 -3
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/ddlstreamitaly/series.py +31 -32
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/ddlstreamitaly/site.py +8 -3
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/ddlstreamitaly/util/ScrapeSerie.py +30 -2
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/guardaserie/__init__.py +22 -9
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/guardaserie/series.py +55 -53
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/guardaserie/site.py +10 -3
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/guardaserie/util/ScrapeSerie.py +27 -1
- streamingcommunity-3.0.0/StreamingCommunity/Api/Site/raiplay/__init__.py +92 -0
- streamingcommunity-3.0.0/StreamingCommunity/Api/Site/raiplay/film.py +65 -0
- streamingcommunity-3.0.0/StreamingCommunity/Api/Site/raiplay/series.py +162 -0
- streamingcommunity-3.0.0/StreamingCommunity/Api/Site/raiplay/site.py +173 -0
- streamingcommunity-3.0.0/StreamingCommunity/Api/Site/raiplay/util/ScrapeSerie.py +127 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/streamingcommunity/__init__.py +30 -24
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/streamingcommunity/film.py +1 -2
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/streamingcommunity/series.py +76 -90
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/streamingcommunity/site.py +8 -4
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +41 -15
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Template/site.py +2 -2
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Lib/Downloader/HLS/downloader.py +1 -1
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Lib/Downloader/HLS/segments.py +9 -18
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Lib/Downloader/MP4/downloader.py +2 -1
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Lib/Downloader/TOR/downloader.py +7 -14
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Lib/FFmpeg/capture.py +1 -5
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Lib/FFmpeg/util.py +57 -19
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Lib/M3U8/estimator.py +57 -41
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Lib/M3U8/parser.py +26 -6
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Upload/update.py +22 -3
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Upload/version.py +1 -1
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Util/ffmpeg_installer.py +26 -1
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Util/os.py +13 -15
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Util/table.py +4 -2
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/global_search.py +1 -4
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/run.py +1 -4
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0/StreamingCommunity.egg-info}/PKG-INFO +1 -1
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity.egg-info/SOURCES.txt +9 -3
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/setup.py +1 -1
- streamingcommunity-2.9.8/StreamingCommunity/Api/Site/animeunity/film_serie.py +0 -181
- streamingcommunity-2.9.8/StreamingCommunity/Api/Site/mostraguarda/__init__.py +0 -73
- streamingcommunity-2.9.8/StreamingCommunity/Api/Site/mostraguarda/film.py +0 -93
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/LICENSE +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/MANIFEST.in +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/README.md +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Player/Helper/Vixcloud/js_parser.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Player/Helper/Vixcloud/util.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Player/maxstream.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Player/supervideo.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/1337xx/title.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/cb01new/film.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Template/Class/SearchType.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Template/Util/__init__.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Template/Util/manage_ep.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Template/__init__.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Template/config_loader.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Lib/Downloader/__init__.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Lib/FFmpeg/__init__.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Lib/FFmpeg/command.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Lib/M3U8/__init__.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Lib/M3U8/decryptor.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Lib/M3U8/url_fixer.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Lib/TMBD/__init__.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Lib/TMBD/obj_tmbd.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Lib/TMBD/tmdb.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/TelegramHelp/__init__.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/TelegramHelp/telegram_bot.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Util/color.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Util/config_json.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Util/headers.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Util/logger.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Util/message.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/__init__.py +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity.egg-info/dependency_links.txt +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity.egg-info/entry_points.txt +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity.egg-info/requires.txt +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity.egg-info/top_level.txt +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/requirements.txt +0 -0
- {streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/setup.cfg +0 -0
|
@@ -18,21 +18,13 @@ max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class VideoSource:
|
|
21
|
-
def __init__(self, cookie) -> None:
|
|
21
|
+
def __init__(self, url, cookie) -> None:
|
|
22
22
|
"""
|
|
23
23
|
Initializes the VideoSource object with default values.
|
|
24
24
|
"""
|
|
25
25
|
self.headers = {'user-agent': get_userAgent()}
|
|
26
|
-
self.cookie = cookie
|
|
27
|
-
|
|
28
|
-
def setup(self, url: str) -> None:
|
|
29
|
-
"""
|
|
30
|
-
Sets up the video source with the provided URL.
|
|
31
|
-
|
|
32
|
-
Parameters:
|
|
33
|
-
- url (str): The URL of the video source.
|
|
34
|
-
"""
|
|
35
26
|
self.url = url
|
|
27
|
+
self.cookie = cookie
|
|
36
28
|
|
|
37
29
|
def make_request(self, url: str) -> str:
|
|
38
30
|
"""
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# 11.04.25
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# External libraries
|
|
5
|
+
import httpx
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# Internal utilities
|
|
9
|
+
from StreamingCommunity.Util.config_json import config_manager
|
|
10
|
+
from StreamingCommunity.Util.headers import get_headers
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Variable
|
|
14
|
+
MAX_TIMEOUT = config_manager.get_int("REQUESTS", "timeout")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class VideoSource:
|
|
18
|
+
|
|
19
|
+
@staticmethod
|
|
20
|
+
def extract_m3u8_url(video_url: str) -> str:
|
|
21
|
+
"""Extract the m3u8 streaming URL from a RaiPlay video URL."""
|
|
22
|
+
if not video_url.endswith('.json'):
|
|
23
|
+
if '/video/' in video_url:
|
|
24
|
+
video_id = video_url.split('/')[-1].split('.')[0]
|
|
25
|
+
video_path = '/'.join(video_url.split('/')[:-1])
|
|
26
|
+
video_url = f"{video_path}/{video_id}.json"
|
|
27
|
+
|
|
28
|
+
else:
|
|
29
|
+
return "Error: Unable to determine video JSON URL"
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
response = httpx.get(video_url, headers=get_headers(), timeout=MAX_TIMEOUT)
|
|
33
|
+
if response.status_code != 200:
|
|
34
|
+
return f"Error: Failed to fetch video data (Status: {response.status_code})"
|
|
35
|
+
|
|
36
|
+
video_data = response.json()
|
|
37
|
+
content_url = video_data.get("video").get("content_url")
|
|
38
|
+
|
|
39
|
+
if not content_url:
|
|
40
|
+
return "Error: No content URL found in video data"
|
|
41
|
+
|
|
42
|
+
# Extract the element key
|
|
43
|
+
if "=" in content_url:
|
|
44
|
+
element_key = content_url.split("=")[1]
|
|
45
|
+
else:
|
|
46
|
+
return "Error: Unable to extract element key"
|
|
47
|
+
|
|
48
|
+
# Request the stream URL
|
|
49
|
+
params = {
|
|
50
|
+
'cont': element_key,
|
|
51
|
+
'output': '62',
|
|
52
|
+
}
|
|
53
|
+
stream_response = httpx.get('https://mediapolisvod.rai.it/relinker/relinkerServlet.htm', params=params, headers=get_headers(), timeout=MAX_TIMEOUT)
|
|
54
|
+
|
|
55
|
+
if stream_response.status_code != 200:
|
|
56
|
+
return f"Error: Failed to fetch stream URL (Status: {stream_response.status_code})"
|
|
57
|
+
|
|
58
|
+
# Extract the m3u8 URL
|
|
59
|
+
stream_data = stream_response.json()
|
|
60
|
+
m3u8_url = stream_data.get("video")[0] if "video" in stream_data else None
|
|
61
|
+
return m3u8_url
|
|
62
|
+
|
|
63
|
+
except Exception as e:
|
|
64
|
+
return f"Error: {str(e)}"
|
{streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Player/sweetpixel.py
RENAMED
|
@@ -16,9 +16,9 @@ from StreamingCommunity.Util.headers import get_userAgent
|
|
|
16
16
|
MAX_TIMEOUT = config_manager.get_int("REQUESTS", "timeout")
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
class
|
|
19
|
+
class VideoSource:
|
|
20
20
|
def __init__(self, full_url, episode_data, session_id, csrf_token):
|
|
21
|
-
"""Initialize the
|
|
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
|
|
@@ -33,7 +33,7 @@ class AnimeWorldPlayer:
|
|
|
33
33
|
timeout=MAX_TIMEOUT
|
|
34
34
|
)
|
|
35
35
|
|
|
36
|
-
def
|
|
36
|
+
def get_playlist(self):
|
|
37
37
|
"""Fetch the download link from AnimeWorld using the episode link."""
|
|
38
38
|
try:
|
|
39
39
|
# Make a POST request to the episode link and follow any redirects
|
{streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Player/vixcloud.py
RENAMED
|
@@ -24,26 +24,20 @@ console = Console()
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
class VideoSource:
|
|
27
|
-
def __init__(self, url: str, is_series: bool):
|
|
27
|
+
def __init__(self, url: str, is_series: bool, media_id: int = None):
|
|
28
28
|
"""
|
|
29
29
|
Initialize video source for streaming site.
|
|
30
30
|
|
|
31
31
|
Args:
|
|
32
32
|
- url (str): The URL of the streaming site.
|
|
33
33
|
- is_series (bool): Flag for series or movie content
|
|
34
|
+
- media_id (int, optional): Unique identifier for media item
|
|
34
35
|
"""
|
|
35
36
|
self.headers = {'user-agent': get_userAgent()}
|
|
36
37
|
self.url = url
|
|
37
38
|
self.is_series = is_series
|
|
38
|
-
|
|
39
|
-
def setup(self, media_id: int):
|
|
40
|
-
"""
|
|
41
|
-
Configure media-specific context.
|
|
42
|
-
|
|
43
|
-
Args:
|
|
44
|
-
media_id (int): Unique identifier for media item
|
|
45
|
-
"""
|
|
46
39
|
self.media_id = media_id
|
|
40
|
+
self.iframe_src = None
|
|
47
41
|
|
|
48
42
|
def get_iframe(self, episode_id: int) -> None:
|
|
49
43
|
"""
|
|
@@ -164,6 +158,7 @@ class VideoSourceAnime(VideoSource):
|
|
|
164
158
|
self.headers = {'user-agent': get_userAgent()}
|
|
165
159
|
self.url = url
|
|
166
160
|
self.src_mp4 = None
|
|
161
|
+
self.iframe_src = None
|
|
167
162
|
|
|
168
163
|
def get_embed(self, episode_id: int):
|
|
169
164
|
"""
|
{streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/1337xx/__init__.py
RENAMED
|
@@ -22,8 +22,7 @@ from .title import download_title
|
|
|
22
22
|
# Variable
|
|
23
23
|
indice = 3
|
|
24
24
|
_useFor = "film_serie"
|
|
25
|
-
|
|
26
|
-
_priority = 2
|
|
25
|
+
_priority = 0
|
|
27
26
|
_engineDownload = "tor"
|
|
28
27
|
|
|
29
28
|
console = Console()
|
|
@@ -39,7 +38,7 @@ def process_search_result(select_title):
|
|
|
39
38
|
|
|
40
39
|
def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None):
|
|
41
40
|
"""
|
|
42
|
-
Main function of the application for search
|
|
41
|
+
Main function of the application for search.
|
|
43
42
|
|
|
44
43
|
Parameters:
|
|
45
44
|
string_to_search (str, optional): String to search for
|
{streamingcommunity-2.9.8 → streamingcommunity-3.0.0}/StreamingCommunity/Api/Site/1337xx/site.py
RENAMED
|
@@ -43,7 +43,12 @@ def title_search(query: str) -> int:
|
|
|
43
43
|
console.print(f"[cyan]Search url: [yellow]{search_url}")
|
|
44
44
|
|
|
45
45
|
try:
|
|
46
|
-
response = httpx.get(
|
|
46
|
+
response = httpx.get(
|
|
47
|
+
search_url,
|
|
48
|
+
headers={'user-agent': get_userAgent()},
|
|
49
|
+
timeout=max_timeout,
|
|
50
|
+
follow_redirects=True
|
|
51
|
+
)
|
|
47
52
|
response.raise_for_status()
|
|
48
53
|
|
|
49
54
|
except Exception as e:
|
|
@@ -25,8 +25,7 @@ from .series import download_series
|
|
|
25
25
|
# Variable
|
|
26
26
|
indice = 2
|
|
27
27
|
_useFor = "film_serie"
|
|
28
|
-
|
|
29
|
-
_priority = 1
|
|
28
|
+
_priority = 0
|
|
30
29
|
_engineDownload = "hls"
|
|
31
30
|
|
|
32
31
|
msg = Prompt()
|
|
@@ -57,27 +56,43 @@ def get_user_input(string_to_search: str = None):
|
|
|
57
56
|
|
|
58
57
|
return string_to_search
|
|
59
58
|
|
|
60
|
-
def process_search_result(select_title):
|
|
59
|
+
def process_search_result(select_title, selections=None):
|
|
61
60
|
"""
|
|
62
61
|
Handles the search result and initiates the download for either a film or series.
|
|
62
|
+
|
|
63
|
+
Parameters:
|
|
64
|
+
select_title (MediaItem): The selected media item
|
|
65
|
+
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
66
|
+
{'season': season_selection, 'episode': episode_selection}
|
|
63
67
|
"""
|
|
64
68
|
if select_title.type == 'tv':
|
|
65
|
-
|
|
69
|
+
season_selection = None
|
|
70
|
+
episode_selection = None
|
|
71
|
+
|
|
72
|
+
if selections:
|
|
73
|
+
season_selection = selections.get('season')
|
|
74
|
+
episode_selection = selections.get('episode')
|
|
75
|
+
|
|
76
|
+
download_series(select_title, season_selection, episode_selection)
|
|
77
|
+
|
|
66
78
|
else:
|
|
67
79
|
download_film(select_title)
|
|
68
80
|
|
|
69
|
-
|
|
81
|
+
# search("Game of Thrones", selections={"season": "1", "episode": "1-3"})
|
|
82
|
+
def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None, selections: dict = None):
|
|
70
83
|
"""
|
|
71
|
-
Main function of the application for search
|
|
84
|
+
Main function of the application for search.
|
|
72
85
|
|
|
73
86
|
Parameters:
|
|
74
87
|
string_to_search (str, optional): String to search for
|
|
75
88
|
get_onylDatabase (bool, optional): If True, return only the database object
|
|
76
89
|
direct_item (dict, optional): Direct item to process (bypass search)
|
|
90
|
+
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
91
|
+
{'season': season_selection, 'episode': episode_selection}
|
|
77
92
|
"""
|
|
78
93
|
if direct_item:
|
|
79
94
|
select_title = MediaItem(**direct_item)
|
|
80
|
-
process_search_result(select_title)
|
|
95
|
+
process_search_result(select_title, selections)
|
|
81
96
|
return
|
|
82
97
|
|
|
83
98
|
# Get the user input for the search term
|
|
@@ -95,7 +110,7 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
|
|
|
95
110
|
|
|
96
111
|
if len_database > 0:
|
|
97
112
|
select_title = get_select_title(table_show_manager, media_search_manager)
|
|
98
|
-
process_search_result(select_title)
|
|
113
|
+
process_search_result(select_title, selections)
|
|
99
114
|
|
|
100
115
|
else:
|
|
101
116
|
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
|
|
@@ -105,4 +120,4 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
|
|
|
105
120
|
|
|
106
121
|
# If no results are found, ask again
|
|
107
122
|
string_to_search = get_user_input()
|
|
108
|
-
search()
|
|
123
|
+
search(string_to_search, get_onlyDatabase, None, selections)
|
|
@@ -19,8 +19,7 @@ from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance, Teleg
|
|
|
19
19
|
from .util.ScrapeSerie import GetSerieInfo
|
|
20
20
|
from StreamingCommunity.Api.Template.Util import (
|
|
21
21
|
manage_selection,
|
|
22
|
-
map_episode_title,
|
|
23
|
-
dynamic_format_number,
|
|
22
|
+
map_episode_title,
|
|
24
23
|
validate_selection,
|
|
25
24
|
validate_episode_selection,
|
|
26
25
|
display_episodes_list
|
|
@@ -40,23 +39,24 @@ console = Console()
|
|
|
40
39
|
|
|
41
40
|
def download_video(index_season_selected: int, index_episode_selected: int, scrape_serie: GetSerieInfo) -> Tuple[str,bool]:
|
|
42
41
|
"""
|
|
43
|
-
|
|
42
|
+
Downloads a specific episode from a specified season.
|
|
44
43
|
|
|
45
44
|
Parameters:
|
|
46
|
-
- index_season_selected (int):
|
|
47
|
-
- index_episode_selected (int):
|
|
45
|
+
- index_season_selected (int): Season number
|
|
46
|
+
- index_episode_selected (int): Episode index
|
|
47
|
+
- scrape_serie (GetSerieInfo): Scraper object with series information
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
- str:
|
|
51
|
-
- bool:
|
|
49
|
+
Returns:
|
|
50
|
+
- str: Path to downloaded file
|
|
51
|
+
- bool: Whether download was stopped
|
|
52
52
|
"""
|
|
53
53
|
start_message()
|
|
54
|
-
index_season_selected = dynamic_format_number(str(index_season_selected))
|
|
55
54
|
|
|
56
|
-
# Get
|
|
57
|
-
obj_episode = scrape_serie.
|
|
55
|
+
# Get episode information
|
|
56
|
+
obj_episode = scrape_serie.selectEpisode(index_season_selected, index_episode_selected-1)
|
|
58
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")
|
|
59
58
|
|
|
59
|
+
# Telegram integration
|
|
60
60
|
if site_constant.TELEGRAM_BOT:
|
|
61
61
|
bot = get_bot_instance()
|
|
62
62
|
|
|
@@ -93,21 +93,21 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
|
|
|
93
93
|
return r_proc['path'], r_proc['stopped']
|
|
94
94
|
|
|
95
95
|
|
|
96
|
-
def download_episode(index_season_selected: int, scrape_serie: GetSerieInfo, download_all: bool = False) -> None:
|
|
96
|
+
def download_episode(index_season_selected: int, scrape_serie: GetSerieInfo, download_all: bool = False, episode_selection: str = None) -> None:
|
|
97
97
|
"""
|
|
98
|
-
|
|
98
|
+
Handle downloading episodes for a specific season.
|
|
99
99
|
|
|
100
100
|
Parameters:
|
|
101
|
-
- index_season_selected (int):
|
|
102
|
-
-
|
|
101
|
+
- index_season_selected (int): Season number
|
|
102
|
+
- scrape_serie (GetSerieInfo): Scraper object with series information
|
|
103
|
+
- download_all (bool): Whether to download all episodes
|
|
104
|
+
- episode_selection (str, optional): Pre-defined episode selection that bypasses manual input
|
|
103
105
|
"""
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
episodes_count = len(
|
|
106
|
+
# Get episodes for the selected season
|
|
107
|
+
episodes = scrape_serie.getEpisodeSeasons(index_season_selected)
|
|
108
|
+
episodes_count = len(episodes)
|
|
107
109
|
|
|
108
110
|
if download_all:
|
|
109
|
-
|
|
110
|
-
# Download all episodes without asking
|
|
111
111
|
for i_episode in range(1, episodes_count + 1):
|
|
112
112
|
path, stopped = download_video(index_season_selected, i_episode, scrape_serie)
|
|
113
113
|
|
|
@@ -117,16 +117,16 @@ def download_episode(index_season_selected: int, scrape_serie: GetSerieInfo, dow
|
|
|
117
117
|
console.print(f"\n[red]End downloaded [yellow]season: [red]{index_season_selected}.")
|
|
118
118
|
|
|
119
119
|
else:
|
|
120
|
+
if episode_selection is not None:
|
|
121
|
+
last_command = episode_selection
|
|
122
|
+
console.print(f"\n[cyan]Using provided episode selection: [yellow]{episode_selection}")
|
|
120
123
|
|
|
121
|
-
|
|
122
|
-
|
|
124
|
+
else:
|
|
125
|
+
last_command = display_episodes_list(episodes)
|
|
126
|
+
|
|
127
|
+
# Prompt user for episode selection
|
|
123
128
|
list_episode_select = manage_selection(last_command, episodes_count)
|
|
124
|
-
|
|
125
|
-
try:
|
|
126
|
-
list_episode_select = validate_episode_selection(list_episode_select, episodes_count)
|
|
127
|
-
except ValueError as e:
|
|
128
|
-
console.print(f"[red]{str(e)}")
|
|
129
|
-
return
|
|
129
|
+
list_episode_select = validate_episode_selection(list_episode_select, episodes_count)
|
|
130
130
|
|
|
131
131
|
# Download selected episodes if not stopped
|
|
132
132
|
for i_episode in list_episode_select:
|
|
@@ -135,69 +135,65 @@ def download_episode(index_season_selected: int, scrape_serie: GetSerieInfo, dow
|
|
|
135
135
|
if stopped:
|
|
136
136
|
break
|
|
137
137
|
|
|
138
|
-
def download_series(select_season: MediaItem) -> None:
|
|
138
|
+
def download_series(select_season: MediaItem, season_selection: str = None, episode_selection: str = None) -> None:
|
|
139
139
|
"""
|
|
140
|
-
|
|
140
|
+
Handle downloading a complete series.
|
|
141
141
|
|
|
142
142
|
Parameters:
|
|
143
|
-
- select_season (MediaItem):
|
|
143
|
+
- select_season (MediaItem): Series metadata from search
|
|
144
|
+
- season_selection (str, optional): Pre-defined season selection that bypasses manual input
|
|
145
|
+
- episode_selection (str, optional): Pre-defined episode selection that bypasses manual input
|
|
144
146
|
"""
|
|
145
|
-
if site_constant.TELEGRAM_BOT:
|
|
146
|
-
bot = get_bot_instance()
|
|
147
|
-
|
|
148
|
-
start_message()
|
|
149
|
-
|
|
150
|
-
# Init class
|
|
151
147
|
scrape_serie = GetSerieInfo(select_season.url)
|
|
152
148
|
|
|
153
|
-
#
|
|
154
|
-
scrape_serie.
|
|
155
|
-
|
|
149
|
+
# Get total number of seasons
|
|
150
|
+
seasons_count = scrape_serie.getNumberSeason()
|
|
151
|
+
|
|
152
|
+
if site_constant.TELEGRAM_BOT:
|
|
153
|
+
bot = get_bot_instance()
|
|
156
154
|
|
|
157
155
|
# Prompt user for season selection and download episodes
|
|
158
156
|
console.print(f"\n[green]Seasons found: [red]{seasons_count}")
|
|
159
157
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
158
|
+
# If season_selection is provided, use it instead of asking for input
|
|
159
|
+
if season_selection is None:
|
|
160
|
+
if site_constant.TELEGRAM_BOT:
|
|
161
|
+
console.print("\n[cyan]Insert season number [yellow](e.g., 1), [red]* [cyan]to download all seasons, "
|
|
162
|
+
"[yellow](e.g., 1-2) [cyan]for a range of seasons, or [yellow](e.g., 3-*) [cyan]to download from a specific season to the end")
|
|
163
|
+
|
|
164
|
+
bot.send_message(f"Stagioni trovate: {seasons_count}", None)
|
|
165
|
+
|
|
166
|
+
index_season_selected = bot.ask(
|
|
167
|
+
"select_title_episode",
|
|
168
|
+
"Menu di selezione delle stagioni\n\n"
|
|
169
|
+
"- Inserisci il numero della stagione (ad esempio, 1)\n"
|
|
170
|
+
"- Inserisci * per scaricare tutte le stagioni\n"
|
|
171
|
+
"- Inserisci un intervallo di stagioni (ad esempio, 1-2) per scaricare da una stagione all'altra\n"
|
|
172
|
+
"- Inserisci (ad esempio, 3-*) per scaricare dalla stagione specificata fino alla fine della serie",
|
|
173
|
+
None
|
|
174
|
+
)
|
|
175
175
|
|
|
176
|
+
else:
|
|
177
|
+
index_season_selected = msg.ask(
|
|
178
|
+
"\n[cyan]Insert season number [yellow](e.g., 1), [red]* [cyan]to download all seasons, "
|
|
179
|
+
"[yellow](e.g., 1-2) [cyan]for a range of seasons, or [yellow](e.g., 3-*) [cyan]to download from a specific season to the end"
|
|
180
|
+
)
|
|
176
181
|
else:
|
|
177
|
-
index_season_selected =
|
|
178
|
-
|
|
179
|
-
"[yellow](e.g., 1-2) [cyan]for a range of seasons, or [yellow](e.g., 3-*) [cyan]to download from a specific season to the end"
|
|
180
|
-
)
|
|
182
|
+
index_season_selected = season_selection
|
|
183
|
+
console.print(f"\n[cyan]Using provided season selection: [yellow]{season_selection}")
|
|
181
184
|
|
|
182
|
-
#
|
|
185
|
+
# Validate the selection
|
|
183
186
|
list_season_select = manage_selection(index_season_selected, seasons_count)
|
|
184
|
-
|
|
185
|
-
try:
|
|
186
|
-
list_season_select = validate_selection(list_season_select, seasons_count)
|
|
187
|
-
except ValueError as e:
|
|
188
|
-
console.print(f"[red]{str(e)}")
|
|
189
|
-
return
|
|
187
|
+
list_season_select = validate_selection(list_season_select, seasons_count)
|
|
190
188
|
|
|
191
189
|
# Loop through the selected seasons and download episodes
|
|
192
190
|
for i_season in list_season_select:
|
|
193
191
|
if len(list_season_select) > 1 or index_season_selected == "*":
|
|
194
|
-
|
|
195
192
|
# Download all episodes if multiple seasons are selected or if '*' is used
|
|
196
193
|
download_episode(i_season, scrape_serie, download_all=True)
|
|
197
194
|
else:
|
|
198
|
-
|
|
199
195
|
# Otherwise, let the user select specific episodes for the single season
|
|
200
|
-
download_episode(i_season, scrape_serie, download_all=False)
|
|
196
|
+
download_episode(i_season, scrape_serie, download_all=False, episode_selection=episode_selection)
|
|
201
197
|
|
|
202
198
|
if site_constant.TELEGRAM_BOT:
|
|
203
199
|
bot.send_message(f"Finito di scaricare tutte le serie e episodi", None)
|
|
@@ -205,4 +201,4 @@ def download_series(select_season: MediaItem) -> None:
|
|
|
205
201
|
# Get script_id
|
|
206
202
|
script_id = TelegramSession.get_session()
|
|
207
203
|
if script_id != "unknown":
|
|
208
|
-
TelegramSession.deleteScriptId(script_id)
|
|
204
|
+
TelegramSession.deleteScriptId(script_id)
|
|
@@ -46,7 +46,12 @@ def title_search(query: str) -> int:
|
|
|
46
46
|
console.print(f"[cyan]Search url: [yellow]{search_url}")
|
|
47
47
|
|
|
48
48
|
try:
|
|
49
|
-
response = httpx.post(
|
|
49
|
+
response = httpx.post(
|
|
50
|
+
search_url,
|
|
51
|
+
headers={'user-agent': get_userAgent()},
|
|
52
|
+
timeout=max_timeout,
|
|
53
|
+
follow_redirects=True
|
|
54
|
+
)
|
|
50
55
|
response.raise_for_status()
|
|
51
56
|
|
|
52
57
|
except Exception as e:
|
|
@@ -78,7 +83,8 @@ def title_search(query: str) -> int:
|
|
|
78
83
|
media_search_manager.add_media({
|
|
79
84
|
'url': url,
|
|
80
85
|
'name': title,
|
|
81
|
-
'type': tipo
|
|
86
|
+
'type': tipo,
|
|
87
|
+
'image': f"{site_constant.FULL_URL}{movie_div.find('img', class_='layer-image').get('data-src')}"
|
|
82
88
|
})
|
|
83
89
|
|
|
84
90
|
if site_constant.TELEGRAM_BOT:
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# 16.03.25
|
|
2
2
|
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
|
|
3
6
|
# External libraries
|
|
4
7
|
import httpx
|
|
5
8
|
from bs4 import BeautifulSoup
|
|
@@ -15,7 +18,6 @@ from StreamingCommunity.Api.Player.Helper.Vixcloud.util import SeasonManager
|
|
|
15
18
|
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
16
19
|
|
|
17
20
|
|
|
18
|
-
|
|
19
21
|
class GetSerieInfo:
|
|
20
22
|
def __init__(self, url):
|
|
21
23
|
"""
|
|
@@ -69,4 +71,37 @@ class GetSerieInfo:
|
|
|
69
71
|
'number': ep_idx,
|
|
70
72
|
'name': episode_name,
|
|
71
73
|
'url': episode_url
|
|
72
|
-
})
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# ------------- FOR GUI -------------
|
|
78
|
+
def getNumberSeason(self) -> int:
|
|
79
|
+
"""
|
|
80
|
+
Get the total number of seasons available for the series.
|
|
81
|
+
"""
|
|
82
|
+
if not self.seasons_manager.seasons:
|
|
83
|
+
self.collect_season()
|
|
84
|
+
|
|
85
|
+
return len(self.seasons_manager.seasons)
|
|
86
|
+
|
|
87
|
+
def getEpisodeSeasons(self, season_number: int) -> list:
|
|
88
|
+
"""
|
|
89
|
+
Get all episodes for a specific season.
|
|
90
|
+
"""
|
|
91
|
+
if not self.seasons_manager.seasons:
|
|
92
|
+
self.collect_season()
|
|
93
|
+
|
|
94
|
+
# Get season directly by its number
|
|
95
|
+
season = self.seasons_manager.get_season_by_number(season_number)
|
|
96
|
+
return season.episodes.episodes if season else []
|
|
97
|
+
|
|
98
|
+
def selectEpisode(self, season_number: int, episode_index: int) -> dict:
|
|
99
|
+
"""
|
|
100
|
+
Get information for a specific episode in a specific season.
|
|
101
|
+
"""
|
|
102
|
+
episodes = self.getEpisodeSeasons(season_number)
|
|
103
|
+
if not episodes or episode_index < 0 or episode_index >= len(episodes):
|
|
104
|
+
logging.error(f"Episode index {episode_index} is out of range for season {season_number}")
|
|
105
|
+
return None
|
|
106
|
+
|
|
107
|
+
return episodes[episode_index]
|
|
@@ -18,14 +18,14 @@ from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
|
|
|
18
18
|
|
|
19
19
|
# Logic class
|
|
20
20
|
from .site import title_search, media_search_manager, table_show_manager
|
|
21
|
-
from .
|
|
21
|
+
from .film import download_film
|
|
22
|
+
from .serie import download_series
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
# Variable
|
|
25
26
|
indice = 1
|
|
26
27
|
_useFor = "anime"
|
|
27
|
-
|
|
28
|
-
_priority = 2
|
|
28
|
+
_priority = 0
|
|
29
29
|
_engineDownload = "mp4"
|
|
30
30
|
|
|
31
31
|
msg = Prompt()
|
|
@@ -56,24 +56,42 @@ def get_user_input(string_to_search: str = None):
|
|
|
56
56
|
|
|
57
57
|
return string_to_search
|
|
58
58
|
|
|
59
|
-
def process_search_result(select_title):
|
|
59
|
+
def process_search_result(select_title, selections=None):
|
|
60
60
|
"""
|
|
61
61
|
Handles the search result and initiates the download for either a film or series.
|
|
62
|
+
|
|
63
|
+
Parameters:
|
|
64
|
+
select_title (MediaItem): The selected media item
|
|
65
|
+
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
66
|
+
{'season': season_selection, 'episode': episode_selection}
|
|
62
67
|
"""
|
|
63
|
-
|
|
68
|
+
if select_title.type == 'Movie' or select_title.type == 'OVA':
|
|
69
|
+
download_film(select_title)
|
|
70
|
+
|
|
71
|
+
else:
|
|
72
|
+
season_selection = None
|
|
73
|
+
episode_selection = None
|
|
64
74
|
|
|
65
|
-
|
|
75
|
+
if selections:
|
|
76
|
+
season_selection = selections.get('season')
|
|
77
|
+
episode_selection = selections.get('episode')
|
|
78
|
+
|
|
79
|
+
download_series(select_title, season_selection, episode_selection)
|
|
80
|
+
|
|
81
|
+
def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_item: dict = None, selections: dict = None):
|
|
66
82
|
"""
|
|
67
|
-
Main function of the application for search
|
|
83
|
+
Main function of the application for search.
|
|
68
84
|
|
|
69
85
|
Parameters:
|
|
70
86
|
string_to_search (str, optional): String to search for
|
|
71
87
|
get_onlyDatabase (bool, optional): If True, return only the database object
|
|
72
88
|
direct_item (dict, optional): Direct item to process (bypass search)
|
|
89
|
+
selections (dict, optional): Dictionary containing selection inputs that bypass manual input
|
|
90
|
+
{'season': season_selection, 'episode': episode_selection}
|
|
73
91
|
"""
|
|
74
92
|
if direct_item:
|
|
75
93
|
select_title = MediaItem(**direct_item)
|
|
76
|
-
process_search_result(select_title)
|
|
94
|
+
process_search_result(select_title, selections)
|
|
77
95
|
return
|
|
78
96
|
|
|
79
97
|
# Get the user input for the search term
|
|
@@ -82,7 +100,7 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
|
|
|
82
100
|
# Perform the database search
|
|
83
101
|
len_database = title_search(string_to_search)
|
|
84
102
|
|
|
85
|
-
|
|
103
|
+
# If only the database is needed, return the manager
|
|
86
104
|
if get_onlyDatabase:
|
|
87
105
|
return media_search_manager
|
|
88
106
|
|
|
@@ -91,8 +109,8 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
|
|
|
91
109
|
|
|
92
110
|
if len_database > 0:
|
|
93
111
|
select_title = get_select_title(table_show_manager, media_search_manager)
|
|
94
|
-
process_search_result(select_title)
|
|
95
|
-
|
|
112
|
+
process_search_result(select_title, selections)
|
|
113
|
+
|
|
96
114
|
else:
|
|
97
115
|
console.print(f"\n[red]Nothing matching was found for[white]: [purple]{string_to_search}")
|
|
98
116
|
|
|
@@ -101,4 +119,4 @@ def search(string_to_search: str = None, get_onlyDatabase: bool = False, direct_
|
|
|
101
119
|
|
|
102
120
|
# If no results are found, ask again
|
|
103
121
|
string_to_search = get_user_input()
|
|
104
|
-
search()
|
|
122
|
+
search(string_to_search, get_onlyDatabase, None, selections)
|