summaryrefslogtreecommitdiffstats
path: root/module/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'module/plugins')
-rw-r--r--module/plugins/Plugin.py8
-rw-r--r--module/plugins/accounts/RapidshareCom.py51
-rw-r--r--module/plugins/accounts/UploadedTo.py35
-rw-r--r--module/plugins/crypter/YoutubeBatch.py33
-rw-r--r--module/plugins/crypter/YoutubeChannel.py52
-rw-r--r--module/plugins/hooks/IRCInterface.py244
-rw-r--r--module/plugins/hooks/UnRar.py4
-rw-r--r--module/plugins/hooks/XMPPInterface.py229
-rw-r--r--module/plugins/hoster/NetloadIn.py20
-rw-r--r--module/plugins/hoster/ShareCx.py155
-rw-r--r--module/plugins/hoster/ShareonlineBiz.py31
-rw-r--r--module/plugins/hoster/YoutubeCom.py7
12 files changed, 635 insertions, 234 deletions
diff --git a/module/plugins/Plugin.py b/module/plugins/Plugin.py
index 6834962e7..f64a5defb 100644
--- a/module/plugins/Plugin.py
+++ b/module/plugins/Plugin.py
@@ -34,6 +34,14 @@ from os import makedirs
from tempfile import NamedTemporaryFile
from mimetypes import guess_type
+from itertools import islice
+
+def chunks(iterable, size):
+ it = iter(iterable)
+ item = list(islice(it, size))
+ while item:
+ yield item
+ item = list(islice(it, size))
def dec(func):
def new(*args):
diff --git a/module/plugins/accounts/RapidshareCom.py b/module/plugins/accounts/RapidshareCom.py
index 052470ada..7f5fff84d 100644
--- a/module/plugins/accounts/RapidshareCom.py
+++ b/module/plugins/accounts/RapidshareCom.py
@@ -28,31 +28,34 @@ class RapidshareCom(Account):
__author_mail__ = ("mkaay@mkaay.de")
def getAccountInfo(self, user):
- data = None
- for account in self.accounts.items():
- if account[0] == user:
- data = account[1]
- if not data:
- return
- req = self.core.requestFactory.getRequest(self.__name__, user)
- api_url_base = "http://api.rapidshare.com/cgi-bin/rsapi.cgi"
- api_param_prem = {"sub": "getaccountdetails_v1", "type": "prem", "login": user, "password": data["password"], "withcookie": 1}
- src = req.load(api_url_base, cookies=False, get=api_param_prem)
- if src.startswith("ERROR"):
- return
- fields = src.split("\n")
- info = {}
- for t in fields:
- if not t.strip():
- continue
- k, v = t.split("=")
- info[k] = v
+ try:
+ data = None
+ for account in self.accounts.items():
+ if account[0] == user:
+ data = account[1]
+ if not data:
+ return
+ req = self.core.requestFactory.getRequest(self.__name__, user)
+ api_url_base = "http://api.rapidshare.com/cgi-bin/rsapi.cgi"
+ api_param_prem = {"sub": "getaccountdetails_v1", "type": "prem", "login": user, "password": data["password"], "withcookie": 1}
+ src = req.load(api_url_base, cookies=False, get=api_param_prem)
+ if src.startswith("ERROR"):
+ return
+ fields = src.split("\n")
+ info = {}
+ for t in fields:
+ if not t.strip():
+ continue
+ k, v = t.split("=")
+ info[k] = v
+
+ out = Account.getAccountInfo(self, user)
+ tmp = {"validuntil":None, "login":str(info["accountid"]), "trafficleft":int(info["tskb"]), "type":self.__name__}
+ out.update(tmp)
- out = Account.getAccountInfo(self, user)
- tmp = {"validuntil":None, "login":str(info["accountid"]), "trafficleft":int(info["tskb"]), "type":self.__name__}
- out.update(tmp)
-
- return out
+ return out
+ except:
+ return Account.getAccountInfo(self, user)
def login(self, user, data):
req = self.core.requestFactory.getRequest(self.__name__, user)
diff --git a/module/plugins/accounts/UploadedTo.py b/module/plugins/accounts/UploadedTo.py
index d2aa22b22..926f91255 100644
--- a/module/plugins/accounts/UploadedTo.py
+++ b/module/plugins/accounts/UploadedTo.py
@@ -30,22 +30,25 @@ class UploadedTo(Account):
__author_mail__ = ("mkaay@mkaay.de")
def getAccountInfo(self, user):
- data = None
- for account in self.accounts.items():
- if account[0] == user:
- data = account[1]
- if not data:
- return
- req = self.core.requestFactory.getRequest(self.__name__, user)
- html = req.load("http://uploaded.to/", cookies=True)
- raw_traffic = re.search(r"Traffic left: </span><span class=.*?>(.*?)</span>", html).group(1)
- raw_valid = re.search(r"Valid until: </span> <span class=.*?>(.*?)</span>", html).group(1)
- traffic = int(self.parseTraffic(raw_traffic))
- validuntil = int(mktime(strptime(raw_valid.strip(), "%d-%m-%Y %H:%M")))
- out = Account.getAccountInfo(self, user)
- tmp = {"login":user, "validuntil":validuntil, "trafficleft":traffic, "type":self.__name__}
- out.update(tmp)
- return out
+ try:
+ data = None
+ for account in self.accounts.items():
+ if account[0] == user:
+ data = account[1]
+ if not data:
+ return
+ req = self.core.requestFactory.getRequest(self.__name__, user)
+ html = req.load("http://uploaded.to/", cookies=True)
+ raw_traffic = re.search(r"Traffic left: </span><span class=.*?>(.*?)</span>", html).group(1)
+ raw_valid = re.search(r"Valid until: </span> <span class=.*?>(.*?)</span>", html).group(1)
+ traffic = int(self.parseTraffic(raw_traffic))
+ validuntil = int(mktime(strptime(raw_valid.strip(), "%d-%m-%Y %H:%M")))
+ out = Account.getAccountInfo(self, user)
+ tmp = {"login":user, "validuntil":validuntil, "trafficleft":traffic, "type":self.__name__}
+ out.update(tmp)
+ return out
+ except:
+ return Account.getAccountInfo(self, user)
def login(self, user, data):
req = self.core.requestFactory.getRequest(self.__name__, user)
diff --git a/module/plugins/crypter/YoutubeBatch.py b/module/plugins/crypter/YoutubeBatch.py
new file mode 100644
index 000000000..091c8558a
--- /dev/null
+++ b/module/plugins/crypter/YoutubeBatch.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import re
+
+from module.plugins.Crypter import Crypter
+
+class YoutubeBatch(Crypter):
+ __name__ = "YoutubeBatch"
+ __type__ = "container"
+ __pattern__ = r"http://(www\.)?(de\.)?\youtube\.com/user/*"
+ __version__ = "0.9"
+ __description__ = """Youtube.com Channel Download Plugin"""
+ __author_name__ = ("RaNaN", "Spoob")
+ __author_mail__ = ("RaNaN@pyload.org", "spoob@pyload.org")
+
+ def setup(self):
+ self.user = re.search(r"/user/(.+)", self.pyfile.url).group(1).split("#")[0]
+ self.playlist = re.search(r"/user/%s.*?/user/(.{16})" % self.user, self.pyfile.url).group(1)
+
+ def file_exists(self):
+ if "User not found" in self.req.load("http://gdata.youtube.com/feeds/api/playlists/%s?v=2" % self.playlist):
+ return False
+ return True
+
+ def decrypt(self, pyfile):
+ if not self.file_exists():
+ self.offline()
+ url = "http://gdata.youtube.com/feeds/api/playlists/%s?v=2" % self.playlist
+ rep = self.load(url)
+ new_links = []
+ new_links.extend(re.findall(r"href\='(http:\/\/www.youtube.com\/watch\?v\=[^']+)&", rep))
+ self.packages.append((self.pyfile.package().name, new_links, self.pyfile.package().name))
diff --git a/module/plugins/crypter/YoutubeChannel.py b/module/plugins/crypter/YoutubeChannel.py
deleted file mode 100644
index 292be06af..000000000
--- a/module/plugins/crypter/YoutubeChannel.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import re
-
-from module.plugins.Crypter import Crypter
-
-class YoutubeChannel(Crypter):
- __name__ = "YoutubeChannel"
- __type__ = "container"
- __pattern__ = r"http://(www\.)?(de\.)?\youtube\.com/user/*"
- __version__ = "0.9"
- __description__ = """Youtube.com Channel Download Plugin"""
- __author_name__ = ("RaNaN", "Spoob")
- __author_mail__ = ("RaNaN@pyload.org", "spoob@pyload.org")
-
- def __init__(self, parent):
- Crypter.__init__(self, parent)
- self.parent = parent
- self.html = None
- self.read_config()
- self.user = re.search(r"/user/(.+)", self.parent.url).group(1).split("#")[0]
-
- def file_exists(self):
- if "User not found" in self.req.load("http://gdata.youtube.com/feeds/api/users/%s" % self.user):
- return False
- return True
-
- def proceed(self, url, location):
- max_videos = self.config['max_videos']
- if not max_videos:
- max_videos = 1000 #max video a user can upload
- page = 0
- temp_links = []
- if "," in self.config['video_groups']:
- video_groups = self.config['video_groups'].split(",")
- else:
- video_groups = [self.config['video_groups']]
- for group in video_groups:
- for start_index in range(1, int(max_videos), 50):
- max_results = max_videos - page * 50
- if max_results > 50:
- max_results = 50
- url = "http://gdata.youtube.com/feeds/api/users/%s/%s?max-results=%i&start-index=%i" % (self.user, group, max_results, start_index)
- rep = self.req.load(url)
- new_links = re.findall(r"href\='(http:\/\/www.youtube.com\/watch\?v\=[^']+)&", rep)
- if new_links != []:
- temp_links.extend(new_links)
- else:
- break
- page += 1
- self.links = temp_links
diff --git a/module/plugins/hooks/IRCInterface.py b/module/plugins/hooks/IRCInterface.py
index a9d9639d4..8d50647e3 100644
--- a/module/plugins/hooks/IRCInterface.py
+++ b/module/plugins/hooks/IRCInterface.py
@@ -15,6 +15,7 @@
along with this program; if not, see <http://www.gnu.org/licenses/>.
@author: RaNaN
+ @author: jeix
@interface-version: 0.2
"""
@@ -33,12 +34,12 @@ class IRCInterface(Thread, Hook):
__version__ = "0.1"
__description__ = """connect to irc and let owner perform different tasks"""
__config__ = [("activated", "bool", "Activated", "False"),
- ("host", "str", "IRC-Server Address", ""),
+ ("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"),
("nick", "str", "Nickname the Client will take", "pyLoad-IRC"),
- ("owner", "str", "Nickname the Client will accept commands from", "Enter your nick here"),
+ ("owner", "str", "Nickname the Client will accept commands from", "Enter your nick here!"),
("info_file", "bool", "Inform about every file finished", "False"),
("info_pack", "bool", "Inform about every package finished", "True")]
__author_name__ = ("Jeix")
@@ -48,27 +49,19 @@ class IRCInterface(Thread, Hook):
Thread.__init__(self)
Hook.__init__(self, core)
self.setDaemon(True)
+ self.sm = core.server_methods
def coreReady(self):
self.new_package = {}
self.abort = False
- self.host = self.getConfig("host") + ":" + str(self.getConfig("port"))
- self.owner = self.getConfig("owner")
- self.nick = self.getConfig("nick")
-
- #self.targets = irc_targets # where replies will go to
- #if len(self.targets) < 1:
-
- self.targets = [self.getConfig("owner")]
-
self.links_added = 0
self.start()
- def packageFinished(self, pypack):
+ def packageFinished(self, pypack):
try:
if self.getConfig("info_pack"):
self.response(_("Package finished: %s") % pypack.name)
@@ -85,15 +78,16 @@ class IRCInterface(Thread, Hook):
def run(self):
# connect to IRC etc.
self.sock = socket.socket()
- temp = self.host.split(":", 1)
- self.sock.connect((temp[0], int(temp[1])))
- self.sock.send("NICK %s\r\n" % self.nick)
- self.sock.send("USER %s %s bla :%s\r\n" % (self.nick, self.host, self.nick))
- for t in self.targets:
- if t.startswith("#"):
- self.sock.send("JOIN %s\r\n" % t)
- self.log.info("pyLoadIRC: Connected to %s!" % self.host)
- self.log.info("pyLoadIRC: Switching to listening mode!")
+ host = self.getConfig("host")
+ self.sock.connect((host, self.getConfig("port")))
+ 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))
+ for t in self.getConfig("owner").split():
+ if t.strip().startswith("#"):
+ self.sock.send("JOIN %s\r\n" % t.strip())
+ self.log.info("pyLoad IRC: Connected to %s!" % host)
+ self.log.info("pyLoad IRC: Switching to listening mode!")
try:
self.main_loop()
@@ -101,7 +95,6 @@ class IRCInterface(Thread, Hook):
self.sock.send("QUIT :byebye\r\n")
print_exc()
self.sock.close()
- sys.exit(1)
def main_loop(self):
@@ -144,14 +137,27 @@ class IRCInterface(Thread, Hook):
def handle_events(self, msg):
- if msg["origin"].split("!", 1)[0] != self.owner:
+ if not msg["origin"].split("!", 1)[0] in self.getConfig("owner").split():
return
- if msg["target"].split("!", 1)[0] != self.nick:
+ if msg["target"].split("!", 1)[0] != self.getConfig("nick"):
return
if msg["action"] != "PRIVMSG":
return
+
+ # HANDLE CTCP ANTI FLOOD/BOT PROTECTION
+ if msg["text"] == "\x01VERSION\x01":
+ self.log.debug("Sending CTCP VERSION.")
+ self.sock.send("NOTICE %s :%s\r\n" % (msg['origin'], "pyLoad! IRC Interface"))
+ return
+ elif msg["text"] == "\x01TIME\x01":
+ self.log.debug("Sending CTCP TIME.")
+ self.sock.send("NOTICE %s :%d\r\n" % (msg['origin'], time.time()))
+ return
+ elif msg["text"] == "\x01LAG\x01":
+ self.log.debug("Received CTCP LAG.") # don't know how to answer
+ return
trigger = "pass"
args = None
@@ -163,30 +169,34 @@ class IRCInterface(Thread, Hook):
handler = getattr(self, "event_%s" % trigger, self.event_pass)
try:
- handler(args)
+ res = handler(args)
+ for line in res:
+ self.response(line, msg["origin"])
except Exception, e:
- self.log.error("pyLoadIRC: "+ repr(e))
+ self.log.error("pyLoad IRC: "+ repr(e))
- def response(self, msg):
- #print _(msg)
- for t in self.targets:
- self.sock.send("PRIVMSG %s :%s\r\n" % (t, msg))
+ def response(self, msg, origin=""):
+ if origin == "":
+ for t in self.getConfig("owner").split():
+ self.sock.send("PRIVMSG %s :%s\r\n" % (t.strip(), msg))
+ else:
+ self.sock.send("PRIVMSG %s :%s\r\n" % (origin.split("!", 1)[0], msg))
#### Events
def event_pass(self, args):
- pass
+ return []
def event_status(self, args):
- downloads = self.core.status_downloads()
+ downloads = self.sm.status_downloads()
if len(downloads) < 1:
- self.response("INFO: There are no active downloads currently.")
- return
+ return ["INFO: There are no active downloads currently."]
- self.response("ID - Name - Status - Speed - ETA - Progress")
+ lines = []
+ lines.append("ID - Name - Status - Speed - ETA - Progress")
for data in downloads:
- self.response("#%d - %s - %s - %s - %s - %s" %
+ lines.append("#%d - %s - %s - %s - %s - %s" %
(
data['id'],
data['name'],
@@ -196,103 +206,114 @@ class IRCInterface(Thread, Hook):
"%d/%d MB (%d%%)" % ((data['size']-data['kbleft']) / 1024, data['size'] / 1024, data['percent'])
)
)
+ return lines
def event_queue(self, args):
# just forward for now
- self.event_status(args)
+ return self.event_status(args)
def event_collector(self, args):
- ps = self.core.get_collector()
+ ps = self.sm.get_collector()
if len(ps) == 0:
- self.response("INFO: No packages in collector!")
- return
+ return ["INFO: No packages in collector!"]
+ lines = []
for packdata in ps:
- self.response('PACKAGE: Package "%s" with id #%d' % (packdata['package_name'], packdata['id']))
- for fileid in self.core.get_package_files(packdata['id']):
- fileinfo = self.core.get_file_info(fileid)
- self.response('#%d FILE: %s (#%d)' % (packdata['id'], fileinfo["filename"], fileinfo["id"]))
+ lines.append('PACKAGE: Package "%s" with id #%d' % (packdata['package_name'], packdata['id']))
+ for fileid in self.sm.get_package_files(packdata['id']):
+ fileinfo = self.sm.get_file_info(fileid)
+ lines.append('#%d FILE: %s (#%d)' % (packdata['id'], fileinfo["filename"], fileinfo["id"]))
+
+ return lines
def event_links(self, args):
- fids = self.core.get_files()
+ fids = self.sm.get_files()
if len(fids) == 0:
- self.response("INFO: No links.")
- return
+ return ["INFO: No links."]
+ lines = []
for fid in fids:
- info = self.core.get_file_info(fid)
- self.response('LINK #%d: %s [%s]' % (fid, info["filename"], info["status_type"]))
+ info = self.sm.get_file_info(fid)
+ lines.append('LINK #%d: %s [%s]' % (fid, info["filename"], info["status_type"]))
+
+ return lines
def event_packages(self, args):
- pids = self.core.get_packages()
+ pids = self.sm.get_packages()
if len(pids) == 0:
- self.response("INFO: No packages.")
- return
+ return ["INFO: No packages."]
+ lines = []
for pid in pids:
- data = self.core.get_package_data(pid)
- self.response('PACKAGE #%d: %s (%d links)' % (pid, data["package_name"], len(self.core.get_package_files(pid))))
+ data = self.sm.get_package_data(pid)
+ lines.append('PACKAGE #%d: %s (%d links)' % (pid, data["package_name"], len(self.sm.get_package_files(pid))))
+
+ return lines
def event_info(self, args):
if not args:
- self.response('ERROR: Use info like this: info <id>')
- return
+ return ['ERROR: Use info like this: info <id>']
- info = self.core.get_file_info(int(args[0]))
- self.response('LINK #%d: %s (%d) [%s bytes]' % (info['id'], info['filename'], info['size'], info['status_type']))
+ info = self.sm.get_file_info(int(args[0]))
+ return ['LINK #%d: %s (%d) [%s bytes]' % (info['id'], info['filename'], info['size'], info['status_type'])]
def event_packinfo(self, args):
if not args:
- self.response('ERROR: Use packinfo like this: packinfo <id>')
- return
+ return ['ERROR: Use packinfo like this: packinfo <id>']
- packdata = self.core.get_package_data(int(args[0]))
- self.response('PACKAGE: Package "%s" with id #%d' % (packdata['package_name'], packdata['id']))
- for fileid in self.core.get_package_files(packdata['id']):
- fileinfo = self.core.get_file_info(fileid)
- self.response('#%d LINK: %s (#%d)' % (packdata['id'], fileinfo["filename"], fileinfo["id"]))
+ lines = []
+ packdata = self.sm.get_package_data(int(args[0]))
+ lines.append('PACKAGE: Package "%s" with id #%d' % (packdata['package_name'], packdata['id']))
+ for fileid in self.sm.get_package_files(packdata['id']):
+ fileinfo = self.sm.get_file_info(fileid)
+ lines.append('#%d LINK: %s (#%d)' % (packdata['id'], fileinfo["filename"], fileinfo["id"]))
+
+ return lines
def event_start(self, args):
if not args:
count = 0
- for packdata in self.core.get_collector_packages():
- self.core.push_package_2_queue(packdata['id'])
+ for packdata in self.sm.get_collector_packages():
+ self.sm.push_package_2_queue(packdata['id'])
count += 1
-
- self.response("INFO: %d downloads started." % count)
- return
+
+ return ["INFO: %d downloads started." % count]
+ lines = []
for val in args:
id = int(val.strip())
- self.core.push_package_2_queue(id)
- self.response("INFO: Starting download #%d" % id)
+ self.sm.push_package_2_queue(id)
+ lines.append("INFO: Starting download #%d" % id)
+
+ return lines
def event_stop(self, args):
if not args:
- self.core.stop_downloads()
- self.response("INFO: All downloads stopped.")
- return
+ self.sm.stop_downloads()
+ return ["INFO: All downloads stopped."]
+ lines = []
for val in args:
id = int(val.strip())
- self.core.stop_download("", id)
- self.response("INFO: Download #%d stopped." % id)
+ self.sm.stop_download("", id)
+ lines.append("INFO: Download #%d stopped." % id)
+
+ return lines
def event_add(self, args):
if len(args) != 2:
- self.response('ERROR: Add links like this: "add <package|id> <link>". '\
- 'This will add the link <link> to to the package <package> / the package with id <id>!')
- return
+ return ['ERROR: Add links like this: "add <package|id> <link>". '\
+ 'This will add the link <link> to to the package <package> / the package with id <id>!']
def get_pack_id(pack):
if pack.isdigit():
pack = int(pack)
- for packdata in self.core.get_collector_packages():
+ for packdata in self.sm.get_collector_packages():
if packdata['id'] == pack:
return pack
return -1
- for packdata in self.core.get_collector_packages():
+ for packdata in self.sm.get_collector_packages():
if packdata['package_name'] == pack:
return packdata['id']
return -1
@@ -304,56 +325,49 @@ class IRCInterface(Thread, Hook):
count_failed = 0
# verify that we have a valid link
- if not self.core.is_valid_link(link):
- self.response("ERROR: Your specified link is not supported by pyLoad.")
- return
+ #if not self.sm.is_valid_link(link):
+ #return ["ERROR: Your specified link is not supported by pyLoad."]
# get a valid package id (create new package if it doesn't exist)
pack_id = get_pack_id(pack)
if pack_id == -1:
- pack_id = self.core.new_package(pack)
+ pack_id = self.sm.new_package(pack)
# move link into package
- fid = self.core.add_links_to_package(pack_id, [link])
- self.response("INFO: Added %s to Package %s [#%d]" % (link, pack, pack_id))
+ fid = self.sm.add_links_to_package(pack_id, [link])
+ return ["INFO: Added %s to Package %s [#%d]" % (link, pack, pack_id)]
def event_del(self, args):
if len(args) < 2:
- self.response("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)")
- return
+ 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.core.del_packages(map(int, args[1:]))
- self.response("INFO: Deleted %d packages!" % ret)
+ ret = self.sm.del_packages(map(int, args[1:]))
+ return ["INFO: Deleted %d packages!" % ret]
elif args[0] == "-l":
- ret = self.core.del_links(map(int, args[1:]))
- self.response("INFO: Deleted %d links!" % ret)
+ ret = self.sm.del_links(map(int, args[1:]))
+ return ["INFO: Deleted %d links!" % ret]
else:
- self.response("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)")
- return
+ 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_help(self, args):
- self.response("The following commands are available:")
- self.response("add <package|packid> <link> Adds link to package. (creates new package if it does not exist)")
- time.sleep(1)
- self.response("collector Shows all packages in collector")
- self.response("del -p|-l <id> [...] Deletes all packages|links with the ids specified")
- time.sleep(1)
- self.response("info <id> Shows info of the link with id <id>")
- self.response("help Shows this help file")
- time.sleep(1)
- self.response("links Shows all links in pyload")
- self.response("packages Shows all packages in pyload")
- time.sleep(1)
- self.response("packinfo <id> Shows info of the package with id <id>")
- self.response("queue Shows info about the queue")
- time.sleep(1)
- self.response("start [<id>...] Starts the package with id <id> or all packages if no id is given")
- self.response("status Show general download status")
- time.sleep(1)
- self.response("stop [<id>...] Stops the package with id <id> or all packages if no id is given")
+ lines = []
+ lines.append("The following commands are available:")
+ lines.append("add <package|packid> <link> Adds link to package. (creates new package if it does not exist)")
+ lines.append("collector Shows all packages in collector")
+ lines.append("del -p|-l <id> [...] Deletes all packages|links with the ids specified")
+ lines.append("info <id> Shows info of the link with id <id>")
+ lines.append("help Shows this help file")
+ lines.append("links Shows all links in pyload")
+ lines.append("packages Shows all packages in pyload")
+ lines.append("packinfo <id> Shows info of the package with id <id>")
+ lines.append("queue Shows info about the queue")
+ lines.append("start [<id>...] Starts the package with id <id> or all packages if no id is given")
+ lines.append("status Show general download status")
+ lines.append("stop [<id>...] Stops the package with id <id> or all packages if no id is given")
+ return lines
class IRCError(Exception):
diff --git a/module/plugins/hooks/UnRar.py b/module/plugins/hooks/UnRar.py
index 7cc73f265..38a5a55e8 100644
--- a/module/plugins/hooks/UnRar.py
+++ b/module/plugins/hooks/UnRar.py
@@ -30,7 +30,7 @@ class UnRar(Hook):
__name__ = "UnRar"
__version__ = "0.1"
__description__ = """unrar"""
- __config__ = [ ("activated", "bool", "Activated", True),
+ __config__ = [ ("activated", "bool", "Activated", False),
("fullpath", "bool", "extract full path", True),
("overwrite", "bool", "overwrite files", True),
("passwordfile", "str", "unrar passoword file", "unrar_passwords.txt"),
@@ -109,7 +109,7 @@ class UnRar(Hook):
u.crackPassword(passwords=self.passwords, statusFunction=s, overwrite=True, destination=folder)
except WrongPasswordError:
continue
- except CommandError as e:
+ except CommandError , e:
if re.search("Cannot find volume", e.stderr):
continue
try:
diff --git a/module/plugins/hooks/XMPPInterface.py b/module/plugins/hooks/XMPPInterface.py
new file mode 100644
index 000000000..67a7f1b77
--- /dev/null
+++ b/module/plugins/hooks/XMPPInterface.py
@@ -0,0 +1,229 @@
+# -*- coding: utf-8 -*-
+
+"""
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+ @author: RaNaN
+ @interface-version: 0.2
+"""
+
+import socket
+import sys
+from threading import Thread
+import time
+from time import sleep
+from traceback import print_exc
+
+from pyxmpp.all import JID,Iq,Presence,Message,StreamError
+from pyxmpp.jabber.client import JabberClient
+from pyxmpp.interface import implements
+from pyxmpp.interfaces import *
+from pyxmpp.streamtls import TLSSettings
+
+from module.plugins.Hook import Hook
+from module.plugins.hooks.IRCInterface import IRCInterface
+
+class XMPPInterface(IRCInterface, JabberClient):
+ __name__ = "XMPPInterface"
+ __version__ = "0.1"
+ __description__ = """connect to jabber and let owner perform different tasks"""
+ __config__ = [("activated", "bool", "Activated", "False"),
+ ("jid", "str", "Jabber ID", "user@exmaple-jabber-server.org"),
+ ("pw", "str", "Password", ""),
+ ("owners", "str", "List of JIDs accepting commands from", "me@icq-gateway.org;some@msn-gateway.org"),
+ ("info_file", "bool", "Inform about every file finished", "False"),
+ ("info_pack", "bool", "Inform about every package finished", "True")]
+ __author_name__ = ("RaNaN")
+ __author_mail__ = ("RaNaN@pyload.org")
+
+ implements(IMessageHandlersProvider)
+
+ def __init__(self, core):
+ IRCInterface.__init__(self, core)
+
+ self.jid = JID(self.getConfig("jid"))
+ password = self.getConfig("pw")
+
+ # if bare JID is provided add a resource -- it is required
+ if not self.jid.resource:
+ self.jid=JID(self.jid.node, self.jid.domain, "pyLoad")
+
+ tls_settings = None
+
+ # setup client with provided connection information
+ # and identity data
+ JabberClient.__init__(self, self.jid, password,
+ disco_name="pyLoad XMPP Client", disco_type="bot",
+ tls_settings = tls_settings)
+
+ self.interface_providers = [
+ VersionHandler(self),
+ self,
+ ]
+
+ def coreReady(self):
+ self.new_package = {}
+
+ self.start()
+
+ def packageFinished(self, pypack):
+
+ try:
+ if self.getConfig("info_pack"):
+ self.announce(_("Package finished: %s") % pypack.name)
+ except:
+ pass
+
+ def downloadFinished(self, pyfile):
+ try:
+ if self.getConfig("info_file"):
+ self.announce(_("Download finished: %s @ %s") % (pyfile.name, pyfile.pluginname) )
+ except:
+ pass
+
+ def run(self):
+ # connect to IRC etc.
+ self.connect()
+ try:
+ self.loop(1)
+ except Exception, ex:
+ self.core.log.error("pyLoad XMPP: %s" % str(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.log.debug("pyLoad XMPP: *** State changed: %s %r ***" % (state,arg) )
+
+ def get_message_handlers(self):
+ """Return list of (message_type, message_handler) tuples.
+
+ The handlers returned will be called when matching message is received
+ in a client session."""
+ return [
+ ("normal", self.message),
+ ]
+
+ def message(self,stanza):
+ """Message handler for the component."""
+ subject=stanza.get_subject()
+ body=stanza.get_body()
+ t=stanza.get_type()
+ self.log.debug(_(u'pyLoad XMPP: Message from %s received.') % (unicode(stanza.get_from(),)))
+ self.log.debug(_(u'pyLoad XMPP: Body: %s') % body)
+
+ if stanza.get_type()=="headline":
+ # 'headline' messages should never be replied to
+ return True
+ if subject:
+ subject=u"Re: "+subject
+
+ to_jid = stanza.get_from()
+ from_jid = stanza.get_to()
+
+ #j = JID()
+ to_name = to_jid.as_utf8()
+ from_name = from_jid.as_utf8()
+
+ names = self.getConfig("owners").split(";")
+
+ if to_name in names or to_jid.node+"@"+to_jid.domain in names:
+
+ messages = []
+
+ trigger = "pass"
+ args = None
+
+ temp = body.split()
+ trigger = temp[0]
+ if len(temp) > 1:
+ args = temp[1:]
+
+ handler = getattr(self, "event_%s" % trigger, self.event_pass)
+ try:
+ res = handler(args)
+ for line in res:
+ m=Message(
+ to_jid=to_jid,
+ from_jid=from_jid,
+ stanza_type=stanza.get_type(),
+ subject=subject,
+ body=line)
+
+ messages.append(m)
+ except Exception, e:
+ self.log.error("pyLoad XMPP: "+ repr(e))
+
+ return messages
+
+ else:
+ return True
+
+
+ def announce(self, message):
+ """ send message to all owners"""
+ for user in self.getConfig("owners").split(";"):
+
+ self.log.debug(_("pyLoad XMPP: Send message to %s") % user)
+
+ to_jid = JID(user)
+
+ m = Message(from_jid=self.jid,
+ to_jid=to_jid,
+ stanza_type="chat",
+ body=message)
+
+ self.stream.send(m)
+
+
+class VersionHandler(object):
+ """Provides handler for a version query.
+
+ This class will answer version query and announce 'jabber:iq:version' namespace
+ in the client's disco#info results."""
+
+ 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.
+
+ jabber:iq:version queries are not supported directly by PyXMPP, so the
+ XML node is accessed directly through the libxml2 API. This should be
+ used very carefully!"""
+ iq=iq.make_result_response()
+ q=iq.new_query("jabber:iq:version")
+ q.newTextChild(q.ns(),"name","Echo component")
+ q.newTextChild(q.ns(),"version","1.0")
+ return iq
+ \ No newline at end of file
diff --git a/module/plugins/hoster/NetloadIn.py b/module/plugins/hoster/NetloadIn.py
index 9e117fa14..6f0cb9461 100644
--- a/module/plugins/hoster/NetloadIn.py
+++ b/module/plugins/hoster/NetloadIn.py
@@ -4,8 +4,12 @@
import re
from time import sleep
+
from module.plugins.Hoster import Hoster
from module.network.Request import getURL
+from module.plugins.Plugin import chunks
+
+
def getInfo(urls):
## returns list of tupels (name, size (in bytes), status (see FileDatabase), url)
@@ -14,14 +18,10 @@ def getInfo(urls):
apiurl = "http://api.netload.in/info.php?auth=Zf9SnQh9WiReEsb18akjvQGqT0I830e8&bz=1&md5=1&file_id="
id_regex = re.compile("http://.*netload\.in/(?:datei(.*?)(?:\.htm|/)|index.php?id=10&file_id=)")
urls_per_query = 80
-
- iterations = len(urls)/urls_per_query
- if len(urls)%urls_per_query > 0:
- iterations = iterations +1
-
- for i in range(iterations):
+
+ for chunk in chunks(urls, urls_per_query):
ids = ""
- for url in urls[i*urls_per_query:(i+1)*urls_per_query]:
+ for url in chunk:
match = id_regex.search(url)
if match:
ids = ids + match.group(1) +";"
@@ -37,19 +37,17 @@ def getInfo(urls):
result = []
- counter = 0
- for r in api.split():
+ for i, r in enumerate(api.split()):
try:
tmp = r.split(";")
try:
size = int(tmp[2])
except:
size = 0
- result.append( (tmp[1], size, 2 if tmp[3] == "online" else 1, urls[(i*80)+counter]) )
+ result.append( (tmp[1], size, 2 if tmp[3] == "online" else 1, chunk[i] ) )
except:
print "Netload prefetch: Error while processing response: "
print r
- counter = counter +1
yield result
diff --git a/module/plugins/hoster/ShareCx.py b/module/plugins/hoster/ShareCx.py
new file mode 100644
index 000000000..e64459754
--- /dev/null
+++ b/module/plugins/hoster/ShareCx.py
@@ -0,0 +1,155 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import re
+from module.plugins.Hoster import Hoster
+from module.plugins.Plugin import chunks
+from module.network.Request import getURL
+#from module.BeautifulSoup import BeautifulSoup
+
+def getInfo(urls):
+ api_url = "http://www.share.cx/uapi?do=check&links="
+
+ for chunk in chunks(urls, 90):
+ get = ""
+ for url in chunk:
+ get += ";"+url
+
+ api = getURL(api_url+get[1:])
+ result = []
+
+ for i, link in enumerate(api.split()):
+ url,name,size = link.split(";")
+ if name and size:
+ status = 2
+ else:
+ status = 1
+
+ if not name: name = chunk[i]
+ if not size: size = 0
+
+ result.append( (name, size, status, chunk[i]) )
+
+ yield result
+
+class ShareCx(Hoster):
+ __name__ = "ShareCx"
+ __type__ = "hoster"
+ __pattern__ = r"http://[\w\.]*?share\.cx/(files|videos)/\d+"
+ __version__ = "0.1"
+ __description__ = """Share.cx Download Hoster"""
+ __author_name__ = ("jeix")
+ __author_mail__ = ("jeix@hasnomail.de")
+
+
+ def setup(self):
+ self.multiDL = False
+
+
+ def process(self, pyfile):
+ self.pyfile = pyfile
+ self.download_html()
+ if not self.file_exists():
+ offline()
+
+ pyfile.name = self.get_file_name()
+ self.doDownload()
+
+
+ def download_html(self):
+ self.html = self.load(self.pyfile.url)
+
+ def doDownload(self):
+ """ returns the absolute downloadable filepath
+ """
+ if self.html == None:
+ self.download_html()
+
+ op = re.search(r'name="op" value="(.*?)"', self.html).group(1)
+ usr_login = re.search(r'name="usr_login" value="(.*?)"', self.html).group(1)
+ id = re.search(r'name="id" value="(.*?)"', self.html).group(1)
+ fname = re.search(r'name="fname" value="(.*?)"', self.html).group(1)
+ referer = re.search(r'name="referer" value="(.*?)"', self.html).group(1)
+ method_free = "Datei+herunterladen"
+
+ self.html = self.load(self.pyfile.url, post={
+ "op" : op,
+ "usr_login" : usr_login,
+ "id" : id,
+ "fname" : fname,
+ "referer" : referer,
+ "method_free" : method_free
+ })
+
+
+ m = re.search(r'startTimer\((\d+)\)', self.html)
+ if m != None:
+ wait_time = int(m.group(1))
+ self.setWait(wait_time)
+ self.wantReconnect = True
+ self.log.debug("%s: IP blocked wait %d seconds." % (self.__name__, wait_time))
+ self.wait()
+
+ m = re.search(r'countdown">.*?(\d+).*?</span>', self.html)
+ if m == None:
+ m = re.search(r'id="countdown_str".*?<span id=".*?">.*?(\d+).*?</span', self.html)
+ if m != None:
+ wait_time = int(m.group(1))
+ self.setWait(wait_time)
+ self.wantReconnect = False
+ self.log.debug("%s: Waiting %d seconds." % (self.__name__, wait_time))
+ self.wait()
+
+
+ op = re.search(r'name="op" value="(.*?)"', self.html).group(1)
+ id = re.search(r'name="id" value="(.*?)"', self.html).group(1)
+ rand = re.search(r'name="rand" value="(.*?)"', self.html).group(1)
+ referer = re.search(r'name="referer" value="(.*?)"', self.html).group(1)
+ method_free = re.search(r'name="method_free" value="(.*?)"', self.html).group(1)
+ method_premium = re.search(r'name="method_premium" value="(.*?)"', self.html).group(1)
+ down_script = re.search(r'name="down_script" value="(.*?)"', self.html).group(1)
+
+ data = {
+ "op" : op,
+ "id" : id,
+ "rand" : rand,
+ "referer" : referer,
+ "method_free" : method_free,
+ "method_premium" : method_premium,
+ "down_script" : down_script
+ }
+
+ if '/captchas/' in self.html:
+ captcha_url = re.search(r'(http://(?:[\w\d]+\.)?.*?/captchas/.*?)').group(1)
+ captcha = self.decryptCaptcha(captcha_url)
+ data["code"] = captcha
+
+
+ self.download(self.pyfile.url, post=data)
+
+ # soup = BeautifulSoup(html)
+ # form = soup.find("form")
+ # postfields = {}
+ # for input in form,findall("input"):
+ # postfields[input["name"]] = input["value"]
+ # postfields["method_free"] = "Datei herunterladen"
+
+ def get_file_name(self):
+ if self.html == None:
+ self.download_html()
+
+ name = re.search(r'alt="Download" /></span>(.*?)</h3>', self.html).group(1)
+ return name
+
+ def file_exists(self):
+ """ returns True or False
+ """
+ if self.html == None:
+ self.download_html()
+
+ if re.search(r'File not found<br>It was deleted due to inactivity or abuse request', self.html) != None:
+ return False
+
+ return True
+
+
diff --git a/module/plugins/hoster/ShareonlineBiz.py b/module/plugins/hoster/ShareonlineBiz.py
index 8646fcc88..42a2bc560 100644
--- a/module/plugins/hoster/ShareonlineBiz.py
+++ b/module/plugins/hoster/ShareonlineBiz.py
@@ -13,19 +13,30 @@ from time import sleep
from module.plugins.Hoster import Hoster
from module.network.Request import getURL
+from module.plugins.Plugin import chunks
+
def getInfo(urls):
api_url_base = "http://www.share-online.biz/linkcheck/linkcheck.php"
- api_param_file = {"links": "\n".join(x.replace("http://www.share-online.biz/dl/","") for x in urls)} #api only supports old style links
- src = getURL(api_url_base, post=api_param_file)
- result = []
- for i, res in enumerate(src.split("\n")):
- if not res:
- continue
- fields = res.split(";")
- status = 2 if fields[1] == "OK" else 3
- result.append((fields[2], int(fields[3]), status, urls[i]))
- yield result
+
+ for chunk in chunks(urls, 90):
+ api_param_file = {"links": "\n".join(x.replace("http://www.share-online.biz/dl/","") for x in chunk)} #api only supports old style links
+ src = getURL(api_url_base, post=api_param_file)
+ result = []
+ for i, res in enumerate(src.split("\n")):
+ if not res:
+ continue
+ fields = res.split(";")
+
+ if fields[1] == "OK":
+ status = 2
+ elif fields[1] in ("DELETED", "NOT FOUND"):
+ status = 1
+ else:
+ status = 3
+
+ result.append((fields[2], int(fields[3]), status, chunk[i]))
+ yield result
class ShareonlineBiz(Hoster):
__name__ = "ShareonlineBiz"
diff --git a/module/plugins/hoster/YoutubeCom.py b/module/plugins/hoster/YoutubeCom.py
index e40b0c9ad..d92d8d128 100644
--- a/module/plugins/hoster/YoutubeCom.py
+++ b/module/plugins/hoster/YoutubeCom.py
@@ -32,9 +32,8 @@ class YoutubeCom(Hoster):
if self.getConf("quality") == "hd" or self.getConf("quality") == "hq":
file_suffix = ".mp4"
- name = re.search(file_name_pattern, html).group(1).replace("/", "") + file_suffix
-
- pyfile.name = name.replace("&amp;", "&").replace("ö", "oe").replace("ä", "ae").replace("ü", "ue")
+ name = (re.search(file_name_pattern, html).group(1).replace("/", "") + file_suffix).decode("utf8")
+ pyfile.name = name #.replace("&amp;", "&").replace("ö", "oe").replace("ä", "ae").replace("ü", "ue")
if self.getConf("quality") == "sd":
quality = "&fmt=6"
@@ -45,4 +44,4 @@ class YoutubeCom(Hoster):
file_url = 'http://youtube.com/get_video?video_id=' + videoId + '&t=' + videoHash + quality + "&asv=2"
- self.download(file_url) \ No newline at end of file
+ self.download(file_url)