diff options
Diffstat (limited to 'pyload/webui/app')
-rw-r--r-- | pyload/webui/app/__init__.py | 3 | ||||
-rw-r--r-- | pyload/webui/app/api.py | 101 | ||||
-rw-r--r-- | pyload/webui/app/cnl.py | 167 | ||||
-rw-r--r-- | pyload/webui/app/json.py | 311 | ||||
-rw-r--r-- | pyload/webui/app/pyload.py | 530 | ||||
-rw-r--r-- | pyload/webui/app/utils.py | 123 |
6 files changed, 0 insertions, 1235 deletions
diff --git a/pyload/webui/app/__init__.py b/pyload/webui/app/__init__.py deleted file mode 100644 index 39d0fadd5..000000000 --- a/pyload/webui/app/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- - -from pyload.webui.app import api, cnl, json, pyload diff --git a/pyload/webui/app/api.py b/pyload/webui/app/api.py deleted file mode 100644 index 1ee4b1608..000000000 --- a/pyload/webui/app/api.py +++ /dev/null @@ -1,101 +0,0 @@ -# -*- coding: utf-8 -*- - -from urllib import unquote -from itertools import chain -from traceback import format_exc, print_exc - -from bottle import route, request, response, HTTPError - -from pyload.utils import toDict, set_session -from pyload.webui import PYLOAD - -from pyload.utils import json -from SafeEval import const_eval as literal_eval -from pyload.api import BaseObject - -# json encoder that accepts TBase objects -class TBaseEncoder(json.JSONEncoder): - - def default(self, o): - if isinstance(o, BaseObject): - return toDict(o) - return json.JSONEncoder.default(self, o) - - -# accepting positional arguments, as well as kwargs via post and get - -@route('/api/<func><args:re:[a-zA-Z0-9\-_/\"\'\[\]%{}]*>') -@route('/api/<func><args:re:[a-zA-Z0-9\-_/\"\'\[\]%{}]*>', method='POST') -def call_api(func, args=""): - response.headers.replace("Content-type", "application/json") - response.headers.append("Cache-Control", "no-cache, must-revalidate") - - s = request.environ.get('beaker.session') - if 'session' in request.POST: - s = s.get_by_id(request.POST['session']) - - if not s or not s.get("authenticated", False): - return HTTPError(403, json.dumps("Forbidden")) - - if not PYLOAD.isAuthorized(func, {"role": s["role"], "permission": s["perms"]}): - return HTTPError(401, json.dumps("Unauthorized")) - - args = args.split("/")[1:] - kwargs = {} - - for x, y in chain(request.GET.iteritems(), request.POST.iteritems()): - if x == "session": continue - kwargs[x] = unquote(y) - - try: - return callApi(func, *args, **kwargs) - except Exception, e: - print_exc() - return HTTPError(500, json.dumps({"error": e.message, "traceback": format_exc()})) - - -def callApi(func, *args, **kwargs): - if not hasattr(PYLOAD.EXTERNAL, func) or func.startswith("_"): - print "Invalid API call", func - return HTTPError(404, json.dumps("Not Found")) - - result = getattr(PYLOAD, func)(*[literal_eval(x) for x in args], - **dict((x, literal_eval(y)) for x, y in kwargs.iteritems())) - - # null is invalid json response - if result is None: result = True - - return json.dumps(result, cls=TBaseEncoder) - - -#post -> username, password -@route('/api/login', method='POST') -def login(): - response.headers.replace("Content-type", "application/json") - response.headers.append("Cache-Control", "no-cache, must-revalidate") - - user = request.forms.get("username") - password = request.forms.get("password") - - info = PYLOAD.checkAuth(user, password) - - if not info: - return json.dumps(False) - - s = set_session(request, info) - - # get the session id by dirty way, documentations seems wrong - try: - sid = s._headers["cookie_out"].split("=")[1].split(";")[0] - return json.dumps(sid) - except Exception: - return json.dumps(True) - - -@route('/api/logout') -def logout(): - response.headers.replace("Content-type", "application/json") - response.headers.append("Cache-Control", "no-cache, must-revalidate") - - s = request.environ.get('beaker.session') - s.delete() diff --git a/pyload/webui/app/cnl.py b/pyload/webui/app/cnl.py deleted file mode 100644 index e00e47f66..000000000 --- a/pyload/webui/app/cnl.py +++ /dev/null @@ -1,167 +0,0 @@ -# -*- coding: utf-8 -*- -from os.path import join -import re -from urllib import unquote -from base64 import standard_b64decode -from binascii import unhexlify - -from bottle import route, request, HTTPError -from pyload.webui import PYLOAD, DL_ROOT, JS - - -try: - from Crypto.Cipher import AES -except Exception: - pass - - -def local_check(function): - def _view(*args, **kwargs): - if request.environ.get("REMOTE_ADDR", "0") in ("127.0.0.1", "localhost") \ - or request.environ.get("HTTP_HOST", "0") in ("127.0.0.1:9666", "localhost:9666"): - return function(*args, **kwargs) - else: - return HTTPError(403, "Forbidden") - - return _view - - -@route('/flash') -@route('/flash/<id>') -@route('/flash', method='POST') -@local_check -def flash(id="0"): - return "JDownloader\r\n" - - -@route('/flash/add', method='POST') -@local_check -def add(request): - package = request.POST.get('referer', None) - urls = filter(lambda x: x != "", request.POST['urls'].split("\n")) - - if package: - PYLOAD.addPackage(package, urls, 0) - else: - PYLOAD.generateAndAddPackages(urls, 0) - - return "" - - -@route('/flash/addcrypted', method='POST') -@local_check -def addcrypted(): - package = request.forms.get('referer', 'ClickAndLoad Package') - dlc = request.forms['crypted'].replace(" ", "+") - - dlc_path = join(DL_ROOT, package.replace("/", "").replace("\\", "").replace(":", "") + ".dlc") - dlc_file = open(dlc_path, "wb") - dlc_file.write(dlc) - dlc_file.close() - - try: - PYLOAD.addPackage(package, [dlc_path], 0) - except Exception: - return HTTPError() - else: - return "success\r\n" - - -@route('/flash/addcrypted2', method='POST') -@local_check -def addcrypted2(): - package = request.forms.get("source", None) - crypted = request.forms["crypted"] - jk = request.forms["jk"] - - crypted = standard_b64decode(unquote(crypted.replace(" ", "+"))) - if JS: - jk = "%s f()" % jk - jk = JS.eval(jk) - - else: - try: - jk = re.findall(r"return ('|\")(.+)('|\")", jk)[0][1] - except Exception: - ## Test for some known js functions to decode - if jk.find("dec") > -1 and jk.find("org") > -1: - org = re.findall(r"var org = ('|\")([^\"']+)", jk)[0][1] - jk = list(org) - jk.reverse() - jk = "".join(jk) - else: - print "Could not decrypt key, please install py-spidermonkey or ossp-js" - - try: - Key = unhexlify(jk) - except Exception: - print "Could not decrypt key, please install py-spidermonkey or ossp-js" - return "failed" - - IV = Key - - obj = AES.new(Key, AES.MODE_CBC, IV) - result = obj.decrypt(crypted).replace("\x00", "").replace("\r", "").split("\n") - - result = filter(lambda x: x != "", result) - - try: - if package: - PYLOAD.addPackage(package, result, 0) - else: - PYLOAD.generateAndAddPackages(result, 0) - except Exception: - return "failed can't add" - else: - return "success\r\n" - - -@route('/flashgot_pyload') -@route('/flashgot_pyload', method='POST') -@route('/flashgot') -@route('/flashgot', method='POST') -@local_check -def flashgot(): - if request.environ['HTTP_REFERER'] not in ("http://localhost:9666/flashgot", "http://127.0.0.1:9666/flashgot"): - return HTTPError() - - autostart = int(request.forms.get('autostart', 0)) - package = request.forms.get('package', None) - urls = filter(lambda x: x != "", request.forms['urls'].split("\n")) - folder = request.forms.get('dir', None) - - if package: - PYLOAD.addPackage(package, urls, autostart) - else: - PYLOAD.generateAndAddPackages(urls, autostart) - - return "" - - -@route('/crossdomain.xml') -@local_check -def crossdomain(): - rep = "<?xml version=\"1.0\"?>\n" - rep += "<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n" - rep += "<cross-domain-policy>\n" - rep += "<allow-access-from domain=\"*\" />\n" - rep += "</cross-domain-policy>" - return rep - - -@route('/flash/checkSupportForUrl') -@local_check -def checksupport(): - url = request.GET.get("url") - res = PYLOAD.checkURLs([url]) - supported = (not res[0][1] is None) - - return str(supported).lower() - - -@route('/jdcheck.js') -@local_check -def jdcheck(): - rep = "jdownloader=true;\n" - rep += "var version='9.581;'" - return rep diff --git a/pyload/webui/app/json.py b/pyload/webui/app/json.py deleted file mode 100644 index c347c25e3..000000000 --- a/pyload/webui/app/json.py +++ /dev/null @@ -1,311 +0,0 @@ -# -*- coding: utf-8 -*- - -from os.path import join -from traceback import print_exc -from shutil import copyfileobj - -from bottle import route, request, HTTPError - -from pyload.webui import PYLOAD - -from pyload.utils import login_required, render_to_response, toDict - -from pyload.utils import decode, formatSize - - -def format_time(seconds): - seconds = int(seconds) - - hours, seconds = divmod(seconds, 3600) - minutes, seconds = divmod(seconds, 60) - return "%.2i:%.2i:%.2i" % (hours, minutes, seconds) - - -def get_sort_key(item): - return item["order"] - - -@route('/json/status') -@route('/json/status', method='POST') -@login_required('LIST') -def status(): - try: - status = toDict(PYLOAD.statusServer()) - status['captcha'] = PYLOAD.isCaptchaWaiting() - return status - except Exception: - return HTTPError() - - -@route('/json/links') -@route('/json/links', method='POST') -@login_required('LIST') -def links(): - try: - links = [toDict(x) for x in PYLOAD.statusDownloads()] - ids = [] - for link in links: - ids.append(link['fid']) - - if link['status'] == 12: - link['info'] = "%s @ %s/s" % (link['format_eta'], formatSize(link['speed'])) - elif link['status'] == 5: - link['percent'] = 0 - link['size'] = 0 - link['bleft'] = 0 - link['info'] = _("waiting %s") % link['format_wait'] - else: - link['info'] = "" - - data = {'links': links, 'ids': ids} - return data - except Exception, e: - print_exc() - return HTTPError() - - -@route('/json/packages') -@login_required('LIST') -def packages(): - print "/json/packages" - try: - data = PYLOAD.getQueue() - - for package in data: - package['links'] = [] - for file in PYLOAD.get_package_files(package['id']): - package['links'].append(PYLOAD.get_file_info(file)) - - return data - - except Exception: - return HTTPError() - - -@route('/json/package/<id:int>') -@login_required('LIST') -def package(id): - try: - data = toDict(PYLOAD.getPackageData(id)) - data["links"] = [toDict(x) for x in data["links"]] - - for pyfile in data["links"]: - if pyfile["status"] == 0: - pyfile["icon"] = "status_finished.png" - elif pyfile["status"] in (2, 3): - pyfile["icon"] = "status_queue.png" - elif pyfile["status"] in (9, 1): - pyfile["icon"] = "status_offline.png" - elif pyfile["status"] == 5: - pyfile["icon"] = "status_waiting.png" - elif pyfile["status"] == 8: - pyfile["icon"] = "status_failed.png" - elif pyfile["status"] == 4: - pyfile["icon"] = "arrow_right.png" - elif pyfile["status"] in (11, 13): - pyfile["icon"] = "status_proc.png" - else: - pyfile["icon"] = "status_downloading.png" - - tmp = data["links"] - tmp.sort(key=get_sort_key) - data["links"] = tmp - return data - - except Exception: - print_exc() - return HTTPError() - - -@route('/json/package_order/<ids>') -@login_required('ADD') -def package_order(ids): - try: - pid, pos = ids.split("|") - PYLOAD.orderPackage(int(pid), int(pos)) - return {"response": "success"} - except Exception: - return HTTPError() - - -@route('/json/abort_link/<id:int>') -@login_required('DELETE') -def abort_link(id): - try: - PYLOAD.stopDownloads([id]) - return {"response": "success"} - except Exception: - return HTTPError() - - -@route('/json/link_order/<ids>') -@login_required('ADD') -def link_order(ids): - try: - pid, pos = ids.split("|") - PYLOAD.orderFile(int(pid), int(pos)) - return {"response": "success"} - except Exception: - return HTTPError() - - -@route('/json/add_package') -@route('/json/add_package', method='POST') -@login_required('ADD') -def add_package(): - name = request.forms.get("add_name", "New Package").strip() - queue = int(request.forms['add_dest']) - links = decode(request.forms['add_links']) - links = links.split("\n") - pw = request.forms.get("add_password", "").strip("\n\r") - - try: - f = request.files['add_file'] - - if not name or name == "New Package": - name = f.name - - fpath = join(PYLOAD.getConfigValue("general", "download_folder"), "tmp_" + f.filename) - destination = open(fpath, 'wb') - copyfileobj(f.file, destination) - destination.close() - links.insert(0, fpath) - except Exception: - pass - - name = name.decode("utf8", "ignore") - - links = map(lambda x: x.strip(), links) - links = filter(lambda x: x != "", links) - - pack = PYLOAD.addPackage(name, links, queue) - if pw: - pw = pw.decode("utf8", "ignore") - data = {"password": pw} - PYLOAD.setPackageData(pack, data) - - -@route('/json/move_package/<dest:int>/<id:int>') -@login_required('MODIFY') -def move_package(dest, id): - try: - PYLOAD.movePackage(dest, id) - return {"response": "success"} - except Exception: - return HTTPError() - - -@route('/json/edit_package', method='POST') -@login_required('MODIFY') -def edit_package(): - try: - id = int(request.forms.get("pack_id")) - data = {"name": request.forms.get("pack_name").decode("utf8", "ignore"), - "folder": request.forms.get("pack_folder").decode("utf8", "ignore"), - "password": request.forms.get("pack_pws").decode("utf8", "ignore")} - - PYLOAD.setPackageData(id, data) - return {"response": "success"} - - except Exception: - return HTTPError() - - -@route('/json/set_captcha') -@route('/json/set_captcha', method='POST') -@login_required('ADD') -def set_captcha(): - if request.environ.get('REQUEST_METHOD', "GET") == "POST": - try: - PYLOAD.setCaptchaResult(request.forms["cap_id"], request.forms["cap_result"]) - except Exception: - pass - - task = PYLOAD.getCaptchaTask() - - if task.tid >= 0: - src = "data:image/%s;base64,%s" % (task.type, task.data) - - return {'captcha': True, 'id': task.tid, 'src': src, 'result_type' : task.resultType} - else: - return {'captcha': False} - - -@route('/json/load_config/<category>/<section>') -@login_required("SETTINGS") -def load_config(category, section): - conf = None - if category == "general": - conf = PYLOAD.getConfigDict() - elif category == "plugin": - conf = PYLOAD.getPluginConfigDict() - - for key, option in conf[section].iteritems(): - if key in ("desc", "outline"): continue - - if ";" in option["type"]: - option["list"] = option["type"].split(";") - - option["value"] = decode(option["value"]) - - return render_to_response("settings_item.html", {"skey": section, "section": conf[section]}) - - -@route('/json/save_config/<category>', method='POST') -@login_required("SETTINGS") -def save_config(category): - for key, value in request.POST.iteritems(): - try: - section, option = key.split("|") - except Exception: - continue - - if category == "general": category = "core" - - PYLOAD.setConfigValue(section, option, decode(value), category) - - -@route('/json/add_account', method='POST') -@login_required("ACCOUNTS") -def add_account(): - login = request.POST["account_login"] - password = request.POST["account_password"] - type = request.POST["account_type"] - - PYLOAD.updateAccount(type, login, password) - - -@route('/json/update_accounts', method='POST') -@login_required("ACCOUNTS") -def update_accounts(): - deleted = [] #dont update deleted accs or they will be created again - - for name, value in request.POST.iteritems(): - value = value.strip() - if not value: continue - - tmp, user = name.split(";") - plugin, action = tmp.split("|") - - if (plugin, user) in deleted: continue - - if action == "password": - PYLOAD.updateAccount(plugin, user, value) - elif action == "time" and "-" in value: - PYLOAD.updateAccount(plugin, user, options={"time": [value]}) - elif action == "limitdl" and value.isdigit(): - PYLOAD.updateAccount(plugin, user, options={"limitDL": [value]}) - elif action == "delete": - deleted.append((plugin,user)) - PYLOAD.removeAccount(plugin, user) - -@route('/json/change_password', method='POST') -def change_password(): - - user = request.POST["user_login"] - oldpw = request.POST["login_current_password"] - newpw = request.POST["login_new_password"] - - if not PYLOAD.changePassword(user, oldpw, newpw): - print "Wrong password" - return HTTPError() diff --git a/pyload/webui/app/pyload.py b/pyload/webui/app/pyload.py deleted file mode 100644 index 2d1a8eb86..000000000 --- a/pyload/webui/app/pyload.py +++ /dev/null @@ -1,530 +0,0 @@ -# -*- coding: utf-8 -*- -# @author: RaNaN - -from datetime import datetime -from operator import itemgetter, attrgetter - -import time -import os -import sys -from os import listdir -from os.path import isdir, isfile, join, abspath -from sys import getfilesystemencoding -from urllib import unquote - -from bottle import route, static_file, request, response, redirect, error - -from pyload.webui import PYLOAD, PYLOAD_DIR, THEME_DIR, SETUP, env - -from pyload.utils import render_to_response, parse_permissions, parse_userdata, \ - login_required, get_permission, set_permission, permlist, toDict, set_session - -from pyload.webui.filters import relpath, unquotepath - -from pyload.utils import formatSize, safe_join, fs_encode, fs_decode - -# Helper - -def pre_processor(): - s = request.environ.get('beaker.session') - user = parse_userdata(s) - perms = parse_permissions(s) - status = {} - captcha = False - update = False - plugins = False - if user["is_authenticated"]: - status = PYLOAD.statusServer() - info = PYLOAD.getInfoByPlugin("UpdateManager") - captcha = PYLOAD.isCaptchaWaiting() - - # check if update check is available - if info: - if info["pyload"] == "True": - update = info["version"] - if info["plugins"] == "True": - plugins = True - - - return {"user" : user, - 'status' : status, - 'captcha': captcha, - 'perms' : perms, - 'url' : request.url, - 'update' : update, - 'plugins': plugins} - - -def base(messages): - return render_to_response('base.html', {'messages': messages}, [pre_processor]) - - -## Views -@error(403) -def error403(code): - return "The parameter you passed has the wrong format" - - -@error(404) -def error404(code): - return "Sorry, this page does not exist" - - -@error(500) -def error500(error): - traceback = error.traceback - if traceback: - print traceback - return base(["An Error occured, please enable debug mode to get more details.", error, - traceback.replace("\n", "<br>") if traceback else "No Traceback"]) - - -@route('/<theme>/<file:re:(.+/)?[^/]+\.min\.[^/]+>') -def server_min(theme, file): - filename = join(THEME_DIR, theme, file) - if not isfile(filename): - file = file.replace(".min.", ".") - if file.endswith(".js"): - return server_js(theme, file) - else: - return server_static(theme, file) - - -@route('/<theme>/<file_static:re:.+\.js>') -def server_js(theme, file): - response.headers['Content-Type'] = "text/javascript; charset=UTF-8" - - if "/render/" in file or ".render." in file: - response.headers['Expires'] = time.strftime("%a, %d %b %Y %H:%M:%S GMT", - time.gmtime(time.time() + 24 * 7 * 60 * 60)) - response.headers['Cache-control'] = "public" - - path = join(theme, file) - return env.get_template(path).render() - else: - return server_static(theme, file) - - -@route('/<theme>/<file:path>') -def server_static(theme, file): - response.headers['Expires'] = time.strftime("%a, %d %b %Y %H:%M:%S GMT", - time.gmtime(time.time() + 24 * 7 * 60 * 60)) - response.headers['Cache-control'] = "public" - - return static_file(file, root=join(THEME_DIR, theme)) - - -@route('/favicon.ico') -def favicon(): - return static_file("icon.ico", root=join(PYLOAD_DIR, "docs", "resources")) - - -@route('/login', method="GET") -def login(): - if not PYLOAD and SETUP: - redirect("/setup") - else: - return render_to_response("login.html", proc=[pre_processor]) - - -@route('/nopermission') -def nopermission(): - return base([_("You dont have permission to access this page.")]) - - -@route('/login', method='POST') -def login_post(): - user = request.forms.get("username") - password = request.forms.get("password") - - info = PYLOAD.checkAuth(user, password) - - if not info: - return render_to_response("login.html", {"errors": True}, [pre_processor]) - - set_session(request, info) - return redirect("/") - - -@route('/logout') -def logout(): - s = request.environ.get('beaker.session') - 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.statusDownloads()] - except Exception: - s = request.environ.get('beaker.session') - s.delete() - 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(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(safe_join(root, item)): - folder = { - 'name': item, - 'path': item, - 'files': [] - } - files = listdir(safe_join(root, item)) - for file in sorted([fs_decode(x) for x in files]): - try: - if isfile(safe_join(root, item, file)): - folder['files'].append(file) - except Exception: - 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:path>') -@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("..", "") - return static_file(fs_encode(path), fs_encode(root)) - - - -@route('/settings') -@login_required('SETTINGS') -def config(): - conf = PYLOAD.getConfig() - plugin = PYLOAD.getPluginConfig() - - conf_menu = [] - plugin_menu = [] - - for entry in sorted(conf.keys()): - conf_menu.append((entry, conf[entry].description)) - - for entry in sorted(plugin.keys()): - plugin_menu.append((entry, plugin[entry].description)) - - accs = PYLOAD.getAccounts(False) - - 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) - - 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 - %H:%M:%S", t) - - try: - data.options["time"] = data.options["time"][0] - except Exception: - data.options["time"] = "0:00-0:00" - - if "limitDL" in data.options: - data.options["limitdl"] = data.options["limitDL"][0] - else: - 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:path>') -@route('/pathchooser/<path:path>') -@login_required('STATUS') -def path(file="", path=""): - if file: - type = "file" - else: - type = "folder" - - 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 Exception: - 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 Exception: - 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 Exception: - 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 Exception: - pass - try: - perpage = int(request.forms['perpage']) - s['perpage'] = perpage - - reversed = bool(request.forms.get('reversed', False)) - s['reversed'] = reversed - except Exception: - pass - - s.save() - - try: - item = int(item) - except Exception: - 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 Exception: - 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(): - return base([_("Run pyload.py -s to access the setup.")]) - - -@route('/info') -def info(): - conf = PYLOAD.getConfigDict() - - 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"]["value"]), - "freespace": formatSize(PYLOAD.freeSpace()), - "remote": conf["remote"]["port"]["value"], - "webif": conf["webinterface"]["port"]["value"], - "language": conf["general"]["language"]["value"]} - - return render_to_response("info.html", data, [pre_processor]) diff --git a/pyload/webui/app/utils.py b/pyload/webui/app/utils.py deleted file mode 100644 index fd0e14cfa..000000000 --- a/pyload/webui/app/utils.py +++ /dev/null @@ -1,123 +0,0 @@ -# -*- coding: utf-8 -*- -# @author: RaNaN, vuolter - -from os.path import join - -from bottle import request, HTTPError, redirect, ServerAdapter - -from pyload.webui import env, THEME - -from pyload.api import has_permission, PERMS, ROLE - -def render_to_response(file, args={}, proc=[]): - for p in proc: - args.update(p()) - path = join(THEME, "tml", file) - return env.get_template(path).render(**args) - - -def parse_permissions(session): - perms = dict((x, False) for x in dir(PERMS) if not x.startswith("_")) - perms["ADMIN"] = False - perms["is_admin"] = False - - if not session.get("authenticated", False): - return perms - - if session.get("role") == ROLE.ADMIN: - for k in perms.iterkeys(): - perms[k] = True - - elif session.get("perms"): - p = session.get("perms") - get_permission(perms, p) - - return perms - - -def permlist(): - return [x for x in dir(PERMS) if not x.startswith("_") and x != "ALL"] - - -def get_permission(perms, p): - """Returns a dict with permission key - - :param perms: dictionary - :param p: bits - """ - for name in permlist(): - perms[name] = has_permission(p, getattr(PERMS, name)) - - -def set_permission(perms): - """generates permission bits from dictionary - - :param perms: dict - """ - permission = 0 - for name in dir(PERMS): - if name.startswith("_"): continue - - if name in perms and perms[name]: - permission |= getattr(PERMS, name) - - return permission - - -def set_session(request, info): - s = request.environ.get('beaker.session') - s["authenticated"] = True - s["user_id"] = info["id"] - s["name"] = info["name"] - s["role"] = info["role"] - s["perms"] = info["permission"] - s["template"] = info["template"] - s.save() - - return s - - -def parse_userdata(session): - return {"name": session.get("name", "Anonymous"), - "is_admin": True if session.get("role", 1) == 0 else False, - "is_authenticated": session.get("authenticated", False)} - - -def login_required(perm=None): - def _dec(func): - def _view(*args, **kwargs): - s = request.environ.get('beaker.session') - if s.get("name", None) and s.get("authenticated", False): - if perm: - perms = parse_permissions(s) - if perm not in perms or not perms[perm]: - if request.headers.get('X-Requested-With') == 'XMLHttpRequest': - return HTTPError(403, "Forbidden") - else: - return redirect("/nopermission") - - return func(*args, **kwargs) - else: - if request.headers.get('X-Requested-With') == 'XMLHttpRequest': - return HTTPError(403, "Forbidden") - else: - return redirect("/login") - - return _view - - return _dec - - -def toDict(obj): - ret = {} - for att in obj.__slots__: - ret[att] = getattr(obj, att) - return ret - - -class CherryPyWSGI(ServerAdapter): - def run(self, handler): - from wsgiserver import CherryPyWSGIServer - - server = CherryPyWSGIServer((self.host, self.port), handler) - server.start() |