From 468f3cf96698b050e42444f941bc1881669e0b92 Mon Sep 17 00:00:00 2001
From: Lovi <62809003+Lovi-0@users.noreply.github.com>
Date: Thu, 6 Feb 2025 14:29:48 +0100
Subject: [PATCH] Fix cb01
---
.github/workflows/build.yml | 48 ++++++++++++++++++
.github/workflows/update-loc-badge.yml | 4 +-
.gitignore | 2 -
MANIFEST.in | 3 ++
README.md | 4 +-
StreamingCommunity/Api/Site/cb01new/film.py | 1 -
.../Lib/Downloader/HLS/downloader.py | 2 +-
.../Lib/Downloader/HLS/segments.py | 12 ++---
StreamingCommunity/Upload/update.py | 24 +++++++--
StreamingCommunity/Util/message.py | 12 ++---
StreamingCommunity/Util/os.py | 22 --------
Test/Media/62809003.ico | Bin 0 -> 4474 bytes
Test/{Util => Media}/loc-badge.json | 0
config.json | 2 +-
setup.py | 32 ++++++++++++
15 files changed, 120 insertions(+), 48 deletions(-)
create mode 100644 .github/workflows/build.yml
create mode 100644 MANIFEST.in
create mode 100644 Test/Media/62809003.ico
rename Test/{Util => Media}/loc-badge.json (100%)
create mode 100644 setup.py
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..089c5cb
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,48 @@
+name: Build and Release with PyInstaller
+
+on:
+ workflow_dispatch:
+
+jobs:
+ build:
+ runs-on: windows-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.11'
+
+ - name: Cache Python dependencies
+ uses: actions/cache@v3
+ with:
+ path: ~/.cache/pip
+ key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
+ restore-keys: |
+ ${{ runner.os }}-pip-
+
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install -r requirements.txt
+ pip install fake-useragent==1.1.3
+
+ - name: Build executable with PyInstaller
+ run: |
+ pyinstaller --onefile --hidden-import=pycryptodomex --hidden-import=fake_useragent --hidden-import=qbittorrentapi --hidden-import=qbittorrent --hidden-import=googlesearch --hidden-import=bs4 --hidden-import=httpx --hidden-import=rich --hidden-import=tqdm --hidden-import=m3u8 --hidden-import=psutil --hidden-import=unidecode --hidden-import=jsbeautifier --hidden-import=pathvalidate --hidden-import=Cryptodome.Cipher --hidden-import=Cryptodome.Cipher.AES --hidden-import=Cryptodome.Util --hidden-import=Cryptodome.Util.Padding --hidden-import=Cryptodome.Random --hidden-import=Pillow --hidden-import=pyTelegramBotAPI --additional-hooks-dir=pyinstaller/hooks --add-data "StreamingCommunity;StreamingCommunity" --name=StreamingCommunity --icon="StreamingCommunity/Test/Media/62809003.ico" test_run.py
+
+ - name: Upload executable as artifact
+ uses: actions/upload-artifact@v3
+ with:
+ name: StreamingCommunity
+ path: dist/StreamingCommunity.exe
+
+ - name: Create or update GitHub release
+ uses: softprops/action-gh-release@v1
+ with:
+ files: dist/StreamingCommunity.exe
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/.github/workflows/update-loc-badge.yml b/.github/workflows/update-loc-badge.yml
index ab23e14..eadfba5 100644
--- a/.github/workflows/update-loc-badge.yml
+++ b/.github/workflows/update-loc-badge.yml
@@ -18,12 +18,12 @@ jobs:
- name: Count Lines of Code
run: |
LOC=$(cloc . --json | jq '.SUM.code')
- echo "{\"schemaVersion\": 1, \"label\": \"Lines of Code\", \"message\": \"$LOC\", \"color\": \"green\"}" > Test/Util/loc-badge.json
+ echo "{\"schemaVersion\": 1, \"label\": \"Lines of Code\", \"message\": \"$LOC\", \"color\": \"green\"}" > Test/Media/loc-badge.json
- name: Commit and Push LOC Badge
run: |
git config --local user.name "GitHub Actions"
git config --local user.email "actions@github.com"
- git add Test/Util/loc-badge.json
+ git add Test/Media/loc-badge.json
git commit -m "Update lines of code badge" || echo "No changes to commit"
git push
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 231113a..d7cc0b7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,8 +23,6 @@ share/python-wheels/
# PyInstaller
*.manifest
*.spec
-setup.py
-MANIFEST.in
# Installer logs
pip-log.txt
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..e02a32e
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,3 @@
+recursive-include StreamingCommunity *
+recursive-include StreamingCommunity/Api *
+recursive-include StreamingCommunity/Lib *
\ No newline at end of file
diff --git a/README.md b/README.md
index 0381241..88c0e0a 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-
+
@@ -25,7 +25,7 @@
-
+
diff --git a/StreamingCommunity/Api/Site/cb01new/film.py b/StreamingCommunity/Api/Site/cb01new/film.py
index 249329d..392612b 100644
--- a/StreamingCommunity/Api/Site/cb01new/film.py
+++ b/StreamingCommunity/Api/Site/cb01new/film.py
@@ -37,7 +37,6 @@ def download_film(select_title: MediaItem) -> str:
console.print(f"[cyan]You can safely stop the download with [bold]Ctrl+c[bold] [cyan] \n")
# Setup api manger
- print(select_title.url)
video_source = VideoSource(select_title.url)
# Define output path
diff --git a/StreamingCommunity/Lib/Downloader/HLS/downloader.py b/StreamingCommunity/Lib/Downloader/HLS/downloader.py
index 4fbb583..e3e124c 100644
--- a/StreamingCommunity/Lib/Downloader/HLS/downloader.py
+++ b/StreamingCommunity/Lib/Downloader/HLS/downloader.py
@@ -506,8 +506,8 @@ class HLS_Downloader:
file_size = internet_manager.format_file_size(os.path.getsize(self.path_manager.output_path))
duration = print_duration_table(self.path_manager.output_path, description=False, return_string=True)
+ print()
panel_content = (
- f"[bold green]Download completed![/bold green]\n"
f"[cyan]File size: [bold red]{file_size}[/bold red]\n"
f"[cyan]Duration: [bold]{duration}[/bold]\n"
f"[cyan]Output: [bold]{os.path.abspath(self.path_manager.output_path)}[/bold]"
diff --git a/StreamingCommunity/Lib/Downloader/HLS/segments.py b/StreamingCommunity/Lib/Downloader/HLS/segments.py
index b17b453..cfc0da5 100644
--- a/StreamingCommunity/Lib/Downloader/HLS/segments.py
+++ b/StreamingCommunity/Lib/Downloader/HLS/segments.py
@@ -87,6 +87,7 @@ class M3U8_Segments:
self.info_maxRetry = 0
self.info_nRetry = 0
self.info_nFailed = 0
+
self.active_retries = 0
self.active_retries_lock = threading.Lock()
@@ -170,7 +171,8 @@ class M3U8_Segments:
client_params = {
'headers': random_headers(self.key_base_url) if hasattr(self, 'key_base_url') else {'User-Agent': get_headers()},
'timeout': MAX_TIMEOOUT,
- 'follow_redirects': True
+ 'follow_redirects': True,
+ 'http2': False
}
if THERE_IS_PROXY_LIST and index is not None and hasattr(self, 'valid_proxy'):
@@ -178,7 +180,7 @@ class M3U8_Segments:
return httpx.Client(**client_params)
- def download_segment(self, ts_url: str, index: int, progress_bar: tqdm, backoff_factor: float = 1.3) -> None:
+ def download_segment(self, ts_url: str, index: int, progress_bar: tqdm, backoff_factor: float = 1.1) -> None:
"""
Downloads a TS segment and adds it to the segment queue with retry logic.
@@ -186,7 +188,6 @@ class M3U8_Segments:
- ts_url (str): The URL of the TS segment.
- index (int): The index of the segment.
- progress_bar (tqdm): Progress counter for tracking download progress.
- - retries (int): The number of times to retry on failure (default is 3).
- backoff_factor (float): The backoff factor for exponential backoff (default is 1.5 seconds).
"""
for attempt in range(REQUEST_MAX_RETRY):
@@ -289,7 +290,7 @@ class M3U8_Segments:
buffer[index] = segment_content
except queue.Empty:
- self.current_timeout = min(MAX_TIMEOOUT, self.current_timeout * 1.25)
+ self.current_timeout = min(MAX_TIMEOOUT, self.current_timeout * 1.1)
if self.stop_event.is_set():
break
@@ -323,7 +324,7 @@ class M3U8_Segments:
# Configure workers and delay
max_workers = self._get_worker_count(type)
delay = max(PROXY_START_MIN, min(PROXY_START_MAX, 1 / (len(self.valid_proxy) + 1))) if THERE_IS_PROXY_LIST else TQDM_DELAY_WORKER
-
+
# Download segments with completion verification
with ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = []
@@ -373,7 +374,6 @@ class M3U8_Segments:
return self._generate_results(type)
-
def _get_bar_format(self, description: str) -> str:
"""
Generate platform-appropriate progress bar format.
diff --git a/StreamingCommunity/Upload/update.py b/StreamingCommunity/Upload/update.py
index 39fd94b..566c355 100644
--- a/StreamingCommunity/Upload/update.py
+++ b/StreamingCommunity/Upload/update.py
@@ -5,14 +5,17 @@ import sys
import time
+# External library
+import httpx
+
+
# Internal utilities
from .version import __version__, __author__, __title__
from StreamingCommunity.Util.console import console
+from StreamingCommunity.Util._jsonConfig import config_manager
+from StreamingCommunity.Util.headers import get_headers
-# External library
-import httpx
-
# Variable
if getattr(sys, 'frozen', False): # Modalità PyInstaller
@@ -26,8 +29,19 @@ def update():
Check for updates on GitHub and display relevant information.
"""
try:
- response_reposity = httpx.get(f"https://api.github.com/repos/{__author__}/{__title__}").json()
- response_releases = httpx.get(f"https://api.github.com/repos/{__author__}/{__title__}/releases").json()
+ response_reposity = httpx.get(
+ url=f"https://api.github.com/repos/{__author__}/{__title__}",
+ headers={'user-agent': get_headers()},
+ timeout=config_manager.get_int("REQUESTS", "timeout"),
+ follow_redirects=True
+ ).json()
+
+ response_releases = httpx.get(
+ url=f"https://api.github.com/repos/{__author__}/{__title__}/releases",
+ headers={'user-agent': get_headers()},
+ timeout=config_manager.get_int("REQUESTS", "timeout"),
+ follow_redirects=True
+ ).json()
except Exception as e:
console.print(f"[red]Error accessing GitHub API: {e}")
diff --git a/StreamingCommunity/Util/message.py b/StreamingCommunity/Util/message.py
index 804541c..96aee0a 100644
--- a/StreamingCommunity/Util/message.py
+++ b/StreamingCommunity/Util/message.py
@@ -17,12 +17,12 @@ def start_message():
"""Display a stylized start message in the console."""
msg = r'''
- __ __ _ _____ __ _
- / //_/(_)________ ____ _ __ / ___// /_________ ____ _____ ___ (_)___ ____ _
- / ,< / / ___/ __ \/ __ \ | |/_/ \__ \/ __/ ___/ _ \/ __ `/ __ `__ \/ / __ \/ __ `/
- / /| |/ / / / /_/ / / / / _> < ___/ / /_/ / / __/ /_/ / / / / / / / / / / /_/ /
-/_/ |_/_/_/ \____/_/ /_/ /_/|_| /____/\__/_/ \___/\__,_/_/ /_/ /_/_/_/ /_/\__, /
- /____/
+ ___ _____ __ _
+ / | ______________ _ ______ ______ _ __ / ___// /_________ ____ _____ ___ (_)___ ____ _
+ / /| | / ___/ ___/ __ \ | /| / / __ `/ ___/ | |/_/ \__ \/ __/ ___/ _ \/ __ `/ __ `__ \/ / __ \/ __ `/
+ / ___ |/ / / / / /_/ / |/ |/ / /_/ / / _> < ___/ / /_/ / / __/ /_/ / / / / / / / / / / /_/ /
+/_/ |_/_/ /_/ \____/|__/|__/\__,_/_/ /_/|_| /____/\__/_/ \___/\__,_/_/ /_/ /_/_/_/ /_/\__, /
+ /____/
'''.rstrip()
if CLEAN:
diff --git a/StreamingCommunity/Util/os.py b/StreamingCommunity/Util/os.py
index fb8479c..90216d0 100644
--- a/StreamingCommunity/Util/os.py
+++ b/StreamingCommunity/Util/os.py
@@ -307,24 +307,6 @@ class OsSummary:
else: # linux
return os.path.join(home, '.local', 'bin', 'binary')
- def get_executable_version(self, command: list):
- """
- Get the version of a given command-line executable.
-
- Args:
- command (list): The command to run, e.g., `['ffmpeg', '-version']`.
-
- Returns:
- str: The version string of the executable.
- """
- try:
- version_output = subprocess.check_output(command, stderr=subprocess.STDOUT).decode().split('\n')[0]
- return version_output.split(" ")[2]
-
- except (FileNotFoundError, subprocess.CalledProcessError):
- console.print(f"{command[0]} not found", style="bold red")
- sys.exit(0)
-
def check_ffmpeg_location(self, command: list) -> str:
"""
Check if a specific executable (ffmpeg or ffprobe) is located using the given command.
@@ -464,11 +446,7 @@ class OsSummary:
console.log("[red]Can't locate ffmpeg or ffprobe")
sys.exit(0)
- ffmpeg_version = self.get_executable_version([self.ffmpeg_path, '-version'])
- ffprobe_version = self.get_executable_version([self.ffprobe_path, '-version'])
-
console.print(f"[cyan]Path[white]: [red]ffmpeg [bold yellow]'{self.ffmpeg_path}'[/bold yellow][white], [red]ffprobe '[bold yellow]{self.ffprobe_path}'[/bold yellow]")
- console.print(f"[cyan]Exe versions[white]: [bold red]ffmpeg {ffmpeg_version}, ffprobe {ffprobe_version}[/bold red]")
# Handle requirements.txt
if not getattr(sys, 'frozen', False):
diff --git a/Test/Media/62809003.ico b/Test/Media/62809003.ico
new file mode 100644
index 0000000000000000000000000000000000000000..ff16d28d891275f2a8d05aac771ad2b040a7da04
GIT binary patch
literal 4474
zcmeHLX*ksH*Z-23k}Rc#hWceGYxQHwHWMmkOUaUL64_=@VlbAGH3_YheW#ci!x$km
zg=oP@gUnz`_I;ZfW{i3C;(tAFpBK;b?m72$U-voZesMnMzRq>7^SJ>)XnXw?A>b(B
zDGdMzw)JEiYcq-6a=W)xi7S^cT>pFfcY{Q?50{_{ufJAcko65AYEftw07xrbxnO)F
zj6Ofi@#q^L>{#9s&k{N&We+l#Gup@AtNvV82I4LPdJ=EcYI7cGccVnB`cbi(Po2Gg
zUpekAmOdFy_aD(`5K!Y
zz)&^_hyj4}z&2(;3IIR=AOZlweBo_6#jLfD-P|%@c@jbs-$APe8PT^E$skgTJ&rsR~5?9@Qcv!Q}
zG>Zj3O)q^HC)QJWF%SrMtg%RRF1uRJa6s`Kg#m;7A?ncVK&?mBQ|jgCeunFMF=d
z2DX~m_+iVxfm>Tg+WFM94{Bh(s?N@b)O;UfU}t3EDIX@`IZM1aMY=W!`7v#nwDMcE>aO5g{v{oyTUknt
z&!ulxw9TIfh(T|_`i|K>ae`{&@{%&HFx<3U#_y+Tc~{jywMVf?>R#^SL*vB{UV1BX
zd`;1dP)(@Z6iu_WUE_28$x_7KY$+f#yC+6=_iFuOjlvEw-HNAgpK`#u?V?w+{C07M
zLtCHp+%PuSd%xa}{w&M3OCfyoNvu~}rygmh@IGl~Pk@;4FRkKSKy%_veL#Lc!8n4y
zJEp2d*$vi%4V<_N@so@_RnueghiG>P>Js?nWGYI@{3;X~&Ion>*xmf@6DX#sN+fJ7
zCwzogxqOxwYVDiphv+u)=Zy$x2jUYs&kLo8Wj|{<&FG3IYaRyNt@V*y4F-C8fHb%C
z<+GyiICRKF(%YYxMX0oNmrS~5!e^6s$tKIVre%GH1|MITVOfVV8TIU_r!cgn1DZ^
z8`&i=8`r2V?XY$p!R^S%14U`=lY_gnUrNG!Wi#4)S!F~tSqrg^8&^j8SucrDNY
zj|o&RS0E%?STsW@Zn}Ai?MCRE?4moQxi(XGtu3s7)Ut$j%f_2x3VkA5LC$t-q}5%Y
z&@#Kx_oOd^`_O}SDEo-XG1Wb@ebu!o8H1f6+3$nH+}HE*QMWWFe0f(>o7Ot@F>%IP-ve}D(%4HqCbl5ky
z=|aADEX7SeKl;0QT0SB2fatE6{@zst0ohSWAw(@=CXzykFhyP~rpLQr2h)D6Hbe7`x5l6W;AK;LsL0Jg!N(^+<)dB+c>OA?WNc>QuNm)?*+Tzwl%2
zAC%!aJ&}aOtz^#d!Cm6uV*v}~=y%Piqd~1tT#d-+K-MUsJ+k=I#bN7Np#&Zxl2}mp
zm^S5<7*HAWlif0FZ&R0_XaTfgsCXDR#N9e-?wepGaXj^1p^=ZzE4n0}%q>h8xltxB
zFH^Z(2{LQ0L?gPG9uLl(ig?CZP#d&Mu2!5#7H#d4o8NxIsJxM(sHkB#qsB|8p)Z#^
z@@N&)&(IO6uXJuFry8!g*vI>RcqX++$3^()!j7YX1I7jl==0dl$^n0Ks=ktrQmUw*
zI9gcqF$;98M+J>^VE#DeBo_PVYEIoXz17xJO&*?w+NfvRDtgoO&BpFsuv9s7s-fTO
z;tpMe#dQwTqvsZ5>np>aHL)1!UUQA{lu$EP*y_J}Uz?E^3L|X&sX>?`+3o%$_ET}o
z9iW)7fXyr96AmHcQQEj`;RxGrcV;0pI`3gLK41|WP9{z2bEc*xN-fqa@@^ayoj!fH
zI$e&~f>VQ8?OeMb1$PeOM&%0qT${Ty`{H|ZxNXeTXER2Ee%TO>cRlRQnQOKWa#p}~
zKU7j}Aci5y+k?$0FFvn(Fn@DZK%bLv&URJLpKFfJq}Of?xJuq~$p{qqZdK_=`|J9R
z)NPW8VDVG<>j#P=CsdF7=}~WBZY$vmlq03#?_mT
zm2n8Jd{YXrB>TBk6&dI_iP#;p?6T0JoqTX~zglc9L>A}r?&G#hoU;m*D%vEzg
zCYTcUEqSCj6yEuW&PjrDzm|(QRnbnAjjqT#A2GoeJi7)6NhQ$=`tvDMtG5Eht#bpTegEB=lV>sboXY5p>(Em@
z540`b8+w$9a~#j6AP9iXtBT8I3w+;KMkx0OXMNz_AfbYkn2en0lJ4&F&hn=t^3Jy9
ztjsF_ew#(lFG*(zPYZt*nrM~n
zn*`gabtSjF`lqCaLR=o@d(l=sxuO0voq!sfw?uFjq!ODlE^7JIR|Z~*LE#r?E#
z3ZsqBy^rW~6;E%peAPWO8yc*qox7K&E4bmKgXAJ9a|6GUZQuVaYe=`cc;WDC{y)VJ
zr(P(tuNfDk6Ur>()^c?G-fV2*Ax4jpYjs*TNy_g@7Hq}i04Qc%B4!()A)sFtieSHO
zT=1C0Gg;S}jzF8%@6ujZP2qOAS5Wp5!?ylJsh-$;l(3GKO)J&y#@v0MmmBTYqjhaO
zVH#HI1}Ll)9$bFgvpW)Ri2TZ*x!28b8dq+i@1_mVyM9J*yw#*f#J6uZj76;&>xMVG
ztrIl5Zi>(p8qtn+B5$Qt%{a8a?j*{R
zv)*zAyxs%3Gt+i&l~36(PU`V%#u?n|{A7TrU=YM1u5i1sp7
zX5T`(Mi9=$TRtyxWF<7{#6#fWS?~`m)g_kl%9x?2s^6F9Ii)(GArh?XF(nS3J9J0O%XaR-XJU$yA4;A8o*dqy(iO
z-a0V^Ti)cO6(fy=NuC{{{21A~V|ofX%s?m=L`C!gI^Mj6jCi=Y0Sr_!iBsPs`L-Q?
zcxYb3M*v40A$WY(pLwqr@An;N`Zw<_-|yzU6@6L_d)fQADm$S6P|?8_n=3fAb?fNW
zQ1$3vliz(W1T}|Y9%*uSSgw|0pY(xC~dE-RooaEmgMCS(PE-SVLN5M^sLc2
zmP;MKytrkSYSg7G1d8cDjzu_Vzth|NayI&tVi%$ghD*7t(of#FSVX;77mITzN1KIg
zG&-fB_C;5ToU;$8%Hn0bKjCeW7?YQTG6|O6pKDEHyhJn>@Bj`Z`SpTw+8o7o!n&|cK!o64c<5}7Ni62`F=}c@>@52EurR(`oQ43
zArnQF%3#M&I^5R>B-P!*)jOjs{Ir*rJvfzdhG>hWu;@xHyQ4EMn685uR&kelciw7B
zx|ggLYgX9W(Pb_vDp;#|$F{0h;su{y}cVrA!k8
z=`vmY6Qwp`zqAFDyv-)%BmTvaepBFI-r-TpnV@sXQ?4nwEkBmn`oCuo#_!hU&Mh
zGiIrTr?r#eR6JsJdMOPh9{ku*;uj9Rqub}&6JZ;prUTj@izf@@Fj3gW%79}K-5xUK
zlIS?K8JWU9!VagT0mb9eK