summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
Diffstat (limited to 'module')
-rw-r--r--module/Api.py12
-rw-r--r--module/common/ImportDebugger.py20
-rw-r--r--module/config/default.conf1
-rw-r--r--module/remote/ClickAndLoadBackend.py170
-rw-r--r--module/remote/RemoteManager.py20
-rw-r--r--module/remote/SocketBackend.py25
-rw-r--r--module/remote/XMLRPCBackend.py40
-rw-r--r--module/remote/__init__.py3
-rw-r--r--module/remote/socketbackend/__init__.py2
-rw-r--r--module/remote/socketbackend/create_ttypes.py87
-rw-r--r--module/remote/socketbackend/ttypes.py352
-rw-r--r--module/setup.py20
-rw-r--r--module/web/api_app.py5
13 files changed, 702 insertions, 55 deletions
diff --git a/module/Api.py b/module/Api.py
index 11072b2cd..ba79a31ef 100644
--- a/module/Api.py
+++ b/module/Api.py
@@ -22,14 +22,18 @@ 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
-
from PyFile import PyFile
from utils import freeSpace, compare_time
from common.packagetools import parseNames
from network.RequestFactory import getURL
-
+from remote import activated
+
+if activated:
+ from remote.thriftbackend.thriftgen.pyload.ttypes import *
+ from remote.thriftbackend.thriftgen.pyload.Pyload import Iface
+ BaseObject = TBase
+else:
+ from remote.socketbackend.ttypes import *
# contains function names mapped to their permissions
# unlisted functions are for admins only
diff --git a/module/common/ImportDebugger.py b/module/common/ImportDebugger.py
new file mode 100644
index 000000000..fdc6d90cf
--- /dev/null
+++ b/module/common/ImportDebugger.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+
+
+import sys
+
+class ImportDebugger(object):
+
+ def __init__(self):
+ self.imported = {}
+
+ def find_module(self, name, path=None):
+
+ if name not in self.imported:
+ self.imported[name] = 0
+
+ self.imported[name] += 1
+
+ print name, path
+
+sys.meta_path.append(ImportDebugger()) \ No newline at end of file
diff --git a/module/config/default.conf b/module/config/default.conf
index 88ccc70e0..b63a06b4c 100644
--- a/module/config/default.conf
+++ b/module/config/default.conf
@@ -4,6 +4,7 @@ remote - "Remote":
int port : "Port" = 7227
ip listenaddr : "Adress" = 0.0.0.0
bool nolocalauth : "No authentication on local connections" = True
+ bool activated : "Activated" = True
ssl - "SSL":
bool activated : "Activated"= False
file cert : "SSL Certificate" = ssl.crt
diff --git a/module/remote/ClickAndLoadBackend.py b/module/remote/ClickAndLoadBackend.py
new file mode 100644
index 000000000..ad8031587
--- /dev/null
+++ b/module/remote/ClickAndLoadBackend.py
@@ -0,0 +1,170 @@
+# -*- coding: utf-8 -*-
+"""
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+ @author: RaNaN
+"""
+import re
+from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
+from cgi import FieldStorage
+from urllib import unquote
+from base64 import standard_b64decode
+from binascii import unhexlify
+
+try:
+ from Crypto.Cipher import AES
+except:
+ pass
+
+from RemoteManager import BackendBase
+
+core = None
+js = None
+
+class ClickAndLoadBackend(BackendBase):
+ def setup(self, host, port):
+ self.httpd = HTTPServer((host, port), CNLHandler)
+ global core, js
+ core = self.m.core
+ js = core.js
+
+ def serve(self):
+ while self.enabled:
+ self.httpd.handle_request()
+
+class CNLHandler(BaseHTTPRequestHandler):
+
+ def add_package(self, name, urls, queue=0):
+ print "name", name
+ print "urls", urls
+ print "queue", queue
+
+ def get_post(self, name, default=""):
+ if name in self.post:
+ return self.post[name]
+ else:
+ return default
+
+ def start_response(self, string):
+
+ self.send_response(200)
+
+ self.send_header("Content-Length", len(string))
+ self.send_header("Content-Language", "de")
+ self.send_header("Vary", "Accept-Language, Cookie")
+ self.send_header("Cache-Control", "no-cache, must-revalidate")
+ self.send_header("Content-type", "text/html")
+ self.end_headers()
+
+ def do_GET(self):
+ path = self.path.strip("/").lower()
+ #self.wfile.write(path+"\n")
+
+ self.map = [ (r"add$", self.add),
+ (r"addcrypted$", self.addcrypted),
+ (r"addcrypted2$", self.addcrypted2),
+ (r"flashgot", self.flashgot),
+ (r"crossdomain\.xml", self.crossdomain),
+ (r"checkSupportForUrl", self.checksupport),
+ (r"jdcheck.js", self.jdcheck),
+ (r"", self.flash) ]
+
+ func = None
+ for r, f in self.map:
+ if re.match(r"(flash(got)?/?)?"+r, path):
+ func = f
+ break
+
+ if func:
+ try:
+ resp = func()
+ if not resp: resp = "success"
+ resp += "\r\n"
+ self.start_response(resp)
+ self.wfile.write(resp)
+ except Exception,e :
+ self.send_error(500, str(e))
+ else:
+ self.send_error(404, "Not Found")
+
+ def do_POST(self):
+ form = FieldStorage(
+ fp=self.rfile,
+ headers=self.headers,
+ environ={'REQUEST_METHOD':'POST',
+ 'CONTENT_TYPE':self.headers['Content-Type'],
+ })
+
+ self.post = {}
+ for name in form.keys():
+ self.post[name] = form[name].value
+
+ return self.do_GET()
+
+ def flash(self):
+ return "JDownloader"
+
+ def add(self):
+ package = self.get_post('referer', 'ClickAndLoad Package')
+ urls = filter(lambda x: x != "", self.get_post('urls').split("\n"))
+
+ self.add_package(package, urls, 0)
+
+ def addcrypted(self):
+ package = self.get_post('referer', 'ClickAndLoad Package')
+ dlc = self.get_post('crypted').replace(" ", "+")
+
+ core.upload_container(package, dlc)
+
+ def addcrypted2(self):
+ package = self.get_post("source", "ClickAndLoad Package")
+ crypted = self.get_post("crypted")
+ jk = self.get_post("jk")
+
+ crypted = standard_b64decode(unquote(crypted.replace(" ", "+")))
+ jk = "%s f()" % jk
+ jk = js.eval(jk)
+ Key = unhexlify(jk)
+ 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)
+
+ self.add_package(package, result, 0)
+
+
+ def flashgot(self):
+ autostart = int(self.get_post('autostart', 0))
+ package = self.get_post('package', "FlashGot")
+ urls = filter(lambda x: x != "", self.get_post('urls').split("\n"))
+
+ self.add_package(package, urls, autostart)
+
+ def crossdomain(self):
+ 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
+
+ def checksupport(self):
+ pass
+
+ def jdcheck(self):
+ rep = "jdownloader=true;\n"
+ rep += "var version='10629';\n"
+ return rep
diff --git a/module/remote/RemoteManager.py b/module/remote/RemoteManager.py
index 2ac26a677..6caedad90 100644
--- a/module/remote/RemoteManager.py
+++ b/module/remote/RemoteManager.py
@@ -24,14 +24,19 @@ class BackendBase(Thread):
Thread.__init__(self)
self.m = manager
self.core = manager.core
+ self.enabled = True
+ self.running = False
def run(self):
+ self.running = True
try:
self.serve()
except Exception, e:
self.core.log.error(_("Remote backend error: %s") % e)
if self.core.debug:
print_exc()
+ finally:
+ self.running = False
def setup(self, host, port):
pass
@@ -42,14 +47,27 @@ class BackendBase(Thread):
def serve(self):
pass
+ def shutdown(self):
+ pass
+
+ def stop(self):
+ self.enabled = False# set flag and call shutdowm message, so thread can react
+ self.shutdown()
+
class RemoteManager():
- available = ["ThriftBackend"]
+ available = []
def __init__(self, core):
self.core = core
self.backends = []
+ if self.core.remote:
+ self.available.append("ThriftBackend")
+ else:
+ self.available.append("SocketBackend")
+
+
def startBackends(self):
host = self.core.config["remote"]["listenaddr"]
port = self.core.config["remote"]["port"]
diff --git a/module/remote/SocketBackend.py b/module/remote/SocketBackend.py
new file mode 100644
index 000000000..1a157cf1d
--- /dev/null
+++ b/module/remote/SocketBackend.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+
+import SocketServer
+
+from RemoteManager import BackendBase
+
+class RequestHandler(SocketServer.BaseRequestHandler):
+
+ def setup(self):
+ pass
+
+ def handle(self):
+
+ print self.request.recv(1024)
+
+
+
+class SocketBackend(BackendBase):
+
+ def setup(self, host, port):
+ #local only
+ self.server = SocketServer.ThreadingTCPServer(("localhost", port), RequestHandler)
+
+ def serve(self):
+ self.server.serve_forever()
diff --git a/module/remote/XMLRPCBackend.py b/module/remote/XMLRPCBackend.py
deleted file mode 100644
index 003dc29ea..000000000
--- a/module/remote/XMLRPCBackend.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- @author: mkaay, RaNaN
-"""
-from os.path import exists
-
-import module.lib.SecureXMLRPCServer as Server
-from module.remote.RemoteManager import BackendBase
-
-class XMLRPCBackend(BackendBase):
- def setup(self, host, port):
- server_addr = (host, port)
- if self.core.config['ssl']['activated']:
- if exists(self.core.config['ssl']['cert']) and exists(self.core.config['ssl']['key']):
- self.core.log.info(_("Using SSL XMLRPCBackend"))
- self.server = Server.SecureXMLRPCServer(server_addr, self.core.config['ssl']['cert'],
- self.core.config['ssl']['key'], self.checkAuth)
- else:
- self.core.log.warning(_("SSL Certificates not found, fallback to auth XMLRPC server"))
- self.server = Server.AuthXMLRPCServer(server_addr, self.checkAuth)
- else:
- self.server = Server.AuthXMLRPCServer(server_addr, self.checkAuth)
-
- self.server.register_instance(self.core.api)
-
- def serve(self):
- self.server.serve_forever()
diff --git a/module/remote/__init__.py b/module/remote/__init__.py
index 8d1c8b69c..9298f5337 100644
--- a/module/remote/__init__.py
+++ b/module/remote/__init__.py
@@ -1 +1,2 @@
-
+# -*- coding: utf-8 -*-
+activated = True
diff --git a/module/remote/socketbackend/__init__.py b/module/remote/socketbackend/__init__.py
new file mode 100644
index 000000000..de6d13128
--- /dev/null
+++ b/module/remote/socketbackend/__init__.py
@@ -0,0 +1,2 @@
+__author__ = 'christian'
+ \ No newline at end of file
diff --git a/module/remote/socketbackend/create_ttypes.py b/module/remote/socketbackend/create_ttypes.py
new file mode 100644
index 000000000..db27bd02f
--- /dev/null
+++ b/module/remote/socketbackend/create_ttypes.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import sys
+from os.path import abspath, dirname, join
+
+path = dirname(abspath(__file__))
+module = join(path, "..", "..")
+
+sys.path.append(join(module, "lib"))
+sys.path.append(join(module, "remote"))
+
+from thriftbackend.thriftgen.pyload import ttypes
+from thriftbackend.thriftgen.pyload.Pyload import Iface
+
+
+def main():
+
+ enums = []
+ classes = []
+
+ print "generating lightweight ttypes.py"
+
+ for name in dir(ttypes):
+ klass = getattr(ttypes, name)
+
+ if name in ("TBase", "TExceptionBase") or name.startswith("_") or not (issubclass(klass, ttypes.TBase) or issubclass(klass, ttypes.TExceptionBase)):
+ continue
+
+ if hasattr(klass, "thrift_spec"):
+ classes.append(klass)
+ else:
+ enums.append(klass)
+
+
+ f = open(join(path, "ttypes.py"), "wb")
+
+ f.write(
+ """#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Autogenerated by pyload
+# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+
+class BaseObject(object):
+ __slots__ = []
+
+""")
+
+ ## generate enums
+ for enum in enums:
+ name = enum.__name__
+ f.write("class %s:\n" % name)
+
+ for attr in dir(enum):
+ if attr.startswith("_") or attr in ("read", "write"): continue
+
+ f.write("\t%s = %s\n" % (attr, getattr(enum, attr)))
+
+ f.write("\n")
+
+ for klass in classes:
+ name = klass.__name__
+ base = "BaseException" if issubclass(klass, ttypes.TExceptionBase) else "BaseObject"
+ f.write("class %s(%s):\n" % (name, base))
+ f.write("\t__slots__ = %s\n\n" % klass.__slots__)
+
+ #create init
+ args = ["self"] + ["%s=None" % x for x in klass.__slots__]
+
+ f.write("\tdef init(%s):\n" % ", ".join(args))
+ for attr in klass.__slots__:
+ f.write("\t\tself.%s = %s\n" % (attr, attr))
+
+ f.write("\n")
+
+ f.write("class Iface:\n")
+
+ for name in dir(Iface):
+ if name.startswith("_"): continue
+ f.write("\tdef %s():\n\t\tpass\n" % name)
+
+ f.write("\n")
+
+ f.close()
+
+if __name__ == "__main__":
+ main() \ No newline at end of file
diff --git a/module/remote/socketbackend/ttypes.py b/module/remote/socketbackend/ttypes.py
new file mode 100644
index 000000000..30a7d3adc
--- /dev/null
+++ b/module/remote/socketbackend/ttypes.py
@@ -0,0 +1,352 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Autogenerated by pyload
+# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+
+class BaseObject(object):
+ __slots__ = []
+
+class Destination:
+ Collector = 0
+ Queue = 1
+
+class DownloadStatus:
+ Aborted = 9
+ Custom = 11
+ Decrypting = 10
+ Downloading = 12
+ Failed = 8
+ Finished = 0
+ Offline = 1
+ Online = 2
+ Processing = 13
+ Queued = 3
+ Skipped = 4
+ Starting = 7
+ TempOffline = 6
+ Unknown = 14
+ Waiting = 5
+
+class ElementType:
+ File = 1
+ Package = 0
+
+class AccountInfo(BaseObject):
+ __slots__ = ['validuntil', 'login', 'options', 'valid', 'trafficleft', 'maxtraffic', 'premium', 'type']
+
+ def init(self, validuntil=None, login=None, options=None, valid=None, trafficleft=None, maxtraffic=None, premium=None, type=None):
+ self.validuntil = validuntil
+ self.login = login
+ self.options = options
+ self.valid = valid
+ self.trafficleft = trafficleft
+ self.maxtraffic = maxtraffic
+ self.premium = premium
+ self.type = type
+
+class CaptchaTask(BaseObject):
+ __slots__ = ['tid', 'data', 'type', 'resultType']
+
+ def init(self, tid=None, data=None, type=None, resultType=None):
+ self.tid = tid
+ self.data = data
+ self.type = type
+ self.resultType = resultType
+
+class ConfigItem(BaseObject):
+ __slots__ = ['name', 'description', 'value', 'type']
+
+ def init(self, name=None, description=None, value=None, type=None):
+ self.name = name
+ self.description = description
+ self.value = value
+ self.type = type
+
+class ConfigSection(BaseObject):
+ __slots__ = ['name', 'description', 'items', 'outline']
+
+ def init(self, name=None, description=None, items=None, outline=None):
+ self.name = name
+ self.description = description
+ self.items = items
+ self.outline = outline
+
+class DownloadInfo(BaseObject):
+ __slots__ = ['fid', 'name', 'speed', 'eta', 'format_eta', 'bleft', 'size', 'format_size', 'percent', 'status', 'statusmsg', 'format_wait', 'wait_until', 'packageID', 'packageName', 'plugin']
+
+ def init(self, fid=None, name=None, speed=None, eta=None, format_eta=None, bleft=None, size=None, format_size=None, percent=None, status=None, statusmsg=None, format_wait=None, wait_until=None, packageID=None, packageName=None, plugin=None):
+ self.fid = fid
+ self.name = name
+ self.speed = speed
+ self.eta = eta
+ self.format_eta = format_eta
+ self.bleft = bleft
+ self.size = size
+ self.format_size = format_size
+ self.percent = percent
+ self.status = status
+ self.statusmsg = statusmsg
+ self.format_wait = format_wait
+ self.wait_until = wait_until
+ self.packageID = packageID
+ self.packageName = packageName
+ self.plugin = plugin
+
+class EventInfo(BaseObject):
+ __slots__ = ['eventname', 'id', 'type', 'destination']
+
+ def init(self, eventname=None, id=None, type=None, destination=None):
+ self.eventname = eventname
+ self.id = id
+ self.type = type
+ self.destination = destination
+
+class FileData(BaseObject):
+ __slots__ = ['fid', 'url', 'name', 'plugin', 'size', 'format_size', 'status', 'statusmsg', 'packageID', 'error', 'order']
+
+ def init(self, fid=None, url=None, name=None, plugin=None, size=None, format_size=None, status=None, statusmsg=None, packageID=None, error=None, order=None):
+ self.fid = fid
+ self.url = url
+ self.name = name
+ self.plugin = plugin
+ self.size = size
+ self.format_size = format_size
+ self.status = status
+ self.statusmsg = statusmsg
+ self.packageID = packageID
+ self.error = error
+ self.order = order
+
+class FileDoesNotExists(BaseException):
+ __slots__ = ['fid']
+
+ def init(self, fid=None):
+ self.fid = fid
+
+class OnlineCheck(BaseObject):
+ __slots__ = ['rid', 'data']
+
+ def init(self, rid=None, data=None):
+ self.rid = rid
+ self.data = data
+
+class OnlineStatus(BaseObject):
+ __slots__ = ['name', 'plugin', 'packagename', 'status', 'size']
+
+ def init(self, name=None, plugin=None, packagename=None, status=None, size=None):
+ self.name = name
+ self.plugin = plugin
+ self.packagename = packagename
+ self.status = status
+ self.size = size
+
+class PackageData(BaseObject):
+ __slots__ = ['pid', 'name', 'folder', 'site', 'password', 'dest', 'order', 'linksdone', 'sizedone', 'sizetotal', 'linkstotal', 'links', 'fids']
+
+ def init(self, pid=None, name=None, folder=None, site=None, password=None, dest=None, order=None, linksdone=None, sizedone=None, sizetotal=None, linkstotal=None, links=None, fids=None):
+ self.pid = pid
+ self.name = name
+ self.folder = folder
+ self.site = site
+ self.password = password
+ self.dest = dest
+ self.order = order
+ self.linksdone = linksdone
+ self.sizedone = sizedone
+ self.sizetotal = sizetotal
+ self.linkstotal = linkstotal
+ self.links = links
+ self.fids = fids
+
+class PackageDoesNotExists(BaseException):
+ __slots__ = ['pid']
+
+ def init(self, pid=None):
+ self.pid = pid
+
+class ServerStatus(BaseObject):
+ __slots__ = ['pause', 'active', 'queue', 'total', 'speed', 'download', 'reconnect']
+
+ def init(self, pause=None, active=None, queue=None, total=None, speed=None, download=None, reconnect=None):
+ self.pause = pause
+ self.active = active
+ self.queue = queue
+ self.total = total
+ self.speed = speed
+ self.download = download
+ self.reconnect = reconnect
+
+class ServiceCall(BaseObject):
+ __slots__ = ['plugin', 'func', 'arguments', 'parseArguments']
+
+ def init(self, plugin=None, func=None, arguments=None, parseArguments=None):
+ self.plugin = plugin
+ self.func = func
+ self.arguments = arguments
+ self.parseArguments = parseArguments
+
+class ServiceDoesNotExists(BaseException):
+ __slots__ = ['plugin', 'func']
+
+ def init(self, plugin=None, func=None):
+ self.plugin = plugin
+ self.func = func
+
+class ServiceException(BaseException):
+ __slots__ = ['msg']
+
+ def init(self, msg=None):
+ self.msg = msg
+
+class UserData(BaseObject):
+ __slots__ = ['name', 'email', 'role', 'permission', 'templateName']
+
+ def init(self, name=None, email=None, role=None, permission=None, templateName=None):
+ self.name = name
+ self.email = email
+ self.role = role
+ self.permission = permission
+ self.templateName = templateName
+
+class Iface:
+ def addFiles():
+ pass
+ def addPackage():
+ pass
+ def call():
+ pass
+ def checkOnlineStatus():
+ pass
+ def checkOnlineStatusContainer():
+ pass
+ def checkURLs():
+ pass
+ def deleteFiles():
+ pass
+ def deleteFinished():
+ pass
+ def deletePackages():
+ pass
+ def freeSpace():
+ pass
+ def generateAndAddPackages():
+ pass
+ def generatePackages():
+ pass
+ def getAccountTypes():
+ pass
+ def getAccounts():
+ pass
+ def getAllInfo():
+ pass
+ def getAllUserData():
+ pass
+ def getCaptchaTask():
+ pass
+ def getCaptchaTaskStatus():
+ pass
+ def getCollector():
+ pass
+ def getCollectorData():
+ pass
+ def getConfig():
+ pass
+ def getConfigValue():
+ pass
+ def getEvents():
+ pass
+ def getFileData():
+ pass
+ def getFileOrder():
+ pass
+ def getInfoByPlugin():
+ pass
+ def getLog():
+ pass
+ def getPackageData():
+ pass
+ def getPackageInfo():
+ pass
+ def getPackageOrder():
+ pass
+ def getPluginConfig():
+ pass
+ def getQueue():
+ pass
+ def getQueueData():
+ pass
+ def getServerVersion():
+ pass
+ def getServices():
+ pass
+ def getUserData():
+ pass
+ def hasService():
+ pass
+ def isCaptchaWaiting():
+ pass
+ def isTimeDownload():
+ pass
+ def isTimeReconnect():
+ pass
+ def kill():
+ pass
+ def login():
+ pass
+ def moveFiles():
+ pass
+ def movePackage():
+ pass
+ def orderFile():
+ pass
+ def orderPackage():
+ pass
+ def parseURLs():
+ pass
+ def pauseServer():
+ pass
+ def pollResults():
+ pass
+ def pullFromQueue():
+ pass
+ def pushToQueue():
+ pass
+ def recheckPackage():
+ pass
+ def removeAccount():
+ pass
+ def restart():
+ pass
+ def restartFailed():
+ pass
+ def restartFile():
+ pass
+ def restartPackage():
+ pass
+ def setCaptchaResult():
+ pass
+ def setConfigValue():
+ pass
+ def setPackageData():
+ pass
+ def setPackageName():
+ pass
+ def statusDownloads():
+ pass
+ def statusServer():
+ pass
+ def stopAllDownloads():
+ pass
+ def stopDownloads():
+ pass
+ def togglePause():
+ pass
+ def toggleReconnect():
+ pass
+ def unpauseServer():
+ pass
+ def updateAccount():
+ pass
+ def uploadContainer():
+ pass
+
diff --git a/module/setup.py b/module/setup.py
index 8677fb65a..4a1c59da6 100644
--- a/module/setup.py
+++ b/module/setup.py
@@ -238,12 +238,14 @@ class Setup():
try:
import jinja2
- if jinja2.__version__ and "unknown" not in jinja2.__version__ and not jinja2.__version__.startswith("2.5"): #@TODO: could be to new aswell
- print _("Your installed jinja2 version %s seems too old.") % jinja2.__version__
- print _("You can safely continue but if the webinterface is not working,")
- print _("please upgrade or deinstall it, pyLoad includes a sufficient jinja2 libary.")
- print
- jinja = False
+ v = jinja2.__version__
+ if v and "unknown" not in v:
+ if not v.startswith("2.5") and not v.startswith("2.6"):
+ print _("Your installed jinja2 version %s seems too old.") % jinja2.__version__
+ print _("You can safely continue but if the webinterface is not working,")
+ print _("please upgrade or deinstall it, pyLoad includes a sufficient jinja2 libary.")
+ print
+ jinja = False
except :
pass
@@ -278,6 +280,12 @@ class Setup():
db.shutdown()
print ""
+ print _("External clients (GUI, CLI or other) need remote access to work over the network.")
+ print _("However, if you only want to use the webinterface you may disable it to save ram.")
+ self.config["remote"]["activated"] = self.ask(_("Enable remote access"), "y", bool=True)
+
+
+ print ""
langs = self.config.getMetaData("general", "language")
self.config["general"]["language"] = self.ask(_("Language"), "en", langs["type"].split(";"))
diff --git a/module/web/api_app.py b/module/web/api_app.py
index db735a5b9..1629c1677 100644
--- a/module/web/api_app.py
+++ b/module/web/api_app.py
@@ -7,19 +7,18 @@ 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_layer import json
from module.lib.SafeEval import const_eval as literal_eval
+from module.Api import BaseObject
# json encoder that accepts TBase objects
class TBaseEncoder(json.JSONEncoder):
def default(self, o):
- if isinstance(o, TBase):
+ if isinstance(o, BaseObject):
return toDict(o)
return json.JSONEncoder.default(self, o)