# -*- 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 . @author: mkaay """ from module.remote.RemoteManager import BackendBase from module.PyFile import PyFile from module.remote.thriftgen.pyload import Pyload from module.remote.thriftgen.pyload.ttypes import * from thrift.transport import TSocket from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol from thrift.server import TServer import threading import logging class Processor(Pyload.Processor): def __init__(self, *args, **kwargs): Pyload.Processor.__init__(self, *args, **kwargs) self.authenticated = {} def process(self, iprot, oprot): trans = oprot.trans if not self.authenticated.has_key(trans): self.authenticated[trans] = False oldclose = trans.close def wrap(): del self.authenticated[trans] oldclose() trans.close = wrap authenticated = self.authenticated[trans] (name, type, seqid) = iprot.readMessageBegin() if name not in self._processMap or (not authenticated and not name == "login"): iprot.skip(Pyload.TType.STRUCT) iprot.readMessageEnd() x = Pyload.TApplicationException(Pyload.TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name)) oprot.writeMessageBegin(name, Pyload.TMessageType.EXCEPTION, seqid) x.write(oprot) oprot.writeMessageEnd() oprot.trans.flush() return elif not authenticated and name == "login": args = Pyload.login_args() args.read(iprot) iprot.readMessageEnd() result = Pyload.login_result() self.authenticated[trans] = self._handler.login(args.username, args.password) result.success = self.authenticated[trans] oprot.writeMessageBegin("login", Pyload.TMessageType.REPLY, seqid) result.write(oprot) oprot.writeMessageEnd() oprot.trans.flush() else: self._processMap[name](self, seqid, iprot, oprot) return True class PyloadHandler: def __init__(self, backend): self.backend = backend self.core = backend.core self.serverMethods = self.core.server_methods #general def getConfigValue(self, category, option, section): """ Parameters: - category - option - section """ self.serverMethods.get_conf_val(category, option, section) def setConfigValue(self, category, option, value, section): """ Parameters: - category - option - value - section """ self.serverMethods.set_conf_val(category, option, value, section) def _convertConfigFormat(self, c): sections = [] for sectionName, sub in c.iteritems(): section = ConfigSection() section.name = sectionName section.decription = sub["desc"] items = [] for key, data in sub.iteritems(): if key == "desc": continue item = ConfigItem() item.name = key item.decription = data["desc"] item.value = str(data["value"]) if data["type"] == "str": item.type = ConfigItemType.String elif data["type"] == "int": item.type = ConfigItemType.Integer elif data["type"] == "bool": item.type = ConfigItemType.Bool elif data["type"] == "password": item.type = ConfigItemType.Password elif data["type"] == "ip": item.type = ConfigItemType.IP elif data["type"] == "file": item.type = ConfigItemType.File elif data["type"] == "folder": item.type = ConfigItemType.Folder elif data["type"] == "time": item.type = ConfigItemType.Time else: item.type = ConfigItemType.Choice item.choice = set([x.strip() for x in data["type"].split(";")]) items.append(item) section.items = items sections.append(section) return sections def getConfig(self): c = self.serverMethods.get_config() return self._convertConfigFormat(c) def getPluginConfig(self): c = self.serverMethods.get_plugin_config() return self._convertConfigFormat(c) def pauseServer(self): self.serverMethods.pause_server() def unpauseServer(self): self.serverMethods.unpause_server() def togglePause(self): return self.serverMethods.toggle_server() def statusServer(self): status = self.serverMethods.status_server() serverStatus = ServerStatus() serverStatus.pause = status["pause"] serverStatus.active = status["activ"] serverStatus.queue = status["queue"] serverStatus.total = status["total"] serverStatus.speed = status["speed"] serverStatus.download = status["download"] serverStatus.reconnect = status["reconnect"] return serverStatus def freeSpace(self): return self.serverMethods.free_space() def getServerVersion(self): return self.serverMethods.get_server_version() def kill(self): self.serverMethods.kill() def restart(self): self.serverMethods.restart() def getLog(self, offset): """ Parameters: - offset """ return list(self.serverMethods.restart(offset)) def checkURL(self, urls): """ Parameters: - urls """ checked = {} for u, p in self.core.pluginManager.parseUrls(urls): if p == "BasePlugin": checked[u] = "" else: checked[u] = p return checked def isTimeDownload(self): return self.serverMethods.is_time_download() def isTimeReconnect(self): return self.serverMethods.is_time_reconnect() #downloads def statusDownloads(self): data = [] for pyfile in [x.active for x in self.core.threadManager.threads + self.core.threadManager.localThreads if x.active and x.active != "quit"]: if not isinstance(pyfile, PyFile): continue status = DownloadStatus() status.id = pyfile.id status.name = pyfile.name status.speed = pyfile.getSpeed()/1024 status.eta = pyfile.getETA() status.format_eta = pyfile.formatETA() status.kbleft = pyfile.getBytesLeft() #holded for backward comp. status.bleft = pyfile.getBytesLeft() status.size = pyfile.getSize() status.format_size = pyfile.formatSize() status.percent = pyfile.getPercent() status.status = pyfile.status status.statusmsg = pyfile.m.statusMsg[pyfile.status] status.format_wait = pyfile.formatWait() status.wait_until = pyfile.waitUntil status.package = pyfile.package().name data.append(status) return data def addPackage(self, name, links, dest): """ Parameters: - name - links - dest """ return self.serverMethods.add_package(name, links, dest) def getPackageData(self, pid): """ Parameters: - pid """ pdata = PackageData() rawData = self.serverMethods.get_package_data(pid) pdata.pid = rawData["id"] pdata.name = rawData["name"] pdata.folder = rawData["folder"] pdata.site = rawData["site"] pdata.password = rawData["password"] pdata.queue = rawData["queue"] pdata.order = rawData["order"] pdata.priority = rawData["priority"] pdata.links = [] for pyfile in rawData["links"]: pdata.links.append(pyfile["id"]) return pdata def getFileData(self, fid): """ Parameters: - fid """ fdata = FileData() rawData = self.serverMethods.get_file_data(pid) fdata.pid = rawData["id"] fdata.url = rawData["url"] fdata.name = rawData["name"] fdata.plugin = rawData["plugin"] fdata.size = rawData["size"] fdata.format_size = rawData["format_size"] fdata.status = rawData["status"] fdata.statusmsg = rawData["statusmsg"] fdata.package = rawData["package"] fdata.error = rawData["error"] fdata.order = rawData["order"] fdata.progress = rawData["progress"] return fdata def deleteFiles(self, fids): """ Parameters: - fids """ self.serverMethods.del_links(fids) def deletePackages(self, pids): """ Parameters: - pids """ self.serverMethods.del_packages(pids) def getQueue(self): packs = self.serverMethods.get_queue() ret = [] for pid in packs: pack = self.serverMethods.get_package_data(pid) pdata = PackageData() pdata.pid = pack["id"] pdata.name = pack["name"] pdata.folder = pack["folder"] pdata.site = pack["site"] pdata.password = pack["password"] pdata.queue = pack["queue"] pdata.order = pack["order"] pdata.priority = pack["priority"] pdata.fileids = [int(x) for x in pack["links"].keys()] ret.append(pdata) return ret def getCollector(self): packs = self.serverMethods.get_queue() ret = [] for pid in packs: pack = self.serverMethods.get_package_data(pid) pdata = PackageData() pdata.pid = pack["id"] pdata.name = pack["name"] pdata.folder = pack["folder"] pdata.site = pack["site"] pdata.password = pack["password"] pdata.queue = pack["queue"] pdata.order = pack["order"] pdata.priority = pack["priority"] pdata.fileids = [int(x) for x in pack["links"].keys()] ret.append(pdata) return ret def addFiles(self, pid, links): """ Parameters: - pid - links """ self.serverMethods.add_files(pid, links) def pushToQueue(self, pid): """ Parameters: - pid """ self.serverMethods.push_package_to_queue(pid) def pullFromQueue(self, pid): """ Parameters: - pid """ self.serverMethods.pull_out_package(pid) def restartPackage(self, pid): """ Parameters: - pid """ self.serverMethods.restart_package(pid) def restartFile(self, fid): """ Parameters: - fid """ self.serverMethods.restart_file(fid) def recheckPackage(self, pid): """ Parameters: - pid """ self.serverMethods.recheck_package(pid) def stopAllDownloads(self): self.serverMethods.stop_downloads() def stopDownloads(self, fids): """ Parameters: - fids """ self.serverMethods.abort_files(fids) def setPackageName(self, pid, name): """ Parameters: - pid - name """ self.serverMethods.set_package_name(pid, name) def movePackage(self, destination, pid): """ Parameters: - destination - pid """ self.serverMethods.move_package(destination, pid) def uploadContainer(self, filename, data): """ Parameters: - filename - data """ self.serverMethods.upload_container(filename, data) def setPriority(self, pid, priority): """ Parameters: - pid - priority """ self.serverMethods.set_priority(pid, priority) def orderPackage(self, pid, position): """ Parameters: - pid - position """ self.serverMethods.order_package(pid, position) def orderFile(self, fid, position): """ Parameters: - fid - position """ self.serverMethods.order_file(fid, position) def setPackageData(self, pid, data): """ Parameters: - pid - data """ packdata = {} packdata["id"] = data.pid packdata["name"] = data.name packdata["folder"] = data.folder packdata["site"] = data.site packdata["password"] = data.password packdata["queue"] = data.queue packdata["order"] = data.order packdata["priority"] = data.priority self.serverMethods.set_package_data(pid, packdata) def deleteFinished(self): self.serverMethods.delete_finished() def restartFailed(self): self.serverMethods.restart_failed() def getPackageOrder(self, destination): """ Parameters: - destination """ order = {} if destination == Destination.Queue: packs = self.serverMethods.get_queue() else: packs = self.serverMethods.get_collector() for pid in packs: pack = self.serverMethods.get_package_data(pid) order[pack["order"]] = pack["id"] return order def getFileOrder(self, pid): """ Parameters: - pid """ rawData = self.serverMethods.get_package_data(pid) order = {} for pyfile in rawData["links"]: order[pyfile["order"]] = pyfile["id"] return order #captcha def isCaptchaWaiting(self): return self.serverMethods.is_captcha_waiting() def getCaptchaTask(self, exclusive): """ Parameters: - exclusive """ t = CaptchaTask() t.tid, t.data, t.type = self.serverMethods.get_captcha_task(exclusive) return t def getCaptchaTaskStatus(self, tid): """ Parameters: - tid """ status = self.serverMethods.get_task_status(tid) if status == "init": return CaptchaStatus.Init elif status == "waiting": return CaptchaStatus.Waiting elif status == "user": return CaptchaStatus.User elif status == "shared-user": return CaptchaStatus.SharedUser elif status == "done": return CaptchaStatus.Done def setCaptchaResult(self, tid, result): """ Parameters: - tid - result """ self.serverMethods.set_captcha_result(tid, result) #events def getEvents(self): events = serverMethods.get_events() newEvents = [] for e in events: e = Event() if e[0] in ("update", "remove", "insert"): event.id = e[3] event.type = ElementType.Package if e[2] == "pack" else ElementType.File event.destination = e[1] if e[0] == "update": event.event = EventType.Update elif e[0] == "remove": event.event = EventType.Remove elif e[0] == "insert": event.event = EventType.Insert elif e[0] == "reload": event.event = EventType.ReloadAll event.destination = e[1] elif e[0] == "account": event.event = EventType.ReloadAccounts elif e[0] == "config": event.event = EventType.ReloadConfig elif e[0] == "order": event.event = EventType.ReloadOrder if e[1]: event.id = e[1] event.type = ElementType.Package if e[2] == "pack" else ElementType.File event.destination = e[3] newEvents.append(event) return newEvents #accounts def getAccounts(self): accs = self.serverMethods.get_accounts() accounts = [] for group in accs.values(): for acc in group: account = AccountInfo() account.validuntil = acc["validuntil"] account.login = acc["login"] account.options = acc["options"] account.valid = acc["valid"] account.trafficleft = acc["trafficleft"] account.maxtraffic = acc["maxtraffic"] account.premium = acc["premium"] account.type = acc["type"] accounts.append(account) return accounts def updateAccounts(self, data): """ Parameters: - data """ self.serverMethods.update_account(data.type, data.login, data.password, data.options) def removeAccount(self, plugin, account): """ Parameters: - plugin - account """ self.serverMethods.remove_account(plugin, account) #auth def login(self, username, password): """ Parameters: - username - password """ return True if self.serverMethods.checkAuth(username, password) else False def getUserData(self): return self.serverMethods.checkAuth(username, password) class ThriftBackend(BackendBase): def setup(self): handler = PyloadHandler(self) processor = Processor(handler) transport = TSocket.TServerSocket(9090) tfactory = TTransport.TBufferedTransportFactory() pfactory = TBinaryProtocol.TBinaryProtocolFactory() #self.server = TServer.TSimpleServer(processor, transport, tfactory, pfactory) self.server = TServer.TThreadedServer(processor, transport, tfactory, pfactory) #server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory) def serve(self): self.server.serve()