diff options
Diffstat (limited to 'module/web/pyload_app.py')
-rw-r--r-- | module/web/pyload_app.py | 431 |
1 files changed, 24 insertions, 407 deletions
diff --git a/module/web/pyload_app.py b/module/web/pyload_app.py index 2234b76c6..ba74d7083 100644 --- a/module/web/pyload_app.py +++ b/module/web/pyload_app.py @@ -16,32 +16,23 @@ @author: RaNaN """ -from datetime import datetime -from operator import itemgetter, attrgetter - import time -import os -import sys -from os.path import isdir, isfile, join, abspath -from sys import getfilesystemencoding -from urllib import unquote -from traceback import print_exc +from os.path import join from bottle import route, static_file, request, response, redirect, HTTPError, error -from webinterface import PYLOAD, PYLOAD_DIR, PROJECT_DIR, SETUP, env - -from utils import render_to_response, parse_permissions, parse_userdata, \ - login_required, get_permission, set_permission, permlist, toDict, set_session +from webinterface import PYLOAD, PROJECT_DIR, SETUP, env -from filters import relpath, unquotepath +from utils import render_to_response, parse_permissions, parse_userdata, set_session -from module.Api import Output, Permission -from module.utils import format_size -from module.utils.fs import save_join, fs_encode, fs_decode, listdir +from module.Api import Output +########## # Helper +########## + +# TODO: useful but needs a rewrite, too def pre_processor(): s = request.environ.get('beaker.session') user = parse_userdata(s) @@ -70,11 +61,11 @@ def pre_processor(): 'plugins': plugins} + def base(messages): return render_to_response('base.html', {'messages': messages}, [pre_processor]) -## Views @error(500) def error500(error): print "An error occured while processing the request." @@ -84,8 +75,8 @@ def error500(error): return base(["An error occured while processing the request.", error, error.traceback.replace("\n", "<br>") if error.traceback else "No Traceback"]) -# render js -@route("/media/js/<path:re:.+\.js>") +# TODO: not working +# @route("/static/js/<path:re:.+\.js>") def js_dynamic(path): response.headers['Expires'] = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(time.time() + 60 * 60 * 24 * 2)) @@ -94,24 +85,29 @@ def js_dynamic(path): try: # static files are not rendered - if "static" not in path and "mootools" not in path: + if "static" not in path: t = env.get_template("js/%s" % path) return t.render() else: - return static_file(path, root=join(PROJECT_DIR, "media", "js")) + return static_file(path, root=join(PROJECT_DIR, "static", "js")) except: return HTTPError(404, "Not Found") -@route('/media/<path:path>') +@route('/static/<path:path>') def server_static(path): response.headers['Expires'] = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(time.time() + 60 * 60 * 24 * 7)) response.headers['Cache-control'] = "public" - return static_file(path, root=join(PROJECT_DIR, "media")) + return static_file(path, root=join(PROJECT_DIR, "static")) @route('/favicon.ico') def favicon(): - return static_file("favicon.ico", root=join(PROJECT_DIR, "media", "img")) + return static_file("favicon.ico", root=join(PROJECT_DIR, "static", "img")) + + +########## +# Views +########## @route('/login', method="GET") @@ -124,7 +120,7 @@ def login(): @route('/nopermission') def nopermission(): - return base([_("You dont have permission to access this page.")]) + return base([_("You don't have permission to access this page.")]) @route("/login", method="POST") @@ -147,386 +143,7 @@ def logout(): s.delete() return render_to_response("logout.html", proc=[pre_processor]) - @route("/") -@route("/home") -@login_required("List") -def home(): - try: - res = [toDict(x) for x in PYLOAD.getProgressInfo()] - except: - s = request.environ.get('beaker.session') - s.delete() - print_exc() - return redirect("/login") - - for link in res: - if link["status"] == 12: - link["information"] = "%s kB @ %s kB/s" % (link["size"] - link["bleft"], link["speed"]) - - return render_to_response("home.html", {"res": res}, [pre_processor]) - - -@route("/queue") -@login_required("List") -def queue(): - queue = PYLOAD.getQueue() - - queue.sort(key=attrgetter("order")) - - return render_to_response('queue.html', {'content': queue, 'target': 1}, [pre_processor]) - - -@route("/collector") -@login_required('LIST') -def collector(): - queue = PYLOAD.getCollector() - - queue.sort(key=attrgetter("order")) - - return render_to_response('queue.html', {'content': queue, 'target': 0}, [pre_processor]) - - -@route("/downloads") -@login_required('DOWNLOAD') -def downloads(): - root = PYLOAD.getConfigValue("general", "download_folder") - - if not isdir(fs_encode(root)): - return base([_('Download directory not found.')]) - data = { - 'folder': [], - 'files': [] - } - - items = listdir(fs_encode(root)) - - for item in sorted([fs_decode(x) for x in items]): - if isdir(save_join(root, item)): - folder = { - 'name': item, - 'path': item, - 'files': [] - } - files = listdir(save_join(root, item)) - for file in sorted([fs_decode(x) for x in files]): - try: - if isfile(save_join(root, item, file)): - folder['files'].append(file) - except: - pass - - data['folder'].append(folder) - elif isfile(join(root, item)): - data['files'].append(item) - - return render_to_response('downloads.html', {'files': data}, [pre_processor]) - - -@route("/downloads/get/<path:re:.+>") -@login_required("DOWNLOAD") -def get_download(path): - path = unquote(path).decode("utf8") - #@TODO some files can not be downloaded - - root = PYLOAD.getConfigValue("general", "download_folder") - - path = path.replace("..", "") - try: - return static_file(fs_encode(path), fs_encode(root)) - - except Exception, e: - print e - return HTTPError(404, "File not Found.") - - - -@route("/settings") -@login_required('SETTINGS') -def config(): - conf = PYLOAD.getConfigRef() - - conf_menu = [] - plugin_menu = [] - - for section, data in sorted(conf.getBaseSections()): - conf_menu.append((section, data.name)) - - for section, data in sorted(conf.getPluginSections()): - plugin_menu.append((section, data.name)) - - accs = PYLOAD.getAccounts(False) - - # prefix attributes with _, because we would change them directly on the object otherweise - for data in accs: - if data.trafficleft == -1: - data._trafficleft = _("unlimited") - elif not data.trafficleft: - data._trafficleft = _("not available") - else: - data._trafficleft = formatSize(data.trafficleft * 1024) - - if data.validuntil == -1: - data._validuntil = _("unlimited") - elif not data.validuntil: - data._validuntil = _("not available") - else: - t = time.localtime(data.validuntil) - data._validuntil = time.strftime("%d.%m.%Y", t) - - if not data.options["time"]: - data.options["time"] = "0:00-0:00" - - if not data.options["limitDL"]: - data.options["limitdl"] = "0" - - return render_to_response('settings.html', - {'conf': {'plugin': plugin_menu, 'general': conf_menu, 'accs': accs}, 'types': PYLOAD.getAccountTypes()}, - [pre_processor]) - - -@route("/filechooser") -@route("/pathchooser") -@route("/filechooser/:file#.+#") -@route("/pathchooser/:path#.+#") -@login_required('STATUS') -def path(file="", path=""): - if file: - type = "file" - else: - type = "folder" +def index(): + return base(["It works!"]) - path = os.path.normpath(unquotepath(path)) - - if os.path.isfile(path): - oldfile = path - path = os.path.dirname(path) - else: - oldfile = '' - - abs = False - - if os.path.isdir(path): - if os.path.isabs(path): - cwd = os.path.abspath(path) - abs = True - else: - cwd = relpath(path) - else: - cwd = os.getcwd() - - try: - cwd = cwd.encode("utf8") - except: - pass - - cwd = os.path.normpath(os.path.abspath(cwd)) - parentdir = os.path.dirname(cwd) - if not abs: - if os.path.abspath(cwd) == "/": - cwd = relpath(cwd) - else: - cwd = relpath(cwd) + os.path.sep - parentdir = relpath(parentdir) + os.path.sep - - if os.path.abspath(cwd) == "/": - parentdir = "" - - try: - folders = os.listdir(cwd) - except: - folders = [] - - files = [] - - for f in folders: - try: - f = f.decode(getfilesystemencoding()) - data = {'name': f, 'fullpath': join(cwd, f)} - data['sort'] = data['fullpath'].lower() - data['modified'] = datetime.fromtimestamp(int(os.path.getmtime(join(cwd, f)))) - data['ext'] = os.path.splitext(f)[1] - except: - continue - - if os.path.isdir(join(cwd, f)): - data['type'] = 'dir' - else: - data['type'] = 'file' - - if os.path.isfile(join(cwd, f)): - data['size'] = os.path.getsize(join(cwd, f)) - - power = 0 - while (data['size'] / 1024) > 0.3: - power += 1 - data['size'] /= 1024. - units = ('', 'K', 'M', 'G', 'T') - data['unit'] = units[power] + 'Byte' - else: - data['size'] = '' - - files.append(data) - - files = sorted(files, key=itemgetter('type', 'sort')) - - return render_to_response('pathchooser.html', - {'cwd': cwd, 'files': files, 'parentdir': parentdir, 'type': type, 'oldfile': oldfile, - 'absolute': abs}, []) - - -@route("/logs") -@route("/logs", method="POST") -@route("/logs/:item") -@route("/logs/:item", method="POST") -@login_required('LOGS') -def logs(item=-1): - s = request.environ.get('beaker.session') - - perpage = s.get('perpage', 34) - reversed = s.get('reversed', False) - - warning = "" - conf = PYLOAD.getConfigValue("log","file_log") - if not conf: - warning = "Warning: File log is disabled, see settings page." - - perpage_p = ((20, 20), (34, 34), (40, 40), (100, 100), (0, 'all')) - fro = None - - if request.environ.get('REQUEST_METHOD', "GET") == "POST": - try: - fro = datetime.strptime(request.forms['from'], '%d.%m.%Y %H:%M:%S') - except: - pass - try: - perpage = int(request.forms['perpage']) - s['perpage'] = perpage - - reversed = bool(request.forms.get('reversed', False)) - s['reversed'] = reversed - except: - pass - - s.save() - - try: - item = int(item) - except: - pass - - log = PYLOAD.getLog() - if not perpage: - item = 0 - - if item < 1 or type(item) is not int: - item = 1 if len(log) - perpage + 1 < 1 else len(log) - perpage + 1 - - if type(fro) is datetime: # we will search for datetime - item = -1 - - data = [] - counter = 0 - perpagecheck = 0 - for l in log: - counter += 1 - - if counter >= item: - try: - date, time, level, message = l.decode("utf8", "ignore").split(" ", 3) - dtime = datetime.strptime(date + ' ' + time, '%d.%m.%Y %H:%M:%S') - except: - dtime = None - date = '?' - time = ' ' - level = '?' - message = l - if item == -1 and dtime is not None and fro <= dtime: - item = counter #found our datetime - if item >= 0: - data.append({'line': counter, 'date': date + " " + time, 'level': level, 'message': message}) - perpagecheck += 1 - if fro is None and dtime is not None: #if fro not set set it to first showed line - fro = dtime - if perpagecheck >= perpage > 0: - break - - if fro is None: #still not set, empty log? - fro = datetime.now() - if reversed: - data.reverse() - return render_to_response('logs.html', {'warning': warning, 'log': data, 'from': fro.strftime('%d.%m.%Y %H:%M:%S'), - 'reversed': reversed, 'perpage': perpage, 'perpage_p': sorted(perpage_p), - 'iprev': 1 if item - perpage < 1 else item - perpage, - 'inext': (item + perpage) if item + perpage < len(log) else item}, - [pre_processor]) - - -@route("/admin") -@route("/admin", method="POST") -@login_required("ADMIN") -def admin(): - # convert to dict - user = dict([(name, toDict(y)) for name, y in PYLOAD.getAllUserData().iteritems()]) - perms = permlist() - - for data in user.itervalues(): - data["perms"] = {} - get_permission(data["perms"], data["permission"]) - data["perms"]["admin"] = True if data["role"] is 0 else False - - - s = request.environ.get('beaker.session') - if request.environ.get('REQUEST_METHOD', "GET") == "POST": - for name in user: - if request.POST.get("%s|admin" % name, False): - user[name]["role"] = 0 - user[name]["perms"]["admin"] = True - elif name != s["name"]: - user[name]["role"] = 1 - user[name]["perms"]["admin"] = False - - # set all perms to false - for perm in perms: - user[name]["perms"][perm] = False - - - for perm in request.POST.getall("%s|perms" % name): - user[name]["perms"][perm] = True - - user[name]["permission"] = set_permission(user[name]["perms"]) - - PYLOAD.setUserPermission(name, user[name]["permission"], user[name]["role"]) - - return render_to_response("admin.html", {"users": user, "permlist": perms}, [pre_processor]) - - -@route("/setup") -def setup(): - if PYLOAD or not SETUP: - return base([_("Run pyLoadCore.py -s to access the setup.")]) - - return render_to_response('setup.html', {"user": False, "perms": False}) - - -@login_required("STATUS") -@route("/info") -def info(): - conf = PYLOAD.getConfigRef() - - if hasattr(os, "uname"): - extra = os.uname() - else: - extra = tuple() - - data = {"python": sys.version, - "os": " ".join((os.name, sys.platform) + extra), - "version": PYLOAD.getServerVersion(), - "folder": abspath(PYLOAD_DIR), "config": abspath(""), - "download": abspath(conf["general"]["download_folder"]), - "freespace": format_size(PYLOAD.freeSpace()), - "remote": conf["remote"]["port"], - "webif": conf["webinterface"]["port"], - "language": conf["general"]["language"]} - - return render_to_response("info.html", data, [pre_processor]) |