bugfix
This commit is contained in:
parent
7ba58a135c
commit
5630669c17
57
README.md
57
README.md
@ -0,0 +1,57 @@
|
||||
# DownloadMgr
|
||||
a web ui for aria2
|
||||
|
||||
## Dependent
|
||||
* [apppublic](https://git.opencomputing.cn/yumoqing/apppublic)
|
||||
* [sqlor](https://git.opencomputing.cn/yumoqing/sqlor)
|
||||
* [ahserver](https://git.opencomputing.cn/yumoqing/ahserver)
|
||||
* [appbase](https://git.opencomputing.cn/yumoqing/appbase)
|
||||
* [rbac](https://git.opencomputing.cn/yumoqing/rbac)
|
||||
* [uapi](https://git.opencomputing.cn/yumoqing/uapi)
|
||||
* [bricks](https://git.opencomputing.cn/yumoqing/bricks)
|
||||
|
||||
also depentent on
|
||||
* [xls2ddl](https://git.opencomputing.cn/yumoqing/xls2ddl)
|
||||
use it to translates database definintion excel file to database ddl sql file
|
||||
and translate table information to CRUD UI for bricks.
|
||||
|
||||
## Install
|
||||
```
|
||||
pip install git+https://git.opencomputing.cn/yumoqing/downloadmgr
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
in your web app
|
||||
```
|
||||
from downloadmgr.init import load_downloadmgr
|
||||
# call the load_downloadmgr() before the web server start listening
|
||||
|
||||
```
|
||||
|
||||
## examples:
|
||||
```
|
||||
from ahserver.webapp import webapp
|
||||
from ahserver.serverenv import ServerEnv
|
||||
from appbase.init import load_appbase
|
||||
from rbac.init import load_rbac
|
||||
from downloadmgr.init import load_downloadmgr
|
||||
|
||||
def get_module_dbanme(modulename):
|
||||
return 'mydb' # assume all modules use same database 'mydb'
|
||||
|
||||
def init():
|
||||
env = ServerEnv()
|
||||
env.get_module_dbname = get_module_dbname
|
||||
load_appbase()
|
||||
load_rbac()
|
||||
load_downloadmgr()
|
||||
|
||||
if __name__ == '__main__':
|
||||
webapp(init)
|
||||
```
|
||||
|
||||
## database table
|
||||
downloadmgr use a table named "download", it record the user download infomation
|
||||
|
||||
|
||||
BIN
downloadmgr/.download.py.swp
Normal file
BIN
downloadmgr/.download.py.swp
Normal file
Binary file not shown.
0
downloadmgr/__init__.py
Normal file
0
downloadmgr/__init__.py
Normal file
106
downloadmgr/download.py
Normal file
106
downloadmgr/download.py
Normal file
@ -0,0 +1,106 @@
|
||||
import time
|
||||
import json
|
||||
from appPublic.dictObject import DictObject
|
||||
from sqlor.dbpools import DBPools
|
||||
from ahserver.serverenv import ServerEnv, get_serverenv
|
||||
|
||||
class DownloadMgr:
|
||||
def __init__(self,request):
|
||||
self.request = request
|
||||
self.env = request['run_ns']
|
||||
self.uapi = self.env.UAPI(request, **self.env)
|
||||
self.uappid = 'downloader'
|
||||
|
||||
async def save_finished_task(self, taskid):
|
||||
db = DBPools()
|
||||
userid = await self.env.get_user()
|
||||
dbname = self.env.get_module_dbname('downloadmgr')
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
ns = {
|
||||
"id": taskid,
|
||||
"finish_time": time.time(),
|
||||
}
|
||||
await sor.U('download', ns)
|
||||
|
||||
async def save_task(self, taskid):
|
||||
db = DBPools()
|
||||
userid = await self.env.get_user()
|
||||
dbname = self.env.get_module_dbname('downloadmgr')
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
ns = {
|
||||
"id": taskid,
|
||||
"userid": userid,
|
||||
"start_time": time.time()
|
||||
}
|
||||
await sor.C('download', ns)
|
||||
|
||||
async def get_user_tasks(self):
|
||||
db = DBPools()
|
||||
userid = await self.env.get_user()
|
||||
dbname = self.env.get_module_dbname('downloadmgr')
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
sql = """select * from download
|
||||
where userid=${userid}$
|
||||
and finish_time is NULL"""
|
||||
ns = {
|
||||
'userid': userid
|
||||
}
|
||||
recs = await sor.sqlExe(sql, ns)
|
||||
return recs
|
||||
return []
|
||||
|
||||
async def uapicall(self, apiname, ns):
|
||||
userid = await self.env.get_user()
|
||||
x = self.uapi.call(self.uappname,
|
||||
apiname,
|
||||
userid,
|
||||
ns)
|
||||
d = json.loads(x.decode('utf-8')
|
||||
return DictObject(**d)
|
||||
|
||||
async download(self, url):
|
||||
try:
|
||||
d = await self.uapicall('addUrl', {'url':url})
|
||||
await self.save_task(d.result)
|
||||
return d.result
|
||||
except Exception as e:
|
||||
self.env.exception(f'{url=},{e}\n{format_exc()}')
|
||||
raise e
|
||||
|
||||
async def delete_file(self, filename):
|
||||
pass
|
||||
|
||||
async remove_task(self, taskid):
|
||||
await self.uapicall('remove-task', {'taskid':taskid})
|
||||
return True
|
||||
|
||||
async def file_downloaded(self, filename):
|
||||
pass
|
||||
|
||||
async def check_download_finished(self, status):
|
||||
s = status
|
||||
if s.totalLength == s.completedLength:
|
||||
await self.save_finished_task(s.gid)
|
||||
await self.file_downloaded(s.info.name)
|
||||
await self.remove_task(s.gid)
|
||||
await self.delete_file(s.info.name)
|
||||
|
||||
async def get_task_status(self, tid):
|
||||
d = await self.uapicall('get_task_status', {'taskid':tid})
|
||||
await self.check_downlaod_finished(d.result)
|
||||
rzt = d.result
|
||||
rzt.filename = rzt.info.name
|
||||
return rzt
|
||||
|
||||
async get_tasks_status(self):
|
||||
recs = await self.get_user_tasks(userid)
|
||||
urls = [r.id for r in recs]
|
||||
try:
|
||||
d = await self.uapicall('get_task_status', {'taskid':tid})
|
||||
await self.check_downlaod_finished(d.result)
|
||||
return d.result
|
||||
except Exception as e:
|
||||
self.env.exception(f'{e=}\n{format_exc()}')
|
||||
raise e
|
||||
|
||||
|
||||
6
downloadmgr/init.py
Normal file
6
downloadmgr/init.py
Normal file
@ -0,0 +1,6 @@
|
||||
from downloadmgr.download import DownloadMgr
|
||||
from ahserver.serverenv import ServerEnv
|
||||
|
||||
def load_downloadmgr():
|
||||
env = ServerEnv()
|
||||
env.DownloadMgr = DownloadMgr
|
||||
BIN
models/download.xlsx
Normal file
BIN
models/download.xlsx
Normal file
Binary file not shown.
4
pyproject.toml
Normal file
4
pyproject.toml
Normal file
@ -0,0 +1,4 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=61", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
16
setup.cfg
Normal file
16
setup.cfg
Normal file
@ -0,0 +1,16 @@
|
||||
[metadata]
|
||||
name=downloadmgr
|
||||
version = 0.0.1
|
||||
description = a web ui for aria2
|
||||
author = "yu moqing"
|
||||
author_email = "yumoqing@gmail.com"
|
||||
readme = "README.md"
|
||||
license = "MIT"
|
||||
[options]
|
||||
packages = find:
|
||||
requires_python = ">=3.8"
|
||||
install_requires =
|
||||
apppublic
|
||||
sqlor
|
||||
ahserver
|
||||
|
||||
26
wwwroot/add_new_download.ui
Normal file
26
wwwroot/add_new_download.ui
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"widgettype":"Form",
|
||||
"options":{
|
||||
"width":"100%",
|
||||
"height":"100%",
|
||||
"fields":[
|
||||
{
|
||||
"name":"url",
|
||||
"label":"下载地址",
|
||||
"uitype":"text",
|
||||
"required":true
|
||||
}
|
||||
]
|
||||
},
|
||||
"binds":[
|
||||
{
|
||||
"wid":"self",
|
||||
"event":"submit",
|
||||
"actiontype":"urlwidget",
|
||||
"target":"self",
|
||||
"options":{
|
||||
"url":"{{entire_url('./download_url.dspy')}}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
8
wwwroot/download_url.dspy
Normal file
8
wwwroot/download_url.dspy
Normal file
@ -0,0 +1,8 @@
|
||||
#
|
||||
dmgr = DownloadMgr(request)
|
||||
try:
|
||||
x = await dmgr.download(params_kw.url)
|
||||
return UiMessage(title='download', message=f'download submited')
|
||||
except Exception as e:
|
||||
exception(f'{params_kw.url} download failed,{e=}\n{format_exc()}')
|
||||
return UiError(title='download error', message=f'{params_kw.url} download failed,{e=}')
|
||||
22
wwwroot/list_downloading.ui
Normal file
22
wwwroot/list_downloading.ui
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"widgettype":"DynamicColumn",
|
||||
"options":{
|
||||
"width":"100%",
|
||||
"height":"100%"
|
||||
},
|
||||
"subwidgets":[
|
||||
{% set dmgr = DownloadMgr(request) %}
|
||||
{for task in dmgr.get_user_tasks() %}
|
||||
{
|
||||
"widgettype":"urlwidget",
|
||||
"options":{
|
||||
"params":{
|
||||
"taskid":"{{task.id}}"
|
||||
},
|
||||
"url":"{{entire_url('task_info.ui')}}"
|
||||
}
|
||||
}
|
||||
{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
]
|
||||
}
|
||||
26
wwwroot/task_info.ui
Normal file
26
wwwroot/task_info.ui
Normal file
@ -0,0 +1,26 @@
|
||||
{% set dmgr=DownloadMgr(request) %}
|
||||
{% set status=dmgr.get_task_status(params_kw.taskid) %}
|
||||
{
|
||||
"widgettype":"VBox",
|
||||
"options":{
|
||||
"cwidth":16,
|
||||
"cheight":14,
|
||||
"css":"card"
|
||||
},
|
||||
"subwidgets":[
|
||||
{
|
||||
"widgettype":"Title3",
|
||||
"options:{
|
||||
"text":"{{status.filename}}",
|
||||
"wrap":true,
|
||||
"halign":"left"
|
||||
}
|
||||
},
|
||||
{
|
||||
"widgettype":"Text",
|
||||
"options":{
|
||||
"text":"{{status.completedLength}}/{{status.totalLength}}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user