Skip to content

Commit

Permalink
Lot of updates here in this new version.
Browse files Browse the repository at this point in the history
- Refactor entire architecture.
- Add **about** button.
- Can set independent youtube-dl options for each task.
- Some UI improvement.
  • Loading branch information
d0u9 committed Nov 18, 2017
2 parents 6d85e56 + 8f86b9e commit 3cce4ac
Show file tree
Hide file tree
Showing 23 changed files with 2,142 additions and 638 deletions.
17 changes: 10 additions & 7 deletions REST_API.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,20 @@
| 1 | POST | /task | create a new download task |
| 2 | PUT | /task/tid/<tid>?act=pause | pause a task with its tid |
| 3 | PUT | /task/tid/<tid>?act=resume | resume download |
| 4 | DELETE | /task/tid/<tid>?del_data=true | delete a task and its data |
| 4 | DELETE | /task/tid/<tid>?del_file=true | delete a task and its data |
| 5 | DELETE | /task/tid/<tid> | delete a task and keep data |
| 6 | GET | /task/tid/<tid>/status | get the full status of a task |
| 7 | GET | /task/tid/<tid>/status?exerpt=true | get the status exerpt of a task |
| 8 | GET | /task/tid/<tid>/info | get the task info |
| 9 | GET | /task/list | get task list exerpt |
| 10 | GET | /task/list?exerpt=false | get task list |
| 11 | GET | /task/list?state={all|downloading|finished|paused} | get task list exerpt according to the state |
| 12 | GET | /task/list?exerpt=false&state={all|downloading|finished|paused} | get task list according to the state |
| 13 | GET | /task/list | get task list of all tasks |
| 14 | GET | /task/state_coutner | get number of tasks in each state |
| 9 | POST | /task/batch/pause | post a list of tasks' tid to be paused |
| 10 | POST | /task/batch/resume | post a list of tasks' tid to be resumed |
| 12 | POST | /task/batch/delete | post a list of tasks' tid to be deleted |
| 13 | GET | /task/list | get task list exerpt |
| 14 | GET | /task/list?exerpt=false | get task list |
| 15 | GET | /task/list?state={all|downloading|finished|paused} | get task list exerpt according to the state |
| 16 | GET | /task/list?exerpt=false&state={all|downloading|finished|paused} | get task list according to the state |
| 17 | GET | /task/state_coutner | get number of tasks in each state |
| 18 | GET | /config | get the server's configuration |
|----+--------+-----------------------------------------------------------------+----------------------------------------------|

