mirror of
https://github.com/Arrowar/StreamingCommunity.git
synced 2025-06-06 19:45:24 +00:00
From fake-useragent to ua-generator
This commit is contained in:
parent
1d56b0c9d4
commit
f3dbdffd52
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
@ -77,12 +77,12 @@ jobs:
|
|||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
python -m pip install -r requirements.txt
|
python -m pip install -r requirements.txt
|
||||||
python -m pip install pyinstaller
|
python -m pip install pyinstaller
|
||||||
python -m pip install fake-useragent==1.1.3
|
|
||||||
- name: Build executable with PyInstaller (Windows)
|
- name: Build executable with PyInstaller (Windows)
|
||||||
if: matrix.os == 'windows-latest'
|
if: matrix.os == 'windows-latest'
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
pyinstaller --onefile --hidden-import=pycryptodomex --hidden-import=fake_useragent `
|
pyinstaller --onefile --hidden-import=pycryptodomex --hidden-import=ua_generator `
|
||||||
--hidden-import=qbittorrentapi --hidden-import=qbittorrent --hidden-import=googlesearch `
|
--hidden-import=qbittorrentapi --hidden-import=qbittorrent --hidden-import=googlesearch `
|
||||||
--hidden-import=bs4 --hidden-import=httpx --hidden-import=rich --hidden-import=tqdm `
|
--hidden-import=bs4 --hidden-import=httpx --hidden-import=rich --hidden-import=tqdm `
|
||||||
--hidden-import=m3u8 --hidden-import=psutil --hidden-import=unidecode `
|
--hidden-import=m3u8 --hidden-import=psutil --hidden-import=unidecode `
|
||||||
@ -93,10 +93,11 @@ jobs:
|
|||||||
--hidden-import=pyTelegramBotAPI --additional-hooks-dir=pyinstaller/hooks `
|
--hidden-import=pyTelegramBotAPI --additional-hooks-dir=pyinstaller/hooks `
|
||||||
--add-data "StreamingCommunity;StreamingCommunity" `
|
--add-data "StreamingCommunity;StreamingCommunity" `
|
||||||
--name=StreamingCommunity --icon=".github/media/logo.ico" test_run.py
|
--name=StreamingCommunity --icon=".github/media/logo.ico" test_run.py
|
||||||
|
|
||||||
- name: Build executable with PyInstaller (Linux)
|
- name: Build executable with PyInstaller (Linux)
|
||||||
if: matrix.os == 'ubuntu-latest'
|
if: matrix.os == 'ubuntu-latest'
|
||||||
run: |
|
run: |
|
||||||
pyinstaller --onefile --hidden-import=pycryptodomex --hidden-import=fake_useragent \
|
pyinstaller --onefile --hidden-import=pycryptodomex --hidden-import=ua_generator \
|
||||||
--hidden-import=qbittorrentapi --hidden-import=qbittorrent --hidden-import=googlesearch \
|
--hidden-import=qbittorrentapi --hidden-import=qbittorrent --hidden-import=googlesearch \
|
||||||
--hidden-import=bs4 --hidden-import=httpx --hidden-import=rich --hidden-import=tqdm \
|
--hidden-import=bs4 --hidden-import=httpx --hidden-import=rich --hidden-import=tqdm \
|
||||||
--hidden-import=m3u8 --hidden-import=psutil --hidden-import=unidecode \
|
--hidden-import=m3u8 --hidden-import=psutil --hidden-import=unidecode \
|
||||||
@ -107,6 +108,7 @@ jobs:
|
|||||||
--hidden-import=pyTelegramBotAPI --additional-hooks-dir=pyinstaller/hooks \
|
--hidden-import=pyTelegramBotAPI --additional-hooks-dir=pyinstaller/hooks \
|
||||||
--add-data "StreamingCommunity:StreamingCommunity" \
|
--add-data "StreamingCommunity:StreamingCommunity" \
|
||||||
--name=StreamingCommunity test_run.py
|
--name=StreamingCommunity test_run.py
|
||||||
|
|
||||||
- name: Upload executable (Windows)
|
- name: Upload executable (Windows)
|
||||||
if: matrix.os == 'windows-latest'
|
if: matrix.os == 'windows-latest'
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
@ -159,11 +159,7 @@ class M3U8Manager:
|
|||||||
If it's a master playlist, only selects video stream.
|
If it's a master playlist, only selects video stream.
|
||||||
"""
|
"""
|
||||||
if not self.is_master:
|
if not self.is_master:
|
||||||
if FILTER_CUSTOM_REOLUTION != -1:
|
self.video_url, self.video_res = self.m3u8_url, "0p"
|
||||||
self.video_url, self.video_res = self.parser._video.get_custom_uri(y_resolution=FILTER_CUSTOM_REOLUTION)
|
|
||||||
else:
|
|
||||||
self.video_url, self.video_res = self.parser._video.get_best_uri()
|
|
||||||
|
|
||||||
self.audio_streams = []
|
self.audio_streams = []
|
||||||
self.sub_streams = []
|
self.sub_streams = []
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ PROXY_START_MAX = config_manager.get_float('REQUESTS', 'proxy_start_max')
|
|||||||
DEFAULT_VIDEO_WORKERS = config_manager.get_int('M3U8_DOWNLOAD', 'default_video_workser')
|
DEFAULT_VIDEO_WORKERS = config_manager.get_int('M3U8_DOWNLOAD', 'default_video_workser')
|
||||||
DEFAULT_AUDIO_WORKERS = config_manager.get_int('M3U8_DOWNLOAD', 'default_audio_workser')
|
DEFAULT_AUDIO_WORKERS = config_manager.get_int('M3U8_DOWNLOAD', 'default_audio_workser')
|
||||||
MAX_TIMEOOUT = config_manager.get_int("REQUESTS", "timeout")
|
MAX_TIMEOOUT = config_manager.get_int("REQUESTS", "timeout")
|
||||||
|
SEGMENT_MAX_TIMEOUT = config_manager.get_int("M3U8_DOWNLOAD", "segment_timeout")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -169,8 +170,9 @@ class M3U8_Segments:
|
|||||||
|
|
||||||
def _get_http_client(self, index: int = None):
|
def _get_http_client(self, index: int = None):
|
||||||
client_params = {
|
client_params = {
|
||||||
'headers': random_headers(self.key_base_url) if hasattr(self, 'key_base_url') else {'User-Agent': get_headers()},
|
#'headers': random_headers(self.key_base_url) if hasattr(self, 'key_base_url') else {'User-Agent': get_headers()},
|
||||||
'timeout': MAX_TIMEOOUT,
|
'headers': {'User-Agent': get_headers()},
|
||||||
|
'timeout': SEGMENT_MAX_TIMEOUT,
|
||||||
'follow_redirects': True,
|
'follow_redirects': True,
|
||||||
'http2': False
|
'http2': False
|
||||||
}
|
}
|
||||||
@ -391,7 +393,7 @@ class M3U8_Segments:
|
|||||||
f"{Colors.YELLOW}[HLS] {Colors.WHITE}({Colors.CYAN}{description}{Colors.WHITE}): "
|
f"{Colors.YELLOW}[HLS] {Colors.WHITE}({Colors.CYAN}{description}{Colors.WHITE}): "
|
||||||
f"{Colors.RED}{{percentage:.2f}}% "
|
f"{Colors.RED}{{percentage:.2f}}% "
|
||||||
f"{Colors.MAGENTA}{{bar}} "
|
f"{Colors.MAGENTA}{{bar}} "
|
||||||
f"{Colors.WHITE}[ {Colors.YELLOW}{{elapsed}}{Colors.WHITE} < {Colors.CYAN}{{remaining}}{Colors.WHITE}{{postfix}}{Colors.WHITE} ]"
|
f"{Colors.YELLOW}{{elapsed}}{Colors.WHITE} < {Colors.CYAN}{{remaining}}{Colors.WHITE}{{postfix}}{Colors.WHITE}"
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_worker_count(self, stream_type: str) -> int:
|
def _get_worker_count(self, stream_type: str) -> int:
|
||||||
|
@ -1,153 +1,12 @@
|
|||||||
# 4.04.24
|
# 4.04.24
|
||||||
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
import random
|
import random
|
||||||
from importlib.metadata import version, PackageNotFoundError
|
|
||||||
|
|
||||||
|
|
||||||
# External library
|
# External library
|
||||||
from fake_useragent import UserAgent
|
import ua_generator
|
||||||
|
|
||||||
|
|
||||||
# Variable
|
|
||||||
try:
|
|
||||||
ua_version = version('fake-useragent')
|
|
||||||
except PackageNotFoundError:
|
|
||||||
ua_version = None
|
|
||||||
|
|
||||||
if not getattr(sys, 'frozen', False):
|
|
||||||
if ua_version == '1.1.3':
|
|
||||||
ua = UserAgent(use_external_data=True)
|
|
||||||
else:
|
|
||||||
ua = UserAgent()
|
|
||||||
else:
|
|
||||||
ua = UserAgent()
|
|
||||||
|
|
||||||
|
|
||||||
def extract_versions(user_agent):
|
|
||||||
"""
|
|
||||||
Extract browser versions from the user agent.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
user_agent (str): User agent of the browser.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list: List of browser versions.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Patterns to extract versions from various user agents
|
|
||||||
patterns = {
|
|
||||||
'chrome': re.compile(r'Chrome/(\d+)\.(\d+)\.(\d+)\.(\d+)'),
|
|
||||||
'firefox': re.compile(r'Firefox/(\d+)\.?(\d+)?\.?(\d+)?'),
|
|
||||||
'safari': re.compile(r'Version/(\d+)\.(\d+)\.(\d+) Safari/(\d+)\.(\d+)\.(\d+)'),
|
|
||||||
'edge': re.compile(r'Edg/(\d+)\.(\d+)\.(\d+)\.(\d+)'),
|
|
||||||
'edgios': re.compile(r'EdgiOS/(\d+)\.(\d+)\.(\d+)\.(\d+)'),
|
|
||||||
'crios': re.compile(r'CriOS/(\d+)\.(\d+)\.(\d+)\.(\d+)'),
|
|
||||||
}
|
|
||||||
|
|
||||||
for key, pattern in patterns.items():
|
|
||||||
match = pattern.search(user_agent)
|
|
||||||
if match:
|
|
||||||
return [match.group(i+1) for i in range(match.lastindex)]
|
|
||||||
|
|
||||||
# Fallback values if specific versions are not found
|
|
||||||
return ['99', '0', '0', '0']
|
|
||||||
|
|
||||||
def get_platform(user_agent):
|
|
||||||
"""
|
|
||||||
Determine the device platform from the user agent.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
user_agent (str): User agent of the browser.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: Device platform.
|
|
||||||
"""
|
|
||||||
if 'Windows' in user_agent:
|
|
||||||
return '"Windows"'
|
|
||||||
elif 'Mac OS X' in user_agent:
|
|
||||||
return '"macOS"'
|
|
||||||
elif 'Android' in user_agent:
|
|
||||||
return '"Android"'
|
|
||||||
elif 'iPhone' in user_agent or 'iPad' in user_agent:
|
|
||||||
return '"iOS"'
|
|
||||||
elif 'Linux' in user_agent:
|
|
||||||
return '"Linux"'
|
|
||||||
return '"Unknown"'
|
|
||||||
|
|
||||||
def get_model(user_agent):
|
|
||||||
"""
|
|
||||||
Determine the device model from the user agent.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
user_agent (str): User agent of the browser.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: Device model.
|
|
||||||
"""
|
|
||||||
if 'iPhone' in user_agent:
|
|
||||||
return '"iPhone"'
|
|
||||||
elif 'iPad' in user_agent:
|
|
||||||
return '"iPad"'
|
|
||||||
elif 'Android' in user_agent:
|
|
||||||
return '"Android"'
|
|
||||||
elif 'Windows' in user_agent:
|
|
||||||
return '"PC"'
|
|
||||||
elif 'Mac OS X' in user_agent:
|
|
||||||
return '"Mac"'
|
|
||||||
elif 'Linux' in user_agent:
|
|
||||||
return '"Linux"'
|
|
||||||
return '"Unknown"'
|
|
||||||
|
|
||||||
def random_headers(referer: str = None):
|
|
||||||
"""
|
|
||||||
Generate random HTTP headers to simulate human-like behavior.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: Generated HTTP headers.
|
|
||||||
"""
|
|
||||||
user_agent = ua.random
|
|
||||||
versions = extract_versions(user_agent)
|
|
||||||
platform = get_platform(user_agent)
|
|
||||||
model = get_model(user_agent)
|
|
||||||
is_mobile = 'Mobi' in user_agent or 'Android' in user_agent
|
|
||||||
|
|
||||||
# Generate sec-ch-ua string based on the browser
|
|
||||||
if 'Chrome' in user_agent or 'CriOS' in user_agent:
|
|
||||||
sec_ch_ua = f'" Not;A Brand";v="{versions[0]}", "Chromium";v="{versions[0]}", "Google Chrome";v="{versions[0]}"'
|
|
||||||
elif 'Edg' in user_agent or 'EdgiOS' in user_agent:
|
|
||||||
sec_ch_ua = f'" Not;A Brand";v="{versions[0]}", "Chromium";v="{versions[0]}", "Microsoft Edge";v="{versions[0]}"'
|
|
||||||
elif 'Firefox' in user_agent:
|
|
||||||
sec_ch_ua = f'" Not;A Brand";v="{versions[0]}", "Firefox";v="{versions[0]}"'
|
|
||||||
elif 'Safari' in user_agent:
|
|
||||||
sec_ch_ua = f'" Not;A Brand";v="{versions[0]}", "Safari";v="{versions[0]}"'
|
|
||||||
else:
|
|
||||||
sec_ch_ua = f'" Not;A Brand";v="{versions[0]}"'
|
|
||||||
|
|
||||||
headers = {
|
|
||||||
'User-Agent': user_agent,
|
|
||||||
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
|
|
||||||
'Accept-Language': random.choice(['en-US', 'en-GB', 'fr-FR', 'es-ES', 'de-DE']),
|
|
||||||
'Accept-Encoding': 'gzip, deflate, br',
|
|
||||||
'Connection': 'keep-alive',
|
|
||||||
'Upgrade-Insecure-Requests': '1',
|
|
||||||
'Sec-Fetch-Dest': 'document',
|
|
||||||
'Sec-Fetch-Mode': 'navigate',
|
|
||||||
'Sec-Fetch-Site': 'none',
|
|
||||||
'Sec-Fetch-User': '?1',
|
|
||||||
'sec-ch-ua-mobile': '?1' if is_mobile else '?0',
|
|
||||||
'sec-ch-ua-platform': platform,
|
|
||||||
'sec-ch-ua': sec_ch_ua,
|
|
||||||
'sec-ch-ua-model': model
|
|
||||||
}
|
|
||||||
|
|
||||||
if referer:
|
|
||||||
headers['Origin'] = referer
|
|
||||||
headers['Referer'] = referer
|
|
||||||
|
|
||||||
return headers
|
|
||||||
|
|
||||||
def get_headers() -> str:
|
def get_headers() -> str:
|
||||||
"""
|
"""
|
||||||
Generate a random user agent to use in HTTP requests.
|
Generate a random user agent to use in HTTP requests.
|
||||||
@ -157,4 +16,34 @@ def get_headers() -> str:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Get a random user agent string from the user agent rotator
|
# Get a random user agent string from the user agent rotator
|
||||||
return str(ua.chrome)
|
user_agent = ua_generator.generate().text
|
||||||
|
return user_agent
|
||||||
|
|
||||||
|
|
||||||
|
def random_headers(referer: str = None):
|
||||||
|
"""
|
||||||
|
Generate random HTTP headers to simulate human-like behavior.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: Generated HTTP headers.
|
||||||
|
"""
|
||||||
|
ua = ua_generator.generate()
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
'User-Agent': ua.text,
|
||||||
|
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
|
||||||
|
'Accept-Language': random.choice(['en-US', 'en-GB', 'fr-FR', 'es-ES', 'de-DE']),
|
||||||
|
'Accept-Encoding': 'gzip, deflate, br',
|
||||||
|
'Connection': 'keep-alive',
|
||||||
|
'Upgrade-Insecure-Requests': '1',
|
||||||
|
'Sec-Fetch-Dest': 'document',
|
||||||
|
'Sec-Fetch-Mode': 'navigate',
|
||||||
|
'Sec-Fetch-Site': 'none',
|
||||||
|
'Sec-Fetch-User': '?1',
|
||||||
|
}
|
||||||
|
|
||||||
|
if referer:
|
||||||
|
headers['Origin'] = referer
|
||||||
|
headers['Referer'] = referer
|
||||||
|
|
||||||
|
return headers
|
@ -31,6 +31,7 @@
|
|||||||
"tqdm_delay": 0.01,
|
"tqdm_delay": 0.01,
|
||||||
"default_video_workser": 12,
|
"default_video_workser": 12,
|
||||||
"default_audio_workser": 12,
|
"default_audio_workser": 12,
|
||||||
|
"segment_timeout": 7,
|
||||||
"download_audio": true,
|
"download_audio": true,
|
||||||
"merge_audio": true,
|
"merge_audio": true,
|
||||||
"specific_list_audio": [
|
"specific_list_audio": [
|
||||||
|
@ -9,7 +9,7 @@ jsbeautifier
|
|||||||
pathvalidate
|
pathvalidate
|
||||||
pycryptodomex
|
pycryptodomex
|
||||||
googlesearch-python
|
googlesearch-python
|
||||||
fake-useragent<2.0.0
|
ua-generator
|
||||||
qbittorrent-api
|
qbittorrent-api
|
||||||
python-qbittorrent
|
python-qbittorrent
|
||||||
Pillow
|
Pillow
|
||||||
|
Loading…
x
Reference in New Issue
Block a user