summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2012-01-01 13:36:59 +0100
committerGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2012-01-01 13:36:59 +0100
commit35742c2cb023ac49ab3056752d2040cdb030cc2b (patch)
treed0f22f591b2b81ab24a982a44820a3d86ba5eea3 /module
parentmissing import (diff)
downloadpyload-35742c2cb023ac49ab3056752d2040cdb030cc2b.tar.xz
Happy new Year !
Diffstat (limited to 'module')
-rw-r--r--module/Api.py34
-rw-r--r--module/PyPackage.py9
-rw-r--r--module/database/FileDatabase.py3
-rw-r--r--module/plugins/Account.py30
-rw-r--r--module/plugins/Crypter.py92
-rw-r--r--module/plugins/crypter/LinkList.py (renamed from module/plugins/container/LinkList.py)32
-rw-r--r--module/plugins/hoster/YoutubeCom.py6
-rw-r--r--module/remote/thriftbackend/pyload.thrift2
-rw-r--r--module/threads/BaseThread.py30
-rw-r--r--module/threads/DecrypterThread.py65
-rw-r--r--module/threads/DownloadThread.py4
-rw-r--r--module/threads/InfoThread.py51
-rw-r--r--module/threads/ThreadManager.py11
-rw-r--r--module/utils/__init__.py4
-rw-r--r--module/utils/fs.py5
-rw-r--r--module/web/templates/default/base.html2
16 files changed, 223 insertions, 157 deletions
diff --git a/module/Api.py b/module/Api.py
index deac1a19f..810613b66 100644
--- a/module/Api.py
+++ b/module/Api.py
@@ -17,10 +17,12 @@
@author: RaNaN
"""
+import re
from base64 import standard_b64encode
from os.path import join
from time import time
-import re
+from itertools import chain
+
from PyFile import PyFile
from utils import freeSpace, compare_time
@@ -321,7 +323,7 @@ class Api(Iface):
self.core.threadManager.createInfoThread(hoster, pid)
self.core.threadManager.createDecryptThread(crypter, pid)
- self.core.log.info(_("Added %(count)d links to package #%(package)d ") % {"count": len(links), "package": pid})
+ self.core.log.debug("Added %d links to package #%d " % (len(hoster), pid))
self.core.files.save()
@permission(PERMS.ADD)
@@ -354,7 +356,7 @@ class Api(Iface):
data, crypter = self.core.pluginManager.parseUrls(urls)
plugins = {}
- for url, plugin in data:
+ for url, plugin in chain(data, crypter):
if plugin in plugins:
plugins[plugin].append(url)
else:
@@ -364,15 +366,14 @@ class Api(Iface):
@permission(PERMS.ADD)
def checkOnlineStatus(self, urls):
- """ initiates online status check
+ """ initiates online status check, will also decrypt files.
:param urls:
:return: initial set of data as `OnlineCheck` instance containing the result id
"""
data, crypter = self.core.pluginManager.parseUrls(urls)
- rid = self.core.threadManager.createResultThread(data, False)
-
+ # initial result does not contain the crypter links
tmp = [(url, (url, OnlineStatus(url, pluginname, "unknown", 3, 0))) for url, pluginname in data]
data = parseNames(tmp)
result = {}
@@ -382,6 +383,9 @@ class Api(Iface):
status.packagename = k
result[url] = status
+ data.update(crypter) # hoster and crypter will be processed
+ rid = self.core.threadManager.createResultThread(data, False)
+
return OnlineCheck(rid, result)
@permission(PERMS.ADD)
@@ -396,8 +400,8 @@ class Api(Iface):
th = open(join(self.core.config["general"]["download_folder"], "tmp_" + container), "wb")
th.write(str(data))
th.close()
-
- return self.checkOnlineStatus(urls + [th.name])
+ urls.append(th.name)
+ return self.checkOnlineStatus(urls)
@permission(PERMS.ADD)
def pollResults(self, rid):
@@ -436,18 +440,6 @@ class Api(Iface):
return [self.addPackage(name, urls, dest) for name, urls
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.
-
- :param links: list of urls
- :param dest: `Destination`
- :return: None
- """
- data, crypter = self.core.pluginManager.parseUrls(links)
- self.core.threadManager.createResultThread(data, True)
-
@permission(PERMS.LIST)
def getPackageData(self, pid):
@@ -677,7 +669,7 @@ class Api(Iface):
th.write(str(data))
th.close()
- self.addPackage(th.name, [th.name], Destination.Queue)
+ self.addPackage(th.name, [th.name])
@permission(PERMS.MODIFY)
def orderPackage(self, pid, position):
diff --git a/module/PyPackage.py b/module/PyPackage.py
index dce501d93..d4b468f9c 100644
--- a/module/PyPackage.py
+++ b/module/PyPackage.py
@@ -69,6 +69,13 @@ class PyPackage():
def delete(self):
self.m.deletePackage(self.id)
-
+
+ def deleteIfEmpty(self):
+ """ True if deleted """
+ if not len(self.getChildren()):
+ self.delete()
+ return True
+ return False
+
def notifyChange(self):
self.m.core.eventManager.dispatchEvent("packageUpdated", self.id)
diff --git a/module/database/FileDatabase.py b/module/database/FileDatabase.py
index abe7c8fc9..116f2b02b 100644
--- a/module/database/FileDatabase.py
+++ b/module/database/FileDatabase.py
@@ -190,8 +190,7 @@ class FileHandler:
self.ev.dispatchEvent("linkDeleted", id, pid)
p = self.getPackage(pid)
- if not len(p.getChildren()):
- p.delete()
+ p.deleteIfEmpty()
pyfiles = self.cache.values()
for pyfile in pyfiles:
diff --git a/module/plugins/Account.py b/module/plugins/Account.py
index 6b65051db..dcf36f8a0 100644
--- a/module/plugins/Account.py
+++ b/module/plugins/Account.py
@@ -48,10 +48,6 @@ class Account(Base, AccountInfo):
else:
activated = Account.activated
- for opt in self.known_opt:
- if opt not in options:
- options[opt] = ""
-
for opt in options.keys():
if opt not in self.known_opt:
del options[opt]
@@ -74,12 +70,9 @@ class Account(Base, AccountInfo):
def init(self):
pass
- #TODO: remove user, data
- def login(self, user, data, req):
+ def login(self, req):
"""login into account, the cookies will be saved so user can be recognized
- :param user: Deprecated
- :param data: Deprecated
:param req: `Request` instance
"""
raise NotImplemented
@@ -98,7 +91,13 @@ class Account(Base, AccountInfo):
self.login_ts = time()
try:
- self.login(self.loginname, {"password": self.password}, req)
+ try:
+ self.login(req)
+ except TypeError: #TODO: temporary
+ self.logDebug("Deprecated .login(...) signature ommit user, data")
+ self.login(self.loginname, {"password": self.password}, req)
+
+
self.valid = True
except WrongPassword:
self.logWarning(
@@ -117,24 +116,23 @@ class Account(Base, AccountInfo):
return self.valid
def restoreDefaults(self):
- self.valid = Account.valid
self.validuntil = Account.validuntil
self.trafficleft = Account.trafficleft
self.maxtraffic = Account.maxtraffic
self.premium = Account.premium
- self.activated = Account.activated
- def update(self, password=None, options={}):
+ def update(self, password=None, options=None):
""" updates account and return true if anything changed """
self.login_ts = 0
+ self.valid = True #set valid so it will be retried to login
if "activated" in options:
self.activated = from_string(options["avtivated"], "bool")
if password:
self.password = password
- self._login()
+ self.relogin()
return True
if options:
# remove unknown options
@@ -172,7 +170,11 @@ class Account(Base, AccountInfo):
self.checkLogin(req)
self.logDebug("Get Account Info for %s" % self.loginname)
try:
- infos = self.loadAccountInfo(self.loginname, req)
+ try:
+ infos = self.loadAccountInfo(req)
+ except TypeError: #TODO: temporary
+ self.logDebug("Deprecated .loadAccountInfo(...) signature, ommit user argument.")
+ infos = self.loadAccountInfo(self.loginname, req)
except Exception, e:
infos = {"error": str(e)}
finally:
diff --git a/module/plugins/Crypter.py b/module/plugins/Crypter.py
index fc54b32d7..7c76afee7 100644
--- a/module/plugins/Crypter.py
+++ b/module/plugins/Crypter.py
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
+from traceback import print_exc
+
from module.Api import Destination
from module.common.packagetools import parseNames
-from module.utils import to_list
-from module.utils.fs import exists
+from module.utils import to_list, has_method
+from module.utils.fs import exists, remove, fs_encode
from Base import Base, Retry
@@ -17,6 +19,12 @@ class Package:
def addUrl(self, url):
self.urls.append(url)
+ def __eq__(self, other):
+ return self.name == other.name and self.urls == other.urls
+
+ def __repr__(self):
+ return "<CrypterPackage name=%s, links=%s, dest=%s" % (self.name, self.urls, self.dest)
+
class PyFileMockup:
""" Legacy class needed by old crypter plugins """
def __init__(self, url):
@@ -49,8 +57,8 @@ class Crypter(Base):
"""Static method to decrypt, something. Can be used by other plugins.
:param core: pyLoad `Core`, needed in decrypt context
- :param url_or_urls: List of urls or urls
- :return: List of decrypted urls, all packages info removed
+ :param url_or_urls: List of urls or single url/ file content
+ :return: List of decrypted urls, all package info removed
"""
urls = to_list(url_or_urls)
p = cls(core)
@@ -66,18 +74,19 @@ class Crypter(Base):
ret.extend(url_or_pack.urls)
else: # single url
ret.append(url_or_pack)
+ # eliminate duplicates
+ return set(ret)
- return ret
-
- def __init__(self, core, pid=-1, password=None):
+ def __init__(self, core, package=None, password=None):
Base.__init__(self, core)
self.req = core.requestFactory.getRequest(self.__name__)
- # Package id plugin was initilized for, dont use this, its not guaranteed to be set
- self.pid = pid
-
+ # Package the plugin was initialized for, dont use this, its not guaranteed to be set
+ self.package = package
#: Password supplied by user
self.password = password
+ #: Propose a renaming of the owner package
+ self.rename = None
# For old style decrypter, do not use these !
self.packages = []
@@ -125,7 +134,7 @@ class Crypter(Base):
"""
return [Package(name, purls) for name, purls in parseNames([(url,url) for url in urls]).iteritems()]
- def processDecrypt(self, urls):
+ def _decrypt(self, urls):
""" Internal method to select decrypting method
:param urls: List of urls/content
@@ -136,28 +145,47 @@ class Crypter(Base):
# seperate local and remote files
content, urls = self.getLocalContent(urls)
- if hasattr(cls, "decryptURLs"):
+ if has_method(cls, "decryptURLs"):
self.setup()
result = to_list(self.decryptURLs(urls))
- elif hasattr(cls, "decryptURL"):
+ elif has_method(cls, "decryptURL"):
result = []
for url in urls:
self.setup()
result.extend(to_list(self.decryptURL(url)))
- elif hasattr(cls, "decrypt"):
+ elif has_method(cls, "decrypt"):
self.logDebug("Deprecated .decrypt() method in Crypter plugin")
- result = [] # TODO
+ self.setup()
+ self.decrypt()
+ result = self.convertPackages()
else:
- self.logError("No Decrypting method was overwritten")
+ if not has_method(cls, "decryptFile"):
+ self.logDebug("No Decrypting method was overwritten in plugin %s" % self.__name__)
result = []
- if hasattr(cls, "decryptFile"):
- for c in content:
+ if has_method(cls, "decryptFile"):
+ for f, c in content:
self.setup()
result.extend(to_list(self.decryptFile(c)))
+ try:
+ if f.startswith("tmp_"): remove(f)
+ except :
+ pass
return result
+ def processDecrypt(self, urls):
+ """ Catches all exceptions in decrypt methods and return results
+
+ :return: Decrypting results
+ """
+ try:
+ return self._decrypt(urls)
+ except Exception:
+ if self.core.debug:
+ print_exc()
+ return []
+
def getLocalContent(self, urls):
"""Load files from disk
@@ -178,9 +206,13 @@ class Crypter(Base):
path = self.core.path(url)
if path:
- f = open(path, "wb")
- content.append(f.read())
- f.close()
+ try:
+ f = open(fs_encode(path), "rb")
+ content.append((f.name, f.read()))
+ f.close()
+ except IOError, e:
+ self.logError("IOError", e)
+ remote.append(url)
else:
remote.append(url)
@@ -193,20 +225,12 @@ class Crypter(Base):
""" Retry decrypting, will only work once. Somewhat deprecated method, should be avoided. """
raise Retry()
- def createPackages(self):
+ def convertPackages(self):
""" Deprecated """
- self.logDebug("Deprecated method .createPackages()")
- for pack in self.packages:
-
- self.log.debug("Parsed package %(name)s with %(len)d links" % { "name" : pack[0], "len" : len(pack[1]) } )
-
- links = [x.decode("utf-8") for x in pack[1]]
-
- pid = self.core.api.files.addLinks(self.pid, links)
-
-
- if self.urls:
- self.core.api.generateAndAddPackages(self.urls)
+ self.logDebug("Deprecated method .convertPackages()")
+ res = [Package(name, urls) for name, urls in self.packages]
+ res.extend(self.urls)
+ return res
def clean(self):
if hasattr(self, "req"):
diff --git a/module/plugins/container/LinkList.py b/module/plugins/crypter/LinkList.py
index 614c76c90..8e46f88a9 100644
--- a/module/plugins/container/LinkList.py
+++ b/module/plugins/crypter/LinkList.py
@@ -1,25 +1,21 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-
-from module.plugins.Crypter import Crypter
+from module.plugins.Crypter import Crypter, Package
class LinkList(Crypter):
__name__ = "LinkList"
__version__ = "0.11"
__pattern__ = r".+\.txt$"
__description__ = """Read Link Lists in txt format"""
- __config__ = [("clear", "bool", "Clear Linklist after adding", False)]
__author_name__ = ("spoob", "jeix")
__author_mail__ = ("spoob@pyload.org", "jeix@hasnomail.com")
+ def decryptFile(self, content):
+ links = content.splitlines()
- def decrypt(self, pyfile):
- txt = open(pyfile.url, 'r')
- links = txt.readlines()
- curPack = "Parsed links from %s" % pyfile.name
-
- packages = {curPack:[],}
+ curPack = "default"
+ packages = {curPack:[]}
for link in links:
link = link.strip()
@@ -33,10 +29,8 @@ class LinkList(Crypter):
packages[curPack] = []
continue
packages[curPack].append(link)
- txt.close()
# empty packages fix
-
delete = []
for key,value in packages.iteritems():
@@ -46,12 +40,12 @@ class LinkList(Crypter):
for key in delete:
del packages[key]
- if self.getConfig("clear"):
- try:
- txt = open(pyfile.url, 'wb')
- txt.close()
- except:
- self.log.warning(_("LinkList could not be cleared."))
-
+ urls = []
+
for name, links in packages.iteritems():
- self.packages.append((name, links, name))
+ if name == "default":
+ urls.extend(links)
+ else:
+ urls.append(Package(name, links))
+
+ return urls \ No newline at end of file
diff --git a/module/plugins/hoster/YoutubeCom.py b/module/plugins/hoster/YoutubeCom.py
index 2b3ea7ed7..b6ea36a3c 100644
--- a/module/plugins/hoster/YoutubeCom.py
+++ b/module/plugins/hoster/YoutubeCom.py
@@ -75,10 +75,10 @@ class YoutubeCom(Hoster):
fmt_dict[fmt] = unquote(url)
self.logDebug("Found links: %s" % fmt_dict)
- for fmt in fmt_dict.keys():
+ for fmt in fmt_dict.keys():
if fmt not in self.formats:
- self.logDebug("FMT not supported: %s" % fmt)
- del fmt_dict[fmt]
+ self.logDebug("FMT not supported: %s" % fmt)
+ del fmt_dict[fmt]
allowed = lambda x: self.getConfig(self.formats[x][0])
sel = lambda x: self.formats[x][3] #select quality index
diff --git a/module/remote/thriftbackend/pyload.thrift b/module/remote/thriftbackend/pyload.thrift
index a6c0a259c..d33b468c3 100644
--- a/module/remote/thriftbackend/pyload.thrift
+++ b/module/remote/thriftbackend/pyload.thrift
@@ -177,7 +177,7 @@ struct AccountInfo {
6: i64 maxtraffic,
7: bool premium,
8: bool activated,
- 9: map<string, list<string>> options,
+ 9: map<string, string> options,
}
struct ServiceCall {
diff --git a/module/threads/BaseThread.py b/module/threads/BaseThread.py
index b5856c856..1ba3f7a9f 100644
--- a/module/threads/BaseThread.py
+++ b/module/threads/BaseThread.py
@@ -1,6 +1,10 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+import os
+import sys
+import locale
+
from threading import Thread
from time import strftime, gmtime
from sys import exc_info
@@ -14,32 +18,33 @@ class BaseThread(Thread):
"""abstract base class for thread types"""
def __init__(self, manager):
- """Constructor"""
Thread.__init__(self)
self.setDaemon(True)
self.m = manager #thread manager
self.log = manager.core.log
-
- def writeDebugReport(self, pyfile):
+ def writeDebugReport(self, name, pyfile=None, plugin=None):
""" writes a debug report to disk """
- dump_name = "debug_%s_%s.zip" % (pyfile.pluginname, strftime("%d-%m-%Y_%H-%M-%S"))
- dump = self.getDebugDump(pyfile)
+ dump_name = "debug_%s_%s.zip" % (name, strftime("%d-%m-%Y_%H-%M-%S"))
+ if pyfile:
+ dump = self.getFileDump(pyfile)
+ else:
+ dump = self.getPluginDump(plugin)
try:
import zipfile
zip = zipfile.ZipFile(dump_name, "w")
- for f in listdir(join("tmp", pyfile.pluginname)):
+ for f in listdir(join("tmp", name)):
try:
# avoid encoding errors
- zip.write(join("tmp", pyfile.pluginname, f), save_join(pyfile.pluginname, f))
+ zip.write(join("tmp", name, f), save_join(name, f))
except:
pass
- info = zipfile.ZipInfo(save_join(pyfile.pluginname, "debug_Report.txt"), gmtime())
+ info = zipfile.ZipInfo(save_join(name, "debug_Report.txt"), gmtime())
info.external_attr = 0644 << 16L # change permissions
zip.writestr(info, dump)
@@ -58,7 +63,7 @@ class BaseThread(Thread):
self.log.info("Debug Report written to %s" % dump_name)
- def getDebugDump(self, pyfile):
+ def getFileDump(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())
@@ -111,6 +116,13 @@ class BaseThread(Thread):
return dump
+ #TODO
+ def getPluginDump(self, plugin):
+ return ""
+
+ def getSystemDump(self):
+ return ""
+
def clean(self, pyfile):
""" set thread unactive and release pyfile """
self.active = False
diff --git a/module/threads/DecrypterThread.py b/module/threads/DecrypterThread.py
index 5ce59a65e..a1b7e4f38 100644
--- a/module/threads/DecrypterThread.py
+++ b/module/threads/DecrypterThread.py
@@ -1,35 +1,78 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+from time import sleep
+from traceback import print_exc
+
+from module.plugins.Base import Retry
+from module.plugins.Crypter import Package
+
from BaseThread import BaseThread
class DecrypterThread(BaseThread):
"""thread for decrypting"""
- def __init__(self, manager, data, package):
+ def __init__(self, manager, data, pid):
"""constructor"""
BaseThread.__init__(self, manager)
- self.queue = data
- self.package = package
-
- self.m.log.debug("Starting Decrypt thread")
+ self.data = data
+ self.pid = pid
self.start()
- def add(self, data):
- self.queue.extend(data)
-
def run(self):
plugin_map = {}
- for plugin, url in self.queue:
+ for url, plugin in self.data:
if plugin in plugin_map:
plugin_map[plugin].append(url)
else:
plugin_map[plugin] = [url]
-
self.decrypt(plugin_map)
def decrypt(self, plugin_map):
+ pack = self.m.core.files.getPackage(self.pid)
+ result = []
+
for name, urls in plugin_map.iteritems():
- p = self.m.core.pluginManager.loadClass("crypter", name)
+ klass = self.m.core.pluginManager.loadClass("crypter", name)
+ plugin = klass(self.m.core, pack, pack.password)
+ plugin_result = []
+
+ try:
+ try:
+ plugin_result = plugin._decrypt(urls)
+ except Retry:
+ sleep(1)
+ plugin_result = plugin._decrypt(urls)
+ except Exception, e:
+ plugin.logError(_("Decrypting failed"), e)
+ if self.m.core.debug:
+ print_exc()
+ self.writeDebugReport(plugin.__name__, plugin=plugin)
+
+ plugin.logDebug("Decrypted", plugin_result)
+ result.extend(plugin_result)
+
+ pack_names = {}
+ urls = []
+
+ for p in result:
+ if isinstance(p, Package):
+ if p.name in pack_names:
+ pack_names[p.name].urls.extend(p.urls)
+ else:
+ pack_names[p.name] = p
+ else:
+ urls.append(p)
+
+ if urls:
+ self.log.info(_("Decrypted %(count)d links into package %(name)s") % {"count": len(urls), "name": pack.name})
+ self.m.core.api.addFiles(self.pid, urls)
+
+ for p in pack_names:
+ self.m.core.api.addPackage(p.name, p.urls, p.dest, pack.password)
+
+ if not result:
+ self.log.info(_("No links decrypted"))
+
diff --git a/module/threads/DownloadThread.py b/module/threads/DownloadThread.py
index 3d444686b..638861338 100644
--- a/module/threads/DownloadThread.py
+++ b/module/threads/DownloadThread.py
@@ -156,7 +156,7 @@ class DownloadThread(BaseThread):
self.m.log.error("pycurl error %s: %s" % (code, msg))
if self.m.core.debug:
print_exc()
- self.writeDebugReport(pyfile)
+ self.writeDebugReport(pyfile.pluginname, pyfile)
self.m.core.hookManager.downloadFailed(pyfile)
@@ -186,7 +186,7 @@ class DownloadThread(BaseThread):
if self.m.core.debug:
print_exc()
- self.writeDebugReport(pyfile)
+ self.writeDebugReport(pyfile.pluginname, pyfile)
self.m.core.hookManager.downloadFailed(pyfile)
self.clean(pyfile)
diff --git a/module/threads/InfoThread.py b/module/threads/InfoThread.py
index 4cba7da38..596153c4b 100644
--- a/module/threads/InfoThread.py
+++ b/module/threads/InfoThread.py
@@ -7,11 +7,12 @@ from traceback import print_exc
from module.Api import OnlineStatus
from module.PyFile import PyFile
from module.common.packagetools import parseNames
+from module.utils import has_method
from BaseThread import BaseThread
class InfoThread(BaseThread):
- def __init__(self, manager, data, pid=-1, rid=-1, add=False):
+ def __init__(self, manager, data, pid=-1, rid=-1):
"""Constructor"""
BaseThread.__init__(self, manager)
@@ -20,7 +21,6 @@ class InfoThread(BaseThread):
# [ .. (name, plugin) .. ]
self.rid = rid #result id
- self.add = add #add packages instead of return result
self.cache = [] #accumulated data
@@ -39,8 +39,8 @@ class InfoThread(BaseThread):
plugins[plugin] = [url]
- # filter out container plugins
- for name in self.m.core.pluginManager.getPlugins("container"):
+ # filter out crypter plugins
+ for name in self.m.core.pluginManager.getPlugins("crypter"):
if name in plugins:
container.extend([(name, url) for url in plugins[name]])
@@ -50,35 +50,17 @@ class InfoThread(BaseThread):
if self.pid > -1:
for pluginname, urls in plugins.iteritems():
plugin = self.m.core.pluginManager.getPlugin(pluginname, True)
- if hasattr(plugin, "getInfo"):
+ klass = getattr(plugin, pluginname)
+ if has_method(klass, "getInfo"):
+ self.fetchForPlugin(pluginname, klass, urls, self.updateDB)
+ self.m.core.files.save()
+ elif has_method(plugin, "getInfo"):
+ self.log.debug("Deprecated .getInfo() method on module level, use classmethod instead")
self.fetchForPlugin(pluginname, plugin, urls, self.updateDB)
self.m.core.files.save()
- elif self.add:
- for pluginname, urls in plugins.iteritems():
- plugin = self.m.core.pluginManager.getPlugin(pluginname, True)
- if hasattr(plugin, "getInfo"):
- self.fetchForPlugin(pluginname, plugin, urls, self.updateCache, True)
-
- else:
- #generate default result
- result = [(url, 0, 3, url) for url in urls]
-
- self.updateCache(pluginname, result)
-
- packs = parseNames([(name, url) for name, x, y, url in self.cache])
-
- self.m.log.debug("Fetched and generated %d packages" % len(packs))
-
- for k, v in packs:
- self.m.core.api.addPackage(k, v)
-
- #empty cache
- del self.cache[:]
-
else: #post the results
-
-
+ #TODO: finer crypter control
for name, url in container:
#attach container content
try:
@@ -98,13 +80,18 @@ class InfoThread(BaseThread):
for pluginname, urls in plugins.iteritems():
plugin = self.m.core.pluginManager.getPlugin(pluginname, True)
- if hasattr(plugin, "getInfo"):
+ klass = getattr(plugin, pluginname)
+ if has_method(klass, "getInfo"):
+ self.fetchForPlugin(pluginname, plugin, urls, self.updateResult, True)
+ #force to process cache
+ if self.cache:
+ self.updateResult(pluginname, [], True)
+ elif has_method(plugin, "getInfo"):
+ self.log.debug("Deprecated .getInfo() method on module level, use staticmethod instead")
self.fetchForPlugin(pluginname, plugin, urls, self.updateResult, True)
-
#force to process cache
if self.cache:
self.updateResult(pluginname, [], True)
-
else:
#generate default result
result = [(url, 0, 3, url) for url in urls]
diff --git a/module/threads/ThreadManager.py b/module/threads/ThreadManager.py
index c32286eb9..612da2536 100644
--- a/module/threads/ThreadManager.py
+++ b/module/threads/ThreadManager.py
@@ -71,7 +71,7 @@ class ThreadManager:
pycurl.global_init(pycurl.GLOBAL_DEFAULT)
- for i in range(0, self.core.config.get("download", "max_downloads")):
+ for i in range(self.core.config.get("download", "max_downloads")):
self.createThread()
@@ -84,25 +84,24 @@ class ThreadManager:
def createInfoThread(self, data, pid):
""" start a thread whichs fetches online status and other infos """
self.timestamp = time() + 5 * 60
-
- InfoThread(self, data, pid)
+ if data: InfoThread(self, data, pid)
@lock
- def createResultThread(self, data, add=False):
+ def createResultThread(self, data):
""" creates a thread to fetch online status, returns result id """
self.timestamp = time() + 5 * 60
rid = self.resultIDs
self.resultIDs += 1
- InfoThread(self, data, rid=rid, add=add)
+ InfoThread(self, data, rid=rid)
return rid
@lock
def createDecryptThread(self, data, pid):
""" Start decrypting of entered data, all links in one package are accumulated to one thread."""
- DecrypterThread(self, data, pid)
+ if data: DecrypterThread(self, data, pid)
@lock
diff --git a/module/utils/__init__.py b/module/utils/__init__.py
index 0d68448cb..a237fde9b 100644
--- a/module/utils/__init__.py
+++ b/module/utils/__init__.py
@@ -157,6 +157,10 @@ def fixup(m):
return text # leave as is
+def has_method(obj, name):
+ """ checks if 'name' was defined in obj, (false if it was inhereted) """
+ return name in obj.__dict__
+
def html_unescape(text):
"""Removes HTML or XML character references and entities from a text string"""
return re.sub("&#?\w+;", fixup, text)
diff --git a/module/utils/fs.py b/module/utils/fs.py
index 23f87a326..037165b6b 100644
--- a/module/utils/fs.py
+++ b/module/utils/fs.py
@@ -20,7 +20,10 @@ else:
# FS utilities
def chmod(path, mode):
- return os.chmod(fs_encode(path), mode)
+ try:
+ return os.chmod(fs_encode(path), mode)
+ except :
+ pass
def chown(path, uid, gid):
return os.chown(fs_encode(path), uid, gid)
diff --git a/module/web/templates/default/base.html b/module/web/templates/default/base.html
index 0b20ecdb0..1f77c04ba 100644
--- a/module/web/templates/default/base.html
+++ b/module/web/templates/default/base.html
@@ -162,7 +162,7 @@
<hr style="clear: both;" />
-<div id="foot">&copy; 2008-2011 pyLoad Team
+<div id="foot">&copy; 2008-2012 pyLoad Team
<a href="#top" class="action top" accesskey="x"><span>{{_("Back to top")}}</span></a><br />
<!--<div class="breadcrumbs"></div>-->