🚸 Select download path

This commit is contained in:
zhbaor 2023-03-04 18:18:39 +08:00
parent afc9c112cb
commit 3b5a998aaa
7 changed files with 303 additions and 18 deletions

View file

@ -1,12 +1,23 @@
from bottle import request, response, Bottle, HTTPResponse
from bottle import request, response, Bottle, static_file
from manager import Manager
from json import dumps
from pathlib import Path
from tkinter import filedialog as fd
manager = Manager()
app = Bottle()
@app.get("/")
def frontend():
return static_file("index.html", root="frontend/dist")
@app.get("/<filepath:path>")
def frontend(filepath):
return static_file(filepath, root="frontend/dist")
@app.post("/video")
def add_videos():
nvlist = request.json["nvlist"].split()
@ -20,8 +31,14 @@ def get_progress():
return dumps(manager.get_progress())
@app.post("/download")
@app.get("/download")
def download():
parent_dir = Path(request.json["parent_dir"])
manager.download(parent_dir)
manager.download()
return "OK"
@app.get("/path")
def get_path():
path = fd.askdirectory()
manager.path = path
return path

View file

@ -57,14 +57,12 @@ const progress_info = computed(() => {
});
function start_download() {
axios.post("http://localhost:8000/download", {
parent_dir: "/home/zhao/Desktop/tmp",
});
axios.get("/download");
}
onMounted(() => {
setInterval(() => {
axios.get("http://localhost:8000/progress").then((resp) => {
axios.get("/progress").then((resp) => {
state_list.value = resp.data;
});
}, 200);

View file

@ -8,18 +8,38 @@ const nvlist = ref("");
const axios = inject("axios");
const path = ref("");
onMounted(() => {
input.value.focus();
});
function sendNVList() {
axios.post("http://localhost:8000/video", { nvlist: nvlist.value });
axios.post("/video", { nvlist: nvlist.value });
emit("change-stage");
}
function get_path() {
axios.get("/path").then(({ data }) => {
path.value = data;
input.value.focus();
});
}
</script>
<template>
<div class="container-fluid vh-100 bg-body-secondary d-flex flex-column p-3">
<div class="mb-3 row g-2">
<div class="col-auto">
<label class="col-form-label">Download Path:</label>
</div>
<div class="col">
<input class="form-control" type="text" v-model="path" />
</div>
<div class="col-auto">
<button class="btn btn-primary" @click="get_path">Choose</button>
</div>
</div>
<textarea
ref="input"
v-model="nvlist"

10
main.py Executable file
View file

@ -0,0 +1,10 @@
#!/usr/bin/env python3
import webview
from backend import app
if __name__ == "__main__":
# Create a standard webview window
window = webview.create_window(
"badl - BiliBili Audio Downloader", app, width=500, height=700
)
webview.start()

View file

@ -11,12 +11,13 @@ class Manager:
self.video_list: list[Video] = []
self.bvid_set = set()
self.queue = SimpleQueue()
self.path = ""
def get_info_worker(self):
while not self.queue.empty():
video: Video = self.queue.get()
video.get_info()
sleep(5)
sleep(1)
def add_videos_by_number(self, video_numbers: list[str]):
for video_number in video_numbers:
@ -34,12 +35,16 @@ class Manager:
while not self.queue.empty():
video: Video = self.queue.get()
filename = sanitize(video.title) + ".m4a"
while True:
try:
video.download(parent_dir / filename)
sleep(5)
break
except:
sleep(1)
sleep(1)
def download(self, parent_dir: str | Path = Path(".")):
if isinstance(parent_dir, str):
parent_dir = Path(parent_dir)
def download(self):
parent_dir = Path(self.path)
for video in self.video_list:
print(video)
self.queue.put(video)

239
poetry.lock generated
View file

@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry and should not be changed by hand.
# This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand.
[[package]]
name = "aiohttp"
@ -1005,7 +1005,7 @@ reference = "mirrors"
name = "packaging"
version = "23.0"
description = "Core utilities for Python packages"
category = "dev"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
@ -1152,6 +1152,22 @@ type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "mirrors"
[[package]]
name = "proxy-tools"
version = "0.1.0"
description = "Proxy Implementation"
category = "main"
optional = false
python-versions = "*"
files = [
{file = "proxy_tools-0.1.0.tar.gz", hash = "sha256:ccb3751f529c047e2d8a58440d86b205303cf0fe8146f784d1cbcd94f0a28010"},
]
[package.source]
type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "mirrors"
[[package]]
name = "pyasn1"
version = "0.4.8"
@ -1169,6 +1185,138 @@ type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "mirrors"
[[package]]
name = "pycairo"
version = "1.23.0"
description = "Python interface for cairo"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "pycairo-1.23.0-cp310-cp310-win32.whl", hash = "sha256:564601e5f528531c6caec1c0177c3d0709081e1a2a5cccc13561f715080ae535"},
{file = "pycairo-1.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:e7cde633986435d87a86b6118b7b6109c384266fd719ef959883e2729f6eafae"},
{file = "pycairo-1.23.0-cp311-cp311-win32.whl", hash = "sha256:3a71f758e461180d241e62ef52e85499c843bd2660fd6d87cec99c9833792bfa"},
{file = "pycairo-1.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:2dec5378133778961993fb59d66df16070e03f4d491b67eb695ca9ad7a696008"},
{file = "pycairo-1.23.0-cp37-cp37m-win32.whl", hash = "sha256:d6bacff15d688ed135b4567965a4b664d9fb8de7417a7865bb138ad612043c9f"},
{file = "pycairo-1.23.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ec305fc7f2f0299df78aadec0eaf6eb9accb90eda242b5d3492544d3f2b28027"},
{file = "pycairo-1.23.0-cp38-cp38-win32.whl", hash = "sha256:1a6d8e0f353062ad92954784e33dbbaf66c880c9c30e947996c542ed9748aaaf"},
{file = "pycairo-1.23.0-cp38-cp38-win_amd64.whl", hash = "sha256:82e335774a17870bc038e0c2fb106c1e5e7ad0c764662023886dfcfce5bb5a52"},
{file = "pycairo-1.23.0-cp39-cp39-win32.whl", hash = "sha256:a4b1f525bbdf637c40f4d91378de36c01ec2b7f8ecc585b700a079b9ff83298e"},
{file = "pycairo-1.23.0-cp39-cp39-win_amd64.whl", hash = "sha256:87efd62a7b7afad9a0a420f05b6008742a6cfc59077697be65afe8dc73ae15ad"},
{file = "pycairo-1.23.0.tar.gz", hash = "sha256:9b61ac818723adc04367301317eb2e814a83522f07bbd1f409af0dada463c44c"},
]
[package.source]
type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "mirrors"
[[package]]
name = "pycparser"
version = "2.21"
description = "C parser in Python"
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
files = [
{file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
{file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
]
[package.source]
type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "mirrors"
[[package]]
name = "pygobject"
version = "3.42.2"
description = "Python bindings for GObject Introspection"
category = "main"
optional = false
python-versions = "^3.6"
files = [
{file = "PyGObject-3.42.2.tar.gz", hash = "sha256:21524cef33100c8fd59dc135948b703d79d303e368ce71fa60521cc971cd8aa7"},
]
[package.dependencies]
pycairo = ">=1.16,<2.0"
[package.source]
type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "mirrors"
[[package]]
name = "pyobjc-core"
version = "9.0.1"
description = "Python<->ObjC Interoperability Module"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "pyobjc-core-9.0.1.tar.gz", hash = "sha256:5ce1510bb0bdff527c597079a42b2e13a19b7592e76850be7960a2775b59c929"},
{file = "pyobjc_core-9.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b614406d46175b1438a9596b664bf61952323116704d19bc1dea68052a0aad98"},
{file = "pyobjc_core-9.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bd397e729f6271c694fb70df8f5d3d3c9b2f2b8ac02fbbdd1757ca96027b94bb"},
{file = "pyobjc_core-9.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d919934eaa6d1cf1505ff447a5c2312be4c5651efcb694eb9f59e86f5bd25e6b"},
{file = "pyobjc_core-9.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:67d67ca8b164f38ceacce28a18025845c3ec69613f3301935d4d2c4ceb22e3fd"},
{file = "pyobjc_core-9.0.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:39d11d71f6161ac0bd93cffc8ea210bb0178b56d16a7408bf74283d6ecfa7430"},
{file = "pyobjc_core-9.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25be1c4d530e473ed98b15063b8d6844f0733c98914de6f09fe1f7652b772bbc"},
]
[package.source]
type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "mirrors"
[[package]]
name = "pyobjc-framework-cocoa"
version = "9.0.1"
description = "Wrappers for the Cocoa frameworks on macOS"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "pyobjc-framework-Cocoa-9.0.1.tar.gz", hash = "sha256:a8b53b3426f94307a58e2f8214dc1094c19afa9dcb96f21be12f937d968b2df3"},
{file = "pyobjc_framework_Cocoa-9.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5f94b0f92a62b781e633e58f09bcaded63d612f9b1e15202f5f372ea59e4aebd"},
{file = "pyobjc_framework_Cocoa-9.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f062c3bb5cc89902e6d164aa9a66ffc03638645dd5f0468b6f525ac997c86e51"},
{file = "pyobjc_framework_Cocoa-9.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0b374c0a9d32ba4fc5610ab2741cb05a005f1dfb82a47dbf2dbb2b3a34b73ce5"},
{file = "pyobjc_framework_Cocoa-9.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8928080cebbce91ac139e460d3dfc94c7cb6935be032dcae9c0a51b247f9c2d9"},
{file = "pyobjc_framework_Cocoa-9.0.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:9d2bd86a0a98d906f762f5dc59f2fc67cce32ae9633b02ff59ac8c8a33dd862d"},
{file = "pyobjc_framework_Cocoa-9.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2a41053cbcee30e1e8914efa749c50b70bf782527d5938f2bc2a6393740969ce"},
]
[package.dependencies]
pyobjc-core = ">=9.0.1"
[package.source]
type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "mirrors"
[[package]]
name = "pyobjc-framework-webkit"
version = "9.0.1"
description = "Wrappers for the framework WebKit on macOS"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "pyobjc-framework-WebKit-9.0.1.tar.gz", hash = "sha256:82ed0cb273012b48f7489072d6e00579f42d54bc4543471c262db3e5c4bb9e87"},
{file = "pyobjc_framework_WebKit-9.0.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:037082f72fa1f1d87889fdc172726c3381769de24ca5207d596f3925df9b25f0"},
{file = "pyobjc_framework_WebKit-9.0.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:952685b820545036833ed737600d32c344916a83b2af4e04acb4b618aaac9431"},
{file = "pyobjc_framework_WebKit-9.0.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:28a7859401b5af7c47e17612b4b3baca6669e76f974f6f6bfe5e93921a00adec"},
]
[package.dependencies]
pyobjc-core = ">=9.0.1"
pyobjc-framework-Cocoa = ">=9.0.1"
[package.source]
type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "mirrors"
[[package]]
name = "pypng"
version = "0.20220715.0"
@ -1186,6 +1334,35 @@ type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "mirrors"
[[package]]
name = "pythonnet"
version = "2.5.2"
description = ".Net and Mono integration for Python"
category = "main"
optional = false
python-versions = "*"
files = [
{file = "pythonnet-2.5.2-cp27-cp27m-win32.whl", hash = "sha256:d519bbc7b1cd3999651efc594d91cb67c46d1d8466dad3d83b578102e58d05bd"},
{file = "pythonnet-2.5.2-cp27-cp27m-win_amd64.whl", hash = "sha256:c02f53d0e61b202cddf3198fac9553d5b4ee0ea0cc4fe658c2ed69ab24def276"},
{file = "pythonnet-2.5.2-cp35-cp35m-win32.whl", hash = "sha256:840bdef89b378663d73f74f18895b6d8630d1f5671457a1db5ffb68179d85582"},
{file = "pythonnet-2.5.2-cp35-cp35m-win_amd64.whl", hash = "sha256:d8e5b27de1e2cfb69b88782ac5cdf605b1a73598a85d86570e46961126628dbb"},
{file = "pythonnet-2.5.2-cp36-cp36m-win32.whl", hash = "sha256:62645c29840c4a877d66e047f3e065b2e5a1a66431a99bce8d42a5af3a093ee1"},
{file = "pythonnet-2.5.2-cp36-cp36m-win_amd64.whl", hash = "sha256:058e536062d1585d07ec5f2cf16aefcfc8eb8179faa90e5db0063d358469d025"},
{file = "pythonnet-2.5.2-cp37-cp37m-win32.whl", hash = "sha256:cc77fc63e2afb0a80199ab44ced4fdfb78c19d8030063c345c80740d15380dd9"},
{file = "pythonnet-2.5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:80c8f5c9bd10440a73eb6aedbbacb2f3dd7701b474816f5ef7636f529d838d38"},
{file = "pythonnet-2.5.2-cp38-cp38-win32.whl", hash = "sha256:41a607b7304e9efc6d4d8db438d6018a17c6637e8b8998848ff5c2a7a1b4687c"},
{file = "pythonnet-2.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:00a4fed9fc05b4efbe8947c79dc0799cffbca4c89e3e068e70b6618f20c906f2"},
{file = "pythonnet-2.5.2.tar.gz", hash = "sha256:b7287480a1f6ae4b6fc80d775446d8af00e051ca1646b6cc3d32c5d3a461ede3"},
]
[package.dependencies]
pycparser = "*"
[package.source]
type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "mirrors"
[[package]]
name = "pytz"
version = "2022.7.1"
@ -1223,6 +1400,39 @@ type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "mirrors"
[[package]]
name = "pywebview"
version = "4.0.2"
description = "Build GUI for your Python program with JavaScript, HTML, and CSS."
category = "main"
optional = false
python-versions = "*"
files = [
{file = "pywebview-4.0.2-py3-none-any.whl", hash = "sha256:c94065f16978badf29d80043d7c0c86c99793b199c46cfe3f1d15271908e2670"},
{file = "pywebview-4.0.2.tar.gz", hash = "sha256:59383610af1326e1b52b06d58262ce7cc54818e644aded9409751b81efb4857a"},
]
[package.dependencies]
bottle = "*"
proxy-tools = "*"
pyobjc-core = {version = "*", markers = "sys_platform == \"darwin\""}
pyobjc-framework-Cocoa = {version = "*", markers = "sys_platform == \"darwin\""}
pyobjc-framework-WebKit = {version = "*", markers = "sys_platform == \"darwin\""}
pythonnet = {version = "*", markers = "sys_platform == \"win32\""}
QtPy = {version = "*", markers = "sys_platform == \"openbsd6\""}
[package.extras]
cef = ["cefpython3"]
gtk = ["PyGObject"]
pyside2 = ["PySide2", "QtPy"]
pyside6 = ["PySide6", "QtPy"]
qt = ["PyQt5", "QtPy", "pyqtwebengine"]
[package.source]
type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "mirrors"
[[package]]
name = "pyyaml"
version = "6.0"
@ -1307,6 +1517,29 @@ type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "mirrors"
[[package]]
name = "qtpy"
version = "2.3.0"
description = "Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6)."
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "QtPy-2.3.0-py3-none-any.whl", hash = "sha256:8d6d544fc20facd27360ea189592e6135c614785f0dec0b4f083289de6beb408"},
{file = "QtPy-2.3.0.tar.gz", hash = "sha256:0603c9c83ccc035a4717a12908bf6bc6cb22509827ea2ec0e94c2da7c9ed57c5"},
]
[package.dependencies]
packaging = "*"
[package.extras]
test = ["pytest (>=6,!=7.0.0,!=7.0.1)", "pytest-cov (>=3.0.0)", "pytest-qt"]
[package.source]
type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "mirrors"
[[package]]
name = "requests"
version = "2.28.2"
@ -1670,4 +1903,4 @@ reference = "mirrors"
[metadata]
lock-version = "2.0"
python-versions = "^3.11"
content-hash = "355be7949f7315d306dda590f37dc6c75b8c29130154e934c9b50285807faab5"
content-hash = "1d4e00a5f792bb7ab25726a3edc04cc9e398e71c7f9b9ce7a896ba3f5603842c"

View file

@ -10,6 +10,8 @@ python = "^3.11"
bilibili-api-python = "^15.1.0"
sanitize-filename = "^1.2.0"
bottle = "^0.12.23"
pywebview = "^4.0.2"
pygobject = "^3.42.2"
[tool.poetry.group.dev.dependencies]
black = "^23.1.0"