summaryrefslogtreecommitdiffstats
path: root/module/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'module/plugins')
-rw-r--r--module/plugins/AccountManager.py11
-rw-r--r--module/plugins/Hook.py16
-rw-r--r--module/plugins/Plugin.py33
-rw-r--r--module/plugins/PluginManager.py8
-rw-r--r--module/plugins/accounts/EuroshareEu.py1
-rw-r--r--module/plugins/accounts/FreeWayMe.py2
-rw-r--r--module/plugins/accounts/FshareVn.py1
-rw-r--r--module/plugins/accounts/OneFichierCom.py2
-rw-r--r--module/plugins/accounts/PremiumizeMe.py1
-rw-r--r--module/plugins/accounts/RPNetBiz.py1
-rw-r--r--module/plugins/accounts/ShareonlineBiz.py1
-rw-r--r--module/plugins/accounts/UploadedTo.py2
-rw-r--r--module/plugins/accounts/ZeveraCom.py1
-rw-r--r--module/plugins/captcha/GigasizeCom.py1
-rw-r--r--module/plugins/captcha/LinksaveIn.py5
-rw-r--r--module/plugins/captcha/NetloadIn.py1
-rw-r--r--module/plugins/captcha/ShareonlineBiz.py1
-rw-r--r--module/plugins/captcha/captcha.py12
-rw-r--r--module/plugins/container/CCF.py1
-rw-r--r--module/plugins/crypter/DDLMusicOrg.py1
-rw-r--r--module/plugins/crypter/DailymotionBatch.py6
-rw-r--r--module/plugins/crypter/DuckCryptInfo.py2
-rw-r--r--module/plugins/crypter/EmbeduploadCom.py1
-rw-r--r--module/plugins/crypter/HoerbuchIn.py1
-rw-r--r--module/plugins/crypter/LinkdecrypterCom.py5
-rw-r--r--module/plugins/crypter/NCryptIn.py6
-rw-r--r--module/plugins/crypter/NetfolderIn.py3
-rw-r--r--module/plugins/crypter/OneKhDe.py2
-rw-r--r--module/plugins/crypter/TurbobitNetFolder.py1
-rw-r--r--module/plugins/crypter/YoutubeBatch.py7
-rw-r--r--module/plugins/hooks/BypassCaptcha.py10
-rwxr-xr-xmodule/plugins/hooks/Captcha9kw.py5
-rw-r--r--module/plugins/hooks/CaptchaBrotherhood.py9
-rw-r--r--module/plugins/hooks/Checksum.py4
-rw-r--r--module/plugins/hooks/DeathByCaptcha.py12
-rw-r--r--module/plugins/hooks/DownloadScheduler.py3
-rw-r--r--module/plugins/hooks/ExpertDecoders.py4
-rw-r--r--module/plugins/hooks/ExtractArchive.py2
-rw-r--r--module/plugins/hooks/HotFolder.py1
-rw-r--r--module/plugins/hooks/IRCInterface.py24
-rw-r--r--module/plugins/hooks/ImageTyperz.py8
-rw-r--r--module/plugins/hooks/LinkdecrypterCom.py1
-rw-r--r--module/plugins/hooks/MergeFiles.py1
-rw-r--r--module/plugins/hooks/MultiHome.py8
-rw-r--r--module/plugins/hooks/PremiumTo.py1
-rw-r--r--module/plugins/hooks/PremiumizeMe.py1
-rw-r--r--module/plugins/hooks/RPNetBiz.py1
-rw-r--r--module/plugins/hooks/RehostTo.py1
-rw-r--r--module/plugins/hooks/RestartFailed.py3
-rw-r--r--module/plugins/hooks/UnSkipOnFail.py2
-rw-r--r--module/plugins/hooks/UpdateManager.py12
-rw-r--r--module/plugins/hooks/WindowsPhoneToastNotify.py3
-rw-r--r--module/plugins/hooks/XMPPInterface.py20
-rw-r--r--module/plugins/hoster/AlldebridCom.py2
-rw-r--r--module/plugins/hoster/BayfilesCom.py2
-rw-r--r--module/plugins/hoster/BezvadataCz.py3
-rw-r--r--module/plugins/hoster/CzshareCom.py3
-rw-r--r--module/plugins/hoster/DailymotionCom.py5
-rw-r--r--module/plugins/hoster/DateiTo.py2
-rw-r--r--module/plugins/hoster/DebridItaliaCom.py1
-rw-r--r--module/plugins/hoster/DepositfilesCom.py1
-rw-r--r--module/plugins/hoster/DlFreeFr.py1
-rw-r--r--module/plugins/hoster/EdiskCz.py1
-rw-r--r--module/plugins/hoster/EuroshareEu.py2
-rw-r--r--module/plugins/hoster/FastixRu.py2
-rw-r--r--module/plugins/hoster/FastshareCz.py1
-rw-r--r--module/plugins/hoster/FileStoreTo.py1
-rw-r--r--module/plugins/hoster/FilecloudIo.py2
-rw-r--r--module/plugins/hoster/FilefactoryCom.py1
-rw-r--r--module/plugins/hoster/FilepostCom.py1
-rw-r--r--module/plugins/hoster/FilesMailRu.py5
-rw-r--r--module/plugins/hoster/FileserveCom.py6
-rw-r--r--module/plugins/hoster/FreakshareCom.py9
-rw-r--r--module/plugins/hoster/FreeWayMe.py1
-rw-r--r--module/plugins/hoster/FshareVn.py4
-rw-r--r--module/plugins/hoster/GamefrontCom.py4
-rw-r--r--module/plugins/hoster/GigapetaCom.py1
-rw-r--r--module/plugins/hoster/GooIm.py1
-rw-r--r--module/plugins/hoster/HellshareCz.py1
-rw-r--r--module/plugins/hoster/IfolderRu.py1
-rw-r--r--module/plugins/hoster/JumbofilesCom.py1
-rw-r--r--module/plugins/hoster/LetitbitNet.py4
-rw-r--r--module/plugins/hoster/LinksnappyCom.py2
-rw-r--r--module/plugins/hoster/LuckyShareNet.py1
-rw-r--r--module/plugins/hoster/MediafireCom.py3
-rw-r--r--module/plugins/hoster/MegaDebridEu.py4
-rw-r--r--module/plugins/hoster/MegaRapidCz.py1
-rw-r--r--module/plugins/hoster/MegacrypterCom.py1
-rw-r--r--module/plugins/hoster/MultishareCz.py4
-rw-r--r--module/plugins/hoster/MyfastfileCom.py1
-rw-r--r--module/plugins/hoster/MyvideoDe.py4
-rw-r--r--module/plugins/hoster/NetloadIn.py8
-rw-r--r--module/plugins/hoster/NowDownloadEu.py1
-rw-r--r--module/plugins/hoster/OverLoadMe.py2
-rw-r--r--module/plugins/hoster/PornhostCom.py4
-rw-r--r--module/plugins/hoster/PornhubCom.py4
-rw-r--r--module/plugins/hoster/PremiumTo.py2
-rw-r--r--module/plugins/hoster/QuickshareCz.py2
-rw-r--r--module/plugins/hoster/RPNetBiz.py1
-rw-r--r--module/plugins/hoster/RapidshareCom.py7
-rw-r--r--module/plugins/hoster/RealdebridCom.py2
-rw-r--r--module/plugins/hoster/RedtubeCom.py4
-rw-r--r--module/plugins/hoster/RehostTo.py2
-rw-r--r--module/plugins/hoster/RemixshareCom.py1
-rw-r--r--module/plugins/hoster/ShareplaceCom.py6
-rw-r--r--module/plugins/hoster/SimplyPremiumCom.py1
-rw-r--r--module/plugins/hoster/SimplydebridCom.py1
-rw-r--r--module/plugins/hoster/StreamCz.py2
-rw-r--r--module/plugins/hoster/TwoSharedCom.py1
-rw-r--r--module/plugins/hoster/UlozTo.py5
-rw-r--r--module/plugins/hoster/UloziskoSk.py1
-rw-r--r--module/plugins/hoster/UnrestrictLi.py2
-rw-r--r--module/plugins/hoster/UploadedTo.py3
-rw-r--r--module/plugins/hoster/UploadheroCom.py2
-rw-r--r--module/plugins/hoster/VeehdCom.py6
-rw-r--r--module/plugins/hoster/VeohCom.py1
-rw-r--r--module/plugins/hoster/VimeoCom.py1
-rw-r--r--module/plugins/hoster/WebshareCz.py1
-rw-r--r--module/plugins/hoster/WrzucTo.py1
-rw-r--r--module/plugins/hoster/XHamsterCom.py4
-rw-r--r--module/plugins/hoster/Xdcc.py2
-rw-r--r--module/plugins/hoster/YoupornCom.py4
-rw-r--r--module/plugins/hoster/YourfilesTo.py6
-rw-r--r--module/plugins/hoster/YoutubeCom.py2
-rw-r--r--module/plugins/hoster/ZDF.py3
-rw-r--r--module/plugins/hoster/ZeveraCom.py1
-rw-r--r--module/plugins/internal/AbstractExtractor.py8
-rw-r--r--module/plugins/internal/MultiHoster.py11
-rw-r--r--module/plugins/internal/SimpleCrypter.py1
-rw-r--r--module/plugins/internal/UnZip.py3
130 files changed, 464 insertions, 17 deletions
diff --git a/module/plugins/AccountManager.py b/module/plugins/AccountManager.py
index 4b8063002..b039b5827 100644
--- a/module/plugins/AccountManager.py
+++ b/module/plugins/AccountManager.py
@@ -14,6 +14,7 @@ ACC_VERSION = 1
class AccountManager():
"""manages all accounts"""
+
#----------------------------------------------------------------------
def __init__(self, core):
"""Constructor"""
@@ -24,6 +25,7 @@ class AccountManager():
self.initPlugins()
self.saveAccounts() # save to add categories to conf
+
def initPlugins(self):
self.accounts = {} # key = ( plugin )
self.plugins = {}
@@ -31,6 +33,7 @@ class AccountManager():
self.initAccountPlugins()
self.loadAccounts()
+
def getAccountPlugin(self, plugin):
"""get account instance for plugin or None if anonymous"""
if plugin in self.accounts:
@@ -41,6 +44,7 @@ class AccountManager():
else:
return None
+
def getAccountPlugins(self):
""" get all account instances"""
@@ -50,6 +54,7 @@ class AccountManager():
return plugins
+
#----------------------------------------------------------------------
def loadAccounts(self):
"""loads all accounts available"""
@@ -97,6 +102,7 @@ class AccountManager():
name, sep, pw = line.partition(":")
self.accounts[plugin][name] = {"password": pw, "options": {}, "valid": True}
+
#----------------------------------------------------------------------
def saveAccounts(self):
"""save all account information"""
@@ -117,12 +123,14 @@ class AccountManager():
f.close()
chmod(f.name, 0600)
+
#----------------------------------------------------------------------
def initAccountPlugins(self):
"""init names"""
for name in self.core.pluginManager.getAccountPlugins():
self.accounts[name] = {}
+
@lock
def updateAccount(self, plugin , user, password=None, options={}):
"""add or update account"""
@@ -134,6 +142,7 @@ class AccountManager():
self.saveAccounts()
if updated: p.scheduleRefresh(user, force=False)
+
@lock
def removeAccount(self, plugin, user):
"""remove account"""
@@ -144,6 +153,7 @@ class AccountManager():
self.saveAccounts()
+
@lock
def getAccountInfos(self, force=True, refresh=False):
data = {}
@@ -162,6 +172,7 @@ class AccountManager():
self.core.pullManager.addEvent(e)
return data
+
def sendChange(self):
e = AccountUpdateEvent()
self.core.pullManager.addEvent(e)
diff --git a/module/plugins/Hook.py b/module/plugins/Hook.py
index 1e4749cd5..4d43b70f7 100644
--- a/module/plugins/Hook.py
+++ b/module/plugins/Hook.py
@@ -81,10 +81,12 @@ class Hook(Base):
self.initPeriodical()
self.setup()
+
def initPeriodical(self):
if self.interval >=1:
self.cb = self.core.scheduler.addJob(0, self._periodical, threaded=False)
+
def _periodical(self):
try:
if self.isActivated(): self.periodical()
@@ -99,14 +101,17 @@ class Hook(Base):
def __repr__(self):
return "<Hook %s>" % self.__name__
+
def setup(self):
""" more init stuff if needed """
pass
+
def unload(self):
""" called when hook was deactivated """
pass
+
def isActivated(self):
""" checks if hook is activated"""
return self.config.getPlugin(self.__name__, "activated")
@@ -116,36 +121,47 @@ class Hook(Base):
def coreReady(self):
pass
+
def coreExiting(self):
pass
+
def downloadPreparing(self, pyfile):
pass
+
def downloadFinished(self, pyfile):
pass
+
def downloadFailed(self, pyfile):
pass
+
def packageFinished(self, pypack):
pass
+
def beforeReconnecting(self, ip):
pass
+
def afterReconnecting(self, ip):
pass
+
def periodical(self):
pass
+
def newCaptchaTask(self, task):
""" new captcha task for the plugin, it MUST set the handler and timeout or will be ignored """
pass
+
def captchaCorrect(self, task):
pass
+
def captchaInvalid(self, task):
pass
diff --git a/module/plugins/Plugin.py b/module/plugins/Plugin.py
index 0a4b6d44d..be26a8960 100644
--- a/module/plugins/Plugin.py
+++ b/module/plugins/Plugin.py
@@ -51,6 +51,7 @@ class Base(object):
A Base class with log/config/db methods *all* plugin types can use
"""
+
def __init__(self, core):
#: Core instance
self.core = core
@@ -59,19 +60,24 @@ class Base(object):
#: core config
self.config = core.config
+
#log functions
def logDebug(self, *args):
self.log.debug("%s: %s" % (self.__name__, " | ".join([a if isinstance(a, basestring) else str(a) for a in args if a])))
+
def logInfo(self, *args):
self.log.info("%s: %s" % (self.__name__, " | ".join([a if isinstance(a, basestring) else str(a) for a in args if a])))
+
def logWarning(self, *args):
self.log.warning("%s: %s" % (self.__name__, " | ".join([a if isinstance(a, basestring) else str(a) for a in args if a])))
+
def logError(self, *args):
self.log.error("%s: %s" % (self.__name__, " | ".join([a if isinstance(a, basestring) else str(a) for a in args if a])))
+
def logCritical(self, *args):
self.log.critical("%s: %s" % (self.__name__, " | ".join([a if isinstance(a, basestring) else str(a) for a in args if a])))
@@ -80,6 +86,7 @@ class Base(object):
""" see `setConfig` """
self.core.config.setPlugin(self.__name__, option, value)
+
def setConfig(self, option, value):
""" Set config value for current plugin
@@ -89,10 +96,12 @@ class Base(object):
"""
self.setConf(option, value)
+
def getConf(self, option):
""" see `getConfig` """
return self.core.config.getPlugin(self.__name__, option)
+
def getConfig(self, option):
""" Returns config value for current plugin
@@ -101,24 +110,29 @@ class Base(object):
"""
return self.getConf(option)
+
def setStorage(self, key, value):
""" Saves a value persistently to the database """
self.core.db.setStorage(self.__name__, key, value)
+
def store(self, key, value):
""" same as `setStorage` """
self.core.db.setStorage(self.__name__, key, value)
+
def getStorage(self, key=None, default=None):
""" Retrieves saved value or dict of all saved entries if key is None """
if key is not None:
return self.core.db.getStorage(self.__name__, key) or default
return self.core.db.getStorage(self.__name__, 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.__name__, key)
@@ -198,22 +212,27 @@ class Plugin(Base):
self.init()
+
def getChunkCount(self):
if self.chunkLimit <= 0:
return self.config['download']['chunks']
return min(self.config['download']['chunks'], self.chunkLimit)
+
def __call__(self):
return self.__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
@@ -234,12 +253,14 @@ class Plugin(Base):
"""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.__name__)
self.retry()
+
def checksum(self, local_file=None):
"""
return codes:
@@ -264,6 +285,7 @@ class Plugin(Base):
self.wantReconnect = True
self.pyfile.waitUntil = time() + int(seconds)
+
def wait(self):
""" waits the time previously set """
self.waiting = True
@@ -281,23 +303,28 @@ class Plugin(Base):
self.waiting = False
self.pyfile.setStatus("starting")
+
def fail(self, reason):
""" fail and give reason """
raise Fail(reason)
+
def error(self, reason=None, type="parse"):
raise Fail("%s error%s | Plugin out of date" % (type.capitalize(), ': ' + str(reason) if reason else ""))
if self.core.debug:
print_exc()
+
def offline(self):
""" fail and indicate file is offline """
raise Fail("offline")
+
def tempOffline(self):
""" fail and indicates file ist temporary offline, the core may take consequences """
raise Fail("temp. offline")
+
def retry(self, max_tries=3, wait_time=1, reason=""):
"""Retries and begin again from the beginning
@@ -316,14 +343,17 @@ class Plugin(Base):
self.retries += 1
raise Retry(reason)
+
def invalidCaptcha(self):
if self.cTask:
self.cTask.invalid()
+
def correctCaptcha(self):
if self.cTask:
self.cTask.correct()
+
def decryptCaptcha(self, url, get={}, post={}, cookies=False, forceUser=False, imgtype='jpg',
result_type='textual'):
""" Loads a captcha and decrypts it with ocr, plugin, user input
@@ -455,6 +485,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
@@ -525,6 +556,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`
@@ -603,6 +635,7 @@ class Plugin(Base):
self.log.debug("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/module/plugins/PluginManager.py b/module/plugins/PluginManager.py
index e263f8e04..034e40d4a 100644
--- a/module/plugins/PluginManager.py
+++ b/module/plugins/PluginManager.py
@@ -60,6 +60,7 @@ class PluginManager:
self.log.debug("created index of plugins")
+
def parse(self, folder, pattern=False, home={}):
"""
returns dict with information
@@ -211,12 +212,14 @@ class PluginManager:
return res
+
def findPlugin(self, name, pluginlist=("hoster", "crypter", "container")):
for ptype in pluginlist:
if name in self.plugins[ptype]:
return self.plugins[ptype][name], ptype
return None, None
+
def getPlugin(self, name, original=False):
"""return plugin module from hoster|decrypter|container"""
plugin, type = self.findPlugin(name)
@@ -230,6 +233,7 @@ class PluginManager:
return self.loadModule(type, name)
+
def getPluginName(self, name):
""" used to obtain new name if other plugin was injected"""
plugin, type = self.findPlugin(name)
@@ -239,6 +243,7 @@ class PluginManager:
return name
+
def loadModule(self, type, name):
""" Returns loaded module for plugin
@@ -258,15 +263,18 @@ class PluginManager:
if self.core.debug:
print_exc()
+
def loadClass(self, type, name):
"""Returns the class of a plugin with the same name"""
module = self.loadModule(type, name)
if module: return getattr(module, name)
+
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
diff --git a/module/plugins/accounts/EuroshareEu.py b/module/plugins/accounts/EuroshareEu.py
index bb2f0c8e2..e08cc7e45 100644
--- a/module/plugins/accounts/EuroshareEu.py
+++ b/module/plugins/accounts/EuroshareEu.py
@@ -31,7 +31,6 @@ class EuroshareEu(Account):
def login(self, user, data, req):
-
html = req.load('http://euroshare.eu/customer-zone/login/', post={
"trvale": "1",
"login": user,
diff --git a/module/plugins/accounts/FreeWayMe.py b/module/plugins/accounts/FreeWayMe.py
index 12c24329c..797748c93 100644
--- a/module/plugins/accounts/FreeWayMe.py
+++ b/module/plugins/accounts/FreeWayMe.py
@@ -32,6 +32,7 @@ class FreeWayMe(Account):
return account_info
+
def getpw(self, user):
return self.accounts[user]['password']
@@ -43,6 +44,7 @@ class FreeWayMe(Account):
if not status:
self.wrongPassword()
+
def getAccountStatus(self, user, req):
answer = req.load("https://www.free-way.me/ajax/jd.php",
get={"id": 4, "user": user, "pass": self.accounts[user]['password']})
diff --git a/module/plugins/accounts/FshareVn.py b/module/plugins/accounts/FshareVn.py
index 45ee5a749..9e513d6f6 100644
--- a/module/plugins/accounts/FshareVn.py
+++ b/module/plugins/accounts/FshareVn.py
@@ -57,6 +57,7 @@ class FshareVn(Account):
if not re.search(r'<img\s+alt="VIP"', html):
self.wrongPassword()
+
def getTrafficLeft(self):
m = re.search(self.TRAFFIC_LEFT_PATTERN, html)
return float(m.group(1)) * 1024 ** {'k': 0, 'K': 0, 'M': 1, 'G': 2}[m.group(2)] if m else 0
diff --git a/module/plugins/accounts/OneFichierCom.py b/module/plugins/accounts/OneFichierCom.py
index 8e8430f61..71fa550b6 100644
--- a/module/plugins/accounts/OneFichierCom.py
+++ b/module/plugins/accounts/OneFichierCom.py
@@ -21,7 +21,6 @@ class OneFichierCom(Account):
def loadAccountInfo(self, user, req):
-
html = req.load("http://1fichier.com/console/abo.pl")
m = re.search(self.VALID_UNTIL_PATTERN, html)
@@ -38,7 +37,6 @@ class OneFichierCom(Account):
def login(self, user, data, req):
-
req.http.c.setopt(REFERER, "http://1fichier.com/login.pl?lg=en")
html = req.load("http://1fichier.com/login.pl?lg=en", post={
diff --git a/module/plugins/accounts/PremiumizeMe.py b/module/plugins/accounts/PremiumizeMe.py
index e65b9ec4b..4a789bfdf 100644
--- a/module/plugins/accounts/PremiumizeMe.py
+++ b/module/plugins/accounts/PremiumizeMe.py
@@ -38,6 +38,7 @@ class PremiumizeMe(Account):
if status['status'] != 200:
self.wrongPassword()
+
def getAccountStatus(self, user, req):
# Use premiumize.me API v1 (see https://secure.premiumize.me/?show=api)
# to retrieve account info and return the parsed json answer
diff --git a/module/plugins/accounts/RPNetBiz.py b/module/plugins/accounts/RPNetBiz.py
index e4b873824..59349bd7a 100644
--- a/module/plugins/accounts/RPNetBiz.py
+++ b/module/plugins/accounts/RPNetBiz.py
@@ -40,6 +40,7 @@ class RPNetBiz(Account):
if 'error' in response:
self.wrongPassword()
+
def getAccountStatus(self, user, req):
# Using the rpnet API, check if valid premium account
response = req.load("https://premium.rpnet.biz/client_api.php",
diff --git a/module/plugins/accounts/ShareonlineBiz.py b/module/plugins/accounts/ShareonlineBiz.py
index 76c564032..c00e4769d 100644
--- a/module/plugins/accounts/ShareonlineBiz.py
+++ b/module/plugins/accounts/ShareonlineBiz.py
@@ -18,6 +18,7 @@ class ShareonlineBiz(Account):
return req.load("http://api.share-online.biz/account.php",
{"username": user, "password": self.accounts[user]['password'], "act": "userDetails"})
+
def loadAccountInfo(self, user, req):
src = self.getUserAPI(user, req)
diff --git a/module/plugins/accounts/UploadedTo.py b/module/plugins/accounts/UploadedTo.py
index 437730a3f..147962838 100644
--- a/module/plugins/accounts/UploadedTo.py
+++ b/module/plugins/accounts/UploadedTo.py
@@ -17,7 +17,6 @@ class UploadedTo(Account):
def loadAccountInfo(self, user, req):
-
req.load("http://uploaded.net/language/en")
html = req.load("http://uploaded.net/me")
@@ -44,7 +43,6 @@ class UploadedTo(Account):
def login(self, user, data, req):
-
req.load("http://uploaded.net/language/en")
req.cj.setCookie("uploaded.net", "lang", "en")
diff --git a/module/plugins/accounts/ZeveraCom.py b/module/plugins/accounts/ZeveraCom.py
index 7e4fb0ab8..8ee8610ba 100644
--- a/module/plugins/accounts/ZeveraCom.py
+++ b/module/plugins/accounts/ZeveraCom.py
@@ -34,6 +34,7 @@ class ZeveraCom(Account):
if self.getAPIData(req) == "No traffic":
self.wrongPassword()
+
def getAPIData(self, req, just_header=False, **kwargs):
get_data = {
'cmd': 'accountinfo',
diff --git a/module/plugins/captcha/GigasizeCom.py b/module/plugins/captcha/GigasizeCom.py
index 8fe67c0d0..d7fe25ab7 100644
--- a/module/plugins/captcha/GigasizeCom.py
+++ b/module/plugins/captcha/GigasizeCom.py
@@ -16,6 +16,7 @@ class GigasizeCom(OCR):
def __init__(self):
OCR.__init__(self)
+
def get_captcha(self, image):
self.load_image(image)
self.threshold(2.8)
diff --git a/module/plugins/captcha/LinksaveIn.py b/module/plugins/captcha/LinksaveIn.py
index e8487c387..6535dd11f 100644
--- a/module/plugins/captcha/LinksaveIn.py
+++ b/module/plugins/captcha/LinksaveIn.py
@@ -26,6 +26,7 @@ class LinksaveIn(OCR):
OCR.__init__(self)
self.data_dir = dirname(abspath(__file__)) + sep + "LinksaveIn" + sep
+
def load_image(self, image):
im = Image.open(image)
frame_nr = 0
@@ -53,6 +54,7 @@ class LinksaveIn(OCR):
self.pixels = self.image.load()
self.result_captcha = ''
+
def get_bg(self):
stat = {}
cstat = {}
@@ -89,6 +91,7 @@ class LinksaveIn(OCR):
max_p = value
return bg
+
def substract_bg(self, bgpath):
bg = Image.open(bgpath)
img = self.image.convert("P")
@@ -111,6 +114,7 @@ class LinksaveIn(OCR):
if rgb_c == rgb_bg:
orgpix[x, y] = (255,255,255)
+
def eval_black_white(self):
new = Image.new("RGB", (140, 75))
pix = new.load()
@@ -132,6 +136,7 @@ class LinksaveIn(OCR):
self.image = new
self.pixels = self.image.load()
+
def get_captcha(self, image):
self.load_image(image)
bg = self.get_bg()
diff --git a/module/plugins/captcha/NetloadIn.py b/module/plugins/captcha/NetloadIn.py
index 514cb259f..a8a05b210 100644
--- a/module/plugins/captcha/NetloadIn.py
+++ b/module/plugins/captcha/NetloadIn.py
@@ -16,6 +16,7 @@ class NetloadIn(OCR):
def __init__(self):
OCR.__init__(self)
+
def get_captcha(self, image):
self.load_image(image)
self.to_greyscale()
diff --git a/module/plugins/captcha/ShareonlineBiz.py b/module/plugins/captcha/ShareonlineBiz.py
index 7435710d5..41caa3697 100644
--- a/module/plugins/captcha/ShareonlineBiz.py
+++ b/module/plugins/captcha/ShareonlineBiz.py
@@ -16,6 +16,7 @@ class ShareonlineBiz(OCR):
def __init__(self):
OCR.__init__(self)
+
def get_captcha(self, image):
self.load_image(image)
self.to_greyscale()
diff --git a/module/plugins/captcha/captcha.py b/module/plugins/captcha/captcha.py
index fb85d8996..dda6fed02 100644
--- a/module/plugins/captcha/captcha.py
+++ b/module/plugins/captcha/captcha.py
@@ -28,18 +28,22 @@ class OCR(object):
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 unload(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"""
@@ -50,6 +54,7 @@ class OCR(object):
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):
#tmpTif = tempfile.NamedTemporaryFile(suffix=".tif")
tmpTif = open(join("tmp", "tmpTif_%s.tif" % self.__name__), "wb")
@@ -103,15 +108,18 @@ class OCR(object):
except:
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
@@ -122,6 +130,7 @@ class OCR(object):
else:
self.pixels[x, y] = 0
+
def clean(self, allowed):
pixels = self.pixels
@@ -167,6 +176,7 @@ class OCR(object):
self.pixels = pixels
+
def derotate_by_average(self):
"""rotate by checking each angle and guess most suitable"""
@@ -241,6 +251,7 @@ class OCR(object):
self.pixels = pixels
+
def split_captcha_letters(self):
captcha = self.image
started = False
@@ -280,6 +291,7 @@ class OCR(object):
return letters
+
def correct(self, values, var=None):
if var:
result = var
diff --git a/module/plugins/container/CCF.py b/module/plugins/container/CCF.py
index 7a90ddf1c..4d62be553 100644
--- a/module/plugins/container/CCF.py
+++ b/module/plugins/container/CCF.py
@@ -24,7 +24,6 @@ class CCF(Container):
def decrypt(self, pyfile):
-
infile = pyfile.url.replace("\n", "")
opener = build_opener(MultipartPostHandler)
diff --git a/module/plugins/crypter/DDLMusicOrg.py b/module/plugins/crypter/DDLMusicOrg.py
index a78794b6d..bd5560ed1 100644
--- a/module/plugins/crypter/DDLMusicOrg.py
+++ b/module/plugins/crypter/DDLMusicOrg.py
@@ -22,6 +22,7 @@ class DDLMusicOrg(Crypter):
def setup(self):
self.multiDL = False
+
def decrypt(self, pyfile):
html = self.load(pyfile.url, cookies=True)
diff --git a/module/plugins/crypter/DailymotionBatch.py b/module/plugins/crypter/DailymotionBatch.py
index a0ed0e80f..5d2f53b38 100644
--- a/module/plugins/crypter/DailymotionBatch.py
+++ b/module/plugins/crypter/DailymotionBatch.py
@@ -26,6 +26,7 @@ class DailymotionBatch(Crypter):
page = self.load(url, get=req)
return json_loads(page)
+
def getPlaylistInfo(self, id):
ref = "playlist/" + id
req = {"fields": "name,owner.screenname"}
@@ -38,6 +39,7 @@ class DailymotionBatch(Crypter):
owner = playlist['owner.screenname']
return name, owner
+
def _getPlaylists(self, user_id, page=1):
ref = "user/%s/playlists" % user_id
req = {"fields": "id", "page": page, "limit": 100}
@@ -53,9 +55,11 @@ class DailymotionBatch(Crypter):
for item in self._getPlaylists(user_id, page + 1):
yield item
+
def getPlaylists(self, user_id):
return [(id,) + self.getPlaylistInfo(id) for id in self._getPlaylists(user_id)]
+
def _getVideos(self, id, page=1):
ref = "playlist/%s/videos" % id
req = {"fields": "url", "page": page, "limit": 100}
@@ -71,9 +75,11 @@ class DailymotionBatch(Crypter):
for item in self._getVideos(id, page + 1):
yield item
+
def getVideos(self, playlist_id):
return list(self._getVideos(playlist_id))[::-1]
+
def decrypt(self, pyfile):
m = re.match(self.__pattern__, pyfile.url)
m_id = m.group("ID")
diff --git a/module/plugins/crypter/DuckCryptInfo.py b/module/plugins/crypter/DuckCryptInfo.py
index 29eeb4453..737ed59ec 100644
--- a/module/plugins/crypter/DuckCryptInfo.py
+++ b/module/plugins/crypter/DuckCryptInfo.py
@@ -33,6 +33,7 @@ class DuckCryptInfo(Crypter):
else:
self.handleFolder(m)
+
def handleFolder(self, m):
src = self.load("http://duckcrypt.info/ajax/auth.php?hash=" + str(m.group(2)))
m = re.match(self.__pattern__, src)
@@ -47,6 +48,7 @@ class DuckCryptInfo(Crypter):
if clink.find("a"):
self.handleLink(clink.find("a")['href'])
+
def handleLink(self, url):
src = self.load(url)
soup = BeautifulSoup(src)
diff --git a/module/plugins/crypter/EmbeduploadCom.py b/module/plugins/crypter/EmbeduploadCom.py
index 71c4d5778..8e4f5da07 100644
--- a/module/plugins/crypter/EmbeduploadCom.py
+++ b/module/plugins/crypter/EmbeduploadCom.py
@@ -44,6 +44,7 @@ class EmbeduploadCom(Crypter):
if not self.urls:
self.fail('Could not extract any links')
+
def getLocation(self, tmp_links):
new_links = []
for link in tmp_links:
diff --git a/module/plugins/crypter/HoerbuchIn.py b/module/plugins/crypter/HoerbuchIn.py
index 34e124d82..773e0bf8b 100644
--- a/module/plugins/crypter/HoerbuchIn.py
+++ b/module/plugins/crypter/HoerbuchIn.py
@@ -40,6 +40,7 @@ class HoerbuchIn(Crypter):
else:
self.urls = self.decryptFolder(pyfile.url)
+
def decryptFolder(self, url):
m = self.protection.search(url)
if m is None:
diff --git a/module/plugins/crypter/LinkdecrypterCom.py b/module/plugins/crypter/LinkdecrypterCom.py
index c72092a5f..0358d1308 100644
--- a/module/plugins/crypter/LinkdecrypterCom.py
+++ b/module/plugins/crypter/LinkdecrypterCom.py
@@ -24,7 +24,6 @@ class LinkdecrypterCom(Crypter):
def decrypt(self, pyfile):
-
self.passwords = self.getPassword().splitlines()
# API not working anymore
@@ -32,8 +31,8 @@ class LinkdecrypterCom(Crypter):
if not self.urls:
self.fail('Could not extract any links')
- def decryptAPI(self):
+ def decryptAPI(self):
get_dict = {"t": "link", "url": self.pyfile.url, "lcache": "1"}
self.html = self.load('http://linkdecrypter.com/api', get=get_dict)
if self.html.startswith('http://'):
@@ -51,8 +50,8 @@ class LinkdecrypterCom(Crypter):
return None
- def decryptHTML(self):
+ def decryptHTML(self):
retries = 5
post_dict = {"link_cache": "on", "pro_links": self.pyfile.url, "modo_links": "text"}
diff --git a/module/plugins/crypter/NCryptIn.py b/module/plugins/crypter/NCryptIn.py
index 28a0735a5..ef696dbd8 100644
--- a/module/plugins/crypter/NCryptIn.py
+++ b/module/plugins/crypter/NCryptIn.py
@@ -131,7 +131,6 @@ class NCryptIn(Crypter):
def unlockProtection(self):
-
postData = {}
form = re.search(r'<form name="protected"(.*?)</form>', self.cleanedHtml, re.DOTALL).group(1)
@@ -210,7 +209,6 @@ class NCryptIn(Crypter):
def handleSingleLink(self):
-
self.logDebug("Handling Single link")
package_links = []
@@ -223,7 +221,6 @@ class NCryptIn(Crypter):
def handleCNL2(self):
-
self.logDebug("Handling CNL2 links")
package_links = []
@@ -239,7 +236,6 @@ class NCryptIn(Crypter):
def handleContainers(self):
-
self.logDebug("Handling Container links")
package_links = []
@@ -254,7 +250,6 @@ class NCryptIn(Crypter):
def handleWebLinks(self):
-
self.logDebug("Handling Web links")
pattern = r'(http://ncrypt\.in/link-.*?=)'
links = re.findall(pattern, self.html)
@@ -280,7 +275,6 @@ class NCryptIn(Crypter):
def _getCipherParams(self):
-
pattern = r'<input.*?name="%s".*?value="(.*?)"'
# Get jk
diff --git a/module/plugins/crypter/NetfolderIn.py b/module/plugins/crypter/NetfolderIn.py
index 027503bd2..03c62ba14 100644
--- a/module/plugins/crypter/NetfolderIn.py
+++ b/module/plugins/crypter/NetfolderIn.py
@@ -40,12 +40,14 @@ class NetfolderIn(SimpleCrypter):
# Set package
self.packages = [(package_name, package_links, folder_name)]
+
def isPasswordProtected(self):
if '<input type="password" name="password"' in self.html:
self.logDebug("Links are password protected")
return True
return False
+
def submitPassword(self):
# Gather data
try:
@@ -69,6 +71,7 @@ class NetfolderIn(SimpleCrypter):
return html
+
def getLinks(self):
links = re.search(r'name="list" value="(.*?)"', self.html).group(1).split(",")
self.logDebug("Package has %d links" % len(links))
diff --git a/module/plugins/crypter/OneKhDe.py b/module/plugins/crypter/OneKhDe.py
index 7a2aefe83..188a0a0ef 100644
--- a/module/plugins/crypter/OneKhDe.py
+++ b/module/plugins/crypter/OneKhDe.py
@@ -22,11 +22,13 @@ class OneKhDe(Crypter):
Crypter.__init__(self, parent)
self.parent = parent
+
def file_exists(self):
""" returns True or False
"""
return True
+
def proceed(self, url, location):
url = self.parent.url
self.html = self.load(url)
diff --git a/module/plugins/crypter/TurbobitNetFolder.py b/module/plugins/crypter/TurbobitNetFolder.py
index 390520d88..1158c5cc1 100644
--- a/module/plugins/crypter/TurbobitNetFolder.py
+++ b/module/plugins/crypter/TurbobitNetFolder.py
@@ -35,6 +35,7 @@ class TurbobitNetFolder(SimpleCrypter):
else:
return
+
def getLinks(self):
id = re.match(self.__pattern__, self.pyfile.url).group("ID")
fixurl = lambda id: "http://turbobit.net/%s.html" % id
diff --git a/module/plugins/crypter/YoutubeBatch.py b/module/plugins/crypter/YoutubeBatch.py
index e5fd83c4f..e70003ab1 100644
--- a/module/plugins/crypter/YoutubeBatch.py
+++ b/module/plugins/crypter/YoutubeBatch.py
@@ -33,6 +33,7 @@ class YoutubeBatch(Crypter):
page = self.load(url, get=req)
return json_loads(page)
+
def getChannel(self, user):
channels = self.api_response("channels", {"part": "id,snippet,contentDetails", "forUsername": user, "maxResults": "50"})
if channels['items']:
@@ -42,6 +43,7 @@ class YoutubeBatch(Crypter):
"relatedPlaylists": channel['contentDetails']['relatedPlaylists'],
"user": user} # One lone channel for user?
+
def getPlaylist(self, p_id):
playlists = self.api_response("playlists", {"part": "snippet", "id": p_id})
if playlists['items']:
@@ -51,6 +53,7 @@ class YoutubeBatch(Crypter):
"channelId": playlist['snippet']['channelId'],
"channelTitle": playlist['snippet']['channelTitle']}
+
def _getPlaylists(self, id, token=None):
req = {"part": "id", "maxResults": "50", "channelId": id}
if token:
@@ -65,9 +68,11 @@ class YoutubeBatch(Crypter):
for item in self._getPlaylists(id, playlists['nextPageToken']):
yield item
+
def getPlaylists(self, ch_id):
return map(self.getPlaylist, self._getPlaylists(ch_id))
+
def _getVideosId(self, id, token=None):
req = {"part": "contentDetails", "maxResults": "50", "playlistId": id}
if token:
@@ -82,9 +87,11 @@ class YoutubeBatch(Crypter):
for item in self._getVideosId(id, playlist['nextPageToken']):
yield item
+
def getVideosId(self, p_id):
return list(self._getVideosId(p_id))
+
def decrypt(self, pyfile):
m = re.match(self.__pattern__, pyfile.url)
m_id = m.group("ID")
diff --git a/module/plugins/hooks/BypassCaptcha.py b/module/plugins/hooks/BypassCaptcha.py
index 984aac919..a07b2fc66 100644
--- a/module/plugins/hooks/BypassCaptcha.py
+++ b/module/plugins/hooks/BypassCaptcha.py
@@ -13,12 +13,15 @@ class BypassCaptchaException(Exception):
def __init__(self, err):
self.err = err
+
def getCode(self):
return self.err
+
def __str__(self):
return "<BypassCaptchaException %s>" % self.err
+
def __repr__(self):
return "<BypassCaptchaException %s>" % self.err
@@ -49,12 +52,14 @@ class BypassCaptcha(Hook):
def setup(self):
self.info = {}
+
def getCredits(self):
response = getURL(self.GETCREDITS_URL, post={"key": self.getConfig("passkey")})
data = dict([x.split(' ', 1) for x in response.splitlines()])
return int(data['Left'])
+
def submit(self, captcha, captchaType="file", match=None):
req = getRequest()
@@ -81,6 +86,7 @@ class BypassCaptcha(Hook):
return ticket, result
+
def respond(self, ticket, success):
try:
response = getURL(self.RESPOND_URL, post={"task_id": ticket, "key": self.getConfig("passkey"),
@@ -88,6 +94,7 @@ class BypassCaptcha(Hook):
except BadHeader, e:
self.logError(_("Could not send response."), e
+
def newCaptchaTask(self, task):
if "service" in task.data:
return False
@@ -110,14 +117,17 @@ class BypassCaptcha(Hook):
else:
self.logInfo(_("Your %s account has not enough credits") % self.__name__)
+
def captchaCorrect(self, task):
if task.data['service'] == self.__name__ and "ticket" in task.data:
self.respond(task.data['ticket'], True)
+
def captchaInvalid(self, task):
if task.data['service'] == self.__name__ and "ticket" in task.data:
self.respond(task.data['ticket'], False)
+
def processCaptcha(self, task):
c = task.captchaFile
try:
diff --git a/module/plugins/hooks/Captcha9kw.py b/module/plugins/hooks/Captcha9kw.py
index 6485db22b..947aff121 100755
--- a/module/plugins/hooks/Captcha9kw.py
+++ b/module/plugins/hooks/Captcha9kw.py
@@ -41,6 +41,7 @@ class Captcha9kw(Hook):
self.API_URL = "https" + self.API_URL if self.getConfig("https") else "http" + self.API_URL
self.info = {}
+
def getCredits(self):
response = getURL(self.API_URL, get={"apikey": self.getConfig("passkey"), "pyload": "1", "source": "pyload",
"action": "usercaptchaguthaben"})
@@ -53,6 +54,7 @@ class Captcha9kw(Hook):
self.logError(response)
return 0
+
def processCaptcha(self, task):
result = None
@@ -100,6 +102,7 @@ class Captcha9kw(Hook):
self.logError(_("Bad upload"), response)
return False
+
def newCaptchaTask(self, task):
if not task.isTextual() and not task.isPositional():
return False
@@ -118,6 +121,7 @@ class Captcha9kw(Hook):
else:
self.logError(_("Your Captcha 9kw.eu Account has not enough credits"))
+
def captchaCorrect(self, task):
if "ticket" in task.data:
@@ -137,6 +141,7 @@ class Captcha9kw(Hook):
else:
self.logError(_("No CaptchaID for correct request (task %s) found.") % task)
+
def captchaInvalid(self, task):
if "ticket" in task.data:
diff --git a/module/plugins/hooks/CaptchaBrotherhood.py b/module/plugins/hooks/CaptchaBrotherhood.py
index 3157fead8..da8fcbafe 100644
--- a/module/plugins/hooks/CaptchaBrotherhood.py
+++ b/module/plugins/hooks/CaptchaBrotherhood.py
@@ -23,12 +23,15 @@ class CaptchaBrotherhoodException(Exception):
def __init__(self, err):
self.err = err
+
def getCode(self):
return self.err
+
def __str__(self):
return "<CaptchaBrotherhoodException %s>" % self.err
+
def __repr__(self):
return "<CaptchaBrotherhoodException %s>" % self.err
@@ -55,6 +58,7 @@ class CaptchaBrotherhood(Hook):
def setup(self):
self.info = {}
+
def getCredits(self):
response = getURL(self.API_URL + "askCredits.aspx",
get={"username": self.getConfig("username"), "password": self.getConfig("passkey")})
@@ -66,6 +70,7 @@ class CaptchaBrotherhood(Hook):
self.info['credits'] = credits
return credits
+
def submit(self, captcha, captchaType="file", match=None):
try:
img = Image.open(captcha)
@@ -116,6 +121,7 @@ class CaptchaBrotherhood(Hook):
raise CaptchaBrotherhoodException("No solution received in time")
+
def get_api(self, api, ticket):
response = getURL("%s%s.aspx" % (self.API_URL, api),
get={"username": self.getConfig("username"),
@@ -126,6 +132,7 @@ class CaptchaBrotherhood(Hook):
return response
+
def newCaptchaTask(self, task):
if "service" in task.data:
return False
@@ -147,10 +154,12 @@ class CaptchaBrotherhood(Hook):
else:
self.logInfo(_("Your CaptchaBrotherhood Account has not enough credits"))
+
def captchaInvalid(self, task):
if task.data['service'] == self.__name__ and "ticket" in task.data:
response = self.get_api("complainCaptcha", task.data['ticket'])
+
def processCaptcha(self, task):
c = task.captchaFile
try:
diff --git a/module/plugins/hooks/Checksum.py b/module/plugins/hooks/Checksum.py
index 32597beeb..4a7cfd661 100644
--- a/module/plugins/hooks/Checksum.py
+++ b/module/plugins/hooks/Checksum.py
@@ -67,12 +67,14 @@ class Checksum(Hook):
if not self.getConfig("check_checksum"):
self.logInfo(_("Checksum validation is disabled in plugin configuration"))
+
def setup(self):
self.algorithms = sorted(
getattr(hashlib, "algorithms", ("md5", "sha1", "sha224", "sha256", "sha384", "sha512")), reverse=True)
self.algorithms.extend(["crc32", "adler32"])
self.formats = self.algorithms + ["sfv", "crc", "hash"]
+
def downloadFinished(self, pyfile):
"""
Compute checksum for the downloaded file and compare it with the hash provided by the hoster.
@@ -130,6 +132,7 @@ class Checksum(Hook):
else:
self.logWarning(_("Unable to validate checksum for file"), pyfile.name)
+
def checkFailed(self, pyfile, local_file, msg):
check_action = self.getConfig("check_action")
if check_action == "retry":
@@ -145,6 +148,7 @@ class Checksum(Hook):
return
pyfile.plugin.fail(reason=msg)
+
def packageFinished(self, pypack):
download_folder = save_join(self.config['general']['download_folder'], pypack.folder, "")
diff --git a/module/plugins/hooks/DeathByCaptcha.py b/module/plugins/hooks/DeathByCaptcha.py
index 2548506cb..99d7f7401 100644
--- a/module/plugins/hooks/DeathByCaptcha.py
+++ b/module/plugins/hooks/DeathByCaptcha.py
@@ -25,21 +25,26 @@ class DeathByCaptchaException(Exception):
'invalid-request': 'Invalid request',
'timed-out': 'No CAPTCHA solution received in time'}
+
def __init__(self, err):
self.err = err
+
def getCode(self):
return self.err
+
def getDesc(self):
if self.err in self.DBC_ERRORS.keys():
return self.DBC_ERRORS[self.err]
else:
return self.err
+
def __str__(self):
return "<DeathByCaptchaException %s>" % self.err
+
def __repr__(self):
return "<DeathByCaptchaException %s>" % self.err
@@ -66,6 +71,7 @@ class DeathByCaptcha(Hook):
def setup(self):
self.info = {}
+
def call_api(self, api="captcha", post=False, multipart=False):
req = getRequest()
req.c.setopt(HTTPHEADER, ["Accept: application/json", "User-Agent: pyLoad %s" % self.core.version])
@@ -106,6 +112,7 @@ class DeathByCaptcha(Hook):
return response
+
def getCredits(self):
response = self.call_api("user", True)
@@ -116,12 +123,14 @@ class DeathByCaptcha(Hook):
else:
raise DeathByCaptchaException(response)
+
def getStatus(self):
response = self.call_api("status", False)
if 'is_service_overloaded' in response and response['is_service_overloaded']:
raise DeathByCaptchaException('service-overload')
+
def submit(self, captcha, captchaType="file", match=None):
#workaround multipart-post bug in HTTPRequest.py
if re.match("^\w*$", self.getConfig("passkey")):
@@ -152,6 +161,7 @@ class DeathByCaptcha(Hook):
return ticket, result
+
def newCaptchaTask(self, task):
if "service" in task.data:
return False
@@ -183,6 +193,7 @@ class DeathByCaptcha(Hook):
task.setWaiting(180)
start_new_thread(self.processCaptcha, (task,))
+
def captchaInvalid(self, task):
if task.data['service'] == self.__name__ and "ticket" in task.data:
try:
@@ -192,6 +203,7 @@ class DeathByCaptcha(Hook):
except Exception, e:
self.logError(e)
+
def processCaptcha(self, task):
c = task.captchaFile
try:
diff --git a/module/plugins/hooks/DownloadScheduler.py b/module/plugins/hooks/DownloadScheduler.py
index c7a0155dd..70930ab67 100644
--- a/module/plugins/hooks/DownloadScheduler.py
+++ b/module/plugins/hooks/DownloadScheduler.py
@@ -26,9 +26,11 @@ class DownloadScheduler(Hook):
def setup(self):
self.cb = None # callback to scheduler job; will be by removed hookmanager when hook unloaded
+
def coreReady(self):
self.updateSchedule()
+
def updateSchedule(self, schedule=None):
if schedule is None:
schedule = self.getConfig("timetable")
@@ -56,6 +58,7 @@ class DownloadScheduler(Hook):
self.core.scheduler.removeJob(self.cb)
self.cb = self.core.scheduler.addJob(next_time, self.updateSchedule, threaded=False)
+
def setDownloadSpeed(self, speed):
if speed == 0:
abort = self.getConfig("abort")
diff --git a/module/plugins/hooks/ExpertDecoders.py b/module/plugins/hooks/ExpertDecoders.py
index 712b19677..e786cc35a 100644
--- a/module/plugins/hooks/ExpertDecoders.py
+++ b/module/plugins/hooks/ExpertDecoders.py
@@ -33,6 +33,7 @@ class ExpertDecoders(Hook):
def setup(self):
self.info = {}
+
def getCredits(self):
response = getURL(self.API_URL, post={"key": self.getConfig("passkey"), "action": "balance"})
@@ -44,6 +45,7 @@ class ExpertDecoders(Hook):
self.logError(response)
return 0
+
def processCaptcha(self, task):
task.data['ticket'] = ticket = uuid4()
result = None
@@ -65,6 +67,7 @@ class ExpertDecoders(Hook):
self.logDebug("Result %s : %s" % (ticket, result))
task.setResult(result)
+
def newCaptchaTask(self, task):
if not task.isTextual():
return False
@@ -83,6 +86,7 @@ class ExpertDecoders(Hook):
else:
self.logInfo(_("Your ExpertDecoders Account has not enough credits"))
+
def captchaInvalid(self, task):
if "ticket" in task.data:
diff --git a/module/plugins/hooks/ExtractArchive.py b/module/plugins/hooks/ExtractArchive.py
index f6958941e..649689f6e 100644
--- a/module/plugins/hooks/ExtractArchive.py
+++ b/module/plugins/hooks/ExtractArchive.py
@@ -14,6 +14,7 @@ if sys.version_info < (2, 7) and os.name != "nt":
import errno
from subprocess import Popen
+
def _eintr_retry_call(func, *args):
while True:
try:
@@ -23,6 +24,7 @@ if sys.version_info < (2, 7) and os.name != "nt":
continue
raise
+
# unsued timeout option for older python version
def wait(self, timeout=0):
"""Wait for child process to terminate. Returns returncode
diff --git a/module/plugins/hooks/HotFolder.py b/module/plugins/hooks/HotFolder.py
index 34a9ff49b..688dcbf48 100644
--- a/module/plugins/hooks/HotFolder.py
+++ b/module/plugins/hooks/HotFolder.py
@@ -28,6 +28,7 @@ class HotFolder(Hook):
def setup(self):
self.interval = 10
+
def periodical(self):
if not exists(join(self.getConfig("folder"), "finished")):
makedirs(join(self.getConfig("folder"), "finished"))
diff --git a/module/plugins/hooks/IRCInterface.py b/module/plugins/hooks/IRCInterface.py
index d648db7cf..59977b8af 100644
--- a/module/plugins/hooks/IRCInterface.py
+++ b/module/plugins/hooks/IRCInterface.py
@@ -44,6 +44,7 @@ class IRCInterface(Thread, Hook):
# self.sm = core.server_methods
self.api = core.api # todo, only use api
+
def coreReady(self):
self.abort = False
self.more = []
@@ -51,6 +52,7 @@ class IRCInterface(Thread, Hook):
self.start()
+
def packageFinished(self, pypack):
try:
if self.getConfig("info_pack"):
@@ -58,6 +60,7 @@ class IRCInterface(Thread, Hook):
except:
pass
+
def downloadFinished(self, pyfile):
try:
if self.getConfig("info_file"):
@@ -66,6 +69,7 @@ class IRCInterface(Thread, Hook):
except:
pass
+
def newCaptchaTask(self, task):
if self.getConfig("captcha") and task.isTextual():
task.handler.append(self)
@@ -78,6 +82,7 @@ class IRCInterface(Thread, Hook):
self.response(_("New Captcha Request: %s") % url)
self.response(_("Answer with 'c %s text on the captcha'") % task.id)
+
def run(self):
# connect to IRC etc.
self.sock = socket.socket()
@@ -99,6 +104,7 @@ class IRCInterface(Thread, Hook):
print_exc()
self.sock.close()
+
def main_loop(self):
readbuffer = ""
while True:
@@ -137,6 +143,7 @@ class IRCInterface(Thread, Hook):
self.handle_events(msg)
+
def handle_events(self, msg):
if not msg['origin'].split("!", 1)[0] in self.getConfig("owner").split():
return
@@ -179,6 +186,7 @@ class IRCInterface(Thread, Hook):
except Exception, e:
self.logError(repr(e))
+
def response(self, msg, origin=""):
if origin == "":
for t in self.getConfig("owner").split():
@@ -186,11 +194,13 @@ class IRCInterface(Thread, Hook):
else:
self.sock.send("PRIVMSG %s :%s\r\n" % (origin.split("!", 1)[0], msg))
+
#### Events
def event_pass(self, args):
return []
+
def event_status(self, args):
downloads = self.api.statusDownloads()
if not downloads:
@@ -216,6 +226,7 @@ class IRCInterface(Thread, Hook):
))
return lines
+
def event_queue(self, args):
ps = self.api.getQueueData()
@@ -228,6 +239,7 @@ class IRCInterface(Thread, Hook):
return lines
+
def event_collector(self, args):
ps = self.api.getCollectorData()
if not ps:
@@ -239,6 +251,7 @@ class IRCInterface(Thread, Hook):
return lines
+
def event_info(self, args):
if not args:
return ["ERROR: Use info like this: info <id>"]
@@ -252,6 +265,7 @@ class IRCInterface(Thread, Hook):
return ['LINK #%s: %s (%s) [%s][%s]' % (info.fid, info.name, info.format_size, info.statusmsg, info.plugin)]
+
def event_packinfo(self, args):
if not args:
return ["ERROR: Use packinfo like this: packinfo <id>"]
@@ -283,6 +297,7 @@ class IRCInterface(Thread, Hook):
return lines
+
def event_more(self, args):
if not self.more:
return ["No more information to display."]
@@ -293,14 +308,17 @@ class IRCInterface(Thread, Hook):
return lines
+
def event_start(self, args):
self.api.unpauseServer()
return ["INFO: Starting downloads."]
+
def event_stop(self, args):
self.api.pauseServer()
return ["INFO: No new downloads will be started."]
+
def event_add(self, args):
if len(args) < 2:
return ['ERROR: Add links like this: "add <packagename|id> links". ',
@@ -326,6 +344,7 @@ class IRCInterface(Thread, Hook):
id = self.api.addPackage(pack, links, 1)
return ["INFO: Created new Package %s [#%d] with %d links." % (pack, id, len(links))]
+
def event_del(self, args):
if len(args) < 2:
return ["ERROR: Use del command like this: del -p|-l <id> [...] (-p indicates that the ids are from packages, -l indicates that the ids are from links)"]
@@ -341,6 +360,7 @@ class IRCInterface(Thread, Hook):
else:
return ["ERROR: Use del command like this: del <-p|-l> <id> [...] (-p indicates that the ids are from packages, -l indicates that the ids are from links)"]
+
def event_push(self, args):
if not args:
return ["ERROR: Push package to queue like this: push <package id>"]
@@ -354,6 +374,7 @@ class IRCInterface(Thread, Hook):
self.api.pushToQueue(id)
return ["INFO: Pushed package #%d to queue." % id]
+
def event_pull(self, args):
if not args:
return ["ERROR: Pull package from queue like this: pull <package id>."]
@@ -365,6 +386,7 @@ class IRCInterface(Thread, Hook):
self.api.pullFromQueue(id)
return ["INFO: Pulled package #%d from queue to collector." % id]
+
def event_c(self, args):
""" captcha answer """
if not args:
@@ -377,6 +399,7 @@ class IRCInterface(Thread, Hook):
task.setResult(" ".join(args[1:]))
return ["INFO: Result %s saved." % " ".join(args[1:])]
+
def event_help(self, args):
lines = ["The following commands are available:",
"add <package|packid> <links> [...] Adds link to package. (creates new package if it does not exist)",
@@ -400,5 +423,6 @@ class IRCError(Exception):
def __init__(self, value):
self.value = value
+
def __str__(self):
return repr(self.value)
diff --git a/module/plugins/hooks/ImageTyperz.py b/module/plugins/hooks/ImageTyperz.py
index b7ee6b105..3eb0acd64 100644
--- a/module/plugins/hooks/ImageTyperz.py
+++ b/module/plugins/hooks/ImageTyperz.py
@@ -17,12 +17,15 @@ class ImageTyperzException(Exception):
def __init__(self, err):
self.err = err
+
def getCode(self):
return self.err
+
def __str__(self):
return "<ImageTyperzException %s>" % self.err
+
def __repr__(self):
return "<ImageTyperzException %s>" % self.err
@@ -51,6 +54,7 @@ class ImageTyperz(Hook):
def setup(self):
self.info = {}
+
def getCredits(self):
response = getURL(self.GETCREDITS_URL, post={"action": "REQUESTBALANCE", "username": self.getConfig("username"),
"password": self.getConfig("passkey")})
@@ -66,6 +70,7 @@ class ImageTyperz(Hook):
self.logInfo(_("Account balance: $%s left") % response)
return balance
+
def submit(self, captcha, captchaType="file", match=None):
req = getRequest()
#raise timeout threshold
@@ -100,6 +105,7 @@ class ImageTyperz(Hook):
return ticket, result
+
def newCaptchaTask(self, task):
if "service" in task.data:
return False
@@ -122,6 +128,7 @@ class ImageTyperz(Hook):
else:
self.logInfo(_("Your %s account has not enough credits") % self.__name__)
+
def captchaInvalid(self, task):
if task.data['service'] == self.__name__ and "ticket" in task.data:
response = getURL(self.RESPOND_URL, post={"action": "SETBADIMAGE", "username": self.getConfig("username"),
@@ -133,6 +140,7 @@ class ImageTyperz(Hook):
else:
self.logError(_("Bad captcha solution received, refund request failed"), response)
+
def processCaptcha(self, task):
c = task.captchaFile
try:
diff --git a/module/plugins/hooks/LinkdecrypterCom.py b/module/plugins/hooks/LinkdecrypterCom.py
index de08e406a..463a5af96 100644
--- a/module/plugins/hooks/LinkdecrypterCom.py
+++ b/module/plugins/hooks/LinkdecrypterCom.py
@@ -25,6 +25,7 @@ class LinkdecrypterCom(Hook):
except Exception, e:
self.logError(e)
+
def loadPatterns(self):
page = getURL("http://linkdecrypter.com/")
m = re.search(r'<b>Supported\(\d+\)</b>: <i>([^+<]*)', page)
diff --git a/module/plugins/hooks/MergeFiles.py b/module/plugins/hooks/MergeFiles.py
index 5a23ff862..0eab0037c 100644
--- a/module/plugins/hooks/MergeFiles.py
+++ b/module/plugins/hooks/MergeFiles.py
@@ -27,6 +27,7 @@ class MergeFiles(Hook):
# nothing to do
pass
+
@threaded
def packageFinished(self, pack):
files = {}
diff --git a/module/plugins/hooks/MultiHome.py b/module/plugins/hooks/MultiHome.py
index 5cda53bd7..378c493e9 100644
--- a/module/plugins/hooks/MultiHome.py
+++ b/module/plugins/hooks/MultiHome.py
@@ -26,19 +26,23 @@ class MultiHome(Hook):
self.parseInterfaces([self.config['download']['interface']])
self.setConfig("interfaces", self.toConfig())
+
def toConfig(self):
return ";".join([i.adress for i in self.interfaces])
+
def parseInterfaces(self, interfaces):
for interface in interfaces:
if not interface or str(interface).lower() == "none":
continue
self.interfaces.append(Interface(interface))
+
def coreReady(self):
requestFactory = self.core.requestFactory
oldGetRequest = requestFactory.getRequest
+
def getRequest(pluginName, account=None):
iface = self.bestInterface(pluginName, account)
if iface:
@@ -49,6 +53,7 @@ class MultiHome(Hook):
requestFactory.getRequest = getRequest
+
def bestInterface(self, pluginName, account):
best = None
for interface in self.interfaces:
@@ -63,13 +68,16 @@ class Interface(object):
self.adress = adress
self.history = {}
+
def lastPluginAccess(self, pluginName, account):
if (pluginName, account) in self.history:
return self.history[(pluginName, account)]
return 0
+
def useFor(self, pluginName, account):
self.history[(pluginName, account)] = time()
+
def __repr__(self):
return "<Interface - %s>" % self.adress
diff --git a/module/plugins/hooks/PremiumTo.py b/module/plugins/hooks/PremiumTo.py
index e783bac8f..15a357ce3 100644
--- a/module/plugins/hooks/PremiumTo.py
+++ b/module/plugins/hooks/PremiumTo.py
@@ -25,6 +25,7 @@ class PremiumTo(MultiHoster):
get={'username': self.account.username, 'password': self.account.password})
return [x.strip() for x in page.replace("\"", "").split(";")]
+
def coreReady(self):
self.account = self.core.accountManager.getAccountPlugin("PremiumTo")
diff --git a/module/plugins/hooks/PremiumizeMe.py b/module/plugins/hooks/PremiumizeMe.py
index c1a7866c4..1ef82612e 100644
--- a/module/plugins/hooks/PremiumizeMe.py
+++ b/module/plugins/hooks/PremiumizeMe.py
@@ -42,6 +42,7 @@ class PremiumizeMe(MultiHoster):
# Extract hosters from json file
return data['result']['hosterlist']
+
def coreReady(self):
# Get account plugin and check if there is a valid account available
self.account = self.core.accountManager.getAccountPlugin("PremiumizeMe")
diff --git a/module/plugins/hooks/RPNetBiz.py b/module/plugins/hooks/RPNetBiz.py
index f0231d0e7..feba36204 100644
--- a/module/plugins/hooks/RPNetBiz.py
+++ b/module/plugins/hooks/RPNetBiz.py
@@ -40,6 +40,7 @@ class RPNetBiz(MultiHoster):
# Extract hosters from json file
return hoster_list['hosters']
+
def coreReady(self):
# Get account plugin and check if there is a valid account available
self.account = self.core.accountManager.getAccountPlugin("RPNetBiz")
diff --git a/module/plugins/hooks/RehostTo.py b/module/plugins/hooks/RehostTo.py
index f3e1465ee..ea4521a28 100644
--- a/module/plugins/hooks/RehostTo.py
+++ b/module/plugins/hooks/RehostTo.py
@@ -24,6 +24,7 @@ class RehostTo(MultiHoster):
page = getURL("http://rehost.to/api.php?cmd=get_supported_och_dl&long_ses=%s" % self.long_ses)
return [x.strip() for x in page.replace("\"", "").split(",")]
+
def coreReady(self):
self.account = self.core.accountManager.getAccountPlugin("RehostTo")
diff --git a/module/plugins/hooks/RestartFailed.py b/module/plugins/hooks/RestartFailed.py
index 6724ceaa8..ebce60b3f 100644
--- a/module/plugins/hooks/RestartFailed.py
+++ b/module/plugins/hooks/RestartFailed.py
@@ -31,13 +31,16 @@ class RestartFailed(Hook):
else:
self.logDebug("Invalid interval value, kept current")
+
def periodical(self):
self.logInfo(_("Restart failed downloads"))
self.api.restartFailed()
+
def setup(self):
self.api = self.core.api
self.interval = self.MIN_INTERVAL
+
def coreReady(self):
self.pluginConfigChanged(self.__name__, "interval", self.getConfig("interval"))
diff --git a/module/plugins/hooks/UnSkipOnFail.py b/module/plugins/hooks/UnSkipOnFail.py
index f29383b32..e3c0f6af9 100644
--- a/module/plugins/hooks/UnSkipOnFail.py
+++ b/module/plugins/hooks/UnSkipOnFail.py
@@ -32,6 +32,7 @@ class UnSkipOnFail(Hook):
self.logInfo(_('restart "%s" (pid:%s)') % (pyfile_name, lpid))
self.setLinkStatus(link, "queued")
+
def findDuplicates(self, pyfile):
""" Search all packages for duplicate links to "pyfile".
Duplicates are links that would overwrite "pyfile".
@@ -61,6 +62,7 @@ class UnSkipOnFail(Hook):
dups.append(link)
return dups
+
def setLinkStatus(self, link, new_status):
""" Change status of "link" to "new_status".
"link" has to be a valid FileData object,
diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py
index cc086af5c..be1d6e5fc 100644
--- a/module/plugins/hooks/UpdateManager.py
+++ b/module/plugins/hooks/UpdateManager.py
@@ -48,14 +48,17 @@ class UpdateManager(Hook):
if value is True and self.core.debug:
self.periodical2()
+
def coreReady(self):
self.pluginConfigChanged(self.__name__, "interval", self.getConfig("interval"))
x = lambda: self.pluginConfigChanged(self.__name__, "reloadplugins", self.getConfig("reloadplugins"))
self.core.scheduler.addJob(10, x, threaded=False)
+
def unload(self):
self.pluginConfigChanged(self.__name__, "reloadplugins", False)
+
def setup(self):
self.cb2 = None
self.interval = self.MIN_INTERVAL
@@ -63,11 +66,13 @@ class UpdateManager(Hook):
self.info = {'pyload': False, 'version': None, 'plugins': False}
self.mtimes = {} #: store modification time for each plugin
+
def periodical2(self):
if not self.updating:
self.autoreloadPlugins()
self.cb2 = self.core.scheduler.addJob(4, self.periodical2, threaded=False)
+
@Expose
def autoreloadPlugins(self):
""" reload and reindex all modified plugins """
@@ -97,16 +102,19 @@ class UpdateManager(Hook):
return True if self.core.pluginManager.reloadPlugins(reloads) else False
+
def periodical(self):
if not self.info['pyload'] and not (self.getConfig("nodebugupdate") and self.core.debug):
self.updateThread()
+
def server_request(self):
try:
return getURL(self.SERVER_URL, get={'v': self.core.api.getServerVersion()}).splitlines()
except:
self.logWarning(_("Unable to contact server to get updates"))
+
@threaded
def updateThread(self):
self.updating = True
@@ -116,11 +124,13 @@ class UpdateManager(Hook):
else:
self.updating = False
+
@Expose
def updatePlugins(self):
""" simple wrapper for calling plugin update quickly """
return self.update(onlyplugin=True)
+
@Expose
def update(self, onlyplugin=False):
""" check for updates """
@@ -142,6 +152,7 @@ class UpdateManager(Hook):
self.info['version'] = newversion
return exitcode #: 0 = No plugins updated; 1 = Plugins updated; 2 = Plugins updated, but restart required; 3 = No plugins updated, new pyLoad version available
+
def _updatePlugins(self, updates):
""" check for plugin updates """
@@ -240,6 +251,7 @@ class UpdateManager(Hook):
return exitcode #: 0 = No plugins updated; 1 = Plugins updated; 2 = Plugins updated, but restart required
+
@Expose
def removePlugins(self, type_plugins):
""" delete plugins from disk """
diff --git a/module/plugins/hooks/WindowsPhoneToastNotify.py b/module/plugins/hooks/WindowsPhoneToastNotify.py
index eed61adbd..cf7920b74 100644
--- a/module/plugins/hooks/WindowsPhoneToastNotify.py
+++ b/module/plugins/hooks/WindowsPhoneToastNotify.py
@@ -25,12 +25,14 @@ class WindowsPhoneToastNotify(Hook):
def setup(self):
self.info = {}
+
def getXmlData(self):
myxml = ("<?xml version='1.0' encoding='utf-8'?> <wp:Notification xmlns:wp='WPNotification'> "
"<wp:Toast> <wp:Text1>Pyload Mobile</wp:Text1> <wp:Text2>Captcha waiting!</wp:Text2> "
"</wp:Toast> </wp:Notification>")
return myxml
+
def doRequest(self):
URL = self.getConfig("pushUrl")
request = self.getXmlData()
@@ -46,6 +48,7 @@ class WindowsPhoneToastNotify(Hook):
webservice.close()
self.setStorage("LAST_NOTIFY", time.time())
+
def newCaptchaTask(self, task):
if not self.getConfig("pushId") or not self.getConfig("pushUrl"):
return False
diff --git a/module/plugins/hooks/XMPPInterface.py b/module/plugins/hooks/XMPPInterface.py
index b32eeb40b..c4d6e1b66 100644
--- a/module/plugins/hooks/XMPPInterface.py
+++ b/module/plugins/hooks/XMPPInterface.py
@@ -30,6 +30,7 @@ class XMPPInterface(IRCInterface, JabberClient):
implements(IMessageHandlersProvider)
+
def __init__(self, core, manager):
IRCInterface.__init__(self, core, manager)
@@ -58,11 +59,13 @@ class XMPPInterface(IRCInterface, JabberClient):
self,
]
+
def coreReady(self):
self.new_package = {}
self.start()
+
def packageFinished(self, pypack):
try:
if self.getConfig("info_pack"):
@@ -70,6 +73,7 @@ class XMPPInterface(IRCInterface, JabberClient):
except:
pass
+
def downloadFinished(self, pyfile):
try:
if self.getConfig("info_file"):
@@ -78,6 +82,7 @@ class XMPPInterface(IRCInterface, JabberClient):
except:
pass
+
def run(self):
# connect to IRC etc.
self.connect()
@@ -86,21 +91,26 @@ class XMPPInterface(IRCInterface, JabberClient):
except Exception, ex:
self.logError(ex)
+
def stream_state_changed(self, state, arg):
"""This one is called when the state of stream connecting the component
to a server changes. This will usually be used to let the user
know what is going on."""
self.logDebug("*** State changed: %s %r ***" % (state, arg))
+
def disconnected(self):
self.logDebug("Client was disconnected")
+
def stream_closed(self, stream):
self.logDebug("Stream was closed", stream)
+
def stream_error(self, err):
self.logDebug("Stream Error", err)
+
def get_message_handlers(self):
"""Return list of (message_type, message_handler) tuples.
@@ -108,6 +118,7 @@ class XMPPInterface(IRCInterface, JabberClient):
in a client session."""
return [("normal", self.message)]
+
def message(self, stanza):
"""Message handler for the component."""
subject = stanza.get_subject()
@@ -165,9 +176,11 @@ class XMPPInterface(IRCInterface, JabberClient):
else:
return True
+
def response(self, msg, origin=""):
return self.announce(msg)
+
def announce(self, message):
""" send message to all owners"""
for user in self.getConfig("owners").split(";"):
@@ -187,9 +200,11 @@ class XMPPInterface(IRCInterface, JabberClient):
stream.send(m)
+
def beforeReconnecting(self, ip):
self.disconnect()
+
def afterReconnecting(self, ip):
self.connect()
@@ -202,24 +217,29 @@ class VersionHandler(object):
implements(IIqHandlersProvider, IFeaturesProvider)
+
def __init__(self, client):
"""Just remember who created this."""
self.client = client
+
def get_features(self):
"""Return namespace which should the client include in its reply to a
disco#info query."""
return ["jabber:iq:version"]
+
def get_iq_get_handlers(self):
"""Return list of tuples (element_name, namespace, handler) describing
handlers of <iq type='get'/> stanzas"""
return [("query", "jabber:iq:version", self.get_version)]
+
def get_iq_set_handlers(self):
"""Return empty list, as this class provides no <iq type='set'/> stanza handler."""
return []
+
def get_version(self, iq):
"""Handler for jabber:iq:version queries.
diff --git a/module/plugins/hoster/AlldebridCom.py b/module/plugins/hoster/AlldebridCom.py
index 74509110c..1b65237a0 100644
--- a/module/plugins/hoster/AlldebridCom.py
+++ b/module/plugins/hoster/AlldebridCom.py
@@ -31,10 +31,12 @@ class AlldebridCom(Hoster):
name += "%s.tmp" % randrange(100, 999)
return name
+
def setup(self):
self.chunkLimit = 16
self.resumeDownload = True
+
def process(self, pyfile):
if re.match(self.__pattern__, pyfile.url):
new_url = pyfile.url
diff --git a/module/plugins/hoster/BayfilesCom.py b/module/plugins/hoster/BayfilesCom.py
index b78af6286..8622f4dca 100644
--- a/module/plugins/hoster/BayfilesCom.py
+++ b/module/plugins/hoster/BayfilesCom.py
@@ -63,12 +63,14 @@ class BayfilesCom(SimpleHoster):
self.error("Free link")
self.startDownload(m.group(1))
+
def handlePremium(self):
m = re.search(self.PREMIUM_LINK_PATTERN, self.html)
if m is None:
self.error("Premium link")
self.startDownload(m.group(1))
+
def startDownload(self, url):
self.logDebug("%s URL: %s" % ("Premium" if self.premium else "Free", url))
self.download(url)
diff --git a/module/plugins/hoster/BezvadataCz.py b/module/plugins/hoster/BezvadataCz.py
index ffd586f74..9da1861ce 100644
--- a/module/plugins/hoster/BezvadataCz.py
+++ b/module/plugins/hoster/BezvadataCz.py
@@ -25,6 +25,7 @@ class BezvadataCz(SimpleHoster):
def setup(self):
self.multiDL = self.resumeDownload = True
+
def handleFree(self):
#download button
m = re.search(r'<a class="stahnoutSoubor".*?href="(.*?)"', self.html)
@@ -75,12 +76,14 @@ class BezvadataCz(SimpleHoster):
self.download(url)
+
def checkErrors(self):
if 'images/button-download-disable.png' in self.html:
self.longWait(5 * 60, 24) #: parallel dl limit
elif '<div class="infobox' in self.html:
self.tempOffline()
+
def loadcaptcha(self, data, *args, **kwargs):
return data.decode("base64")
diff --git a/module/plugins/hoster/CzshareCom.py b/module/plugins/hoster/CzshareCom.py
index 9f2f23d9e..2b8278a7e 100644
--- a/module/plugins/hoster/CzshareCom.py
+++ b/module/plugins/hoster/CzshareCom.py
@@ -62,6 +62,7 @@ class CzshareCom(SimpleHoster):
return True
+
def handlePremium(self):
# parse download link
try:
@@ -75,6 +76,7 @@ class CzshareCom(SimpleHoster):
self.download("http://sdilej.cz/profi_down.php", post=inputs, disposition=True)
self.checkDownloadedFile()
+
def handleFree(self):
# get free url
m = re.search(self.FREE_URL_PATTERN, self.html)
@@ -126,6 +128,7 @@ class CzshareCom(SimpleHoster):
self.download(url)
self.checkDownloadedFile()
+
def checkDownloadedFile(self):
# check download
check = self.checkDownload({
diff --git a/module/plugins/hoster/DailymotionCom.py b/module/plugins/hoster/DailymotionCom.py
index 726663ca6..b4ef6fa92 100644
--- a/module/plugins/hoster/DailymotionCom.py
+++ b/module/plugins/hoster/DailymotionCom.py
@@ -54,6 +54,7 @@ class DailymotionCom(Hoster):
def setup(self):
self.resumeDownload = self.multiDL = True
+
def getStreams(self):
streams = []
for result in re.finditer(r"\"(?P<URL>http:\\/\\/www.dailymotion.com\\/cdn\\/H264-(?P<QF>.*?)\\.*?)\"",
@@ -65,6 +66,7 @@ class DailymotionCom(Hoster):
streams.append((quality, link))
return sorted(streams, key=lambda x: x[0][::-1])
+
def getQuality(self):
q = self.getConfig("quality")
if q == "Lowest":
@@ -75,6 +77,7 @@ class DailymotionCom(Hoster):
quality = int(q.rsplit(" ")[1][:-1])
return quality
+
def getLink(self, streams, quality):
if quality > 0:
for x, s in reversed([item for item in enumerate(streams)]):
@@ -91,6 +94,7 @@ class DailymotionCom(Hoster):
self.logInfo("Download video quality %sx%s" % s[0])
return s[1]
+
def checkInfo(self, pyfile):
pyfile.name, pyfile.size, pyfile.status, pyfile.url = getInfo([pyfile.url])[0]
if pyfile.status == 1:
@@ -98,6 +102,7 @@ class DailymotionCom(Hoster):
elif pyfile.status == 6:
self.tempOffline()
+
def process(self, pyfile):
self.checkInfo(pyfile)
diff --git a/module/plugins/hoster/DateiTo.py b/module/plugins/hoster/DateiTo.py
index 06a485eae..93840b108 100644
--- a/module/plugins/hoster/DateiTo.py
+++ b/module/plugins/hoster/DateiTo.py
@@ -65,6 +65,7 @@ class DateiTo(SimpleHoster):
self.logDebug("Download URL", download_url)
self.download(download_url)
+
def checkErrors(self):
m = re.search(self.PARALELL_PATTERN, self.html)
if m:
@@ -73,6 +74,7 @@ class DateiTo(SimpleHoster):
self.wait(wait_time + 1, False)
self.retry()
+
def doWait(self):
m = re.search(self.WAIT_PATTERN, self.html)
wait_time = int(m.group(1)) if m else 30
diff --git a/module/plugins/hoster/DebridItaliaCom.py b/module/plugins/hoster/DebridItaliaCom.py
index 4e961fa9f..b1a2a4c77 100644
--- a/module/plugins/hoster/DebridItaliaCom.py
+++ b/module/plugins/hoster/DebridItaliaCom.py
@@ -21,6 +21,7 @@ class DebridItaliaCom(Hoster):
self.chunkLimit = -1
self.resumeDownload = True
+
def process(self, pyfile):
if re.match(self.__pattern__, pyfile.url):
new_url = pyfile.url
diff --git a/module/plugins/hoster/DepositfilesCom.py b/module/plugins/hoster/DepositfilesCom.py
index ade91e7d4..16340036f 100644
--- a/module/plugins/hoster/DepositfilesCom.py
+++ b/module/plugins/hoster/DepositfilesCom.py
@@ -101,6 +101,7 @@ class DepositfilesCom(SimpleHoster):
except:
self.retry(wait_time=60)
+
def handlePremium(self):
if '<span class="html_download_api-gold_traffic_limit">' in self.html:
self.logWarning("Download limit reached")
diff --git a/module/plugins/hoster/DlFreeFr.py b/module/plugins/hoster/DlFreeFr.py
index b653e2a8f..8932e749c 100644
--- a/module/plugins/hoster/DlFreeFr.py
+++ b/module/plugins/hoster/DlFreeFr.py
@@ -14,6 +14,7 @@ class CustomBrowser(Browser):
def __init__(self, bucket=None, options={}):
Browser.__init__(self, bucket, options)
+
def load(self, *args, **kwargs):
post = kwargs.get("post")
diff --git a/module/plugins/hoster/EdiskCz.py b/module/plugins/hoster/EdiskCz.py
index 5112c55ab..a2e1937fb 100644
--- a/module/plugins/hoster/EdiskCz.py
+++ b/module/plugins/hoster/EdiskCz.py
@@ -27,6 +27,7 @@ class EdiskCz(SimpleHoster):
def setup(self):
self.multiDL = False
+
def process(self, pyfile):
url = re.sub("/(stahni|sk/stahni)/", "/en/download/", pyfile.url)
diff --git a/module/plugins/hoster/EuroshareEu.py b/module/plugins/hoster/EuroshareEu.py
index a4a4e6881..d7c4b2eeb 100644
--- a/module/plugins/hoster/EuroshareEu.py
+++ b/module/plugins/hoster/EuroshareEu.py
@@ -31,6 +31,7 @@ class EuroshareEu(SimpleHoster):
self.multiDL = self.resumeDownload = self.premium
self.req.setOption("timeout", 120)
+
def handlePremium(self):
if self.ERR_NOT_LOGGED_IN_PATTERN in self.html:
self.account.relogin(self.user)
@@ -46,6 +47,7 @@ class EuroshareEu(SimpleHoster):
elif check == "json":
self.fail(self.lastCheck.group(1))
+
def handleFree(self):
if re.search(self.ERR_PARDL_PATTERN, self.html) is not None:
self.longWait(5 * 60, 12)
diff --git a/module/plugins/hoster/FastixRu.py b/module/plugins/hoster/FastixRu.py
index 7f61f7d7c..b1e834c61 100644
--- a/module/plugins/hoster/FastixRu.py
+++ b/module/plugins/hoster/FastixRu.py
@@ -30,10 +30,12 @@ class FastixRu(Hoster):
name += "%s.tmp" % randrange(100, 999)
return name
+
def setup(self):
self.chunkLimit = 3
self.resumeDownload = True
+
def process(self, pyfile):
if re.match(self.__pattern__, pyfile.url):
new_url = pyfile.url
diff --git a/module/plugins/hoster/FastshareCz.py b/module/plugins/hoster/FastshareCz.py
index 2a8d3af7d..0019a5708 100644
--- a/module/plugins/hoster/FastshareCz.py
+++ b/module/plugins/hoster/FastshareCz.py
@@ -60,6 +60,7 @@ class FastshareCz(SimpleHoster):
elif check == "wrong_captcha":
self.retry(max_tries=5, reason="Wrong captcha")
+
def handlePremium(self):
header = self.load(self.pyfile.url, just_header=True)
if "location" in header:
diff --git a/module/plugins/hoster/FileStoreTo.py b/module/plugins/hoster/FileStoreTo.py
index 549335a04..b8e56271b 100644
--- a/module/plugins/hoster/FileStoreTo.py
+++ b/module/plugins/hoster/FileStoreTo.py
@@ -25,6 +25,7 @@ class FileStoreTo(SimpleHoster):
def setup(self):
self.resumeDownload = self.multiDL = True
+
def handleFree(self):
self.wait(10)
ldc = re.search(r'wert="(\w+)"', self.html).group(1)
diff --git a/module/plugins/hoster/FilecloudIo.py b/module/plugins/hoster/FilecloudIo.py
index 5672e780d..659a2cc0f 100644
--- a/module/plugins/hoster/FilecloudIo.py
+++ b/module/plugins/hoster/FilecloudIo.py
@@ -37,6 +37,7 @@ class FilecloudIo(SimpleHoster):
self.resumeDownload = self.multiDL = True
self.chunkLimit = 1
+
def handleFree(self):
data = {"ukey": self.file_info['ID']}
@@ -104,6 +105,7 @@ class FilecloudIo(SimpleHoster):
else:
self.fail("Unexpected server response")
+
def handlePremium(self):
akey = self.account.getAccountData(self.user)['akey']
ukey = self.file_info['ID']
diff --git a/module/plugins/hoster/FilefactoryCom.py b/module/plugins/hoster/FilefactoryCom.py
index a5942e261..0801ca9a1 100644
--- a/module/plugins/hoster/FilefactoryCom.py
+++ b/module/plugins/hoster/FilefactoryCom.py
@@ -85,6 +85,7 @@ class FilefactoryCom(SimpleHoster):
elif check == "error":
self.fail("Unknown error")
+
def handlePremium(self):
header = self.load(self.pyfile.url, just_header=True)
if 'location' in header:
diff --git a/module/plugins/hoster/FilepostCom.py b/module/plugins/hoster/FilepostCom.py
index 0748b64f2..45fb2e644 100644
--- a/module/plugins/hoster/FilepostCom.py
+++ b/module/plugins/hoster/FilepostCom.py
@@ -93,6 +93,7 @@ class FilepostCom(SimpleHoster):
# Download
self.download(download_url)
+
def getJsonResponse(self, get_dict, post_dict, field):
json_response = json_loads(self.load('https://filepost.com/files/get/', get=get_dict, post=post_dict))
self.logDebug(json_response)
diff --git a/module/plugins/hoster/FilesMailRu.py b/module/plugins/hoster/FilesMailRu.py
index 2889e0565..cd8069efc 100644
--- a/module/plugins/hoster/FilesMailRu.py
+++ b/module/plugins/hoster/FilesMailRu.py
@@ -45,6 +45,7 @@ class FilesMailRu(Hoster):
if not self.account:
self.multiDL = False
+
def process(self, pyfile):
self.html = self.load(pyfile.url)
self.url_pattern = '<a href="(.+?)" onclick="return Act\(this\, \'dlink\'\, event\)">(.+?)</a>'
@@ -68,20 +69,24 @@ class FilesMailRu(Hoster):
self.download(self.getFileUrl())
self.myPostProcess()
+
def prepare(self):
"""You have to wait some seconds. Otherwise you will get a 40Byte HTML Page instead of the file you expected"""
self.setWait(10)
self.wait()
return True
+
def getFileUrl(self):
"""gives you the URL to the file. Extracted from the Files.mail.ru HTML-page stored in self.html"""
return re.search(self.url_pattern, self.html).group(0).split('<a href="')[1].split('" onclick="return Act')[0]
+
def getFileName(self):
"""gives you the Name for each file. Also extracted from the HTML-Page"""
return re.search(self.url_pattern, self.html).group(0).split(', event)">')[1].split('</a>')[0]
+
def myPostProcess(self):
# searches the file for HTMl-Code. Sometimes the Redirect
# doesn't work (maybe a curl Problem) and you get only a small
diff --git a/module/plugins/hoster/FileserveCom.py b/module/plugins/hoster/FileserveCom.py
index 4e722eb9f..7a06472d3 100644
--- a/module/plugins/hoster/FileserveCom.py
+++ b/module/plugins/hoster/FileserveCom.py
@@ -64,6 +64,7 @@ class FileserveCom(Hoster):
self.url = "%s%s" % (self.URLS[0], self.file_id)
self.logDebug("File ID: %s URL: %s" % (self.file_id, self.url))
+
def process(self, pyfile):
pyfile.name, pyfile.size, status, self.url = checkFile(self, [self.url])[0]
if status != 2:
@@ -75,6 +76,7 @@ class FileserveCom(Hoster):
else:
self.handleFree()
+
def handleFree(self):
self.html = self.load(self.url)
action = self.load(self.url, post={"checkDownload": "check"}, decode=True)
@@ -132,6 +134,7 @@ class FileserveCom(Hoster):
self.thread.m.reconnecting.wait(3) # Ease issue with later downloads appearing to be in parallel
+
def doTimmer(self):
response = self.load(self.url, post={"downloadLink": "wait"}, decode=True)
self.logDebug("Wait response : %s" % response[:80])
@@ -150,6 +153,7 @@ class FileserveCom(Hoster):
self.setWait(wait_time)
self.wait()
+
def doCaptcha(self):
captcha_key = re.search(self.CAPTCHA_KEY_PATTERN, self.html).group("key")
recaptcha = ReCaptcha(self)
@@ -170,12 +174,14 @@ class FileserveCom(Hoster):
else:
self.fail("Invalid captcha")
+
def doLongWait(self, m):
wait_time = (int(m.group(1)) * {'seconds': 1, 'minutes': 60, 'hours': 3600}[m.group(2)]) if m else 12 * 60
self.setWait(wait_time, True)
self.wait()
self.retry()
+
def handlePremium(self):
premium_url = None
if self.__name__ == "FileserveCom":
diff --git a/module/plugins/hoster/FreakshareCom.py b/module/plugins/hoster/FreakshareCom.py
index df06f2e74..6287545cb 100644
--- a/module/plugins/hoster/FreakshareCom.py
+++ b/module/plugins/hoster/FreakshareCom.py
@@ -26,6 +26,7 @@ class FreakshareCom(Hoster):
self.multiDL = False
self.req_opts = []
+
def process(self, pyfile):
self.pyfile = pyfile
@@ -62,6 +63,7 @@ class FreakshareCom(Hoster):
elif check == "downloadserver":
self.retry(5, 15 * 60, "No Download server")
+
def prepare(self):
pyfile = self.pyfile
@@ -81,10 +83,12 @@ class FreakshareCom(Hoster):
return True
+
def download_html(self):
self.load("http://freakshare.com/index.php", {"language": "EN"}) # Set english language in server session
self.html = self.load(self.pyfile.url)
+
def get_file_url(self):
""" returns the absolute downloadable filepath
"""
@@ -97,6 +101,7 @@ class FreakshareCom(Hoster):
else:
self.offline()
+
def get_file_name(self):
if not self.html:
self.download_html()
@@ -110,6 +115,7 @@ class FreakshareCom(Hoster):
else:
return self.pyfile.url
+
def get_file_size(self):
size = 0
if not self.html:
@@ -124,6 +130,7 @@ class FreakshareCom(Hoster):
return size
+
def get_waiting_time(self):
if not self.html:
self.download_html()
@@ -138,6 +145,7 @@ class FreakshareCom(Hoster):
else:
return 60
+
def file_exists(self):
""" returns True or False
"""
@@ -148,6 +156,7 @@ class FreakshareCom(Hoster):
else:
return True
+
def get_download_options(self):
re_envelope = re.search(r".*?value=\"Free\sDownload\".*?\n*?(.*?<.*?>\n*)*?\n*\s*?</form>",
self.html).group(0) # get the whole request
diff --git a/module/plugins/hoster/FreeWayMe.py b/module/plugins/hoster/FreeWayMe.py
index 996c8b6aa..88ba982f6 100644
--- a/module/plugins/hoster/FreeWayMe.py
+++ b/module/plugins/hoster/FreeWayMe.py
@@ -20,6 +20,7 @@ class FreeWayMe(Hoster):
self.chunkLimit = 1
self.multiDL = self.premium
+
def process(self, pyfile):
if not self.account:
self.logError(_("Please enter your %s account or deactivate this plugin") % "FreeWayMe")
diff --git a/module/plugins/hoster/FshareVn.py b/module/plugins/hoster/FshareVn.py
index 1a995ce28..7ce7cd3e6 100644
--- a/module/plugins/hoster/FshareVn.py
+++ b/module/plugins/hoster/FshareVn.py
@@ -58,6 +58,7 @@ class FshareVn(SimpleHoster):
self.handleFree()
self.checkDownloadedFile()
+
def handleFree(self):
self.html = self.load(self.pyfile.url, decode=True)
@@ -94,9 +95,11 @@ class FshareVn(SimpleHoster):
self.wait()
self.download(self.url)
+
def handlePremium(self):
self.download(self.pyfile.url)
+
def checkErrors(self):
if '/error.php?' in self.req.lastEffectiveURL or u"Liên kết bạn chọn khÃŽng tồn" in self.html:
self.offline()
@@ -111,6 +114,7 @@ class FshareVn(SimpleHoster):
self.logError("Unknown error occured or wait time not parsed")
self.retry(30, 2 * 60, "Unknown error")
+
def checkDownloadedFile(self):
# check download
check = self.checkDownload({
diff --git a/module/plugins/hoster/GamefrontCom.py b/module/plugins/hoster/GamefrontCom.py
index b7e7f0bc8..2009d06ab 100644
--- a/module/plugins/hoster/GamefrontCom.py
+++ b/module/plugins/hoster/GamefrontCom.py
@@ -28,6 +28,7 @@ class GamefrontCom(Hoster):
self.resumeDownload = self.multiDL = True
self.chunkLimit = -1
+
def process(self, pyfile):
self.pyfile = pyfile
self.html = self.load(pyfile.url, decode=True)
@@ -44,12 +45,14 @@ class GamefrontCom(Hoster):
self.download(link)
+
def _checkOnline(self):
if re.search(self.PATTERN_OFFLINE, self.html):
return False
else:
return True
+
def _getName(self):
name = re.search(self.PATTERN_FILENAME, self.html)
if name is None:
@@ -57,6 +60,7 @@ class GamefrontCom(Hoster):
return name.group(1)
+
def _getLink(self):
self.html2 = self.load("http://www.gamefront.com/" + re.search("(files/service/thankyou\\?id=\w+)",
self.html).group(1))
diff --git a/module/plugins/hoster/GigapetaCom.py b/module/plugins/hoster/GigapetaCom.py
index efec11079..65d940c5a 100644
--- a/module/plugins/hoster/GigapetaCom.py
+++ b/module/plugins/hoster/GigapetaCom.py
@@ -55,6 +55,7 @@ class GigapetaCom(SimpleHoster):
self.logDebug("Download URL: %s" % download_url)
self.download(download_url)
+
def checkErrors(self):
if "All threads for IP" in self.html:
self.logDebug("Your IP is already downloading a file - wait and retry")
diff --git a/module/plugins/hoster/GooIm.py b/module/plugins/hoster/GooIm.py
index d27b38f1f..d8f4c6190 100644
--- a/module/plugins/hoster/GooIm.py
+++ b/module/plugins/hoster/GooIm.py
@@ -27,6 +27,7 @@ class GooIm(SimpleHoster):
def setup(self):
self.multiDL = self.resumeDownload = True
+
def handleFree(self):
url = self.pyfile.url
self.html = self.load(url, cookies=True)
diff --git a/module/plugins/hoster/HellshareCz.py b/module/plugins/hoster/HellshareCz.py
index 10975829c..7a8579e78 100644
--- a/module/plugins/hoster/HellshareCz.py
+++ b/module/plugins/hoster/HellshareCz.py
@@ -27,6 +27,7 @@ class HellshareCz(SimpleHoster):
self.resumeDownload = self.multiDL = True if self.account else False
self.chunkLimit = 1
+
def process(self, pyfile):
if not self.account:
self.fail("User not logged in")
diff --git a/module/plugins/hoster/IfolderRu.py b/module/plugins/hoster/IfolderRu.py
index 774761049..176225e30 100644
--- a/module/plugins/hoster/IfolderRu.py
+++ b/module/plugins/hoster/IfolderRu.py
@@ -33,6 +33,7 @@ class IfolderRu(SimpleHoster):
self.resumeDownload = self.multiDL = True if self.account else False
self.chunkLimit = 1
+
def process(self, pyfile):
file_id = re.match(self.__pattern__, pyfile.url).group('ID')
self.html = self.load("http://rusfolder.com/%s" % file_id, cookies=True, decode=True)
diff --git a/module/plugins/hoster/JumbofilesCom.py b/module/plugins/hoster/JumbofilesCom.py
index fe0b72804..f43ee7697 100644
--- a/module/plugins/hoster/JumbofilesCom.py
+++ b/module/plugins/hoster/JumbofilesCom.py
@@ -25,6 +25,7 @@ class JumbofilesCom(SimpleHoster):
def setup(self):
self.resumeDownload = self.multiDL = True
+
def handleFree(self):
ukey = re.match(self.__pattern__, self.pyfile.url).group(1)
post_data = {"id": ukey, "op": "download3", "rand": ""}
diff --git a/module/plugins/hoster/LetitbitNet.py b/module/plugins/hoster/LetitbitNet.py
index 8443c2206..002c986e2 100644
--- a/module/plugins/hoster/LetitbitNet.py
+++ b/module/plugins/hoster/LetitbitNet.py
@@ -56,7 +56,7 @@ class LetitbitNet(SimpleHoster):
def setup(self):
self.resumeDownload = True
- #TODO confirm that resume works
+
def getFileInfo(self):
api_rep = api_download_info(self.pyfile.url)
@@ -67,6 +67,7 @@ class LetitbitNet(SimpleHoster):
else:
self.offline()
+
def handleFree(self):
action, inputs = self.parseHtmlForm('id="ifree_form"')
if not action:
@@ -149,6 +150,7 @@ class LetitbitNet(SimpleHoster):
else:
self.fail("Download did not finish correctly")
+
def handlePremium(self):
api_key = self.user
premium_key = self.account.getAccountData(self.user)['password']
diff --git a/module/plugins/hoster/LinksnappyCom.py b/module/plugins/hoster/LinksnappyCom.py
index 3372a505d..b96c9492c 100644
--- a/module/plugins/hoster/LinksnappyCom.py
+++ b/module/plugins/hoster/LinksnappyCom.py
@@ -27,6 +27,7 @@ class LinksnappyCom(Hoster):
self.chunkLimit = -1
self.resumeDownload = True
+
def process(self, pyfile):
if re.match(self.__pattern__, pyfile.url):
new_url = pyfile.url
@@ -67,6 +68,7 @@ class LinksnappyCom(Hoster):
if check == "html302":
self.retry(wait_time=5, reason="Linksnappy returns only HTML data.")
+
@staticmethod
def _get_host(url):
host = urlsplit(url).netloc
diff --git a/module/plugins/hoster/LuckyShareNet.py b/module/plugins/hoster/LuckyShareNet.py
index fe5a80679..4a4d4a047 100644
--- a/module/plugins/hoster/LuckyShareNet.py
+++ b/module/plugins/hoster/LuckyShareNet.py
@@ -38,6 +38,7 @@ class LuckyShareNet(SimpleHoster):
self.retry(reason="Hash expired")
return json_loads(rep)
+
# TODO: There should be a filesize limit for free downloads
# TODO: Some files could not be downloaded in free mode
def handleFree(self):
diff --git a/module/plugins/hoster/MediafireCom.py b/module/plugins/hoster/MediafireCom.py
index c2581aa9f..31b85b433 100644
--- a/module/plugins/hoster/MediafireCom.py
+++ b/module/plugins/hoster/MediafireCom.py
@@ -71,6 +71,7 @@ class MediafireCom(SimpleHoster):
def setup(self):
self.multiDL = False
+
def process(self, pyfile):
pyfile.url = re.sub(r'/view/?\?', '/?', pyfile.url)
@@ -93,6 +94,7 @@ class MediafireCom(SimpleHoster):
self.multiDL = True
self.download(self.url, disposition=True)
+
def handleFree(self):
passwords = self.getPassword().splitlines()
while self.PASSWORD_PATTERN in self.html:
@@ -111,6 +113,7 @@ class MediafireCom(SimpleHoster):
self.download(download_url)
+
def checkCaptcha(self):
solvemedia = SolveMedia(self)
diff --git a/module/plugins/hoster/MegaDebridEu.py b/module/plugins/hoster/MegaDebridEu.py
index ca0569c6b..68b7e0c1e 100644
--- a/module/plugins/hoster/MegaDebridEu.py
+++ b/module/plugins/hoster/MegaDebridEu.py
@@ -29,6 +29,7 @@ class MegaDebridEu(Hoster):
except IndexError:
return ""
+
def process(self, pyfile):
if re.match(self.__pattern__, pyfile.url):
new_url = pyfile.url
@@ -47,6 +48,7 @@ class MegaDebridEu(Hoster):
pyfile.name = filename
self.download(new_url, disposition=True)
+
def connectToApi(self):
"""
Connexion to the mega-debrid API
@@ -63,6 +65,7 @@ class MegaDebridEu(Hoster):
else:
return False
+
def debridLink(self, linkToDebrid):
"""
Debrid a link
@@ -78,6 +81,7 @@ class MegaDebridEu(Hoster):
else:
self.exitOnFail("Unable to debrid %s" % linkToDebrid)
+
def exitOnFail(self, msg):
"""
exit the plugin on fail case
diff --git a/module/plugins/hoster/MegaRapidCz.py b/module/plugins/hoster/MegaRapidCz.py
index 153f6ea8b..01b2aaf70 100644
--- a/module/plugins/hoster/MegaRapidCz.py
+++ b/module/plugins/hoster/MegaRapidCz.py
@@ -48,6 +48,7 @@ class MegaRapidCz(SimpleHoster):
def setup(self):
self.chunkLimit = 1
+
def handlePremium(self):
try:
self.html = self.load(self.pyfile.url, decode=True)
diff --git a/module/plugins/hoster/MegacrypterCom.py b/module/plugins/hoster/MegacrypterCom.py
index 67dec2a0b..5464dedce 100644
--- a/module/plugins/hoster/MegacrypterCom.py
+++ b/module/plugins/hoster/MegacrypterCom.py
@@ -29,6 +29,7 @@ class MegacrypterCom(MegaNz):
self.logDebug("API Response: " + resp)
return json_loads(resp)
+
def process(self, pyfile):
# match is guaranteed because plugin was chosen to handle url
node = re.match(self.__pattern__, pyfile.url).group(1)
diff --git a/module/plugins/hoster/MultishareCz.py b/module/plugins/hoster/MultishareCz.py
index 1ce16f30c..f7c8b47fd 100644
--- a/module/plugins/hoster/MultishareCz.py
+++ b/module/plugins/hoster/MultishareCz.py
@@ -38,9 +38,11 @@ class MultishareCz(SimpleHoster):
else:
self.handleOverriden()
+
def handleFree(self):
self.download("http://www.multishare.cz/html/download_free.php?ID=%s" % self.fileID)
+
def handlePremium(self):
if not self.checkCredit():
self.logWarning("Not enough credit left to download file")
@@ -48,6 +50,7 @@ class MultishareCz(SimpleHoster):
self.download("http://www.multishare.cz/html/download_premium.php?ID=%s" % self.fileID)
+
def handleOverriden(self):
if not self.premium:
self.fail("Only premium users can download from other hosters")
@@ -63,6 +66,7 @@ class MultishareCz(SimpleHoster):
self.logDebug(url, params)
self.download(url, get=params)
+
def checkCredit(self):
self.acc_info = self.account.getAccountInfo(self.user, True)
self.logInfo("User %s has %i MB left" % (self.user, self.acc_info['trafficleft'] / 1024))
diff --git a/module/plugins/hoster/MyfastfileCom.py b/module/plugins/hoster/MyfastfileCom.py
index 8fbae3e0a..d3a699e98 100644
--- a/module/plugins/hoster/MyfastfileCom.py
+++ b/module/plugins/hoster/MyfastfileCom.py
@@ -22,6 +22,7 @@ class MyfastfileCom(Hoster):
self.chunkLimit = -1
self.resumeDownload = True
+
def process(self, pyfile):
if re.match(self.__pattern__, pyfile.url):
new_url = pyfile.url
diff --git a/module/plugins/hoster/MyvideoDe.py b/module/plugins/hoster/MyvideoDe.py
index 1f02b5b69..1f8c785a7 100644
--- a/module/plugins/hoster/MyvideoDe.py
+++ b/module/plugins/hoster/MyvideoDe.py
@@ -24,19 +24,23 @@ class MyvideoDe(Hoster):
pyfile.name = self.get_file_name()
self.download(self.get_file_url())
+
def download_html(self):
self.html = self.load(self.pyfile.url)
+
def get_file_url(self):
videoId = re.search(r"addVariable\('_videoid','(.*)'\);p.addParam\('quality'", self.html).group(1)
videoServer = re.search("rel='image_src' href='(.*)thumbs/.*' />", self.html).group(1)
file_url = videoServer + videoId + ".flv"
return file_url
+
def get_file_name(self):
file_name_pattern = r'<h1 class=\'globalHd\'>(.*)</h1>'
return unescape(re.search(file_name_pattern, self.html).group(1).replace("/", "") + '.flv')
+
def file_exists(self):
self.download_html()
self.load(str(self.pyfile.url), cookies=False, just_header=True)
diff --git a/module/plugins/hoster/NetloadIn.py b/module/plugins/hoster/NetloadIn.py
index 0c255afbe..800de3068 100644
--- a/module/plugins/hoster/NetloadIn.py
+++ b/module/plugins/hoster/NetloadIn.py
@@ -66,12 +66,14 @@ class NetloadIn(Hoster):
def setup(self):
self.multiDL = self.resumeDownload = self.premium
+
def process(self, pyfile):
self.url = pyfile.url
self.prepare()
pyfile.setStatus("downloading")
self.proceed(self.url)
+
def prepare(self):
self.download_api_data()
@@ -93,6 +95,7 @@ class NetloadIn(Hoster):
self.fail("Failed")
return False
+
def download_api_data(self, n=0):
url = self.url
id_regex = re.compile(self.__pattern__)
@@ -134,6 +137,7 @@ class NetloadIn(Hoster):
else:
self.api_data = False
+
def final_wait(self, page):
wait_time = self.get_wait_time(page)
self.setWait(wait_time)
@@ -141,6 +145,7 @@ class NetloadIn(Hoster):
self.wait()
self.url = self.get_file_url(page)
+
def download_html(self):
self.logDebug("Netload: Entering download_html")
page = self.load(self.url, decode=True)
@@ -227,6 +232,7 @@ class NetloadIn(Hoster):
return False
+
def get_file_url(self, page):
try:
file_url_pattern = r'<a class="Orange_Link" href="(http://.+)".?>Or click here'
@@ -242,10 +248,12 @@ class NetloadIn(Hoster):
self.logDebug("Netload: Getting final link failed")
return None
+
def get_wait_time(self, page):
wait_seconds = int(re.search(r"countdown\((.+),'change\(\)'\)", page).group(1)) / 100
return wait_seconds
+
def proceed(self, url):
self.logDebug("Netload: Downloading..")
diff --git a/module/plugins/hoster/NowDownloadEu.py b/module/plugins/hoster/NowDownloadEu.py
index 57d31acd5..256b2c801 100644
--- a/module/plugins/hoster/NowDownloadEu.py
+++ b/module/plugins/hoster/NowDownloadEu.py
@@ -34,6 +34,7 @@ class NowDownloadEu(SimpleHoster):
self.multiDL = self.resumeDownload = True
self.chunkLimit = -1
+
def handleFree(self):
tokenlink = re.search(self.TOKEN_PATTERN, self.html)
continuelink = re.search(self.CONTINUE_PATTERN, self.html)
diff --git a/module/plugins/hoster/OverLoadMe.py b/module/plugins/hoster/OverLoadMe.py
index 5c3a36318..1b50ae8a2 100644
--- a/module/plugins/hoster/OverLoadMe.py
+++ b/module/plugins/hoster/OverLoadMe.py
@@ -31,10 +31,12 @@ class OverLoadMe(Hoster):
name += "%s.tmp" % randrange(100, 999)
return name
+
def setup(self):
self.chunkLimit = 5
self.resumeDownload = True
+
def process(self, pyfile):
if re.match(self.__pattern__, pyfile.url):
new_url = pyfile.url
diff --git a/module/plugins/hoster/PornhostCom.py b/module/plugins/hoster/PornhostCom.py
index 51426de71..6fb0fad83 100644
--- a/module/plugins/hoster/PornhostCom.py
+++ b/module/plugins/hoster/PornhostCom.py
@@ -25,11 +25,13 @@ class PornhostCom(Hoster):
pyfile.name = self.get_file_name()
self.download(self.get_file_url())
+
# Old interface
def download_html(self):
url = self.pyfile.url
self.html = self.load(url)
+
def get_file_url(self):
""" returns the absolute downloadable filepath
"""
@@ -47,6 +49,7 @@ class PornhostCom(Hoster):
return url.group(1).strip()
+
def get_file_name(self):
if not self.html:
self.download_html()
@@ -63,6 +66,7 @@ class PornhostCom(Hoster):
return name
+
def file_exists(self):
""" returns True or False
"""
diff --git a/module/plugins/hoster/PornhubCom.py b/module/plugins/hoster/PornhubCom.py
index 60b57d2c8..01204010d 100644
--- a/module/plugins/hoster/PornhubCom.py
+++ b/module/plugins/hoster/PornhubCom.py
@@ -25,10 +25,12 @@ class PornhubCom(Hoster):
pyfile.name = self.get_file_name()
self.download(self.get_file_url())
+
def download_html(self):
url = self.pyfile.url
self.html = self.load(url)
+
def get_file_url(self):
""" returns the absolute downloadable filepath
"""
@@ -57,6 +59,7 @@ class PornhubCom(Hoster):
return re.search(r'flv_url.*(http.*?)##post_roll', content).group(1)
+
def get_file_name(self):
if not self.html:
self.download_html()
@@ -73,6 +76,7 @@ class PornhubCom(Hoster):
return name + '.flv'
+
def file_exists(self):
""" returns True or False
"""
diff --git a/module/plugins/hoster/PremiumTo.py b/module/plugins/hoster/PremiumTo.py
index ed96f315b..8595304c4 100644
--- a/module/plugins/hoster/PremiumTo.py
+++ b/module/plugins/hoster/PremiumTo.py
@@ -26,6 +26,7 @@ class PremiumTo(Hoster):
self.resumeDownload = True
self.chunkLimit = 1
+
def process(self, pyfile):
if not self.account:
self.logError(_("Please enter your %s account or deactivate this plugin") % "premium.to")
@@ -66,6 +67,7 @@ class PremiumTo(Hoster):
if err:
self.fail(err)
+
def getTraffic(self):
try:
api_r = self.load("http://premium.to/api/straffic.php",
diff --git a/module/plugins/hoster/QuickshareCz.py b/module/plugins/hoster/QuickshareCz.py
index 5946565c6..12de0fa5b 100644
--- a/module/plugins/hoster/QuickshareCz.py
+++ b/module/plugins/hoster/QuickshareCz.py
@@ -53,6 +53,7 @@ class QuickshareCz(SimpleHoster):
if check == "err":
self.fail("File not m or plugin defect")
+
def handleFree(self):
# get download url
download_url = '%s/download.php' % self.jsvars['server']
@@ -83,6 +84,7 @@ class QuickshareCz(SimpleHoster):
# download file
self.download(download_url)
+
def handlePremium(self):
download_url = '%s/download_premium.php' % self.jsvars['server']
data = dict((x, self.jsvars[x]) for x in self.jsvars if x in ("ID1", "ID2", "ID4", "ID5"))
diff --git a/module/plugins/hoster/RPNetBiz.py b/module/plugins/hoster/RPNetBiz.py
index 3132001ed..0d032ef2f 100644
--- a/module/plugins/hoster/RPNetBiz.py
+++ b/module/plugins/hoster/RPNetBiz.py
@@ -22,6 +22,7 @@ class RPNetBiz(Hoster):
self.chunkLimit = -1
self.resumeDownload = True
+
def process(self, pyfile):
if re.match(self.__pattern__, pyfile.url):
link_status = {'generated': pyfile.url}
diff --git a/module/plugins/hoster/RapidshareCom.py b/module/plugins/hoster/RapidshareCom.py
index befbbb123..2dd36b84e 100644
--- a/module/plugins/hoster/RapidshareCom.py
+++ b/module/plugins/hoster/RapidshareCom.py
@@ -70,10 +70,12 @@ class RapidshareCom(Hoster):
self.chunkLimit = -1 if self.premium else 1
self.multiDL = self.resumeDownload = self.premium
+
def process(self, pyfile):
self.url = pyfile.url
self.prepare()
+
def prepare(self):
m = re.match(self.__pattern__, self.url)
@@ -106,6 +108,7 @@ class RapidshareCom(Hoster):
else:
self.fail("Unknown response code.")
+
def handleFree(self):
while self.no_download:
self.dl_dict = self.freeWait()
@@ -128,12 +131,14 @@ class RapidshareCom(Hoster):
self.offset += 5
self.handleFree()
+
def handlePremium(self):
info = self.account.getAccountInfo(self.user, True)
self.logDebug("%s: Use Premium Account" % self.__name__)
url = self.api_data['mirror']
self.download(url, get={"directstart": 1})
+
def download_api_data(self, force=False):
"""
http://images.rapidshare.com/apidoc.txt
@@ -168,6 +173,7 @@ class RapidshareCom(Hoster):
self.api_data['mirror'] = "http://rs%(serverid)s%(shorthost)s.rapidshare.com/files/%(fileid)s/%(filename)s" % self.api_data
+
def freeWait(self):
"""downloads html with the important information
"""
@@ -219,6 +225,7 @@ class RapidshareCom(Hoster):
return dl_dict
+
def get_file_name(self):
if self.api_data['filename']:
return self.api_data['filename']
diff --git a/module/plugins/hoster/RealdebridCom.py b/module/plugins/hoster/RealdebridCom.py
index fe6db98cb..cf1f825ef 100644
--- a/module/plugins/hoster/RealdebridCom.py
+++ b/module/plugins/hoster/RealdebridCom.py
@@ -32,10 +32,12 @@ class RealdebridCom(Hoster):
name += "%s.tmp" % randrange(100, 999)
return name
+
def setup(self):
self.chunkLimit = 3
self.resumeDownload = True
+
def process(self, pyfile):
if re.match(self.__pattern__, pyfile.url):
new_url = pyfile.url
diff --git a/module/plugins/hoster/RedtubeCom.py b/module/plugins/hoster/RedtubeCom.py
index f8ac81693..d136d145b 100644
--- a/module/plugins/hoster/RedtubeCom.py
+++ b/module/plugins/hoster/RedtubeCom.py
@@ -26,10 +26,12 @@ class RedtubeCom(Hoster):
pyfile.name = self.get_file_name()
self.download(self.get_file_url())
+
def download_html(self):
url = self.pyfile.url
self.html = self.load(url)
+
def get_file_url(self):
""" returns the absolute downloadable filepath
"""
@@ -40,12 +42,14 @@ class RedtubeCom(Hoster):
return file_url
+
def get_file_name(self):
if not self.html:
self.download_html()
return re.search('<title>(.*?)- RedTube - Free Porn Videos</title>', self.html).group(1).strip() + ".flv"
+
def file_exists(self):
""" returns True or False
"""
diff --git a/module/plugins/hoster/RehostTo.py b/module/plugins/hoster/RehostTo.py
index e1f719c19..80465724d 100644
--- a/module/plugins/hoster/RehostTo.py
+++ b/module/plugins/hoster/RehostTo.py
@@ -20,10 +20,12 @@ class RehostTo(Hoster):
def getFilename(self, url):
return unquote(url.rsplit("/", 1)[1])
+
def setup(self):
self.chunkLimit = 1
self.resumeDownload = True
+
def process(self, pyfile):
if not self.account:
self.logError(_("Please enter your %s account or deactivate this plugin") % "rehost.to")
diff --git a/module/plugins/hoster/RemixshareCom.py b/module/plugins/hoster/RemixshareCom.py
index 4e812b20d..94be78b4f 100644
--- a/module/plugins/hoster/RemixshareCom.py
+++ b/module/plugins/hoster/RemixshareCom.py
@@ -38,6 +38,7 @@ class RemixshareCom(SimpleHoster):
self.multiDL = True
self.chunkLimit = 1
+
def handleFree(self):
b = re.search(self.LINK_PATTERN, self.html)
if not b:
diff --git a/module/plugins/hoster/ShareplaceCom.py b/module/plugins/hoster/ShareplaceCom.py
index 84be2706f..bef14de0f 100644
--- a/module/plugins/hoster/ShareplaceCom.py
+++ b/module/plugins/hoster/ShareplaceCom.py
@@ -24,6 +24,7 @@ class ShareplaceCom(Hoster):
self.prepare()
self.download(self.get_file_url())
+
def prepare(self):
if not self.file_exists():
self.offline()
@@ -35,6 +36,7 @@ class ShareplaceCom(Hoster):
self.logDebug("%s: Waiting %d seconds." % (self.__name__, wait_time))
self.wait()
+
def get_waiting_time(self):
if not self.html:
self.download_html()
@@ -48,10 +50,12 @@ class ShareplaceCom(Hoster):
return sec
+
def download_html(self):
url = re.sub("shareplace.com\/\?", "shareplace.com//index1.php/?a=", self.pyfile.url)
self.html = self.load(url, decode=True)
+
def get_file_url(self):
""" returns the absolute downloadable filepath
"""
@@ -66,12 +70,14 @@ class ShareplaceCom(Hoster):
else:
self.fail("absolute filepath could not be found. offline? ")
+
def get_file_name(self):
if not self.html:
self.download_html()
return re.search("<title>\s*(.*?)\s*</title>", self.html).group(1)
+
def file_exists(self):
""" returns True or False
"""
diff --git a/module/plugins/hoster/SimplyPremiumCom.py b/module/plugins/hoster/SimplyPremiumCom.py
index e78a1f469..965c1421a 100644
--- a/module/plugins/hoster/SimplyPremiumCom.py
+++ b/module/plugins/hoster/SimplyPremiumCom.py
@@ -24,6 +24,7 @@ class SimplyPremiumCom(Hoster):
self.chunkLimit = 16
self.resumeDownload = False
+
def process(self, pyfile):
if re.match(self.__pattern__, pyfile.url):
new_url = pyfile.url
diff --git a/module/plugins/hoster/SimplydebridCom.py b/module/plugins/hoster/SimplydebridCom.py
index c7df990e3..dea82591d 100644
--- a/module/plugins/hoster/SimplydebridCom.py
+++ b/module/plugins/hoster/SimplydebridCom.py
@@ -21,6 +21,7 @@ class SimplydebridCom(Hoster):
self.resumeDownload = self.multiDL = True
self.chunkLimit = 1
+
def process(self, pyfile):
if not self.account:
self.logError(_("Please enter your %s account or deactivate this plugin") % "simply-debrid.com")
diff --git a/module/plugins/hoster/StreamCz.py b/module/plugins/hoster/StreamCz.py
index 1459ca5f1..d4ebd7701 100644
--- a/module/plugins/hoster/StreamCz.py
+++ b/module/plugins/hoster/StreamCz.py
@@ -42,8 +42,8 @@ class StreamCz(Hoster):
self.multiDL = True
self.resumeDownload = True
- def process(self, pyfile):
+ def process(self, pyfile):
self.html = self.load(pyfile.url, decode=True)
if re.search(self.OFFLINE_PATTERN, self.html):
diff --git a/module/plugins/hoster/TwoSharedCom.py b/module/plugins/hoster/TwoSharedCom.py
index 6b755219a..e1cdead9b 100644
--- a/module/plugins/hoster/TwoSharedCom.py
+++ b/module/plugins/hoster/TwoSharedCom.py
@@ -27,6 +27,7 @@ class TwoSharedCom(SimpleHoster):
def setup(self):
self.resumeDownload = self.multiDL = True
+
def handleFree(self):
m = re.search(self.LINK_PATTERN, self.html)
if m is None:
diff --git a/module/plugins/hoster/UlozTo.py b/module/plugins/hoster/UlozTo.py
index 2d4762ba6..9b70c8efa 100644
--- a/module/plugins/hoster/UlozTo.py
+++ b/module/plugins/hoster/UlozTo.py
@@ -44,6 +44,7 @@ class UlozTo(SimpleHoster):
self.multiDL = self.premium
self.resumeDownload = True
+
def process(self, pyfile):
pyfile.url = re.sub(r"(?<=http://)([^/]+)", "www.ulozto.net", pyfile.url)
self.html = self.load(pyfile.url, decode=True, cookies=True)
@@ -81,6 +82,7 @@ class UlozTo(SimpleHoster):
self.doCheckDownload()
+
def handleFree(self):
action, inputs = self.parseHtmlForm('id="frm-downloadDialog-freeDownloadForm"')
if not action or not inputs:
@@ -115,11 +117,13 @@ class UlozTo(SimpleHoster):
self.multiDL = True
self.download("http://www.ulozto.net" + action, post=inputs, cookies=True, disposition=True)
+
def handlePremium(self):
self.download(self.pyfile.url + "?do=directDownload", disposition=True)
#parsed_url = self.findDownloadURL(premium=True)
#self.download(parsed_url, post={"download": "Download"})
+
def findDownloadURL(self, premium=False):
msg = "%s link" % ("Premium" if premium else "Free")
m = re.search(self.PREMIUM_URL_PATTERN if premium else self.FREE_URL_PATTERN, self.html)
@@ -129,6 +133,7 @@ class UlozTo(SimpleHoster):
self.logDebug("%s: %s" % (msg, parsed_url))
return parsed_url
+
def doCheckDownload(self):
check = self.checkDownload({
"wrong_captcha": re.compile(r'<ul class="error">\s*<li>Error rewriting the text.</li>'),
diff --git a/module/plugins/hoster/UloziskoSk.py b/module/plugins/hoster/UloziskoSk.py
index 4323a71e5..2db2ce65e 100644
--- a/module/plugins/hoster/UloziskoSk.py
+++ b/module/plugins/hoster/UloziskoSk.py
@@ -38,6 +38,7 @@ class UloziskoSk(SimpleHoster):
else:
self.handleFree()
+
def handleFree(self):
m = re.search(self.LINK_PATTERN, self.html)
if m is None:
diff --git a/module/plugins/hoster/UnrestrictLi.py b/module/plugins/hoster/UnrestrictLi.py
index 2acb7816d..a2ee2a020 100644
--- a/module/plugins/hoster/UnrestrictLi.py
+++ b/module/plugins/hoster/UnrestrictLi.py
@@ -34,6 +34,7 @@ class UnrestrictLi(Hoster):
self.chunkLimit = 16
self.resumeDownload = True
+
def process(self, pyfile):
if re.match(self.__pattern__, pyfile.url):
new_url = pyfile.url
@@ -82,6 +83,7 @@ class UnrestrictLi(Hoster):
self.load("https://unrestrict.li/history/&delete=all")
self.logInfo("Download history deleted")
+
def setNameSize(self):
if 'name' in self.api_data:
self.pyfile.name = self.api_data['name']
diff --git a/module/plugins/hoster/UploadedTo.py b/module/plugins/hoster/UploadedTo.py
index 73a903902..764bb75de 100644
--- a/module/plugins/hoster/UploadedTo.py
+++ b/module/plugins/hoster/UploadedTo.py
@@ -119,6 +119,7 @@ class UploadedTo(Hoster):
self.fileID = getID(self.pyfile.url)
self.pyfile.url = "http://uploaded.net/file/%s" % self.fileID
+
def process(self, pyfile):
self.load("http://uploaded.net/language/en", just_header=True)
@@ -158,6 +159,7 @@ class UploadedTo(Hoster):
else:
self.handleFree()
+
def handlePremium(self):
info = self.account.getAccountInfo(self.user, True)
self.logDebug("%(name)s: Use Premium Account (%(left)sGB left)" % {"name": self.__name__,
@@ -183,6 +185,7 @@ class UploadedTo(Hoster):
print "Premium URL: " + url
self.download(url, post={})
+
def handleFree(self):
self.html = self.load(self.pyfile.url, decode=True)
diff --git a/module/plugins/hoster/UploadheroCom.py b/module/plugins/hoster/UploadheroCom.py
index 753ad6807..f2bcaea6a 100644
--- a/module/plugins/hoster/UploadheroCom.py
+++ b/module/plugins/hoster/UploadheroCom.py
@@ -58,12 +58,14 @@ class UploadheroCom(SimpleHoster):
self.download(download_url)
+
def handlePremium(self):
self.logDebug("%s: Use Premium Account" % self.__name__)
link = re.search(self.PREMIUM_URL_PATTERN, self.html).group(1)
self.logDebug("Downloading link : '%s'" % link)
self.download(link)
+
def checkErrors(self):
m = re.search(self.IP_BLOCKED_PATTERN, self.html)
if m:
diff --git a/module/plugins/hoster/VeehdCom.py b/module/plugins/hoster/VeehdCom.py
index f82d429d1..47f95ed41 100644
--- a/module/plugins/hoster/VeehdCom.py
+++ b/module/plugins/hoster/VeehdCom.py
@@ -22,10 +22,12 @@ class VeehdCom(Hoster):
def _debug(self, msg):
self.logDebug("[%s] %s" % (self.__name__, msg))
+
def setup(self):
self.multiDL = True
self.req.canContinue = True
+
def process(self, pyfile):
self.download_html()
if not self.file_exists():
@@ -34,11 +36,13 @@ class VeehdCom(Hoster):
pyfile.name = self.get_file_name()
self.download(self.get_file_url())
+
def download_html(self):
url = self.pyfile.url
self._debug("Requesting page: %s" % (repr(url),))
self.html = self.load(url)
+
def file_exists(self):
if not self.html:
self.download_html()
@@ -47,6 +51,7 @@ class VeehdCom(Hoster):
return False
return True
+
def get_file_name(self):
if not self.html:
self.download_html()
@@ -65,6 +70,7 @@ class VeehdCom(Hoster):
return re.sub(pattern, self.getConfig('replacement_char'), name) + '.avi'
+
def get_file_url(self):
""" returns the absolute downloadable filepath
"""
diff --git a/module/plugins/hoster/VeohCom.py b/module/plugins/hoster/VeohCom.py
index a4b94f40f..f35ed2510 100644
--- a/module/plugins/hoster/VeohCom.py
+++ b/module/plugins/hoster/VeohCom.py
@@ -30,6 +30,7 @@ class VeohCom(SimpleHoster):
self.resumeDownload = self.multiDL = True
self.chunkLimit = -1
+
def handleFree(self):
quality = self.getConfig("quality")
if quality == "Auto":
diff --git a/module/plugins/hoster/VimeoCom.py b/module/plugins/hoster/VimeoCom.py
index 2f554ee1b..8de7fad88 100644
--- a/module/plugins/hoster/VimeoCom.py
+++ b/module/plugins/hoster/VimeoCom.py
@@ -32,6 +32,7 @@ class VimeoCom(SimpleHoster):
self.resumeDownload = self.multiDL = True
self.chunkLimit = -1
+
def handleFree(self):
password = self.getPassword()
diff --git a/module/plugins/hoster/WebshareCz.py b/module/plugins/hoster/WebshareCz.py
index 6e0354d12..42f1e9a14 100644
--- a/module/plugins/hoster/WebshareCz.py
+++ b/module/plugins/hoster/WebshareCz.py
@@ -43,6 +43,7 @@ class WebshareCz(SimpleHoster):
self.logDebug("Direct link: " + direct)
self.download(direct, disposition=True)
+
def getFileInfo(self):
self.logDebug("URL: %s" % self.pyfile.url)
diff --git a/module/plugins/hoster/WrzucTo.py b/module/plugins/hoster/WrzucTo.py
index 47731642d..896da1c1b 100644
--- a/module/plugins/hoster/WrzucTo.py
+++ b/module/plugins/hoster/WrzucTo.py
@@ -28,6 +28,7 @@ class WrzucTo(SimpleHoster):
def setup(self):
self.multiDL = True
+
def handleFree(self):
data = dict(re.findall(r'(md5|file): "(.*?)"', self.html))
if len(data) != 2:
diff --git a/module/plugins/hoster/XHamsterCom.py b/module/plugins/hoster/XHamsterCom.py
index dae9a8eae..7257b2988 100644
--- a/module/plugins/hoster/XHamsterCom.py
+++ b/module/plugins/hoster/XHamsterCom.py
@@ -41,10 +41,12 @@ class XHamsterCom(Hoster):
pyfile.name = self.get_file_name() + self.desired_fmt
self.download(self.get_file_url())
+
def download_html(self):
url = self.pyfile.url
self.html = self.load(url)
+
def get_file_url(self):
""" returns the absolute downloadable filepath
"""
@@ -94,6 +96,7 @@ class XHamsterCom(Hoster):
return long_url
+
def get_file_name(self):
if not self.html:
self.download_html()
@@ -114,6 +117,7 @@ class XHamsterCom(Hoster):
return name.group(1)
+
def file_exists(self):
""" returns True or False
"""
diff --git a/module/plugins/hoster/Xdcc.py b/module/plugins/hoster/Xdcc.py
index db9c5edf9..244c3d7e2 100644
--- a/module/plugins/hoster/Xdcc.py
+++ b/module/plugins/hoster/Xdcc.py
@@ -33,6 +33,7 @@ class Xdcc(Hoster):
self.timeout = 30
self.multiDL = False
+
def process(self, pyfile):
# change request type
self.req = pyfile.m.core.requestFactory.getRequest(self.__name__, type="XDCC")
@@ -59,6 +60,7 @@ class Xdcc(Hoster):
self.fail("Server blocked our ip, retry again later manually")
+
def doDownload(self, url):
self.pyfile.setStatus("waiting") # real link
diff --git a/module/plugins/hoster/YoupornCom.py b/module/plugins/hoster/YoupornCom.py
index 37788b9f7..821a7a8d6 100644
--- a/module/plugins/hoster/YoupornCom.py
+++ b/module/plugins/hoster/YoupornCom.py
@@ -26,10 +26,12 @@ class YoupornCom(Hoster):
pyfile.name = self.get_file_name()
self.download(self.get_file_url())
+
def download_html(self):
url = self.pyfile.url
self.html = self.load(url, post={"user_choice": "Enter"}, cookies=False)
+
def get_file_url(self):
""" returns the absolute downloadable filepath
"""
@@ -38,6 +40,7 @@ class YoupornCom(Hoster):
return re.search(r'(http://download\.youporn\.com/download/\d+\?save=1)">', self.html).group(1)
+
def get_file_name(self):
if not self.html:
self.download_html()
@@ -45,6 +48,7 @@ class YoupornCom(Hoster):
file_name_pattern = r'<title>(.+) - '
return re.search(file_name_pattern, self.html).group(1).replace("&amp;", "&").replace("/", "") + '.flv'
+
def file_exists(self):
""" returns True or False
"""
diff --git a/module/plugins/hoster/YourfilesTo.py b/module/plugins/hoster/YourfilesTo.py
index 4487a728a..9de5929ff 100644
--- a/module/plugins/hoster/YourfilesTo.py
+++ b/module/plugins/hoster/YourfilesTo.py
@@ -25,6 +25,7 @@ class YourfilesTo(Hoster):
self.prepare()
self.download(self.get_file_url())
+
def prepare(self):
if not self.file_exists():
self.offline()
@@ -36,6 +37,7 @@ class YourfilesTo(Hoster):
self.logDebug("%s: Waiting %d seconds." % (self.__name__, wait_time))
self.wait()
+
def get_waiting_time(self):
if not self.html:
self.download_html()
@@ -49,10 +51,12 @@ class YourfilesTo(Hoster):
return sec
+
def download_html(self):
url = self.pyfile.url
self.html = self.load(url)
+
def get_file_url(self):
""" returns the absolute downloadable filepath
"""
@@ -64,12 +68,14 @@ class YourfilesTo(Hoster):
else:
self.fail("absolute filepath could not be found. offline? ")
+
def get_file_name(self):
if not self.html:
self.download_html()
return re.search("<title>(.*)</title>", self.html).group(1)
+
def file_exists(self):
""" returns True or False
"""
diff --git a/module/plugins/hoster/YoutubeCom.py b/module/plugins/hoster/YoutubeCom.py
index 5eacdc738..f16e9ae43 100644
--- a/module/plugins/hoster/YoutubeCom.py
+++ b/module/plugins/hoster/YoutubeCom.py
@@ -16,6 +16,7 @@ def which(program):
Courtesy of http://stackoverflow.com/a/377028/675646"""
+
def is_exe(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
@@ -85,6 +86,7 @@ class YoutubeCom(Hoster):
def setup(self):
self.resumeDownload = self.multiDL = True
+
def process(self, pyfile):
pyfile.url = replace_patterns(pyfile.url, self.FILE_URL_REPLACEMENTS)
html = self.load(pyfile.url, decode=True)
diff --git a/module/plugins/hoster/ZDF.py b/module/plugins/hoster/ZDF.py
index 83a3bd95c..274dd474a 100644
--- a/module/plugins/hoster/ZDF.py
+++ b/module/plugins/hoster/ZDF.py
@@ -29,15 +29,18 @@ class ZDF(Hoster):
any(f.text == "progressive" for f in video.iter("facet")),
)
+
@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))
+
def process(self, pyfile):
xml = fromstring(self.load(self.XML_API % self.get_id(pyfile.url)))
diff --git a/module/plugins/hoster/ZeveraCom.py b/module/plugins/hoster/ZeveraCom.py
index 5720579bb..9394a5c93 100644
--- a/module/plugins/hoster/ZeveraCom.py
+++ b/module/plugins/hoster/ZeveraCom.py
@@ -19,6 +19,7 @@ class ZeveraCom(Hoster):
self.resumeDownload = self.multiDL = True
self.chunkLimit = 1
+
def process(self, pyfile):
if not self.account:
self.logError(_("Please enter your %s account or deactivate this plugin") % "zevera.com")
diff --git a/module/plugins/internal/AbstractExtractor.py b/module/plugins/internal/AbstractExtractor.py
index 2b21ee357..8282e6ff5 100644
--- a/module/plugins/internal/AbstractExtractor.py
+++ b/module/plugins/internal/AbstractExtractor.py
@@ -28,6 +28,7 @@ class AbtractExtractor:
"""
return True
+
@staticmethod
def getTargets(files_ids):
""" Filter suited targets from list of filename id tuple list
@@ -36,6 +37,7 @@ class AbtractExtractor:
"""
raise NotImplementedError
+
def __init__(self, m, file, out, fullpath, overwrite, excludefiles, renice):
"""Initialize extractor for specific file
@@ -55,10 +57,12 @@ class AbtractExtractor:
self.renice = renice
self.files = [] #: Store extracted files here
+
def init(self):
""" Initialize additional data structures """
pass
+
def checkArchive(self):
"""Check if password if needed. Raise ArchiveError if integrity is
questionable.
@@ -68,6 +72,7 @@ class AbtractExtractor:
"""
return False
+
def checkPassword(self, password):
""" Check if the given password is/might be correct.
If it can not be decided at this point return true.
@@ -77,6 +82,7 @@ class AbtractExtractor:
"""
return True
+
def extract(self, progress, password=None):
"""Extract the archive. Raise specific errors in case of failure.
@@ -89,6 +95,7 @@ class AbtractExtractor:
"""
raise NotImplementedError
+
def getDeleteFiles(self):
"""Return list of files to delete, do *not* delete them here.
@@ -96,6 +103,7 @@ class AbtractExtractor:
"""
raise NotImplementedError
+
def getExtractedFiles(self):
"""Populate self.files at some point while extracting"""
return self.files
diff --git a/module/plugins/internal/MultiHoster.py b/module/plugins/internal/MultiHoster.py
index 4ef43bc31..5aadf6f2e 100644
--- a/module/plugins/internal/MultiHoster.py
+++ b/module/plugins/internal/MultiHoster.py
@@ -28,6 +28,7 @@ class MultiHoster(Hook):
self.supported = []
self.new_supported = []
+
def getConfig(self, option, default=''):
"""getConfig with default value - sublass may not implements all config options"""
try:
@@ -35,6 +36,7 @@ class MultiHoster(Hook):
except KeyError:
return default
+
def getHosterCached(self):
if not self.hosters:
@@ -61,6 +63,7 @@ class MultiHoster(Hook):
return self.hosters
+
def toHosterSet(self, hosters):
hosters = set((str(x).strip().lower() for x in hosters))
@@ -72,6 +75,7 @@ class MultiHoster(Hook):
hosters.discard('')
return hosters
+
def getHoster(self):
"""Load list of supported hoster
@@ -79,6 +83,7 @@ class MultiHoster(Hook):
"""
raise NotImplementedError
+
def coreReady(self):
if self.cb:
self.core.scheduler.removeJob(self.cb)
@@ -94,9 +99,11 @@ class MultiHoster(Hook):
else:
self.periodical()
+
def initPeriodical(self):
pass
+
def periodical(self):
"""reload hoster list periodically"""
self.logInfo(_("Reloading supported hoster list"))
@@ -112,6 +119,7 @@ class MultiHoster(Hook):
for hoster in old_supported:
self.unloadHoster(hoster)
+
def overridePlugins(self):
pluginMap = {}
for name in self.core.pluginManager.hosterPlugins.keys():
@@ -162,6 +170,7 @@ class MultiHoster(Hook):
dict['pattern'] = regexp
dict['re'] = re.compile(regexp)
+
def unloadHoster(self, hoster):
dict = self.core.pluginManager.hosterPlugins[hoster]
if "module" in dict:
@@ -171,6 +180,7 @@ class MultiHoster(Hook):
del dict['new_module']
del dict['new_name']
+
def unload(self):
"""Remove override for all hosters. Scheduler job is removed by hookmanager"""
for hoster in self.supported:
@@ -182,6 +192,7 @@ class MultiHoster(Hook):
dict['pattern'] = getattr(klass, "__pattern__", r'^unmatchable$')
dict['re'] = re.compile(dict['pattern'])
+
def downloadFailed(self, pyfile):
"""remove plugin override if download fails but not if file is offline/temp.offline"""
if pyfile.hasStatus("failed") and self.getConfig("unloadFailing", True):
diff --git a/module/plugins/internal/SimpleCrypter.py b/module/plugins/internal/SimpleCrypter.py
index 613ffce1f..6c00a2267 100644
--- a/module/plugins/internal/SimpleCrypter.py
+++ b/module/plugins/internal/SimpleCrypter.py
@@ -51,6 +51,7 @@ class SimpleCrypter(Crypter):
and its loadPage method:
+
def loadPage(self, page_n):
return the html of the page number page_n
"""
diff --git a/module/plugins/internal/UnZip.py b/module/plugins/internal/UnZip.py
index 52b4bca27..ec493bcd8 100644
--- a/module/plugins/internal/UnZip.py
+++ b/module/plugins/internal/UnZip.py
@@ -19,6 +19,7 @@ class UnZip(AbtractExtractor):
def checkDeps():
return sys.version_info[:2] >= (2, 6)
+
@staticmethod
def getTargets(files_ids):
result = []
@@ -29,10 +30,12 @@ class UnZip(AbtractExtractor):
return result
+
def extract(self, progress, password=None):
z = zipfile.ZipFile(self.file)
self.files = z.namelist()
z.extractall(self.out)
+
def getDeleteFiles(self):
return [self.file]