StreamingCommunity 3.3.8__py3-none-any.whl → 3.4.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/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 -15
- StreamingCommunity/Api/Site/altadefinizione/site.py +2 -7
- 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 +17 -8
- StreamingCommunity/Api/Site/crunchyroll/series.py +8 -9
- StreamingCommunity/Api/Site/crunchyroll/site.py +14 -16
- StreamingCommunity/Api/Site/crunchyroll/util/ScrapeSerie.py +18 -65
- StreamingCommunity/Api/Site/crunchyroll/util/get_license.py +97 -106
- 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 +1 -2
- StreamingCommunity/Api/Site/mediasetinfinity/site.py +3 -11
- 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 +8 -26
- StreamingCommunity/Api/Site/raiplay/film.py +6 -7
- StreamingCommunity/Api/Site/raiplay/series.py +1 -12
- StreamingCommunity/Api/Site/raiplay/site.py +8 -24
- StreamingCommunity/Api/Site/raiplay/util/ScrapeSerie.py +15 -22
- StreamingCommunity/Api/Site/raiplay/util/get_license.py +3 -12
- StreamingCommunity/Api/Site/streamingcommunity/film.py +5 -16
- StreamingCommunity/Api/Site/streamingcommunity/site.py +3 -22
- StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +11 -26
- StreamingCommunity/Api/Site/streamingwatch/__init__.py +1 -0
- StreamingCommunity/Api/Site/streamingwatch/film.py +4 -2
- StreamingCommunity/Api/Site/streamingwatch/series.py +1 -1
- StreamingCommunity/Api/Site/streamingwatch/site.py +4 -18
- StreamingCommunity/Api/Site/streamingwatch/util/ScrapeSerie.py +0 -3
- StreamingCommunity/Api/Template/config_loader.py +0 -7
- StreamingCommunity/Lib/Downloader/DASH/cdm_helpher.py +8 -3
- StreamingCommunity/Lib/Downloader/DASH/decrypt.py +55 -1
- StreamingCommunity/Lib/Downloader/DASH/downloader.py +139 -55
- StreamingCommunity/Lib/Downloader/DASH/parser.py +458 -101
- StreamingCommunity/Lib/Downloader/DASH/segments.py +131 -74
- StreamingCommunity/Lib/Downloader/HLS/downloader.py +31 -50
- StreamingCommunity/Lib/Downloader/HLS/segments.py +266 -365
- StreamingCommunity/Lib/Downloader/MP4/downloader.py +1 -1
- StreamingCommunity/Lib/FFmpeg/capture.py +37 -5
- StreamingCommunity/Lib/FFmpeg/command.py +35 -93
- StreamingCommunity/Lib/M3U8/estimator.py +0 -1
- StreamingCommunity/Lib/TMBD/tmdb.py +2 -4
- StreamingCommunity/TelegramHelp/config.json +0 -1
- 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-3.3.8.dist-info → streamingcommunity-3.4.0.dist-info}/METADATA +1 -3
- streamingcommunity-3.4.0.dist-info/RECORD +111 -0
- streamingcommunity-3.3.8.dist-info/RECORD +0 -111
- {streamingcommunity-3.3.8.dist-info → streamingcommunity-3.4.0.dist-info}/WHEEL +0 -0
- {streamingcommunity-3.3.8.dist-info → streamingcommunity-3.4.0.dist-info}/entry_points.txt +0 -0
- {streamingcommunity-3.3.8.dist-info → streamingcommunity-3.4.0.dist-info}/licenses/LICENSE +0 -0
- {streamingcommunity-3.3.8.dist-info → streamingcommunity-3.4.0.dist-info}/top_level.txt +0 -0
|
@@ -9,13 +9,8 @@ from bs4 import BeautifulSoup
|
|
|
9
9
|
# Internal utilities
|
|
10
10
|
from StreamingCommunity.Util.headers import get_userAgent
|
|
11
11
|
from StreamingCommunity.Util.http_client import create_client
|
|
12
|
-
from StreamingCommunity.Util.config_json import config_manager
|
|
13
12
|
|
|
14
13
|
|
|
15
|
-
# Variable
|
|
16
|
-
MAX_TIMEOUT = config_manager.get_int("REQUESTS", "timeout")
|
|
17
|
-
REQUEST_VERIFY = config_manager.get_bool('REQUESTS', 'verify')
|
|
18
|
-
|
|
19
14
|
|
|
20
15
|
class VideoSource:
|
|
21
16
|
def __init__(self):
|
|
@@ -1,21 +1,12 @@
|
|
|
1
1
|
# 11.04.25
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
# External libraries
|
|
5
|
-
import httpx
|
|
6
|
-
|
|
7
|
-
|
|
8
4
|
# Internal utilities
|
|
9
|
-
from StreamingCommunity.Util.
|
|
5
|
+
from StreamingCommunity.Util.http_client import create_client
|
|
10
6
|
from StreamingCommunity.Util.headers import get_headers
|
|
11
7
|
|
|
12
8
|
|
|
13
|
-
# Variable
|
|
14
|
-
MAX_TIMEOUT = config_manager.get_int("REQUESTS", "timeout")
|
|
15
|
-
REQUEST_VERIFY = config_manager.get_bool('REQUESTS', 'verify')
|
|
16
|
-
|
|
17
9
|
class VideoSource:
|
|
18
|
-
|
|
19
10
|
@staticmethod
|
|
20
11
|
def extract_m3u8_url(video_url: str) -> str:
|
|
21
12
|
"""Extract the m3u8 streaming URL from a RaiPlay video URL."""
|
|
@@ -29,7 +20,7 @@ class VideoSource:
|
|
|
29
20
|
return "Error: Unable to determine video JSON URL"
|
|
30
21
|
|
|
31
22
|
try:
|
|
32
|
-
response =
|
|
23
|
+
response = create_client(headers=get_headers()).get(video_url)
|
|
33
24
|
if response.status_code != 200:
|
|
34
25
|
return f"Error: Failed to fetch video data (Status: {response.status_code})"
|
|
35
26
|
|
|
@@ -50,8 +41,8 @@ class VideoSource:
|
|
|
50
41
|
'cont': element_key,
|
|
51
42
|
'output': '62',
|
|
52
43
|
}
|
|
53
|
-
|
|
54
|
-
|
|
44
|
+
|
|
45
|
+
stream_response = create_client(headers=get_headers()).get('https://mediapolisvod.rai.it/relinker/relinkerServlet.htm', params=params)
|
|
55
46
|
if stream_response.status_code != 200:
|
|
56
47
|
return f"Error: Failed to fetch stream URL (Status: {stream_response.status_code})"
|
|
57
48
|
|
|
@@ -7,19 +7,13 @@ import logging
|
|
|
7
7
|
# External libraries
|
|
8
8
|
import jsbeautifier
|
|
9
9
|
from bs4 import BeautifulSoup
|
|
10
|
-
from curl_cffi import requests
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
# Internal utilities
|
|
14
|
-
from StreamingCommunity.Util.
|
|
13
|
+
from StreamingCommunity.Util.http_client import create_client_curl
|
|
15
14
|
from StreamingCommunity.Util.headers import get_headers
|
|
16
15
|
|
|
17
16
|
|
|
18
|
-
# Variable
|
|
19
|
-
MAX_TIMEOUT = config_manager.get_int("REQUESTS", "timeout")
|
|
20
|
-
REQUEST_VERIFY = config_manager.get_bool('REQUESTS', 'verify')
|
|
21
|
-
|
|
22
|
-
|
|
23
17
|
class VideoSource:
|
|
24
18
|
def __init__(self, url: str) -> None:
|
|
25
19
|
"""
|
|
@@ -42,10 +36,11 @@ class VideoSource:
|
|
|
42
36
|
- str: The response content if successful, None otherwise.
|
|
43
37
|
"""
|
|
44
38
|
try:
|
|
45
|
-
response =
|
|
39
|
+
response = create_client_curl(headers=self.headers).get(url)
|
|
46
40
|
if response.status_code >= 400:
|
|
47
41
|
logging.error(f"Request failed with status code: {response.status_code}")
|
|
48
42
|
return None
|
|
43
|
+
|
|
49
44
|
return response.text
|
|
50
45
|
|
|
51
46
|
except Exception as e:
|
|
@@ -3,19 +3,11 @@
|
|
|
3
3
|
import logging
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
# External libraries
|
|
7
|
-
|
|
8
|
-
|
|
9
6
|
# Internal utilities
|
|
10
|
-
from StreamingCommunity.Util.config_json import config_manager
|
|
11
7
|
from StreamingCommunity.Util.headers import get_userAgent
|
|
12
8
|
from StreamingCommunity.Util.http_client import create_client
|
|
13
9
|
|
|
14
10
|
|
|
15
|
-
# Variable
|
|
16
|
-
MAX_TIMEOUT = config_manager.get_int("REQUESTS", "timeout")
|
|
17
|
-
REQUEST_VERIFY = config_manager.get_bool('REQUESTS', 'verify')
|
|
18
|
-
|
|
19
11
|
class VideoSource:
|
|
20
12
|
def __init__(self, site_url, episode_data, session_id, csrf_token):
|
|
21
13
|
"""Initialize the VideoSource with session details, episode data, and URL."""
|
|
@@ -44,4 +36,4 @@ class VideoSource:
|
|
|
44
36
|
|
|
45
37
|
except Exception as e:
|
|
46
38
|
logging.error(f"Error in new API system: {e}")
|
|
47
|
-
return None
|
|
39
|
+
return None
|
|
@@ -6,21 +6,18 @@ from urllib.parse import urlparse, parse_qs, urlencode, urlunparse
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
# External libraries
|
|
9
|
-
import httpx
|
|
10
9
|
from bs4 import BeautifulSoup
|
|
11
10
|
from rich.console import Console
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
# Internal utilities
|
|
15
14
|
from StreamingCommunity.Util.headers import get_userAgent
|
|
16
|
-
from StreamingCommunity.Util.
|
|
15
|
+
from StreamingCommunity.Util.http_client import create_client
|
|
17
16
|
from .Helper.Vixcloud.util import WindowVideo, WindowParameter, StreamsCollection
|
|
18
17
|
from .Helper.Vixcloud.js_parser import JavaScriptParser
|
|
19
18
|
|
|
20
19
|
|
|
21
20
|
# Variable
|
|
22
|
-
MAX_TIMEOUT = config_manager.get_int("REQUESTS", "timeout")
|
|
23
|
-
REQUEST_VERIFY = config_manager.get_bool('REQUESTS', 'verify')
|
|
24
21
|
console = Console()
|
|
25
22
|
|
|
26
23
|
|
|
@@ -57,7 +54,7 @@ class VideoSource:
|
|
|
57
54
|
}
|
|
58
55
|
|
|
59
56
|
try:
|
|
60
|
-
response =
|
|
57
|
+
response = create_client(headers=self.headers).get(f"{self.url}/iframe/{self.media_id}", params=params)
|
|
61
58
|
response.raise_for_status()
|
|
62
59
|
|
|
63
60
|
# Parse response with BeautifulSoup to get iframe source
|
|
@@ -100,7 +97,7 @@ class VideoSource:
|
|
|
100
97
|
"""
|
|
101
98
|
try:
|
|
102
99
|
if self.iframe_src is not None:
|
|
103
|
-
response =
|
|
100
|
+
response = create_client(headers=self.headers).get(self.iframe_src)
|
|
104
101
|
response.raise_for_status()
|
|
105
102
|
|
|
106
103
|
# Parse response with BeautifulSoup to get content
|
|
@@ -110,14 +107,6 @@ class VideoSource:
|
|
|
110
107
|
# Parse script to get video information
|
|
111
108
|
self.parse_script(script_text=script)
|
|
112
109
|
|
|
113
|
-
except httpx.HTTPStatusError as e:
|
|
114
|
-
if e.response.status_code == 404:
|
|
115
|
-
console.print("[yellow]This content will be available soon![/yellow]")
|
|
116
|
-
return
|
|
117
|
-
|
|
118
|
-
logging.error(f"Error getting content: {e}")
|
|
119
|
-
raise
|
|
120
|
-
|
|
121
110
|
except Exception as e:
|
|
122
111
|
logging.error(f"Error getting content: {e}")
|
|
123
112
|
raise
|
|
@@ -178,7 +167,7 @@ class VideoSourceAnime(VideoSource):
|
|
|
178
167
|
str: Parsed script content
|
|
179
168
|
"""
|
|
180
169
|
try:
|
|
181
|
-
response =
|
|
170
|
+
response = create_client(headers=self.headers).get(f"{self.url}/embed-url/{episode_id}")
|
|
182
171
|
response.raise_for_status()
|
|
183
172
|
|
|
184
173
|
# Extract and clean embed URL
|
|
@@ -186,7 +175,7 @@ class VideoSourceAnime(VideoSource):
|
|
|
186
175
|
self.iframe_src = embed_url
|
|
187
176
|
|
|
188
177
|
# Fetch video content using embed URL
|
|
189
|
-
video_response =
|
|
178
|
+
video_response = create_client(headers=self.headers).get(embed_url)
|
|
190
179
|
video_response.raise_for_status()
|
|
191
180
|
|
|
192
181
|
# Parse response with BeautifulSoup to get content of the scriot
|
|
@@ -15,7 +15,7 @@ from StreamingCommunity.Util.headers import get_headers
|
|
|
15
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
|
-
from StreamingCommunity.TelegramHelp.telegram_bot import
|
|
18
|
+
from StreamingCommunity.TelegramHelp.telegram_bot import TelegramSession
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
# Logic class
|
|
@@ -31,6 +31,7 @@ from StreamingCommunity.Api.Player.supervideo import VideoSource
|
|
|
31
31
|
# Variable
|
|
32
32
|
console = Console()
|
|
33
33
|
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
34
|
+
extension_output = config_manager.get("M3U8_CONVERSION", "extension")
|
|
34
35
|
|
|
35
36
|
|
|
36
37
|
def download_film(select_title: MediaItem) -> str:
|
|
@@ -43,18 +44,6 @@ def download_film(select_title: MediaItem) -> str:
|
|
|
43
44
|
Return:
|
|
44
45
|
- str: output path if successful, otherwise None
|
|
45
46
|
"""
|
|
46
|
-
if site_constant.TELEGRAM_BOT:
|
|
47
|
-
bot = get_bot_instance()
|
|
48
|
-
bot.send_message(f"Download in corso:\n{select_title.name}", None)
|
|
49
|
-
|
|
50
|
-
# Viene usato per lo screen
|
|
51
|
-
console.print(f"## Download: [red]{select_title.name} ##")
|
|
52
|
-
|
|
53
|
-
# Get script_id
|
|
54
|
-
script_id = TelegramSession.get_session()
|
|
55
|
-
if script_id != "unknown":
|
|
56
|
-
TelegramSession.updateScriptId(script_id, select_title.name)
|
|
57
|
-
|
|
58
47
|
start_message()
|
|
59
48
|
console.print(f"\n[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [cyan]{select_title.name}[/cyan] \n")
|
|
60
49
|
|
|
@@ -92,8 +81,8 @@ def download_film(select_title: MediaItem) -> str:
|
|
|
92
81
|
master_playlist = video_source.get_playlist()
|
|
93
82
|
|
|
94
83
|
# Define the filename and path for the downloaded film
|
|
95
|
-
title_name = os_manager.get_sanitize_file(select_title.name) +
|
|
96
|
-
mp4_path = os.path.join(site_constant.MOVIE_FOLDER, title_name.replace(
|
|
84
|
+
title_name = os_manager.get_sanitize_file(select_title.name, select_title.date) + extension_output
|
|
85
|
+
mp4_path = os.path.join(site_constant.MOVIE_FOLDER, title_name.replace(extension_output, ""))
|
|
97
86
|
|
|
98
87
|
# Download the film using the m3u8 playlist, and output filename
|
|
99
88
|
hls_process = HLS_Downloader(
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
# External libraries
|
|
5
|
-
import httpx
|
|
6
5
|
from bs4 import BeautifulSoup
|
|
7
6
|
from rich.console import Console
|
|
8
7
|
|
|
@@ -10,6 +9,7 @@ from rich.console import Console
|
|
|
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
|
from StreamingCommunity.Util.table import TVShowManager
|
|
14
14
|
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
|
|
15
15
|
|
|
@@ -46,12 +46,7 @@ def title_search(query: str) -> int:
|
|
|
46
46
|
console.print(f"[cyan]Search url: [yellow]{search_url}")
|
|
47
47
|
|
|
48
48
|
try:
|
|
49
|
-
response =
|
|
50
|
-
search_url,
|
|
51
|
-
headers={'user-agent': get_userAgent()},
|
|
52
|
-
timeout=max_timeout,
|
|
53
|
-
follow_redirects=True
|
|
54
|
-
)
|
|
49
|
+
response = create_client(headers={'user-agent': get_userAgent()}).get(search_url)
|
|
55
50
|
response.raise_for_status()
|
|
56
51
|
|
|
57
52
|
except Exception as e:
|
|
@@ -4,20 +4,15 @@ import logging
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
# External libraries
|
|
7
|
-
import httpx
|
|
8
7
|
from bs4 import BeautifulSoup
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
# Internal utilities
|
|
12
11
|
from StreamingCommunity.Util.headers import get_userAgent
|
|
13
|
-
from StreamingCommunity.Util.
|
|
12
|
+
from StreamingCommunity.Util.http_client import create_client
|
|
14
13
|
from StreamingCommunity.Api.Player.Helper.Vixcloud.util import SeasonManager
|
|
15
14
|
|
|
16
15
|
|
|
17
|
-
# Variable
|
|
18
|
-
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
19
|
-
|
|
20
|
-
|
|
21
16
|
class GetSerieInfo:
|
|
22
17
|
def __init__(self, url):
|
|
23
18
|
"""
|
|
@@ -34,7 +29,7 @@ class GetSerieInfo:
|
|
|
34
29
|
"""
|
|
35
30
|
Retrieve all episodes for all seasons
|
|
36
31
|
"""
|
|
37
|
-
response =
|
|
32
|
+
response = create_client(headers=self.headers).get(self.url)
|
|
38
33
|
soup = BeautifulSoup(response.text, "html.parser")
|
|
39
34
|
self.series_name = soup.find("title").get_text(strip=True).split(" - ")[0]
|
|
40
35
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# 10.12.23
|
|
2
2
|
|
|
3
|
-
# External libraries
|
|
4
3
|
import urllib.parse
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# External libraries
|
|
7
7
|
from rich.console import Console
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
# Internal utilities
|
|
11
|
-
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, create_client_curl
|
|
13
13
|
from StreamingCommunity.Util.table import TVShowManager
|
|
14
14
|
from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
|
|
15
15
|
|
|
@@ -18,21 +18,18 @@ from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
|
|
|
18
18
|
from StreamingCommunity.Api.Template.config_loader import site_constant
|
|
19
19
|
from StreamingCommunity.Api.Template.Class.SearchType import MediaManager
|
|
20
20
|
|
|
21
|
+
|
|
22
|
+
# Variable
|
|
21
23
|
console = Console()
|
|
22
24
|
media_search_manager = MediaManager()
|
|
23
25
|
table_show_manager = TVShowManager()
|
|
24
|
-
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
def get_token(user_agent: str) -> dict:
|
|
28
29
|
"""
|
|
29
30
|
Retrieve session cookies from the site.
|
|
30
31
|
"""
|
|
31
|
-
response =
|
|
32
|
-
site_constant.FULL_URL,
|
|
33
|
-
headers={'user-agent': user_agent},
|
|
34
|
-
impersonate="chrome120"
|
|
35
|
-
)
|
|
32
|
+
response = create_client_curl(headers={'user-agent': user_agent}).get(site_constant.FULL_URL)
|
|
36
33
|
response.raise_for_status()
|
|
37
34
|
all_cookies = {name: value for name, value in response.cookies.items()}
|
|
38
35
|
|
|
@@ -80,13 +77,7 @@ def title_search(query: str) -> int:
|
|
|
80
77
|
|
|
81
78
|
# First call: /livesearch
|
|
82
79
|
try:
|
|
83
|
-
response1 =
|
|
84
|
-
f'{site_constant.FULL_URL}/livesearch',
|
|
85
|
-
cookies=cookies,
|
|
86
|
-
headers=headers,
|
|
87
|
-
json={'title': query},
|
|
88
|
-
timeout=max_timeout
|
|
89
|
-
)
|
|
80
|
+
response1 = create_client(headers=headers).post(f'{site_constant.FULL_URL}/livesearch', cookies=cookies, json={'title': query})
|
|
90
81
|
response1.raise_for_status()
|
|
91
82
|
process_results(response1.json().get('records', []), seen_titles, media_search_manager, choices)
|
|
92
83
|
|
|
@@ -107,13 +98,7 @@ def title_search(query: str) -> int:
|
|
|
107
98
|
'dubbed': False,
|
|
108
99
|
'season': False
|
|
109
100
|
}
|
|
110
|
-
response2 =
|
|
111
|
-
f'{site_constant.FULL_URL}/archivio/get-animes',
|
|
112
|
-
cookies=cookies,
|
|
113
|
-
headers=headers,
|
|
114
|
-
json=json_data,
|
|
115
|
-
timeout=max_timeout
|
|
116
|
-
)
|
|
101
|
+
response2 = create_client(headers=headers).post(f'{site_constant.FULL_URL}/archivio/get-animes', cookies=cookies, json=json_data)
|
|
117
102
|
response2.raise_for_status()
|
|
118
103
|
process_results(response2.json().get('records', []), seen_titles, media_search_manager, choices)
|
|
119
104
|
|
|
@@ -3,21 +3,12 @@
|
|
|
3
3
|
import logging
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
# External libraries
|
|
7
|
-
import httpx
|
|
8
|
-
|
|
9
|
-
|
|
10
6
|
# Internal utilities
|
|
11
|
-
from StreamingCommunity.Util.headers import
|
|
12
|
-
from StreamingCommunity.Util.
|
|
7
|
+
from StreamingCommunity.Util.headers import get_headers
|
|
8
|
+
from StreamingCommunity.Util.http_client import create_client
|
|
13
9
|
from StreamingCommunity.Api.Player.Helper.Vixcloud.util import EpisodeManager, Episode
|
|
14
10
|
|
|
15
11
|
|
|
16
|
-
# Variable
|
|
17
|
-
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
12
|
class ScrapeSerieAnime:
|
|
22
13
|
def __init__(self, url: str):
|
|
23
14
|
"""
|
|
@@ -27,7 +18,7 @@ class ScrapeSerieAnime:
|
|
|
27
18
|
url (str): Url of the streaming site
|
|
28
19
|
"""
|
|
29
20
|
self.is_series = False
|
|
30
|
-
self.headers =
|
|
21
|
+
self.headers = get_headers()
|
|
31
22
|
self.url = url
|
|
32
23
|
self.episodes_cache = None
|
|
33
24
|
|
|
@@ -61,11 +52,7 @@ class ScrapeSerieAnime:
|
|
|
61
52
|
"""
|
|
62
53
|
try:
|
|
63
54
|
# Get initial episode count
|
|
64
|
-
response =
|
|
65
|
-
url=f"{self.url}/info_api/{self.media_id}/",
|
|
66
|
-
headers=self.headers,
|
|
67
|
-
timeout=max_timeout
|
|
68
|
-
)
|
|
55
|
+
response = create_client(headers=self.headers).get(f"{self.url}/info_api/{self.media_id}/")
|
|
69
56
|
response.raise_for_status()
|
|
70
57
|
initial_count = response.json()["episodes_count"]
|
|
71
58
|
|
|
@@ -75,18 +62,15 @@ class ScrapeSerieAnime:
|
|
|
75
62
|
# Fetch episodes in chunks
|
|
76
63
|
while start_range <= initial_count:
|
|
77
64
|
end_range = min(start_range + 119, initial_count)
|
|
65
|
+
|
|
66
|
+
params={
|
|
67
|
+
"start_range": start_range,
|
|
68
|
+
"end_range": end_range
|
|
69
|
+
}
|
|
78
70
|
|
|
79
|
-
response =
|
|
80
|
-
url=f"{self.url}/info_api/{self.media_id}/1",
|
|
81
|
-
params={
|
|
82
|
-
"start_range": start_range,
|
|
83
|
-
"end_range": end_range
|
|
84
|
-
},
|
|
85
|
-
headers=self.headers,
|
|
86
|
-
timeout=max_timeout
|
|
87
|
-
)
|
|
71
|
+
response = create_client(headers=self.headers).get(f"{self.url}/info_api/{self.media_id}/1", params=params)
|
|
88
72
|
response.raise_for_status()
|
|
89
|
-
|
|
73
|
+
|
|
90
74
|
chunk_episodes = response.json().get("episodes", [])
|
|
91
75
|
all_episodes.extend(chunk_episodes)
|
|
92
76
|
start_range = end_range + 1
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
# External library
|
|
6
7
|
from rich.console import Console
|
|
7
8
|
|
|
@@ -44,8 +45,9 @@ def download_film(select_title: MediaItem):
|
|
|
44
45
|
console.print(f"\n[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] ([cyan]{scrape_serie.get_name()}[/cyan]) \n")
|
|
45
46
|
|
|
46
47
|
# Define filename and path for the downloaded video
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
serie_name_with_year = os_manager.get_sanitize_file(scrape_serie.get_name(), select_title.date)
|
|
49
|
+
mp4_name = f"{serie_name_with_year}.mp4"
|
|
50
|
+
mp4_path = os.path.join(site_constant.ANIME_FOLDER, serie_name_with_year.replace('.mp4', ''))
|
|
49
51
|
|
|
50
52
|
# Create output folder
|
|
51
53
|
os_manager.create_path(mp4_path)
|
|
@@ -2,15 +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
|
from rich.console import Console
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
# Internal utilities
|
|
12
|
-
from StreamingCommunity.Util.
|
|
13
|
-
from StreamingCommunity.Util.headers import get_userAgent, get_headers
|
|
12
|
+
from StreamingCommunity.Util.headers import get_headers
|
|
14
13
|
from StreamingCommunity.Util.http_client import create_client
|
|
15
14
|
from StreamingCommunity.Util.table import TVShowManager
|
|
16
15
|
|
|
@@ -24,7 +23,6 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaManager
|
|
|
24
23
|
console = Console()
|
|
25
24
|
media_search_manager = MediaManager()
|
|
26
25
|
table_show_manager = TVShowManager()
|
|
27
|
-
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
28
26
|
|
|
29
27
|
|
|
30
28
|
def get_session_and_csrf() -> dict:
|
|
@@ -72,13 +70,7 @@ def title_search(query: str) -> int:
|
|
|
72
70
|
|
|
73
71
|
# Make the GET request
|
|
74
72
|
try:
|
|
75
|
-
response =
|
|
76
|
-
search_url,
|
|
77
|
-
headers={'User-Agent': get_userAgent()},
|
|
78
|
-
timeout=max_timeout,
|
|
79
|
-
verify=False
|
|
80
|
-
)
|
|
81
|
-
|
|
73
|
+
response = create_client(headers=get_headers()).get(search_url)
|
|
82
74
|
except Exception as e:
|
|
83
75
|
console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
|
|
84
76
|
return 0
|
|
@@ -10,7 +10,6 @@ from bs4 import BeautifulSoup
|
|
|
10
10
|
# Internal utilities
|
|
11
11
|
from StreamingCommunity.Util.headers import get_userAgent
|
|
12
12
|
from StreamingCommunity.Util.http_client import create_client
|
|
13
|
-
from StreamingCommunity.Util.config_json import config_manager
|
|
14
13
|
from StreamingCommunity.Util.os import os_manager
|
|
15
14
|
|
|
16
15
|
|
|
@@ -19,8 +18,6 @@ from ..site import get_session_and_csrf
|
|
|
19
18
|
from StreamingCommunity.Api.Player.sweetpixel import VideoSource
|
|
20
19
|
|
|
21
20
|
|
|
22
|
-
# Variable
|
|
23
|
-
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
|
24
21
|
|
|
25
22
|
|
|
26
23
|
class ScrapSerie:
|
|
@@ -34,7 +31,7 @@ class ScrapSerie:
|
|
|
34
31
|
)
|
|
35
32
|
|
|
36
33
|
try:
|
|
37
|
-
self.response = self.client.get(self.url
|
|
34
|
+
self.response = self.client.get(self.url)
|
|
38
35
|
self.response.raise_for_status()
|
|
39
36
|
|
|
40
37
|
except Exception as e:
|
|
@@ -11,7 +11,7 @@ from rich.console import Console
|
|
|
11
11
|
# Internal utilities
|
|
12
12
|
from StreamingCommunity.Util.message import start_message
|
|
13
13
|
from StreamingCommunity.Util.config_json import config_manager
|
|
14
|
-
from StreamingCommunity.Util.os import os_manager
|
|
14
|
+
from StreamingCommunity.Util.os import os_manager
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
# Logic class
|
|
@@ -21,12 +21,12 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
|
21
21
|
|
|
22
22
|
# Player
|
|
23
23
|
from StreamingCommunity import DASH_Downloader
|
|
24
|
-
from .util.get_license import get_playback_session,
|
|
24
|
+
from .util.get_license import get_playback_session, CrunchyrollClient
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
# Variable
|
|
28
28
|
console = Console()
|
|
29
|
-
|
|
29
|
+
extension_output = config_manager.get("M3U8_CONVERSION", "extension")
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
def download_film(select_title: MediaItem) -> str:
|
|
@@ -42,20 +42,24 @@ def download_film(select_title: MediaItem) -> str:
|
|
|
42
42
|
start_message()
|
|
43
43
|
console.print(f"\n[bold yellow]Download:[/bold yellow] [red]{site_constant.SITE_NAME}[/red] → [cyan]{select_title.name}[/cyan] \n")
|
|
44
44
|
|
|
45
|
+
# Initialize Crunchyroll client
|
|
46
|
+
client = CrunchyrollClient()
|
|
47
|
+
if not client.start():
|
|
48
|
+
console.print("[bold red]Failed to authenticate with Crunchyroll.[/bold red]")
|
|
49
|
+
return None, True
|
|
50
|
+
|
|
45
51
|
# Define filename and path for the downloaded video
|
|
46
|
-
mp4_name = os_manager.get_sanitize_file(select_title.name) +
|
|
47
|
-
mp4_path = os.path.join(site_constant.MOVIE_FOLDER, mp4_name.replace(
|
|
52
|
+
mp4_name = os_manager.get_sanitize_file(select_title.name, select_title.date) + extension_output
|
|
53
|
+
mp4_path = os.path.join(site_constant.MOVIE_FOLDER, mp4_name.replace(extension_output, ""))
|
|
48
54
|
|
|
49
55
|
# Generate mpd and license URLs
|
|
50
56
|
url_id = select_title.get('url').split('/')[-1]
|
|
51
|
-
|
|
52
|
-
mpd_url, mpd_headers, mpd_list_sub = get_playback_session(get_auth_token(device_id), device_id, url_id)
|
|
57
|
+
mpd_url, mpd_headers, mpd_list_sub = get_playback_session(client, url_id)
|
|
53
58
|
parsed_url = urlparse(mpd_url)
|
|
54
59
|
query_params = parse_qs(parsed_url.query)
|
|
55
60
|
|
|
56
61
|
# Download the episode
|
|
57
62
|
dash_process = DASH_Downloader(
|
|
58
|
-
cdm_device=get_wvd_path(),
|
|
59
63
|
license_url='https://www.crunchyroll.com/license/v1/license/widevine',
|
|
60
64
|
mpd_url=mpd_url,
|
|
61
65
|
mpd_sub_list=mpd_list_sub,
|
|
@@ -82,4 +86,9 @@ def download_film(select_title: MediaItem) -> str:
|
|
|
82
86
|
except Exception:
|
|
83
87
|
pass
|
|
84
88
|
|
|
89
|
+
# Delete stream after download
|
|
90
|
+
token = query_params['playbackGuid'][0]
|
|
91
|
+
if token:
|
|
92
|
+
client.delete_active_stream(url_id, token)
|
|
93
|
+
|
|
85
94
|
return status['path'], status['stopped']
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# 16.03.25
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
|
-
from typing import Tuple
|
|
5
4
|
from urllib.parse import urlparse, parse_qs
|
|
5
|
+
from typing import Tuple
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
# External library
|
|
@@ -12,11 +12,11 @@ from rich.prompt import Prompt
|
|
|
12
12
|
|
|
13
13
|
# Internal utilities
|
|
14
14
|
from StreamingCommunity.Util.message import start_message
|
|
15
|
-
from StreamingCommunity.Util.os import os_manager
|
|
15
|
+
from StreamingCommunity.Util.os import os_manager
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
# Logic class
|
|
19
|
-
from .util.ScrapeSerie import GetSerieInfo
|
|
19
|
+
from .util.ScrapeSerie import GetSerieInfo
|
|
20
20
|
from StreamingCommunity.Api.Template.Util import (
|
|
21
21
|
manage_selection,
|
|
22
22
|
map_episode_title,
|
|
@@ -30,7 +30,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
|
|
|
30
30
|
|
|
31
31
|
# Player
|
|
32
32
|
from StreamingCommunity import DASH_Downloader
|
|
33
|
-
from .util.get_license import get_playback_session
|
|
33
|
+
from .util.get_license import get_playback_session
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
# Variable
|
|
@@ -52,6 +52,7 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
|
|
|
52
52
|
- bool: Whether download was stopped
|
|
53
53
|
"""
|
|
54
54
|
start_message()
|
|
55
|
+
client = scrape_serie.client
|
|
55
56
|
|
|
56
57
|
# Get episode information
|
|
57
58
|
obj_episode = scrape_serie.selectEpisode(index_season_selected, index_episode_selected-1)
|
|
@@ -64,16 +65,13 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
|
|
|
64
65
|
|
|
65
66
|
# Generate mpd and license URLs
|
|
66
67
|
url_id = obj_episode.get('url').split('/')[-1]
|
|
67
|
-
device_id = generate_device_id()
|
|
68
|
-
token_mpd = get_auth_token(device_id)
|
|
69
68
|
|
|
70
|
-
mpd_url, mpd_headers, mpd_list_sub = get_playback_session(
|
|
69
|
+
mpd_url, mpd_headers, mpd_list_sub = get_playback_session(client, url_id)
|
|
71
70
|
parsed_url = urlparse(mpd_url)
|
|
72
71
|
query_params = parse_qs(parsed_url.query)
|
|
73
72
|
|
|
74
73
|
# Download the episode
|
|
75
74
|
dash_process = DASH_Downloader(
|
|
76
|
-
cdm_device=get_wvd_path(),
|
|
77
75
|
license_url='https://www.crunchyroll.com/license/v1/license/widevine',
|
|
78
76
|
mpd_url=mpd_url,
|
|
79
77
|
mpd_sub_list=mpd_list_sub,
|
|
@@ -101,7 +99,8 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
|
|
|
101
99
|
pass
|
|
102
100
|
|
|
103
101
|
# Delete episode stream
|
|
104
|
-
|
|
102
|
+
token = query_params['playbackGuid'][0]
|
|
103
|
+
client.delete_active_stream(url_id, token)
|
|
105
104
|
|
|
106
105
|
return status['path'], status['stopped']
|
|
107
106
|
|