summaryrefslogtreecommitdiffstats
path: root/pyload/plugins/addon
diff options
context:
space:
mode:
Diffstat (limited to 'pyload/plugins/addon')
-rw-r--r--pyload/plugins/addon/Checksum.py32
-rw-r--r--pyload/plugins/addon/ClickAndLoad.py55
-rw-r--r--pyload/plugins/addon/DeleteFinished.py23
-rw-r--r--pyload/plugins/addon/DownloadScheduler.py17
-rw-r--r--pyload/plugins/addon/ExternalScripts.py13
-rw-r--r--pyload/plugins/addon/ExtractArchive.py42
-rw-r--r--pyload/plugins/addon/HotFolder.py60
-rw-r--r--pyload/plugins/addon/IRCInterface.py82
-rw-r--r--pyload/plugins/addon/MergeFiles.py21
-rw-r--r--pyload/plugins/addon/MultiHome.py17
-rw-r--r--pyload/plugins/addon/RestartFailed.py22
-rw-r--r--pyload/plugins/addon/UnSkipOnFail.py9
-rw-r--r--pyload/plugins/addon/WindowsPhoneToastNotify.py15
-rw-r--r--pyload/plugins/addon/XMPPInterface.py32
14 files changed, 269 insertions, 171 deletions
diff --git a/pyload/plugins/addon/Checksum.py b/pyload/plugins/addon/Checksum.py
index 551ce7bd9..00c3d9cfd 100644
--- a/pyload/plugins/addon/Checksum.py
+++ b/pyload/plugins/addon/Checksum.py
@@ -18,7 +18,7 @@ def computeChecksum(local_file, algorithm):
h = getattr(hashlib, algorithm)()
with open(local_file, 'rb') as f:
- for chunk in iter(lambda: f.read(128 * h.block_size), b''):
+ for chunk in iter(lambda: f.read(128 * h.block_size), ''):
h.update(chunk)
return h.hexdigest()
@@ -28,7 +28,7 @@ def computeChecksum(local_file, algorithm):
last = 0
with open(local_file, 'rb') as f:
- for chunk in iter(lambda: f.read(8192), b''):
+ for chunk in iter(lambda: f.read(8192), ''):
last = hf(chunk, last)
return "%x" % last
@@ -38,21 +38,21 @@ def computeChecksum(local_file, algorithm):
class Checksum(Addon):
- __name__ = "Checksum"
- __type__ = "addon"
- __version__ = "0.13"
+ __name__ = "Checksum"
+ __type__ = "addon"
+ __version__ = "0.14"
- __config__ = [("activated", "bool", "Activated", False),
- ("check_checksum", "bool", "Check checksum? (If False only size will be verified)", True),
+ __config__ = [("check_checksum", "bool", "Check checksum? (If False only size will be verified)", True),
("check_action", "fail;retry;nothing", "What to do if check fails?", "retry"),
("max_tries", "int", "Number of retries", 2),
("retry_action", "fail;nothing", "What to do if all retries fail?", "fail"),
("wait_time", "int", "Time to wait before each retry (seconds)", 1)]
__description__ = """Verify downloaded file size and checksum"""
- __authors__ = [("zoidberg", "zoidberg@mujmail.cz"),
- ("Walter Purcaro", "vuolter@gmail.com"),
- ("stickell", "l.stickell@yahoo.it")]
+ __license__ = "GPLv3"
+ __authors__ = [("zoidberg", "zoidberg@mujmail.cz"),
+ ("Walter Purcaro", "vuolter@gmail.com"),
+ ("stickell", "l.stickell@yahoo.it")]
methods = {'sfv': 'crc32', 'crc': 'crc32', 'hash': 'md5'}
@@ -66,12 +66,14 @@ class Checksum(Addon):
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.
@@ -117,7 +119,7 @@ class Checksum(Addon):
checksum = computeChecksum(local_file, key.replace("-", "").lower())
if checksum:
if checksum == data[key].lower():
- self.logInfo(_('File integrity of "%s" verified by %s checksum (%s).') %
+ self.logInfo(_('File integrity of "%s" verified by %s checksum (%s)') %
(pyfile.name, key.upper(), checksum))
break
else:
@@ -127,7 +129,8 @@ class Checksum(Addon):
else:
self.logWarning(_("Unsupported hashing algorithm"), key.upper())
else:
- self.logWarning(_("Unable to validate checksum for file"), pyfile.name)
+ self.logWarning(_("Unable to validate checksum for file: ") + pyfile.name)
+
def checkFailed(self, pyfile, local_file, msg):
check_action = self.getConfig("check_action")
@@ -137,13 +140,14 @@ class Checksum(Addon):
if pyfile.plugin.retries < max_tries:
if local_file:
remove(local_file)
- pyfile.plugin.retry(max_tries=max_tries, wait_time=self.getConfig("wait_time"), reason=msg)
+ pyfile.plugin.retry(max_tries, self.getConfig("wait_time"), msg)
elif retry_action == "nothing":
return
elif check_action == "nothing":
return
pyfile.plugin.fail(reason=msg)
+
def packageFinished(self, pypack):
download_folder = safe_join(self.config['general']['download_folder'], pypack.folder, "")
@@ -169,7 +173,7 @@ class Checksum(Addon):
algorithm = self.methods.get(file_type, file_type)
checksum = computeChecksum(local_file, algorithm)
if checksum == data['hash']:
- self.logInfo(_('File integrity of "%s" verified by %s checksum (%s).') %
+ self.logInfo(_('File integrity of "%s" verified by %s checksum (%s)') %
(data['name'], algorithm, checksum))
else:
self.logWarning(_("%s checksum for file %s does not match (%s != %s)") %
diff --git a/pyload/plugins/addon/ClickAndLoad.py b/pyload/plugins/addon/ClickAndLoad.py
index 7a90b8f04..c45a1ef2d 100644
--- a/pyload/plugins/addon/ClickAndLoad.py
+++ b/pyload/plugins/addon/ClickAndLoad.py
@@ -6,33 +6,6 @@ import thread
from pyload.plugins.base.Addon import Addon
-class ClickAndLoad(Addon):
- __name__ = "ClickAndLoad"
- __type__ = "addon"
- __version__ = "0.22"
-
- __config__ = [("activated", "bool", "Activated", True),
- ("extern", "bool", "Allow external link adding", False)]
-
- __description__ = """Gives abillity to use jd's click and load. depends on webinterface"""
- __authors__ = [("RaNaN", "RaNaN@pyload.de"),
- ("mkaay", "mkaay@mkaay.de")]
-
-
- def coreReady(self):
- self.port = int(self.config['webinterface']['port'])
- if self.config['webinterface']['activated']:
- try:
- if self.getConfig("extern"):
- ip = "0.0.0.0"
- else:
- ip = "127.0.0.1"
-
- thread.start_new_thread(proxy, (self, ip, self.port, 9666))
- except:
- self.logError(_("ClickAndLoad port already in use"))
-
-
def proxy(self, *settings):
thread.start_new_thread(server, (self,) + settings)
lock = thread.allocate_lock()
@@ -74,3 +47,31 @@ def forward(source, destination):
else:
#source.shutdown(socket.SHUT_RD)
destination.shutdown(socket.SHUT_WR)
+
+
+class ClickAndLoad(Addon):
+ __name__ = "ClickAndLoad"
+ __type__ = "addon"
+ __version__ = "0.22"
+
+ __config__ = [("activated", "bool", "Activated", True),
+ ("extern", "bool", "Allow external link adding", False)]
+
+ __description__ = """Click'N'Load hook plugin"""
+ __license__ = "GPLv3"
+ __authors__ = [("RaNaN", "RaNaN@pyload.de"),
+ ("mkaay", "mkaay@mkaay.de")]
+
+
+ def coreReady(self):
+ self.port = int(self.config['webinterface']['port'])
+ if self.config['webinterface']['activated']:
+ try:
+ if self.getConfig("extern"):
+ ip = "0.0.0.0"
+ else:
+ ip = "127.0.0.1"
+
+ thread.start_new_thread(proxy, (self, ip, self.port, 9666))
+ except:
+ self.logError(_("ClickAndLoad port already in use"))
diff --git a/pyload/plugins/addon/DeleteFinished.py b/pyload/plugins/addon/DeleteFinished.py
index 25e49dec5..719de143a 100644
--- a/pyload/plugins/addon/DeleteFinished.py
+++ b/pyload/plugins/addon/DeleteFinished.py
@@ -5,16 +5,20 @@ from pyload.plugins.base.Addon import Addon
class DeleteFinished(Addon):
- __name__ = "DeleteFinished"
- __type__ = "addon"
- __version__ = "1.09"
+ __name__ = "DeleteFinished"
+ __type__ = "addon"
+ __version__ = "1.11"
__config__ = [('activated', 'bool', 'Activated', 'False'),
('interval', 'int', 'Delete every (hours)', '72'),
('deloffline', 'bool', 'Delete packages with offline links', 'False')]
__description__ = """Automatically delete all finished packages from queue"""
- __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+
+
+ # event_list = ["pluginConfigChanged"]
## overwritten methods ##
@@ -28,30 +32,36 @@ class DeleteFinished(Addon):
self.info['sleep'] = True
self.addEvent('packageFinished', self.wakeup)
+
def pluginConfigChanged(self, plugin, name, value):
- if name == 'interval' and value != self.interval:
+ if name == "interval" and value != self.interval:
self.interval = value * 3600
self.initPeriodical()
+
def unload(self):
self.removeEvent('packageFinished', self.wakeup)
+
def coreReady(self):
self.info = {'sleep': True}
interval = self.getConfig('interval')
- self.pluginConfigChanged('DeleteFinished', 'interval', interval)
+ self.pluginConfigChanged(self.__name__, 'interval', interval)
self.addEvent('packageFinished', self.wakeup)
+
## own methods ##
@style.queue
def deleteFinished(self, mode):
self.c.execute('DELETE FROM packages WHERE NOT EXISTS(SELECT 1 FROM links WHERE package=packages.id AND status NOT IN (%s))' % mode)
self.c.execute('DELETE FROM links WHERE NOT EXISTS(SELECT 1 FROM packages WHERE id=links.package)')
+
def wakeup(self, pypack):
self.removeEvent('packageFinished', self.wakeup)
self.info['sleep'] = False
+
## event managing ##
def addEvent(self, event, func):
"""Adds an event listener for event name"""
@@ -63,6 +73,7 @@ class DeleteFinished(Addon):
else:
self.m.events[event] = [func]
+
def setup(self):
self.m = self.manager
self.removeEvent = self.m.removeEvent
diff --git a/pyload/plugins/addon/DownloadScheduler.py b/pyload/plugins/addon/DownloadScheduler.py
index 48bbeb3af..ef15a859f 100644
--- a/pyload/plugins/addon/DownloadScheduler.py
+++ b/pyload/plugins/addon/DownloadScheduler.py
@@ -8,26 +8,28 @@ from pyload.plugins.base.Addon import Addon
class DownloadScheduler(Addon):
- __name__ = "DownloadScheduler"
- __type__ = "addon"
+ __name__ = "DownloadScheduler"
+ __type__ = "addon"
__version__ = "0.21"
- __config__ = [("activated", "bool", "Activated", False),
- ("timetable", "str", "List time periods as hh:mm full or number(kB/s)",
+ __config__ = [("timetable", "str", "List time periods as hh:mm full or number(kB/s)",
"0:00 full, 7:00 250, 10:00 0, 17:00 150"),
("abort", "bool", "Abort active downloads when start period with speed 0", False)]
__description__ = """Download Scheduler"""
- __authors__ = [("zoidberg", "zoidberg@mujmail.cz"),
- ("stickell", "l.stickell@yahoo.it")]
+ __license__ = "GPLv3"
+ __authors__ = [("zoidberg", "zoidberg@mujmail.cz"),
+ ("stickell", "l.stickell@yahoo.it")]
def setup(self):
- self.cb = None # callback to scheduler job; will be by removed AddonManager when addon unloaded
+ self.cb = None #: callback to scheduler job; will be by removed AddonManager when addon unloaded
+
def coreReady(self):
self.updateSchedule()
+
def updateSchedule(self, schedule=None):
if schedule is None:
schedule = self.getConfig("timetable")
@@ -55,6 +57,7 @@ class DownloadScheduler(Addon):
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/pyload/plugins/addon/ExternalScripts.py b/pyload/plugins/addon/ExternalScripts.py
index 52d14c9d3..122de00c5 100644
--- a/pyload/plugins/addon/ExternalScripts.py
+++ b/pyload/plugins/addon/ExternalScripts.py
@@ -11,17 +11,18 @@ from pyload.utils import safe_join
class ExternalScripts(Addon):
- __name__ = "ExternalScripts"
- __type__ = "addon"
+ __name__ = "ExternalScripts"
+ __type__ = "addon"
__version__ = "0.24"
__config__ = [("activated", "bool", "Activated", True)]
__description__ = """Run external scripts"""
- __authors__ = [("mkaay", "mkaay@mkaay.de"),
- ("RaNaN", "ranan@pyload.org"),
- ("spoob", "spoob@pyload.org"),
- ("Walter Purcaro", "vuolter@gmail.com")]
+ __license__ = "GPLv3"
+ __authors__ = [("mkaay", "mkaay@mkaay.de"),
+ ("RaNaN", "ranan@pyload.org"),
+ ("spoob", "spoob@pyload.org"),
+ ("Walter Purcaro", "vuolter@gmail.com")]
event_list = ["archive_extracted", "package_extracted", "all_archives_extracted", "all_archives_processed",
diff --git a/pyload/plugins/addon/ExtractArchive.py b/pyload/plugins/addon/ExtractArchive.py
index cdf2eecee..a53d2f951 100644
--- a/pyload/plugins/addon/ExtractArchive.py
+++ b/pyload/plugins/addon/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
@@ -53,8 +55,8 @@ from pyload.utils import safe_join, fs_encode
class ExtractArchive(Addon):
- __name__ = "ExtractArchive"
- __type__ = "addon"
+ __name__ = "ExtractArchive"
+ __type__ = "addon"
__version__ = "0.17"
__config__ = [("activated", "bool", "Activated", True),
@@ -70,9 +72,10 @@ class ExtractArchive(Addon):
("renice", "int", "CPU Priority", 0)]
__description__ = """Extract different kind of archives"""
- __authors__ = [("RaNaN", "ranan@pyload.org"),
- ("AndroKev", None),
- ("Walter Purcaro", "vuolter@gmail.com")]
+ __license__ = "GPLv3"
+ __authors__ = [("RaNaN", "ranan@pyload.org"),
+ ("AndroKev", None),
+ ("Walter Purcaro", "vuolter@gmail.com")]
event_list = ["allDownloadsProcessed"]
@@ -307,16 +310,18 @@ class ExtractArchive(Addon):
def reloadPasswords(self):
passwordfile = self.getConfig("passwordfile")
- if not exists(passwordfile):
- open(passwordfile, "wb").close()
- passwords = []
- f = open(passwordfile, "rb")
- for pw in f.read().splitlines():
- passwords.append(pw)
- f.close()
+ try:
+ passwords = []
+ with open(passwordfile, "a+") as f:
+ for pw in f.read().splitlines():
+ passwords.append(pw)
- self.passwords = passwords
+ except IOError, e:
+ self.logError(e)
+
+ else:
+ self.passwords = passwords
@Expose
@@ -326,12 +331,15 @@ class ExtractArchive(Addon):
if pw in self.passwords:
self.passwords.remove(pw)
+
self.passwords.insert(0, pw)
- f = open(passwordfile, "wb")
- for pw in self.passwords:
- f.write(pw + "\n")
- f.close()
+ try:
+ with open(passwordfile, "wb") as f:
+ for pw in self.passwords:
+ f.write(pw + "\n")
+ except IOError, e:
+ self.logError(e)
def setPermissions(self, files):
diff --git a/pyload/plugins/addon/HotFolder.py b/pyload/plugins/addon/HotFolder.py
index cceb71ca7..0bce193ce 100644
--- a/pyload/plugins/addon/HotFolder.py
+++ b/pyload/plugins/addon/HotFolder.py
@@ -7,58 +7,58 @@ from os.path import exists, isfile, join
from shutil import move
from pyload.plugins.base.Addon import Addon
+from module.utils import fs_encode, save_join
class HotFolder(Addon):
- __name__ = "HotFolder"
- __type__ = "addon"
+ __name__ = "HotFolder"
+ __type__ = "addon"
__version__ = "0.11"
- __config__ = [("activated", "bool", "Activated", False),
- ("folder", "str", "Folder to observe", "container"),
+ __config__ = [("folder", "str", "Folder to observe", "container"),
("watch_file", "bool", "Observe link file", False),
("keep", "bool", "Keep added containers", True),
("file", "str", "Link file", "links.txt")]
__description__ = """Observe folder and file for changes and add container and links"""
- __authors__ = [("RaNaN", "RaNaN@pyload.de")]
+ __license__ = "GPLv3"
+ __authors__ = [("RaNaN", "RaNaN@pyload.de")]
def setup(self):
self.interval = 10
+
def periodical(self):
- if not exists(join(self.getConfig("folder"), "finished")):
- makedirs(join(self.getConfig("folder"), "finished"))
+ folder = fs_encode(self.getConfig("folder"))
+
+ try:
+ if not exists(join(folder, "finished")):
+ makedirs(join(folder, "finished"))
- if self.getConfig("watch_file"):
+ if self.getConfig("watch_file"):
+ with open(fs_encode(self.getConfig("file")), "a+") as f:
+ content = f.read().strip()
- if not exists(self.getConfig("file")):
- f = open(self.getConfig("file"), "wb")
- f.close()
+ if content:
+ name = "%s_%s.txt" % (self.getConfig("file"), time.strftime("%H-%M-%S_%d%b%Y"))
- f = open(self.getConfig("file"), "rb")
- content = f.read().strip()
- f.close()
- f = open(self.getConfig("file"), "wb")
- f.close()
- if content:
- name = "%s_%s.txt" % (self.getConfig("file"), time.strftime("%H-%M-%S_%d%b%Y"))
+ with open(save_join(folder, "finished", name), "wb") as f:
+ f.write(content)
- f = open(join(self.getConfig("folder"), "finished", name), "wb")
- f.write(content)
- f.close()
+ self.core.api.addPackage(f.name, [f.name], 1)
- self.core.api.addPackage(f.name, [f.name], 1)
+ for f in listdir(folder):
+ path = join(folder, f)
- for f in listdir(self.getConfig("folder")):
- path = join(self.getConfig("folder"), f)
+ if not isfile(path) or f.endswith("~") or f.startswith("#") or f.startswith("."):
+ continue
- if not isfile(path) or f.endswith("~") or f.startswith("#") or f.startswith("."):
- continue
+ newpath = join(folder, "finished", f if self.getConfig("keep") else "tmp_" + f)
+ move(path, newpath)
- newpath = join(self.getConfig("folder"), "finished", f if self.getConfig("keep") else "tmp_" + f)
- move(path, newpath)
+ self.logInfo(_("Added %s from HotFolder") % f)
+ self.core.api.addPackage(f, [newpath], 1)
- self.logInfo(_("Added %s from HotFolder") % f)
- self.core.api.addPackage(f, [newpath], 1)
+ except IOError, e:
+ self.logError(e)
diff --git a/pyload/plugins/addon/IRCInterface.py b/pyload/plugins/addon/IRCInterface.py
index 9f77bfc7e..041c8b07b 100644
--- a/pyload/plugins/addon/IRCInterface.py
+++ b/pyload/plugins/addon/IRCInterface.py
@@ -2,6 +2,7 @@
import re
import socket
+import ssl
import time
from pycurl import FORM_FILE
@@ -17,15 +18,15 @@ from pyload.utils import formatSize
class IRCInterface(Thread, Addon):
- __name__ = "IRCInterface"
- __type__ = "addon"
- __version__ = "0.11"
+ __name__ = "IRCInterface"
+ __type__ = "addon"
+ __version__ = "0.12"
- __config__ = [("activated", "bool", "Activated", False),
- ("host", "str", "IRC-Server Address", "Enter your server here!"),
+ __config__ = [("host", "str", "IRC-Server Address", "Enter your server here!"),
("port", "int", "IRC-Server Port", 6667),
("ident", "str", "Clients ident", "pyload-irc"),
("realname", "str", "Realname", "pyload-irc"),
+ ("ssl", "bool", "Use SSL", False),
("nick", "str", "Nickname the Client will take", "pyLoad-IRC"),
("owner", "str", "Nickname the Client will accept commands from", "Enter your nick here!"),
("info_file", "bool", "Inform about every file finished", False),
@@ -33,15 +34,15 @@ class IRCInterface(Thread, Addon):
("captcha", "bool", "Send captcha requests", True)]
__description__ = """Connect to irc and let owner perform different tasks"""
- __authors__ = [("Jeix", "Jeix@hasnomail.com")]
+ __license__ = "GPLv3"
+ __authors__ = [("Jeix", "Jeix@hasnomail.com")]
def __init__(self, core, manager):
Thread.__init__(self)
Addon.__init__(self, core, manager)
self.setDaemon(True)
- # self.sm = core.server_methods
- self.api = core.api # todo, only use api
+
def coreReady(self):
self.abort = False
@@ -50,6 +51,7 @@ class IRCInterface(Thread, Addon):
self.start()
+
def packageFinished(self, pypack):
try:
if self.getConfig("info_pack"):
@@ -57,6 +59,7 @@ class IRCInterface(Thread, Addon):
except:
pass
+
def downloadFinished(self, pyfile):
try:
if self.getConfig("info_file"):
@@ -65,6 +68,7 @@ class IRCInterface(Thread, Addon):
except:
pass
+
def newCaptchaTask(self, task):
if self.getConfig("captcha") and task.isTextual():
task.handler.append(self)
@@ -77,11 +81,16 @@ class IRCInterface(Thread, Addon):
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()
host = self.getConfig("host")
self.sock.connect((host, self.getConfig("port")))
+
+ if self.getConfig("ssl"):
+ self.sock = ssl.wrap_socket(self.sock, cert_reqs=ssl.CERT_NONE) #@TODO: support certificate
+
nick = self.getConfig("nick")
self.sock.send("NICK %s\r\n" % nick)
self.sock.send("USER %s %s bla :%s\r\n" % (nick, host, nick))
@@ -98,6 +107,7 @@ class IRCInterface(Thread, Addon):
print_exc()
self.sock.close()
+
def main_loop(self):
readbuffer = ""
while True:
@@ -136,6 +146,7 @@ class IRCInterface(Thread, Addon):
self.handle_events(msg)
+
def handle_events(self, msg):
if not msg['origin'].split("!", 1)[0] in self.getConfig("owner").split():
return
@@ -148,15 +159,15 @@ class IRCInterface(Thread, Addon):
# HANDLE CTCP ANTI FLOOD/BOT PROTECTION
if msg['text'] == "\x01VERSION\x01":
- self.logDebug("Sending CTCP VERSION.")
+ self.logDebug("Sending CTCP VERSION")
self.sock.send("NOTICE %s :%s\r\n" % (msg['origin'], "pyLoad! IRC Interface"))
return
elif msg['text'] == "\x01TIME\x01":
- self.logDebug("Sending CTCP TIME.")
+ self.logDebug("Sending CTCP TIME")
self.sock.send("NOTICE %s :%d\r\n" % (msg['origin'], time.time()))
return
elif msg['text'] == "\x01LAG\x01":
- self.logDebug("Received CTCP LAG.") # don't know how to answer
+ self.logDebug("Received CTCP LAG") #: don't know how to answer
return
trigger = "pass"
@@ -176,7 +187,8 @@ class IRCInterface(Thread, Addon):
for line in res:
self.response(line, msg['origin'])
except Exception, e:
- self.logError(repr(e))
+ self.logError(e)
+
def response(self, msg, origin=""):
if origin == "":
@@ -185,13 +197,15 @@ class IRCInterface(Thread, Addon):
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()
+ downloads = self.core.api.statusDownloads()
if not downloads:
return ["INFO: There are no active downloads currently."]
@@ -215,8 +229,9 @@ class IRCInterface(Thread, Addon):
))
return lines
+
def event_queue(self, args):
- ps = self.api.getQueueData()
+ ps = self.core.api.getQueueData()
if not ps:
return ["INFO: There are no packages in queue."]
@@ -227,8 +242,9 @@ class IRCInterface(Thread, Addon):
return lines
+
def event_collector(self, args):
- ps = self.api.getCollectorData()
+ ps = self.core.api.getCollectorData()
if not ps:
return ["INFO: No packages in collector!"]
@@ -238,19 +254,21 @@ class IRCInterface(Thread, Addon):
return lines
+
def event_info(self, args):
if not args:
return ["ERROR: Use info like this: info <id>"]
info = None
try:
- info = self.api.getFileData(int(args[0]))
+ info = self.core.api.getFileData(int(args[0]))
except FileDoesNotExists:
return ["ERROR: Link doesn't exists."]
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>"]
@@ -258,7 +276,7 @@ class IRCInterface(Thread, Addon):
lines = []
pack = None
try:
- pack = self.api.getPackageData(int(args[0]))
+ pack = self.core.api.getPackageData(int(args[0]))
except PackageDoesNotExists:
return ["ERROR: Package doesn't exists."]
@@ -282,6 +300,7 @@ class IRCInterface(Thread, Addon):
return lines
+
def event_more(self, args):
if not self.more:
return ["No more information to display."]
@@ -292,14 +311,17 @@ class IRCInterface(Thread, Addon):
return lines
+
def event_start(self, args):
- self.api.unpauseServer()
+ self.core.api.unpauseServer()
return ["INFO: Starting downloads."]
+
def event_stop(self, args):
- self.api.pauseServer()
+ self.core.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". ',
@@ -312,7 +334,7 @@ class IRCInterface(Thread, Addon):
count_failed = 0
try:
id = int(pack)
- pack = self.api.getPackageData(id)
+ pack = self.core.api.getPackageData(id)
if not pack:
return ["ERROR: Package doesn't exists."]
@@ -322,48 +344,52 @@ class IRCInterface(Thread, Addon):
except:
# create new package
- id = self.api.addPackage(pack, links, 1)
+ id = self.core.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)"]
if args[0] == "-p":
- ret = self.api.deletePackages(map(int, args[1:]))
+ ret = self.core.api.deletePackages(map(int, args[1:]))
return ["INFO: Deleted %d packages!" % len(args[1:])]
elif args[0] == "-l":
- ret = self.api.delLinks(map(int, args[1:]))
+ ret = self.core.api.delLinks(map(int, args[1:]))
return ["INFO: Deleted %d links!" % len(args[1:])]
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>"]
id = int(args[0])
try:
- info = self.api.getPackageInfo(id)
+ info = self.core.api.getPackageInfo(id)
except PackageDoesNotExists:
return ["ERROR: Package #%d does not exist." % id]
- self.api.pushToQueue(id)
+ self.core.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>."]
id = int(args[0])
- if not self.api.getPackageData(id):
+ if not self.core.api.getPackageData(id):
return ["ERROR: Package #%d does not exist." % id]
- self.api.pullFromQueue(id)
+ self.core.api.pullFromQueue(id)
return ["INFO: Pulled package #%d from queue to collector." % id]
+
def event_c(self, args):
""" captcha answer """
if not args:
@@ -376,6 +402,7 @@ class IRCInterface(Thread, Addon):
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)",
@@ -399,5 +426,6 @@ class IRCError(Exception):
def __init__(self, value):
self.value = value
+
def __str__(self):
return repr(self.value)
diff --git a/pyload/plugins/addon/MergeFiles.py b/pyload/plugins/addon/MergeFiles.py
index 1edbf119a..e67f87f56 100644
--- a/pyload/plugins/addon/MergeFiles.py
+++ b/pyload/plugins/addon/MergeFiles.py
@@ -2,21 +2,23 @@
import os
import re
-import traceback
+
+from traceback import print_exc
from pyload.plugins.base.Addon import Addon, threaded
from pyload.utils import safe_join, fs_encode
class MergeFiles(Addon):
- __name__ = "MergeFiles"
- __type__ = "addon"
+ __name__ = "MergeFiles"
+ __type__ = "addon"
__version__ = "0.12"
- __config__ = [("activated", "bool", "Activated", False)]
+ __config__ = [("activated", "bool", "Activated", True)]
__description__ = """Merges parts splitted with hjsplit"""
- __authors__ = [("and9000", "me@has-no-mail.com")]
+ __license__ = "GPLv3"
+ __authors__ = [("and9000", "me@has-no-mail.com")]
BUFFER_SIZE = 4096
@@ -26,12 +28,13 @@ class MergeFiles(Addon):
# nothing to do
pass
+
@threaded
def packageFinished(self, pack):
files = {}
fid_dict = {}
for fid, data in pack.getChildren().iteritems():
- if re.search("\.[0-9]{3}$", data['name']):
+ if re.search("\.\d{3}$", data['name']):
if data['name'][:-4] not in files:
files[data['name'][:-4]] = []
files[data['name'][:-4]].append(data['name'])
@@ -55,6 +58,7 @@ class MergeFiles(Addon):
s_file = open(os.path.join(download_folder, splitted_file), "rb")
size_written = 0
s_file_size = int(os.path.getsize(os.path.join(download_folder, splitted_file)))
+
while True:
f_buffer = s_file.read(self.BUFFER_SIZE)
if f_buffer:
@@ -63,10 +67,13 @@ class MergeFiles(Addon):
pyfile.setProgress((size_written * 100) / s_file_size)
else:
break
+
s_file.close()
self.logDebug("Finished merging part", splitted_file)
+
except Exception, e:
- print traceback.print_exc()
+ print_exc()
+
finally:
pyfile.setProgress(100)
pyfile.setStatus("finished")
diff --git a/pyload/plugins/addon/MultiHome.py b/pyload/plugins/addon/MultiHome.py
index f7bca4843..a808802ba 100644
--- a/pyload/plugins/addon/MultiHome.py
+++ b/pyload/plugins/addon/MultiHome.py
@@ -6,15 +6,15 @@ from pyload.plugins.base.Addon import Addon
class MultiHome(Addon):
- __name__ = "MultiHome"
- __type__ = "addon"
+ __name__ = "MultiHome"
+ __type__ = "addon"
__version__ = "0.11"
- __config__ = [("activated", "bool", "Activated", False),
- ("interfaces", "str", "Interfaces", "None")]
+ __config__ = [("interfaces", "str", "Interfaces", "None")]
__description__ = """Ip address changer"""
- __authors__ = [("mkaay", "mkaay@mkaay.de")]
+ __license__ = "GPLv3"
+ __authors__ = [("mkaay", "mkaay@mkaay.de")]
def setup(self):
@@ -25,15 +25,18 @@ class MultiHome(Addon):
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
@@ -48,6 +51,7 @@ class MultiHome(Addon):
requestFactory.getRequest = getRequest
+
def bestInterface(self, pluginName, account):
best = None
for interface in self.interfaces:
@@ -62,13 +66,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/pyload/plugins/addon/RestartFailed.py b/pyload/plugins/addon/RestartFailed.py
index 7d736db46..879836bcf 100644
--- a/pyload/plugins/addon/RestartFailed.py
+++ b/pyload/plugins/addon/RestartFailed.py
@@ -4,18 +4,18 @@ from pyload.plugins.base.Addon import Addon
class RestartFailed(Addon):
- __name__ = "RestartFailed"
- __type__ = "addon"
- __version__ = "1.55"
+ __name__ = "RestartFailed"
+ __type__ = "addon"
+ __version__ = "1.57"
- __config__ = [("activated", "bool", "Activated", False),
- ("interval", "int", "Check interval in minutes", 90)]
+ __config__ = [("interval", "int", "Check interval in minutes", 90)]
__description__ = """Periodically restart all failed downloads in queue"""
- __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
+ __license__ = "GPLv3"
+ __authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
- event_list = ["pluginConfigChanged"]
+ # event_list = ["pluginConfigChanged"]
MIN_INTERVAL = 15 * 60 #: 15m minimum check interval (value is in seconds)
@@ -30,13 +30,15 @@ class RestartFailed(Addon):
else:
self.logDebug("Invalid interval value, kept current")
+
def periodical(self):
- self.logInfo(_("Restart failed downloads"))
- self.api.restartFailed()
+ self.logDebug(_("Restart failed downloads"))
+ self.core.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/pyload/plugins/addon/UnSkipOnFail.py b/pyload/plugins/addon/UnSkipOnFail.py
index 7ab069e93..5122e21eb 100644
--- a/pyload/plugins/addon/UnSkipOnFail.py
+++ b/pyload/plugins/addon/UnSkipOnFail.py
@@ -8,14 +8,15 @@ from pyload.utils import fs_encode
class UnSkipOnFail(Addon):
- __name__ = "UnSkipOnFail"
- __type__ = "addon"
+ __name__ = "UnSkipOnFail"
+ __type__ = "addon"
__version__ = "0.01"
__config__ = [("activated", "bool", "Activated", True)]
__description__ = """When a download fails, restart skipped duplicates"""
- __authors__ = [("hagg", None)]
+ __license__ = "GPLv3"
+ __authors__ = [("hagg", None)]
def downloadFailed(self, pyfile):
@@ -31,6 +32,7 @@ class UnSkipOnFail(Addon):
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".
@@ -60,6 +62,7 @@ class UnSkipOnFail(Addon):
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/pyload/plugins/addon/WindowsPhoneToastNotify.py b/pyload/plugins/addon/WindowsPhoneToastNotify.py
index e6605dfb2..e35f74e84 100644
--- a/pyload/plugins/addon/WindowsPhoneToastNotify.py
+++ b/pyload/plugins/addon/WindowsPhoneToastNotify.py
@@ -7,22 +7,23 @@ from pyload.plugins.base.Addon import Addon
class WindowsPhoneToastNotify(Addon):
- __name__ = "WindowsPhoneToastNotify"
- __type__ = "addon"
+ __name__ = "WindowsPhoneToastNotify"
+ __type__ = "addon"
__version__ = "0.02"
- __config__ = [("activated", "bool", "Activated", False),
- ("force", "bool", "Force even if client is connected", False),
+ __config__ = [("force", "bool", "Force even if client is connected", False),
("pushId", "str", "pushId", ""),
("pushUrl", "str", "pushUrl", ""),
("pushTimeout", "int", "Timeout between notifications in seconds", 0)]
__description__ = """Send push notifications to Windows Phone"""
- __authors__ = [("Andy Voigt", "phone-support@hotmail.de")]
+ __license__ = "GPLv3"
+ __authors__ = [("Andy Voigt", "phone-support@hotmail.de")]
def setup(self):
- self.info = {}
+ self.info = {} #@TODO: Remove in 0.4.10
+
def getXmlData(self):
myxml = ("<?xml version='1.0' encoding='utf-8'?> <wp:Notification xmlns:wp='WPNotification'> "
@@ -30,6 +31,7 @@ class WindowsPhoneToastNotify(Addon):
"</wp:Toast> </wp:Notification>")
return myxml
+
def doRequest(self):
URL = self.getConfig("pushUrl")
request = self.getXmlData()
@@ -45,6 +47,7 @@ class WindowsPhoneToastNotify(Addon):
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/pyload/plugins/addon/XMPPInterface.py b/pyload/plugins/addon/XMPPInterface.py
index de04f05fb..07db5c66a 100644
--- a/pyload/plugins/addon/XMPPInterface.py
+++ b/pyload/plugins/addon/XMPPInterface.py
@@ -10,12 +10,11 @@ from pyload.plugins.addon.IRCInterface import IRCInterface
class XMPPInterface(IRCInterface, JabberClient):
- __name__ = "XMPPInterface"
- __type__ = "addon"
+ __name__ = "XMPPInterface"
+ __type__ = "addon"
__version__ = "0.11"
- __config__ = [("activated", "bool", "Activated", False),
- ("jid", "str", "Jabber ID", "user@exmaple-jabber-server.org"),
+ __config__ = [("jid", "str", "Jabber ID", "user@exmaple-jabber-server.org"),
("pw", "str", "Password", ""),
("tls", "bool", "Use TLS", False),
("owners", "str", "List of JIDs accepting commands from", "me@icq-gateway.org;some@msn-gateway.org"),
@@ -24,11 +23,13 @@ class XMPPInterface(IRCInterface, JabberClient):
("captcha", "bool", "Send captcha requests", True)]
__description__ = """Connect to jabber and let owner perform different tasks"""
- __authors__ = [("RaNaN", "RaNaN@pyload.org")]
+ __license__ = "GPLv3"
+ __authors__ = [("RaNaN", "RaNaN@pyload.org")]
implements(IMessageHandlersProvider)
+
def __init__(self, core, manager):
IRCInterface.__init__(self, core, manager)
@@ -57,11 +58,13 @@ class XMPPInterface(IRCInterface, JabberClient):
self,
]
+
def coreReady(self):
self.new_package = {}
self.start()
+
def packageFinished(self, pypack):
try:
if self.getConfig("info_pack"):
@@ -69,6 +72,7 @@ class XMPPInterface(IRCInterface, JabberClient):
except:
pass
+
def downloadFinished(self, pyfile):
try:
if self.getConfig("info_file"):
@@ -77,6 +81,7 @@ class XMPPInterface(IRCInterface, JabberClient):
except:
pass
+
def run(self):
# connect to IRC etc.
self.connect()
@@ -85,21 +90,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.
@@ -107,6 +117,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()
@@ -157,16 +168,18 @@ class XMPPInterface(IRCInterface, JabberClient):
messages.append(m)
except Exception, e:
- self.logError(repr(e))
+ self.logError(e)
return messages
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(";"):
@@ -186,9 +199,11 @@ class XMPPInterface(IRCInterface, JabberClient):
stream.send(m)
+
def beforeReconnecting(self, ip):
self.disconnect()
+
def afterReconnecting(self, ip):
self.connect()
@@ -201,24 +216,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.