summaryrefslogtreecommitdiffstats
path: root/pyload/webui/app
diff options
context:
space:
mode:
Diffstat (limited to 'pyload/webui/app')
-rw-r--r--pyload/webui/app/__init__.py3
-rw-r--r--pyload/webui/app/api.py101
-rw-r--r--pyload/webui/app/cnl.py167
-rw-r--r--pyload/webui/app/json.py311
-rw-r--r--pyload/webui/app/pyload.py530
-rw-r--r--pyload/webui/app/utils.py123
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()