Note:
Expand Down
6 changes: 3 additions & 3 deletions example_config.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"general": {
"download_dir": "~/Downloads/youtube_dl",
"db_path": "~/Documents/youtube_dl_webui.db",
"download_log_size": 10
"download_dir": "/tmp/youtube_dl",
"db_path": "/tmp/youtube_dl_webui.db",
"log_size": 10
},
"server": {
"host": "0.0.0.0",
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

setup (
name='youtube_dl_webui',
version='0.1.1',
version='0.2.0',
packages=['youtube_dl_webui'],
license='GPL-2.0',
author='d0u9, yuanyingfeiyu',
Expand Down
509 changes: 509 additions & 0 deletions test/sample_info_dict.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions youtube_dl_webui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
def getopt(argv):
parser = ArgumentParser(description='Another webui for youtube-dl')

parser.add_argument('-c', '--config', metavar="CONFIG_FILE", help="config file", default="/etc/youtube-dl-webui.conf")
parser.add_argument('-c', '--config', metavar="CONFIG_FILE", help="config file")
parser.add_argument('--host', metavar="ADDR", help="the address server listens on")
parser.add_argument('--port', metavar="PORT", help="the port server listens on")

Expand All @@ -23,5 +23,5 @@ def main(argv=None):
print("-----------------------------------")

cmd_args = getopt(argv)
core = Core(args=cmd_args)
core.run()
core = Core(cmd_args=cmd_args)
core.start()
7 changes: 7 additions & 0 deletions youtube_dl_webui/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import sys
import os.path
import json
import logging.config

if __package__ is None and not hasattr(sys, 'frozen'):
path = os.path.realpath(os.path.abspath(__file__))
Expand All @@ -14,5 +16,10 @@
import youtube_dl_webui

if __name__ == '__main__':
# Setup logger
with open('logging.json') as f:
logging_conf = json.load(f)
logging.config.dictConfig(logging_conf)

youtube_dl_webui.main()

178 changes: 178 additions & 0 deletions youtube_dl_webui/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import logging
import json

from copy import deepcopy
from os.path import expanduser

class conf_base(object):
def __init__(self, valid_fields, conf_dict):
# each item in the _valid_fields is a tuple represents
# (key, default_val, type, validate_regex, call_function)
self._valid_fields = valid_fields
self._conf = {}
self.load(conf_dict)

def load(self, conf_dict):
for field in self._valid_fields:
key = field[0]
dft_val = field[1]
val_type = field[2]
vld_regx = field[3]
func = field[4]

# More check can be made here
if key in conf_dict:
self._conf[key] = conf_dict[key] if func is None else func(conf_dict.get(key, dft_val))
elif dft_val is not None:
self._conf[key] = dft_val if func is None else func(conf_dict.get(key, dft_val))


def get_val(self, key):
return self._conf[key]

def __getitem__(self, key):
return self.get_val(key)

def set_val(self, key, val):
self._conf[key] = val

def __setitem__(self, key, val):
self.set_val(key, val)

def dict(self):
return self._conf


class ydl_conf(conf_base):
_valid_fields = [
#(key, default_val, type, validate_regex, call_function)
('proxy', None, 'string', None, None),
('format', None, 'string', None, None),
]

_task_settable_fields = set(['format'])

def __init__(self, conf_dict={}):
self.logger = logging.getLogger('ydl_webui')

super(ydl_conf, self).__init__(self._valid_fields, conf_dict)

def merge_conf(self, task_conf_dict={}):
ret = deepcopy(self.dict())
for key, val in task_conf_dict.items():
if key not in self._task_settable_fields or val == '':
continue
ret[key] = val

return ret


class svr_conf(conf_base):
_valid_fields = [
#(key, default_val, type, validate_regex, call_function)
('host', '127.0.0.1', 'string', None, None),
('port', '5000', 'string', None, None),
]

def __init__(self, conf_dict={}):
self.logger = logging.getLogger('ydl_webui')

super(svr_conf, self).__init__(self._valid_fields, conf_dict)


class gen_conf(conf_base):
_valid_fields = [
#(key, default_val, type, validate_regex, call_function)
('download_dir', '~/Downloads/youtube-dl', 'string', '', expanduser),
('db_path', '~/.conf/ydl_webui.db', 'string', '', expanduser),
('log_size', 10, 'int', '', None),
]

def __init__(self, conf_dict={}):
self.logger = logging.getLogger('ydl_webui')

super(gen_conf, self).__init__(self._valid_fields, conf_dict)


class conf(object):
_valid_fields = set(('youtube_dl', 'server', 'general'))

ydl_conf = None
svr_conf = None
gen_conf = None

def __init__(self, conf_file, conf_dict={}, cmd_args={}):
self.logger = logging.getLogger('ydl_webui')
self.conf_file = conf_file
self.cmd_args = cmd_args
self.load(conf_dict)

def cmd_args_override(self):
_cat_dict = {'host': 'server',
'port': 'server'}

for key, val in self.cmd_args.items():
if key not in _cat_dict or val is None:
continue
sub_conf = self.get_val(_cat_dict[key])
sub_conf.set_val(key, val)

def load(self, conf_dict):
if not isinstance(conf_dict, dict):
self.logger.error("input parameter(conf_dict) is not an instance of dict")
return

for f in self._valid_fields:
if f == 'youtube_dl':
self.ydl_conf = ydl_conf(conf_dict.get(f, {}))
elif f == 'server':
self.svr_conf = svr_conf(conf_dict.get(f, {}))
elif f == 'general':
self.gen_conf = gen_conf(conf_dict.get(f, {}))

# override configurations by cmdline arguments
self.cmd_args_override()

def save2file(self):
if self.conf_file is not None:
try:
with open(self.conf_file, 'w') as f:
json.dump(self.dict(), f, indent=4)
except PermissionError:
return (False, 'permission error')
except FileNotFoundError:
return (False, 'can not find file')
else:
return (True, None)

def dict(self):
d = {}
for f in self._valid_fields:
if f == 'youtube_dl':
d[f] = self.ydl_conf.dict()
elif f == 'server':
d[f] = self.svr_conf.dict()
elif f == 'general':
d[f] = self.gen_conf.dict()

return d

def get_val(self, key):
if key not in self._valid_fields:
raise KeyError(key)

if key == 'youtube_dl':
return self.ydl_conf
elif key == 'server':
return self.svr_conf
elif key == 'general':
return self.gen_conf
else:
raise KeyError(key)

def __getitem__(self, key):
return self.get_val(key)

Loading

0 comments on commit 3cce4ac

Please sign in to comment.