StreamingCommunity 2.5.6__py3-none-any.whl → 2.5.8__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/ddl.py +2 -3
- StreamingCommunity/Api/Site/1337xx/__init__.py +5 -6
- StreamingCommunity/Api/Site/1337xx/site.py +7 -14
- StreamingCommunity/Api/Site/1337xx/title.py +3 -5
- StreamingCommunity/Api/Site/altadefinizionegratis/__init__.py +7 -6
- StreamingCommunity/Api/Site/altadefinizionegratis/film.py +14 -19
- StreamingCommunity/Api/Site/altadefinizionegratis/site.py +6 -14
- StreamingCommunity/Api/Site/animeunity/__init__.py +7 -7
- StreamingCommunity/Api/Site/animeunity/film_serie.py +29 -31
- StreamingCommunity/Api/Site/animeunity/site.py +14 -22
- StreamingCommunity/Api/Site/cb01new/__init__.py +5 -4
- StreamingCommunity/Api/Site/cb01new/film.py +2 -5
- StreamingCommunity/Api/Site/cb01new/site.py +5 -13
- StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py +5 -4
- StreamingCommunity/Api/Site/ddlstreamitaly/series.py +12 -49
- StreamingCommunity/Api/Site/ddlstreamitaly/site.py +6 -16
- StreamingCommunity/Api/Site/ddlstreamitaly/util/ScrapeSerie.py +2 -3
- StreamingCommunity/Api/Site/guardaserie/__init__.py +5 -4
- StreamingCommunity/Api/Site/guardaserie/series.py +12 -46
- StreamingCommunity/Api/Site/guardaserie/site.py +5 -13
- StreamingCommunity/Api/Site/guardaserie/util/ScrapeSerie.py +10 -14
- StreamingCommunity/Api/Site/ilcorsaronero/__init__.py +5 -4
- StreamingCommunity/Api/Site/ilcorsaronero/site.py +5 -13
- StreamingCommunity/Api/Site/ilcorsaronero/title.py +3 -5
- StreamingCommunity/Api/Site/mostraguarda/__init__.py +2 -2
- StreamingCommunity/Api/Site/mostraguarda/film.py +4 -8
- StreamingCommunity/Api/Site/streamingcommunity/__init__.py +8 -7
- StreamingCommunity/Api/Site/streamingcommunity/film.py +14 -18
- StreamingCommunity/Api/Site/streamingcommunity/series.py +25 -76
- StreamingCommunity/Api/Site/streamingcommunity/site.py +11 -23
- StreamingCommunity/Api/Template/Util/__init__.py +8 -1
- StreamingCommunity/Api/Template/Util/manage_ep.py +46 -2
- StreamingCommunity/Api/Template/config_loader.py +71 -0
- StreamingCommunity/Lib/Downloader/HLS/downloader.py +60 -60
- StreamingCommunity/Lib/Downloader/HLS/segments.py +40 -15
- StreamingCommunity/Lib/Downloader/MP4/downloader.py +47 -40
- StreamingCommunity/Lib/FFmpeg/command.py +59 -3
- StreamingCommunity/Lib/M3U8/estimator.py +10 -12
- StreamingCommunity/Lib/M3U8/parser.py +12 -51
- StreamingCommunity/Lib/TMBD/tmdb.py +66 -99
- StreamingCommunity/TelegramHelp/telegram_bot.py +222 -68
- StreamingCommunity/Util/_jsonConfig.py +14 -13
- StreamingCommunity/Util/ffmpeg_installer.py +70 -64
- StreamingCommunity/Util/headers.py +11 -122
- StreamingCommunity/Util/os.py +65 -56
- StreamingCommunity/Util/table.py +62 -108
- StreamingCommunity/run.py +16 -11
- {StreamingCommunity-2.5.6.dist-info → StreamingCommunity-2.5.8.dist-info}/METADATA +57 -23
- StreamingCommunity-2.5.8.dist-info/RECORD +86 -0
- StreamingCommunity/Api/Site/1337xx/costant.py +0 -15
- StreamingCommunity/Api/Site/altadefinizionegratis/costant.py +0 -21
- StreamingCommunity/Api/Site/animeunity/costant.py +0 -21
- StreamingCommunity/Api/Site/cb01new/costant.py +0 -19
- StreamingCommunity/Api/Site/ddlstreamitaly/costant.py +0 -20
- StreamingCommunity/Api/Site/guardaserie/costant.py +0 -19
- StreamingCommunity/Api/Site/ilcorsaronero/costant.py +0 -19
- StreamingCommunity/Api/Site/mostraguarda/costant.py +0 -19
- StreamingCommunity/Api/Site/streamingcommunity/costant.py +0 -21
- StreamingCommunity/TelegramHelp/request_manager.py +0 -82
- StreamingCommunity/TelegramHelp/session.py +0 -56
- StreamingCommunity-2.5.6.dist-info/RECORD +0 -96
- {StreamingCommunity-2.5.6.dist-info → StreamingCommunity-2.5.8.dist-info}/LICENSE +0 -0
- {StreamingCommunity-2.5.6.dist-info → StreamingCommunity-2.5.8.dist-info}/WHEEL +0 -0
- {StreamingCommunity-2.5.6.dist-info → StreamingCommunity-2.5.8.dist-info}/entry_points.txt +0 -0
- {StreamingCommunity-2.5.6.dist-info → StreamingCommunity-2.5.8.dist-info}/top_level.txt +0 -0
|
@@ -4,17 +4,18 @@ import os
|
|
|
4
4
|
import sys
|
|
5
5
|
import json
|
|
6
6
|
import logging
|
|
7
|
+
from pathlib import Path
|
|
7
8
|
from typing import Any, List
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
class ConfigManager:
|
|
11
|
-
def __init__(self,
|
|
12
|
+
def __init__(self, file_name: str = 'config.json') -> None:
|
|
12
13
|
"""Initialize the ConfigManager.
|
|
13
14
|
|
|
14
15
|
Parameters:
|
|
15
16
|
- file_path (str, optional): The path to the configuration file. Default is 'config.json'.
|
|
16
17
|
"""
|
|
17
|
-
self.file_path =
|
|
18
|
+
self.file_path = Path(__file__).parent.parent.parent / file_name
|
|
18
19
|
self.config = {}
|
|
19
20
|
self.cache = {}
|
|
20
21
|
|
|
@@ -50,17 +51,17 @@ class ConfigManager:
|
|
|
50
51
|
def download_requirements(self, url: str, filename: str):
|
|
51
52
|
"""
|
|
52
53
|
Download the requirements.txt file from the specified URL if not found locally using requests.
|
|
53
|
-
|
|
54
|
+
|
|
54
55
|
Args:
|
|
55
56
|
url (str): The URL to download the requirements file from.
|
|
56
57
|
filename (str): The local filename to save the requirements file as.
|
|
57
58
|
"""
|
|
58
59
|
try:
|
|
59
60
|
import requests
|
|
60
|
-
|
|
61
|
+
|
|
61
62
|
logging.info(f"{filename} not found locally. Downloading from {url}...")
|
|
62
63
|
response = requests.get(url)
|
|
63
|
-
|
|
64
|
+
|
|
64
65
|
if response.status_code == 200:
|
|
65
66
|
with open(filename, 'wb') as f:
|
|
66
67
|
f.write(response.content)
|
|
@@ -68,7 +69,7 @@ class ConfigManager:
|
|
|
68
69
|
else:
|
|
69
70
|
logging.error(f"Failed to download {filename}. HTTP Status code: {response.status_code}")
|
|
70
71
|
sys.exit(0)
|
|
71
|
-
|
|
72
|
+
|
|
72
73
|
except Exception as e:
|
|
73
74
|
logging.error(f"Failed to download {filename}: {e}")
|
|
74
75
|
sys.exit(0)
|
|
@@ -89,15 +90,15 @@ class ConfigManager:
|
|
|
89
90
|
|
|
90
91
|
if cache_key in self.cache:
|
|
91
92
|
return self.cache[cache_key]
|
|
92
|
-
|
|
93
|
+
|
|
93
94
|
if section in self.config and key in self.config[section]:
|
|
94
95
|
value = self.config[section][key]
|
|
95
96
|
else:
|
|
96
97
|
raise ValueError(f"Key '{key}' not found in section '{section}'")
|
|
97
|
-
|
|
98
|
+
|
|
98
99
|
value = self._convert_to_data_type(value, data_type)
|
|
99
100
|
self.cache[cache_key] = value
|
|
100
|
-
|
|
101
|
+
|
|
101
102
|
return value
|
|
102
103
|
|
|
103
104
|
def _convert_to_data_type(self, value: str, data_type: type) -> Any:
|
|
@@ -120,7 +121,7 @@ class ConfigManager:
|
|
|
120
121
|
return None
|
|
121
122
|
else:
|
|
122
123
|
return value
|
|
123
|
-
|
|
124
|
+
|
|
124
125
|
def get(self, section: str, key: str) -> Any:
|
|
125
126
|
"""Read a value from the configuration file.
|
|
126
127
|
|
|
@@ -144,7 +145,7 @@ class ConfigManager:
|
|
|
144
145
|
int: The integer value.
|
|
145
146
|
"""
|
|
146
147
|
return self.read_key(section, key, int)
|
|
147
|
-
|
|
148
|
+
|
|
148
149
|
def get_float(self, section: str, key: str) -> int:
|
|
149
150
|
"""Read an float value from the configuration file.
|
|
150
151
|
|
|
@@ -180,7 +181,7 @@ class ConfigManager:
|
|
|
180
181
|
list: The list value.
|
|
181
182
|
"""
|
|
182
183
|
return self.read_key(section, key, list)
|
|
183
|
-
|
|
184
|
+
|
|
184
185
|
def get_dict(self, section: str, key: str) -> dict:
|
|
185
186
|
"""Read a dictionary value from the configuration file.
|
|
186
187
|
|
|
@@ -220,7 +221,7 @@ class ConfigManager:
|
|
|
220
221
|
json.dump(self.config, f, indent=4)
|
|
221
222
|
except Exception as e:
|
|
222
223
|
print(f"Error writing configuration file: {e}")
|
|
223
|
-
|
|
224
|
+
|
|
224
225
|
|
|
225
226
|
# Initialize
|
|
226
227
|
config_manager = ConfigManager()
|
|
@@ -4,8 +4,6 @@ import os
|
|
|
4
4
|
import glob
|
|
5
5
|
import gzip
|
|
6
6
|
import shutil
|
|
7
|
-
import tarfile
|
|
8
|
-
import zipfile
|
|
9
7
|
import logging
|
|
10
8
|
import platform
|
|
11
9
|
import subprocess
|
|
@@ -179,64 +177,59 @@ class FFMPEGDownloader:
|
|
|
179
177
|
size = file.write(chunk)
|
|
180
178
|
progress.update(download_task, advance=size)
|
|
181
179
|
return True
|
|
180
|
+
|
|
182
181
|
except Exception as e:
|
|
183
182
|
logging.error(f"Download error: {e}")
|
|
184
183
|
return False
|
|
185
184
|
|
|
186
|
-
def
|
|
185
|
+
def _extract_file(self, gz_path: str, final_path: str) -> bool:
|
|
187
186
|
"""
|
|
188
|
-
Extract
|
|
187
|
+
Extract a gzipped file and set proper permissions.
|
|
189
188
|
|
|
190
189
|
Parameters:
|
|
191
|
-
|
|
190
|
+
gz_path (str): Path to the gzipped file
|
|
191
|
+
final_path (str): Path where the extracted file should be saved
|
|
192
192
|
|
|
193
193
|
Returns:
|
|
194
|
-
|
|
195
|
-
ffprobe, and ffplay executables. Returns None for each executable that couldn't be extracted.
|
|
194
|
+
bool: True if extraction was successful, False otherwise
|
|
196
195
|
"""
|
|
197
196
|
try:
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
if
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
197
|
+
logging.info(f"Attempting to extract {gz_path} to {final_path}")
|
|
198
|
+
|
|
199
|
+
# Check if source file exists and is readable
|
|
200
|
+
if not os.path.exists(gz_path):
|
|
201
|
+
logging.error(f"Source file {gz_path} does not exist")
|
|
202
|
+
return False
|
|
203
|
+
|
|
204
|
+
if not os.access(gz_path, os.R_OK):
|
|
205
|
+
logging.error(f"Source file {gz_path} is not readable")
|
|
206
|
+
return False
|
|
207
|
+
|
|
208
|
+
# Extract the file
|
|
209
|
+
with gzip.open(gz_path, 'rb') as f_in:
|
|
210
|
+
# Test if the gzip file is valid
|
|
211
|
+
try:
|
|
212
|
+
f_in.read(1)
|
|
213
|
+
f_in.seek(0)
|
|
214
|
+
except Exception as e:
|
|
215
|
+
logging.error(f"Invalid gzip file {gz_path}: {e}")
|
|
216
|
+
return False
|
|
217
|
+
|
|
218
|
+
# Extract the file
|
|
219
|
+
with open(final_path, 'wb') as f_out:
|
|
211
220
|
shutil.copyfileobj(f_in, f_out)
|
|
212
|
-
else:
|
|
213
|
-
raise ValueError("Unsupported archive format")
|
|
214
|
-
|
|
215
|
-
config = FFMPEG_CONFIGURATION[self.os_name]
|
|
216
|
-
executables = config['executables']
|
|
217
|
-
found_paths = []
|
|
218
|
-
|
|
219
|
-
for executable in executables:
|
|
220
|
-
exe_paths = glob.glob(os.path.join(extraction_path, '**', executable), recursive=True)
|
|
221
|
-
if exe_paths:
|
|
222
|
-
dest_path = os.path.join(self.base_dir, executable)
|
|
223
|
-
shutil.copy2(exe_paths[0], dest_path)
|
|
224
|
-
|
|
225
|
-
if self.os_name != 'windows':
|
|
226
|
-
os.chmod(dest_path, 0o755)
|
|
227
|
-
|
|
228
|
-
found_paths.append(dest_path)
|
|
229
|
-
else:
|
|
230
|
-
found_paths.append(None)
|
|
231
221
|
|
|
232
|
-
|
|
233
|
-
os.
|
|
234
|
-
|
|
235
|
-
|
|
222
|
+
# Set executable permissions
|
|
223
|
+
os.chmod(final_path, 0o755)
|
|
224
|
+
logging.info(f"Successfully extracted {gz_path} to {final_path}")
|
|
225
|
+
|
|
226
|
+
# Remove the gzip file
|
|
227
|
+
os.remove(gz_path)
|
|
228
|
+
return True
|
|
236
229
|
|
|
237
230
|
except Exception as e:
|
|
238
|
-
logging.error(f"Extraction
|
|
239
|
-
return
|
|
231
|
+
logging.error(f"Extraction error for {gz_path}: {e}")
|
|
232
|
+
return False
|
|
240
233
|
|
|
241
234
|
def download(self) -> Tuple[Optional[str], Optional[str], Optional[str]]:
|
|
242
235
|
"""
|
|
@@ -244,30 +237,43 @@ class FFMPEGDownloader:
|
|
|
244
237
|
|
|
245
238
|
Returns:
|
|
246
239
|
Tuple[Optional[str], Optional[str], Optional[str]]: Paths to ffmpeg, ffprobe, and ffplay executables.
|
|
247
|
-
Returns None for each executable that couldn't be downloaded or set up.
|
|
248
240
|
"""
|
|
249
241
|
config = FFMPEG_CONFIGURATION[self.os_name]
|
|
250
242
|
executables = [exe.format(arch=self.arch) for exe in config['executables']]
|
|
251
|
-
|
|
243
|
+
successful_extractions = []
|
|
244
|
+
|
|
252
245
|
for executable in executables:
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
246
|
+
try:
|
|
247
|
+
download_url = f"https://github.com/eugeneware/ffmpeg-static/releases/latest/download/{executable}.gz"
|
|
248
|
+
download_path = os.path.join(self.base_dir, f"{executable}.gz")
|
|
249
|
+
final_path = os.path.join(self.base_dir, executable)
|
|
250
|
+
|
|
251
|
+
# Log the current operation
|
|
252
|
+
logging.info(f"Processing {executable}")
|
|
253
|
+
console.print(f"[bold blue]Downloading {executable} from GitHub[/]")
|
|
254
|
+
|
|
255
|
+
# Download the file
|
|
256
|
+
if not self._download_file(download_url, download_path):
|
|
257
|
+
console.print(f"[bold red]Failed to download {executable}[/]")
|
|
258
|
+
continue
|
|
259
|
+
|
|
260
|
+
# Extract the file
|
|
261
|
+
if self._extract_file(download_path, final_path):
|
|
262
|
+
successful_extractions.append(final_path)
|
|
263
|
+
console.print(f"[bold green]Successfully installed {executable}[/]")
|
|
264
|
+
else:
|
|
265
|
+
console.print(f"[bold red]Failed to extract {executable}[/]")
|
|
266
|
+
|
|
267
|
+
except Exception as e:
|
|
268
|
+
logging.error(f"Error processing {executable}: {e}")
|
|
269
|
+
console.print(f"[bold red]Error processing {executable}: {str(e)}[/]")
|
|
270
|
+
continue
|
|
271
|
+
|
|
272
|
+
# Return the results based on successful extractions
|
|
267
273
|
return (
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
None
|
|
274
|
+
successful_extractions[0] if len(successful_extractions) > 0 else None,
|
|
275
|
+
successful_extractions[1] if len(successful_extractions) > 1 else None,
|
|
276
|
+
None # ffplay is not included in the current implementation
|
|
271
277
|
)
|
|
272
278
|
|
|
273
279
|
def check_ffmpeg() -> Tuple[Optional[str], Optional[str], Optional[str]]:
|
|
@@ -1,104 +1,24 @@
|
|
|
1
1
|
# 4.04.24
|
|
2
2
|
|
|
3
|
-
import re
|
|
4
|
-
import sys
|
|
5
3
|
import random
|
|
6
|
-
from importlib.metadata import version, PackageNotFoundError
|
|
7
4
|
|
|
8
5
|
|
|
9
6
|
# External library
|
|
10
|
-
|
|
7
|
+
import ua_generator
|
|
11
8
|
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
try:
|
|
15
|
-
ua_version = version('fake-useragent')
|
|
16
|
-
except PackageNotFoundError:
|
|
17
|
-
ua_version = None
|
|
18
|
-
|
|
19
|
-
if not getattr(sys, 'frozen', False):
|
|
20
|
-
if ua_version == '1.1.3':
|
|
21
|
-
ua = UserAgent(use_external_data=True)
|
|
22
|
-
else:
|
|
23
|
-
ua = UserAgent()
|
|
24
|
-
else:
|
|
25
|
-
ua = UserAgent()
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def extract_versions(user_agent):
|
|
29
|
-
"""
|
|
30
|
-
Extract browser versions from the user agent.
|
|
31
|
-
|
|
32
|
-
Parameters:
|
|
33
|
-
user_agent (str): User agent of the browser.
|
|
34
|
-
|
|
35
|
-
Returns:
|
|
36
|
-
list: List of browser versions.
|
|
37
|
-
"""
|
|
38
|
-
|
|
39
|
-
# Patterns to extract versions from various user agents
|
|
40
|
-
patterns = {
|
|
41
|
-
'chrome': re.compile(r'Chrome/(\d+)\.(\d+)\.(\d+)\.(\d+)'),
|
|
42
|
-
'firefox': re.compile(r'Firefox/(\d+)\.?(\d+)?\.?(\d+)?'),
|
|
43
|
-
'safari': re.compile(r'Version/(\d+)\.(\d+)\.(\d+) Safari/(\d+)\.(\d+)\.(\d+)'),
|
|
44
|
-
'edge': re.compile(r'Edg/(\d+)\.(\d+)\.(\d+)\.(\d+)'),
|
|
45
|
-
'edgios': re.compile(r'EdgiOS/(\d+)\.(\d+)\.(\d+)\.(\d+)'),
|
|
46
|
-
'crios': re.compile(r'CriOS/(\d+)\.(\d+)\.(\d+)\.(\d+)'),
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
for key, pattern in patterns.items():
|
|
50
|
-
match = pattern.search(user_agent)
|
|
51
|
-
if match:
|
|
52
|
-
return [match.group(i+1) for i in range(match.lastindex)]
|
|
53
|
-
|
|
54
|
-
# Fallback values if specific versions are not found
|
|
55
|
-
return ['99', '0', '0', '0']
|
|
56
|
-
|
|
57
|
-
def get_platform(user_agent):
|
|
10
|
+
def get_headers() -> str:
|
|
58
11
|
"""
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
Parameters:
|
|
62
|
-
user_agent (str): User agent of the browser.
|
|
12
|
+
Generate a random user agent to use in HTTP requests.
|
|
63
13
|
|
|
64
14
|
Returns:
|
|
65
|
-
str:
|
|
66
|
-
"""
|
|
67
|
-
if 'Windows' in user_agent:
|
|
68
|
-
return '"Windows"'
|
|
69
|
-
elif 'Mac OS X' in user_agent:
|
|
70
|
-
return '"macOS"'
|
|
71
|
-
elif 'Android' in user_agent:
|
|
72
|
-
return '"Android"'
|
|
73
|
-
elif 'iPhone' in user_agent or 'iPad' in user_agent:
|
|
74
|
-
return '"iOS"'
|
|
75
|
-
elif 'Linux' in user_agent:
|
|
76
|
-
return '"Linux"'
|
|
77
|
-
return '"Unknown"'
|
|
78
|
-
|
|
79
|
-
def get_model(user_agent):
|
|
15
|
+
- str: A random user agent string.
|
|
80
16
|
"""
|
|
81
|
-
|
|
17
|
+
|
|
18
|
+
# Get a random user agent string from the user agent rotator
|
|
19
|
+
user_agent = ua_generator.generate().text
|
|
20
|
+
return user_agent
|
|
82
21
|
|
|
83
|
-
Parameters:
|
|
84
|
-
user_agent (str): User agent of the browser.
|
|
85
|
-
|
|
86
|
-
Returns:
|
|
87
|
-
str: Device model.
|
|
88
|
-
"""
|
|
89
|
-
if 'iPhone' in user_agent:
|
|
90
|
-
return '"iPhone"'
|
|
91
|
-
elif 'iPad' in user_agent:
|
|
92
|
-
return '"iPad"'
|
|
93
|
-
elif 'Android' in user_agent:
|
|
94
|
-
return '"Android"'
|
|
95
|
-
elif 'Windows' in user_agent:
|
|
96
|
-
return '"PC"'
|
|
97
|
-
elif 'Mac OS X' in user_agent:
|
|
98
|
-
return '"Mac"'
|
|
99
|
-
elif 'Linux' in user_agent:
|
|
100
|
-
return '"Linux"'
|
|
101
|
-
return '"Unknown"'
|
|
102
22
|
|
|
103
23
|
def random_headers(referer: str = None):
|
|
104
24
|
"""
|
|
@@ -107,26 +27,10 @@ def random_headers(referer: str = None):
|
|
|
107
27
|
Returns:
|
|
108
28
|
dict: Generated HTTP headers.
|
|
109
29
|
"""
|
|
110
|
-
|
|
111
|
-
versions = extract_versions(user_agent)
|
|
112
|
-
platform = get_platform(user_agent)
|
|
113
|
-
model = get_model(user_agent)
|
|
114
|
-
is_mobile = 'Mobi' in user_agent or 'Android' in user_agent
|
|
115
|
-
|
|
116
|
-
# Generate sec-ch-ua string based on the browser
|
|
117
|
-
if 'Chrome' in user_agent or 'CriOS' in user_agent:
|
|
118
|
-
sec_ch_ua = f'" Not;A Brand";v="{versions[0]}", "Chromium";v="{versions[0]}", "Google Chrome";v="{versions[0]}"'
|
|
119
|
-
elif 'Edg' in user_agent or 'EdgiOS' in user_agent:
|
|
120
|
-
sec_ch_ua = f'" Not;A Brand";v="{versions[0]}", "Chromium";v="{versions[0]}", "Microsoft Edge";v="{versions[0]}"'
|
|
121
|
-
elif 'Firefox' in user_agent:
|
|
122
|
-
sec_ch_ua = f'" Not;A Brand";v="{versions[0]}", "Firefox";v="{versions[0]}"'
|
|
123
|
-
elif 'Safari' in user_agent:
|
|
124
|
-
sec_ch_ua = f'" Not;A Brand";v="{versions[0]}", "Safari";v="{versions[0]}"'
|
|
125
|
-
else:
|
|
126
|
-
sec_ch_ua = f'" Not;A Brand";v="{versions[0]}"'
|
|
30
|
+
ua = ua_generator.generate()
|
|
127
31
|
|
|
128
32
|
headers = {
|
|
129
|
-
'User-Agent':
|
|
33
|
+
'User-Agent': ua.text,
|
|
130
34
|
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
|
|
131
35
|
'Accept-Language': random.choice(['en-US', 'en-GB', 'fr-FR', 'es-ES', 'de-DE']),
|
|
132
36
|
'Accept-Encoding': 'gzip, deflate, br',
|
|
@@ -136,25 +40,10 @@ def random_headers(referer: str = None):
|
|
|
136
40
|
'Sec-Fetch-Mode': 'navigate',
|
|
137
41
|
'Sec-Fetch-Site': 'none',
|
|
138
42
|
'Sec-Fetch-User': '?1',
|
|
139
|
-
'sec-ch-ua-mobile': '?1' if is_mobile else '?0',
|
|
140
|
-
'sec-ch-ua-platform': platform,
|
|
141
|
-
'sec-ch-ua': sec_ch_ua,
|
|
142
|
-
'sec-ch-ua-model': model
|
|
143
43
|
}
|
|
144
44
|
|
|
145
45
|
if referer:
|
|
146
46
|
headers['Origin'] = referer
|
|
147
47
|
headers['Referer'] = referer
|
|
148
48
|
|
|
149
|
-
return headers
|
|
150
|
-
|
|
151
|
-
def get_headers() -> str:
|
|
152
|
-
"""
|
|
153
|
-
Generate a random user agent to use in HTTP requests.
|
|
154
|
-
|
|
155
|
-
Returns:
|
|
156
|
-
- str: A random user agent string.
|
|
157
|
-
"""
|
|
158
|
-
|
|
159
|
-
# Get a random user agent string from the user agent rotator
|
|
160
|
-
return str(ua.chrome)
|
|
49
|
+
return headers
|