StreamingCommunity 1.7.6__py3-none-any.whl → 1.8.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/Src/Api/Player/Helper/Vixcloud/js_parser.py +4 -1
- StreamingCommunity/Src/Api/Player/Helper/Vixcloud/util.py +166 -166
- StreamingCommunity/Src/Api/Player/ddl.py +89 -89
- StreamingCommunity/Src/Api/Player/maxstream.py +151 -151
- StreamingCommunity/Src/Api/Player/supervideo.py +193 -193
- StreamingCommunity/Src/Api/Player/vixcloud.py +224 -212
- StreamingCommunity/Src/Api/Site/1337xx/__init__.py +50 -50
- StreamingCommunity/Src/Api/Site/1337xx/costant.py +14 -14
- StreamingCommunity/Src/Api/Site/1337xx/site.py +83 -83
- StreamingCommunity/Src/Api/Site/1337xx/title.py +66 -66
- StreamingCommunity/Src/Api/Site/altadefinizione/__init__.py +50 -50
- StreamingCommunity/Src/Api/Site/altadefinizione/costant.py +14 -14
- StreamingCommunity/Src/Api/Site/altadefinizione/film.py +69 -69
- StreamingCommunity/Src/Api/Site/altadefinizione/site.py +86 -86
- StreamingCommunity/Src/Api/Site/animeunity/__init__.py +50 -50
- StreamingCommunity/Src/Api/Site/animeunity/costant.py +15 -15
- StreamingCommunity/Src/Api/Site/animeunity/film_serie.py +131 -131
- StreamingCommunity/Src/Api/Site/animeunity/site.py +164 -164
- StreamingCommunity/Src/Api/Site/bitsearch/__init__.py +51 -51
- StreamingCommunity/Src/Api/Site/bitsearch/costant.py +15 -15
- StreamingCommunity/Src/Api/Site/bitsearch/site.py +84 -84
- StreamingCommunity/Src/Api/Site/bitsearch/title.py +47 -47
- StreamingCommunity/Src/Api/Site/cb01new/__init__.py +51 -51
- StreamingCommunity/Src/Api/Site/cb01new/costant.py +15 -15
- StreamingCommunity/Src/Api/Site/cb01new/film.py +69 -69
- StreamingCommunity/Src/Api/Site/cb01new/site.py +74 -74
- StreamingCommunity/Src/Api/Site/ddlstreamitaly/__init__.py +57 -57
- StreamingCommunity/Src/Api/Site/ddlstreamitaly/costant.py +16 -16
- StreamingCommunity/Src/Api/Site/ddlstreamitaly/series.py +142 -142
- StreamingCommunity/Src/Api/Site/ddlstreamitaly/site.py +92 -92
- StreamingCommunity/Src/Api/Site/ddlstreamitaly/util/ScrapeSerie.py +82 -82
- StreamingCommunity/Src/Api/Site/guardaserie/__init__.py +52 -52
- StreamingCommunity/Src/Api/Site/guardaserie/costant.py +15 -15
- StreamingCommunity/Src/Api/Site/guardaserie/series.py +195 -195
- StreamingCommunity/Src/Api/Site/guardaserie/site.py +84 -84
- StreamingCommunity/Src/Api/Site/guardaserie/util/ScrapeSerie.py +110 -110
- StreamingCommunity/Src/Api/Site/mostraguarda/__init__.py +48 -48
- StreamingCommunity/Src/Api/Site/mostraguarda/costant.py +14 -14
- StreamingCommunity/Src/Api/Site/mostraguarda/film.py +94 -94
- StreamingCommunity/Src/Api/Site/piratebays/__init__.py +50 -50
- StreamingCommunity/Src/Api/Site/piratebays/costant.py +14 -14
- StreamingCommunity/Src/Api/Site/piratebays/site.py +88 -88
- StreamingCommunity/Src/Api/Site/piratebays/title.py +45 -45
- StreamingCommunity/Src/Api/Site/streamingcommunity/__init__.py +55 -55
- StreamingCommunity/Src/Api/Site/streamingcommunity/costant.py +14 -14
- StreamingCommunity/Src/Api/Site/streamingcommunity/film.py +70 -70
- StreamingCommunity/Src/Api/Site/streamingcommunity/series.py +203 -203
- StreamingCommunity/Src/Api/Site/streamingcommunity/site.py +125 -125
- StreamingCommunity/Src/Api/Template/Class/SearchType.py +101 -101
- StreamingCommunity/Src/Api/Template/Util/__init__.py +4 -4
- StreamingCommunity/Src/Api/Template/Util/get_domain.py +137 -137
- StreamingCommunity/Src/Api/Template/Util/manage_ep.py +153 -153
- StreamingCommunity/Src/Api/Template/Util/recall_search.py +37 -37
- StreamingCommunity/Src/Api/Template/__init__.py +2 -2
- StreamingCommunity/Src/Api/Template/site.py +87 -87
- StreamingCommunity/Src/Lib/Downloader/HLS/downloader.py +968 -968
- StreamingCommunity/Src/Lib/Downloader/HLS/proxyes.py +110 -110
- StreamingCommunity/Src/Lib/Downloader/HLS/segments.py +540 -540
- StreamingCommunity/Src/Lib/Downloader/MP4/downloader.py +156 -156
- StreamingCommunity/Src/Lib/Downloader/TOR/downloader.py +222 -222
- StreamingCommunity/Src/Lib/Downloader/__init__.py +4 -4
- StreamingCommunity/Src/Lib/Driver/driver_1.py +76 -76
- StreamingCommunity/Src/Lib/FFmpeg/__init__.py +4 -4
- StreamingCommunity/Src/Lib/FFmpeg/capture.py +170 -170
- StreamingCommunity/Src/Lib/FFmpeg/command.py +292 -292
- StreamingCommunity/Src/Lib/FFmpeg/util.py +241 -241
- StreamingCommunity/Src/Lib/M3U8/__init__.py +5 -5
- StreamingCommunity/Src/Lib/M3U8/decryptor.py +128 -128
- StreamingCommunity/Src/Lib/M3U8/estimator.py +172 -172
- StreamingCommunity/Src/Lib/M3U8/parser.py +666 -666
- StreamingCommunity/Src/Lib/M3U8/url_fixer.py +51 -51
- StreamingCommunity/Src/Lib/TMBD/__init__.py +1 -1
- StreamingCommunity/Src/Lib/TMBD/obj_tmbd.py +39 -39
- StreamingCommunity/Src/Lib/TMBD/tmdb.py +345 -345
- StreamingCommunity/Src/Upload/update.py +64 -64
- StreamingCommunity/Src/Upload/version.py +5 -5
- StreamingCommunity/Src/Util/_jsonConfig.py +204 -204
- StreamingCommunity/Src/Util/call_stack.py +42 -42
- StreamingCommunity/Src/Util/color.py +20 -20
- StreamingCommunity/Src/Util/console.py +12 -12
- StreamingCommunity/Src/Util/headers.py +147 -147
- StreamingCommunity/Src/Util/logger.py +53 -53
- StreamingCommunity/Src/Util/message.py +46 -46
- StreamingCommunity/Src/Util/os.py +417 -417
- StreamingCommunity/Src/Util/table.py +163 -163
- StreamingCommunity/run.py +196 -196
- {StreamingCommunity-1.7.6.dist-info → StreamingCommunity-1.8.0.dist-info}/METADATA +1 -1
- StreamingCommunity-1.8.0.dist-info/RECORD +97 -0
- StreamingCommunity-1.7.6.dist-info/RECORD +0 -97
- {StreamingCommunity-1.7.6.dist-info → StreamingCommunity-1.8.0.dist-info}/LICENSE +0 -0
- {StreamingCommunity-1.7.6.dist-info → StreamingCommunity-1.8.0.dist-info}/WHEEL +0 -0
- {StreamingCommunity-1.7.6.dist-info → StreamingCommunity-1.8.0.dist-info}/entry_points.txt +0 -0
- {StreamingCommunity-1.7.6.dist-info → StreamingCommunity-1.8.0.dist-info}/top_level.txt +0 -0
|
@@ -1,156 +1,156 @@
|
|
|
1
|
-
# 09.06.24
|
|
2
|
-
|
|
3
|
-
import os
|
|
4
|
-
import sys
|
|
5
|
-
import ssl
|
|
6
|
-
import certifi
|
|
7
|
-
import logging
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# External libraries
|
|
11
|
-
import httpx
|
|
12
|
-
from tqdm import tqdm
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
# Internal utilities
|
|
16
|
-
from StreamingCommunity.Src.Util.headers import get_headers
|
|
17
|
-
from StreamingCommunity.Src.Util.color import Colors
|
|
18
|
-
from StreamingCommunity.Src.Util.console import console, Panel
|
|
19
|
-
from StreamingCommunity.Src.Util._jsonConfig import config_manager
|
|
20
|
-
from StreamingCommunity.Src.Util.os import internet_manager
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# Logic class
|
|
24
|
-
from ...FFmpeg import print_duration_table
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
# Suppress SSL warnings
|
|
28
|
-
import urllib3
|
|
29
|
-
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
# Config
|
|
33
|
-
GET_ONLY_LINK = config_manager.get_bool('M3U8_PARSER', 'get_only_link')
|
|
34
|
-
TQDM_USE_LARGE_BAR = config_manager.get_int('M3U8_DOWNLOAD', 'tqdm_use_large_bar')
|
|
35
|
-
REQUEST_VERIFY = config_manager.get_float('REQUESTS', 'verify_ssl')
|
|
36
|
-
REQUEST_TIMEOUT = config_manager.get_float('REQUESTS', 'timeout')
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
def MP4_downloader(url: str, path: str, referer: str = None, headers_: dict = None):
|
|
41
|
-
"""
|
|
42
|
-
Downloads an MP4 video from a given URL with robust error handling and SSL bypass.
|
|
43
|
-
|
|
44
|
-
Parameters:
|
|
45
|
-
- url (str): The URL of the MP4 video to download.
|
|
46
|
-
- path (str): The local path where the downloaded MP4 file will be saved.
|
|
47
|
-
- referer (str, optional): The referer header value.
|
|
48
|
-
- headers_ (dict, optional): Custom headers for the request.
|
|
49
|
-
"""
|
|
50
|
-
# Early return for link-only mode
|
|
51
|
-
if GET_ONLY_LINK:
|
|
52
|
-
return {'path': path, 'url': url}
|
|
53
|
-
|
|
54
|
-
# Validate URL
|
|
55
|
-
if not (url.lower().startswith('http://') or url.lower().startswith('https://')):
|
|
56
|
-
logging.error(f"Invalid URL: {url}")
|
|
57
|
-
console.print(f"[bold red]Invalid URL: {url}[/bold red]")
|
|
58
|
-
return None
|
|
59
|
-
|
|
60
|
-
# Prepare headers
|
|
61
|
-
try:
|
|
62
|
-
headers = {}
|
|
63
|
-
if referer:
|
|
64
|
-
headers['Referer'] = referer
|
|
65
|
-
|
|
66
|
-
# Use custom headers if provided, otherwise use default user agent
|
|
67
|
-
if headers_:
|
|
68
|
-
headers.update(headers_)
|
|
69
|
-
else:
|
|
70
|
-
headers['User-Agent'] = get_headers()
|
|
71
|
-
|
|
72
|
-
except Exception as header_err:
|
|
73
|
-
logging.error(f"Error preparing headers: {header_err}")
|
|
74
|
-
console.print(f"[bold red]Error preparing headers: {header_err}[/bold red]")
|
|
75
|
-
return None
|
|
76
|
-
|
|
77
|
-
try:
|
|
78
|
-
# Create a custom transport that bypasses SSL verification
|
|
79
|
-
transport = httpx.HTTPTransport(
|
|
80
|
-
verify=False, # Disable SSL certificate verification
|
|
81
|
-
http2=True # Optional: enable HTTP/2 support
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
# Download with streaming and progress tracking
|
|
85
|
-
with httpx.Client(transport=transport, timeout=httpx.Timeout(60.0)) as client:
|
|
86
|
-
with client.stream("GET", url, headers=headers, timeout=REQUEST_TIMEOUT) as response:
|
|
87
|
-
response.raise_for_status()
|
|
88
|
-
|
|
89
|
-
# Get total file size
|
|
90
|
-
total = int(response.headers.get('content-length', 0))
|
|
91
|
-
|
|
92
|
-
# Handle empty streams
|
|
93
|
-
if total == 0:
|
|
94
|
-
console.print("[bold red]No video stream found.[/bold red]")
|
|
95
|
-
return None
|
|
96
|
-
|
|
97
|
-
# Create progress bar
|
|
98
|
-
progress_bar = tqdm(
|
|
99
|
-
total=total,
|
|
100
|
-
ascii='░▒█',
|
|
101
|
-
bar_format=f"{Colors.YELLOW}[MP4] {Colors.WHITE}({Colors.CYAN}video{Colors.WHITE}): "
|
|
102
|
-
f"{Colors.RED}{{percentage:.2f}}% {Colors.MAGENTA}{{bar}} {Colors.WHITE}[ "
|
|
103
|
-
f"{Colors.YELLOW}{{n_fmt}}{Colors.WHITE} / {Colors.RED}{{total_fmt}} {Colors.WHITE}] "
|
|
104
|
-
f"{Colors.YELLOW}{{elapsed}} {Colors.WHITE}< {Colors.CYAN}{{remaining}} {Colors.WHITE}| "
|
|
105
|
-
f"{Colors.YELLOW}{{rate_fmt}}{{postfix}} {Colors.WHITE}]",
|
|
106
|
-
unit='iB',
|
|
107
|
-
unit_scale=True,
|
|
108
|
-
desc='Downloading',
|
|
109
|
-
mininterval=0.05
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
# Ensure directory exists
|
|
113
|
-
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
114
|
-
|
|
115
|
-
# Download file
|
|
116
|
-
with open(path, 'wb') as file, progress_bar as bar:
|
|
117
|
-
downloaded = 0
|
|
118
|
-
for chunk in response.iter_bytes(chunk_size=1024):
|
|
119
|
-
if chunk:
|
|
120
|
-
size = file.write(chunk)
|
|
121
|
-
downloaded += size
|
|
122
|
-
bar.update(size)
|
|
123
|
-
|
|
124
|
-
# Optional: Add a check to stop download if needed
|
|
125
|
-
# if downloaded > MAX_DOWNLOAD_SIZE:
|
|
126
|
-
# break
|
|
127
|
-
|
|
128
|
-
# Post-download processing
|
|
129
|
-
if os.path.exists(path) and os.path.getsize(path) > 0:
|
|
130
|
-
console.print(Panel(
|
|
131
|
-
f"[bold green]Download completed![/bold green]\n"
|
|
132
|
-
f"[cyan]File size: [bold red]{internet_manager.format_file_size(os.path.getsize(path))}[/bold red]\n"
|
|
133
|
-
f"[cyan]Duration: [bold]{print_duration_table(path, description=False, return_string=True)}[/bold]",
|
|
134
|
-
title=f"{os.path.basename(path.replace('.mp4', ''))}",
|
|
135
|
-
border_style="green"
|
|
136
|
-
))
|
|
137
|
-
return path
|
|
138
|
-
|
|
139
|
-
else:
|
|
140
|
-
console.print("[bold red]Download failed or file is empty.[/bold red]")
|
|
141
|
-
return None
|
|
142
|
-
|
|
143
|
-
except httpx.HTTPStatusError as http_err:
|
|
144
|
-
logging.error(f"HTTP error occurred: {http_err}")
|
|
145
|
-
console.print(f"[bold red]HTTP Error: {http_err}[/bold red]")
|
|
146
|
-
return None
|
|
147
|
-
|
|
148
|
-
except httpx.RequestError as req_err:
|
|
149
|
-
logging.error(f"Request error: {req_err}")
|
|
150
|
-
console.print(f"[bold red]Request Error: {req_err}[/bold red]")
|
|
151
|
-
return None
|
|
152
|
-
|
|
153
|
-
except Exception as e:
|
|
154
|
-
logging.error(f"Unexpected error during download: {e}")
|
|
155
|
-
console.print(f"[bold red]Unexpected Error: {e}[/bold red]")
|
|
156
|
-
return None
|
|
1
|
+
# 09.06.24
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
import ssl
|
|
6
|
+
import certifi
|
|
7
|
+
import logging
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# External libraries
|
|
11
|
+
import httpx
|
|
12
|
+
from tqdm import tqdm
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# Internal utilities
|
|
16
|
+
from StreamingCommunity.Src.Util.headers import get_headers
|
|
17
|
+
from StreamingCommunity.Src.Util.color import Colors
|
|
18
|
+
from StreamingCommunity.Src.Util.console import console, Panel
|
|
19
|
+
from StreamingCommunity.Src.Util._jsonConfig import config_manager
|
|
20
|
+
from StreamingCommunity.Src.Util.os import internet_manager
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# Logic class
|
|
24
|
+
from ...FFmpeg import print_duration_table
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# Suppress SSL warnings
|
|
28
|
+
import urllib3
|
|
29
|
+
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# Config
|
|
33
|
+
GET_ONLY_LINK = config_manager.get_bool('M3U8_PARSER', 'get_only_link')
|
|
34
|
+
TQDM_USE_LARGE_BAR = config_manager.get_int('M3U8_DOWNLOAD', 'tqdm_use_large_bar')
|
|
35
|
+
REQUEST_VERIFY = config_manager.get_float('REQUESTS', 'verify_ssl')
|
|
36
|
+
REQUEST_TIMEOUT = config_manager.get_float('REQUESTS', 'timeout')
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def MP4_downloader(url: str, path: str, referer: str = None, headers_: dict = None):
|
|
41
|
+
"""
|
|
42
|
+
Downloads an MP4 video from a given URL with robust error handling and SSL bypass.
|
|
43
|
+
|
|
44
|
+
Parameters:
|
|
45
|
+
- url (str): The URL of the MP4 video to download.
|
|
46
|
+
- path (str): The local path where the downloaded MP4 file will be saved.
|
|
47
|
+
- referer (str, optional): The referer header value.
|
|
48
|
+
- headers_ (dict, optional): Custom headers for the request.
|
|
49
|
+
"""
|
|
50
|
+
# Early return for link-only mode
|
|
51
|
+
if GET_ONLY_LINK:
|
|
52
|
+
return {'path': path, 'url': url}
|
|
53
|
+
|
|
54
|
+
# Validate URL
|
|
55
|
+
if not (url.lower().startswith('http://') or url.lower().startswith('https://')):
|
|
56
|
+
logging.error(f"Invalid URL: {url}")
|
|
57
|
+
console.print(f"[bold red]Invalid URL: {url}[/bold red]")
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
# Prepare headers
|
|
61
|
+
try:
|
|
62
|
+
headers = {}
|
|
63
|
+
if referer:
|
|
64
|
+
headers['Referer'] = referer
|
|
65
|
+
|
|
66
|
+
# Use custom headers if provided, otherwise use default user agent
|
|
67
|
+
if headers_:
|
|
68
|
+
headers.update(headers_)
|
|
69
|
+
else:
|
|
70
|
+
headers['User-Agent'] = get_headers()
|
|
71
|
+
|
|
72
|
+
except Exception as header_err:
|
|
73
|
+
logging.error(f"Error preparing headers: {header_err}")
|
|
74
|
+
console.print(f"[bold red]Error preparing headers: {header_err}[/bold red]")
|
|
75
|
+
return None
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
# Create a custom transport that bypasses SSL verification
|
|
79
|
+
transport = httpx.HTTPTransport(
|
|
80
|
+
verify=False, # Disable SSL certificate verification
|
|
81
|
+
http2=True # Optional: enable HTTP/2 support
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Download with streaming and progress tracking
|
|
85
|
+
with httpx.Client(transport=transport, timeout=httpx.Timeout(60.0)) as client:
|
|
86
|
+
with client.stream("GET", url, headers=headers, timeout=REQUEST_TIMEOUT) as response:
|
|
87
|
+
response.raise_for_status()
|
|
88
|
+
|
|
89
|
+
# Get total file size
|
|
90
|
+
total = int(response.headers.get('content-length', 0))
|
|
91
|
+
|
|
92
|
+
# Handle empty streams
|
|
93
|
+
if total == 0:
|
|
94
|
+
console.print("[bold red]No video stream found.[/bold red]")
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
# Create progress bar
|
|
98
|
+
progress_bar = tqdm(
|
|
99
|
+
total=total,
|
|
100
|
+
ascii='░▒█',
|
|
101
|
+
bar_format=f"{Colors.YELLOW}[MP4] {Colors.WHITE}({Colors.CYAN}video{Colors.WHITE}): "
|
|
102
|
+
f"{Colors.RED}{{percentage:.2f}}% {Colors.MAGENTA}{{bar}} {Colors.WHITE}[ "
|
|
103
|
+
f"{Colors.YELLOW}{{n_fmt}}{Colors.WHITE} / {Colors.RED}{{total_fmt}} {Colors.WHITE}] "
|
|
104
|
+
f"{Colors.YELLOW}{{elapsed}} {Colors.WHITE}< {Colors.CYAN}{{remaining}} {Colors.WHITE}| "
|
|
105
|
+
f"{Colors.YELLOW}{{rate_fmt}}{{postfix}} {Colors.WHITE}]",
|
|
106
|
+
unit='iB',
|
|
107
|
+
unit_scale=True,
|
|
108
|
+
desc='Downloading',
|
|
109
|
+
mininterval=0.05
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# Ensure directory exists
|
|
113
|
+
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
114
|
+
|
|
115
|
+
# Download file
|
|
116
|
+
with open(path, 'wb') as file, progress_bar as bar:
|
|
117
|
+
downloaded = 0
|
|
118
|
+
for chunk in response.iter_bytes(chunk_size=1024):
|
|
119
|
+
if chunk:
|
|
120
|
+
size = file.write(chunk)
|
|
121
|
+
downloaded += size
|
|
122
|
+
bar.update(size)
|
|
123
|
+
|
|
124
|
+
# Optional: Add a check to stop download if needed
|
|
125
|
+
# if downloaded > MAX_DOWNLOAD_SIZE:
|
|
126
|
+
# break
|
|
127
|
+
|
|
128
|
+
# Post-download processing
|
|
129
|
+
if os.path.exists(path) and os.path.getsize(path) > 0:
|
|
130
|
+
console.print(Panel(
|
|
131
|
+
f"[bold green]Download completed![/bold green]\n"
|
|
132
|
+
f"[cyan]File size: [bold red]{internet_manager.format_file_size(os.path.getsize(path))}[/bold red]\n"
|
|
133
|
+
f"[cyan]Duration: [bold]{print_duration_table(path, description=False, return_string=True)}[/bold]",
|
|
134
|
+
title=f"{os.path.basename(path.replace('.mp4', ''))}",
|
|
135
|
+
border_style="green"
|
|
136
|
+
))
|
|
137
|
+
return path
|
|
138
|
+
|
|
139
|
+
else:
|
|
140
|
+
console.print("[bold red]Download failed or file is empty.[/bold red]")
|
|
141
|
+
return None
|
|
142
|
+
|
|
143
|
+
except httpx.HTTPStatusError as http_err:
|
|
144
|
+
logging.error(f"HTTP error occurred: {http_err}")
|
|
145
|
+
console.print(f"[bold red]HTTP Error: {http_err}[/bold red]")
|
|
146
|
+
return None
|
|
147
|
+
|
|
148
|
+
except httpx.RequestError as req_err:
|
|
149
|
+
logging.error(f"Request error: {req_err}")
|
|
150
|
+
console.print(f"[bold red]Request Error: {req_err}[/bold red]")
|
|
151
|
+
return None
|
|
152
|
+
|
|
153
|
+
except Exception as e:
|
|
154
|
+
logging.error(f"Unexpected error during download: {e}")
|
|
155
|
+
console.print(f"[bold red]Unexpected Error: {e}[/bold red]")
|
|
156
|
+
return None
|