diff options
| author | 2015-04-13 17:20:59 +0200 | |
|---|---|---|
| committer | 2015-04-13 17:20:59 +0200 | |
| commit | e00ef98491f79ae8aa972ae1473dae4a7b78c07e (patch) | |
| tree | 31be0c7cdcebb61525bcc387bcf15d265a1c494a /pyload | |
| parent | Fix except (diff) | |
| download | pyload-e00ef98491f79ae8aa972ae1473dae4a7b78c07e.tar.xz | |
Cleanup
Diffstat (limited to 'pyload')
100 files changed, 1595 insertions, 10 deletions
| diff --git a/pyload/Core.py b/pyload/Core.py index d3e23309a..c79c832e1 100755 --- a/pyload/Core.py +++ b/pyload/Core.py @@ -48,6 +48,7 @@ sys.stdout = getwriter(enc)(sys.stdout, errors="replace")  class Core(object):      """pyLoad Core, one tool to rule them all... (the filehosters) :D""" +      def __init__(self):          self.doDebug = False          self.running = False @@ -122,6 +123,7 @@ class Core(object):                  self.print_help()                  exit() +      def print_help(self):          print          print "pyLoad v%s     2008-2015 the pyLoad Team" % CURRENT_VERSION @@ -149,6 +151,7 @@ class Core(object):          print "  -h, --help", " " * 13, "Display this help screen"          print +      def toggle_pause(self):          if self.threadManager.pause:              self.threadManager.pause = False @@ -157,11 +160,13 @@ class Core(object):              self.threadManager.pause = True              return True +      def quit(self, a, b):          self.shutdown()          self.log.info(_("Received Quit signal"))          _exit(1) +      def writePidFile(self):          self.deletePidFile()          pid = os.getpid() @@ -169,11 +174,13 @@ class Core(object):          f.write(str(pid))          f.close() +      def deletePidFile(self):          if self.checkPidFile():              self.log.debug("Deleting old pidfile %s" % self.pidfile)              os.remove(self.pidfile) +      def checkPidFile(self):          """ return pid as int or 0"""          if os.path.isfile(self.pidfile): @@ -186,6 +193,7 @@ class Core(object):          return 0 +      def isAlreadyRunning(self):          pid = self.checkPidFile()          if not pid or os.name == "nt": return False @@ -196,6 +204,7 @@ class Core(object):          return pid +      def quitInstance(self):          if os.name == "nt":              print "Not supported on windows." @@ -238,6 +247,7 @@ class Core(object):                  print join(path, f)                  remove(join(path, f)) +      def start(self, rpc=True, web=True):          """ starts the fun :D """ @@ -436,6 +446,7 @@ class Core(object):              self.threadManager.work()              self.scheduler.work() +      def setupDB(self):          self.db = DatabaseBackend(self) # the backend          self.db.setup() @@ -443,11 +454,13 @@ class Core(object):          self.files = FileHandler(self)          self.db.manager = self.files #ugly? +      def init_webserver(self):          if self.config['webui']['activated']:              self.webserver = WebServer(self)              self.webserver.start() +      def init_logger(self, level):          console = logging.StreamHandler(sys.stdout)          frm = logging.Formatter("%(asctime)s %(levelname)-8s  %(message)s", "%d.%m.%Y %H:%M:%S") @@ -469,11 +482,13 @@ class Core(object):          self.log.addHandler(console) #if console logging          self.log.setLevel(level) +      def removeLogger(self):          for h in list(self.log.handlers):              self.log.removeHandler(h)              h.close() +      def check_install(self, check_name, legend, python=True, essential=False):          """check wether needed tools are installed"""          try: @@ -491,6 +506,7 @@ class Core(object):              return False +      def check_file(self, check_names, description="", folder=False, empty=True, essential=False, quiet=False):          """check wether needed files exists"""          tmp_names = [] @@ -528,9 +544,11 @@ class Core(object):                      if essential:                          exit() +      def isClientConnected(self):          return (self.lastClientConnected + 30) > time() +      def restart(self):          self.shutdown()          chdir(owd) @@ -544,6 +562,7 @@ class Core(object):          execl(executable, executable, *sys.argv)          _exit(0) +      def shutdown(self):          self.log.info(_("shutting down..."))          try: diff --git a/pyload/api/__init__.py b/pyload/api/__init__.py index 387481da2..0b63995a3 100644 --- a/pyload/api/__init__.py +++ b/pyload/api/__init__.py @@ -38,6 +38,7 @@ permMap = {}  # decorator only called on init, never initialized, so has no effect on runtime  def permission(bits):      class _Dec(object): +          def __new__(cls, func, *args, **kwargs):              permMap[func.__name__] = bits              return func @@ -85,15 +86,18 @@ class Api(Iface):      """      EXTERNAL = Iface  # let the json api know which methods are external +      def __init__(self, core):          self.core = core +      def _convertPyFile(self, p):          fdata = FileData(p["id"], p["url"], p["name"], p["plugin"], p["size"],                           p["format_size"], p["status"], p["statusmsg"],                           p["package"], p["error"], p["order"])          return fdata +      def _convertConfigFormat(self, c):          sections = {}          for sectionName, sub in c.iteritems(): @@ -115,6 +119,8 @@ class Api(Iface):          return sections      @permission(PERMS.SETTINGS) + +      def getConfigValue(self, category, option, section="core"):          """Retrieve config value. @@ -130,6 +136,8 @@ class Api(Iface):          return str(value)      @permission(PERMS.SETTINGS) + +      def setConfigValue(self, category, option, value, section="core"):          """Set new config value. @@ -147,6 +155,8 @@ class Api(Iface):              self.core.config.setPlugin(category, option, value)      @permission(PERMS.SETTINGS) + +      def getConfig(self):          """Retrieves complete config of core. @@ -154,6 +164,7 @@ class Api(Iface):          """          return self._convertConfigFormat(self.core.config.config) +      def getConfigDict(self):          """Retrieves complete config in dict format, not for RPC. @@ -162,6 +173,8 @@ class Api(Iface):          return self.core.config.config      @permission(PERMS.SETTINGS) + +      def getPluginConfig(self):          """Retrieves complete config for all plugins. @@ -169,6 +182,7 @@ class Api(Iface):          """          return self._convertConfigFormat(self.core.config.plugin) +      def getPluginConfigDict(self):          """Plugin config as dict, not for RPC. @@ -177,16 +191,22 @@ class Api(Iface):          return self.core.config.plugin      @permission(PERMS.STATUS) + +      def pauseServer(self):          """Pause server: Tt wont start any new downloads, but nothing gets aborted."""          self.core.threadManager.pause = True      @permission(PERMS.STATUS) + +      def unpauseServer(self):          """Unpause server: New Downloads will be started."""          self.core.threadManager.pause = False      @permission(PERMS.STATUS) + +      def togglePause(self):          """Toggle pause state. @@ -196,6 +216,8 @@ class Api(Iface):          return self.core.threadManager.pause      @permission(PERMS.STATUS) + +      def toggleReconnect(self):          """Toggle reconnect activation. @@ -205,6 +227,8 @@ class Api(Iface):          return self.core.config["reconnect"]["activated"]      @permission(PERMS.LIST) + +      def statusServer(self):          """Some general information about the current status of pyLoad. @@ -219,24 +243,32 @@ class Api(Iface):          return serverStatus      @permission(PERMS.STATUS) + +      def freeSpace(self):          """Available free space at download directory in bytes"""          return freeSpace(self.core.config["general"]["download_folder"])      @permission(PERMS.ALL) + +      def getServerVersion(self):          """pyLoad Core version """          return self.core.version +      def kill(self):          """Clean way to quit pyLoad"""          self.core.do_kill = True +      def restart(self):          """Restart pyload core"""          self.core.do_restart = True      @permission(PERMS.LOGS) + +      def getLog(self, offset=0):          """Returns most recent log entries. @@ -255,6 +287,8 @@ class Api(Iface):              return ['No log available']      @permission(PERMS.STATUS) + +      def isTimeDownload(self):          """Checks if pyload will start new downloads according to time in config. @@ -265,6 +299,8 @@ class Api(Iface):          return compare_time(start, end)      @permission(PERMS.STATUS) + +      def isTimeReconnect(self):          """Checks if pyload will try to make a reconnect @@ -275,6 +311,8 @@ class Api(Iface):          return compare_time(start, end) and self.core.config["reconnect"]["activated"]      @permission(PERMS.LIST) + +      def statusDownloads(self):          """ Status off all currently running downloads. @@ -292,6 +330,8 @@ class Api(Iface):          return data      @permission(PERMS.ADD) + +      def addPackage(self, name, links, dest=Destination.Queue):          """Adds a package, with links to desired destination. @@ -318,6 +358,8 @@ class Api(Iface):          return pid      @permission(PERMS.ADD) + +      def parseURLs(self, html=None, url=None):          """Parses html content or any arbitaty text for links and returns result of `checkURLs` @@ -334,6 +376,8 @@ class Api(Iface):          return self.checkURLs(set(urls))      @permission(PERMS.ADD) + +      def checkURLs(self, urls):          """ Gets urls and returns pluginname mapped to list of matches urls. @@ -352,6 +396,8 @@ class Api(Iface):          return plugins      @permission(PERMS.ADD) + +      def checkOnlineStatus(self, urls):          """ initiates online status check @@ -373,6 +419,8 @@ class Api(Iface):          return OnlineCheck(rid, result)      @permission(PERMS.ADD) + +      def checkOnlineStatusContainer(self, urls, container, data):          """ checks online status of urls and a submited container file @@ -387,6 +435,8 @@ class Api(Iface):          return self.checkOnlineStatus(urls + [th.name])      @permission(PERMS.ADD) + +      def pollResults(self, rid):          """ Polls the result available for ResultID @@ -401,6 +451,8 @@ class Api(Iface):              return OnlineCheck(rid, result)      @permission(PERMS.ADD) + +      def generatePackages(self, links):          """ Parses links, generates packages names from urls @@ -410,6 +462,8 @@ class Api(Iface):          return parseNames((x, x) for x in links)      @permission(PERMS.ADD) + +      def generateAndAddPackages(self, links, dest=Destination.Queue):          """Generates and add packages @@ -421,6 +475,8 @@ class Api(Iface):                  in self.generatePackages(links).iteritems()]      @permission(PERMS.ADD) + +      def checkAndAddPackages(self, links, dest=Destination.Queue):          """Checks online status, retrieves names, and will add packages.\          Because of this packages are not added immediatly, only for internal use. @@ -433,6 +489,8 @@ class Api(Iface):          self.core.threadManager.createResultThread(data, True)      @permission(PERMS.LIST) + +      def getPackageData(self, pid):          """Returns complete information about package, and included files. @@ -447,6 +505,8 @@ class Api(Iface):                             links=[self._convertPyFile(x) for x in data["links"].itervalues()])      @permission(PERMS.LIST) + +      def getPackageInfo(self, pid):          """Returns information about package, without detailed information about containing files @@ -462,6 +522,8 @@ class Api(Iface):                             fids=[int(x) for x in data["links"]])      @permission(PERMS.LIST) + +      def getFileData(self, fid):          """Get complete information about a specific file. @@ -474,6 +536,8 @@ class Api(Iface):          return self._convertPyFile(info.values()[0])      @permission(PERMS.DELETE) + +      def deleteFiles(self, fids):          """Deletes several file entries from pyload. @@ -484,6 +548,8 @@ class Api(Iface):          self.core.files.save()      @permission(PERMS.DELETE) + +      def deletePackages(self, pids):          """Deletes packages and containing links. @@ -494,6 +560,8 @@ class Api(Iface):          self.core.files.save()      @permission(PERMS.LIST) + +      def getQueue(self):          """Returns info about queue and packages, **not** about files, see `getQueueData` \          or `getPackageData` instead. @@ -507,6 +575,8 @@ class Api(Iface):                  for pack in self.core.files.getInfoData(Destination.Queue).itervalues()]      @permission(PERMS.LIST) + +      def getQueueData(self):          """Return complete data about everything in queue, this is very expensive use it sparely.\             See `getQueue` for alternative. @@ -520,6 +590,8 @@ class Api(Iface):                  for pack in self.core.files.getCompleteData(Destination.Queue).itervalues()]      @permission(PERMS.LIST) + +      def getCollector(self):          """same as `getQueue` for collector. @@ -532,6 +604,8 @@ class Api(Iface):                  for pack in self.core.files.getInfoData(Destination.Collector).itervalues()]      @permission(PERMS.LIST) + +      def getCollectorData(self):          """same as `getQueueData` for collector. @@ -544,6 +618,8 @@ class Api(Iface):                  for pack in self.core.files.getCompleteData(Destination.Collector).itervalues()]      @permission(PERMS.ADD) + +      def addFiles(self, pid, links):          """Adds files to specific package. @@ -555,6 +631,8 @@ class Api(Iface):          self.core.files.save()      @permission(PERMS.MODIFY) + +      def pushToQueue(self, pid):          """Moves package from Collector to Queue. @@ -563,6 +641,8 @@ class Api(Iface):          self.core.files.setPackageLocation(pid, Destination.Queue)      @permission(PERMS.MODIFY) + +      def pullFromQueue(self, pid):          """Moves package from Queue to Collector. @@ -571,6 +651,8 @@ class Api(Iface):          self.core.files.setPackageLocation(pid, Destination.Collector)      @permission(PERMS.MODIFY) + +      def restartPackage(self, pid):          """Restarts a package, resets every containing files. @@ -579,6 +661,8 @@ class Api(Iface):          self.core.files.restartPackage(int(pid))      @permission(PERMS.MODIFY) + +      def restartFile(self, fid):          """Resets file status, so it will be downloaded again. @@ -587,6 +671,8 @@ class Api(Iface):          self.core.files.restartFile(int(fid))      @permission(PERMS.MODIFY) + +      def recheckPackage(self, pid):          """Proofes online status of all files in a package, also a default action when package is added. @@ -596,6 +682,8 @@ class Api(Iface):          self.core.files.reCheckPackage(int(pid))      @permission(PERMS.MODIFY) + +      def stopAllDownloads(self):          """Aborts all running downloads.""" @@ -604,6 +692,8 @@ class Api(Iface):              pyfile.abortDownload()      @permission(PERMS.MODIFY) + +      def stopDownloads(self, fids):          """Aborts specific downloads. @@ -616,6 +706,8 @@ class Api(Iface):                  pyfile.abortDownload()      @permission(PERMS.MODIFY) + +      def setPackageName(self, pid, name):          """Renames a package. @@ -627,6 +719,8 @@ class Api(Iface):          pack.sync()      @permission(PERMS.MODIFY) + +      def movePackage(self, destination, pid):          """Set a new package location. @@ -637,6 +731,8 @@ class Api(Iface):              self.core.files.setPackageLocation(pid, destination)      @permission(PERMS.MODIFY) + +      def moveFiles(self, fids, pid):          """Move multiple files to another package @@ -649,6 +745,8 @@ class Api(Iface):      @permission(PERMS.ADD) + +      def uploadContainer(self, filename, data):          """Uploads and adds a container file to pyLoad. @@ -661,6 +759,8 @@ class Api(Iface):          self.addPackage(th.name, [th.name], Destination.Queue)      @permission(PERMS.MODIFY) + +      def orderPackage(self, pid, position):          """Gives a package a new position. @@ -670,6 +770,8 @@ class Api(Iface):          self.core.files.reorderPackage(pid, position)      @permission(PERMS.MODIFY) + +      def orderFile(self, fid, position):          """Gives a new position to a file within its package. @@ -679,6 +781,8 @@ class Api(Iface):          self.core.files.reorderFile(fid, position)      @permission(PERMS.MODIFY) + +      def setPackageData(self, pid, data):          """Allows to modify several package attributes. @@ -696,6 +800,8 @@ class Api(Iface):          self.core.files.save()      @permission(PERMS.DELETE) + +      def deleteFinished(self):          """Deletes all finished files and completly finished packages. @@ -704,11 +810,15 @@ class Api(Iface):          return self.core.files.deleteFinishedLinks()      @permission(PERMS.MODIFY) + +      def restartFailed(self):          """Restarts all failed failes."""          self.core.files.restartFailed()      @permission(PERMS.LIST) + +      def getPackageOrder(self, destination):          """Returns information about package order. @@ -725,6 +835,8 @@ class Api(Iface):          return order      @permission(PERMS.LIST) + +      def getFileOrder(self, pid):          """Information about file order within package. @@ -741,6 +853,8 @@ class Api(Iface):      @permission(PERMS.STATUS) + +      def isCaptchaWaiting(self):          """Indicates wether a captcha task is available @@ -751,6 +865,8 @@ class Api(Iface):          return not task is None      @permission(PERMS.STATUS) + +      def getCaptchaTask(self, exclusive=False):          """Returns a captcha task @@ -767,6 +883,8 @@ class Api(Iface):          return CaptchaTask(-1)      @permission(PERMS.STATUS) + +      def getCaptchaTaskStatus(self, tid):          """Get information about captcha task @@ -778,6 +896,8 @@ class Api(Iface):          return task.getStatus() if task else ""      @permission(PERMS.STATUS) + +      def setCaptchaResult(self, tid, result):          """Set result for a captcha task @@ -791,6 +911,8 @@ class Api(Iface):              self.core.captchaManager.removeTask(task)      @permission(PERMS.STATUS) + +      def getEvents(self, uuid):          """Lists occured events, may be affected to changes in future. @@ -800,6 +922,7 @@ class Api(Iface):          events = self.core.pullManager.getEvents(uuid)          new_events = [] +          def convDest(d):              return Destination.Queue if d == "queue" else Destination.Collector @@ -821,6 +944,8 @@ class Api(Iface):          return new_events      @permission(PERMS.ACCOUNTS) + +      def getAccounts(self, refresh):          """Get information about all entered accounts. @@ -835,6 +960,8 @@ class Api(Iface):          return accounts or []      @permission(PERMS.ALL) + +      def getAccountTypes(self):          """All available account types. @@ -843,11 +970,15 @@ class Api(Iface):          return self.core.accountManager.accounts.keys()      @permission(PERMS.ACCOUNTS) + +      def updateAccount(self, plugin, account, password=None, options=None):          """Changes pw/options for specific account."""          self.core.accountManager.updateAccount(plugin, account, password, options or {})      @permission(PERMS.ACCOUNTS) + +      def removeAccount(self, plugin, account):          """Remove account from pyload. @@ -857,6 +988,8 @@ class Api(Iface):          self.core.accountManager.removeAccount(plugin, account)      @permission(PERMS.ALL) + +      def login(self, username, password, remoteip=None):          """Login into pyLoad, this **must** be called when using rpc before any methods can be used. @@ -867,6 +1000,7 @@ class Api(Iface):          """          return bool(self.checkAuth(username, password, remoteip)) +      def checkAuth(self, username, password, remoteip=None):          """Check authentication and returns details @@ -880,6 +1014,7 @@ class Api(Iface):          else:              return self.core.db.checkAuth(username, password) +      def isAuthorized(self, func, userdata):          """checks if the user is authorized for specific method @@ -895,6 +1030,8 @@ class Api(Iface):              return False      @permission(PERMS.ALL) + +      def getUserData(self, username, password):          """similar to `checkAuth` but returns UserData thrift type """          user = self.checkAuth(username, password) @@ -903,12 +1040,15 @@ class Api(Iface):          else:              return UserData() +      def getAllUserData(self):          """returns all known user and info"""          return dict((user, UserData(user, data["email"], data["role"], data["permission"], data["template"])) for user, data                  in self.core.db.getAllUserData().iteritems())      @permission(PERMS.STATUS) + +      def getServices(self):          """ A dict of available services, these can be defined by addon plugins. @@ -917,6 +1057,8 @@ class Api(Iface):          return dict((plugin, funcs) for plugin, funcs in self.core.addonManager.methods.iteritems())      @permission(PERMS.STATUS) + +      def hasService(self, plugin, func):          """Checks wether a service is available. @@ -928,6 +1070,8 @@ class Api(Iface):          return plugin in cont and func in cont[plugin]      @permission(PERMS.STATUS) + +      def call(self, info):          """Calls a service (a method in addon plugin). @@ -948,6 +1092,8 @@ class Api(Iface):              raise ServiceException(e.message)      @permission(PERMS.STATUS) + +      def getAllInfo(self):          """Returns all information stored by addon plugins. Values are always strings @@ -956,6 +1102,8 @@ class Api(Iface):          return self.core.addonManager.getAllInfo()      @permission(PERMS.STATUS) + +      def getInfoByPlugin(self, plugin):          """Returns information stored by a specific plugin. @@ -964,10 +1112,12 @@ class Api(Iface):          """          return self.core.addonManager.getInfo(plugin) +      def changePassword(self, user, oldpw, newpw):          """ changes password for specific user """          return self.core.db.changePassword(user, oldpw, newpw) +      def setUserPermission(self, user, perm, role):          self.core.db.setPermission(user, perm)          self.core.db.setRole(user, role) diff --git a/pyload/api/types.py b/pyload/api/types.py index 81385bf9f..10a64a813 100644 --- a/pyload/api/types.py +++ b/pyload/api/types.py @@ -50,6 +50,7 @@ class Output(object):  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 @@ -63,6 +64,7 @@ class AccountInfo(BaseObject):  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 @@ -72,6 +74,7 @@ class CaptchaTask(BaseObject):  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 @@ -81,6 +84,7 @@ class ConfigItem(BaseObject):  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 @@ -90,6 +94,7 @@ class ConfigSection(BaseObject):  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 @@ -111,6 +116,7 @@ class DownloadInfo(BaseObject):  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 @@ -120,6 +126,7 @@ class EventInfo(BaseObject):  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 @@ -136,12 +143,14 @@ class FileData(BaseObject):  class FileDoesNotExists(Exception):      __slots__ = ['fid'] +      def __init__(self, fid=None):          self.fid = fid  class InteractionTask(BaseObject):      __slots__ = ['iid', 'input', 'structure', 'preset', 'output', 'data', 'title', 'description', 'plugin'] +      def __init__(self, iid=None, input=None, structure=None, preset=None, output=None, data=None, title=None, description=None, plugin=None):          self.iid = iid          self.input = input @@ -156,6 +165,7 @@ class InteractionTask(BaseObject):  class OnlineCheck(BaseObject):      __slots__ = ['rid', 'data'] +      def __init__(self, rid=None, data=None):          self.rid = rid          self.data = data @@ -163,6 +173,7 @@ class OnlineCheck(BaseObject):  class OnlineStatus(BaseObject):      __slots__ = ['name', 'plugin', 'packagename', 'status', 'size'] +      def __init__(self, name=None, plugin=(None, None), packagename=None, status=None, size=None):          self.name = name          self.plugin = plugin @@ -173,6 +184,7 @@ class OnlineStatus(BaseObject):  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 @@ -191,12 +203,14 @@ class PackageData(BaseObject):  class PackageDoesNotExists(Exception):      __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 @@ -209,6 +223,7 @@ class ServerStatus(BaseObject):  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 @@ -218,6 +233,7 @@ class ServiceCall(BaseObject):  class ServiceDoesNotExists(Exception):      __slots__ = ['plugin', 'func'] +      def __init__(self, plugin=None, func=None):          self.plugin = plugin          self.func = func @@ -225,12 +241,14 @@ class ServiceDoesNotExists(Exception):  class ServiceException(Exception):      __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 @@ -239,143 +257,282 @@ class UserData(BaseObject):          self.templateName = templateName  class Iface(object): +      def addFiles(self, pid, links):          pass + +      def addPackage(self, name, links, dest):          pass + +      def call(self, info):          pass + +      def checkOnlineStatus(self, urls):          pass + +      def checkOnlineStatusContainer(self, urls, filename, data):          pass + +      def checkURLs(self, urls):          pass + +      def deleteFiles(self, fids):          pass + +      def deleteFinished(self):          pass + +      def deletePackages(self, pids):          pass + +      def freeSpace(self):          pass + +      def generateAndAddPackages(self, links, dest):          pass + +      def generatePackages(self, links):          pass + +      def getAccountTypes(self):          pass + +      def getAccounts(self, refresh):          pass + +      def getAllInfo(self):          pass + +      def getAllUserData(self):          pass + +      def getCaptchaTask(self, exclusive):          pass + +      def getCaptchaTaskStatus(self, tid):          pass + +      def getCollector(self):          pass + +      def getCollectorData(self):          pass + +      def getConfig(self):          pass + +      def getConfigValue(self, category, option, section):          pass + +      def getEvents(self, uuid):          pass + +      def getFileData(self, fid):          pass + +      def getFileOrder(self, pid):          pass + +      def getInfoByPlugin(self, plugin):          pass + +      def getLog(self, offset):          pass + +      def getPackageData(self, pid):          pass + +      def getPackageInfo(self, pid):          pass + +      def getPackageOrder(self, destination):          pass + +      def getPluginConfig(self):          pass + +      def getQueue(self):          pass + +      def getQueueData(self):          pass + +      def getServerVersion(self):          pass + +      def getServices(self):          pass + +      def getUserData(self, username, password):          pass + +      def hasService(self, plugin, func):          pass + +      def isCaptchaWaiting(self):          pass + +      def isTimeDownload(self):          pass + +      def isTimeReconnect(self):          pass + +      def kill(self):          pass + +      def login(self, username, password):          pass + +      def moveFiles(self, fids, pid):          pass + +      def movePackage(self, destination, pid):          pass + +      def orderFile(self, fid, position):          pass + +      def orderPackage(self, pid, position):          pass + +      def parseURLs(self, html, url):          pass + +      def pauseServer(self):          pass + +      def pollResults(self, rid):          pass + +      def pullFromQueue(self, pid):          pass + +      def pushToQueue(self, pid):          pass + +      def recheckPackage(self, pid):          pass + +      def removeAccount(self, plugin, account):          pass + +      def restart(self):          pass + +      def restartFailed(self):          pass + +      def restartFile(self, fid):          pass + +      def restartPackage(self, pid):          pass + +      def setCaptchaResult(self, tid, result):          pass + +      def setConfigValue(self, category, option, value, section):          pass + +      def setPackageData(self, pid, data):          pass + +      def setPackageName(self, pid, name):          pass + +      def statusDownloads(self):          pass + +      def statusServer(self):          pass + +      def stopAllDownloads(self):          pass + +      def stopDownloads(self, fids):          pass + +      def togglePause(self):          pass + +      def toggleReconnect(self):          pass + +      def unpauseServer(self):          pass + +      def updateAccount(self, plugin, account, password, options):          pass + +      def uploadContainer(self, filename, data):          pass diff --git a/pyload/cli/AddPackage.py b/pyload/cli/AddPackage.py index f7e30b64e..131d0d7d7 100644 --- a/pyload/cli/AddPackage.py +++ b/pyload/cli/AddPackage.py @@ -12,6 +12,7 @@ class AddPackage(Handler):          self.name = ""          self.urls = [] +      def onEnter(self, inp):          if inp == "0":              self.cli.reset() @@ -28,6 +29,7 @@ class AddPackage(Handler):                  self.urls.append(inp)              self.setInput() +      def renderBody(self, line):          println(line, white(_("Add Package:")))          println(line + 1, "") diff --git a/pyload/cli/Cli.py b/pyload/cli/Cli.py index d8c8602fc..855ef47cc 100644 --- a/pyload/cli/Cli.py +++ b/pyload/cli/Cli.py @@ -36,6 +36,7 @@ from Getch import Getch  from rename_process import renameProcess  class Cli(object): +      def __init__(self, client, command):          self.client = client          self.command = command @@ -66,11 +67,13 @@ class Cli(object):          else:              self.processCommand() +      def reset(self):          """ reset to initial main menu """          self.input = ""          self.headerHandler = self.bodyHandler = self.inputHandler = self +      def start(self):          """ main loop. handle input """          while True: @@ -130,11 +133,13 @@ class Cli(object):      def setInput(self, string=""):          self.input = string +      def setHandler(self, klass):          #create new handler with reference to cli          self.bodyHandler = self.inputHandler = klass(self)          self.input = "" +      def renderHeader(self, line):          """ prints download status """          #print updated information @@ -182,6 +187,7 @@ class Cli(object):          return line + 1 +      def renderBody(self, line):          """ prints initial menu """          println(line, white(_("Menu:"))) @@ -195,6 +201,7 @@ class Cli(object):          return line + 8 +      def renderFooter(self, line):          """ prints out the input line with input """          println(line, "") @@ -212,6 +219,7 @@ class Cli(object):          #set cursor to position          print "\033[" + str(self.inputline) + ";0H" +      def onChar(self, char):          """ default no special handling for single chars """          if char == "1": @@ -232,12 +240,15 @@ class Cli(object):              os.system('clear')              sys.exit() +      def onEnter(self, inp):          pass +      def onBackSpace(self):          pass +      def processCommand(self):          command = self.command[0]          args = [] @@ -339,6 +350,7 @@ class Cli(object):          else:              print_commands() +      def printOnlineCheck(self, client, rid):          while True:              sleep(1) @@ -354,11 +366,13 @@ class Cli(object):  class RefreshThread(Thread): +      def __init__(self, cli):          Thread.__init__(self)          self.setDaemon(True)          self.cli = cli +      def run(self):          while True:              sleep(1) diff --git a/pyload/cli/Handler.py b/pyload/cli/Handler.py index 4aab3f0e2..33e5dd8e6 100644 --- a/pyload/cli/Handler.py +++ b/pyload/cli/Handler.py @@ -2,6 +2,7 @@  # @author: RaNaN  class Handler(object): +      def __init__(self, cli):          self.cli = cli          self.init() @@ -9,24 +10,31 @@ class Handler(object):      client = property(lambda self: self.cli.client)      input = property(lambda self: self.cli.input) +      def init(self):          pass +      def onChar(self, char):          pass +      def onBackSpace(self):          pass +      def onEnter(self, inp):          pass +      def setInput(self, inp=""):          self.cli.setInput(inp) +      def backspace(self):          self.cli.setInput(self.input[:-1]) +      def renderBody(self, line):          """ gets the line where to render output and should return the line number below its content """          return line + 1 diff --git a/pyload/cli/ManageFiles.py b/pyload/cli/ManageFiles.py index ca1070113..3bf8d1686 100644 --- a/pyload/cli/ManageFiles.py +++ b/pyload/cli/ManageFiles.py @@ -22,6 +22,7 @@ class ManageFiles(Handler):          self.links = None          self.time = 0 +      def onChar(self, char):          if char in ("m", "d", "r"):              self.mode = char @@ -33,12 +34,14 @@ class ManageFiles(Handler):              self.pos += 5              self.backspace() +      def onBackSpace(self):          if not self.input and self.mode:              self.mode = ""          if not self.input and self.package > -1:              self.package = -1 +      def onEnter(self, input):          if input == "0":              self.cli.reset() @@ -74,6 +77,7 @@ class ManageFiles(Handler):          self.mode = ""          self.setInput() +      def renderBody(self, line):          if self.package < 0:              println(line, white(_("Manage Packages:"))) @@ -131,6 +135,7 @@ class ManageFiles(Handler):          println(line + 1, mag("0.") + _(" back to main menu"))          return line + 2 +      def getPackages(self):          if self.cache and self.time + 2 < time():              return self.cache @@ -145,6 +150,7 @@ class ManageFiles(Handler):          return data +      def getLinks(self):          if self.links and self.time + 1 < time():              return self.links @@ -156,6 +162,7 @@ class ManageFiles(Handler):          self.time = time()          return data +      def parseInput(self, inp, package=True):          inp = inp.strip()          if "-" in inp: diff --git a/pyload/database/Backend.py b/pyload/database/Backend.py index 4b63dd284..48c1fcb0d 100644 --- a/pyload/database/Backend.py +++ b/pyload/database/Backend.py @@ -22,34 +22,49 @@ class style(object):      db = None      @classmethod + +      def setDB(cls, db):          cls.db = db      @classmethod + +      def inner(cls, f):          @staticmethod + +          def x(*args, **kwargs):              if cls.db:                  return f(cls.db, *args, **kwargs)          return x      @classmethod + +      def queue(cls, f):          @staticmethod + +          def x(*args, **kwargs):              if cls.db:                  return cls.db.queue(f, *args, **kwargs)          return x      @classmethod + +      def async(cls, f):          @staticmethod + +          def x(*args, **kwargs):              if cls.db:                  return cls.db.async(f, *args, **kwargs)          return x  class DatabaseJob(object): +      def __init__(self, f, *args, **kwargs):          self.done = Event() @@ -63,6 +78,7 @@ class DatabaseJob(object):  #        import inspect  #        self.frame = inspect.currentframe() +      def __repr__(self):          from os.path import basename          frame = self.frame.f_back @@ -75,6 +91,7 @@ class DatabaseJob(object):          return "DataBase Job %s:%s\n%sResult: %s" % (self.f.__name__, self.args[1:], output, self.result) +      def processJob(self):          try:              self.result = self.f(*self.args, **self.kwargs) @@ -89,11 +106,14 @@ class DatabaseJob(object):          finally:              self.done.set() +      def wait(self):          self.done.wait()  class DatabaseBackend(Thread):      subs = [] + +      def __init__(self, core):          Thread.__init__(self)          self.setDaemon(True) @@ -105,10 +125,12 @@ class DatabaseBackend(Thread):          style.setDB(self) +      def setup(self):          self.start()          self.setuplock.wait() +      def run(self):          """main loop, which executes commands"""          convert = self._checkVersion() #returns None or current version @@ -137,10 +159,13 @@ class DatabaseBackend(Thread):              j.processJob()      @style.queue + +      def shutdown(self):          self.conn.commit()          self.jobs.put("quit") +      def _checkVersion(self):          """ check db version and delete it if needed"""          if not exists("files.version"): @@ -165,6 +190,7 @@ class DatabaseBackend(Thread):              f.close()              return v +      def _convertDB(self, v):          try:              getattr(self, "_convertV%i" % v)() @@ -176,6 +202,7 @@ class DatabaseBackend(Thread):      #convert scripts start----------------------------------------------------- +      def _convertV2(self):          self.c.execute('CREATE TABLE IF NOT EXISTS "storage" ("id" INTEGER PRIMARY KEY AUTOINCREMENT, "identifier" TEXT NOT NULL, "key" TEXT NOT NULL, "value" TEXT DEFAULT "")')          try: @@ -184,6 +211,7 @@ class DatabaseBackend(Thread):              print "Database was converted from v2 to v3."          self._convertV3() +      def _convertV3(self):          self.c.execute('CREATE TABLE IF NOT EXISTS "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT, "name" TEXT NOT NULL, "email" TEXT DEFAULT "" NOT NULL, "password" TEXT NOT NULL, "role" INTEGER DEFAULT 0 NOT NULL, "permission" INTEGER DEFAULT 0 NOT NULL, "template" TEXT DEFAULT "default" NOT NULL)')          try: @@ -193,6 +221,7 @@ class DatabaseBackend(Thread):      #convert scripts end------------------------------------------------------- +      def _createTables(self):          """create tables for database""" @@ -249,26 +278,35 @@ class DatabaseBackend(Thread):              self.c.executemany("INSERT INTO users(name, password, email) VALUES (?, ?, ?)", users)              move("pyload.db", "pyload.old.db") +      def createCursor(self):          return self.conn.cursor()      @style.async + +      def commit(self):          self.conn.commit()      @style.queue + +      def syncSave(self):          self.conn.commit()      @style.async + +      def rollback(self):          self.conn.rollback() +      def async(self, f, *args, **kwargs):          args = (self,) + args          job = DatabaseJob(f, *args, **kwargs)          self.jobs.put(job) +      def queue(self, f, *args, **kwargs):          args = (self,) + args          job = DatabaseJob(f, *args, **kwargs) @@ -277,13 +315,18 @@ class DatabaseBackend(Thread):          return job.result      @classmethod + +      def registerSub(cls, klass):          cls.subs.append(klass)      @classmethod + +      def unregisterSub(cls, klass):          cls.subs.remove(klass) +      def __getattr__(self, attr):          for sub in DatabaseBackend.subs:              if hasattr(sub, attr): diff --git a/pyload/database/File.py b/pyload/database/File.py index 857da1ff9..0ff520623 100644 --- a/pyload/database/File.py +++ b/pyload/database/File.py @@ -42,7 +42,10 @@ class FileHandler(object):          self.db = self.core.db +      def change(func): + +          def new(*args):              args[0].unchanged = False              args[0].filecount = -1 @@ -51,12 +54,16 @@ class FileHandler(object):              return func(*args)          return new +      #-------------------------------------------------------------------------- +      def save(self):          """saves all data to backend"""          self.db.commit() +      #-------------------------------------------------------------------------- +      def syncSave(self):          """saves all data to backend and waits until all data are written"""          pyfiles = self.cache.values() @@ -70,6 +77,8 @@ class FileHandler(object):          self.db.syncSave()      @lock + +      def getCompleteData(self, queue=1):          """gets a complete data representation""" @@ -89,6 +98,8 @@ class FileHandler(object):          return packs      @lock + +      def getInfoData(self, queue=1):          """gets a data representation without links""" @@ -101,6 +112,8 @@ class FileHandler(object):      @lock      @change + +      def addLinks(self, urls, package):          """adds links""" @@ -114,7 +127,9 @@ class FileHandler(object):          #@TODO: change from reloadAll event to package update event          self.core.pullManager.addEvent(ReloadAllEvent("collector")) +      #-------------------------------------------------------------------------- +      @lock      @change      def addPackage(self, name, folder, queue=0): @@ -125,7 +140,9 @@ class FileHandler(object):          self.core.pullManager.addEvent(e)          return lastID +      #-------------------------------------------------------------------------- +      @lock      @change      def deletePackage(self, id): @@ -161,7 +178,9 @@ class FileHandler(object):                  pack.order -= 1                  pack.notifyChange() +      #-------------------------------------------------------------------------- +      @lock      @change      def deleteLink(self, id): @@ -197,18 +216,24 @@ class FileHandler(object):                  pyfile.notifyChange()      #-------------------------------------------------------------------------- + +      def releaseLink(self, id):          """removes pyfile from cache"""          if id in self.cache:              del self.cache[id] +      #-------------------------------------------------------------------------- +      def releasePackage(self, id):          """removes package from cache"""          if id in self.packageCache:              del self.packageCache[id] +      #-------------------------------------------------------------------------- +      def updateLink(self, pyfile):          """updates link"""          self.db.updateLink(pyfile) @@ -216,7 +241,9 @@ class FileHandler(object):          e = UpdateEvent("file", pyfile.id, "collector" if not pyfile.package().queue else "queue")          self.core.pullManager.addEvent(e) +      #-------------------------------------------------------------------------- +      def updatePackage(self, pypack):          """updates a package"""          self.db.updatePackage(pypack) @@ -224,7 +251,9 @@ class FileHandler(object):          e = UpdateEvent("pack", pypack.id, "collector" if not pypack.queue else "queue")          self.core.pullManager.addEvent(e) +      #-------------------------------------------------------------------------- +      def getPackage(self, id):          """return package instance""" @@ -233,7 +262,9 @@ class FileHandler(object):          else:              return self.db.getPackage(id) +      #-------------------------------------------------------------------------- +      def getPackageData(self, id):          """returns dict with package information"""          pack = self.getPackage(id) @@ -257,7 +288,9 @@ class FileHandler(object):          return pack +      #-------------------------------------------------------------------------- +      def getFileData(self, id):          """returns dict with file information"""          if id in self.cache: @@ -265,7 +298,9 @@ class FileHandler(object):          return self.db.getLinkData(id) +      #-------------------------------------------------------------------------- +      def getFile(self, id):          """returns pyfile instance"""          if id in self.cache: @@ -273,7 +308,9 @@ class FileHandler(object):          else:              return self.db.getFile(id) +      #-------------------------------------------------------------------------- +      @lock      def getJob(self, occ):          """get suitable job""" @@ -317,6 +354,8 @@ class FileHandler(object):          return pyfile      @lock + +      def getDecryptJob(self):          """return job for decrypting"""          if "decrypt" in self.jobCache: @@ -332,6 +371,7 @@ class FileHandler(object):              self.jobCache["decrypt"] = "empty"              return None +      def getFileCount(self):          """returns number of files""" @@ -340,6 +380,7 @@ class FileHandler(object):          return self.filecount +      def getQueueCount(self, force=False):          """number of files that have to be processed"""          if self.queuecount == -1 or force: @@ -347,6 +388,7 @@ class FileHandler(object):          return self.queuecount +      def checkAllLinksFinished(self):          """checks if all files are finished and dispatch event""" @@ -357,6 +399,7 @@ class FileHandler(object):          return False +      def checkAllLinksProcessed(self, fid):          """checks if all files was processed and pyload would idle now, needs fid which will be ignored when counting""" @@ -370,11 +413,14 @@ class FileHandler(object):          return False +      def resetCount(self):          self.queuecount = -1      @lock      @change + +      def restartPackage(self, id):          """restart package"""          pyfiles = self.cache.values() @@ -392,6 +438,8 @@ class FileHandler(object):      @lock      @change + +      def restartFile(self, id):          """ restart file"""          if id in self.cache: @@ -407,6 +455,8 @@ class FileHandler(object):      @lock      @change + +      def setPackageLocation(self, id, queue):          """push package to queue""" @@ -440,6 +490,8 @@ class FileHandler(object):      @lock      @change + +      def reorderPackage(self, id, position):          p = self.getPackage(id) @@ -467,6 +519,8 @@ class FileHandler(object):      @lock      @change + +      def reorderFile(self, id, position):          f = self.getFileData(id)          f = f[id] @@ -497,12 +551,15 @@ class FileHandler(object):          self.core.pullManager.addEvent(e)      @change + +      def updateFileInfo(self, data, pid):          """ updates file info (name, size, status, url)"""          ids = self.db.updateLinkInfo(data)          e = UpdateEvent("pack", pid, "collector" if not self.getPackage(pid).queue else "queue")          self.core.pullManager.addEvent(e) +      def checkPackageFinished(self, pyfile):          """ checks if package is finished and calls AddonManager """ @@ -513,6 +570,7 @@ class FileHandler(object):                  self.core.addonManager.packageFinished(pyfile.package())                  pyfile.package().setFinished = True +      def reCheckPackage(self, pid):          """ recheck links in package """          data = self.db.getPackageData(pid) @@ -527,6 +585,8 @@ class FileHandler(object):      @lock      @change + +      def deleteFinishedLinks(self):          """ deletes finished links and packages, return deleted packages """ @@ -549,6 +609,8 @@ class FileHandler(object):      @lock      @change + +      def restartFailed(self):          """ restart all failed links """          self.db.restartFailed() @@ -556,24 +618,32 @@ class FileHandler(object):  class FileMethods(object):      @style.queue + +      def filecount(self, queue):          """returns number of files in queue"""          self.c.execute("SELECT COUNT(*) FROM links as l INNER JOIN packages as p ON l.package=p.id WHERE p.queue=?", (queue,))          return self.c.fetchone()[0]      @style.queue + +      def queuecount(self, queue):          """ number of files in queue not finished yet"""          self.c.execute("SELECT COUNT(*) FROM links as l INNER JOIN packages as p ON l.package=p.id WHERE p.queue=? AND l.status NOT IN (0, 4)", (queue,))          return self.c.fetchone()[0]      @style.queue + +      def processcount(self, queue, fid):          """ number of files which have to be proccessed """          self.c.execute("SELECT COUNT(*) FROM links as l INNER JOIN packages as p ON l.package=p.id WHERE p.queue=? AND l.status IN (2, 3, 5, 7, 12) AND l.id != ?", (queue, str(fid)))          return self.c.fetchone()[0]      @style.inner + +      def _nextPackageOrder(self, queue=0):          self.c.execute('SELECT MAX(packageorder) FROM packages WHERE queue=?', (queue,))          max = self.c.fetchone()[0] @@ -583,6 +653,8 @@ class FileMethods(object):              return 0      @style.inner + +      def _nextFileOrder(self, package):          self.c.execute('SELECT MAX(linkorder) FROM links WHERE package=?', (package,))          max = self.c.fetchone()[0] @@ -592,12 +664,16 @@ class FileMethods(object):              return 0      @style.queue + +      def addLink(self, url, name, plugin, package):          order = self._nextFileOrder(package)          self.c.execute('INSERT INTO links(url, name, plugin, package, linkorder) VALUES(?,?,?,?,?)', (url, name, ".".join(plugintype, pluginname), package, order))          return self.c.lastrowid      @style.queue + +      def addLinks(self, links, package):          """ links is a list of tupels (url, plugin)"""          order = self._nextFileOrder(package) @@ -606,23 +682,31 @@ class FileMethods(object):          self.c.executemany('INSERT INTO links(url, name, plugin, package, linkorder) VALUES(?,?,?,?,?)', links)      @style.queue + +      def addPackage(self, name, folder, queue):          order = self._nextPackageOrder(queue)          self.c.execute('INSERT INTO packages(name, folder, queue, packageorder) VALUES(?,?,?,?)', (name, folder, queue, order))          return self.c.lastrowid      @style.queue + +      def deletePackage(self, p):          self.c.execute('DELETE FROM links WHERE package=?', (str(p.id),))          self.c.execute('DELETE FROM packages WHERE id=?', (str(p.id),))          self.c.execute('UPDATE packages SET packageorder=packageorder-1 WHERE packageorder > ? AND queue=?', (p.order, p.queue))      @style.queue + +      def deleteLink(self, f):          self.c.execute('DELETE FROM links WHERE id=?', (str(f.id),))          self.c.execute('UPDATE links SET linkorder=linkorder-1 WHERE linkorder > ? AND package=?', (f.order, str(f.packageid)))      @style.queue + +      def getAllLinks(self, q):          """return information about all links in queue q @@ -656,6 +740,8 @@ class FileMethods(object):          return data      @style.queue + +      def getAllPackages(self, q):          """return information about packages in queue q          (only useful in get all data) @@ -693,6 +779,8 @@ class FileMethods(object):          return data      @style.queue + +      def getLinkData(self, id):          """get link information as dict"""          self.c.execute('SELECT id, url, name, size, status, error, plugin, package, linkorder FROM links WHERE id=?', (str(id),)) @@ -717,6 +805,8 @@ class FileMethods(object):          return data      @style.queue + +      def getPackageData(self, id):          """get data about links for a package"""          self.c.execute('SELECT id, url, name, size, status, error, plugin, package, linkorder FROM links WHERE package=? ORDER BY linkorder', (str(id),)) @@ -740,14 +830,20 @@ class FileMethods(object):          return data      @style.async + +      def updateLink(self, f):          self.c.execute('UPDATE links SET url=?, name=?, size=?, status=?, error=?, package=? WHERE id=?', (f.url, f.name, f.size, f.status, str(f.error), str(f.packageid), str(f.id)))      @style.queue + +      def updatePackage(self, p):          self.c.execute('UPDATE packages SET name=?, folder=?, site=?, password=?, queue=? WHERE id=?', (p.name, p.folder, p.site, p.password, p.queue, str(p.id)))      @style.queue + +      def updateLinkInfo(self, data):          """ data is list of tupels (name, size, status, url) """          self.c.executemany('UPDATE links SET name=?, size=?, status=? WHERE url=? AND status IN (1, 2, 3, 14)', data) @@ -758,6 +854,8 @@ class FileMethods(object):          return ids      @style.queue + +      def reorderPackage(self, p, position, noMove=False):          if position == -1:              position = self._nextPackageOrder(p.queue) @@ -770,6 +868,8 @@ class FileMethods(object):          self.c.execute('UPDATE packages SET packageorder=? WHERE id=?', (position, str(p.id)))      @style.queue + +      def reorderLink(self, f, position):          """ reorder link with f as dict for pyfile  """          if f["order"] > position: @@ -780,19 +880,27 @@ class FileMethods(object):          self.c.execute('UPDATE links SET linkorder=? WHERE id=?', (position, f["id"]))      @style.queue + +      def clearPackageOrder(self, p):          self.c.execute('UPDATE packages SET packageorder=? WHERE id=?', (-1, str(p.id)))          self.c.execute('UPDATE packages SET packageorder=packageorder-1 WHERE packageorder > ? AND queue=? AND id != ?', (p.order, p.queue, str(p.id)))      @style.async + +      def restartFile(self, id):          self.c.execute('UPDATE links SET status=3, error="" WHERE id=?', (str(id),))      @style.async + +      def restartPackage(self, id):          self.c.execute('UPDATE links SET status=3 WHERE package=?', (str(id),))      @style.queue + +      def getPackage(self, id):          """return package instance from id"""          self.c.execute("SELECT name, folder, site, password, queue, packageorder FROM packages WHERE id=?", (str(id),)) @@ -800,7 +908,9 @@ class FileMethods(object):          if not r: return None          return PyPackage(self.manager, id, * r) +      #-------------------------------------------------------------------------- +      @style.queue      def getFile(self, id):          """return link instance from id""" @@ -812,6 +922,8 @@ class FileMethods(object):          return PyFile(self.manager, id, * r)      @style.queue + +      def getJob(self, occ):          """return pyfile ids, which are suitable for download and dont use a occupied plugin""" @@ -832,6 +944,8 @@ class FileMethods(object):          return [x[0] for x in self.c]      @style.queue + +      def getPluginJob(self, plugins):          """returns pyfile ids with suited plugins"""          cmd = "SELECT l.id FROM links as l INNER JOIN packages as p ON l.package=p.id WHERE l.plugin IN %s AND l.status IN (2, 3, 14) ORDER BY p.packageorder ASC, l.linkorder ASC LIMIT 5" % plugins @@ -841,6 +955,8 @@ class FileMethods(object):          return [x[0] for x in self.c]      @style.queue + +      def getUnfinished(self, pid):          """return list of max length 3 ids with pyfiles in package not finished or processed""" @@ -848,21 +964,29 @@ class FileMethods(object):          return [r[0] for r in self.c]      @style.queue + +      def deleteFinished(self):          self.c.execute("DELETE FROM links WHERE status IN (0, 4)")          self.c.execute("DELETE FROM packages WHERE NOT EXISTS(SELECT 1 FROM links WHERE packages.id=links.package)")      @style.queue + +      def restartFailed(self):          self.c.execute("UPDATE links SET status=3, error='' WHERE status IN (6, 8, 9)")      @style.queue + +      def findDuplicates(self, id, folder, filename):          """ checks if filename exists with different id and same package """          self.c.execute("SELECT l.plugin FROM links as l INNER JOIN packages as p ON l.package=p.id AND p.folder=? WHERE l.id!=? AND l.status=0 AND l.name=?", (folder, id, filename))          return self.c.fetchone()      @style.queue + +      def purgeLinks(self):          self.c.execute("DELETE FROM links;")          self.c.execute("DELETE FROM packages;") diff --git a/pyload/database/Storage.py b/pyload/database/Storage.py index 75e166d39..bd7844d8d 100644 --- a/pyload/database/Storage.py +++ b/pyload/database/Storage.py @@ -6,6 +6,8 @@ from pyload.database import DatabaseBackend  class StorageMethods(object):      @style.queue + +      def setStorage(db, identifier, key, value):          db.c.execute("SELECT id FROM storage WHERE identifier=? AND key=?", (identifier, key))          if db.c.fetchone() is not None: @@ -14,6 +16,8 @@ class StorageMethods(object):              db.c.execute("INSERT INTO storage (identifier, key, value) VALUES (?, ?, ?)", (identifier, key, value))      @style.queue + +      def getStorage(db, identifier, key=None):          if key is not None:              db.c.execute("SELECT value FROM storage WHERE identifier=? AND key=?", (identifier, key)) @@ -28,6 +32,8 @@ class StorageMethods(object):              return d      @style.queue + +      def delStorage(db, identifier, key):          db.c.execute("DELETE FROM storage WHERE identifier=? AND key=?", (identifier, key)) diff --git a/pyload/database/User.py b/pyload/database/User.py index 54545e588..52b05749f 100644 --- a/pyload/database/User.py +++ b/pyload/database/User.py @@ -8,6 +8,8 @@ from pyload.database import DatabaseBackend, style  class UserMethods(object):      @style.queue + +      def checkAuth(db, user, password):          c = db.c          c.execute('SELECT id, name, password, role, permission, template, email FROM "users" WHERE name=?', (user,)) @@ -25,6 +27,8 @@ class UserMethods(object):              return {}      @style.queue + +      def addUser(db, user, password):          salt = reduce(lambda x, y: x + y, [str(random.randint(0, 9)) for i in range(0, 5)])          h = sha1(salt + password) @@ -39,6 +43,8 @@ class UserMethods(object):      @style.queue + +      def changePassword(db, user, oldpw, newpw):          db.c.execute('SELECT id, name, password FROM users WHERE name=?', (user,))          r = db.c.fetchone() @@ -60,15 +66,21 @@ class UserMethods(object):      @style.async + +      def setPermission(db, user, perms):          db.c.execute("UPDATE users SET permission=? WHERE name=?", (perms, user))      @style.async + +      def setRole(db, user, role):          db.c.execute("UPDATE users SET role=? WHERE name=?", (role, user))      @style.queue + +      def listUsers(db):          db.c.execute('SELECT name FROM users')          users = [] @@ -77,6 +89,8 @@ class UserMethods(object):          return users      @style.queue + +      def getAllUserData(db):          db.c.execute("SELECT name, permission, role, template, email FROM users")          user = {} @@ -86,6 +100,8 @@ class UserMethods(object):          return user      @style.queue + +      def removeUser(db, user):          db.c.execute('DELETE FROM users WHERE name=?', (user,)) diff --git a/pyload/datatype/File.py b/pyload/datatype/File.py index 0dadbd7f8..9a29a1f41 100644 --- a/pyload/datatype/File.py +++ b/pyload/datatype/File.py @@ -40,6 +40,7 @@ class PyFile(object):                   "active", "abort", "statusname", "reconnected", "progress",                   "maxprogress", "pluginmodule", "pluginclass") +      def __init__(self, manager, id, url, name, size, status, error, plugin, package, order):          self.m = manager @@ -76,10 +77,13 @@ class PyFile(object):      # will convert all sizes to ints      size = property(lambda self: self._size, setSize) +      def __repr__(self):          return "PyFile %s: %s@%s" % (self.id, self.name, self.pluginname)      @lock + +      def initPlugin(self):          """ inits plugin instance """          if not self.plugin: @@ -88,6 +92,8 @@ class PyFile(object):              self.plugin       = self.pluginclass(self)      @lock + +      def hasPlugin(self):          """Thread safe way to determine this file has initialized plugin attribute @@ -95,32 +101,40 @@ class PyFile(object):          """          return hasattr(self, "plugin") and self.plugin +      def package(self):          """ return package instance"""          return self.m.getPackage(self.packageid) +      def setStatus(self, status):          self.status = statusMap[status]          self.sync()  #@TODO: needed aslong no better job approving exists +      def setCustomStatus(self, msg, status="processing"):          self.statusname = msg          self.setStatus(status) +      def getStatusName(self):          if self.status not in (13, 14) or not self.statusname:              return self.m.statusMsg[self.status]          else:              return self.statusname +      def hasStatus(self, status):          return statusMap[status] == self.status +      def sync(self):          """sync PyFile instance with database"""          self.m.updateLink(self)      @lock + +      def release(self):          """sync and remove from cache"""          # file has valid package @@ -133,14 +147,17 @@ class PyFile(object):          self.m.releaseLink(self.id) +      def delete(self):          """delete pyfile from database"""          self.m.deleteLink(self.id) +      def toDict(self):          """return dict with all information for interface"""          return self.toDbDict() +      def toDbDict(self):          """return data as dict for databse @@ -167,6 +184,7 @@ class PyFile(object):              }          } +      def abortDownload(self):          """abort pyfile if possible"""          while self.id in self.m.core.threadManager.processingIds(): @@ -181,6 +199,7 @@ class PyFile(object):          self.release() +      def finishIfDone(self):          """set status to finish and release file if every thread is finished with it""" @@ -192,9 +211,11 @@ class PyFile(object):          self.m.checkAllLinksFinished()          return True +      def checkIfProcessed(self):          self.m.checkAllLinksProcessed(self.id) +      def formatWait(self):          """ formats and return wait time in humanreadable format """          seconds = self.waitUntil - time() @@ -205,10 +226,12 @@ class PyFile(object):          minutes, seconds = divmod(seconds, 60)          return "%.2i:%.2i:%.2i" % (hours, minutes, seconds) +      def formatSize(self):          """ formats size to readable format """          return formatSize(self.getSize()) +      def formatETA(self):          """ formats eta to readable format """          seconds = self.getETA() @@ -219,6 +242,7 @@ class PyFile(object):          minutes, seconds = divmod(seconds, 60)          return "%.2i:%.2i:%.2i" % (hours, minutes, seconds) +      def getSpeed(self):          """ calculates speed """          try: @@ -226,6 +250,7 @@ class PyFile(object):          except Exception:              return 0 +      def getETA(self):          """ gets established time of arrival"""          try: @@ -233,6 +258,7 @@ class PyFile(object):          except Exception:              return 0 +      def getBytesLeft(self):          """ gets bytes left """          try: @@ -240,6 +266,7 @@ class PyFile(object):          except Exception:              return 0 +      def getPercent(self):          """ get % of download """          if self.status == 12: @@ -250,6 +277,7 @@ class PyFile(object):          else:              return self.progress +      def getSize(self):          """ get size of download """          try: @@ -260,10 +288,12 @@ class PyFile(object):          except Exception:              return self.size +      def notifyChange(self):          e = UpdateEvent("file", self.id, "collector" if not self.package().queue else "queue")          self.m.core.pullManager.addEvent(e) +      def setProgress(self, value):          if not value == self.progress:              self.progress = value diff --git a/pyload/datatype/Package.py b/pyload/datatype/Package.py index bf3edffea..cad6519db 100644 --- a/pyload/datatype/Package.py +++ b/pyload/datatype/Package.py @@ -8,6 +8,7 @@ class PyPackage(object):      """      Represents a package object at runtime      """ +      def __init__(self, manager, id, name, folder, site, password, queue, order):          self.m = manager          self.m.packageCache[int(id)] = self @@ -22,9 +23,12 @@ class PyPackage(object):          self.setFinished = False      @property + +      def folder(self):          return safe_filename(self._folder) +      def toDict(self):          """ Returns a dictionary representation of the data. @@ -43,22 +47,27 @@ class PyPackage(object):              }          } +      def getChildren(self):          """get information about contained links"""          return self.m.getPackageData(self.id)["links"] +      def sync(self):          """sync with db"""          self.m.updatePackage(self) +      def release(self):          """sync and delete from cache"""          self.sync()          self.m.releasePackage(self.id) +      def delete(self):          self.m.deletePackage(self.id) +      def notifyChange(self):          e = UpdateEvent("pack", self.id, "collector" if not self.queue else "queue")          self.m.core.pullManager.addEvent(e) diff --git a/pyload/manager/Account.py b/pyload/manager/Account.py index 12fc970c2..9b7cb590a 100644 --- a/pyload/manager/Account.py +++ b/pyload/manager/Account.py @@ -16,7 +16,6 @@ ACC_VERSION = 1  class AccountManager(object):      """manages all accounts""" -    #----------------------------------------------------------------------      def __init__(self, core):          """Constructor""" @@ -64,6 +63,7 @@ class AccountManager(object):      #---------------------------------------------------------------------- +      def loadAccounts(self):          """loads all accounts available""" @@ -111,6 +111,7 @@ class AccountManager(object):      #---------------------------------------------------------------------- +      def saveAccounts(self):          """save all account information""" @@ -135,6 +136,7 @@ class AccountManager(object):      #---------------------------------------------------------------------- +      def initAccountPlugins(self):          """init names"""          for name in self.core.pluginManager.getAccountPlugins(): @@ -142,6 +144,8 @@ class AccountManager(object):      @lock + +      def updateAccount(self, plugin , user, password=None, options={}):          """add or update account"""          if plugin in self.accounts: @@ -154,6 +158,8 @@ class AccountManager(object):      @lock + +      def removeAccount(self, plugin, user):          """remove account""" @@ -165,6 +171,8 @@ class AccountManager(object):      @lock + +      def getAccountInfos(self, force=True, refresh=False):          data = {} diff --git a/pyload/manager/Addon.py b/pyload/manager/Addon.py index 9ce3a4f8f..61585e1cb 100644 --- a/pyload/manager/Addon.py +++ b/pyload/manager/Addon.py @@ -67,6 +67,7 @@ class AddonManager(object):      def try_catch(func): +          def new(*args):              try:                  return func(*args) @@ -178,6 +179,8 @@ class AddonManager(object):      @try_catch + +      def coreReady(self):          for plugin in self.plugins:              if plugin.isActivated(): @@ -187,6 +190,8 @@ class AddonManager(object):      @try_catch + +      def coreExiting(self):          for plugin in self.plugins:              if plugin.isActivated(): @@ -196,6 +201,8 @@ class AddonManager(object):      @lock + +      def downloadPreparing(self, pyfile):          for plugin in self.plugins:              if plugin.isActivated(): @@ -205,6 +212,8 @@ class AddonManager(object):      @lock + +      def downloadFinished(self, pyfile):          for plugin in self.plugins:              if plugin.isActivated(): @@ -215,6 +224,8 @@ class AddonManager(object):      @lock      @try_catch + +      def downloadFailed(self, pyfile):          for plugin in self.plugins:              if plugin.isActivated(): @@ -224,6 +235,8 @@ class AddonManager(object):      @lock + +      def packageFinished(self, package):          for plugin in self.plugins:              if plugin.isActivated(): @@ -233,6 +246,8 @@ class AddonManager(object):      @lock + +      def beforeReconnecting(self, ip):          for plugin in self.plugins:              plugin.beforeReconnecting(ip) @@ -241,6 +256,8 @@ class AddonManager(object):      @lock + +      def afterReconnecting(self, ip):          for plugin in self.plugins:              if plugin.isActivated(): diff --git a/pyload/manager/Captcha.py b/pyload/manager/Captcha.py index e54eacf30..0814cf78a 100644 --- a/pyload/manager/Captcha.py +++ b/pyload/manager/Captcha.py @@ -9,23 +9,27 @@ from pyload.utils import encode  class CaptchaManager(object): +      def __init__(self, core):          self.lock = Lock()          self.core = core          self.tasks = []  # task store, for outgoing tasks only          self.ids = 0  # only for internal purpose +      def newTask(self, img, format, file, result_type):          task = CaptchaTask(self.ids, img, format, file, result_type)          self.ids += 1          return task +      def removeTask(self, task):          self.lock.acquire()          if task in self.tasks:              self.tasks.remove(task)          self.lock.release() +      def getTask(self):          self.lock.acquire()          for task in self.tasks: @@ -35,6 +39,7 @@ class CaptchaManager(object):          self.lock.release()          return None +      def getTaskByID(self, tid):          self.lock.acquire()          for task in self.tasks: @@ -44,6 +49,7 @@ class CaptchaManager(object):          self.lock.release()          return None +      def handleCaptcha(self, task, timeout=50):          cli = self.core.isClientConnected() @@ -65,6 +71,7 @@ class CaptchaManager(object):  class CaptchaTask(object): +      def __init__(self, id, img, format, file, result_type='textual'):          self.id = str(id)          self.captchaImg = img @@ -78,9 +85,11 @@ class CaptchaTask(object):          self.status = "init"          self.data = {}  # handler can store data here +      def getCaptcha(self):          return self.captchaImg, self.captchaFormat, self.captchaResultType +      def setResult(self, text):          if self.isTextual():              self.result = text @@ -91,48 +100,59 @@ class CaptchaTask(object):              except Exception:                  self.result = None +      def getResult(self):          return encode(self.result) +      def getStatus(self):          return self.status +      def setWaiting(self, sec):          """ let the captcha wait secs for the solution """          self.waitUntil = max(time() + sec, self.waitUntil)          self.status = "waiting" +      def isWaiting(self):          if self.result or self.error or self.timedOut():              return False          else:              return True +      def isTextual(self):          """ returns if text is written on the captcha """          return self.captchaResultType == 'textual' +      def isPositional(self):          """ returns if user have to click a specific region on the captcha """          return self.captchaResultType == 'positional' +      def setWatingForUser(self, exclusive):          if exclusive:              self.status = "user"          else:              self.status = "shared-user" +      def timedOut(self):          return time() > self.waitUntil +      def invalid(self):          """ indicates the captcha was not correct """          for x in self.handler:              x.captchaInvalid(self) +      def correct(self):          for x in self.handler:              x.captchaCorrect(self) +      def __str__(self):          return "<CaptchaTask '%s'>" % self.id diff --git a/pyload/manager/Event.py b/pyload/manager/Event.py index 20897290e..90aaaca30 100644 --- a/pyload/manager/Event.py +++ b/pyload/manager/Event.py @@ -5,18 +5,22 @@ from time import time  from pyload.utils import uniqify  class PullManager(object): +      def __init__(self, core):          self.core = core          self.clients = [] +      def newClient(self, uuid):          self.clients.append(Client(uuid)) +      def clean(self):          for n, client in enumerate(self.clients):              if client.lastActive + 30 < time():                  del self.clients[n] +      def getEvents(self, uuid):          events = []          validUuid = False @@ -32,28 +36,34 @@ class PullManager(object):              events = [ReloadAllEvent("queue").toList(), ReloadAllEvent("collector").toList()]          return uniqify(events) +      def addEvent(self, event):          for client in self.clients:              client.addEvent(event)  class Client(object): +      def __init__(self, uuid):          self.uuid = uuid          self.lastActive = time()          self.events = [] +      def newEvents(self):          return len(self.events) > 0 +      def popEvent(self):          if not len(self.events):              return None          return self.events.pop(0) +      def addEvent(self, event):          self.events.append(event)  class UpdateEvent(object): +      def __init__(self, itype, iid, destination):          assert itype == "pack" or itype == "file"          assert destination == "queue" or destination == "collector" @@ -61,10 +71,12 @@ class UpdateEvent(object):          self.id = iid          self.destination = destination +      def toList(self):          return ["update", self.destination, self.type, self.id]  class RemoveEvent(object): +      def __init__(self, itype, iid, destination):          assert itype == "pack" or itype == "file"          assert destination == "queue" or destination == "collector" @@ -72,10 +84,12 @@ class RemoveEvent(object):          self.id = iid          self.destination = destination +      def toList(self):          return ["remove", self.destination, self.type, self.id]  class InsertEvent(object): +      def __init__(self, itype, iid, after, destination):          assert itype == "pack" or itype == "file"          assert destination == "queue" or destination == "collector" @@ -84,21 +98,26 @@ class InsertEvent(object):          self.after = after          self.destination = destination +      def toList(self):          return ["insert", self.destination, self.type, self.id, self.after]  class ReloadAllEvent(object): +      def __init__(self, destination):          assert destination == "queue" or destination == "collector"          self.destination = destination +      def toList(self):          return ["reload", self.destination]  class AccountUpdateEvent(object): +      def toList(self):          return ["account"]  class ConfigUpdateEvent(object): +      def toList(self):          return ["config"] diff --git a/pyload/manager/Plugin.py b/pyload/manager/Plugin.py index 918f6de8a..10abbc2ea 100644 --- a/pyload/manager/Plugin.py +++ b/pyload/manager/Plugin.py @@ -25,6 +25,7 @@ class PluginManager(object):      CONFIG  = re.compile(r'__config\s*=\s*\[([^\]]+)', re.M)      DESC    = re.compile(r'__description\s*=\s*("|"""|\')([^"\']+)') +      def __init__(self, core):          self.core = core @@ -34,6 +35,7 @@ class PluginManager(object):          # register for import addon          sys.meta_path.append(self) +      def loadTypes(self):          rootdir = join(pypath, "pyload", "plugin")          userdir = "userplugins" @@ -46,6 +48,7 @@ class PluginManager(object):          self.TYPES = list(set(self.TYPES) | types) +      def createIndex(self):          """create information for all plugins available""" @@ -64,6 +67,7 @@ class PluginManager(object):          self.core.log.debug("Created index of plugins") +      def parse(self, folder, rootplugins={}):          """          returns dict with information @@ -179,6 +183,7 @@ class PluginManager(object):          return plugins +      def parseUrls(self, urls):          """parse plugins for given list of urls""" @@ -217,6 +222,7 @@ class PluginManager(object):          print res          return res +      def findPlugin(self, type, name):          if type not in self.plugins:              return None @@ -229,6 +235,7 @@ class PluginManager(object):          else:              return self.plugins[type][name] +      def getPlugin(self, type, name, original=False):          """return plugin module from hoster|decrypter|container"""          plugin = self.findPlugin(type, name) @@ -241,6 +248,7 @@ class PluginManager(object):          else:              return self.loadModule(type, name) +      def getPluginName(self, type, name):          """ used to obtain new name if other plugin was injected"""          plugin = self.findPlugin(type, name) @@ -253,6 +261,7 @@ class PluginManager(object):          return name +      def loadModule(self, type, name):          """ Returns loaded module for plugin @@ -282,6 +291,7 @@ class PluginManager(object):                                      % {'name': name, 'type': type, 'version': plugins[name]['version']})                  return module +      def loadClass(self, type, name):          """Returns the class of a plugin with the same name"""          module = self.loadModule(type, name) @@ -290,10 +300,12 @@ class PluginManager(object):          else:              return None +      def getAccountPlugins(self):          """return list of account plugin names"""          return self.accountPlugins.keys() +      def find_module(self, fullname, path=None):          # redirecting imports if necesarry          if fullname.startswith(self.ROOT) or fullname.startswith(self.USERROOT):  # seperate pyload plugins @@ -312,6 +324,7 @@ class PluginManager(object):                  if user and not self.plugins[type][name]['user']:                      return self +      def load_module(self, name, replace=True):          if name not in sys.modules:  # could be already in modules              if replace: @@ -333,6 +346,7 @@ class PluginManager(object):          return sys.modules[name] +      def reloadPlugins(self, type_plugins):          """ reload and reindex plugins """          if not type_plugins: @@ -378,6 +392,7 @@ class PluginManager(object):          return reloaded  #: return a list of the plugins successfully reloaded +      def reloadPlugin(self, type_plugin):          """ reload and reindex ONE plugin """          return True if self.reloadPlugins(type_plugin) else False diff --git a/pyload/manager/Remote.py b/pyload/manager/Remote.py index 910881164..4fdb36fc2 100644 --- a/pyload/manager/Remote.py +++ b/pyload/manager/Remote.py @@ -5,6 +5,7 @@ from threading import Thread  from traceback import print_exc  class BackendBase(Thread): +      def __init__(self, manager):          Thread.__init__(self)          self.m = manager @@ -12,6 +13,7 @@ class BackendBase(Thread):          self.enabled = True          self.running = False +      def run(self):          self.running = True          try: @@ -23,18 +25,23 @@ class BackendBase(Thread):          finally:              self.running = False +      def setup(self, host, port):          pass +      def checkDeps(self):          return True +      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() @@ -43,6 +50,7 @@ class BackendBase(Thread):  class RemoteManager(object):      available = [] +      def __init__(self, core):          self.core = core          self.backends = [] diff --git a/pyload/manager/Thread.py b/pyload/manager/Thread.py index 753a8c251..dd8e6bcce 100644 --- a/pyload/manager/Thread.py +++ b/pyload/manager/Thread.py @@ -54,12 +54,14 @@ class ThreadManager(object):          for i in range(0, self.core.config.get("download", "max_downloads")):              self.createThread() +      def createThread(self):          """create a download thread"""          thread = DownloadThread(self)          self.threads.append(thread) +      def createInfoThread(self, data, pid):          """          start a thread whichs fetches online status and other infos @@ -70,6 +72,8 @@ class ThreadManager(object):          InfoThread(self, data, pid)      @lock + +      def createResultThread(self, data, add=False):          """ creates a thread to fetch online status, returns result id """          self.timestamp = time() + 5 * 60 @@ -82,6 +86,8 @@ class ThreadManager(object):          return rid      @lock + +      def getInfoResult(self, rid):          """returns result and clears it"""          self.timestamp = time() + 5 * 60 @@ -94,9 +100,12 @@ class ThreadManager(object):              return {}      @lock + +      def setInfoResults(self, rid, result):          self.infoResults[rid].update(result) +      def getActiveFiles(self):          active = [x.active for x in self.threads if x.active and isinstance(x.active, PyFile)] @@ -105,10 +114,12 @@ class ThreadManager(object):          return active +      def processingIds(self):          """get a id list of all pyfiles processed"""          return [x.id for x in self.getActiveFiles()] +      def work(self):          """run all task which have to be done (this is for repetivive call by core)"""          try: @@ -136,7 +147,9 @@ class ThreadManager(object):              self.infoResults.clear()              self.core.log.debug("Cleared Result cache") +      #-------------------------------------------------------------------------- +      def tryReconnect(self):          """checks if reconnect needed""" @@ -189,6 +202,7 @@ class ThreadManager(object):          self.reconnecting.clear() +      def getIP(self):          """retrieve current ip"""          services = [("http://automation.whatismyip.com/n09230945.asp", "(\S+)"), @@ -207,7 +221,9 @@ class ThreadManager(object):          return ip +      #-------------------------------------------------------------------------- +      def checkThreadCount(self):          """checks if there are need for increasing or reducing thread count""" @@ -220,6 +236,7 @@ class ThreadManager(object):              if free:                  free[0].put("quit") +      def cleanPycurl(self):          """ make a global curl cleanup (currently ununused) """          if self.processingIds(): @@ -230,7 +247,9 @@ class ThreadManager(object):          self.core.log.debug("Cleaned up pycurl")          return True +      #-------------------------------------------------------------------------- +      def assignJob(self):          """assing a job to a thread if possible""" @@ -287,10 +306,12 @@ class ThreadManager(object):              else:                  thread = DecrypterThread(self, job) +      def getLimit(self, thread):          limit = thread.active.plugin.account.getAccountData(thread.active.plugin.user)["options"].get("limitDL", ["0"])[0]          return int(limit) +      def cleanup(self):          """do global cleanup, should be called when finished with pycurl"""          pycurl.global_cleanup() diff --git a/pyload/manager/event/Scheduler.py b/pyload/manager/event/Scheduler.py index 2cb537383..d67d9063a 100644 --- a/pyload/manager/event/Scheduler.py +++ b/pyload/manager/event/Scheduler.py @@ -11,13 +11,16 @@ class AlreadyCalled(Exception):  class Deferred(object): +      def __init__(self):          self.call = []          self.result = () +      def addCallback(self, f, *cargs, **ckwargs):          self.call.append((f, cargs, ckwargs)) +      def callback(self, *args, **kwargs):          if self.result:              raise AlreadyCalled @@ -29,11 +32,13 @@ class Deferred(object):  class Scheduler(object): +      def __init__(self, core):          self.core = core          self.queue = PriorityQueue() +      def addJob(self, t, call, args=[], kwargs={}, threaded=True):          d = Deferred()          t += time() @@ -41,6 +46,7 @@ class Scheduler(object):          self.queue.put((t, j))          return d +      def removeJob(self, d):          """          :param d: defered object @@ -58,6 +64,7 @@ class Scheduler(object):          return False +      def work(self):          while True:              t, j = self.queue.get() @@ -72,6 +79,7 @@ class Scheduler(object):  class Job(object): +      def __init__(self, time, call, args=[], kwargs={}, deferred=None, threaded=True):          self.time = float(time)          self.call = call @@ -80,6 +88,7 @@ class Job(object):          self.deferred = deferred          self.threaded = threaded +      def run(self):          ret = self.call(*self.args, **self.kwargs)          if self.deferred is None: @@ -87,6 +96,7 @@ class Job(object):          else:              self.deferred.callback(ret) +      def start(self):          if self.threaded:              t = Thread(target=self.run) @@ -103,17 +113,21 @@ class PriorityQueue(object):          self.queue = []          self.lock = Lock() +      def __iter__(self):          return iter(self.queue) +      def __delitem__(self, key):          del self.queue[key] +      def put(self, element):          self.lock.acquire()          heappush(self.queue, element)          self.lock.release() +      def get(self):          """ return element or None """          self.lock.acquire() diff --git a/pyload/manager/thread/Addon.py b/pyload/manager/thread/Addon.py index 7feec227e..f3d219989 100644 --- a/pyload/manager/thread/Addon.py +++ b/pyload/manager/thread/Addon.py @@ -20,7 +20,6 @@ from pyload.manager.thread.Plugin import PluginThread  class AddonThread(PluginThread):      """thread for addons""" -    #--------------------------------------------------------------------------      def __init__(self, m, function, args, kwargs):          """Constructor"""          PluginThread.__init__(self, m) @@ -35,20 +34,24 @@ class AddonThread(PluginThread):          self.start() +      def getActiveFiles(self):          return self.active +      def addActive(self, pyfile):          """ Adds a pyfile to active list and thus will be displayed on overview"""          if pyfile not in self.active:              self.active.append(pyfile) +      def finishFile(self, pyfile):          if pyfile in self.active:              self.active.remove(pyfile)          pyfile.finishIfDone() +      def run(self):          try:              try: diff --git a/pyload/manager/thread/Decrypter.py b/pyload/manager/thread/Decrypter.py index 12806163c..308e94f10 100644 --- a/pyload/manager/thread/Decrypter.py +++ b/pyload/manager/thread/Decrypter.py @@ -33,9 +33,11 @@ class DecrypterThread(PluginThread):          self.start() +      def getActiveFiles(self):          return [self.active] +      def run(self):          """run method""" diff --git a/pyload/manager/thread/Download.py b/pyload/manager/thread/Download.py index 37fe844ec..fc76b655e 100644 --- a/pyload/manager/thread/Download.py +++ b/pyload/manager/thread/Download.py @@ -21,8 +21,6 @@ from pyload.plugin.Plugin import Abort, Fail, Reconnect, Retry, SkipDownload  class DownloadThread(PluginThread):      """thread for downloading files from 'real' hoster plugins""" -    #-------------------------------------------------------------------------- -      def __init__(self, manager):          """Constructor"""          PluginThread.__init__(self, manager) @@ -32,7 +30,9 @@ class DownloadThread(PluginThread):          self.start() +      #-------------------------------------------------------------------------- +      def run(self):          """run method"""          pyfile = None @@ -201,10 +201,12 @@ class DownloadThread(PluginThread):              pyfile.finishIfDone()              self.m.core.files.save() +      def put(self, job):          """assing job to thread"""          self.queue.put(job) +      def stop(self):          """stops the thread"""          self.put("quit") diff --git a/pyload/manager/thread/Info.py b/pyload/manager/thread/Info.py index edc9489e9..487c3b924 100644 --- a/pyload/manager/thread/Info.py +++ b/pyload/manager/thread/Info.py @@ -36,6 +36,7 @@ class InfoThread(PluginThread):          self.start() +      def run(self):          """run method""" @@ -120,9 +121,11 @@ class InfoThread(PluginThread):          self.m.timestamp = time() + 5 * 60 +      def updateDB(self, plugin, result):          self.m.core.files.updateFileInfo(result, self.pid) +      def updateResult(self, plugin, result, force=False):          # parse package name and generate result          # accumulate results @@ -144,9 +147,11 @@ class InfoThread(PluginThread):              self.cache = [] +      def updateCache(self, plugin, result):          self.cache.extend(result) +      def fetchForPlugin(self, pluginname, plugin, urls, cb, err=None):          try:              result = []  # result loaded from cache @@ -184,6 +189,7 @@ class InfoThread(PluginThread):                  result = [(url, 0, 3, url) for url in urls]                  cb(pluginname, result) +      def decryptContainer(self, plugin, url):          data = []          # only works on container plugins diff --git a/pyload/manager/thread/Plugin.py b/pyload/manager/thread/Plugin.py index 1e7d7b4e4..155e687d4 100644 --- a/pyload/manager/thread/Plugin.py +++ b/pyload/manager/thread/Plugin.py @@ -23,7 +23,6 @@ from pyload.api import OnlineStatus  class PluginThread(Thread):      """abstract base class for thread types""" -    #--------------------------------------------------------------------------      def __init__(self, manager):          """Constructor"""          Thread.__init__(self) @@ -70,6 +69,7 @@ class PluginThread(Thread):          self.m.core.log.info("Debug Report written to %s" % dump_name) +      def getDebugDump(self, pyfile):          dump = "pyLoad %s Debug Report of %s %s \n\nTRACEBACK:\n %s \n\nFRAMESTACK:\n" % (              self.m.core.api.getServerVersion(), pyfile.pluginname, pyfile.plugin.__version, format_exc()) @@ -124,6 +124,7 @@ class PluginThread(Thread):          return dump +      def clean(self, pyfile):          """ set thread unactive and release pyfile """          self.active = False diff --git a/pyload/network/Browser.py b/pyload/network/Browser.py index 89341ff25..1c0596ccc 100644 --- a/pyload/network/Browser.py +++ b/pyload/network/Browser.py @@ -9,6 +9,7 @@ from pyload.network.HTTPDownload import HTTPDownload  class Browser(object):      __slots__ = ("log", "options", "bucket", "cj", "_size", "http", "dl") +      def __init__(self, bucket=None, options={}):          self.log = getLogger("log") @@ -26,6 +27,7 @@ class Browser(object):          if hasattr(self, "http"): self.http.close()          self.http = HTTPRequest(self.cj, self.options) +      def setLastURL(self, val):          self.http.lastURL = val @@ -35,17 +37,22 @@ class Browser(object):      code = property(lambda self: self.http.code)      cookieJar = property(lambda self: self.cj) +      def setCookieJar(self, cj):          self.cj = cj          self.http.cj = cj      @property + +      def speed(self):          if self.dl:              return self.dl.speed          return 0      @property + +      def size(self):          if self._size:              return self._size @@ -54,30 +61,38 @@ class Browser(object):          return 0      @property + +      def arrived(self):          if self.dl:              return self.dl.arrived          return 0      @property + +      def percent(self):          if not self.size: return 0          return (self.arrived * 100) / self.size +      def clearCookies(self):          if self.cj:              self.cj.clear()          self.http.clearCookies() +      def clearReferer(self):          self.http.lastURL = None +      def abortDownloads(self):          self.http.abort = True          if self.dl:              self._size = self.dl.size              self.dl.abort = True +      def httpDownload(self, url, filename, get={}, post={}, ref=True, cookies=True, chunks=1, resume=False,                       progressNotify=None, disposition=False):          """ this can also download ftp """ @@ -91,14 +106,17 @@ class Browser(object):          return name +      def load(self, *args, **kwargs):          """ retrieves page """          return self.http.load(*args, **kwargs) +      def putHeader(self, name, value):          """ add a header to the request """          self.http.putHeader(name, value) +      def addAuth(self, pwd):          """Adds user and pw for http auth @@ -107,20 +125,25 @@ class Browser(object):          self.options["auth"] = pwd          self.renewHTTPRequest() #we need a new request +      def removeAuth(self):          if "auth" in self.options: del self.options["auth"]          self.renewHTTPRequest() +      def setOption(self, name, value):          """Adds an option to the request, see HTTPRequest for existing ones"""          self.options[name] = value +      def deleteOption(self, name):          if name in self.options: del self.options[name] +      def clearHeaders(self):          self.http.clearHeaders() +      def close(self):          """ cleanup """          if hasattr(self, "http"): diff --git a/pyload/network/CookieJar.py b/pyload/network/CookieJar.py index a2b302776..35d7fa6ef 100644 --- a/pyload/network/CookieJar.py +++ b/pyload/network/CookieJar.py @@ -21,6 +21,7 @@ class CookieJar(Cookie.SimpleCookie):      def getCookie(self, name):          return self[name].value +      def setCookie(self, domain, name, value, path="/", exp=None, secure="FALSE"):          self[name] = value          self[name]["domain"] = domain diff --git a/pyload/network/HTTPChunk.py b/pyload/network/HTTPChunk.py index 41752b940..5395b7bda 100644 --- a/pyload/network/HTTPChunk.py +++ b/pyload/network/HTTPChunk.py @@ -17,12 +17,14 @@ class WrongFormat(Exception):  class ChunkInfo(object): +      def __init__(self, name):          self.name = unicode(name)          self.size = 0          self.resume = False          self.chunks = [] +      def __repr__(self):          ret = "ChunkInfo: %s, %s\n" % (self.name, self.size)          for i, c in enumerate(self.chunks): @@ -30,15 +32,19 @@ class ChunkInfo(object):          return ret +      def setSize(self, size):          self.size = int(size) +      def addChunk(self, name, range):          self.chunks.append((name, range)) +      def clear(self):          self.chunks = [] +      def createChunks(self, chunks):          self.clear()          chunk_size = self.size / chunks @@ -62,6 +68,8 @@ class ChunkInfo(object):          fh.close()      @staticmethod + +      def load(name):          fs_name = fs_encode("%s.chunks" % name)          if not exists(fs_name): @@ -93,21 +101,26 @@ class ChunkInfo(object):          fh.close()          return ci +      def remove(self):          fs_name = fs_encode("%s.chunks" % self.name)          if exists(fs_name): remove(fs_name) +      def getCount(self):          return len(self.chunks) +      def getChunkName(self, index):          return self.chunks[index][0] +      def getChunkRange(self, index):          return self.chunks[index][1]  class HTTPChunk(HTTPRequest): +      def __init__(self, id, parent, range=None, resume=False):          self.id = id          self.p = parent # HTTPDownload instance @@ -136,13 +149,17 @@ class HTTPChunk(HTTPRequest):          self.sleep = 0.000          self.lastSize = 0 +      def __repr__(self):          return "<HTTPChunk id=%d, size=%d, arrived=%d>" % (self.id, self.size, self.arrived)      @property + +      def cj(self):          return self.p.cj +      def getHandle(self):          """ returns a Curl handle ready to use for perform/multiperform """ @@ -188,6 +205,7 @@ class HTTPChunk(HTTPRequest):          return self.c +      def writeHeader(self, buf):          self.header += buf          #@TODO forward headers?, this is possibly unneeeded, when we just parse valid 200 headers @@ -202,6 +220,7 @@ class HTTPChunk(HTTPRequest):          self.headerParsed = True +      def writeBody(self, buf):          #ignore BOM, it confuses unrar          if not self.BOMChecked: @@ -263,25 +282,30 @@ class HTTPChunk(HTTPRequest):          self.headerParsed = True +      def stop(self):          """The download will not proceed after next call of writeBody"""          self.range = [0, 0]          self.size = 0 +      def resetRange(self):          """ Reset the range, so the download will load all data available  """          self.range = None +      def setRange(self, range):          self.range = range          self.size = range[1] - range[0] +      def flushFile(self):          """  flush and close file """          self.fp.flush()          fsync(self.fp.fileno()) #make sure everything was written to disk          self.fp.close() #needs to be closed, or merging chunks will fail +      def close(self):          """ closes everything, unusable after this """          if self.fp: self.fp.close() diff --git a/pyload/network/HTTPDownload.py b/pyload/network/HTTPDownload.py index 0d331ca99..89e594640 100644 --- a/pyload/network/HTTPDownload.py +++ b/pyload/network/HTTPDownload.py @@ -59,19 +59,26 @@ class HTTPDownload(object):          self.progress = progress      @property + +      def speed(self):          last = [sum(x) for x in self.lastSpeeds if x]          return (sum(self.speeds) + sum(last)) / (1 + len(last))      @property + +      def arrived(self):          return sum([c.arrived for c in self.chunks])      @property + +      def percent(self):          if not self.size: return 0          return (self.arrived * 100) / self.size +      def _copyChunks(self):          init = fs_encode(self.info.getChunkName(0)) #initial chunk name @@ -104,6 +111,7 @@ class HTTPDownload(object):          move(init, fs_encode(self.filename))          self.info.remove() #remove info file +      def download(self, chunks=1, resume=False):          """ returns new filename or None """ @@ -132,6 +140,7 @@ class HTTPDownload(object):          if self.nameDisposition and self.disposition: return self.nameDisposition          return None +      def _download(self, chunks, resume):          if not resume:              self.info.clear() @@ -280,15 +289,18 @@ class HTTPDownload(object):          self._copyChunks() +      def updateProgress(self):          if self.progress:              self.progress(self.percent) +      def findChunk(self, handle):          """ linear search to find a chunk (should be ok since chunk size is usually low) """          for chunk in self.chunks:              if chunk.c == handle: return chunk +      def closeChunk(self, chunk):          try:              self.m.remove_handle(chunk.c) @@ -297,6 +309,7 @@ class HTTPDownload(object):          finally:              chunk.close() +      def close(self):          """ cleanup """          for chunk in self.chunks: diff --git a/pyload/network/HTTPRequest.py b/pyload/network/HTTPRequest.py index fe7e26c48..3e5903df3 100644 --- a/pyload/network/HTTPRequest.py +++ b/pyload/network/HTTPRequest.py @@ -28,6 +28,7 @@ bad_headers = range(400, 404) + range(405, 418) + range(500, 506)  class BadHeader(Exception): +      def __init__(self, code, content=""):          Exception.__init__(self, "Bad server response: %s %s" % (code, responses[int(code)]))          self.code = code @@ -35,6 +36,7 @@ class BadHeader(Exception):  class HTTPRequest(object): +      def __init__(self, cookies=None, options=None):          self.c = pycurl.Curl()          self.rep = StringIO() @@ -58,6 +60,7 @@ class HTTPRequest(object):          self.log = getLogger("log") +      def initHandle(self):          """ sets common options to curl handle """          self.c.setopt(pycurl.FOLLOWLOCATION, 1) @@ -87,6 +90,7 @@ class HTTPRequest(object):                                            "Keep-Alive: 300",                                            "Expect:"]) +      def setInterface(self, options):          interface, proxy, ipv6 = options["interface"], options["proxies"], options["ipv6"] @@ -119,11 +123,13 @@ class HTTPRequest(object):          if "timeout" in options:              self.c.setopt(pycurl.LOW_SPEED_TIME, options["timeout"]) +      def addCookies(self):          """ put cookies from curl handle to cj """          if self.cj:              self.cj.addCookies(self.c.getinfo(pycurl.INFO_COOKIELIST)) +      def getCookies(self):          """ add cookies from cj to curl handle """          if self.cj: @@ -131,9 +137,11 @@ class HTTPRequest(object):                  self.c.setopt(pycurl.COOKIELIST, c)          return +      def clearCookies(self):          self.c.setopt(pycurl.COOKIELIST, "") +      def setRequestContext(self, url, get, post, referer, cookies, multipart=False):          """ sets everything needed for the request """ @@ -171,6 +179,7 @@ class HTTPRequest(object):              self.c.setopt(pycurl.COOKIEJAR, "")              self.getCookies() +      def load(self, url, get={}, post={}, referer=True, cookies=True, just_header=False, multipart=False, decode=False, follow_location=True, save_cookies=True):          """ load and returns a given page """ @@ -212,6 +221,7 @@ class HTTPRequest(object):          return rep +      def verifyHeader(self):          """ raise an exceptions on bad headers """          code = int(self.c.getinfo(pycurl.RESPONSE_CODE)) @@ -220,10 +230,12 @@ class HTTPRequest(object):              raise BadHeader(code, self.getResponse())          return code +      def checkHeader(self):          """ check if header indicates failure"""          return int(self.c.getinfo(pycurl.RESPONSE_CODE)) not in bad_headers +      def getResponse(self):          """ retrieve response from string io """          if self.rep is None: @@ -234,6 +246,7 @@ class HTTPRequest(object):              self.rep = StringIO()              return value +      def decodeResponse(self, rep):          """ decode with correct encoding, relies on header """          header = self.header.splitlines() @@ -269,6 +282,7 @@ class HTTPRequest(object):          return rep +      def write(self, buf):          """ writes response """          if self.rep.tell() > 1000000 or self.abort: @@ -283,16 +297,20 @@ class HTTPRequest(object):          else:              self.rep.write(buf) +      def writeHeader(self, buf):          """ writes header """          self.header += buf +      def putHeader(self, name, value):          self.headers.append("%s: %s" % (name, value)) +      def clearHeaders(self):          self.headers = [] +      def close(self):          """ cleanup, unusable after this """          self.rep.close() diff --git a/pyload/network/JsEngine.py b/pyload/network/JsEngine.py index c64e8c490..bcf6ae0e2 100644 --- a/pyload/network/JsEngine.py +++ b/pyload/network/JsEngine.py @@ -33,6 +33,8 @@ class JsEngine(object):      @classmethod + +      def find(cls):          """ Check if there is any engine available """          return [E for E in ENGINES if E.find()] @@ -120,6 +122,8 @@ class AbstractEngine(object):      @classmethod + +      def find(cls):          """ Check if the engine is available """          try: diff --git a/pyload/network/RequestFactory.py b/pyload/network/RequestFactory.py index 579eafea7..5f8e7e206 100644 --- a/pyload/network/RequestFactory.py +++ b/pyload/network/RequestFactory.py @@ -11,6 +11,7 @@ from pyload.network.CookieJar import CookieJar  from pyload.network.XDCCRequest import XDCCRequest  class RequestFactory(object): +      def __init__(self, core):          self.lock = Lock()          self.core = core @@ -18,9 +19,11 @@ class RequestFactory(object):          self.updateBucket()          self.cookiejars = {} +      def iface(self):          return self.core.config["download"]["interface"] +      def getRequest(self, pluginName, account=None, type="HTTP"):          self.lock.acquire() @@ -38,12 +41,14 @@ class RequestFactory(object):          self.lock.release()          return req +      def getHTTPRequest(self, **kwargs):          """ returns a http request, dont forget to close it ! """          options = self.getOptions()          options.update(kwargs) # submit kwargs as additional options          return HTTPRequest(CookieJar(None), options) +      def getURL(self, *args, **kwargs):          """ see HTTPRequest for argument list """          cj = None @@ -65,6 +70,7 @@ class RequestFactory(object):          return rep +      def getCookieJar(self, pluginName, account=None):          if (pluginName, account) in self.cookiejars:              return self.cookiejars[(pluginName, account)] @@ -73,6 +79,7 @@ class RequestFactory(object):          self.cookiejars[(pluginName, account)] = cj          return cj +      def getProxies(self):          """ returns a proxy list for the request classes """          if not self.core.config["proxy"]["proxy"]: @@ -99,12 +106,14 @@ class RequestFactory(object):                  "password": pw,                  } +      def getOptions(self):          """returns options needed for pycurl"""          return {"interface": self.iface(),                  "proxies": self.getProxies(),                  "ipv6": self.core.config["download"]["ipv6"]} +      def updateBucket(self):          """ set values in the bucket according to settings"""          if not self.core.config["download"]["limit_speed"]: diff --git a/pyload/network/XDCCRequest.py b/pyload/network/XDCCRequest.py index c49f418c4..a4813e039 100644 --- a/pyload/network/XDCCRequest.py +++ b/pyload/network/XDCCRequest.py @@ -16,6 +16,7 @@ from pyload.plugin.Plugin import Abort  class XDCCRequest(object): +      def __init__(self, timeout=30, proxies={}):          self.proxies = proxies @@ -27,6 +28,7 @@ class XDCCRequest(object):          self.abort = False +      def createSocket(self):          # proxytype = None          # proxy = None @@ -46,6 +48,7 @@ class XDCCRequest(object):          return socket.socket() +      def download(self, ip, port, filename, irc, progress=None):          ircbuffer = "" @@ -109,6 +112,7 @@ class XDCCRequest(object):          return filename +      def _keepAlive(self, sock, *readbuffer):          fdset = select([sock], [], [], 0)          if sock not in fdset[0]: @@ -124,21 +128,29 @@ class XDCCRequest(object):              if first[0] == "PING":                  sock.send("PONG %s\r\n" % first[1]) +      def abortDownloads(self):          self.abort = True      @property + +      def size(self):          return self.filesize      @property + +      def arrived(self):          return self.recv      @property + +      def percent(self):          if not self.filesize: return 0          return (self.recv * 100) / self.filesize +      def close(self):          pass diff --git a/pyload/plugin/Account.py b/pyload/plugin/Account.py index 6a3eddc5b..09dd90ad0 100644 --- a/pyload/plugin/Account.py +++ b/pyload/plugin/Account.py @@ -63,6 +63,8 @@ class Account(Base):      @lock + +      def _login(self, user, data):          # set timestamp for login          self.timestamps[user] = time() @@ -137,6 +139,8 @@ class Account(Base):      @lock + +      def getAccountInfo(self, name, force=False):          """retrieve account infos for an user, do **not** overwrite this method!\\          just use it to retrieve infos in hoster plugins. see `loadAccountInfo` @@ -295,6 +299,8 @@ class Account(Base):      @lock + +      def checkLogin(self, user):          """ checks if user is still logged in """          if user in self.timestamps: diff --git a/pyload/plugin/Addon.py b/pyload/plugin/Addon.py index 1f4730851..35f010f29 100644 --- a/pyload/plugin/Addon.py +++ b/pyload/plugin/Addon.py @@ -16,6 +16,7 @@ class Expose(object):  def threaded(fn): +      def run(*args,**kwargs):          addonManager.startThread(fn, *args, **kwargs) @@ -111,6 +112,7 @@ class Addon(Base):          if has_method(self.__class__, "unload"):              self.unload() +      def unload(self):  # Deprecated, use method deactivate() instead          pass @@ -121,11 +123,14 @@ class Addon(Base):      # Event methods - overwrite these if needed + +      def activate(self):          """ called when addon was activated """          if has_method(self.__class__, "coreReady"):              self.coreReady() +      def coreReady(self):  # Deprecated, use method activate() instead          pass @@ -135,6 +140,7 @@ class Addon(Base):          if has_method(self.__class__, "coreExiting"):              self.coreExiting() +      def coreExiting(self):  # Deprecated, use method exit() instead          pass diff --git a/pyload/plugin/Extractor.py b/pyload/plugin/Extractor.py index 80f123a52..decb332fd 100644 --- a/pyload/plugin/Extractor.py +++ b/pyload/plugin/Extractor.py @@ -36,17 +36,23 @@ class Extractor:      @classmethod + +      def isArchive(cls, filename):          name = os.path.basename(filename).lower()          return any(name.endswith(ext) for ext in cls.EXTENSIONS)      @classmethod + +      def isMultipart(cls, filename):          return False      @classmethod + +      def isUsable(cls):          """ Check if system statisfy dependencies          :return: boolean @@ -55,6 +61,8 @@ class Extractor:      @classmethod + +      def getTargets(cls, files_ids):          """ Filter suited targets from list of filename id tuple list          :param files_ids: List of filepathes @@ -111,6 +119,7 @@ class Extractor:          """          raise NotImplementedError +      def verify(self):          """Testing with Extractors buildt-in method          Raises error if password is needed, integrity is questionable or else. diff --git a/pyload/plugin/OCR.py b/pyload/plugin/OCR.py index df32b9f23..df5eeea1f 100644 --- a/pyload/plugin/OCR.py +++ b/pyload/plugin/OCR.py @@ -26,21 +26,26 @@ class OCR(Base):      __license     = "GPLv3"      __authors     = [("pyLoad Team", "admin@pyload.org")] +      def __init__(self):          self.logger = logging.getLogger("log") +      def load_image(self, image):          self.image = Image.open(image)          self.pixels = self.image.load()          self.result_captcha = '' +      def deactivate(self):          """delete all tmp images"""          pass +      def threshold(self, value):          self.image = self.image.point(lambda a: a * value + 10) +      def run(self, command):          """Run a command""" @@ -51,6 +56,7 @@ class OCR(Base):          popen.stderr.close()          self.logger.debug("Tesseract ReturnCode %s Output: %s" % (popen.returncode, output)) +      def run_tesser(self, subset=False, digits=True, lowercase=True, uppercase=True, pagesegmode=None):          # tmpTif = tempfile.NamedTemporaryFile(suffix=".tif")          try: @@ -113,15 +119,18 @@ class OCR(Base):          except Exception:              pass +      def get_captcha(self, name):          raise NotImplementedError +      def to_greyscale(self):          if self.image.mode != 'L':              self.image = self.image.convert('L')          self.pixels = self.image.load() +      def eval_black_white(self, limit):          self.pixels = self.image.load()          w, h = self.image.size @@ -132,6 +141,7 @@ class OCR(Base):                  else:                      self.pixels[x, y] = 0 +      def clean(self, allowed):          pixels = self.pixels @@ -177,6 +187,7 @@ class OCR(Base):          self.pixels = pixels +      def derotate_by_average(self):          """rotate by checking each angle and guess most suitable""" @@ -250,6 +261,7 @@ class OCR(Base):          self.pixels = pixels +      def split_captcha_letters(self):          captcha = self.image          started = False @@ -289,6 +301,7 @@ class OCR(Base):          return letters +      def correct(self, values, var=None):          if var:              result = var diff --git a/pyload/plugin/Plugin.py b/pyload/plugin/Plugin.py index c14155751..cedab3b4f 100644 --- a/pyload/plugin/Plugin.py +++ b/pyload/plugin/Plugin.py @@ -61,38 +61,49 @@ class Base(object):          #: Core instance          self.core = core +      def _log(self, type, args):          msg = " | ".join([encode(str(a)).strip() for a in args if a])          logger = getattr(self.core.log, type)          logger("%s: %s" % (self.__class__.__name__, msg or _("%s MARK" % type.upper()))) +      def logDebug(self, *args):          if self.core.debug:              return self._log("debug", args) +      def logInfo(self, *args):          return self._log("info", args) +      def logWarning(self, *args):          return self._log("warning", args) +      def logError(self, *args):          return self._log("error", args) +      def logCritical(self, *args):          return self._log("critical", args) +      def grtPluginType(self):          return getattr(self, "_%s__type" % self.__class__.__name__) +      def getPluginConfSection(self):          return "%s_%s" % (self.__class__.__name__, getattr(self, "_%s__type" % self.__class__.__name__))      #: Deprecated method + +      def setConf(self, option, value):          """ see `setConfig` """          self.setConfig(option, value) +      def setConfig(self, option, value):          """ Set config value for current plugin @@ -103,10 +114,13 @@ class Base(object):          self.core.config.setPlugin(self.getPluginConfSection(), option, value)      #: Deprecated method + +      def getConf(self, option):          """ see `getConfig` """          return self.core.config.getPlugin(self.getPluginConfSection(), option) +      def getConfig(self, option):          """ Returns config value for current plugin @@ -115,24 +129,29 @@ class Base(object):          """          return self.core.config.getPlugin(self.getPluginConfSection(), option) +      def setStorage(self, key, value):          """ Saves a value persistently to the database """          self.core.db.setStorage(self.getPluginConfSection(), key, value) +      def store(self, key, value):          """ same as `setStorage` """          self.core.db.setStorage(self.getPluginConfSection(), key, value) +      def getStorage(self, key=None, default=None):          """ Retrieves saved value or dict of all saved entries if key is None """          if key:              return self.core.db.getStorage(self.getPluginConfSection(), key) or default          return self.core.db.getStorage(self.getPluginConfSection(), key) +      def retrieve(self, *args, **kwargs):          """ same as `getStorage` """          return self.getStorage(*args, **kwargs) +      def delStorage(self, key):          """ Delete entry in db """          self.core.db.delStorage(self.__class__.__name__, key) @@ -158,6 +177,7 @@ class Plugin(Base):      info = {}  #: file info dict +      def __init__(self, pyfile):          Base.__init__(self, pyfile.m.core) @@ -224,22 +244,27 @@ class Plugin(Base):          self.init() +      def getChunkCount(self):          if self.chunkLimit <= 0:              return self.core.config['download']['chunks']          return min(self.core.config['download']['chunks'], self.chunkLimit) +      def __call__(self):          return self.__class__.__name__ +      def init(self):          """initialize the plugin (in addition to `__init__`)"""          pass +      def setup(self):          """ setup for enviroment and other things, called before downloading (possibly more than one time)"""          pass +      def preprocessing(self, thread):          """ handles important things to do before starting """          self.thread = thread @@ -255,16 +280,19 @@ class Plugin(Base):          return self.process(self.pyfile) +      def process(self, pyfile):          """the 'main' method of every plugin, you **have to** overwrite it"""          raise NotImplementedError +      def resetAccount(self):          """ dont use account and retry download """          self.account = None          self.req = self.core.requestFactory.getRequest(self.__class__.__name__)          self.retry() +      def checksum(self, local_file=None):          """          return codes: @@ -278,11 +306,13 @@ class Plugin(Base):          return True, 10 +      def setReconnect(self, reconnect):          reconnect = bool(reconnect)          self.logDebug("Set wantReconnect to: %s (previous: %s)" % (reconnect, self.wantReconnect))          self.wantReconnect = reconnect +      def setWait(self, seconds, reconnect=None):          """Set a specific wait time later used with `wait` @@ -300,6 +330,7 @@ class Plugin(Base):          if reconnect is not None:              self.setReconnect(reconnect) +      def wait(self, seconds=None, reconnect=None):          """ waits the time previously set """ @@ -345,16 +376,19 @@ class Plugin(Base):          pyfile.status = status +      def fail(self, reason):          """ fail and give reason """          raise Fail(reason) +      def abort(self, reason=""):          """ abort and give reason """          if reason:              self.pyfile.error = str(reason)          raise Abort +      def error(self, reason="", type=""):          if not reason and not type:              type = "unknown" @@ -365,18 +399,21 @@ class Plugin(Base):          raise Fail(msg) +      def offline(self, reason=""):          """ fail and indicate file is offline """          if reason:              self.pyfile.error = str(reason)          raise Fail("offline") +      def tempOffline(self, reason=""):          """ fail and indicates file ist temporary offline, the core may take consequences """          if reason:              self.pyfile.error = str(reason)          raise Fail("temp. offline") +      def retry(self, max_tries=5, wait_time=1, reason=""):          """Retries and begin again from the beginning @@ -392,16 +429,19 @@ class Plugin(Base):          self.retries += 1          raise Retry(reason) +      def invalidCaptcha(self):          self.logError(_("Invalid captcha"))          if self.cTask:              self.cTask.invalid() +      def correctCaptcha(self):          self.logInfo(_("Correct captcha"))          if self.cTask:              self.cTask.correct() +      def decryptCaptcha(self, url, get={}, post={}, cookies=False, forceUser=False, imgtype='jpg',                         result_type='textual', timeout=290):          """ Loads a captcha and decrypts it with ocr, plugin, user input @@ -472,6 +512,7 @@ class Plugin(Base):          return result +      def load(self, url, get={}, post={}, ref=True, cookies=True, just_header=False, decode=False, follow_location=True, save_cookies=True):          """Load content at url and returns it @@ -539,6 +580,7 @@ class Plugin(Base):          return res +      def download(self, url, get={}, post={}, ref=True, cookies=True, disposition=False):          """Downloads the content at url to download folder @@ -628,6 +670,7 @@ class Plugin(Base):          self.lastDownload = filename          return self.lastDownload +      def checkDownload(self, rules, api_size=0, max_size=50000, delete=True, read_size=0):          """ checks the content of the last downloaded file, re match is saved to `lastCheck` @@ -668,12 +711,14 @@ class Plugin(Base):                      self.lastCheck = m                      return name +      def getPassword(self):          """ get the password the user provided in the package"""          password = self.pyfile.package().password          if not password: return ""          return password +      def checkForSameFiles(self, starting=False):          """ checks if same file was/is downloaded within same package @@ -705,6 +750,7 @@ class Plugin(Base):              self.logDebug("File %s not skipped, because it does not exists." % self.pyfile.name) +      def clean(self):          """ clean everything and remove references """          if hasattr(self, "pyfile"): diff --git a/pyload/plugin/account/NoPremiumPl.py b/pyload/plugin/account/NoPremiumPl.py index cbbc937b5..ac0e64cd4 100644 --- a/pyload/plugin/account/NoPremiumPl.py +++ b/pyload/plugin/account/NoPremiumPl.py @@ -31,6 +31,7 @@ class NoPremiumPl(Account):      _usr = None      _pwd = None +      def loadAccountInfo(self, name, req):          self._req = req          try: @@ -53,6 +54,7 @@ class NoPremiumPl(Account):                      "premium": premium                  }) +      def login(self, user, data, req):          self._usr = user          self._pwd = hashlib.sha1(hashlib.md5(data["password"]).hexdigest()).hexdigest() @@ -68,6 +70,7 @@ class NoPremiumPl(Account):          data['usr'] = self._usr          data['pwd'] = self._pwd +      def createAuthQuery(self):          query = self._api_query          query["username"] = self._usr @@ -75,6 +78,7 @@ class NoPremiumPl(Account):          return query +      def runAuthQuery(self):          data = self._req.load(self._api_url, post=self.createAuthQuery()) diff --git a/pyload/plugin/account/OboomCom.py b/pyload/plugin/account/OboomCom.py index 17239bda2..17d81428c 100644 --- a/pyload/plugin/account/OboomCom.py +++ b/pyload/plugin/account/OboomCom.py @@ -9,11 +9,13 @@ except ImportError:      from beaker.crypto.pbkdf2 import pbkdf2      from binascii import b2a_hex      class PBKDF2(object): +          def __init__(self, passphrase, salt, iterations=1000):              self.passphrase = passphrase              self.salt = salt              self.iterations = iterations +          def hexread(self, octets):              return b2a_hex(pbkdf2(self.passphrase, self.salt, self.iterations, octets)) diff --git a/pyload/plugin/account/PremiumTo.py b/pyload/plugin/account/PremiumTo.py index 01369554f..fcd856ea7 100644 --- a/pyload/plugin/account/PremiumTo.py +++ b/pyload/plugin/account/PremiumTo.py @@ -15,7 +15,6 @@ class PremiumTo(Account):                         ("stickell", "l.stickell@yahoo.it")] -      def loadAccountInfo(self, user, req):          traffic = req.load("http://premium.to/api/straffic.php",                             get={'username': self.username, 'password': self.password}) diff --git a/pyload/plugin/account/RapideoPl.py b/pyload/plugin/account/RapideoPl.py index dddb22781..d40c76cb5 100644 --- a/pyload/plugin/account/RapideoPl.py +++ b/pyload/plugin/account/RapideoPl.py @@ -31,6 +31,7 @@ class RapideoPl(Account):      _usr = None      _pwd = None +      def loadAccountInfo(self, name, req):          self._req = req          try: @@ -53,6 +54,7 @@ class RapideoPl(Account):                      "premium": premium                  }) +      def login(self, user, data, req):          self._usr = user          self._pwd = hashlib.md5(data["password"]).hexdigest() @@ -67,6 +69,7 @@ class RapideoPl(Account):          data['usr'] = self._usr          data['pwd'] = self._pwd +      def createAuthQuery(self):          query = self._api_query          query["username"] = self._usr @@ -74,6 +77,7 @@ class RapideoPl(Account):          return query +      def runAuthQuery(self):          data = self._req.load(self._api_url, post=self.createAuthQuery()) diff --git a/pyload/plugin/account/SmoozedCom.py b/pyload/plugin/account/SmoozedCom.py index 3d0756021..7f4beb7d9 100644 --- a/pyload/plugin/account/SmoozedCom.py +++ b/pyload/plugin/account/SmoozedCom.py @@ -10,11 +10,13 @@ except ImportError:      from beaker.crypto.pbkdf2 import pbkdf2      from binascii import b2a_hex      class PBKDF2(object): +          def __init__(self, passphrase, salt, iterations=1000):              self.passphrase = passphrase              self.salt = salt              self.iterations = iterations +          def hexread(self, octets):              return b2a_hex(pbkdf2(self.passphrase, self.salt, self.iterations, octets)) diff --git a/pyload/plugin/addon/AndroidPhoneNotify.py b/pyload/plugin/addon/AndroidPhoneNotify.py index 8332f668d..3fb291e11 100644 --- a/pyload/plugin/addon/AndroidPhoneNotify.py +++ b/pyload/plugin/addon/AndroidPhoneNotify.py @@ -75,6 +75,8 @@ class AndroidPhoneNotify(Addon):      @Expose + +      def notify(self,                 event,                 msg="", diff --git a/pyload/plugin/addon/AntiVirus.py b/pyload/plugin/addon/AntiVirus.py index 3866014ee..c6628a684 100644 --- a/pyload/plugin/addon/AntiVirus.py +++ b/pyload/plugin/addon/AntiVirus.py @@ -43,6 +43,8 @@ class AntiVirus(Addon):      @Expose      @threaded + +      def scan(self, pyfile, thread):          file     = fs_encode(pyfile.plugin.lastDownload)          filename = os.path.basename(pyfile.plugin.lastDownload) diff --git a/pyload/plugin/addon/ClickNLoad.py b/pyload/plugin/addon/ClickNLoad.py index b6448598a..6a3d5d662 100644 --- a/pyload/plugin/addon/ClickNLoad.py +++ b/pyload/plugin/addon/ClickNLoad.py @@ -48,6 +48,8 @@ class ClickNLoad(Addon):      @threaded + +      def proxy(self, ip, webport, cnlport):          time.sleep(10)  #@TODO: Remove in 0.4.10 (implement addon delay on startup) @@ -61,6 +63,8 @@ class ClickNLoad(Addon):      @threaded + +      def _server(self, ip, webport, cnlport):          try:              dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) diff --git a/pyload/plugin/addon/DeleteFinished.py b/pyload/plugin/addon/DeleteFinished.py index f8f42da1e..c0a2e8752 100644 --- a/pyload/plugin/addon/DeleteFinished.py +++ b/pyload/plugin/addon/DeleteFinished.py @@ -23,6 +23,8 @@ class DeleteFinished(Addon):      ## overwritten methods ## + +      def setup(self):          self.interval = self.MIN_CHECK_INTERVAL @@ -59,6 +61,8 @@ class DeleteFinished(Addon):      ## own methods ##      @style.queue + +      def deleteFinished(self, mode):          self.c.execute('DELETE FROM packages WHERE NOT EXISTS(SELECT 1 FROM links WHERE package=packages.id AND status NOT IN (%s))' % mode)          self.c.execute('DELETE FROM links WHERE NOT EXISTS(SELECT 1 FROM packages WHERE id=links.package)') @@ -70,6 +74,8 @@ class DeleteFinished(Addon):      ## event managing ## + +      def addEvent(self, event, func):          """Adds an event listener for event name"""          if event in self.manager.events: diff --git a/pyload/plugin/addon/ExtractArchive.py b/pyload/plugin/addon/ExtractArchive.py index d94c0ca18..a52b55f0a 100644 --- a/pyload/plugin/addon/ExtractArchive.py +++ b/pyload/plugin/addon/ExtractArchive.py @@ -14,6 +14,7 @@ if sys.version_info < (2, 7) and os.name != "nt":      import errno      import subprocess +      def _eintr_retry_call(func, *args):          while True:              try: @@ -26,6 +27,8 @@ if sys.version_info < (2, 7) and os.name != "nt":      # unsued timeout option for older python version + +      def wait(self, timeout=0):          """Wait for child process to terminate.  Returns returncode          attribute.""" @@ -190,6 +193,8 @@ class ExtractArchive(Addon):      @threaded + +      def extractQueued(self, thread):          packages = self.queue.get()          while packages: @@ -206,6 +211,8 @@ class ExtractArchive(Addon):      @Expose + +      def extractPackage(self, *ids):          """ Extract packages with given id"""          for id in ids: @@ -231,6 +238,8 @@ class ExtractArchive(Addon):      @Expose + +      def extract(self, ids, thread=None):  #@TODO: Use pypack, not pid to improve method usability          if not ids:              return False @@ -503,6 +512,8 @@ class ExtractArchive(Addon):      @Expose + +      def getPasswords(self, reload=True):          """ List of saved passwords """          if reload: @@ -528,6 +539,8 @@ class ExtractArchive(Addon):      @Expose + +      def addPassword(self, password):          """  Adds a password to saved list"""          try: diff --git a/pyload/plugin/addon/IRCInterface.py b/pyload/plugin/addon/IRCInterface.py index 1246c91fa..73998b674 100644 --- a/pyload/plugin/addon/IRCInterface.py +++ b/pyload/plugin/addon/IRCInterface.py @@ -199,6 +199,7 @@ class IRCInterface(Thread, Addon):          #### Events +      def event_pass(self, args):          return [] diff --git a/pyload/plugin/addon/MergeFiles.py b/pyload/plugin/addon/MergeFiles.py index dfc5f41d4..e7da4a82a 100644 --- a/pyload/plugin/addon/MergeFiles.py +++ b/pyload/plugin/addon/MergeFiles.py @@ -26,6 +26,8 @@ class MergeFiles(Addon):      @threaded + +      def packageFinished(self, pack):          files = {}          fid_dict = {} diff --git a/pyload/plugin/addon/MultiHome.py b/pyload/plugin/addon/MultiHome.py index 458ddbeca..057764a1e 100644 --- a/pyload/plugin/addon/MultiHome.py +++ b/pyload/plugin/addon/MultiHome.py @@ -43,6 +43,7 @@ class MultiHome(Addon):          requestFactory = self.core.requestFactory          oldGetRequest = requestFactory.getRequest +          def getRequest(pluginName, account=None):              iface = self.bestInterface(pluginName, account)              if iface: diff --git a/pyload/plugin/addon/SkipRev.py b/pyload/plugin/addon/SkipRev.py index 5209da615..e55d98056 100644 --- a/pyload/plugin/addon/SkipRev.py +++ b/pyload/plugin/addon/SkipRev.py @@ -25,6 +25,8 @@ class SkipRev(Addon):      @staticmethod + +      def _setup(self):          self.pyfile.plugin._setup()          if self.pyfile.hasStatus("skipped"): diff --git a/pyload/plugin/addon/UpdateManager.py b/pyload/plugin/addon/UpdateManager.py index 023884029..c7c7ec047 100644 --- a/pyload/plugin/addon/UpdateManager.py +++ b/pyload/plugin/addon/UpdateManager.py @@ -50,12 +50,14 @@ class UpdateManager(Addon):      SERVER_URL         = "http://updatemanager.pyload.org" if release_status == 5 else None      MIN_CHECK_INTERVAL = 3 * 60 * 60  #: 3 hours +      def activate(self):          if self.checkonstart:              self.update()          self.initPeriodical() +      def setup(self):          self.interval = 10          self.info     = {'pyload': False, 'version': None, 'plugins': False, 'last_check': time.time()} @@ -67,6 +69,7 @@ class UpdateManager(Addon):          else:              self.checkonstart = False +      def periodical(self):          if self.core.debug:              if self.getConfig('reloadplugins'): @@ -80,6 +83,8 @@ class UpdateManager(Addon):              self.update()      @Expose + +      def autoreloadPlugins(self):          """ reload and reindex all modified plugins """          modules = filter( @@ -108,6 +113,7 @@ class UpdateManager(Addon):          return True if self.core.pluginManager.reloadPlugins(reloads) else False +      def server_response(self):          try:              return getURL(self.SERVER_URL, get={'v': self.core.api.getServerVersion()}).splitlines() @@ -117,6 +123,8 @@ class UpdateManager(Addon):      @Expose      @threaded + +      def update(self):          """ check for updates """ @@ -127,6 +135,7 @@ class UpdateManager(Addon):          else:              self.core.api.unpauseServer() +      def _update(self):          data = self.server_response() @@ -156,6 +165,7 @@ class UpdateManager(Addon):          #  2 = Plugins updated, but restart required          return exitcode +      def _updatePlugins(self, data):          """ check for plugin updates """ @@ -266,6 +276,8 @@ class UpdateManager(Addon):          return exitcode      @Expose + +      def removePlugins(self, type_plugins):          """ delete plugins from disk """ diff --git a/pyload/plugin/addon/WindowsPhoneNotify.py b/pyload/plugin/addon/WindowsPhoneNotify.py index b1d1c8b0f..f7a5e6ec1 100644 --- a/pyload/plugin/addon/WindowsPhoneNotify.py +++ b/pyload/plugin/addon/WindowsPhoneNotify.py @@ -82,6 +82,8 @@ class WindowsPhoneNotify(Addon):      @Expose + +      def notify(self,                 event,                 msg="", diff --git a/pyload/plugin/captcha/AdYouLike.py b/pyload/plugin/captcha/AdYouLike.py index 83fc4e1a3..a29524bcc 100644 --- a/pyload/plugin/captcha/AdYouLike.py +++ b/pyload/plugin/captcha/AdYouLike.py @@ -18,6 +18,7 @@ class AdYouLike(Captcha):      AYL_PATTERN      = r'Adyoulike\.create\s*\((.+?)\)'      CALLBACK_PATTERN = r'(Adyoulike\.g\._jsonp_\d+)' +      def detect_key(self, html=None):          if not html:              if hasattr(self.plugin, "html") and self.plugin.html: @@ -37,6 +38,7 @@ class AdYouLike(Captcha):              self.logDebug("Ayl or callback not found")              return None +      def challenge(self, key=None, html=None):          if not key:              if self.detect_key(html): @@ -68,6 +70,7 @@ class AdYouLike(Captcha):          return self.result(ayl, challenge), challenge +      def result(self, server, challenge):          # Adyoulike.g._jsonp_5579316662423138          # ({"translations":{"fr":{"instructions_visual":"Recopiez « Soonnight » ci-dessous :"}}, diff --git a/pyload/plugin/captcha/ReCaptcha.py b/pyload/plugin/captcha/ReCaptcha.py index 004a86bf9..9c75c2212 100644 --- a/pyload/plugin/captcha/ReCaptcha.py +++ b/pyload/plugin/captcha/ReCaptcha.py @@ -24,6 +24,7 @@ class ReCaptcha(Captcha):      KEY_V2_PATTERN = r'(?:data-sitekey=["\']|["\']sitekey["\']:\s*["\'])([\w-]+)'      KEY_V1_PATTERN = r'(?:recaptcha(?:/api|\.net)/(?:challenge|noscript)\?k=|Recaptcha\.create\s*\(\s*["\'])([\w-]+)' +      def detect_key(self, html=None):          if not html:              if hasattr(self.plugin, "html") and self.plugin.html: @@ -42,6 +43,7 @@ class ReCaptcha(Captcha):              self.logDebug("Key not found")              return None +      def challenge(self, key=None, html=None, version=None):          if not key:              if self.detect_key(html): @@ -63,6 +65,7 @@ class ReCaptcha(Captcha):              self.plugin.fail(errmsg)              raise TypeError(errmsg) +      def _challenge_v1(self, key):          html = self.plugin.req.load("http://www.google.com/recaptcha/api/challenge",                                      get={'k': key}) @@ -79,6 +82,7 @@ class ReCaptcha(Captcha):          return self.result(server, challenge), challenge +      def result(self, server, challenge):          result = self.plugin.decryptCaptcha("%simage" % server,                                              get={'c': challenge}, @@ -90,6 +94,7 @@ class ReCaptcha(Captcha):          return result +      def _collectApiInfo(self):          html = self.plugin.req.load("http://www.google.com/recaptcha/api.js")          a    = re.search(r'po.src = \'(.*?)\';', html).group(1) @@ -109,6 +114,7 @@ class ReCaptcha(Captcha):          return vers, language, jsh +      def _prepareTimeAndRpc(self):          self.plugin.req.load("http://www.google.com/recaptcha/api2/demo") @@ -124,6 +130,7 @@ class ReCaptcha(Captcha):          return millis, rpc +      def _challenge_v2(self, key, parent=None):          if parent is None:              try: diff --git a/pyload/plugin/extractor/SevenZip.py b/pyload/plugin/extractor/SevenZip.py index 71b288ab0..7cf6aee35 100644 --- a/pyload/plugin/extractor/SevenZip.py +++ b/pyload/plugin/extractor/SevenZip.py @@ -38,6 +38,8 @@ class SevenZip(UnRar):      @classmethod + +      def isUsable(cls):          if os.name == "nt":              cls.CMD = os.path.join(pypath, "7z.exe") @@ -68,7 +70,6 @@ class SevenZip(UnRar):              raise CRCError(err) -      def check(self, password):          p = self.call_cmd("l", "-slt", fs_encode(self.filename))          out, err = p.communicate() diff --git a/pyload/plugin/extractor/UnRar.py b/pyload/plugin/extractor/UnRar.py index cad58ff4f..32d33bc51 100644 --- a/pyload/plugin/extractor/UnRar.py +++ b/pyload/plugin/extractor/UnRar.py @@ -49,6 +49,8 @@ class UnRar(Extractor):      @classmethod + +      def isUsable(cls):          if os.name == "nt":              try: @@ -80,6 +82,8 @@ class UnRar(Extractor):      @classmethod + +      def isMultipart(cls, filename):          return True if cls.re_multipart.search(filename) else False diff --git a/pyload/plugin/extractor/UnZip.py b/pyload/plugin/extractor/UnZip.py index b4fa637f0..5e93064c2 100644 --- a/pyload/plugin/extractor/UnZip.py +++ b/pyload/plugin/extractor/UnZip.py @@ -25,6 +25,8 @@ class UnZip(Extractor):      @classmethod + +      def isUsable(cls):          return sys.version_info[:2] >= (2, 6) diff --git a/pyload/plugin/hook/BypassCaptcha.py b/pyload/plugin/hook/BypassCaptcha.py index 141ac7282..01359f3d3 100644 --- a/pyload/plugin/hook/BypassCaptcha.py +++ b/pyload/plugin/hook/BypassCaptcha.py @@ -123,6 +123,8 @@ class BypassCaptcha(Hook):      @threaded + +      def _processCaptcha(self, task):          c = task.captchaFile          try: diff --git a/pyload/plugin/hook/Captcha9Kw.py b/pyload/plugin/hook/Captcha9Kw.py index 9cb8e7928..b388de444 100644 --- a/pyload/plugin/hook/Captcha9Kw.py +++ b/pyload/plugin/hook/Captcha9Kw.py @@ -61,6 +61,8 @@ class Captcha9kw(Hook):      @threaded + +      def _processCaptcha(self, task):          try:              with open(task.captchaFile, 'rb') as f: diff --git a/pyload/plugin/hook/CaptchaBrotherhood.py b/pyload/plugin/hook/CaptchaBrotherhood.py index eff005d14..a4a461517 100644 --- a/pyload/plugin/hook/CaptchaBrotherhood.py +++ b/pyload/plugin/hook/CaptchaBrotherhood.py @@ -160,6 +160,8 @@ class CaptchaBrotherhood(Hook):      @threaded + +      def _processCaptcha(self, task):          c = task.captchaFile          try: diff --git a/pyload/plugin/hook/DeathByCaptcha.py b/pyload/plugin/hook/DeathByCaptcha.py index 4b77c8718..3688a68d0 100644 --- a/pyload/plugin/hook/DeathByCaptcha.py +++ b/pyload/plugin/hook/DeathByCaptcha.py @@ -206,6 +206,8 @@ class DeathByCaptcha(Hook):      @threaded + +      def _processCaptcha(self, task):          c = task.captchaFile          try: diff --git a/pyload/plugin/hook/ExpertDecoders.py b/pyload/plugin/hook/ExpertDecoders.py index 2e2982d2d..b34309d25 100644 --- a/pyload/plugin/hook/ExpertDecoders.py +++ b/pyload/plugin/hook/ExpertDecoders.py @@ -46,6 +46,8 @@ class ExpertDecoders(Hook):      @threaded + +      def _processCaptcha(self, task):          task.data['ticket'] = ticket = uuid4()          result = None diff --git a/pyload/plugin/hook/ImageTyperz.py b/pyload/plugin/hook/ImageTyperz.py index ca5e02559..717077790 100644 --- a/pyload/plugin/hook/ImageTyperz.py +++ b/pyload/plugin/hook/ImageTyperz.py @@ -141,6 +141,8 @@ class ImageTyperz(Hook):      @threaded + +      def _processCaptcha(self, task):          c = task.captchaFile          try: diff --git a/pyload/plugin/hoster/FilerNet.py b/pyload/plugin/hoster/FilerNet.py index 7cefa6d9f..f9b38e8cb 100644 --- a/pyload/plugin/hoster/FilerNet.py +++ b/pyload/plugin/hoster/FilerNet.py @@ -33,6 +33,7 @@ class FilerNet(SimpleHoster):      LINK_FREE_PATTERN = LINK_PREMIUM_PATTERN = r'href="([^"]+)">Get download</a>' +      def handleFree(self, pyfile):          inputs = self.parseHtmlForm(input_names={'token': re.compile(r'.+')})[1]          if 'token' not in inputs: diff --git a/pyload/plugin/hoster/GigapetaCom.py b/pyload/plugin/hoster/GigapetaCom.py index 803f37897..adbdc2396 100644 --- a/pyload/plugin/hoster/GigapetaCom.py +++ b/pyload/plugin/hoster/GigapetaCom.py @@ -51,7 +51,6 @@ class GigapetaCom(SimpleHoster):              self.fail(_("No valid captcha code entered")) -      def checkErrors(self):          if "All threads for IP" in self.html:              self.logDebug("Your IP is already downloading a file") diff --git a/pyload/plugin/hoster/Keep2ShareCc.py b/pyload/plugin/hoster/Keep2ShareCc.py index 4285bedb9..59e5f5c79 100644 --- a/pyload/plugin/hoster/Keep2ShareCc.py +++ b/pyload/plugin/hoster/Keep2ShareCc.py @@ -86,6 +86,8 @@ class Keep2ShareCc(SimpleHoster):                  self.error(_("Free download link not found"))          self.link = m.group(1) + +      def handleCaptcha(self):          post_data = {'free'               : 1,                       'freeDownloadRequest': 1, diff --git a/pyload/plugin/hoster/KingfilesNet.py b/pyload/plugin/hoster/KingfilesNet.py index af1d49390..5f4207d11 100644 --- a/pyload/plugin/hoster/KingfilesNet.py +++ b/pyload/plugin/hoster/KingfilesNet.py @@ -28,10 +28,12 @@ class KingfilesNet(SimpleHoster):      LINK_FREE_PATTERN = r'var download_url = \'(.+)\';' +      def setup(self):          self.resumeDownload = True          self.multiDL        = True +      def handleFree(self, pyfile):          # Click the free user button          post_data = {'op'         : "download1", diff --git a/pyload/plugin/hoster/LinksnappyCom.py b/pyload/plugin/hoster/LinksnappyCom.py index 2cb14dd51..3f2cf9821 100644 --- a/pyload/plugin/hoster/LinksnappyCom.py +++ b/pyload/plugin/hoster/LinksnappyCom.py @@ -51,6 +51,8 @@ class LinksnappyCom(MultiHoster):      @staticmethod + +      def _get_host(url):          host = urlsplit(url).netloc          return re.search(r'[\w-]+\.\w+$', host).group(0) diff --git a/pyload/plugin/hoster/LuckyShareNet.py b/pyload/plugin/hoster/LuckyShareNet.py index e124c5b94..6dff7d517 100644 --- a/pyload/plugin/hoster/LuckyShareNet.py +++ b/pyload/plugin/hoster/LuckyShareNet.py @@ -42,6 +42,8 @@ class LuckyShareNet(SimpleHoster):      # TODO: There should be a filesize limit for free downloads      # TODO: Some files could not be downloaded in free mode + +      def handleFree(self, pyfile):          rep = self.load(r"http://luckyshare.net/download/request/type/time/file/" + self.info['pattern']['ID'], decode=True) diff --git a/pyload/plugin/hoster/MyfastfileCom.py b/pyload/plugin/hoster/MyfastfileCom.py index c6bf4c227..57041d6cd 100644 --- a/pyload/plugin/hoster/MyfastfileCom.py +++ b/pyload/plugin/hoster/MyfastfileCom.py @@ -19,7 +19,6 @@ class MyfastfileCom(MultiHoster):      __authors     = [("stickell", "l.stickell@yahoo.it")] -      def setup(self):          self.chunkLimit = -1 diff --git a/pyload/plugin/hoster/PornhostCom.py b/pyload/plugin/hoster/PornhostCom.py index 819612fcf..f6a63117c 100644 --- a/pyload/plugin/hoster/PornhostCom.py +++ b/pyload/plugin/hoster/PornhostCom.py @@ -27,6 +27,8 @@ class PornhostCom(Hoster):      # Old interface + +      def download_html(self):          url = self.pyfile.url          self.html = self.load(url) diff --git a/pyload/plugin/hoster/ShareonlineBiz.py b/pyload/plugin/hoster/ShareonlineBiz.py index dcdeca168..608ee73b3 100644 --- a/pyload/plugin/hoster/ShareonlineBiz.py +++ b/pyload/plugin/hoster/ShareonlineBiz.py @@ -37,6 +37,8 @@ class ShareonlineBiz(SimpleHoster):      @classmethod + +      def getInfo(cls, url="", html=""):          info = {'name': urlparse(unquote(url)).path.split('/')[-1] or _("Unknown"), 'size': 0, 'status': 3 if url else 1, 'url': url} diff --git a/pyload/plugin/hoster/UploadedTo.py b/pyload/plugin/hoster/UploadedTo.py index 7031d0ab2..7660ec3ad 100644 --- a/pyload/plugin/hoster/UploadedTo.py +++ b/pyload/plugin/hoster/UploadedTo.py @@ -32,6 +32,8 @@ class UploadedTo(SimpleHoster):      @classmethod + +      def apiInfo(cls, url="", get={}, post={}):          info = super(UploadedTo, cls).apiInfo(url) diff --git a/pyload/plugin/hoster/WebshareCz.py b/pyload/plugin/hoster/WebshareCz.py index 11b7b37b0..673dfaac5 100644 --- a/pyload/plugin/hoster/WebshareCz.py +++ b/pyload/plugin/hoster/WebshareCz.py @@ -21,6 +21,8 @@ class WebshareCz(SimpleHoster):      @classmethod + +      def getInfo(cls, url="", html=""):          info = super(WebshareCz, cls).getInfo(url, html) diff --git a/pyload/plugin/hoster/ZDF.py b/pyload/plugin/hoster/ZDF.py index c02eadc23..6f17df61a 100644 --- a/pyload/plugin/hoster/ZDF.py +++ b/pyload/plugin/hoster/ZDF.py @@ -23,6 +23,8 @@ class ZDF(Hoster):      @staticmethod + +      def video_key(video):          return (              int(video.findtext("videoBitrate", "0")), @@ -31,12 +33,16 @@ class ZDF(Hoster):      @staticmethod + +      def video_valid(video):          return video.findtext("url").startswith("http") and video.findtext("url").endswith(".mp4") and \                 video.findtext("facets/facet").startswith("progressive")      @staticmethod + +      def get_id(url):          return int(re.search(r"\D*(\d{4,})\D*", url).group(1)) diff --git a/pyload/plugin/hoster/ZippyshareCom.py b/pyload/plugin/hoster/ZippyshareCom.py index 5bd25d8c1..91a636f0a 100644 --- a/pyload/plugin/hoster/ZippyshareCom.py +++ b/pyload/plugin/hoster/ZippyshareCom.py @@ -65,6 +65,7 @@ class ZippyshareCom(SimpleHoster):          # meant to be populated with the initialization of all the DOM elements found in the scripts          initScripts = set() +          def replElementById(element):              id   = element.group(1) # id might be either 'x' (a real id) or x (a variable)              attr = element.group(4)  # attr might be None diff --git a/pyload/plugin/internal/BasePlugin.py b/pyload/plugin/internal/BasePlugin.py index 996dc8e76..1ddfee122 100644 --- a/pyload/plugin/internal/BasePlugin.py +++ b/pyload/plugin/internal/BasePlugin.py @@ -24,6 +24,8 @@ class BasePlugin(Hoster):      @classmethod + +      def getInfo(cls, url="", html=""):  #@TODO: Move to hoster class in 0.4.10          url   = unquote(url)          url_p = urlparse(url) diff --git a/pyload/plugin/internal/DeadCrypter.py b/pyload/plugin/internal/DeadCrypter.py index daa7e1a0d..c66a1b5e3 100644 --- a/pyload/plugin/internal/DeadCrypter.py +++ b/pyload/plugin/internal/DeadCrypter.py @@ -16,6 +16,8 @@ class DeadCrypter(_Crypter):      @classmethod + +      def apiInfo(cls, url="", get={}, post={}):          api = super(DeadCrypter, self).apiInfo(url, get, post)          api['status'] = 1 diff --git a/pyload/plugin/internal/DeadHoster.py b/pyload/plugin/internal/DeadHoster.py index 2e57decdb..5f00d0128 100644 --- a/pyload/plugin/internal/DeadHoster.py +++ b/pyload/plugin/internal/DeadHoster.py @@ -16,6 +16,8 @@ class DeadHoster(_Hoster):      @classmethod + +      def apiInfo(cls, url="", get={}, post={}):          api = super(DeadHoster, self).apiInfo(url, get, post)          api['status'] = 1 diff --git a/pyload/plugin/internal/SimpleCrypter.py b/pyload/plugin/internal/SimpleCrypter.py index ba5cb991c..f6c5aa5e2 100644 --- a/pyload/plugin/internal/SimpleCrypter.py +++ b/pyload/plugin/internal/SimpleCrypter.py @@ -49,7 +49,6 @@ class SimpleCrypter(Crypter, SimpleHoster):      and its loadPage method: -        def loadPage(self, page_n):            return the html of the page number page_n      """ diff --git a/pyload/plugin/internal/SimpleHoster.py b/pyload/plugin/internal/SimpleHoster.py index 79b3cac1a..b32cb60c0 100644 --- a/pyload/plugin/internal/SimpleHoster.py +++ b/pyload/plugin/internal/SimpleHoster.py @@ -311,12 +311,16 @@ class SimpleHoster(Hoster):      @classmethod + +      def parseInfos(cls, urls):  #@TODO: Built-in in 0.4.10 core (remove from plugins)          for url in urls:              url = replace_patterns(url, cls.URL_REPLACEMENTS)              yield cls.getInfo(url)      @classmethod + +      def apiInfo(cls, url="", get={}, post={}):          url   = urllib.unquote(url)          url_p = urlparse.urlparse(url) @@ -328,6 +332,8 @@ class SimpleHoster(Hoster):                  'url': url}      @classmethod + +      def getInfo(cls, url="", html=""):          info   = cls.apiInfo(url)          online = False if info['status'] != 2 else True @@ -406,9 +412,11 @@ class SimpleHoster(Hoster):          return info +      def setup(self):          self.resumeDownload = self.multiDL = self.premium +      def prepare(self):          self.pyfile.error = ""  #@TODO: Remove in 0.4.10 @@ -442,12 +450,14 @@ class SimpleHoster(Hoster):          self.pyfile.url = replace_patterns(self.pyfile.url, self.URL_REPLACEMENTS) +      def preload(self):          self.html = self.load(self.pyfile.url, cookies=bool(self.COOKIES), decode=not self.TEXT_ENCODING)          if isinstance(self.TEXT_ENCODING, basestring):              self.html = unicode(self.html, self.TEXT_ENCODING) +      def process(self, pyfile):          try:              self.prepare() @@ -487,6 +497,7 @@ class SimpleHoster(Hoster):              else:                  raise Fail(e) +      def downloadLink(self, link, disposition=True):          if link and isinstance(link, basestring):              self.correctCaptcha() @@ -498,6 +509,7 @@ class SimpleHoster(Hoster):              self.download(link, ref=False, disposition=disposition) +      def checkFile(self, rules={}):          if self.cTask and not self.lastDownload:              self.invalidCaptcha() @@ -538,6 +550,7 @@ class SimpleHoster(Hoster):              self.logWarning("Check result: " + errmsg, "Waiting 1 minute and retry")              self.retry(3, 60, errmsg) +      def checkErrors(self):          if not self.html:              self.logWarning(_("No html code to check")) @@ -582,6 +595,7 @@ class SimpleHoster(Hoster):          self.info.pop('error', None) +      def checkStatus(self, getinfo=True):          if not self.info or getinfo:              self.logDebug("Update file info...") @@ -604,6 +618,7 @@ class SimpleHoster(Hoster):          finally:              self.logDebug("File status: %s" % statusMap[status]) +      def checkNameSize(self, getinfo=True):          if not self.info or getinfo:              self.logDebug("Update file info...") @@ -631,6 +646,7 @@ class SimpleHoster(Hoster):          self.logDebug("File name: %s" % self.pyfile.name,                        "File size: %s byte" % self.pyfile.size if self.pyfile.size > 0 else "File size: Unknown") +      def checkInfo(self):          self.checkNameSize() @@ -641,11 +657,14 @@ class SimpleHoster(Hoster):          self.checkStatus(getinfo=False)      #: Deprecated + +      def getFileInfo(self):          self.info = {}          self.checkInfo()          return self.info +      def handleDirect(self, pyfile):          link = self.directLink(pyfile.url, self.resumeDownload) @@ -655,9 +674,11 @@ class SimpleHoster(Hoster):          else:              self.logDebug("Direct download link not found") +      def handleMulti(self, pyfile):  #: Multi-hoster handler          pass +      def handleFree(self, pyfile):          if not hasattr(self, 'LINK_FREE_PATTERN'):              self.logError(_("Free download not implemented")) @@ -668,6 +689,7 @@ class SimpleHoster(Hoster):          else:              self.link = m.group(1) +      def handlePremium(self, pyfile):          if not hasattr(self, 'LINK_PREMIUM_PATTERN'):              self.logError(_("Premium download not implemented")) @@ -680,6 +702,7 @@ class SimpleHoster(Hoster):          else:              self.link = m.group(1) +      def longWait(self, wait_time=None, max_tries=3):          if wait_time and isinstance(wait_time, (int, long, float)):              time_str  = "%dh %dm" % divmod(wait_time / 60, 60) @@ -693,9 +716,11 @@ class SimpleHoster(Hoster):          self.wait(wait_time, True)          self.retry(max_tries=max_tries, reason=_("Download limit reached")) +      def parseHtmlForm(self, attr_str="", input_names={}):          return parseHtmlForm(attr_str, self.html, input_names) +      def checkTrafficLeft(self):          if not self.account:              return True @@ -711,6 +736,7 @@ class SimpleHoster(Hoster):              self.logInfo(_("Filesize: %i KiB, Traffic left for user %s: %i KiB") % (size, self.user, traffic))              return size <= traffic +      def getConfig(self, option, default=''):  #@TODO: Remove in 0.4.10          """getConfig with default value - sublass may not implements all config options"""          try: @@ -719,6 +745,7 @@ class SimpleHoster(Hoster):          except KeyError:              return default +      def retryFree(self):          if not self.premium:              return @@ -729,8 +756,11 @@ class SimpleHoster(Hoster):          raise Retry(_("Fallback to free download"))      #@TODO: Remove in 0.4.10 + +      def wait(self, seconds=0, reconnect=None):          return _wait(self, seconds, reconnect) +      def error(self, reason="", type="parse"):          return _error(self, reason, type) diff --git a/pyload/plugin/internal/XFSHoster.py b/pyload/plugin/internal/XFSHoster.py index d2d5fb0dd..4cef261df 100644 --- a/pyload/plugin/internal/XFSHoster.py +++ b/pyload/plugin/internal/XFSHoster.py @@ -52,10 +52,12 @@ class XFSHoster(SimpleHoster):      FORM_PATTERN    = None      FORM_INPUTS_MAP = None  #: dict passed as input_names to parseHtmlForm +      def setup(self):          self.chunkLimit     = -1 if self.premium else 1          self.resumeDownload = self.multiDL = self.premium +      def prepare(self):          """ Initialize important variables """          if not self.HOSTER_DOMAIN: @@ -84,6 +86,7 @@ class XFSHoster(SimpleHoster):          if self.DIRECT_LINK is None:              self.directDL = self.premium +      def handleFree(self, pyfile):          for i in xrange(1, 6):              self.logDebug("Getting download link: #%d" % i) @@ -111,9 +114,11 @@ class XFSHoster(SimpleHoster):          self.link = m.group(1).strip()  #@TODO: Remove .strip() in 0.4.10 +      def handlePremium(self, pyfile):          return self.handleFree(pyfile) +      def handleMulti(self, pyfile):          if not self.account:              self.fail(_("Only registered or premium users can use url leech feature")) @@ -171,6 +176,7 @@ class XFSHoster(SimpleHoster):          if 'location' in header:  #: Direct download link              self.link = header['location'] +      def checkErrors(self):          m = re.search(self.ERROR_PATTERN, self.html)          if m is None: @@ -223,6 +229,7 @@ class XFSHoster(SimpleHoster):          else:              self.info.pop('error', None) +      def getPostParameters(self):          if self.FORM_PATTERN or self.FORM_INPUTS_MAP:              action, inputs = self.parseHtmlForm(self.FORM_PATTERN or "", self.FORM_INPUTS_MAP or {}) @@ -268,6 +275,7 @@ class XFSHoster(SimpleHoster):          return inputs +      def handleCaptcha(self, inputs):          m = re.search(self.CAPTCHA_PATTERN, self.html)          if m: diff --git a/pyload/remote/ClickNLoadBackend.py b/pyload/remote/ClickNLoadBackend.py index fbacb3244..31678ab8b 100644 --- a/pyload/remote/ClickNLoadBackend.py +++ b/pyload/remote/ClickNLoadBackend.py @@ -19,12 +19,14 @@ core = None  js = None  class ClickNLoadBackend(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() @@ -36,12 +38,14 @@ class CNLHandler(BaseHTTPRequestHandler):          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) @@ -53,6 +57,7 @@ class CNLHandler(BaseHTTPRequestHandler):          self.send_header("Content-type", "text/html")          self.end_headers() +      def do_GET(self):          path = self.path.strip("/").lower()          #self.wfile.write(path+"\n") @@ -84,6 +89,7 @@ class CNLHandler(BaseHTTPRequestHandler):          else:              self.send_error(404, "Not Found") +      def do_POST(self):          form = FieldStorage(                  fp=self.rfile, @@ -98,21 +104,25 @@ class CNLHandler(BaseHTTPRequestHandler):          return self.do_GET() +      def flash(self):          return "JDownloader" +      def add(self):          package = self.get_post('referer', 'ClickNLoad 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', 'ClickNLoad Package')          dlc = self.get_post('crypted').replace(" ", "+")          core.upload_container(package, dlc) +      def addcrypted2(self):          package = self.get_post("source", "ClickNLoad Package")          crypted = self.get_post("crypted") @@ -139,6 +149,7 @@ class CNLHandler(BaseHTTPRequestHandler):          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" @@ -147,9 +158,11 @@ class CNLHandler(BaseHTTPRequestHandler):          rep += "</cross-domain-policy>"          return rep +      def checksupport(self):          pass +      def jdcheck(self):          rep = "jdownloader=true;\n"          rep += "var version='10629';\n" diff --git a/pyload/remote/SocketBackend.py b/pyload/remote/SocketBackend.py index a1c885347..6b88663f8 100644 --- a/pyload/remote/SocketBackend.py +++ b/pyload/remote/SocketBackend.py @@ -9,6 +9,7 @@ class RequestHandler(SocketServer.BaseRequestHandler):      def setup(self):          pass +      def handle(self):          print self.request.recv(1024) @@ -21,5 +22,6 @@ class SocketBackend(BackendBase):          #local only          self.server = SocketServer.ThreadingTCPServer(("localhost", port), RequestHandler) +      def serve(self):          self.server.serve_forever() diff --git a/pyload/remote/ThriftBackend.py b/pyload/remote/ThriftBackend.py index 16917cfc9..83bb83811 100644 --- a/pyload/remote/ThriftBackend.py +++ b/pyload/remote/ThriftBackend.py @@ -14,6 +14,7 @@ from pyload.remote.thriftbackend.Transport import TransportFactory  from thrift.server import TServer  class ThriftBackend(BackendBase): +      def setup(self, host, port):          processor = Processor(self.core.api) @@ -38,5 +39,6 @@ class ThriftBackend(BackendBase):          #server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory) +      def serve(self):          self.server.serve() diff --git a/pyload/remote/thriftbackend/Processor.py b/pyload/remote/thriftbackend/Processor.py index 683697d1c..24a0c05b6 100644 --- a/pyload/remote/thriftbackend/Processor.py +++ b/pyload/remote/thriftbackend/Processor.py @@ -3,16 +3,19 @@  from pyload.remote.thriftbackend.thriftgen.pyload import Pyload  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 trans not in self.authenticated:              self.authenticated[trans] = False              oldclose = trans.close +              def wrap():                  if self in self.authenticated:                      del self.authenticated[trans] diff --git a/pyload/remote/thriftbackend/Protocol.py b/pyload/remote/thriftbackend/Protocol.py index 417b45834..c020e7a23 100644 --- a/pyload/remote/thriftbackend/Protocol.py +++ b/pyload/remote/thriftbackend/Protocol.py @@ -3,6 +3,7 @@  from thrift.protocol import TBinaryProtocol  class Protocol(TBinaryProtocol.TBinaryProtocol): +      def writeString(self, str):          try:              str = str.encode("utf8", "ignore") @@ -12,6 +13,7 @@ class Protocol(TBinaryProtocol.TBinaryProtocol):          self.writeI32(len(str))          self.trans.write(str) +      def readString(self):          len = self.readI32()          str = self.trans.readAll(len) diff --git a/pyload/remote/thriftbackend/Socket.py b/pyload/remote/thriftbackend/Socket.py index f6edc8408..7e1268c5c 100644 --- a/pyload/remote/thriftbackend/Socket.py +++ b/pyload/remote/thriftbackend/Socket.py @@ -11,22 +11,28 @@ from thrift.transport.TSocket import TSocket, TServerSocket, TTransportException  WantReadError = Exception #overwritten when ssl is used  class SecureSocketConnection(object): +      def __init__(self, connection):          self.__dict__["connection"] = connection +      def __getattr__(self, name):          return getattr(self.__dict__["connection"], name) +      def __setattr__(self, name, value):          setattr(self.__dict__["connection"], name, value) +      def shutdown(self, how=1):          self.__dict__["connection"].shutdown() +      def accept(self):          connection, address = self.__dict__["connection"].accept()          return SecureSocketConnection(connection), address +      def send(self, buff):          try:              return self.__dict__["connection"].send(buff) @@ -34,6 +40,7 @@ class SecureSocketConnection(object):              sleep(0.1)              return self.send(buff) +      def recv(self, buff):          try:              return self.__dict__["connection"].recv(buff) @@ -42,10 +49,12 @@ class SecureSocketConnection(object):              return self.recv(buff)  class Socket(TSocket): +      def __init__(self, host='localhost', port=7228, ssl=False):          TSocket.__init__(self, host, port)          self.ssl = ssl +      def open(self):          if self.ssl:              SSL = __import__("OpenSSL", globals(), locals(), "SSL", -1).SSL @@ -62,6 +71,7 @@ class Socket(TSocket):          self.handle.settimeout(self._timeout)          self.handle.connect((self.host, self.port)) +      def read(self, sz):          try:              buff = self.handle.recv(sz) @@ -93,6 +103,7 @@ class Socket(TSocket):  class ServerSocket(TServerSocket, Socket): +      def __init__(self, port=7228, host="0.0.0.0", key="", cert=""):          self.host = host          self.port = port @@ -100,6 +111,7 @@ class ServerSocket(TServerSocket, Socket):          self.cert = cert          self.handle = None +      def listen(self):          if self.cert and self.key:              SSL = __import__("OpenSSL", globals(), locals(), "SSL", -1).SSL @@ -122,6 +134,7 @@ class ServerSocket(TServerSocket, Socket):          self.handle.bind((self.host, self.port))          self.handle.listen(128) +      def accept(self):          client, addr = self.handle.accept()          result = Socket() diff --git a/pyload/remote/thriftbackend/ThriftClient.py b/pyload/remote/thriftbackend/ThriftClient.py index 26658e341..c779c9b9c 100644 --- a/pyload/remote/thriftbackend/ThriftClient.py +++ b/pyload/remote/thriftbackend/ThriftClient.py @@ -36,6 +36,7 @@ class NoSSL(Exception):      pass  class ThriftClient(object): +      def __init__(self, host="localhost", port=7227, user="", password=""):          self.createConnection(host, port) @@ -76,6 +77,7 @@ class ThriftClient(object):              self.transport.close()              raise WrongLogin +      def createConnection(self, host, port, ssl=False):          self.socket = Socket(host, port, ssl)          self.transport = TTransport.TBufferedTransport(self.socket) @@ -84,8 +86,10 @@ class ThriftClient(object):          protocol = Protocol(self.transport)          self.client = Pyload.Client(protocol) +      def close(self):          self.transport.close() +      def __getattr__(self, item):          return getattr(self.client, item) diff --git a/pyload/remote/thriftbackend/Transport.py b/pyload/remote/thriftbackend/Transport.py index 7db4ba9d7..7ecb16746 100644 --- a/pyload/remote/thriftbackend/Transport.py +++ b/pyload/remote/thriftbackend/Transport.py @@ -6,6 +6,7 @@ from thrift.transport.TZlibTransport import TZlibTransport  class Transport(TBufferedTransport):      DEFAULT_BUFFER = 4096 +      def __init__(self, trans, rbuf_size = DEFAULT_BUFFER):          TBufferedTransport.__init__(self, trans, rbuf_size)          self.handle = trans.handle @@ -14,12 +15,14 @@ class Transport(TBufferedTransport):  class TransportCompressed(TZlibTransport):      DEFAULT_BUFFER = 4096 +      def __init__(self, trans, rbuf_size = DEFAULT_BUFFER):          TZlibTransport.__init__(self, trans, rbuf_size)          self.handle = trans.handle          self.remoteaddr = trans.handle.getpeername()  class TransportFactory(object): +      def getTransport(self, trans):          buffered = Transport(trans)          return buffered @@ -28,6 +31,7 @@ class TransportFactoryCompressed(object):      _last_trans = None      _last_z = None +      def getTransport(self, trans, compresslevel=9):          if trans == self._last_trans:            return self._last_z diff --git a/pyload/remote/thriftbackend/thriftgen/pyload/Pyload.py b/pyload/remote/thriftbackend/thriftgen/pyload/Pyload.py index e8d2cf9af..874b705ba 100644 --- a/pyload/remote/thriftbackend/thriftgen/pyload/Pyload.py +++ b/pyload/remote/thriftbackend/thriftgen/pyload/Pyload.py @@ -13,6 +13,7 @@ from thrift.protocol.TBase import TBase, TExceptionBase  class Iface(object): +    def getConfigValue(self, category, option, section):      """      Parameters: @@ -22,6 +23,7 @@ class Iface(object):      """      pass +    def setConfigValue(self, category, option, value, section):      """      Parameters: @@ -32,36 +34,47 @@ class Iface(object):      """      pass +    def getConfig(self,):      pass +    def getPluginConfig(self,):      pass +    def pauseServer(self,):      pass +    def unpauseServer(self,):      pass +    def togglePause(self,):      pass +    def statusServer(self,):      pass +    def freeSpace(self,):      pass +    def getServerVersion(self,):      pass +    def kill(self,):      pass +    def restart(self,):      pass +    def getLog(self, offset):      """      Parameters: @@ -69,15 +82,19 @@ class Iface(object):      """      pass +    def isTimeDownload(self,):      pass +    def isTimeReconnect(self,):      pass +    def toggleReconnect(self,):      pass +    def generatePackages(self, links):      """      Parameters: @@ -85,6 +102,7 @@ class Iface(object):      """      pass +    def checkURLs(self, urls):      """      Parameters: @@ -92,6 +110,7 @@ class Iface(object):      """      pass +    def parseURLs(self, html, url):      """      Parameters: @@ -100,6 +119,7 @@ class Iface(object):      """      pass +    def checkOnlineStatus(self, urls):      """      Parameters: @@ -107,6 +127,7 @@ class Iface(object):      """      pass +    def checkOnlineStatusContainer(self, urls, filename, data):      """      Parameters: @@ -116,6 +137,7 @@ class Iface(object):      """      pass +    def pollResults(self, rid):      """      Parameters: @@ -123,9 +145,11 @@ class Iface(object):      """      pass +    def statusDownloads(self,):      pass +    def getPackageData(self, pid):      """      Parameters: @@ -133,6 +157,7 @@ class Iface(object):      """      pass +    def getPackageInfo(self, pid):      """      Parameters: @@ -140,6 +165,7 @@ class Iface(object):      """      pass +    def getFileData(self, fid):      """      Parameters: @@ -147,18 +173,23 @@ class Iface(object):      """      pass +    def getQueue(self,):      pass +    def getCollector(self,):      pass +    def getQueueData(self,):      pass +    def getCollectorData(self,):      pass +    def getPackageOrder(self, destination):      """      Parameters: @@ -166,6 +197,7 @@ class Iface(object):      """      pass +    def getFileOrder(self, pid):      """      Parameters: @@ -173,6 +205,7 @@ class Iface(object):      """      pass +    def generateAndAddPackages(self, links, dest):      """      Parameters: @@ -181,6 +214,7 @@ class Iface(object):      """      pass +    def addPackage(self, name, links, dest):      """      Parameters: @@ -190,6 +224,7 @@ class Iface(object):      """      pass +    def addFiles(self, pid, links):      """      Parameters: @@ -198,6 +233,7 @@ class Iface(object):      """      pass +    def uploadContainer(self, filename, data):      """      Parameters: @@ -206,6 +242,7 @@ class Iface(object):      """      pass +    def deleteFiles(self, fids):      """      Parameters: @@ -213,6 +250,7 @@ class Iface(object):      """      pass +    def deletePackages(self, pids):      """      Parameters: @@ -220,6 +258,7 @@ class Iface(object):      """      pass +    def pushToQueue(self, pid):      """      Parameters: @@ -227,6 +266,7 @@ class Iface(object):      """      pass +    def pullFromQueue(self, pid):      """      Parameters: @@ -234,6 +274,7 @@ class Iface(object):      """      pass +    def restartPackage(self, pid):      """      Parameters: @@ -241,6 +282,7 @@ class Iface(object):      """      pass +    def restartFile(self, fid):      """      Parameters: @@ -248,6 +290,7 @@ class Iface(object):      """      pass +    def recheckPackage(self, pid):      """      Parameters: @@ -255,9 +298,11 @@ class Iface(object):      """      pass +    def stopAllDownloads(self,):      pass +    def stopDownloads(self, fids):      """      Parameters: @@ -265,6 +310,7 @@ class Iface(object):      """      pass +    def setPackageName(self, pid, name):      """      Parameters: @@ -273,6 +319,7 @@ class Iface(object):      """      pass +    def movePackage(self, destination, pid):      """      Parameters: @@ -281,6 +328,7 @@ class Iface(object):      """      pass +    def moveFiles(self, fids, pid):      """      Parameters: @@ -289,6 +337,7 @@ class Iface(object):      """      pass +    def orderPackage(self, pid, position):      """      Parameters: @@ -297,6 +346,7 @@ class Iface(object):      """      pass +    def orderFile(self, fid, position):      """      Parameters: @@ -305,6 +355,7 @@ class Iface(object):      """      pass +    def setPackageData(self, pid, data):      """      Parameters: @@ -313,12 +364,15 @@ class Iface(object):      """      pass +    def deleteFinished(self,):      pass +    def restartFailed(self,):      pass +    def getEvents(self, uuid):      """      Parameters: @@ -326,6 +380,7 @@ class Iface(object):      """      pass +    def getAccounts(self, refresh):      """      Parameters: @@ -333,9 +388,11 @@ class Iface(object):      """      pass +    def getAccountTypes(self,):      pass +    def updateAccount(self, plugin, account, password, options):      """      Parameters: @@ -346,6 +403,7 @@ class Iface(object):      """      pass +    def removeAccount(self, plugin, account):      """      Parameters: @@ -354,6 +412,7 @@ class Iface(object):      """      pass +    def login(self, username, password):      """      Parameters: @@ -362,6 +421,7 @@ class Iface(object):      """      pass +    def getUserData(self, username, password):      """      Parameters: @@ -370,12 +430,15 @@ class Iface(object):      """      pass +    def getAllUserData(self,):      pass +    def getServices(self,):      pass +    def hasService(self, plugin, func):      """      Parameters: @@ -384,6 +447,7 @@ class Iface(object):      """      pass +    def call(self, info):      """      Parameters: @@ -391,9 +455,11 @@ class Iface(object):      """      pass +    def getAllInfo(self,):      pass +    def getInfoByPlugin(self, plugin):      """      Parameters: @@ -401,9 +467,11 @@ class Iface(object):      """      pass +    def isCaptchaWaiting(self,):      pass +    def getCaptchaTask(self, exclusive):      """      Parameters: @@ -411,6 +479,7 @@ class Iface(object):      """      pass +    def getCaptchaTaskStatus(self, tid):      """      Parameters: @@ -418,6 +487,7 @@ class Iface(object):      """      pass +    def setCaptchaResult(self, tid, result):      """      Parameters: @@ -428,12 +498,14 @@ class Iface(object):  class Client(Iface): +    def __init__(self, iprot, oprot=None):      self._iprot = self._oprot = iprot      if oprot is not None:        self._oprot = oprot      self._seqid = 0 +    def getConfigValue(self, category, option, section):      """      Parameters: @@ -444,6 +516,7 @@ class Client(Iface):      self.send_getConfigValue(category, option, section)      return self.recv_getConfigValue() +    def send_getConfigValue(self, category, option, section):      self._oprot.writeMessageBegin('getConfigValue', TMessageType.CALL, self._seqid)      args = getConfigValue_args() @@ -454,6 +527,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getConfigValue(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -468,6 +542,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getConfigValue failed: unknown result"); +    def setConfigValue(self, category, option, value, section):      """      Parameters: @@ -479,6 +554,7 @@ class Client(Iface):      self.send_setConfigValue(category, option, value, section)      self.recv_setConfigValue() +    def send_setConfigValue(self, category, option, value, section):      self._oprot.writeMessageBegin('setConfigValue', TMessageType.CALL, self._seqid)      args = setConfigValue_args() @@ -490,6 +566,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_setConfigValue(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -502,10 +579,12 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def getConfig(self,):      self.send_getConfig()      return self.recv_getConfig() +    def send_getConfig(self,):      self._oprot.writeMessageBegin('getConfig', TMessageType.CALL, self._seqid)      args = getConfig_args() @@ -513,6 +592,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getConfig(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -527,10 +607,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getConfig failed: unknown result"); +    def getPluginConfig(self,):      self.send_getPluginConfig()      return self.recv_getPluginConfig() +    def send_getPluginConfig(self,):      self._oprot.writeMessageBegin('getPluginConfig', TMessageType.CALL, self._seqid)      args = getPluginConfig_args() @@ -538,6 +620,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getPluginConfig(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -552,10 +635,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getPluginConfig failed: unknown result"); +    def pauseServer(self,):      self.send_pauseServer()      self.recv_pauseServer() +    def send_pauseServer(self,):      self._oprot.writeMessageBegin('pauseServer', TMessageType.CALL, self._seqid)      args = pauseServer_args() @@ -563,6 +648,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_pauseServer(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -575,10 +661,12 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def unpauseServer(self,):      self.send_unpauseServer()      self.recv_unpauseServer() +    def send_unpauseServer(self,):      self._oprot.writeMessageBegin('unpauseServer', TMessageType.CALL, self._seqid)      args = unpauseServer_args() @@ -586,6 +674,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_unpauseServer(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -598,10 +687,12 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def togglePause(self,):      self.send_togglePause()      return self.recv_togglePause() +    def send_togglePause(self,):      self._oprot.writeMessageBegin('togglePause', TMessageType.CALL, self._seqid)      args = togglePause_args() @@ -609,6 +700,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_togglePause(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -623,10 +715,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "togglePause failed: unknown result"); +    def statusServer(self,):      self.send_statusServer()      return self.recv_statusServer() +    def send_statusServer(self,):      self._oprot.writeMessageBegin('statusServer', TMessageType.CALL, self._seqid)      args = statusServer_args() @@ -634,6 +728,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_statusServer(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -648,10 +743,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "statusServer failed: unknown result"); +    def freeSpace(self,):      self.send_freeSpace()      return self.recv_freeSpace() +    def send_freeSpace(self,):      self._oprot.writeMessageBegin('freeSpace', TMessageType.CALL, self._seqid)      args = freeSpace_args() @@ -659,6 +756,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_freeSpace(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -673,10 +771,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "freeSpace failed: unknown result"); +    def getServerVersion(self,):      self.send_getServerVersion()      return self.recv_getServerVersion() +    def send_getServerVersion(self,):      self._oprot.writeMessageBegin('getServerVersion', TMessageType.CALL, self._seqid)      args = getServerVersion_args() @@ -684,6 +784,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getServerVersion(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -698,10 +799,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getServerVersion failed: unknown result"); +    def kill(self,):      self.send_kill()      self.recv_kill() +    def send_kill(self,):      self._oprot.writeMessageBegin('kill', TMessageType.CALL, self._seqid)      args = kill_args() @@ -709,6 +812,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_kill(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -721,10 +825,12 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def restart(self,):      self.send_restart()      self.recv_restart() +    def send_restart(self,):      self._oprot.writeMessageBegin('restart', TMessageType.CALL, self._seqid)      args = restart_args() @@ -732,6 +838,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_restart(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -744,6 +851,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def getLog(self, offset):      """      Parameters: @@ -752,6 +860,7 @@ class Client(Iface):      self.send_getLog(offset)      return self.recv_getLog() +    def send_getLog(self, offset):      self._oprot.writeMessageBegin('getLog', TMessageType.CALL, self._seqid)      args = getLog_args() @@ -760,6 +869,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getLog(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -774,10 +884,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getLog failed: unknown result"); +    def isTimeDownload(self,):      self.send_isTimeDownload()      return self.recv_isTimeDownload() +    def send_isTimeDownload(self,):      self._oprot.writeMessageBegin('isTimeDownload', TMessageType.CALL, self._seqid)      args = isTimeDownload_args() @@ -785,6 +897,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_isTimeDownload(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -799,10 +912,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "isTimeDownload failed: unknown result"); +    def isTimeReconnect(self,):      self.send_isTimeReconnect()      return self.recv_isTimeReconnect() +    def send_isTimeReconnect(self,):      self._oprot.writeMessageBegin('isTimeReconnect', TMessageType.CALL, self._seqid)      args = isTimeReconnect_args() @@ -810,6 +925,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_isTimeReconnect(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -824,10 +940,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "isTimeReconnect failed: unknown result"); +    def toggleReconnect(self,):      self.send_toggleReconnect()      return self.recv_toggleReconnect() +    def send_toggleReconnect(self,):      self._oprot.writeMessageBegin('toggleReconnect', TMessageType.CALL, self._seqid)      args = toggleReconnect_args() @@ -835,6 +953,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_toggleReconnect(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -849,6 +968,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "toggleReconnect failed: unknown result"); +    def generatePackages(self, links):      """      Parameters: @@ -857,6 +977,7 @@ class Client(Iface):      self.send_generatePackages(links)      return self.recv_generatePackages() +    def send_generatePackages(self, links):      self._oprot.writeMessageBegin('generatePackages', TMessageType.CALL, self._seqid)      args = generatePackages_args() @@ -865,6 +986,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_generatePackages(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -879,6 +1001,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "generatePackages failed: unknown result"); +    def checkURLs(self, urls):      """      Parameters: @@ -887,6 +1010,7 @@ class Client(Iface):      self.send_checkURLs(urls)      return self.recv_checkURLs() +    def send_checkURLs(self, urls):      self._oprot.writeMessageBegin('checkURLs', TMessageType.CALL, self._seqid)      args = checkURLs_args() @@ -895,6 +1019,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_checkURLs(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -909,6 +1034,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "checkURLs failed: unknown result"); +    def parseURLs(self, html, url):      """      Parameters: @@ -918,6 +1044,7 @@ class Client(Iface):      self.send_parseURLs(html, url)      return self.recv_parseURLs() +    def send_parseURLs(self, html, url):      self._oprot.writeMessageBegin('parseURLs', TMessageType.CALL, self._seqid)      args = parseURLs_args() @@ -927,6 +1054,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_parseURLs(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -941,6 +1069,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "parseURLs failed: unknown result"); +    def checkOnlineStatus(self, urls):      """      Parameters: @@ -949,6 +1078,7 @@ class Client(Iface):      self.send_checkOnlineStatus(urls)      return self.recv_checkOnlineStatus() +    def send_checkOnlineStatus(self, urls):      self._oprot.writeMessageBegin('checkOnlineStatus', TMessageType.CALL, self._seqid)      args = checkOnlineStatus_args() @@ -957,6 +1087,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_checkOnlineStatus(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -971,6 +1102,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "checkOnlineStatus failed: unknown result"); +    def checkOnlineStatusContainer(self, urls, filename, data):      """      Parameters: @@ -981,6 +1113,7 @@ class Client(Iface):      self.send_checkOnlineStatusContainer(urls, filename, data)      return self.recv_checkOnlineStatusContainer() +    def send_checkOnlineStatusContainer(self, urls, filename, data):      self._oprot.writeMessageBegin('checkOnlineStatusContainer', TMessageType.CALL, self._seqid)      args = checkOnlineStatusContainer_args() @@ -991,6 +1124,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_checkOnlineStatusContainer(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1005,6 +1139,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "checkOnlineStatusContainer failed: unknown result"); +    def pollResults(self, rid):      """      Parameters: @@ -1013,6 +1148,7 @@ class Client(Iface):      self.send_pollResults(rid)      return self.recv_pollResults() +    def send_pollResults(self, rid):      self._oprot.writeMessageBegin('pollResults', TMessageType.CALL, self._seqid)      args = pollResults_args() @@ -1021,6 +1157,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_pollResults(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1035,10 +1172,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "pollResults failed: unknown result"); +    def statusDownloads(self,):      self.send_statusDownloads()      return self.recv_statusDownloads() +    def send_statusDownloads(self,):      self._oprot.writeMessageBegin('statusDownloads', TMessageType.CALL, self._seqid)      args = statusDownloads_args() @@ -1046,6 +1185,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_statusDownloads(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1060,6 +1200,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "statusDownloads failed: unknown result"); +    def getPackageData(self, pid):      """      Parameters: @@ -1068,6 +1209,7 @@ class Client(Iface):      self.send_getPackageData(pid)      return self.recv_getPackageData() +    def send_getPackageData(self, pid):      self._oprot.writeMessageBegin('getPackageData', TMessageType.CALL, self._seqid)      args = getPackageData_args() @@ -1076,6 +1218,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getPackageData(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1092,6 +1235,7 @@ class Client(Iface):        raise result.e      raise TApplicationException(TApplicationException.MISSING_RESULT, "getPackageData failed: unknown result"); +    def getPackageInfo(self, pid):      """      Parameters: @@ -1100,6 +1244,7 @@ class Client(Iface):      self.send_getPackageInfo(pid)      return self.recv_getPackageInfo() +    def send_getPackageInfo(self, pid):      self._oprot.writeMessageBegin('getPackageInfo', TMessageType.CALL, self._seqid)      args = getPackageInfo_args() @@ -1108,6 +1253,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getPackageInfo(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1124,6 +1270,7 @@ class Client(Iface):        raise result.e      raise TApplicationException(TApplicationException.MISSING_RESULT, "getPackageInfo failed: unknown result"); +    def getFileData(self, fid):      """      Parameters: @@ -1132,6 +1279,7 @@ class Client(Iface):      self.send_getFileData(fid)      return self.recv_getFileData() +    def send_getFileData(self, fid):      self._oprot.writeMessageBegin('getFileData', TMessageType.CALL, self._seqid)      args = getFileData_args() @@ -1140,6 +1288,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getFileData(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1156,10 +1305,12 @@ class Client(Iface):        raise result.e      raise TApplicationException(TApplicationException.MISSING_RESULT, "getFileData failed: unknown result"); +    def getQueue(self,):      self.send_getQueue()      return self.recv_getQueue() +    def send_getQueue(self,):      self._oprot.writeMessageBegin('getQueue', TMessageType.CALL, self._seqid)      args = getQueue_args() @@ -1167,6 +1318,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getQueue(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1181,10 +1333,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getQueue failed: unknown result"); +    def getCollector(self,):      self.send_getCollector()      return self.recv_getCollector() +    def send_getCollector(self,):      self._oprot.writeMessageBegin('getCollector', TMessageType.CALL, self._seqid)      args = getCollector_args() @@ -1192,6 +1346,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getCollector(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1206,10 +1361,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getCollector failed: unknown result"); +    def getQueueData(self,):      self.send_getQueueData()      return self.recv_getQueueData() +    def send_getQueueData(self,):      self._oprot.writeMessageBegin('getQueueData', TMessageType.CALL, self._seqid)      args = getQueueData_args() @@ -1217,6 +1374,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getQueueData(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1231,10 +1389,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getQueueData failed: unknown result"); +    def getCollectorData(self,):      self.send_getCollectorData()      return self.recv_getCollectorData() +    def send_getCollectorData(self,):      self._oprot.writeMessageBegin('getCollectorData', TMessageType.CALL, self._seqid)      args = getCollectorData_args() @@ -1242,6 +1402,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getCollectorData(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1256,6 +1417,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getCollectorData failed: unknown result"); +    def getPackageOrder(self, destination):      """      Parameters: @@ -1264,6 +1426,7 @@ class Client(Iface):      self.send_getPackageOrder(destination)      return self.recv_getPackageOrder() +    def send_getPackageOrder(self, destination):      self._oprot.writeMessageBegin('getPackageOrder', TMessageType.CALL, self._seqid)      args = getPackageOrder_args() @@ -1272,6 +1435,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getPackageOrder(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1286,6 +1450,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getPackageOrder failed: unknown result"); +    def getFileOrder(self, pid):      """      Parameters: @@ -1294,6 +1459,7 @@ class Client(Iface):      self.send_getFileOrder(pid)      return self.recv_getFileOrder() +    def send_getFileOrder(self, pid):      self._oprot.writeMessageBegin('getFileOrder', TMessageType.CALL, self._seqid)      args = getFileOrder_args() @@ -1302,6 +1468,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getFileOrder(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1316,6 +1483,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getFileOrder failed: unknown result"); +    def generateAndAddPackages(self, links, dest):      """      Parameters: @@ -1325,6 +1493,7 @@ class Client(Iface):      self.send_generateAndAddPackages(links, dest)      return self.recv_generateAndAddPackages() +    def send_generateAndAddPackages(self, links, dest):      self._oprot.writeMessageBegin('generateAndAddPackages', TMessageType.CALL, self._seqid)      args = generateAndAddPackages_args() @@ -1334,6 +1503,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_generateAndAddPackages(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1348,6 +1518,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "generateAndAddPackages failed: unknown result"); +    def addPackage(self, name, links, dest):      """      Parameters: @@ -1358,6 +1529,7 @@ class Client(Iface):      self.send_addPackage(name, links, dest)      return self.recv_addPackage() +    def send_addPackage(self, name, links, dest):      self._oprot.writeMessageBegin('addPackage', TMessageType.CALL, self._seqid)      args = addPackage_args() @@ -1368,6 +1540,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_addPackage(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1382,6 +1555,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "addPackage failed: unknown result"); +    def addFiles(self, pid, links):      """      Parameters: @@ -1391,6 +1565,7 @@ class Client(Iface):      self.send_addFiles(pid, links)      self.recv_addFiles() +    def send_addFiles(self, pid, links):      self._oprot.writeMessageBegin('addFiles', TMessageType.CALL, self._seqid)      args = addFiles_args() @@ -1400,6 +1575,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_addFiles(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1412,6 +1588,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def uploadContainer(self, filename, data):      """      Parameters: @@ -1421,6 +1598,7 @@ class Client(Iface):      self.send_uploadContainer(filename, data)      self.recv_uploadContainer() +    def send_uploadContainer(self, filename, data):      self._oprot.writeMessageBegin('uploadContainer', TMessageType.CALL, self._seqid)      args = uploadContainer_args() @@ -1430,6 +1608,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_uploadContainer(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1442,6 +1621,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def deleteFiles(self, fids):      """      Parameters: @@ -1450,6 +1630,7 @@ class Client(Iface):      self.send_deleteFiles(fids)      self.recv_deleteFiles() +    def send_deleteFiles(self, fids):      self._oprot.writeMessageBegin('deleteFiles', TMessageType.CALL, self._seqid)      args = deleteFiles_args() @@ -1458,6 +1639,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_deleteFiles(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1470,6 +1652,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def deletePackages(self, pids):      """      Parameters: @@ -1478,6 +1661,7 @@ class Client(Iface):      self.send_deletePackages(pids)      self.recv_deletePackages() +    def send_deletePackages(self, pids):      self._oprot.writeMessageBegin('deletePackages', TMessageType.CALL, self._seqid)      args = deletePackages_args() @@ -1486,6 +1670,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_deletePackages(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1498,6 +1683,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def pushToQueue(self, pid):      """      Parameters: @@ -1506,6 +1692,7 @@ class Client(Iface):      self.send_pushToQueue(pid)      self.recv_pushToQueue() +    def send_pushToQueue(self, pid):      self._oprot.writeMessageBegin('pushToQueue', TMessageType.CALL, self._seqid)      args = pushToQueue_args() @@ -1514,6 +1701,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_pushToQueue(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1526,6 +1714,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def pullFromQueue(self, pid):      """      Parameters: @@ -1534,6 +1723,7 @@ class Client(Iface):      self.send_pullFromQueue(pid)      self.recv_pullFromQueue() +    def send_pullFromQueue(self, pid):      self._oprot.writeMessageBegin('pullFromQueue', TMessageType.CALL, self._seqid)      args = pullFromQueue_args() @@ -1542,6 +1732,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_pullFromQueue(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1554,6 +1745,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def restartPackage(self, pid):      """      Parameters: @@ -1562,6 +1754,7 @@ class Client(Iface):      self.send_restartPackage(pid)      self.recv_restartPackage() +    def send_restartPackage(self, pid):      self._oprot.writeMessageBegin('restartPackage', TMessageType.CALL, self._seqid)      args = restartPackage_args() @@ -1570,6 +1763,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_restartPackage(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1582,6 +1776,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def restartFile(self, fid):      """      Parameters: @@ -1590,6 +1785,7 @@ class Client(Iface):      self.send_restartFile(fid)      self.recv_restartFile() +    def send_restartFile(self, fid):      self._oprot.writeMessageBegin('restartFile', TMessageType.CALL, self._seqid)      args = restartFile_args() @@ -1598,6 +1794,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_restartFile(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1610,6 +1807,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def recheckPackage(self, pid):      """      Parameters: @@ -1618,6 +1816,7 @@ class Client(Iface):      self.send_recheckPackage(pid)      self.recv_recheckPackage() +    def send_recheckPackage(self, pid):      self._oprot.writeMessageBegin('recheckPackage', TMessageType.CALL, self._seqid)      args = recheckPackage_args() @@ -1626,6 +1825,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_recheckPackage(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1638,10 +1838,12 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def stopAllDownloads(self,):      self.send_stopAllDownloads()      self.recv_stopAllDownloads() +    def send_stopAllDownloads(self,):      self._oprot.writeMessageBegin('stopAllDownloads', TMessageType.CALL, self._seqid)      args = stopAllDownloads_args() @@ -1649,6 +1851,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_stopAllDownloads(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1661,6 +1864,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def stopDownloads(self, fids):      """      Parameters: @@ -1669,6 +1873,7 @@ class Client(Iface):      self.send_stopDownloads(fids)      self.recv_stopDownloads() +    def send_stopDownloads(self, fids):      self._oprot.writeMessageBegin('stopDownloads', TMessageType.CALL, self._seqid)      args = stopDownloads_args() @@ -1677,6 +1882,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_stopDownloads(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1689,6 +1895,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def setPackageName(self, pid, name):      """      Parameters: @@ -1698,6 +1905,7 @@ class Client(Iface):      self.send_setPackageName(pid, name)      self.recv_setPackageName() +    def send_setPackageName(self, pid, name):      self._oprot.writeMessageBegin('setPackageName', TMessageType.CALL, self._seqid)      args = setPackageName_args() @@ -1707,6 +1915,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_setPackageName(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1719,6 +1928,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def movePackage(self, destination, pid):      """      Parameters: @@ -1728,6 +1938,7 @@ class Client(Iface):      self.send_movePackage(destination, pid)      self.recv_movePackage() +    def send_movePackage(self, destination, pid):      self._oprot.writeMessageBegin('movePackage', TMessageType.CALL, self._seqid)      args = movePackage_args() @@ -1737,6 +1948,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_movePackage(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1749,6 +1961,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def moveFiles(self, fids, pid):      """      Parameters: @@ -1758,6 +1971,7 @@ class Client(Iface):      self.send_moveFiles(fids, pid)      self.recv_moveFiles() +    def send_moveFiles(self, fids, pid):      self._oprot.writeMessageBegin('moveFiles', TMessageType.CALL, self._seqid)      args = moveFiles_args() @@ -1767,6 +1981,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_moveFiles(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1779,6 +1994,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def orderPackage(self, pid, position):      """      Parameters: @@ -1788,6 +2004,7 @@ class Client(Iface):      self.send_orderPackage(pid, position)      self.recv_orderPackage() +    def send_orderPackage(self, pid, position):      self._oprot.writeMessageBegin('orderPackage', TMessageType.CALL, self._seqid)      args = orderPackage_args() @@ -1797,6 +2014,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_orderPackage(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1809,6 +2027,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def orderFile(self, fid, position):      """      Parameters: @@ -1818,6 +2037,7 @@ class Client(Iface):      self.send_orderFile(fid, position)      self.recv_orderFile() +    def send_orderFile(self, fid, position):      self._oprot.writeMessageBegin('orderFile', TMessageType.CALL, self._seqid)      args = orderFile_args() @@ -1827,6 +2047,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_orderFile(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1839,6 +2060,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def setPackageData(self, pid, data):      """      Parameters: @@ -1848,6 +2070,7 @@ class Client(Iface):      self.send_setPackageData(pid, data)      self.recv_setPackageData() +    def send_setPackageData(self, pid, data):      self._oprot.writeMessageBegin('setPackageData', TMessageType.CALL, self._seqid)      args = setPackageData_args() @@ -1857,6 +2080,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_setPackageData(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1871,10 +2095,12 @@ class Client(Iface):        raise result.e      return +    def deleteFinished(self,):      self.send_deleteFinished()      return self.recv_deleteFinished() +    def send_deleteFinished(self,):      self._oprot.writeMessageBegin('deleteFinished', TMessageType.CALL, self._seqid)      args = deleteFinished_args() @@ -1882,6 +2108,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_deleteFinished(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1896,10 +2123,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "deleteFinished failed: unknown result"); +    def restartFailed(self,):      self.send_restartFailed()      self.recv_restartFailed() +    def send_restartFailed(self,):      self._oprot.writeMessageBegin('restartFailed', TMessageType.CALL, self._seqid)      args = restartFailed_args() @@ -1907,6 +2136,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_restartFailed(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1919,6 +2149,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def getEvents(self, uuid):      """      Parameters: @@ -1927,6 +2158,7 @@ class Client(Iface):      self.send_getEvents(uuid)      return self.recv_getEvents() +    def send_getEvents(self, uuid):      self._oprot.writeMessageBegin('getEvents', TMessageType.CALL, self._seqid)      args = getEvents_args() @@ -1935,6 +2167,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getEvents(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1949,6 +2182,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getEvents failed: unknown result"); +    def getAccounts(self, refresh):      """      Parameters: @@ -1957,6 +2191,7 @@ class Client(Iface):      self.send_getAccounts(refresh)      return self.recv_getAccounts() +    def send_getAccounts(self, refresh):      self._oprot.writeMessageBegin('getAccounts', TMessageType.CALL, self._seqid)      args = getAccounts_args() @@ -1965,6 +2200,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getAccounts(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -1979,10 +2215,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getAccounts failed: unknown result"); +    def getAccountTypes(self,):      self.send_getAccountTypes()      return self.recv_getAccountTypes() +    def send_getAccountTypes(self,):      self._oprot.writeMessageBegin('getAccountTypes', TMessageType.CALL, self._seqid)      args = getAccountTypes_args() @@ -1990,6 +2228,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getAccountTypes(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -2004,6 +2243,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getAccountTypes failed: unknown result"); +    def updateAccount(self, plugin, account, password, options):      """      Parameters: @@ -2015,6 +2255,7 @@ class Client(Iface):      self.send_updateAccount(plugin, account, password, options)      self.recv_updateAccount() +    def send_updateAccount(self, plugin, account, password, options):      self._oprot.writeMessageBegin('updateAccount', TMessageType.CALL, self._seqid)      args = updateAccount_args() @@ -2026,6 +2267,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_updateAccount(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -2038,6 +2280,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def removeAccount(self, plugin, account):      """      Parameters: @@ -2047,6 +2290,7 @@ class Client(Iface):      self.send_removeAccount(plugin, account)      self.recv_removeAccount() +    def send_removeAccount(self, plugin, account):      self._oprot.writeMessageBegin('removeAccount', TMessageType.CALL, self._seqid)      args = removeAccount_args() @@ -2056,6 +2300,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_removeAccount(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -2068,6 +2313,7 @@ class Client(Iface):      self._iprot.readMessageEnd()      return +    def login(self, username, password):      """      Parameters: @@ -2077,6 +2323,7 @@ class Client(Iface):      self.send_login(username, password)      return self.recv_login() +    def send_login(self, username, password):      self._oprot.writeMessageBegin('login', TMessageType.CALL, self._seqid)      args = login_args() @@ -2086,6 +2333,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_login(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -2100,6 +2348,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "login failed: unknown result"); +    def getUserData(self, username, password):      """      Parameters: @@ -2109,6 +2358,7 @@ class Client(Iface):      self.send_getUserData(username, password)      return self.recv_getUserData() +    def send_getUserData(self, username, password):      self._oprot.writeMessageBegin('getUserData', TMessageType.CALL, self._seqid)      args = getUserData_args() @@ -2118,6 +2368,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getUserData(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -2132,10 +2383,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getUserData failed: unknown result"); +    def getAllUserData(self,):      self.send_getAllUserData()      return self.recv_getAllUserData() +    def send_getAllUserData(self,):      self._oprot.writeMessageBegin('getAllUserData', TMessageType.CALL, self._seqid)      args = getAllUserData_args() @@ -2143,6 +2396,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getAllUserData(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -2157,10 +2411,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getAllUserData failed: unknown result"); +    def getServices(self,):      self.send_getServices()      return self.recv_getServices() +    def send_getServices(self,):      self._oprot.writeMessageBegin('getServices', TMessageType.CALL, self._seqid)      args = getServices_args() @@ -2168,6 +2424,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getServices(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -2182,6 +2439,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getServices failed: unknown result"); +    def hasService(self, plugin, func):      """      Parameters: @@ -2191,6 +2449,7 @@ class Client(Iface):      self.send_hasService(plugin, func)      return self.recv_hasService() +    def send_hasService(self, plugin, func):      self._oprot.writeMessageBegin('hasService', TMessageType.CALL, self._seqid)      args = hasService_args() @@ -2200,6 +2459,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_hasService(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -2214,6 +2474,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "hasService failed: unknown result"); +    def call(self, info):      """      Parameters: @@ -2222,6 +2483,7 @@ class Client(Iface):      self.send_call(info)      return self.recv_call() +    def send_call(self, info):      self._oprot.writeMessageBegin('call', TMessageType.CALL, self._seqid)      args = call_args() @@ -2230,6 +2492,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_call(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -2248,10 +2511,12 @@ class Client(Iface):        raise result.e      raise TApplicationException(TApplicationException.MISSING_RESULT, "call failed: unknown result"); +    def getAllInfo(self,):      self.send_getAllInfo()      return self.recv_getAllInfo() +    def send_getAllInfo(self,):      self._oprot.writeMessageBegin('getAllInfo', TMessageType.CALL, self._seqid)      args = getAllInfo_args() @@ -2259,6 +2524,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getAllInfo(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -2273,6 +2539,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getAllInfo failed: unknown result"); +    def getInfoByPlugin(self, plugin):      """      Parameters: @@ -2281,6 +2548,7 @@ class Client(Iface):      self.send_getInfoByPlugin(plugin)      return self.recv_getInfoByPlugin() +    def send_getInfoByPlugin(self, plugin):      self._oprot.writeMessageBegin('getInfoByPlugin', TMessageType.CALL, self._seqid)      args = getInfoByPlugin_args() @@ -2289,6 +2557,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getInfoByPlugin(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -2303,10 +2572,12 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getInfoByPlugin failed: unknown result"); +    def isCaptchaWaiting(self,):      self.send_isCaptchaWaiting()      return self.recv_isCaptchaWaiting() +    def send_isCaptchaWaiting(self,):      self._oprot.writeMessageBegin('isCaptchaWaiting', TMessageType.CALL, self._seqid)      args = isCaptchaWaiting_args() @@ -2314,6 +2585,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_isCaptchaWaiting(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -2328,6 +2600,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "isCaptchaWaiting failed: unknown result"); +    def getCaptchaTask(self, exclusive):      """      Parameters: @@ -2336,6 +2609,7 @@ class Client(Iface):      self.send_getCaptchaTask(exclusive)      return self.recv_getCaptchaTask() +    def send_getCaptchaTask(self, exclusive):      self._oprot.writeMessageBegin('getCaptchaTask', TMessageType.CALL, self._seqid)      args = getCaptchaTask_args() @@ -2344,6 +2618,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getCaptchaTask(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -2358,6 +2633,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getCaptchaTask failed: unknown result"); +    def getCaptchaTaskStatus(self, tid):      """      Parameters: @@ -2366,6 +2642,7 @@ class Client(Iface):      self.send_getCaptchaTaskStatus(tid)      return self.recv_getCaptchaTaskStatus() +    def send_getCaptchaTaskStatus(self, tid):      self._oprot.writeMessageBegin('getCaptchaTaskStatus', TMessageType.CALL, self._seqid)      args = getCaptchaTaskStatus_args() @@ -2374,6 +2651,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_getCaptchaTaskStatus(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -2388,6 +2666,7 @@ class Client(Iface):        return result.success      raise TApplicationException(TApplicationException.MISSING_RESULT, "getCaptchaTaskStatus failed: unknown result"); +    def setCaptchaResult(self, tid, result):      """      Parameters: @@ -2397,6 +2676,7 @@ class Client(Iface):      self.send_setCaptchaResult(tid, result)      self.recv_setCaptchaResult() +    def send_setCaptchaResult(self, tid, result):      self._oprot.writeMessageBegin('setCaptchaResult', TMessageType.CALL, self._seqid)      args = setCaptchaResult_args() @@ -2406,6 +2686,7 @@ class Client(Iface):      self._oprot.writeMessageEnd()      self._oprot.trans.flush() +    def recv_setCaptchaResult(self,):      (fname, mtype, rseqid) = self._iprot.readMessageBegin()      if mtype == TMessageType.EXCEPTION: @@ -2420,6 +2701,7 @@ class Client(Iface):  class Processor(Iface, TProcessor): +    def __init__(self, handler):      self._handler = handler      self._processMap = {} @@ -2494,6 +2776,7 @@ class Processor(Iface, TProcessor):      self._processMap["getCaptchaTaskStatus"] = Processor.process_getCaptchaTaskStatus      self._processMap["setCaptchaResult"] = Processor.process_setCaptchaResult +    def process(self, iprot, oprot):      (name, type, seqid) = iprot.readMessageBegin()      if name not in self._processMap: @@ -2509,6 +2792,7 @@ class Processor(Iface, TProcessor):        self._processMap[name](self, seqid, iprot, oprot)      return True +    def process_getConfigValue(self, seqid, iprot, oprot):      args = getConfigValue_args()      args.read(iprot) @@ -2520,6 +2804,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_setConfigValue(self, seqid, iprot, oprot):      args = setConfigValue_args()      args.read(iprot) @@ -2531,6 +2816,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getConfig(self, seqid, iprot, oprot):      args = getConfig_args()      args.read(iprot) @@ -2542,6 +2828,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getPluginConfig(self, seqid, iprot, oprot):      args = getPluginConfig_args()      args.read(iprot) @@ -2553,6 +2840,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_pauseServer(self, seqid, iprot, oprot):      args = pauseServer_args()      args.read(iprot) @@ -2564,6 +2852,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_unpauseServer(self, seqid, iprot, oprot):      args = unpauseServer_args()      args.read(iprot) @@ -2575,6 +2864,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_togglePause(self, seqid, iprot, oprot):      args = togglePause_args()      args.read(iprot) @@ -2586,6 +2876,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_statusServer(self, seqid, iprot, oprot):      args = statusServer_args()      args.read(iprot) @@ -2597,6 +2888,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_freeSpace(self, seqid, iprot, oprot):      args = freeSpace_args()      args.read(iprot) @@ -2608,6 +2900,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getServerVersion(self, seqid, iprot, oprot):      args = getServerVersion_args()      args.read(iprot) @@ -2619,6 +2912,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_kill(self, seqid, iprot, oprot):      args = kill_args()      args.read(iprot) @@ -2630,6 +2924,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_restart(self, seqid, iprot, oprot):      args = restart_args()      args.read(iprot) @@ -2641,6 +2936,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getLog(self, seqid, iprot, oprot):      args = getLog_args()      args.read(iprot) @@ -2652,6 +2948,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_isTimeDownload(self, seqid, iprot, oprot):      args = isTimeDownload_args()      args.read(iprot) @@ -2663,6 +2960,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_isTimeReconnect(self, seqid, iprot, oprot):      args = isTimeReconnect_args()      args.read(iprot) @@ -2674,6 +2972,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_toggleReconnect(self, seqid, iprot, oprot):      args = toggleReconnect_args()      args.read(iprot) @@ -2685,6 +2984,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_generatePackages(self, seqid, iprot, oprot):      args = generatePackages_args()      args.read(iprot) @@ -2696,6 +2996,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_checkURLs(self, seqid, iprot, oprot):      args = checkURLs_args()      args.read(iprot) @@ -2707,6 +3008,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_parseURLs(self, seqid, iprot, oprot):      args = parseURLs_args()      args.read(iprot) @@ -2718,6 +3020,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_checkOnlineStatus(self, seqid, iprot, oprot):      args = checkOnlineStatus_args()      args.read(iprot) @@ -2729,6 +3032,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_checkOnlineStatusContainer(self, seqid, iprot, oprot):      args = checkOnlineStatusContainer_args()      args.read(iprot) @@ -2740,6 +3044,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_pollResults(self, seqid, iprot, oprot):      args = pollResults_args()      args.read(iprot) @@ -2751,6 +3056,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_statusDownloads(self, seqid, iprot, oprot):      args = statusDownloads_args()      args.read(iprot) @@ -2762,6 +3068,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getPackageData(self, seqid, iprot, oprot):      args = getPackageData_args()      args.read(iprot) @@ -2776,6 +3083,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getPackageInfo(self, seqid, iprot, oprot):      args = getPackageInfo_args()      args.read(iprot) @@ -2790,6 +3098,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getFileData(self, seqid, iprot, oprot):      args = getFileData_args()      args.read(iprot) @@ -2804,6 +3113,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getQueue(self, seqid, iprot, oprot):      args = getQueue_args()      args.read(iprot) @@ -2815,6 +3125,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getCollector(self, seqid, iprot, oprot):      args = getCollector_args()      args.read(iprot) @@ -2826,6 +3137,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getQueueData(self, seqid, iprot, oprot):      args = getQueueData_args()      args.read(iprot) @@ -2837,6 +3149,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getCollectorData(self, seqid, iprot, oprot):      args = getCollectorData_args()      args.read(iprot) @@ -2848,6 +3161,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getPackageOrder(self, seqid, iprot, oprot):      args = getPackageOrder_args()      args.read(iprot) @@ -2859,6 +3173,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getFileOrder(self, seqid, iprot, oprot):      args = getFileOrder_args()      args.read(iprot) @@ -2870,6 +3185,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_generateAndAddPackages(self, seqid, iprot, oprot):      args = generateAndAddPackages_args()      args.read(iprot) @@ -2881,6 +3197,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_addPackage(self, seqid, iprot, oprot):      args = addPackage_args()      args.read(iprot) @@ -2892,6 +3209,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_addFiles(self, seqid, iprot, oprot):      args = addFiles_args()      args.read(iprot) @@ -2903,6 +3221,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_uploadContainer(self, seqid, iprot, oprot):      args = uploadContainer_args()      args.read(iprot) @@ -2914,6 +3233,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_deleteFiles(self, seqid, iprot, oprot):      args = deleteFiles_args()      args.read(iprot) @@ -2925,6 +3245,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_deletePackages(self, seqid, iprot, oprot):      args = deletePackages_args()      args.read(iprot) @@ -2936,6 +3257,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_pushToQueue(self, seqid, iprot, oprot):      args = pushToQueue_args()      args.read(iprot) @@ -2947,6 +3269,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_pullFromQueue(self, seqid, iprot, oprot):      args = pullFromQueue_args()      args.read(iprot) @@ -2958,6 +3281,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_restartPackage(self, seqid, iprot, oprot):      args = restartPackage_args()      args.read(iprot) @@ -2969,6 +3293,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_restartFile(self, seqid, iprot, oprot):      args = restartFile_args()      args.read(iprot) @@ -2980,6 +3305,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_recheckPackage(self, seqid, iprot, oprot):      args = recheckPackage_args()      args.read(iprot) @@ -2991,6 +3317,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_stopAllDownloads(self, seqid, iprot, oprot):      args = stopAllDownloads_args()      args.read(iprot) @@ -3002,6 +3329,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_stopDownloads(self, seqid, iprot, oprot):      args = stopDownloads_args()      args.read(iprot) @@ -3013,6 +3341,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_setPackageName(self, seqid, iprot, oprot):      args = setPackageName_args()      args.read(iprot) @@ -3024,6 +3353,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_movePackage(self, seqid, iprot, oprot):      args = movePackage_args()      args.read(iprot) @@ -3035,6 +3365,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_moveFiles(self, seqid, iprot, oprot):      args = moveFiles_args()      args.read(iprot) @@ -3046,6 +3377,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_orderPackage(self, seqid, iprot, oprot):      args = orderPackage_args()      args.read(iprot) @@ -3057,6 +3389,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_orderFile(self, seqid, iprot, oprot):      args = orderFile_args()      args.read(iprot) @@ -3068,6 +3401,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_setPackageData(self, seqid, iprot, oprot):      args = setPackageData_args()      args.read(iprot) @@ -3082,6 +3416,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_deleteFinished(self, seqid, iprot, oprot):      args = deleteFinished_args()      args.read(iprot) @@ -3093,6 +3428,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_restartFailed(self, seqid, iprot, oprot):      args = restartFailed_args()      args.read(iprot) @@ -3104,6 +3440,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getEvents(self, seqid, iprot, oprot):      args = getEvents_args()      args.read(iprot) @@ -3115,6 +3452,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getAccounts(self, seqid, iprot, oprot):      args = getAccounts_args()      args.read(iprot) @@ -3126,6 +3464,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getAccountTypes(self, seqid, iprot, oprot):      args = getAccountTypes_args()      args.read(iprot) @@ -3137,6 +3476,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_updateAccount(self, seqid, iprot, oprot):      args = updateAccount_args()      args.read(iprot) @@ -3148,6 +3488,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_removeAccount(self, seqid, iprot, oprot):      args = removeAccount_args()      args.read(iprot) @@ -3159,6 +3500,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_login(self, seqid, iprot, oprot):      args = login_args()      args.read(iprot) @@ -3170,6 +3512,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getUserData(self, seqid, iprot, oprot):      args = getUserData_args()      args.read(iprot) @@ -3181,6 +3524,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getAllUserData(self, seqid, iprot, oprot):      args = getAllUserData_args()      args.read(iprot) @@ -3192,6 +3536,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getServices(self, seqid, iprot, oprot):      args = getServices_args()      args.read(iprot) @@ -3203,6 +3548,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_hasService(self, seqid, iprot, oprot):      args = hasService_args()      args.read(iprot) @@ -3214,6 +3560,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_call(self, seqid, iprot, oprot):      args = call_args()      args.read(iprot) @@ -3230,6 +3577,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getAllInfo(self, seqid, iprot, oprot):      args = getAllInfo_args()      args.read(iprot) @@ -3241,6 +3589,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getInfoByPlugin(self, seqid, iprot, oprot):      args = getInfoByPlugin_args()      args.read(iprot) @@ -3252,6 +3601,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_isCaptchaWaiting(self, seqid, iprot, oprot):      args = isCaptchaWaiting_args()      args.read(iprot) @@ -3263,6 +3613,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getCaptchaTask(self, seqid, iprot, oprot):      args = getCaptchaTask_args()      args.read(iprot) @@ -3274,6 +3625,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_getCaptchaTaskStatus(self, seqid, iprot, oprot):      args = getCaptchaTaskStatus_args()      args.read(iprot) @@ -3285,6 +3637,7 @@ class Processor(Iface, TProcessor):      oprot.writeMessageEnd()      oprot.trans.flush() +    def process_setCaptchaResult(self, seqid, iprot, oprot):      args = setCaptchaResult_args()      args.read(iprot) @@ -3320,6 +3673,7 @@ class getConfigValue_args(TBase):      (3, TType.STRING, 'section', None, None,), # 3    ) +    def __init__(self, category=None, option=None, section=None,):      self.category = category      self.option = option @@ -3340,6 +3694,7 @@ class getConfigValue_result(TBase):      (0, TType.STRING, 'success', None, None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -3368,6 +3723,7 @@ class setConfigValue_args(TBase):      (4, TType.STRING, 'section', None, None,), # 4    ) +    def __init__(self, category=None, option=None, value=None, section=None,):      self.category = category      self.option = option @@ -3407,6 +3763,7 @@ class getConfig_result(TBase):      (0, TType.MAP, 'success', (TType.STRING, None, TType.STRUCT, (ConfigSection, ConfigSection.thrift_spec)), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -3434,6 +3791,7 @@ class getPluginConfig_result(TBase):      (0, TType.MAP, 'success', (TType.STRING, None, TType.STRUCT, (ConfigSection, ConfigSection.thrift_spec)), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -3497,6 +3855,7 @@ class togglePause_result(TBase):      (0, TType.BOOL, 'success', None, None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -3524,6 +3883,7 @@ class statusServer_result(TBase):      (0, TType.STRUCT, 'success', (ServerStatus, ServerStatus.thrift_spec), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -3551,6 +3911,7 @@ class freeSpace_result(TBase):      (0, TType.I64, 'success', None, None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -3578,6 +3939,7 @@ class getServerVersion_result(TBase):      (0, TType.STRING, 'success', None, None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -3633,6 +3995,7 @@ class getLog_args(TBase):      (1, TType.I32, 'offset', None, None,), # 1    ) +    def __init__(self, offset=None,):      self.offset = offset @@ -3651,6 +4014,7 @@ class getLog_result(TBase):      (0, TType.LIST, 'success', (TType.STRING, None), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -3678,6 +4042,7 @@ class isTimeDownload_result(TBase):      (0, TType.BOOL, 'success', None, None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -3705,6 +4070,7 @@ class isTimeReconnect_result(TBase):      (0, TType.BOOL, 'success', None, None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -3732,6 +4098,7 @@ class toggleReconnect_result(TBase):      (0, TType.BOOL, 'success', None, None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -3751,6 +4118,7 @@ class generatePackages_args(TBase):      (1, TType.LIST, 'links', (TType.STRING, None), None,), # 1    ) +    def __init__(self, links=None,):      self.links = links @@ -3769,6 +4137,7 @@ class generatePackages_result(TBase):      (0, TType.MAP, 'success', (TType.STRING, None, TType.LIST, (TType.STRING, None)), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -3788,6 +4157,7 @@ class checkURLs_args(TBase):      (1, TType.LIST, 'urls', (TType.STRING, None), None,), # 1    ) +    def __init__(self, urls=None,):      self.urls = urls @@ -3806,6 +4176,7 @@ class checkURLs_result(TBase):      (0, TType.MAP, 'success', (TType.STRING, None, TType.LIST, (TType.STRING, None)), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -3828,6 +4199,7 @@ class parseURLs_args(TBase):      (2, TType.STRING, 'url', None, None,), # 2    ) +    def __init__(self, html=None, url=None,):      self.html = html      self.url = url @@ -3847,6 +4219,7 @@ class parseURLs_result(TBase):      (0, TType.MAP, 'success', (TType.STRING, None, TType.LIST, (TType.STRING, None)), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -3866,6 +4239,7 @@ class checkOnlineStatus_args(TBase):      (1, TType.LIST, 'urls', (TType.STRING, None), None,), # 1    ) +    def __init__(self, urls=None,):      self.urls = urls @@ -3884,6 +4258,7 @@ class checkOnlineStatus_result(TBase):      (0, TType.STRUCT, 'success', (OnlineCheck, OnlineCheck.thrift_spec), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -3909,6 +4284,7 @@ class checkOnlineStatusContainer_args(TBase):      (3, TType.STRING, 'data', None, None,), # 3    ) +    def __init__(self, urls=None, filename=None, data=None,):      self.urls = urls      self.filename = filename @@ -3929,6 +4305,7 @@ class checkOnlineStatusContainer_result(TBase):      (0, TType.STRUCT, 'success', (OnlineCheck, OnlineCheck.thrift_spec), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -3948,6 +4325,7 @@ class pollResults_args(TBase):      (1, TType.I32, 'rid', None, None,), # 1    ) +    def __init__(self, rid=None,):      self.rid = rid @@ -3966,6 +4344,7 @@ class pollResults_result(TBase):      (0, TType.STRUCT, 'success', (OnlineCheck, OnlineCheck.thrift_spec), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -3993,6 +4372,7 @@ class statusDownloads_result(TBase):      (0, TType.LIST, 'success', (TType.STRUCT, (DownloadInfo, DownloadInfo.thrift_spec)), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -4012,6 +4392,7 @@ class getPackageData_args(TBase):      (1, TType.I32, 'pid', None, None,), # 1    ) +    def __init__(self, pid=None,):      self.pid = pid @@ -4033,6 +4414,7 @@ class getPackageData_result(TBase):      (1, TType.STRUCT, 'e', (PackageDoesNotExists, PackageDoesNotExists.thrift_spec), None,), # 1    ) +    def __init__(self, success=None, e=None,):      self.success = success      self.e = e @@ -4053,6 +4435,7 @@ class getPackageInfo_args(TBase):      (1, TType.I32, 'pid', None, None,), # 1    ) +    def __init__(self, pid=None,):      self.pid = pid @@ -4074,6 +4457,7 @@ class getPackageInfo_result(TBase):      (1, TType.STRUCT, 'e', (PackageDoesNotExists, PackageDoesNotExists.thrift_spec), None,), # 1    ) +    def __init__(self, success=None, e=None,):      self.success = success      self.e = e @@ -4094,6 +4478,7 @@ class getFileData_args(TBase):      (1, TType.I32, 'fid', None, None,), # 1    ) +    def __init__(self, fid=None,):      self.fid = fid @@ -4115,6 +4500,7 @@ class getFileData_result(TBase):      (1, TType.STRUCT, 'e', (FileDoesNotExists, FileDoesNotExists.thrift_spec), None,), # 1    ) +    def __init__(self, success=None, e=None,):      self.success = success      self.e = e @@ -4143,6 +4529,7 @@ class getQueue_result(TBase):      (0, TType.LIST, 'success', (TType.STRUCT, (PackageData, PackageData.thrift_spec)), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -4170,6 +4557,7 @@ class getCollector_result(TBase):      (0, TType.LIST, 'success', (TType.STRUCT, (PackageData, PackageData.thrift_spec)), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -4197,6 +4585,7 @@ class getQueueData_result(TBase):      (0, TType.LIST, 'success', (TType.STRUCT, (PackageData, PackageData.thrift_spec)), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -4224,6 +4613,7 @@ class getCollectorData_result(TBase):      (0, TType.LIST, 'success', (TType.STRUCT, (PackageData, PackageData.thrift_spec)), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -4243,6 +4633,7 @@ class getPackageOrder_args(TBase):      (1, TType.I32, 'destination', None, None,), # 1    ) +    def __init__(self, destination=None,):      self.destination = destination @@ -4261,6 +4652,7 @@ class getPackageOrder_result(TBase):      (0, TType.MAP, 'success', (TType.I16, None, TType.I32, None), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -4280,6 +4672,7 @@ class getFileOrder_args(TBase):      (1, TType.I32, 'pid', None, None,), # 1    ) +    def __init__(self, pid=None,):      self.pid = pid @@ -4298,6 +4691,7 @@ class getFileOrder_result(TBase):      (0, TType.MAP, 'success', (TType.I16, None, TType.I32, None), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -4320,6 +4714,7 @@ class generateAndAddPackages_args(TBase):      (2, TType.I32, 'dest', None, None,), # 2    ) +    def __init__(self, links=None, dest=None,):      self.links = links      self.dest = dest @@ -4339,6 +4734,7 @@ class generateAndAddPackages_result(TBase):      (0, TType.LIST, 'success', (TType.I32, None), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -4364,6 +4760,7 @@ class addPackage_args(TBase):      (3, TType.I32, 'dest', None, None,), # 3    ) +    def __init__(self, name=None, links=None, dest=None,):      self.name = name      self.links = links @@ -4384,6 +4781,7 @@ class addPackage_result(TBase):      (0, TType.I32, 'success', None, None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -4406,6 +4804,7 @@ class addFiles_args(TBase):      (2, TType.LIST, 'links', (TType.STRING, None), None,), # 2    ) +    def __init__(self, pid=None, links=None,):      self.pid = pid      self.links = links @@ -4438,6 +4837,7 @@ class uploadContainer_args(TBase):      (2, TType.STRING, 'data', None, None,), # 2    ) +    def __init__(self, filename=None, data=None,):      self.filename = filename      self.data = data @@ -4467,6 +4867,7 @@ class deleteFiles_args(TBase):      (1, TType.LIST, 'fids', (TType.I32, None), None,), # 1    ) +    def __init__(self, fids=None,):      self.fids = fids @@ -4495,6 +4896,7 @@ class deletePackages_args(TBase):      (1, TType.LIST, 'pids', (TType.I32, None), None,), # 1    ) +    def __init__(self, pids=None,):      self.pids = pids @@ -4523,6 +4925,7 @@ class pushToQueue_args(TBase):      (1, TType.I32, 'pid', None, None,), # 1    ) +    def __init__(self, pid=None,):      self.pid = pid @@ -4551,6 +4954,7 @@ class pullFromQueue_args(TBase):      (1, TType.I32, 'pid', None, None,), # 1    ) +    def __init__(self, pid=None,):      self.pid = pid @@ -4579,6 +4983,7 @@ class restartPackage_args(TBase):      (1, TType.I32, 'pid', None, None,), # 1    ) +    def __init__(self, pid=None,):      self.pid = pid @@ -4607,6 +5012,7 @@ class restartFile_args(TBase):      (1, TType.I32, 'fid', None, None,), # 1    ) +    def __init__(self, fid=None,):      self.fid = fid @@ -4635,6 +5041,7 @@ class recheckPackage_args(TBase):      (1, TType.I32, 'pid', None, None,), # 1    ) +    def __init__(self, pid=None,):      self.pid = pid @@ -4681,6 +5088,7 @@ class stopDownloads_args(TBase):      (1, TType.LIST, 'fids', (TType.I32, None), None,), # 1    ) +    def __init__(self, fids=None,):      self.fids = fids @@ -4712,6 +5120,7 @@ class setPackageName_args(TBase):      (2, TType.STRING, 'name', None, None,), # 2    ) +    def __init__(self, pid=None, name=None,):      self.pid = pid      self.name = name @@ -4744,6 +5153,7 @@ class movePackage_args(TBase):      (2, TType.I32, 'pid', None, None,), # 2    ) +    def __init__(self, destination=None, pid=None,):      self.destination = destination      self.pid = pid @@ -4776,6 +5186,7 @@ class moveFiles_args(TBase):      (2, TType.I32, 'pid', None, None,), # 2    ) +    def __init__(self, fids=None, pid=None,):      self.fids = fids      self.pid = pid @@ -4808,6 +5219,7 @@ class orderPackage_args(TBase):      (2, TType.I16, 'position', None, None,), # 2    ) +    def __init__(self, pid=None, position=None,):      self.pid = pid      self.position = position @@ -4840,6 +5252,7 @@ class orderFile_args(TBase):      (2, TType.I16, 'position', None, None,), # 2    ) +    def __init__(self, fid=None, position=None,):      self.fid = fid      self.position = position @@ -4872,6 +5285,7 @@ class setPackageData_args(TBase):      (2, TType.MAP, 'data', (TType.STRING, None, TType.STRING, None), None,), # 2    ) +    def __init__(self, pid=None, data=None,):      self.pid = pid      self.data = data @@ -4892,6 +5306,7 @@ class setPackageData_result(TBase):      (1, TType.STRUCT, 'e', (PackageDoesNotExists, PackageDoesNotExists.thrift_spec), None,), # 1    ) +    def __init__(self, e=None,):      self.e = e @@ -4919,6 +5334,7 @@ class deleteFinished_result(TBase):      (0, TType.LIST, 'success', (TType.I32, None), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -4956,6 +5372,7 @@ class getEvents_args(TBase):      (1, TType.STRING, 'uuid', None, None,), # 1    ) +    def __init__(self, uuid=None,):      self.uuid = uuid @@ -4974,6 +5391,7 @@ class getEvents_result(TBase):      (0, TType.LIST, 'success', (TType.STRUCT, (EventInfo, EventInfo.thrift_spec)), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -4993,6 +5411,7 @@ class getAccounts_args(TBase):      (1, TType.BOOL, 'refresh', None, None,), # 1    ) +    def __init__(self, refresh=None,):      self.refresh = refresh @@ -5011,6 +5430,7 @@ class getAccounts_result(TBase):      (0, TType.LIST, 'success', (TType.STRUCT, (AccountInfo, AccountInfo.thrift_spec)), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -5038,6 +5458,7 @@ class getAccountTypes_result(TBase):      (0, TType.LIST, 'success', (TType.STRING, None), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -5066,6 +5487,7 @@ class updateAccount_args(TBase):      (4, TType.MAP, 'options', (TType.STRING, None, TType.STRING, None), None,), # 4    ) +    def __init__(self, plugin=None, account=None, password=None, options=None,):      self.plugin = plugin      self.account = account @@ -5100,6 +5522,7 @@ class removeAccount_args(TBase):      (2, TType.STRING, 'account', None, None,), # 2    ) +    def __init__(self, plugin=None, account=None,):      self.plugin = plugin      self.account = account @@ -5132,6 +5555,7 @@ class login_args(TBase):      (2, TType.STRING, 'password', None, None,), # 2    ) +    def __init__(self, username=None, password=None,):      self.username = username      self.password = password @@ -5151,6 +5575,7 @@ class login_result(TBase):      (0, TType.BOOL, 'success', None, None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -5173,6 +5598,7 @@ class getUserData_args(TBase):      (2, TType.STRING, 'password', None, None,), # 2    ) +    def __init__(self, username=None, password=None,):      self.username = username      self.password = password @@ -5192,6 +5618,7 @@ class getUserData_result(TBase):      (0, TType.STRUCT, 'success', (UserData, UserData.thrift_spec), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -5219,6 +5646,7 @@ class getAllUserData_result(TBase):      (0, TType.MAP, 'success', (TType.STRING, None, TType.STRUCT, (UserData, UserData.thrift_spec)), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -5246,6 +5674,7 @@ class getServices_result(TBase):      (0, TType.MAP, 'success', (TType.STRING, None, TType.MAP, (TType.STRING, None, TType.STRING, None)), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -5268,6 +5697,7 @@ class hasService_args(TBase):      (2, TType.STRING, 'func', None, None,), # 2    ) +    def __init__(self, plugin=None, func=None,):      self.plugin = plugin      self.func = func @@ -5287,6 +5717,7 @@ class hasService_result(TBase):      (0, TType.BOOL, 'success', None, None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -5306,6 +5737,7 @@ class call_args(TBase):      (1, TType.STRUCT, 'info', (ServiceCall, ServiceCall.thrift_spec), None,), # 1    ) +    def __init__(self, info=None,):      self.info = info @@ -5330,6 +5762,7 @@ class call_result(TBase):      (2, TType.STRUCT, 'e', (ServiceException, ServiceException.thrift_spec), None,), # 2    ) +    def __init__(self, success=None, ex=None, e=None,):      self.success = success      self.ex = ex @@ -5359,6 +5792,7 @@ class getAllInfo_result(TBase):      (0, TType.MAP, 'success', (TType.STRING, None, TType.MAP, (TType.STRING, None, TType.STRING, None)), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -5378,6 +5812,7 @@ class getInfoByPlugin_args(TBase):      (1, TType.STRING, 'plugin', None, None,), # 1    ) +    def __init__(self, plugin=None,):      self.plugin = plugin @@ -5396,6 +5831,7 @@ class getInfoByPlugin_result(TBase):      (0, TType.MAP, 'success', (TType.STRING, None, TType.STRING, None), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -5423,6 +5859,7 @@ class isCaptchaWaiting_result(TBase):      (0, TType.BOOL, 'success', None, None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -5442,6 +5879,7 @@ class getCaptchaTask_args(TBase):      (1, TType.BOOL, 'exclusive', None, None,), # 1    ) +    def __init__(self, exclusive=None,):      self.exclusive = exclusive @@ -5460,6 +5898,7 @@ class getCaptchaTask_result(TBase):      (0, TType.STRUCT, 'success', (CaptchaTask, CaptchaTask.thrift_spec), None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -5479,6 +5918,7 @@ class getCaptchaTaskStatus_args(TBase):      (1, TType.I32, 'tid', None, None,), # 1    ) +    def __init__(self, tid=None,):      self.tid = tid @@ -5497,6 +5937,7 @@ class getCaptchaTaskStatus_result(TBase):      (0, TType.STRING, 'success', None, None,), # 0    ) +    def __init__(self, success=None,):      self.success = success @@ -5519,6 +5960,7 @@ class setCaptchaResult_args(TBase):      (2, TType.STRING, 'result', None, None,), # 2    ) +    def __init__(self, tid=None, result=None,):      self.tid = tid      self.result = result diff --git a/pyload/remote/thriftbackend/thriftgen/pyload/ttypes.py b/pyload/remote/thriftbackend/thriftgen/pyload/ttypes.py index 67d23161d..70b29ff1e 100644 --- a/pyload/remote/thriftbackend/thriftgen/pyload/ttypes.py +++ b/pyload/remote/thriftbackend/thriftgen/pyload/ttypes.py @@ -208,6 +208,7 @@ class DownloadInfo(TBase):      (16, TType.STRING, 'plugin', None, None,), # 16    ) +    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 @@ -260,6 +261,7 @@ class ServerStatus(TBase):      (7, TType.BOOL, 'reconnect', None, None,), # 7    ) +    def __init__(self, pause=None, active=None, queue=None, total=None, speed=None, download=None, reconnect=None,):      self.pause = pause      self.active = active @@ -294,6 +296,7 @@ class ConfigItem(TBase):      (4, TType.STRING, 'type', None, None,), # 4    ) +    def __init__(self, name=None, description=None, value=None, type=None,):      self.name = name      self.description = description @@ -325,6 +328,7 @@ class ConfigSection(TBase):      (4, TType.STRING, 'outline', None, None,), # 4    ) +    def __init__(self, name=None, description=None, items=None, outline=None,):      self.name = name      self.description = description @@ -377,6 +381,7 @@ class FileData(TBase):      (11, TType.I16, 'order', None, None,), # 11    ) +    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 @@ -442,6 +447,7 @@ class PackageData(TBase):      (13, TType.LIST, 'fids', (TType.I32, None), None,), # 13    ) +    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 @@ -497,6 +503,7 @@ class InteractionTask(TBase):      (9, TType.STRING, 'plugin', None, None,), # 9    ) +    def __init__(self, iid=None, input=None, structure=None, preset=None, output=None, data=None, title=None, description=None, plugin=None,):      self.iid = iid      self.input = input @@ -533,6 +540,7 @@ class CaptchaTask(TBase):      (4, TType.STRING, 'resultType', None, None,), # 4    ) +    def __init__(self, tid=None, data=None, type=None, resultType=None,):      self.tid = tid      self.data = data @@ -564,6 +572,7 @@ class EventInfo(TBase):      (4, TType.I32, 'destination', None, None,), # 4    ) +    def __init__(self, eventname=None, id=None, type=None, destination=None,):      self.eventname = eventname      self.id = id @@ -598,6 +607,7 @@ class UserData(TBase):      (5, TType.STRING, 'templateName', None, None,), # 5    ) +    def __init__(self, name=None, email=None, role=None, permission=None, templateName=None,):      self.name = name      self.email = email @@ -642,6 +652,7 @@ class AccountInfo(TBase):      (8, TType.STRING, 'type', None, None,), # 8    ) +    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 @@ -677,6 +688,7 @@ class ServiceCall(TBase):      (4, TType.BOOL, 'parseArguments', None, None,), # 4    ) +    def __init__(self, plugin=None, func=None, arguments=None, parseArguments=None,):      self.plugin = plugin      self.func = func @@ -711,6 +723,7 @@ class OnlineStatus(TBase):      (5, TType.I64, 'size', None, None,), # 5    ) +    def __init__(self, name=None, plugin=None, packagename=None, status=None, size=None,):      self.name = name      self.plugin = plugin @@ -737,6 +750,7 @@ class OnlineCheck(TBase):      (2, TType.MAP, 'data', (TType.STRING, None, TType.STRUCT, (OnlineStatus, OnlineStatus.thrift_spec)), None,), # 2    ) +    def __init__(self, rid=None, data=None,):      self.rid = rid      self.data = data @@ -757,9 +771,11 @@ class PackageDoesNotExists(TExceptionBase):      (1, TType.I32, 'pid', None, None,), # 1    ) +    def __init__(self, pid=None,):      self.pid = pid +    def __str__(self):      return repr(self) @@ -779,9 +795,11 @@ class FileDoesNotExists(TExceptionBase):      (1, TType.I32, 'fid', None, None,), # 1    ) +    def __init__(self, fid=None,):      self.fid = fid +    def __str__(self):      return repr(self) @@ -804,10 +822,12 @@ class ServiceDoesNotExists(TExceptionBase):      (2, TType.STRING, 'func', None, None,), # 2    ) +    def __init__(self, plugin=None, func=None,):      self.plugin = plugin      self.func = func +    def __str__(self):      return repr(self) @@ -827,8 +847,10 @@ class ServiceException(TExceptionBase):      (1, TType.STRING, 'msg', None, None,), # 1    ) +    def __init__(self, msg=None,):      self.msg = msg +    def __str__(self):      return repr(self) diff --git a/pyload/utils/__init__.py b/pyload/utils/__init__.py index 13567f1a2..22f92222e 100644 --- a/pyload/utils/__init__.py +++ b/pyload/utils/__init__.py @@ -90,6 +90,8 @@ def save_join(*args):  # Use fs_encode before accesing files on disk, it will encode the string properly  if sys.getfilesystemencoding().startswith('ANSI'): + +      def fs_encode(string):          return safe_filename(encode(string)) @@ -206,6 +208,8 @@ def parseFileSize(string, unit=None):  # returns bytes  def lock(func): + +      def new(*args):          # print "Handler: %s args: %s" % (func, args[1:])          args[0].lock.acquire() diff --git a/pyload/webui/app/cnl.py b/pyload/webui/app/cnl.py index dee0f2341..51767033f 100644 --- a/pyload/webui/app/cnl.py +++ b/pyload/webui/app/cnl.py @@ -16,6 +16,8 @@ except Exception:  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"): diff --git a/pyload/webui/app/utils.py b/pyload/webui/app/utils.py index 4a431493b..ac7fa84fb 100644 --- a/pyload/webui/app/utils.py +++ b/pyload/webui/app/utils.py @@ -84,7 +84,11 @@ def parse_userdata(session):  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): @@ -116,6 +120,7 @@ def toDict(obj):  class CherryPyWSGI(ServerAdapter): +      def run(self, handler):          from wsgiserver import CherryPyWSGIServer diff --git a/pyload/webui/filters.py b/pyload/webui/filters.py index 527b18446..c784b248d 100644 --- a/pyload/webui/filters.py +++ b/pyload/webui/filters.py @@ -8,6 +8,8 @@ try:      from os.path import relpath  except Exception:      from posixpath import curdir, sep, pardir + +      def relpath(path, start=curdir):          """Return a relative version of a path"""          if not path: diff --git a/pyload/webui/middlewares.py b/pyload/webui/middlewares.py index 19328f9ef..26537f900 100644 --- a/pyload/webui/middlewares.py +++ b/pyload/webui/middlewares.py @@ -8,19 +8,23 @@ except ImportError:      from StringIO import StringIO  class StripPathMiddleware(object): +      def __init__(self, app):          self.app = app +      def __call__(self, e, h):          e['PATH_INFO'] = e['PATH_INFO'].rstrip('/')          return self.app(e, h)  class PrefixMiddleware(object): +      def __init__(self, app, prefix="/pyload"):          self.app = app          self.prefix = prefix +      def __call__(self, e, h):          path = e["PATH_INFO"]          if path.startswith(self.prefix): @@ -42,6 +46,7 @@ class GZipMiddleWare(object):          self.application = application          self.compress_level = int(compress_level) +      def __call__(self, environ, start_response):          if 'gzip' not in environ.get('HTTP_ACCEPT_ENCODING', ''):              # nothing for us to do, so this middleware will @@ -80,6 +85,7 @@ class GzipResponse(object):          self.content_length = None          self.headers = () +      def gzip_start_response(self, status, headers, exc_info=None):          self.headers = headers          ct = header_value(headers,'content-type') @@ -102,6 +108,7 @@ class GzipResponse(object):          self.status = status          return self.buffer.write +      def write(self):          out = self.buffer          out.seek(0) @@ -109,6 +116,7 @@ class GzipResponse(object):          out.close()          return [s] +      def finish_response(self, app_iter):          if self.compressible:              output = gzip.GzipFile(mode='wb', compresslevel=self.compress_level, | 
