feat: 补齐桌面端下载播放,并将窗口改为夜间主题和应用图标
This commit is contained in:
@@ -89,6 +89,64 @@ class HttpClient:
|
||||
raise RuntimeError("不是图片")
|
||||
return response.content, media
|
||||
|
||||
def download_file(self, url: str, dest, on_chunk=None, stop=None) -> int:
|
||||
from pathlib import Path
|
||||
|
||||
target = Path(dest)
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
temporary = target.with_name(target.name + ".part")
|
||||
last_error = None
|
||||
for _attempt in range(3):
|
||||
if stop and stop():
|
||||
raise RuntimeError("已取消")
|
||||
try:
|
||||
with self._client_locked().stream("GET", url, headers={"User-Agent": "RaptDrama"}) as response:
|
||||
response.raise_for_status()
|
||||
size = 0
|
||||
with temporary.open("wb") as handle:
|
||||
for chunk in response.iter_bytes(64 * 1024):
|
||||
if stop and stop():
|
||||
raise RuntimeError("已取消")
|
||||
if not chunk:
|
||||
continue
|
||||
handle.write(chunk)
|
||||
size += len(chunk)
|
||||
if on_chunk:
|
||||
on_chunk(len(chunk))
|
||||
temporary.replace(target)
|
||||
return size
|
||||
except RuntimeError:
|
||||
temporary.unlink(missing_ok=True)
|
||||
raise
|
||||
except (httpx.HTTPError, TimeoutError, OSError) as exc:
|
||||
last_error = exc
|
||||
temporary.unlink(missing_ok=True)
|
||||
time.sleep(0.4)
|
||||
raise RuntimeError(f"下载失败: {last_error}")
|
||||
|
||||
def read_text(self, url: str) -> str:
|
||||
last_error = None
|
||||
for _attempt in range(3):
|
||||
try:
|
||||
response = self._client_locked().get(url, headers={"User-Agent": "RaptDrama"})
|
||||
response.raise_for_status()
|
||||
return response.text
|
||||
except (httpx.HTTPError, TimeoutError, OSError) as exc:
|
||||
last_error = exc
|
||||
time.sleep(0.4)
|
||||
raise RuntimeError(f"下载失败: {last_error}")
|
||||
|
||||
def open_stream(self, url: str) -> httpx.Response:
|
||||
client = self._client_locked()
|
||||
request = client.build_request("GET", url, headers={"User-Agent": "RaptDrama"})
|
||||
response = client.send(request, stream=True)
|
||||
try:
|
||||
response.raise_for_status()
|
||||
except Exception:
|
||||
response.close()
|
||||
raise
|
||||
return response
|
||||
|
||||
def _close_locked(self) -> None:
|
||||
if self._client is not None:
|
||||
self._client.close()
|
||||
|
||||
Reference in New Issue
Block a user