mirror of
https://github.com/Arrowar/StreamingCommunity.git
synced 2025-06-07 12:05:35 +00:00
Migrate to pycryptodomex
This commit is contained in:
parent
b59b8f162b
commit
31016f45dd
17
README.md
17
README.md
@ -20,7 +20,6 @@ Chat, contribute, and have fun in our **Git_StreamingCommunity** Discord [Server
|
|||||||
- [Configuration](#configuration)
|
- [Configuration](#configuration)
|
||||||
- [Default](#default-settings)
|
- [Default](#default-settings)
|
||||||
- [Request](#requests-settings)
|
- [Request](#requests-settings)
|
||||||
- [Browser](#browser-settings)
|
|
||||||
- [Download](#m3u8_download-settings)
|
- [Download](#m3u8_download-settings)
|
||||||
- [Parser](#m3u8_parser-settings)
|
- [Parser](#m3u8_parser-settings)
|
||||||
- [Docker](#docker)
|
- [Docker](#docker)
|
||||||
@ -173,8 +172,7 @@ The configuration file is divided into several main sections:
|
|||||||
"movie_folder_name": "Movie",
|
"movie_folder_name": "Movie",
|
||||||
"serie_folder_name": "TV",
|
"serie_folder_name": "TV",
|
||||||
"map_episode_name": "%(tv_name)_S%(season)E%(episode)_%(episode_name)",
|
"map_episode_name": "%(tv_name)_S%(season)E%(episode)_%(episode_name)",
|
||||||
"not_close": false,
|
"not_close": false
|
||||||
"show_trending": false
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -202,7 +200,6 @@ The configuration file is divided into several main sections:
|
|||||||
`<br/><br/>`
|
`<br/><br/>`
|
||||||
|
|
||||||
- `not_close`: If true, continues running after downloading
|
- `not_close`: If true, continues running after downloading
|
||||||
- `show_trending`: Display trending content on startup
|
|
||||||
|
|
||||||
### qBittorrent Configuration
|
### qBittorrent Configuration
|
||||||
|
|
||||||
@ -235,18 +232,6 @@ The configuration file is divided into several main sections:
|
|||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
## BROWSER Settings
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"headless": false
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `headless`: Controls whether to run browser in headless mode
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
## M3U8_DOWNLOAD Settings
|
## M3U8_DOWNLOAD Settings
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
@ -78,7 +78,7 @@ class VideoSource:
|
|||||||
logging.warning("Anchor tag not found. Trying the alternative method.")
|
logging.warning("Anchor tag not found. Trying the alternative method.")
|
||||||
headers = {
|
headers = {
|
||||||
'origin': 'https://stayonline.pro',
|
'origin': 'https://stayonline.pro',
|
||||||
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 OPR/111.0.0.0',
|
'user-agent': get_headers(),
|
||||||
'x-requested-with': 'XMLHttpRequest',
|
'x-requested-with': 'XMLHttpRequest',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ from bs4 import BeautifulSoup
|
|||||||
|
|
||||||
# Internal utilities
|
# Internal utilities
|
||||||
from StreamingCommunity.Util.headers import get_headers
|
from StreamingCommunity.Util.headers import get_headers
|
||||||
from StreamingCommunity.Util.console import console, Panel
|
from StreamingCommunity.Util.console import console
|
||||||
from StreamingCommunity.Util._jsonConfig import config_manager
|
from StreamingCommunity.Util._jsonConfig import config_manager
|
||||||
from .Helper.Vixcloud.util import WindowVideo, WindowParameter, StreamsCollection
|
from .Helper.Vixcloud.util import WindowVideo, WindowParameter, StreamsCollection
|
||||||
from .Helper.Vixcloud.js_parser import JavaScriptParser
|
from .Helper.Vixcloud.js_parser import JavaScriptParser
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
# 12.14.24
|
# 12.14.24
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
from typing import List, Dict, Optional
|
from typing import List, Dict, Optional
|
||||||
@ -11,6 +12,7 @@ from bs4 import BeautifulSoup
|
|||||||
|
|
||||||
# Internal utilities
|
# Internal utilities
|
||||||
from StreamingCommunity.Util._jsonConfig import config_manager
|
from StreamingCommunity.Util._jsonConfig import config_manager
|
||||||
|
from StreamingCommunity.Util.headers import get_headers
|
||||||
from StreamingCommunity.Util.console import console
|
from StreamingCommunity.Util.console import console
|
||||||
|
|
||||||
|
|
||||||
@ -23,7 +25,7 @@ class IlCorsaroNeroScraper:
|
|||||||
self.base_url = base_url
|
self.base_url = base_url
|
||||||
self.max_page = max_page
|
self.max_page = max_page
|
||||||
self.headers = {
|
self.headers = {
|
||||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
|
'User-Agent': get_headers(),
|
||||||
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
|
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
|
||||||
'Accept-Language': 'en-US,en;q=0.5',
|
'Accept-Language': 'en-US,en;q=0.5',
|
||||||
'Connection': 'keep-alive',
|
'Connection': 'keep-alive',
|
||||||
|
@ -60,6 +60,11 @@ def get_final_redirect_url(initial_url, max_timeout):
|
|||||||
|
|
||||||
) as client:
|
) as client:
|
||||||
response = client.get(initial_url)
|
response = client.get(initial_url)
|
||||||
|
|
||||||
|
if response.status_code == 403:
|
||||||
|
console.print("[bold red]The owner of this website has banned your IP[/bold red]")
|
||||||
|
raise
|
||||||
|
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
|
|
||||||
# Capture the final URL after all redirects
|
# Capture the final URL after all redirects
|
||||||
|
@ -49,7 +49,6 @@ GET_ONLY_LINK = config_manager.get_bool('M3U8_PARSER', 'get_only_link')
|
|||||||
|
|
||||||
# Variable
|
# Variable
|
||||||
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
||||||
headers_index = config_manager.get_dict('REQUESTS', 'user-agent')
|
|
||||||
m3u8_url_fixer = M3U8_UrlFix()
|
m3u8_url_fixer = M3U8_UrlFix()
|
||||||
list_MissingTs = []
|
list_MissingTs = []
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ TQDM_DELAY_WORKER = config_manager.get_float('M3U8_DOWNLOAD', 'tqdm_delay')
|
|||||||
TQDM_USE_LARGE_BAR = config_manager.get_int('M3U8_DOWNLOAD', 'tqdm_use_large_bar')
|
TQDM_USE_LARGE_BAR = config_manager.get_int('M3U8_DOWNLOAD', 'tqdm_use_large_bar')
|
||||||
|
|
||||||
REQUEST_MAX_RETRY = config_manager.get_int('REQUESTS', 'max_retry')
|
REQUEST_MAX_RETRY = config_manager.get_int('REQUESTS', 'max_retry')
|
||||||
REQUEST_VERIFY = config_manager.get_bool('REQUESTS', 'verify_ssl')
|
REQUEST_VERIFY = False
|
||||||
|
|
||||||
THERE_IS_PROXY_LIST = os_manager.check_file("list_proxy.txt")
|
THERE_IS_PROXY_LIST = os_manager.check_file("list_proxy.txt")
|
||||||
PROXY_START_MIN = config_manager.get_float('REQUESTS', 'proxy_start_min')
|
PROXY_START_MIN = config_manager.get_float('REQUESTS', 'proxy_start_min')
|
||||||
@ -55,7 +55,6 @@ DEFAULT_AUDIO_WORKERS = config_manager.get_int('M3U8_DOWNLOAD', 'default_audio_w
|
|||||||
|
|
||||||
|
|
||||||
# Variable
|
# Variable
|
||||||
headers_index = config_manager.get_dict('REQUESTS', 'user-agent')
|
|
||||||
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
max_timeout = config_manager.get_int("REQUESTS", "timeout")
|
||||||
|
|
||||||
|
|
||||||
@ -110,7 +109,6 @@ class M3U8_Segments:
|
|||||||
Returns:
|
Returns:
|
||||||
bytes: The encryption key in bytes.
|
bytes: The encryption key in bytes.
|
||||||
"""
|
"""
|
||||||
headers_index = {'user-agent': get_headers()}
|
|
||||||
|
|
||||||
# Construct the full URL of the key
|
# Construct the full URL of the key
|
||||||
key_uri = urljoin(self.url, m3u8_parser.keys.get('uri'))
|
key_uri = urljoin(self.url, m3u8_parser.keys.get('uri'))
|
||||||
@ -122,7 +120,7 @@ class M3U8_Segments:
|
|||||||
try:
|
try:
|
||||||
response = httpx.get(
|
response = httpx.get(
|
||||||
url=key_uri,
|
url=key_uri,
|
||||||
headers=headers_index,
|
headers={'User-Agent': get_headers()},
|
||||||
timeout=max_timeout
|
timeout=max_timeout
|
||||||
)
|
)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
@ -194,14 +192,12 @@ class M3U8_Segments:
|
|||||||
"""
|
"""
|
||||||
Makes a request to the index M3U8 file to get information about segments.
|
Makes a request to the index M3U8 file to get information about segments.
|
||||||
"""
|
"""
|
||||||
headers_index = {'user-agent': get_headers()}
|
|
||||||
|
|
||||||
if self.is_index_url:
|
if self.is_index_url:
|
||||||
|
|
||||||
# Send a GET request to retrieve the index M3U8 file
|
# Send a GET request to retrieve the index M3U8 file
|
||||||
response = httpx.get(
|
response = httpx.get(
|
||||||
self.url,
|
self.url,
|
||||||
headers=headers_index,
|
headers={'User-Agent': get_headers()},
|
||||||
timeout=max_timeout
|
timeout=max_timeout
|
||||||
)
|
)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
@ -271,7 +267,7 @@ class M3U8_Segments:
|
|||||||
else:
|
else:
|
||||||
response = client.get(
|
response = client.get(
|
||||||
url=ts_url,
|
url=ts_url,
|
||||||
headers={'user-agent': get_headers()},
|
headers={'User-Agent': get_headers()},
|
||||||
timeout=max_timeout,
|
timeout=max_timeout,
|
||||||
follow_redirects=True
|
follow_redirects=True
|
||||||
)
|
)
|
||||||
@ -289,7 +285,7 @@ class M3U8_Segments:
|
|||||||
else:
|
else:
|
||||||
response = client_2.get(
|
response = client_2.get(
|
||||||
url=ts_url,
|
url=ts_url,
|
||||||
headers={'user-agent': get_headers()},
|
headers={'User-Agent': get_headers()},
|
||||||
timeout=max_timeout,
|
timeout=max_timeout,
|
||||||
follow_redirects=True
|
follow_redirects=True
|
||||||
)
|
)
|
||||||
|
@ -32,7 +32,6 @@ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|||||||
# Config
|
# Config
|
||||||
GET_ONLY_LINK = config_manager.get_bool('M3U8_PARSER', 'get_only_link')
|
GET_ONLY_LINK = config_manager.get_bool('M3U8_PARSER', 'get_only_link')
|
||||||
TQDM_USE_LARGE_BAR = config_manager.get_int('M3U8_DOWNLOAD', 'tqdm_use_large_bar')
|
TQDM_USE_LARGE_BAR = config_manager.get_int('M3U8_DOWNLOAD', 'tqdm_use_large_bar')
|
||||||
REQUEST_VERIFY = config_manager.get_float('REQUESTS', 'verify_ssl')
|
|
||||||
REQUEST_TIMEOUT = config_manager.get_float('REQUESTS', 'timeout')
|
REQUEST_TIMEOUT = config_manager.get_float('REQUESTS', 'timeout')
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@ PASSWORD = str(config_manager.get_dict('DEFAULT', 'config_qbit_tor')['pass'])
|
|||||||
|
|
||||||
# Config
|
# Config
|
||||||
TQDM_USE_LARGE_BAR = config_manager.get_int('M3U8_DOWNLOAD', 'tqdm_use_large_bar')
|
TQDM_USE_LARGE_BAR = config_manager.get_int('M3U8_DOWNLOAD', 'tqdm_use_large_bar')
|
||||||
REQUEST_VERIFY = config_manager.get_float('REQUESTS', 'verify_ssl')
|
|
||||||
REQUEST_TIMEOUT = config_manager.get_float('REQUESTS', 'timeout')
|
REQUEST_TIMEOUT = config_manager.get_float('REQUESTS', 'timeout')
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,76 +0,0 @@
|
|||||||
# 29.06.24
|
|
||||||
|
|
||||||
import tempfile
|
|
||||||
import logging
|
|
||||||
|
|
||||||
|
|
||||||
# External library
|
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
from seleniumbase import Driver
|
|
||||||
|
|
||||||
|
|
||||||
# Internal utilities
|
|
||||||
from StreamingCommunity.Util._jsonConfig import config_manager
|
|
||||||
|
|
||||||
|
|
||||||
# Config
|
|
||||||
USE_HEADLESS = config_manager.get_bool("BROWSER", "headless")
|
|
||||||
|
|
||||||
|
|
||||||
class WebAutomation:
|
|
||||||
"""
|
|
||||||
A class for automating web interactions using SeleniumBase and BeautifulSoup.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
"""
|
|
||||||
Initializes the WebAutomation instance with SeleniumBase Driver.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
headless (bool, optional): Whether to run the browser in headless mode. Default is True.
|
|
||||||
"""
|
|
||||||
logging.getLogger('seleniumbase').setLevel(logging.ERROR)
|
|
||||||
|
|
||||||
self.driver = Driver(
|
|
||||||
uc=True,
|
|
||||||
uc_cdp_events=True,
|
|
||||||
headless=USE_HEADLESS,
|
|
||||||
user_data_dir = tempfile.mkdtemp(),
|
|
||||||
chromium_arg="--disable-search-engine-choice-screen"
|
|
||||||
)
|
|
||||||
|
|
||||||
def quit(self):
|
|
||||||
"""
|
|
||||||
Quits the WebDriver instance.
|
|
||||||
"""
|
|
||||||
self.driver.quit()
|
|
||||||
|
|
||||||
def get_page(self, url):
|
|
||||||
"""
|
|
||||||
Navigates the browser to the specified URL.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
url (str): The URL to navigate to.
|
|
||||||
"""
|
|
||||||
self.driver.get(url)
|
|
||||||
|
|
||||||
def retrieve_soup(self):
|
|
||||||
"""
|
|
||||||
Retrieves the BeautifulSoup object for the current page's HTML content.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
BeautifulSoup object: Parsed HTML content of the current page.
|
|
||||||
"""
|
|
||||||
html_content = self.driver.page_source
|
|
||||||
soup = BeautifulSoup(html_content, 'html.parser')
|
|
||||||
return soup
|
|
||||||
|
|
||||||
def get_content(self):
|
|
||||||
"""
|
|
||||||
Returns the HTML content of the current page.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The HTML content of the current page.
|
|
||||||
"""
|
|
||||||
return self.driver.page_source
|
|
||||||
|
|
@ -12,14 +12,14 @@ from StreamingCommunity.Util.console import console
|
|||||||
|
|
||||||
|
|
||||||
# Check if Crypto module is installed
|
# Check if Crypto module is installed
|
||||||
crypto_spec = importlib.util.find_spec("Crypto")
|
crypto_spec = importlib.util.find_spec("Cryptodome")
|
||||||
crypto_installed = crypto_spec is not None
|
crypto_installed = crypto_spec is not None
|
||||||
|
|
||||||
|
|
||||||
if crypto_installed:
|
if crypto_installed:
|
||||||
logging.info("Decrypy use: Crypto")
|
console.print("[cyan]Decrypy use: Cryptodome")
|
||||||
from Crypto.Cipher import AES # type: ignore
|
from Cryptodome.Cipher import AES
|
||||||
from Crypto.Util.Padding import unpad # type: ignore
|
from Cryptodome.Util.Padding import unpad
|
||||||
|
|
||||||
class M3U8_Decryption:
|
class M3U8_Decryption:
|
||||||
"""
|
"""
|
||||||
@ -93,12 +93,12 @@ else:
|
|||||||
# Check if openssl command is available
|
# Check if openssl command is available
|
||||||
try:
|
try:
|
||||||
openssl_available = subprocess.run(["openssl", "version"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode == 0
|
openssl_available = subprocess.run(["openssl", "version"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode == 0
|
||||||
logging.info("Decrypy use: OPENSSL")
|
console.print("[cyan]Decrypy use: OPENSSL")
|
||||||
except:
|
except:
|
||||||
openssl_available = False
|
openssl_available = False
|
||||||
|
|
||||||
if not openssl_available:
|
if not openssl_available:
|
||||||
console.log("[red]Neither python library: pycryptodome nor openssl software is installed. Please install either one of them. Read readme.md [Requirement].")
|
console.log("[red]Neither python library: pycryptodomex nor openssl software is installed. Please install either one of them. Read readme.md [Requirement].")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
class M3U8_Decryption:
|
class M3U8_Decryption:
|
||||||
|
@ -23,7 +23,6 @@ from StreamingCommunity.Util.logger import Logger
|
|||||||
|
|
||||||
# Config
|
# Config
|
||||||
CLOSE_CONSOLE = config_manager.get_bool('DEFAULT', 'not_close')
|
CLOSE_CONSOLE = config_manager.get_bool('DEFAULT', 'not_close')
|
||||||
SHOW_TRENDING = config_manager.get_bool('DEFAULT', 'show_trending')
|
|
||||||
|
|
||||||
|
|
||||||
def run_function(func: Callable[..., None], close_console: bool = False) -> None:
|
def run_function(func: Callable[..., None], close_console: bool = False) -> None:
|
||||||
@ -126,13 +125,6 @@ def initialize():
|
|||||||
except:
|
except:
|
||||||
console.log("[red]Error with loading github.")
|
console.log("[red]Error with loading github.")
|
||||||
|
|
||||||
# Show trending film and series
|
|
||||||
if SHOW_TRENDING:
|
|
||||||
tmdb.display_trending_films()
|
|
||||||
print()
|
|
||||||
tmdb.display_trending_tv_shows()
|
|
||||||
print()
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
|
10
config.json
10
config.json
@ -15,19 +15,13 @@
|
|||||||
"user": "admin",
|
"user": "admin",
|
||||||
"pass": "adminadmin"
|
"pass": "adminadmin"
|
||||||
},
|
},
|
||||||
"not_close": false,
|
"not_close": false
|
||||||
"show_trending": false
|
|
||||||
},
|
},
|
||||||
"REQUESTS": {
|
"REQUESTS": {
|
||||||
"timeout": 20,
|
"timeout": 20,
|
||||||
"max_retry": 8,
|
"max_retry": 8,
|
||||||
"verify_ssl": true,
|
|
||||||
"proxy_start_min": 0.1,
|
"proxy_start_min": 0.1,
|
||||||
"proxy_start_max": 0.5,
|
"proxy_start_max": 0.5
|
||||||
"user-agent": ""
|
|
||||||
},
|
|
||||||
"BROWSER": {
|
|
||||||
"headless": false
|
|
||||||
},
|
},
|
||||||
"M3U8_DOWNLOAD": {
|
"M3U8_DOWNLOAD": {
|
||||||
"tqdm_delay": 0.01,
|
"tqdm_delay": 0.01,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
httpx
|
httpx
|
||||||
|
cffi
|
||||||
bs4
|
bs4
|
||||||
rich
|
rich
|
||||||
tqdm
|
tqdm
|
||||||
@ -7,7 +8,7 @@ psutil
|
|||||||
unidecode
|
unidecode
|
||||||
jsbeautifier
|
jsbeautifier
|
||||||
pathvalidate
|
pathvalidate
|
||||||
pycryptodome
|
pycryptodomex
|
||||||
fake-useragent==1.1.3
|
fake-useragent==1.1.3
|
||||||
qbittorrent-api
|
qbittorrent-api
|
||||||
python-qbittorrent
|
python-qbittorrent
|
||||||
|
Loading…
x
Reference in New Issue
Block a user