summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2011-09-20 20:41:45 +0200
committerGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2011-09-20 20:41:45 +0200
commit73ede837c8b9a31a8bd0b380d2246fba67bddd89 (patch)
treeda3bc22833f5fc2bf3e614228eff68291d60412c
parentclosed #390 (diff)
downloadpyload-73ede837c8b9a31a8bd0b380d2246fba67bddd89.tar.xz
general JSON API, url parser
-rw-r--r--docs/access_api.rst45
-rw-r--r--docs/conf.py2
-rw-r--r--locale/generate_locale.py68
-rw-r--r--module/Api.py53
-rw-r--r--module/database/UserDatabase.py5
-rw-r--r--module/remote/thriftbackend/ThriftClient.py4
-rwxr-xr-xmodule/remote/thriftbackend/generateThrift.sh4
-rw-r--r--module/remote/thriftbackend/pyload.thrift2
-rwxr-xr-xmodule/remote/thriftbackend/thriftgen/pyload/Pyload-remote8
-rw-r--r--module/remote/thriftbackend/thriftgen/pyload/Pyload.py21
-rw-r--r--module/web/api_app.py107
-rw-r--r--module/web/pyload_app.py12
-rw-r--r--module/web/utils.py20
-rw-r--r--module/web/webinterface.py1
14 files changed, 250 insertions, 102 deletions
diff --git a/docs/access_api.rst b/docs/access_api.rst
index c23a409bf..11955c76d 100644
--- a/docs/access_api.rst
+++ b/docs/access_api.rst
@@ -21,6 +21,7 @@ interesting is the possibillity to call function from different programs written
pyLoad uses thrift as backend and provides its :class:`Api <module.Api.Api>` as service.
More information about thrift can be found here http://wiki.apache.org/thrift/.
+
Using Thrift
------------
@@ -34,14 +35,15 @@ supported here http://wiki.apache.org/thrift/LibraryFeatures?action=show&redirec
Now install thrift, for instructions see http://wiki.apache.org/thrift/ThriftInstallation.
If every thing went fine you are ready to generate the method stubs, the command basically looks like this. ::
- $thrift --gen (language) pyload.thrift
+ $ thrift --gen (language) pyload.thrift
You find now a directory named :file:`gen-(language)`. For instruction how to use the generated files consider the docs
at the thrift wiki and the examples here http://wiki.apache.org/thrift/ThriftUsage.
+=======
Example
--------
+=======
In case you want to use python, pyload has already all files included to access the api over rpc.
A basic script that prints out some information: ::
@@ -62,4 +64,41 @@ A basic script that prints out some information: ::
print "Package Name: ", data.name
That's all for now, pretty easy isn't it?
-If you still have open questions come around in irc or post them at our pyload forum. \ No newline at end of file
+If you still have open questions come around in irc or post them at our pyload forum.
+
+
+Using HTTP/JSON
+---------------
+
+Another maybe easier way, which does not require much setup is to access the JSON Api via HTTP.
+For this reason the webinterface must be enabled.
+
+=====
+Login
+=====
+
+First you need to authenticate, if you using this within the webinterface and the user is logged the API is also accessible,
+since they share the same cookie/session.
+
+However, if you are building a external client and want to authenticate manually
+you have to send your credentials ``username`` and ``password`` as
+POST parameter to ``http://pyload-core/api/login``.
+
+The result will be your session id. If you are using cookies, it will be set and you can use the API now.
+In case you dont't have cookies enabled you can pass the session id as ``session`` POST parameter
+so pyLoad can authenticate you.
+
+===============
+Calling Methods
+===============
+
+In general you can use any method listed at the :class:`Api <module.Api.Api>` documentation, which is also available to
+the thriftbackend.
+
+Access works simply via ``http://pyload-core/api/methodName``. To pass arguments you have 2 choices.
+Either use positional arguments, eg ``http://pyload-core/api/getFileData/1``, where 1 is the FileID, or use keyword arguments
+supplied via GET or POST ``http://pyload-core/api/getFileData?fid=1``. You can find the argument names in the :class:`Api <module.Api.Api>`
+documentation. If one of the argument is a container data type, e.g a list, format it as json/python first and urlencode it before submitting.
+
+The return value will be formatted in JSON, complex data types as dictionaries.
+As mentionted above for a documentation about the return types look at the thrift specification file :file:`module/remote/thriftbackend/pyload.thrift`. \ No newline at end of file
diff --git a/docs/conf.py b/docs/conf.py
index cdd2bfc6f..331d13144 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -61,7 +61,7 @@ copyright = u'2011, pyLoad Team'
# The short X.Y version.
version = '0.4'
# The full version, including alpha/beta/rc tags.
-release = '0.4.7'
+release = '0.4.8'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/locale/generate_locale.py b/locale/generate_locale.py
index d519ca35f..0b18b1ad8 100644
--- a/locale/generate_locale.py
+++ b/locale/generate_locale.py
@@ -6,9 +6,21 @@ from os.path import join
from subprocess import call
-options = ["--from-code=utf-8", "--copyright-holder=pyLoad Team", "--package-name=pyLoad", "--package-version=0.4.5",
+options = ["--from-code=utf-8", "--copyright-holder=pyLoad Team", "--package-name=pyLoad", "--package-version=0.4.8",
"--msgid-bugs-address='bugs@pyload.org'"]
+
+def po2pot(name):
+ f = open("%s.po" % name, "rb")
+ content = f.read()
+ f.close()
+ remove("core.po")
+ content = content.replace("charset=CHARSET", "charset=UTF-8")
+
+ f = open("locale/%s.pot" % name, "wb")
+ f.write(content)
+ f.close()
+
###### Core
EXCLUDE = ["BeautifulSoup.py", "module/gui", "module/cli", "web/locale", "web/ajax", "web/cnl", "web/pyload", "setup.py"]
@@ -26,16 +38,7 @@ for path, dir, filenames in walk("./module"):
f.close()
call(["xgettext", "--files-from=includes.txt", "--default-domain=core"] + options)
-
-f = open("core.po", "rb")
-content = f.read()
-f.close()
-remove("core.po")
-content = content.replace("charset=CHARSET", "charset=UTF-8")
-
-f = open("locale/core.pot", "wb")
-f.write(content)
-f.close()
+po2pot("core")
########## GUI
@@ -55,16 +58,7 @@ for path, dir, filenames in walk("./module/gui"):
f.close()
call(["xgettext", "--files-from=includes.txt", "--default-domain=gui"] + options)
-
-f = open("gui.po", "rb")
-content = f.read()
-f.close()
-remove("gui.po")
-content = content.replace("charset=CHARSET", "charset=UTF-8")
-
-f = open("locale/gui.pot", "wb")
-f.write(content)
-f.close()
+po2pot("gui")
###### CLI
@@ -83,16 +77,7 @@ for path, dir, filenames in walk("./module/cli"):
f.close()
call(["xgettext", "--files-from=includes.txt", "--default-domain=cli"] + options)
-
-f = open("cli.po", "rb")
-content = f.read()
-f.close()
-remove("cli.po")
-content = content.replace("charset=CHARSET", "charset=UTF-8")
-
-f = open("locale/cli.pot", "wb")
-f.write(content)
-f.close()
+po2pot("cli")
###### Setup
@@ -103,16 +88,7 @@ f.write("./module/setup.py\n")
f.close()
call(["xgettext", "--files-from=includes.txt", "--default-domain=setup"] + options)
-
-f = open("setup.po", "rb")
-content = f.read()
-f.close()
-remove("setup.po")
-content = content.replace("charset=CHARSET", "charset=UTF-8")
-
-f = open("locale/setup.pot", "wb")
-f.write(content)
-f.close()
+po2pot("setup")
### Web
@@ -129,15 +105,7 @@ for path, dir, filenames in walk("./module/web"):
f.close()
call(["xgettext", "--files-from=includes.txt", "--default-domain=django", "--language=Python"] + options)
+po2pot("django")
-f = open("django.po", "rb")
-content = f.read()
-f.close()
-remove("django.po")
-content = content.replace("charset=CHARSET", "charset=UTF-8")
-
-f = open("locale/django.pot", "wb")
-f.write(content)
-f.close()
print
print "All finished."
diff --git a/module/Api.py b/module/Api.py
index 54aeff669..5583bb603 100644
--- a/module/Api.py
+++ b/module/Api.py
@@ -20,6 +20,7 @@
from base64 import standard_b64encode
from os.path import join
from time import time
+import re
from remote.thriftbackend.thriftgen.pyload.ttypes import *
from remote.thriftbackend.thriftgen.pyload.Pyload import Iface
@@ -28,6 +29,11 @@ from PyFile import PyFile
from database.UserDatabase import ROLE
from utils import freeSpace, compare_time
from common.packagetools import parseNames
+from network.RequestFactory import getURL
+
+
+urlmatcher = re.compile(r"((https?|ftps?|xdcc|sftp):((//)|(\\\\))+[\w\d:#@%/;$()~_?\+-=\\\.&]*)", re.IGNORECASE)
+
class Api(Iface):
"""
@@ -39,6 +45,8 @@ class Api(Iface):
for information about data structures and what methods are usuable with rpc.
"""
+ EXTERNAL = Iface # let the json api know which methods are external
+
def __init__(self, core):
self.core = core
@@ -54,7 +62,7 @@ class Api(Iface):
section = ConfigSection(sectionName, sub["desc"])
items = []
for key, data in sub.iteritems():
- if key in ("desc","outline"):
+ if key in ("desc", "outline"):
continue
item = ConfigItem()
item.name = key
@@ -130,7 +138,7 @@ class Api(Iface):
"""
return self.core.config.plugin
-
+
def pauseServer(self):
"""Pause server: Tt wont start any new downloads, but nothing gets aborted."""
self.core.threadManager.pause = True
@@ -175,7 +183,7 @@ class Api(Iface):
return freeSpace(self.core.config["general"]["download_folder"])
def getServerVersion(self):
- """pyLoad Core version """
+ """pyLoad Core version """
return self.core.version
def kill(self):
@@ -266,14 +274,30 @@ class Api(Iface):
return pid
- def parseURLs(self, html):
- # TODO parse
+ def parseURLs(self, html=None, url=None):
+ """Parses html content or any arbitaty text for links and returns result of `checkURLs`
+
+ :param html: html source
+ :return:
+ """
urls = []
+ if html:
+ urls += [x[0] for x in urlmatcher.findall(html)]
+
+ if url:
+ page = getURL(url)
+ urls += [x[0] for x in urlmatcher.findall(page)]
+
return self.checkURLs(urls)
def checkURLs(self, urls):
+ """ Gets urls and returns pluginname mapped to list of matches urls.
+
+ :param urls:
+ :return: {plugin: urls}
+ """
data = self.core.pluginManager.parseUrls(urls)
plugins = {}
@@ -289,7 +313,7 @@ class Api(Iface):
""" initiates online status check
:param urls:
- :return: initial set of data and the result id
+ :return: initial set of data as `OnlineCheck` instance containing the result id
"""
data = self.core.pluginManager.parseUrls(urls)
@@ -298,7 +322,7 @@ class Api(Iface):
tmp = [(url, (url, OnlineStatus(url, pluginname, "unknown", 3, 0))) for url, pluginname in data]
data = parseNames(tmp)
result = {}
-
+
for k, v in data.iteritems():
for url, status in v:
status.packagename = k
@@ -307,7 +331,7 @@ class Api(Iface):
return OnlineCheck(rid, result)
def checkOnlineStatusContainer(self, urls, container, data):
- """ checks online status of files and container file
+ """ checks online status of urls and a submited container file
:param urls: list of urls
:param container: container file name
@@ -323,8 +347,8 @@ class Api(Iface):
def pollResults(self, rid):
""" Polls the result available for ResultID
- :param rid: if -1 no more data is available
- :return:
+ :param rid: `ResultID`
+ :return: `OnlineCheck`, if rid is -1 then no more data available
"""
result = self.core.threadManager.getInfoResult(rid)
@@ -336,12 +360,12 @@ class Api(Iface):
def generatePackages(self, links):
- """ Parses links, generates packages names only from urls
+ """ Parses links, generates packages names from urls
:param links: list of urls
- :return: package names mapt to urls
+ :return: package names mapped to urls
"""
- result = parseNames((x,x) for x in links)
+ result = parseNames((x, x) for x in links)
return result
def generateAndAddPackages(self, links, dest=Destination.Queue):
@@ -365,7 +389,6 @@ class Api(Iface):
data = self.core.pluginManager.parseUrls(links)
self.core.threadManager.createResultThread(data, True)
-
def getPackageData(self, pid):
"""Returns complete information about package, and included files.
@@ -410,7 +433,7 @@ class Api(Iface):
info = self.core.files.getFileData(int(fid))
if not info:
raise FileDoesNotExists(fid)
-
+
fdata = self._convertPyFile(info.values()[0])
return fdata
diff --git a/module/database/UserDatabase.py b/module/database/UserDatabase.py
index 0e3011593..f888e219e 100644
--- a/module/database/UserDatabase.py
+++ b/module/database/UserDatabase.py
@@ -23,13 +23,14 @@ from hashlib import sha1
import random
class PERMS:
+ ALL = 0 # requires no permission, but login
ADD = 1 # can add packages
DELETE = 2 # can delete packages
STATUS = 4 # see and change server status
- SEE_DOWNLOADS = 16 # see queue and collector
+ SEE_DOWNLOADS = 16 # see queue and collector / modify downloads
DOWNLOAD = 32 # can download from webinterface
SETTINGS = 64 # can access settings
- FILEMANAGER = 128 # can manage files and folders trough webinterface
+ ACCOUNTS = 128 # can access accounts
class ROLE:
ADMIN = 0 #admin has all permissions implicit
diff --git a/module/remote/thriftbackend/ThriftClient.py b/module/remote/thriftbackend/ThriftClient.py
index 3b6a56448..27cb89b0d 100644
--- a/module/remote/thriftbackend/ThriftClient.py
+++ b/module/remote/thriftbackend/ThriftClient.py
@@ -17,9 +17,7 @@ from Protocol import Protocol
from thriftgen.pyload import Pyload
from thriftgen.pyload.ttypes import *
-from thriftgen.pyload.Pyload import PackageDoesNotExists
-from thriftgen.pyload.Pyload import FileDoesNotExists
-
+from thriftgen.pyload.Pyload import PackageDoesNotExists, FileDoesNotExists
ConnectionClosed = TTransport.TTransportException
diff --git a/module/remote/thriftbackend/generateThrift.sh b/module/remote/thriftbackend/generateThrift.sh
index 7acb8531c..c5ca72736 100755
--- a/module/remote/thriftbackend/generateThrift.sh
+++ b/module/remote/thriftbackend/generateThrift.sh
@@ -1,9 +1,7 @@
#!/bin/sh
rm -rf thriftgen
-# use thrift 0.7.0 from trunk
-# patched if needed https://issues.apache.org/jira/browse/THRIFT-1115?page=com.atlassian.jira.plugin.system.issuetabpanels%3Achangehistory-tabpanel#issue-tabs
-# --gen py:slots,dynamic
+# use thrift from trunk or a release with dynamic/slots python code generation
thrift -strict -v --gen py --gen java pyload.thrift
mv gen-py thriftgen
diff --git a/module/remote/thriftbackend/pyload.thrift b/module/remote/thriftbackend/pyload.thrift
index e7ae10055..dc085e180 100644
--- a/module/remote/thriftbackend/pyload.thrift
+++ b/module/remote/thriftbackend/pyload.thrift
@@ -211,7 +211,7 @@ service Pyload {
// packagename - urls
map<string, LinkList> generatePackages(1: LinkList links),
map<PluginName, LinkList> checkURLs(1: LinkList urls),
- map<PluginName, LinkList> parseURLs(1: string html),
+ map<PluginName, LinkList> parseURLs(1: string html, 2: string url),
// parses results and generates packages
OnlineCheck checkOnlineStatus(1: LinkList urls),
diff --git a/module/remote/thriftbackend/thriftgen/pyload/Pyload-remote b/module/remote/thriftbackend/thriftgen/pyload/Pyload-remote
index 6c8116d92..0251fbeae 100755
--- a/module/remote/thriftbackend/thriftgen/pyload/Pyload-remote
+++ b/module/remote/thriftbackend/thriftgen/pyload/Pyload-remote
@@ -41,7 +41,7 @@ if len(sys.argv) <= 1 or sys.argv[1] == '--help':
print ' bool toggleReconnect()'
print ' generatePackages(LinkList links)'
print ' checkURLs(LinkList urls)'
- print ' parseURLs(string html)'
+ print ' parseURLs(string html, string url)'
print ' OnlineCheck checkOnlineStatus(LinkList urls)'
print ' OnlineCheck checkOnlineStatusContainer(LinkList urls, string filename, string data)'
print ' OnlineCheck pollResults(ResultID rid)'
@@ -251,10 +251,10 @@ elif cmd == 'checkURLs':
pp.pprint(client.checkURLs(eval(args[0]),))
elif cmd == 'parseURLs':
- if len(args) != 1:
- print 'parseURLs requires 1 args'
+ if len(args) != 2:
+ print 'parseURLs requires 2 args'
sys.exit(1)
- pp.pprint(client.parseURLs(args[0],))
+ pp.pprint(client.parseURLs(args[0],args[1],))
elif cmd == 'checkOnlineStatus':
if len(args) != 1:
diff --git a/module/remote/thriftbackend/thriftgen/pyload/Pyload.py b/module/remote/thriftbackend/thriftgen/pyload/Pyload.py
index a29eed62f..828ff520d 100644
--- a/module/remote/thriftbackend/thriftgen/pyload/Pyload.py
+++ b/module/remote/thriftbackend/thriftgen/pyload/Pyload.py
@@ -9,7 +9,7 @@
from thrift.Thrift import TType, TMessageType
from ttypes import *
from thrift.Thrift import TProcessor
-from thrift.protocol.TBase import TBase, TExceptionBase
+from thrift.protocol.TBase import TBase, TExceptionBase, TApplicationException
class Iface(object):
@@ -92,10 +92,11 @@ class Iface(object):
"""
pass
- def parseURLs(self, html):
+ def parseURLs(self, html, url):
"""
Parameters:
- html
+ - url
"""
pass
@@ -905,18 +906,20 @@ class Client(Iface):
return result.success
raise TApplicationException(TApplicationException.MISSING_RESULT, "checkURLs failed: unknown result");
- def parseURLs(self, html):
+ def parseURLs(self, html, url):
"""
Parameters:
- html
+ - url
"""
- self.send_parseURLs(html)
+ self.send_parseURLs(html, url)
return self.recv_parseURLs()
- def send_parseURLs(self, html):
+ def send_parseURLs(self, html, url):
self._oprot.writeMessageBegin('parseURLs', TMessageType.CALL, self._seqid)
args = parseURLs_args()
args.html = html
+ args.url = url
args.write(self._oprot)
self._oprot.writeMessageEnd()
self._oprot.trans.flush()
@@ -2678,7 +2681,7 @@ class Processor(Iface, TProcessor):
args.read(iprot)
iprot.readMessageEnd()
result = parseURLs_result()
- result.success = self._handler.parseURLs(args.html)
+ result.success = self._handler.parseURLs(args.html, args.url)
oprot.writeMessageBegin("parseURLs", TMessageType.REPLY, seqid)
result.write(oprot)
oprot.writeMessageEnd()
@@ -3769,19 +3772,23 @@ class parseURLs_args(TBase):
"""
Attributes:
- html
+ - url
"""
__slots__ = [
'html',
+ 'url',
]
thrift_spec = (
None, # 0
(1, TType.STRING, 'html', None, None, ), # 1
+ (2, TType.STRING, 'url', None, None, ), # 2
)
- def __init__(self, html=None,):
+ def __init__(self, html=None, url=None,):
self.html = html
+ self.url = url
class parseURLs_result(TBase):
diff --git a/module/web/api_app.py b/module/web/api_app.py
new file mode 100644
index 000000000..7d1a95c58
--- /dev/null
+++ b/module/web/api_app.py
@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+# -*- 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 thrift.protocol.TBase import TBase
+
+from utils import toDict, set_session
+
+from webinterface import PYLOAD
+
+from module.common.json import json_dumps
+from module.database.UserDatabase import ROLE
+
+try:
+ from ast import literal_eval
+except ImportError: # python 2.5
+ from module.lib.SafeEval import safe_eval as literal_eval
+
+
+# convert to format serializable by json
+def traverse(data):
+ if type(data) == list:
+ return [traverse(x) for x in data]
+ elif type(data) == dict:
+ return dict([(x, traverse(y)) for x, y in data.iteritems()])
+ elif isinstance(data, TBase):
+ return toDict(data)
+ else:
+ return data
+
+
+# accepting positional arguments, as well as kwargs via post and get
+
+@route("/api/:func:args#[a-zA-Z0-9\-_/\"'\[\]%{}]*#")
+@route("/api/:func:args#[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) or s.get("role", -1) != ROLE.ADMIN:
+ 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()]))
+
+ return json_dumps(traverse(result))
+
+
+#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:
+ 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/module/web/pyload_app.py b/module/web/pyload_app.py
index 8d76d39ec..49568baad 100644
--- a/module/web/pyload_app.py
+++ b/module/web/pyload_app.py
@@ -32,7 +32,7 @@ from bottle import route, static_file, request, response, redirect, HTTPError, e
from webinterface import PYLOAD, PYLOAD_DIR, PROJECT_DIR, SETUP
from utils import render_to_response, parse_permissions, parse_userdata, \
- login_required, get_permission, set_permission, toDict
+ login_required, get_permission, set_permission, toDict, set_session
from filters import relpath, unquotepath
@@ -119,15 +119,7 @@ def login_post():
if not info:
return render_to_response("login.html", {"errors": True}, [pre_processor])
- s = request.environ.get('beaker.session')
- s["authenticated"] = True
- s["id"] = info["id"]
- s["name"] = info["name"]
- s["role"] = info["role"]
- s["perms"] = info["permission"]
- s["template"] = info["template"]
- s.save()
-
+ set_session(request, info)
return redirect("/")
diff --git a/module/web/utils.py b/module/web/utils.py
index b99736216..39ddb361f 100644
--- a/module/web/utils.py
+++ b/module/web/utils.py
@@ -52,6 +52,7 @@ def parse_permissions(session):
return perms
+
def get_permission(perms, p):
perms["add"] = has_permission(p, PERMS.ADD)
perms["delete"] = has_permission(p, PERMS.DELETE)
@@ -59,7 +60,7 @@ def get_permission(perms, p):
perms["see_downloads"] = has_permission(p, PERMS.SEE_DOWNLOADS)
perms["download"] = has_permission(p, PERMS.DOWNLOAD)
perms["settings"] = has_permission(p, PERMS.SETTINGS)
- perms["filemanager"] = has_permission(p, PERMS.FILEMANAGER)
+ perms["accounts"] = has_permission(p, PERMS.ACCOUNTS)
def set_permission(perms):
permission = 0
@@ -75,11 +76,24 @@ def set_permission(perms):
permission |= PERMS.DOWNLOAD
if perms["settings"]:
permission |= PERMS.SETTINGS
- if perms["filemanager"]:
- permission |= PERMS.FILEMANAGER
+ if perms["accounts"]:
+ permission |= PERMS.ACCOUNTS
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,
diff --git a/module/web/webinterface.py b/module/web/webinterface.py
index 4d07c436e..d2b96b03c 100644
--- a/module/web/webinterface.py
+++ b/module/web/webinterface.py
@@ -105,6 +105,7 @@ web = GZipMiddleWare(web)
import pyload_app
import json_app
import cnl_app
+import api_app
def run_simple(host="0.0.0.0", port="8000"):
run(app=web, host=host, port=port, quiet=True)