StreamingCommunity 3.3.9__py3-none-any.whl → 3.4.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of StreamingCommunity might be problematic. Click here for more details.
- StreamingCommunity/Api/Player/hdplayer.py +0 -5
- StreamingCommunity/Api/Player/mediapolisvod.py +4 -13
- StreamingCommunity/Api/Player/supervideo.py +3 -8
- StreamingCommunity/Api/Player/sweetpixel.py +1 -9
- StreamingCommunity/Api/Player/vixcloud.py +5 -16
- StreamingCommunity/Api/Site/altadefinizione/film.py +4 -16
- StreamingCommunity/Api/Site/altadefinizione/series.py +3 -12
- StreamingCommunity/Api/Site/altadefinizione/site.py +2 -9
- StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py +2 -7
- StreamingCommunity/Api/Site/animeunity/site.py +9 -24
- StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py +11 -27
- StreamingCommunity/Api/Site/animeworld/film.py +4 -2
- StreamingCommunity/Api/Site/animeworld/site.py +3 -11
- StreamingCommunity/Api/Site/animeworld/util/ScrapeSerie.py +1 -4
- StreamingCommunity/Api/Site/crunchyroll/film.py +4 -5
- StreamingCommunity/Api/Site/crunchyroll/series.py +5 -17
- StreamingCommunity/Api/Site/crunchyroll/site.py +4 -13
- StreamingCommunity/Api/Site/crunchyroll/util/ScrapeSerie.py +5 -27
- StreamingCommunity/Api/Site/crunchyroll/util/get_license.py +11 -26
- StreamingCommunity/Api/Site/guardaserie/series.py +3 -14
- StreamingCommunity/Api/Site/guardaserie/site.py +4 -12
- StreamingCommunity/Api/Site/guardaserie/util/ScrapeSerie.py +3 -10
- StreamingCommunity/Api/Site/mediasetinfinity/film.py +11 -12
- StreamingCommunity/Api/Site/mediasetinfinity/series.py +4 -15
- StreamingCommunity/Api/Site/mediasetinfinity/site.py +16 -32
- StreamingCommunity/Api/Site/mediasetinfinity/util/ScrapeSerie.py +39 -50
- StreamingCommunity/Api/Site/mediasetinfinity/util/fix_mpd.py +3 -3
- StreamingCommunity/Api/Site/mediasetinfinity/util/get_license.py +7 -25
- StreamingCommunity/Api/Site/raiplay/film.py +6 -8
- StreamingCommunity/Api/Site/raiplay/series.py +5 -20
- StreamingCommunity/Api/Site/raiplay/site.py +45 -47
- StreamingCommunity/Api/Site/raiplay/util/ScrapeSerie.py +91 -55
- StreamingCommunity/Api/Site/raiplay/util/get_license.py +3 -12
- StreamingCommunity/Api/Site/streamingcommunity/film.py +5 -16
- StreamingCommunity/Api/Site/streamingcommunity/series.py +5 -10
- StreamingCommunity/Api/Site/streamingcommunity/site.py +3 -22
- StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +11 -27
- StreamingCommunity/Api/Site/streamingwatch/__init__.py +1 -0
- StreamingCommunity/Api/Site/streamingwatch/film.py +4 -2
- StreamingCommunity/Api/Site/streamingwatch/series.py +4 -14
- StreamingCommunity/Api/Site/streamingwatch/site.py +4 -18
- StreamingCommunity/Api/Site/streamingwatch/util/ScrapeSerie.py +0 -3
- StreamingCommunity/Api/Template/Util/__init__.py +4 -2
- StreamingCommunity/Api/Template/Util/manage_ep.py +66 -0
- StreamingCommunity/Api/Template/config_loader.py +0 -7
- StreamingCommunity/Lib/Downloader/DASH/decrypt.py +54 -1
- StreamingCommunity/Lib/Downloader/DASH/downloader.py +186 -70
- StreamingCommunity/Lib/Downloader/DASH/parser.py +2 -3
- StreamingCommunity/Lib/Downloader/DASH/segments.py +109 -68
- StreamingCommunity/Lib/Downloader/HLS/downloader.py +100 -82
- StreamingCommunity/Lib/Downloader/HLS/segments.py +40 -28
- StreamingCommunity/Lib/Downloader/MP4/downloader.py +16 -4
- StreamingCommunity/Lib/FFmpeg/capture.py +37 -5
- StreamingCommunity/Lib/FFmpeg/command.py +32 -90
- StreamingCommunity/Lib/M3U8/estimator.py +47 -1
- StreamingCommunity/Lib/TMBD/tmdb.py +2 -4
- StreamingCommunity/TelegramHelp/config.json +0 -1
- StreamingCommunity/Upload/update.py +19 -6
- StreamingCommunity/Upload/version.py +1 -1
- StreamingCommunity/Util/config_json.py +28 -21
- StreamingCommunity/Util/http_client.py +28 -0
- StreamingCommunity/Util/os.py +16 -6
- StreamingCommunity/Util/table.py +50 -8
- {streamingcommunity-3.3.9.dist-info → streamingcommunity-3.4.2.dist-info}/METADATA +1 -3
- streamingcommunity-3.4.2.dist-info/RECORD +111 -0
- streamingcommunity-3.3.9.dist-info/RECORD +0 -111
- {streamingcommunity-3.3.9.dist-info → streamingcommunity-3.4.2.dist-info}/WHEEL +0 -0
- {streamingcommunity-3.3.9.dist-info → streamingcommunity-3.4.2.dist-info}/entry_points.txt +0 -0
- {streamingcommunity-3.3.9.dist-info → streamingcommunity-3.4.2.dist-info}/licenses/LICENSE +0 -0
- {streamingcommunity-3.3.9.dist-info → streamingcommunity-3.4.2.dist-info}/top_level.txt +0 -0
|
@@ -5,18 +5,14 @@ from urllib.parse import urlparse
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
# External libraries
|
|
8
|
-
import httpx
|
|
9
8
|
from bs4 import BeautifulSoup
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
# Internal utilities
|
|
13
|
-
from StreamingCommunity.Util.config_json import config_manager
|
|
14
12
|
from StreamingCommunity.Util.headers import get_headers, get_userAgent
|
|
13
|
+
from StreamingCommunity.Util.http_client import create_client
|
|
15
14
|
from StreamingCommunity.Api.Player.Helper.Vixcloud.util import SeasonManager
|
|
16
15
|
|
|
17
|
-
# Variable
|
|
18
|
-
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
19
|
-
|
|
20
16
|
|
|
21
17
|
class GetSerieInfo:
|
|
22
18
|
def __init__(self, url):
|
|
@@ -46,20 +42,14 @@ class GetSerieInfo:
|
|
|
46
42
|
|
|
47
43
|
def _get_series_data(self):
|
|
48
44
|
"""Get series data through the API"""
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
response = client.get(
|
|
54
|
-
f'https://feed.entertainment.tv.theplatform.eu/f/{self.public_id}/mediaset-prod-all-series-v2',
|
|
55
|
-
params=params,
|
|
56
|
-
headers=headers
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
if response.status_code == 200:
|
|
45
|
+
try:
|
|
46
|
+
params = {'byGuid': self.serie_id}
|
|
47
|
+
response = create_client(headers=self.headers).get(f'https://feed.entertainment.tv.theplatform.eu/f/{self.public_id}/mediaset-prod-all-series-v2', params=params)
|
|
48
|
+
response.raise_for_status()
|
|
60
49
|
return response.json()
|
|
61
|
-
|
|
62
|
-
|
|
50
|
+
|
|
51
|
+
except Exception as e:
|
|
52
|
+
logging.error(f"Failed to get series data with error: {e}")
|
|
63
53
|
return None
|
|
64
54
|
|
|
65
55
|
def _process_available_seasons(self, data):
|
|
@@ -106,32 +96,30 @@ class GetSerieInfo:
|
|
|
106
96
|
|
|
107
97
|
def _extract_season_sb_ids(self, stagioni_disponibili):
|
|
108
98
|
"""Extract sb IDs from season pages"""
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
else:
|
|
134
|
-
logging.warning(f"Link 'Episodi' or 'Puntate intere' not found for season {season['tvSeasonNumber']}")
|
|
99
|
+
client = create_client()
|
|
100
|
+
|
|
101
|
+
for season in stagioni_disponibili:
|
|
102
|
+
response_page = client.get(season['page_url'], headers={'User-Agent': get_userAgent()})
|
|
103
|
+
|
|
104
|
+
print("Response for _extract_season_sb_ids:", response_page.status_code, " season index:", season['tvSeasonNumber'])
|
|
105
|
+
soup = BeautifulSoup(response_page.text, 'html.parser')
|
|
106
|
+
|
|
107
|
+
# Try first with 'Episodi', then with 'Puntate intere'
|
|
108
|
+
link = soup.find('a', string='Episodi')
|
|
109
|
+
if not link:
|
|
110
|
+
#print("Using word: Puntate intere")
|
|
111
|
+
link = soup.find('a', string='Puntate intere')
|
|
112
|
+
|
|
113
|
+
if link is None:
|
|
114
|
+
link = soup.find('a', class_ = 'titleCarousel')
|
|
115
|
+
|
|
116
|
+
if link and link.has_attr('href'):
|
|
117
|
+
if not link.string == 'Puntate intere':
|
|
118
|
+
print("Using word: Episodi")
|
|
119
|
+
|
|
120
|
+
season['sb'] = link['href'].split(',')[-1]
|
|
121
|
+
else:
|
|
122
|
+
logging.warning(f"Link 'Episodi' or 'Puntate intere' not found for season {season['tvSeasonNumber']}")
|
|
135
123
|
|
|
136
124
|
def _get_season_episodes(self, season):
|
|
137
125
|
"""Get episodes for a specific season"""
|
|
@@ -147,11 +135,11 @@ class GetSerieInfo:
|
|
|
147
135
|
'range': '0-100',
|
|
148
136
|
}
|
|
149
137
|
episode_url = f"https://feed.entertainment.tv.theplatform.eu/f/{self.public_id}/mediaset-prod-all-programs-v2"
|
|
150
|
-
|
|
151
|
-
with httpx.Client(timeout=max_timeout, follow_redirects=True) as client:
|
|
152
|
-
episode_response = client.get(episode_url, headers=episode_headers, params=params)
|
|
153
138
|
|
|
154
|
-
|
|
139
|
+
try:
|
|
140
|
+
episode_response = create_client(headers=episode_headers).get(episode_url, params=params)
|
|
141
|
+
episode_response.raise_for_status()
|
|
142
|
+
|
|
155
143
|
episode_data = episode_response.json()
|
|
156
144
|
season['episodes'] = []
|
|
157
145
|
|
|
@@ -166,8 +154,9 @@ class GetSerieInfo:
|
|
|
166
154
|
season['episodes'].append(episode_info)
|
|
167
155
|
|
|
168
156
|
print(f"Found {len(season['episodes'])} episodes for season {season['tvSeasonNumber']}")
|
|
169
|
-
|
|
170
|
-
|
|
157
|
+
|
|
158
|
+
except Exception as e:
|
|
159
|
+
logging.error(f"Failed to get episodes for season {season['tvSeasonNumber']} with error: {e}")
|
|
171
160
|
|
|
172
161
|
def collect_season(self) -> None:
|
|
173
162
|
"""
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
from urllib.parse import urlparse, urlunparse
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
#
|
|
7
|
-
import
|
|
6
|
+
# Internal utilities
|
|
7
|
+
from StreamingCommunity.Util.http_client import create_client
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def try_mpd(url, qualities):
|
|
@@ -42,7 +42,7 @@ def try_mpd(url, qualities):
|
|
|
42
42
|
mpd_url = urlunparse(parsed._replace(path=new_path)).strip()
|
|
43
43
|
|
|
44
44
|
try:
|
|
45
|
-
r =
|
|
45
|
+
r = create_client().head(mpd_url)
|
|
46
46
|
if r.status_code == 200:
|
|
47
47
|
return mpd_url
|
|
48
48
|
|
|
@@ -7,19 +7,17 @@ import xml.etree.ElementTree as ET
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
# External library
|
|
10
|
-
import httpx
|
|
11
10
|
from bs4 import BeautifulSoup
|
|
12
11
|
from rich.console import Console
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
# Internal utilities
|
|
16
|
-
from StreamingCommunity.Util.
|
|
15
|
+
from StreamingCommunity.Util.http_client import create_client
|
|
17
16
|
from StreamingCommunity.Util.headers import get_headers, get_userAgent
|
|
18
17
|
|
|
19
18
|
|
|
20
19
|
# Variable
|
|
21
20
|
console = Console()
|
|
22
|
-
MAX_TIMEOUT = config_manager.get_int("REQUESTS", "timeout")
|
|
23
21
|
network_data = []
|
|
24
22
|
class_mediaset_api = None
|
|
25
23
|
|
|
@@ -51,17 +49,13 @@ class MediasetAPI:
|
|
|
51
49
|
'appName': self.app_name,
|
|
52
50
|
'client_id': self.client_id,
|
|
53
51
|
}
|
|
54
|
-
response =
|
|
55
|
-
'https://api-ott-prod-fe.mediaset.net/PROD/play/idm/anonymous/login/v2.0',
|
|
56
|
-
headers=self.headers,
|
|
57
|
-
json=json_data,
|
|
58
|
-
)
|
|
52
|
+
response = create_client(headers=self.headers).post('https://api-ott-prod-fe.mediaset.net/PROD/play/idm/anonymous/login/v2.0', json=json_data)
|
|
59
53
|
return response.json()['response']['beToken']
|
|
60
54
|
|
|
61
55
|
def fetch_html(self, timeout=10):
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return
|
|
56
|
+
response = create_client(headers=self.headers).get("https://mediasetinfinity.mediaset.it/")
|
|
57
|
+
response.raise_for_status()
|
|
58
|
+
return response.text
|
|
65
59
|
|
|
66
60
|
def find_relevant_script(self, html):
|
|
67
61
|
soup = BeautifulSoup(html, "html.parser")
|
|
@@ -124,13 +118,7 @@ def get_playback_url(CONTENT_ID):
|
|
|
124
118
|
}
|
|
125
119
|
|
|
126
120
|
try:
|
|
127
|
-
response =
|
|
128
|
-
'https://api-ott-prod-fe.mediaset.net/PROD/play/playback/check/v2.0',
|
|
129
|
-
headers=headers,
|
|
130
|
-
json=json_data,
|
|
131
|
-
follow_redirects=True,
|
|
132
|
-
timeout=MAX_TIMEOUT
|
|
133
|
-
)
|
|
121
|
+
response = create_client(headers=headers).post('https://api-ott-prod-fe.mediaset.net/PROD/play/playback/check/v2.0', json=json_data)
|
|
134
122
|
response.raise_for_status()
|
|
135
123
|
resp_json = response.json()
|
|
136
124
|
|
|
@@ -255,13 +243,7 @@ def get_tracking_info(PLAYBACK_JSON):
|
|
|
255
243
|
params['publicUrl'] = PLAYBACK_JSON['publicUrl']
|
|
256
244
|
|
|
257
245
|
try:
|
|
258
|
-
response =
|
|
259
|
-
PLAYBACK_JSON['url'],
|
|
260
|
-
headers={'user-agent': get_userAgent()},
|
|
261
|
-
params=params,
|
|
262
|
-
follow_redirects=True,
|
|
263
|
-
timeout=MAX_TIMEOUT
|
|
264
|
-
)
|
|
246
|
+
response = create_client(headers={'user-agent': get_userAgent()}).get(PLAYBACK_JSON['url'], params=params)
|
|
265
247
|
response.raise_for_status()
|
|
266
248
|
|
|
267
249
|
results = parse_smil_for_media_info(response.text)
|
|
@@ -5,17 +5,16 @@ from typing import Tuple
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
# External library
|
|
8
|
-
import httpx
|
|
9
8
|
from rich.console import Console
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
# Internal utilities
|
|
13
12
|
from StreamingCommunity.Util.os import os_manager
|
|
13
|
+
from StreamingCommunity.Util.config_json import config_manager
|
|
14
14
|
from StreamingCommunity.Util.headers import get_headers
|
|
15
|
-
from StreamingCommunity.Util.
|
|
15
|
+
from StreamingCommunity.Util.http_client import create_client
|
|
16
16
|
from StreamingCommunity.Util.message import start_message
|
|
17
17
|
|
|
18
|
-
|
|
19
18
|
# Logic class
|
|
20
19
|
from .util.get_license import generate_license_url
|
|
21
20
|
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
@@ -29,6 +28,7 @@ from StreamingCommunity.Api.Player.mediapolisvod import VideoSource
|
|
|
29
28
|
|
|
30
29
|
# Variable
|
|
31
30
|
console = Console()
|
|
31
|
+
extension_output = config_manager.get("M3U8_CONVERSION", "extension")
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
def download_film(select_title: MediaItem) -> Tuple[str, bool]:
|
|
@@ -46,13 +46,13 @@ def download_film(select_title: MediaItem) -> Tuple[str, bool]:
|
|
|
46
46
|
console.print(f"\n[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [cyan]{select_title.name}[/cyan] \n")
|
|
47
47
|
|
|
48
48
|
# Extract m3u8 URL from the film's URL
|
|
49
|
-
response =
|
|
49
|
+
response = create_client(headers=get_headers()).get(select_title.url + ".json")
|
|
50
50
|
first_item_path = "https://www.raiplay.it" + response.json().get("first_item_path")
|
|
51
51
|
master_playlist = VideoSource.extract_m3u8_url(first_item_path)
|
|
52
52
|
|
|
53
53
|
# Define the filename and path for the downloaded film
|
|
54
|
-
mp4_name = os_manager.get_sanitize_file(select_title.name) +
|
|
55
|
-
mp4_path = os.path.join(site_constant.MOVIE_FOLDER, mp4_name.replace(
|
|
54
|
+
mp4_name = os_manager.get_sanitize_file(select_title.name, select_title.date) + extension_output
|
|
55
|
+
mp4_path = os.path.join(site_constant.MOVIE_FOLDER, mp4_name.replace(extension_output, ""))
|
|
56
56
|
|
|
57
57
|
# HLS
|
|
58
58
|
if ".mpd" not in master_playlist:
|
|
@@ -66,7 +66,6 @@ def download_film(select_title: MediaItem) -> Tuple[str, bool]:
|
|
|
66
66
|
license_url = generate_license_url(select_title.mpd_id)
|
|
67
67
|
|
|
68
68
|
dash_process = DASH_Downloader(
|
|
69
|
-
cdm_device=get_wvd_path(),
|
|
70
69
|
license_url=license_url,
|
|
71
70
|
mpd_url=master_playlist,
|
|
72
71
|
output_path=os.path.join(mp4_path, mp4_name),
|
|
@@ -79,7 +78,6 @@ def download_film(select_title: MediaItem) -> Tuple[str, bool]:
|
|
|
79
78
|
# Get final output path and status
|
|
80
79
|
r_proc = dash_process.get_status()
|
|
81
80
|
|
|
82
|
-
|
|
83
81
|
if r_proc['error'] is not None:
|
|
84
82
|
try:
|
|
85
83
|
os.remove(r_proc['path'])
|
|
@@ -11,7 +11,6 @@ from rich.prompt import Prompt
|
|
|
11
11
|
|
|
12
12
|
# Internal utilities
|
|
13
13
|
from StreamingCommunity.Util.headers import get_headers, get_userAgent
|
|
14
|
-
from StreamingCommunity.Util.os import get_wvd_path
|
|
15
14
|
from StreamingCommunity.Util.message import start_message
|
|
16
15
|
|
|
17
16
|
|
|
@@ -24,7 +23,8 @@ from StreamingCommunity.Api.Template.Util import (
|
|
|
24
23
|
map_episode_title,
|
|
25
24
|
validate_selection,
|
|
26
25
|
validate_episode_selection,
|
|
27
|
-
display_episodes_list
|
|
26
|
+
display_episodes_list,
|
|
27
|
+
display_seasons_list
|
|
28
28
|
)
|
|
29
29
|
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
30
30
|
from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
@@ -72,17 +72,8 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
|
|
|
72
72
|
m3u8_url=master_playlist,
|
|
73
73
|
output_path=os.path.join(mp4_path, mp4_name)
|
|
74
74
|
).start()
|
|
75
|
-
# Get streaming URL
|
|
76
|
-
master_playlist = VideoSource.extract_m3u8_url(obj_episode.url)
|
|
77
75
|
|
|
78
|
-
#
|
|
79
|
-
if ".mpd" not in master_playlist:
|
|
80
|
-
r_proc = HLS_Downloader(
|
|
81
|
-
m3u8_url=master_playlist,
|
|
82
|
-
output_path=os.path.join(mp4_path, mp4_name)
|
|
83
|
-
).start()
|
|
84
|
-
|
|
85
|
-
# MPD
|
|
76
|
+
# MPD (DASH)
|
|
86
77
|
else:
|
|
87
78
|
full_license_url = generate_license_url(obj_episode.mpd_id)
|
|
88
79
|
license_headers = {
|
|
@@ -91,7 +82,6 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
|
|
|
91
82
|
}
|
|
92
83
|
|
|
93
84
|
dash_process = DASH_Downloader(
|
|
94
|
-
cdm_device=get_wvd_path(),
|
|
95
85
|
license_url=full_license_url.split("?")[0],
|
|
96
86
|
mpd_url=master_playlist,
|
|
97
87
|
output_path=os.path.join(mp4_path, mp4_name),
|
|
@@ -171,15 +161,10 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
|
|
|
171
161
|
# Get seasons info
|
|
172
162
|
scrape_serie.collect_info_title()
|
|
173
163
|
seasons_count = len(scrape_serie.seasons_manager)
|
|
174
|
-
console.print(f"\n[green]Seasons found: [red]{seasons_count}")
|
|
175
164
|
|
|
176
165
|
# If season_selection is provided, use it instead of asking for input
|
|
177
166
|
if season_selection is None:
|
|
178
|
-
index_season_selected =
|
|
179
|
-
"\n[cyan]Insert season number [yellow](e.g., 1), [red]* [cyan]to download all seasons, "
|
|
180
|
-
"[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"
|
|
181
|
-
)
|
|
182
|
-
|
|
167
|
+
index_season_selected = display_seasons_list(scrape_serie.seasons_manager)
|
|
183
168
|
else:
|
|
184
169
|
index_season_selected = season_selection
|
|
185
170
|
console.print(f"\n[cyan]Using provided season selection: [yellow]{season_selection}")
|
|
@@ -193,4 +178,4 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
|
|
|
193
178
|
if len(list_season_select) > 1 or index_season_selected == "*":
|
|
194
179
|
download_episode(season_number, scrape_serie, download_all=True)
|
|
195
180
|
else:
|
|
196
|
-
download_episode(season_number, scrape_serie, download_all=False, episode_selection=episode_selection)
|
|
181
|
+
download_episode(season_number, scrape_serie, download_all=False, episode_selection=episode_selection)
|
|
@@ -1,42 +1,21 @@
|
|
|
1
1
|
# 21.05.24
|
|
2
2
|
|
|
3
3
|
# External libraries
|
|
4
|
-
import httpx
|
|
5
4
|
from rich.console import Console
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
# Internal utilities
|
|
9
|
-
from StreamingCommunity.Util.
|
|
10
|
-
from StreamingCommunity.Util.
|
|
8
|
+
from StreamingCommunity.Util.headers import get_headers
|
|
9
|
+
from StreamingCommunity.Util.http_client import create_client
|
|
11
10
|
from StreamingCommunity.Util.table import TVShowManager
|
|
12
11
|
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
13
12
|
from StreamingCommunity.Api.Template.Class.SearchType import MediaManager
|
|
14
13
|
|
|
15
14
|
|
|
16
|
-
# Logic Import
|
|
17
|
-
from .util.ScrapeSerie import GetSerieInfo
|
|
18
|
-
|
|
19
|
-
|
|
20
15
|
# Variable
|
|
21
16
|
console = Console()
|
|
22
17
|
media_search_manager = MediaManager()
|
|
23
18
|
table_show_manager = TVShowManager()
|
|
24
|
-
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def determine_media_type(item):
|
|
28
|
-
"""
|
|
29
|
-
Determine if the item is a film or TV series by checking actual seasons count
|
|
30
|
-
using GetSerieInfo.
|
|
31
|
-
"""
|
|
32
|
-
try:
|
|
33
|
-
scraper = GetSerieInfo(item.get('path_id'))
|
|
34
|
-
scraper.collect_info_title()
|
|
35
|
-
return scraper.prog_tipology, scraper.prog_description, scraper.prog_year
|
|
36
|
-
|
|
37
|
-
except Exception as e:
|
|
38
|
-
console.print(f"[red]Error determining media type: {e}[/red]")
|
|
39
|
-
return None, None, None
|
|
40
19
|
|
|
41
20
|
|
|
42
21
|
def title_search(query: str) -> int:
|
|
@@ -67,37 +46,56 @@ def title_search(query: str) -> int:
|
|
|
67
46
|
}
|
|
68
47
|
|
|
69
48
|
try:
|
|
70
|
-
response =
|
|
71
|
-
search_url,
|
|
72
|
-
headers={'user-agent': get_userAgent()},
|
|
73
|
-
json=json_data,
|
|
74
|
-
timeout=max_timeout,
|
|
75
|
-
follow_redirects=True
|
|
76
|
-
)
|
|
49
|
+
response = create_client(headers=get_headers()).post(search_url, json=json_data)
|
|
77
50
|
response.raise_for_status()
|
|
78
51
|
|
|
79
52
|
except Exception as e:
|
|
80
53
|
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
81
54
|
return 0
|
|
82
55
|
|
|
83
|
-
|
|
84
|
-
|
|
56
|
+
try:
|
|
57
|
+
response_data = response.json()
|
|
58
|
+
cards = response_data.get('agg', {}).get('titoli', {}).get('cards', [])
|
|
59
|
+
|
|
60
|
+
# Limit to only 15 results for performance
|
|
61
|
+
data = cards[:15]
|
|
62
|
+
console.print(f"[cyan]Found {len(cards)} results, processing first {len(data)}...[/cyan]")
|
|
63
|
+
|
|
64
|
+
except Exception as e:
|
|
65
|
+
console.print(f"[red]Error parsing search results: {e}[/red]")
|
|
66
|
+
return 0
|
|
85
67
|
|
|
86
68
|
# Process each item and add to media manager
|
|
87
|
-
for item in data:
|
|
88
|
-
|
|
89
|
-
|
|
69
|
+
for idx, item in enumerate(data, 1):
|
|
70
|
+
try:
|
|
71
|
+
# Get path_id
|
|
72
|
+
path_id = item.get('path_id', '')
|
|
73
|
+
if not path_id:
|
|
74
|
+
console.print("[yellow]Skipping item due to missing path_id[/yellow]")
|
|
75
|
+
continue
|
|
76
|
+
|
|
77
|
+
# Get image URL - handle both relative and absolute URLs
|
|
78
|
+
image = item.get('immagine', '')
|
|
79
|
+
if image and not image.startswith('http'):
|
|
80
|
+
image = f"https://www.raiplay.it{image}"
|
|
81
|
+
|
|
82
|
+
# Get URL - handle both relative and absolute URLs
|
|
83
|
+
url = item.get('url', '')
|
|
84
|
+
if url and not url.startswith('http'):
|
|
85
|
+
url = f"https://www.raiplay.it{url}"
|
|
86
|
+
|
|
87
|
+
media_search_manager.add_media({
|
|
88
|
+
'id': item.get('id', ''),
|
|
89
|
+
'name': item.get('titolo', 'Unknown'),
|
|
90
|
+
'type': "tv",
|
|
91
|
+
'path_id': path_id,
|
|
92
|
+
'url': url,
|
|
93
|
+
'image': image,
|
|
94
|
+
'year': image.split("/")[5]
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
except Exception as e:
|
|
98
|
+
console.print(f"[red]Error processing item '{item.get('titolo', 'Unknown')}': {e}[/red]")
|
|
90
99
|
continue
|
|
91
|
-
|
|
92
|
-
media_search_manager.add_media({
|
|
93
|
-
'id': item.get('id', ''),
|
|
94
|
-
'name': item.get('titolo', ''),
|
|
95
|
-
'type': media_type,
|
|
96
|
-
'path_id': item.get('path_id', ''),
|
|
97
|
-
'url': f"https://www.raiplay.it{item.get('url', '')}",
|
|
98
|
-
'image': f"https://www.raiplay.it{item.get('immagine', '')}",
|
|
99
|
-
'desc': prog_description,
|
|
100
|
-
'year': prog_year
|
|
101
|
-
})
|
|
102
|
-
|
|
100
|
+
|
|
103
101
|
return media_search_manager.get_length()
|