diff options
Diffstat (limited to 'module')
34 files changed, 1000 insertions, 216 deletions
diff --git a/module/database/FileDatabase.py b/module/database/FileDatabase.py index 357cd766d..7e7efb028 100644 --- a/module/database/FileDatabase.py +++ b/module/database/FileDatabase.py @@ -877,7 +877,7 @@ class FileMethods(): @style.queue def restartFailed(self): - self.c.execute("UPDATE links SET status=3,error='' WHERE status IN (8, 9)") + self.c.execute("UPDATE links SET status=3,error='' WHERE status IN (6, 8, 9)") @style.queue def findDuplicates(self, id, folder, filename): diff --git a/module/plugins/accounts/DdlstorageCom.py b/module/plugins/accounts/DdlstorageCom.py new file mode 100644 index 000000000..01d165f23 --- /dev/null +++ b/module/plugins/accounts/DdlstorageCom.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +from module.plugins.internal.XFSPAccount import XFSPAccount + +class DdlstorageCom(XFSPAccount): + __name__ = "DdlstorageCom" + __version__ = "0.01" + __type__ = "account" + __description__ = """DDLStorage.com account plugin""" + __author_name__ = ("zoidberg") + __author_mail__ = ("zoidberg@mujmail.cz") + + MAIN_PAGE = "http://ddlstorage.com/"
\ No newline at end of file diff --git a/module/plugins/accounts/FilefactoryCom.py b/module/plugins/accounts/FilefactoryCom.py index 8c04cf49b..73431b546 100644 --- a/module/plugins/accounts/FilefactoryCom.py +++ b/module/plugins/accounts/FilefactoryCom.py @@ -23,32 +23,32 @@ from time import mktime, strptime class FilefactoryCom(Account): __name__ = "FilefactoryCom" - __version__ = "0.1" + __version__ = "0.11" __type__ = "account" __description__ = """filefactory.com account plugin""" __author_name__ = ("zoidberg") __author_mail__ = ("zoidberg@mujmail.cz") - ACCOUNT_INFO_PATTERN = r'Your account is valid until the <strong>(.*?)</strong>' - - def loadAccountInfo(self, user, req): - premium = False - validuntil = -1 - - html = req.load("http://filefactory.com/member/") - if "You are a FileFactory Premium Member" in html: + ACCOUNT_INFO_PATTERN = r'"greenText">Premium member until<.*?datetime="(.*?)"' + + def loadAccountInfo(self, user, req): + html = req.load("http://www.filefactory.com/member/") + + found = re.search(self.ACCOUNT_INFO_PATTERN, html) + if found: premium = True - found = re.search(self.ACCOUNT_INFO_PATTERN, html) - if found: - validuntil = mktime(strptime(re.sub(r"(\d)[a-z]{2} ", r"\1 ", found.group(1)),"%d %B, %Y")) + validuntil = mktime(strptime(re.sub(r"(\d)[a-z]{2} ", r"\1 ", found.group(1)),"%d %B, %Y")) + else: + premium = False + validuntil = -1 return {"premium": premium, "trafficleft": -1, "validuntil": validuntil} def login(self, user, data, req): - html = req.load("http://filefactory.com/member/login.php", post={ + html = req.load("http://www.filefactory.com/member/login.php", post={ "email": user, "password": data["password"], "redirect": "/"}) - if not re.search(r'location:.*?\?login=1', req.http.header, re.I): + if '/member/login.php?err=1' in req.http.header: self.wrongPassword()
\ No newline at end of file diff --git a/module/plugins/accounts/NetloadIn.py b/module/plugins/accounts/NetloadIn.py index 4d05732ce..cef3e298b 100755 --- a/module/plugins/accounts/NetloadIn.py +++ b/module/plugins/accounts/NetloadIn.py @@ -23,7 +23,7 @@ from time import time class NetloadIn(Account): __name__ = "NetloadIn" - __version__ = "0.21" + __version__ = "0.22" __type__ = "account" __description__ = """netload.in account plugin""" __author_name__ = ("RaNaN", "CryNickSystems") diff --git a/module/plugins/accounts/ShareRapidCom.py b/module/plugins/accounts/ShareRapidCom.py index 9828b1f7e..178fe236e 100644 --- a/module/plugins/accounts/ShareRapidCom.py +++ b/module/plugins/accounts/ShareRapidCom.py @@ -5,32 +5,29 @@ from module.plugins.Account import Account class ShareRapidCom(Account): __name__ = "ShareRapidCom" - __version__ = "0.1" + __version__ = "0.3" __type__ = "account" __description__ = """ShareRapid account plugin""" __author_name__ = ("MikyWoW") def loadAccountInfo(self, user, req): src = req.load("http://share-rapid.com/mujucet/", cookies=True) - if "Kredit:" in src: - start = src.index('Kredit:</td><td>') - src = src[start+16:] - start = src.index('GB') - kredit = src[0:start-1] - ret = float(kredit)*1024*1024 - tmp = {"premium": True, "trafficleft": ret, "validuntil": -1} + found = re.search(r'<tr><td>GB:</td><td>(.*?) GB', src) + if found: + ret = float(found.group(1)) * (1 << 20) + tmp = {"premium": True, "trafficleft": ret, "validuntil": -1} else: - tmp = {"premium": False, "trafficleft": None, "validuntil": None} + tmp = {"premium": False, "trafficleft": None, "validuntil": None} return tmp def login(self, user, data, req): htm = req.load("http://share-rapid.com/prihlaseni/", cookies=True) if "Heslo:" in htm: - start = htm.index('id="inp_hash" name="hash" value="') - htm = htm[start+33:] - hashes = htm[0:32] - html = req.load("http://share-rapid.com/prihlaseni/", + start = htm.index('id="inp_hash" name="hash" value="') + htm = htm[start+33:] + hashes = htm[0:32] + htm = req.load("http://share-rapid.com/prihlaseni/", post={"hash": hashes,"login": user, "pass1": data["password"],"remember": 0, "sbmt": "P%C5%99ihl%C3%A1sit"}, cookies=True) - if "Heslo:" in html: - self.wrongPassword()
\ No newline at end of file + if "Heslo:" in htm: + self.wrongPassword()
\ No newline at end of file diff --git a/module/plugins/accounts/StahnuTo.py b/module/plugins/accounts/StahnuTo.py new file mode 100644 index 000000000..8a4523bc5 --- /dev/null +++ b/module/plugins/accounts/StahnuTo.py @@ -0,0 +1,49 @@ +# -*- 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: zoidberg +""" + +from module.plugins.Account import Account +from module.utils import parseFileSize +import re + +class StahnuTo(Account): + __name__ = "StahnuTo" + __version__ = "0.02" + __type__ = "account" + __description__ = """StahnuTo account plugin""" + __author_name__ = ("zoidberg") + __author_mail__ = ("zoidberg@mujmail.cz") + + #login_timeout = 60 + + def loadAccountInfo(self, user, req): + html = req.load("http://www.stahnu.to/") + + found = re.search(r'>VIP: (\d+.*)<', html) + trafficleft = parseFileSize(found.group(1)) * 1024 if found else 0 + + return {"premium": trafficleft > (512 * 1024), "trafficleft": trafficleft, "validuntil": -1} + + def login(self, user, data, req): + html = req.load("http://www.stahnu.to/login.php", post={ + "username": user, + "password": data["password"], + "submit": "Login"}) + + if not '<a href="logout.php">' in html: + self.wrongPassword()
\ No newline at end of file diff --git a/module/plugins/accounts/UlozTo.py b/module/plugins/accounts/UlozTo.py index 0375337b0..0c4ecda6a 100644 --- a/module/plugins/accounts/UlozTo.py +++ b/module/plugins/accounts/UlozTo.py @@ -5,7 +5,7 @@ import re class UlozTo(Account): __name__ = "UlozTo" - __version__ = "0.02" + __version__ = "0.03" __type__ = "account" __description__ = """uloz.to account plugin""" __author_name__ = ("zoidberg") @@ -14,11 +14,14 @@ class UlozTo(Account): TRAFFIC_LEFT_PATTERN = r'<li class="menu-kredit"><a href="/kredit/" title="[^"]*?GB = ([0-9.]+) MB">' def loadAccountInfo(self, user, req): - html = req.load("http://www.ulozto.net/statistiky", decode = True) + #this cookie gets lost somehow after each request + self.phpsessid = req.cj.getCookie("PHPSESSID") + html = req.load("http://www.ulozto.net/", decode = True) + req.cj.setCookie("www.ulozto.net", "PHPSESSID", self.phpsessid) found = re.search(self.TRAFFIC_LEFT_PATTERN, html) trafficleft = int(float(found.group(1).replace(' ','').replace(',','.')) * 1000 / 1.024) if found else 0 - self.premium = True if trafficleft else False + self.premium = True if trafficleft else False return {"validuntil": -1, "trafficleft": trafficleft} diff --git a/module/plugins/accounts/UploadheroCom.py b/module/plugins/accounts/UploadheroCom.py new file mode 100644 index 000000000..f1e0649e6 --- /dev/null +++ b/module/plugins/accounts/UploadheroCom.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from module.plugins.Account import Account
+import re,datetime,time
+
+class UploadheroCom(Account):
+ __name__ = "UploadheroCom"
+ __version__ = "0.1"
+ __type__ = "account"
+ __description__ = """Uploadhero.com account plugin"""
+ __author_name__ = ("mcmyst")
+ __author_mail__ = ("mcmyst@hotmail.fr")
+
+
+ def loadAccountInfo(self, user, req):
+ premium_pattern = re.compile('Il vous reste <span class="bleu">([0-9]+)</span> jours premium.')
+
+ data = self.getAccountData(user)
+ page = req.load("http://uploadhero.com/my-account")
+
+ if premium_pattern.search(page):
+ end_date = datetime.date.today() + datetime.timedelta(days=int(premium_pattern.search(page).group(1)))
+ end_date = time.mktime(future.timetuple())
+ account_info = {"validuntil": end_date, "trafficleft": -1, "premium": True}
+ else:
+ account_info = {"validuntil": -1, "trafficleft": -1, "premium": False}
+
+ return account_info
+
+ def login(self, user, data, req):
+ page = req.load("http://uploadhero.com/lib/connexion.php", post={"pseudo_login": user, "password_login": data["password"]})
+
+ if "mot de passe invalide" in page:
+ self.wrongPassword()
\ No newline at end of file diff --git a/module/plugins/crypter/C1neonCom.py b/module/plugins/crypter/C1neonCom.py new file mode 100644 index 000000000..e9861ab54 --- /dev/null +++ b/module/plugins/crypter/C1neonCom.py @@ -0,0 +1,129 @@ +# -*- 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: godofdream +""" + +import re +import random +from module.plugins.Crypter import Crypter +from module.common.json_layer import json_loads +class C1neonCom(Crypter): + __name__ = "C1neonCom" + __type__ = "container" + __pattern__ = r"http://(www\.)?c1neon.com/.*?" + __version__ = "0.02" + __config__ = [ + ("changeNameS", "Packagename;Show;Season;Episode", "Rename Show by", "Show"), + ("changeName", "Packagename;Movie", "Rename Movie by", "Movie"), + ("useStreams", "bool", "Use Streams too", False), + ("hosterListMode", "all;onlypreferred", "Use for hosters (if supported)", "all"), + ("randomPreferred", "bool", "Randomize Preferred-List", False), + ("hosterList", "str", "Preferred Hoster list (comma separated, no ending)", "2shared,Bayfiles,Netload,Rapidshare,Share-online"), + ("ignoreList", "str", "Ignored Hoster list (comma separated, no ending)", "Megaupload") + ] + __description__ = """C1neon.Com Container Plugin""" + __author_name__ = ("godofdream") + __author_mail__ = ("soilfiction@gmail.com") + + VALUES_PATTERN = r"var subcats = (.*?)(;</script>|;var)" + SHOW_PATTERN = r"title='(.*?)'" + SERIE_PATTERN = r"<title>.*Serie.*</title>" + + def decrypt(self, pyfile): + src = self.req.load(str(pyfile.url)) + + pattern = re.compile(self.VALUES_PATTERN, re.DOTALL) + data = json_loads(re.search(pattern, src).group(1)) + + # Get package info + links = [] + Showname = re.search(self.SHOW_PATTERN, src) + if Showname: + Showname = Showname.group(1).decode("utf-8") + else: + Showname = self.pyfile.package().name + + if re.search(self.SERIE_PATTERN, src): + for Season in data: + self.logDebug("Season " + Season) + for Episode in data[Season]: + self.logDebug("Episode " + Episode) + links.extend(self.getpreferred(data[Season][Episode])) + if self.getConfig("changeNameS") == "Episode": + self.packages.append((data[Season][Episode]['info']['name'].split("»")[0], links, data[Season][Episode]['info']['name'].split("»")[0])) + links = [] + + if self.getConfig("changeNameS") == "Season": + self.packages.append((Showname + " Season " + Season, links, Showname + " Season " + Season)) + links = [] + + if self.getConfig("changeNameS") == "Show": + if links == []: + self.fail('Could not extract any links (Out of Date?)') + else: + self.packages.append((Showname, links, Showname)) + + elif self.getConfig("changeNameS") == "Packagename": + if links == []: + self.fail('Could not extract any links (Out of Date?)') + else: + self.core.files.addLinks(links, self.pyfile.package().id) + else: + for Movie in data: + links.extend(self.getpreferred(data[Movie])) + if self.getConfig("changeName") == "Movie": + if links == []: + self.fail('Could not extract any links (Out of Date?)') + else: + self.packages.append((Showname, links, Showname)) + + elif self.getConfig("changeName") == "Packagename": + if links == []: + self.fail('Could not extract any links (Out of Date?)') + else: + self.core.files.addLinks(links, self.pyfile.package().id) + + #selects the preferred hoster, after that selects any hoster (ignoring the one to ignore) + #selects only one Hoster + def getpreferred(self, hosterslist): + hosterlist = hosterslist['d'] + if self.getConfig("useStreams"): + hosterlist.append(hosterslist['s']) + + result = [] + preferredList = self.getConfig("hosterList").strip().lower().replace('|',',').replace('.','').replace(';',',').split(',') + if self.getConfig("randomPreferred") == True: + random.shuffle(preferredList) + for preferred in preferredList: + for Hoster in hosterlist: + if preferred == Hoster.split('<')[0].strip().lower().replace('.',''): + for Part in hosterlist[Hoster]: + self.logDebug("selected " + Part[3]) + result.append(str(Part[3])) + return result + + ignorelist = self.getConfig("ignoreList").strip().lower().replace('|',',').replace('.','').replace(';',',').split(',') + if self.getConfig('hosterListMode') == "all": + for Hoster in hosterlist: + if Hoster.split('<')[0].strip().lower().replace('.','') not in ignorelist: + for Part in hosterlist[Hoster]: + self.logDebug("selected " + Part[3]) + result.append(str(Part[3])) + return result + return result + + + diff --git a/module/plugins/crypter/SerienjunkiesOrg.py b/module/plugins/crypter/SerienjunkiesOrg.py index 2178f5300..ebcb5cebc 100644 --- a/module/plugins/crypter/SerienjunkiesOrg.py +++ b/module/plugins/crypter/SerienjunkiesOrg.py @@ -2,7 +2,7 @@ import re from time import sleep - +import random from module.plugins.Crypter import Crypter from module.lib.BeautifulSoup import BeautifulSoup from module.unescape import unescape @@ -10,36 +10,23 @@ from module.unescape import unescape class SerienjunkiesOrg(Crypter): __name__ = "SerienjunkiesOrg" __type__ = "container" - __pattern__ = r"http://.*?serienjunkies.org/.*?" - __version__ = "0.31" - __config__ = [("preferredHoster", "str", "preferred hoster", - "RapidshareCom,UploadedTo,NetloadIn,FilefactoryCom,FreakshareNet,FilebaseTo,MegauploadCom,HotfileCom,DepositfilesCom,EasyshareCom,KickloadCom") - , - ("changeName", "bool", "Take SJ.org episode name", "True")] + __pattern__ = r"http://.*?(serienjunkies.org|dokujunkies.org)/.*?" + __version__ = "0.35" + __config__ = [ + ("changeNameSJ", "Packagename;Show;Season;Format;Episode", "Take SJ.org name", "Show"), + ("changeNameDJ", "Packagename;Show;Format;Episode", "Take DJ.org name", "Show"), + ("randomPreferred", "bool", "Randomize Preferred-List", False), + ("hosterListMode", "OnlyOne;OnlyPreferred(One);OnlyPreferred(All);All", "Use for hosters (if supported)", "All"), + ("hosterList", "str", "Preferred Hoster list (comma separated)", "RapidshareCom,UploadedTo,NetloadIn,FilefactoryCom,FreakshareNet,FilebaseTo,MegauploadCom,HotfileCom,DepositfilesCom,EasyshareCom,KickloadCom"), + ("ignoreList", "str", "Ignored Hoster list (comma separated)", "MegauploadCom") + ] __description__ = """serienjunkies.org Container Plugin""" - __author_name__ = ("mkaay") - __author_mail__ = ("mkaay@mkaay.de") + __author_name__ = ("mkaay", "godofdream") + __author_mail__ = ("mkaay@mkaay.de", "soilfiction@gmail.com") - def setup(self): - self.hosterMap = { - "rc": "RapidshareCom", - "ff": "FilefactoryCom", - "ut": "UploadedTo", - "ul": "UploadedTo", - "nl": "NetloadIn", - "fs": "FreakshareNet", - "fb": "FilebaseTo", - "mu": "MegauploadCom", - "hf": "HotfileCom", - "df": "DepositfilesCom", - "es": "EasyshareCom", - "kl": "KickloadCom", - "fc": "FilesonicCom", - } - self.hosterMapReverse = dict((v, k) for k, v in self.hosterMap.iteritems()) + def setup(self): self.multiDL = False - self.limitDL = 4 def getSJSrc(self, url): src = self.req.load(str(url)) @@ -51,72 +38,84 @@ class SerienjunkiesOrg(Crypter): def handleShow(self, url): src = self.getSJSrc(url) soup = BeautifulSoup(src) + packageName = self.pyfile.package().name + if self.getConfig("changeNameSJ") == "Show": + found = unescape(soup.find("h2").find("a").string.split(' –')[0]) + if found: + packageName = found + nav = soup.find("div", attrs={"id": "scb"}) + + package_links = [] for a in nav.findAll("a"): - self.packages.append((unescape(a.text), [a["href"]], unescape(a.text))) + if self.getConfig("changeNameSJ") == "Show": + package_links.append(a["href"]) + else: + package_links.append(a["href"] + "#hasName") + if self.getConfig("changeNameSJ") == "Show": + self.packages.append((packageName, package_links, packageName)) + else: + self.core.files.addLinks(package_links, self.pyfile.package().id) + def handleSeason(self, url): src = self.getSJSrc(url) soup = BeautifulSoup(src) post = soup.find("div", attrs={"class": "post-content"}) ps = post.findAll("p") - hosterPattern = re.compile("^http://download\.serienjunkies\.org/f-.*?/([rcfultns]{2})_.*?\.html$") - preferredHoster = self.getConfig("preferredHoster").split(",") - self.log.debug("Preferred hoster: %s" % ", ".join(preferredHoster)) + + seasonName = unescape(soup.find("a", attrs={"rel": "bookmark"}).string).replace("–", "-") groups = {} gid = -1 - seasonName = unescape(soup.find("a", attrs={"rel": "bookmark"}).string) for p in ps: - if re.search("<strong>Dauer|<strong>Sprache|<strong>Format", str(p)): + if re.search("<strong>Sprache|<strong>Format", str(p)): var = p.findAll("strong") - opts = {"Dauer": "", "Uploader": "", "Sprache": "", "Format": "", u"Größe": ""} + opts = {"Sprache": "", "Format": ""} for v in var: - n = unescape(v.string) - n = n.strip() + n = unescape(v.string).strip() n = re.sub(r"^([:]?)(.*?)([:]?)$", r'\2', n) if n.strip() not in opts: continue val = v.nextSibling if not val: continue - val = val.encode("utf-8") - val = unescape(val) val = val.replace("|", "").strip() - val = val.strip() val = re.sub(r"^([:]?)(.*?)([:]?)$", r'\2', val) opts[n.strip()] = val.strip() gid += 1 groups[gid] = {} - groups[gid]["ep"] = [] + groups[gid]["ep"] = {} groups[gid]["opts"] = opts elif re.search("<strong>Download:", str(p)): - links1 = p.findAll("a", attrs={"href": hosterPattern}) - links2 = p.findAll("a", attrs={"href": re.compile("^http://serienjunkies.org/safe/.*$")}) - for link in links1 + links2: - groups[gid]["ep"].append(link["href"]) + parts = str(p).split("<br />") + if re.search("<strong>", parts[0]): + ename = re.search('<strong>(.*?)</strong>',parts[0]).group(1).strip().decode("utf-8").replace("–", "-") + groups[gid]["ep"][ename] = {} + parts.remove(parts[0]) + for part in parts: + hostername = re.search(" \| ([-a-zA-Z0-9]+\.\w+)",part) + if hostername: + hostername = hostername.group(1) + groups[gid]["ep"][ename][hostername] = [] + links = re.findall('href="(.*?)"',part) + for link in links: + groups[gid]["ep"][ename][hostername].append(link + "#hasName") + + links = [] for g in groups.values(): - links = [] - linklist = g["ep"] + for ename in g["ep"]: + links.extend(self.getpreferred(g["ep"][ename])) + if self.getConfig("changeNameSJ") == "Episode": + self.packages.append((ename, links, ename)) + links = [] package = "%s (%s, %s)" % (seasonName, g["opts"]["Format"], g["opts"]["Sprache"]) - linkgroups = {} - for link in linklist: - key = re.sub("^http://download\.serienjunkies\.org/f-.*?/(.{2})_", "", link) - if key not in linkgroups: - linkgroups[key] = [] - linkgroups[key].append(link) - for group in linkgroups.values(): - for pHoster in preferredHoster: - hmatch = False - for link in group: - m = hosterPattern.match(link) - if m: - if pHoster == self.hosterMap[m.group(1)]: - links.append(link) - hmatch = True - break - if hmatch: - break - self.packages.append((package, links, package)) + if self.getConfig("changeNameSJ") == "Format": + self.packages.append((package, links, package)) + links = [] + if (self.getConfig("changeNameSJ") == "Packagename") or re.search("#hasName", url): + self.core.files.addLinks(links, self.pyfile.package().id) + elif (self.getConfig("changeNameSJ") == "Season") or not re.search("#hasName", url): + self.packages.append((seasonName, links, seasonName)) def handleEpisode(self, url): src = self.getSJSrc(url) @@ -127,11 +126,11 @@ class SerienjunkiesOrg(Crypter): soup = BeautifulSoup(src) form = soup.find("form") h1 = soup.find("h1") - packageName = h1.text + if h1.get("class") == "wrap": captchaTag = soup.find(attrs={"src": re.compile("^/secure/")}) if not captchaTag: - sleep(1) + sleep(5) self.retry() captchaUrl = "http://download.serienjunkies.org" + captchaTag["src"] @@ -155,12 +154,12 @@ class SerienjunkiesOrg(Crypter): for link in rawLinks: frameUrl = link["action"].replace("/go-", "/frame/go-") links.append(self.handleFrame(frameUrl)) - - # thx gartd6oDLobo - if not self.getConfig("changeName"): - packageName = self.pyfile.package().name - - self.packages.append((packageName, links, packageName)) + if re.search("#hasName", url) or ((self.getConfig("changeNameSJ") == "Packagename") and (self.getConfig("changeNameDJ") == "Packagename")): + self.core.files.addLinks(links, self.pyfile.package().id) + else: + eName = h1.text + self.packages.append((eName, links, eName)) + def handleOldStyleLink(self, url): sj = self.req.load(str(url)) @@ -177,18 +176,96 @@ class SerienjunkiesOrg(Crypter): decrypted = self.req.lastEffectiveURL if decrypted == str(url): self.retry() - self.packages.append((self.pyfile.package().name, [decrypted], self.pyfile.package().folder)) + self.core.files.addLinks([decrypted], self.pyfile.package().id) def handleFrame(self, url): self.req.load(str(url)) return self.req.lastEffectiveURL + def handleShowDJ(self, url): + src = self.getSJSrc(url) + soup = BeautifulSoup(src) + post = soup.find("div", attrs={"id": "page_post"}) + ps = post.findAll("p") + found = unescape(soup.find("h2").find("a").string.split(' –')[0]) + if found: + seasonName = found + + groups = {} + gid = -1 + for p in ps: + if re.search("<strong>Sprache|<strong>Format", str(p)): + var = p.findAll("strong") + opts = {"Sprache": "", "Format": ""} + for v in var: + n = unescape(v.string).strip() + n = re.sub(r"^([:]?)(.*?)([:]?)$", r'\2', n) + if n.strip() not in opts: + continue + val = v.nextSibling + if not val: + continue + val = val.replace("|", "").strip() + val = re.sub(r"^([:]?)(.*?)([:]?)$", r'\2', val) + opts[n.strip()] = val.strip() + gid += 1 + groups[gid] = {} + groups[gid]["ep"] = {} + groups[gid]["opts"] = opts + elif re.search("<strong>Download:", str(p)): + parts = str(p).split("<br />") + if re.search("<strong>", parts[0]): + ename = re.search('<strong>(.*?)</strong>',parts[0]).group(1).strip().decode("utf-8").replace("–", "-") + groups[gid]["ep"][ename] = {} + parts.remove(parts[0]) + for part in parts: + hostername = re.search(" \| ([-a-zA-Z0-9]+\.\w+)",part) + if hostername: + hostername = hostername.group(1) + groups[gid]["ep"][ename][hostername] = [] + links = re.findall('href="(.*?)"',part) + for link in links: + groups[gid]["ep"][ename][hostername].append(link + "#hasName") + + links = [] + for g in groups.values(): + for ename in g["ep"]: + links.extend(self.getpreferred(g["ep"][ename])) + if self.getConfig("changeNameDJ") == "Episode": + self.packages.append((ename, links, ename)) + links = [] + package = "%s (%s, %s)" % (seasonName, g["opts"]["Format"], g["opts"]["Sprache"]) + if self.getConfig("changeNameDJ") == "Format": + self.packages.append((package, links, package)) + links = [] + if (self.getConfig("changeNameDJ") == "Packagename") or re.search("#hasName", url): + self.core.files.addLinks(links, self.pyfile.package().id) + elif (self.getConfig("changeNameDJ") == "Show") or not re.search("#hasName", url): + self.packages.append((seasonName, links, seasonName)) + + + + + + + + def handleCategoryDJ(self, url): + package_links = [] + src = self.getSJSrc(url) + soup = BeautifulSoup(src) + content = soup.find("div", attrs={"id": "content"}) + for a in content.findAll("a", attrs={"rel": "bookmark"}): + package_links.append(a["href"]) + self.core.files.addLinks(package_links, self.pyfile.package().id) + def decrypt(self, pyfile): showPattern = re.compile("^http://serienjunkies.org/serie/(.*)/$") seasonPattern = re.compile("^http://serienjunkies.org/.*?/(.*)/$") - episodePattern = re.compile("^http://download.serienjunkies.org/f-.*?.html$") + episodePattern = re.compile("^http://download.serienjunkies.org/f-.*?.html(#hasName)?$") oldStyleLink = re.compile("^http://serienjunkies.org/safe/(.*)$") - framePattern = re.compile("^http://download.serienjunkies.org/frame/go-.*?/$") + categoryPatternDJ = re.compile("^http://dokujunkies.org/.*?(.*)$") + showPatternDJ = re.compile("^http://dokujunkies.org/.*?/(.*)\.html(#hasName)?$") + framePattern = re.compile("^http://download.(serienjunkies.org|dokujunkies.org)/frame/go-.*?/$") url = pyfile.url if framePattern.match(url): self.packages.append((self.pyfile.package().name, [self.handleFrame(url)], self.pyfile.package().name)) @@ -198,5 +275,42 @@ class SerienjunkiesOrg(Crypter): self.handleOldStyleLink(url) elif showPattern.match(url): self.handleShow(url) + elif showPatternDJ.match(url): + self.handleShowDJ(url) elif seasonPattern.match(url): self.handleSeason(url) + elif categoryPatternDJ.match(url): + self.handleCategoryDJ(url) + + #selects the preferred hoster, after that selects any hoster (ignoring the one to ignore) + def getpreferred(self, hosterlist): + + result = [] + preferredList = self.getConfig("hosterList").strip().lower().replace('|',',').replace('.','').replace(';',',').split(',') + if (self.getConfig("randomPreferred") == True) and (self.getConfig("hosterListMode") in ["OnlyOne","OnlyPreferred(One)"]) : + random.shuffle(preferredList) + # we don't want hosters be read two times + hosterlist2 = hosterlist.copy() + + for preferred in preferredList: + for Hoster in hosterlist: + if preferred == Hoster.lower().replace('.',''): + for Part in hosterlist[Hoster]: + self.logDebug("selected " + Part) + result.append(str(Part)) + del(hosterlist2[Hoster]) + if (self.getConfig("hosterListMode") in ["OnlyOne","OnlyPreferred(One)"]): + return result + + + ignorelist = self.getConfig("ignoreList").strip().lower().replace('|',',').replace('.','').replace(';',',').split(',') + if self.getConfig('hosterListMode') in ["OnlyOne","All"]: + for Hoster in hosterlist2: + if Hoster.strip().lower().replace('.','') not in ignorelist: + for Part in hosterlist2[Hoster]: + self.logDebug("selected2 " + Part) + result.append(str(Part)) + + if self.getConfig('hosterListMode') == "OnlyOne": + return result + return result diff --git a/module/plugins/hooks/XFileSharingPro.py b/module/plugins/hooks/XFileSharingPro.py index b87158a21..f4461f8c6 100644 --- a/module/plugins/hooks/XFileSharingPro.py +++ b/module/plugins/hooks/XFileSharingPro.py @@ -5,7 +5,7 @@ import re class XFileSharingPro(Hook): __name__ = "XFileSharingPro" - __version__ = "0.01" + __version__ = "0.02" __type__ = "hook" __config__ = [ ("activated", "bool", "Activated" , "True"), ("loadDefault", "bool", "Load default hoster list" , "True"), @@ -22,15 +22,15 @@ class XFileSharingPro(Hook): if self.getConfig('loadDefault'): hosterList |= set(( #WORKING HOSTERS: + "azsharing\.com", "banashare\.com", "fileband\.com", "kingsupload\.com", "migahost\.com", "ryushare.com", "xfileshare\.eu", #NOT TESTED: - "aieshare\.com", "amonshare\.com", "asixfiles\.com", "azsharing\.com", "banashare\.com", "batubia\.com", + "aieshare\.com", "amonshare\.com", "asixfiles\.com", "bebasupload\.com", "boosterking\.com", "buckshare\.com", "bulletupload\.com", "crocshare\.com", "ddlanime\.com", "divxme\.com", "dopeshare\.com", "downupload\.com", "eyesfile\.com", "eyvx\.com", "fik1\.com", "file4safe\.com", "file4sharing\.com", - "fileband\.com", "filebeep\.com", "filebit\.com", "filebox\.com", "filedove\.com", "fileforth\.com", - "filemade\.com", "filemak\.com", "fileplanet\.com", "fileplaygroud\.com", "filerace\.com", "filerio\.com", "filestrack\.com", + "fileforth\.com", "filemade\.com", "filemak\.com", "fileplaygroud\.com", "filerace\.com", "filestrack\.com", "fileupper\.com", "filevelocity\.com", "fooget\.com", "4bytez\.com", "freefilessharing\.com", "glumbouploads\.com", "grupload\.com", "heftyfile\.com", "hipfile\.com", "host4desi\.com", "hulkshare\.com", "idupin\.com", "imageporter\.com", "isharefast\.com", - "jalurcepat\.com", "kingsupload\.com", "laoupload\.com", "linkzhost\.com", "loombo\.com", "maknyos\.com", "migahost\.com", + "jalurcepat\.com", "laoupload\.com", "linkzhost\.com", "loombo\.com", "maknyos\.com", "mlfat4arab\.com", "movreel\.com", "netuploaded\.com", "ok2upload\.com", "180upload\.com", "1hostclick\.com", "ovfile\.com", "putshare\.com", "pyramidfiles\.com", "q4share\.com", "queenshare\.com", "ravishare\.com", "rockdizfile\.com", "sendmyway\.com", "share76\.com", "sharebeast\.com", "sharehut\.com", "sharerun\.com", "shareswift\.com", "sharingonline\.com", "6ybh-upload\.com", @@ -38,7 +38,7 @@ class XFileSharingPro(Hook): "uploaddot\.com", "uploadfloor\.com", "uploadic\.com", "uploadville\.com", "uptobox\.com", "vidbull\.com", "zalaa\.com", "zomgupload\\.com\.com", "kupload\.org", "movbay\.org", "multishare\.org", "omegave\.org", "toucansharing\.org", "uflinq\.org", "banicrazy\.info", "flowhot\.info", "upbrasil\.info", "shareyourfilez\.biz", "bzlink\.us", "cloudcache\.cc", "fileserver\.cc" - "farshare\.to", "kingshare\.to", "filemaze\.ws", "filehost\.ws", "goldfile\.eu", "xfileshare\.eu", "filestock\.ru", "moidisk\.ru" + "farshare\.to", "kingshare\.to", "filemaze\.ws", "filehost\.ws", "goldfile\.eu", "filestock\.ru", "moidisk\.ru" "4up\.me", "kfiles\.kz", "odsiebie\.pl", "upchi\.co\.il", "upit\.in", "verzend\.be" )) @@ -53,9 +53,9 @@ class XFileSharingPro(Hook): self.logError("Hoster list is empty" % len(hosterList)) return - regexp = r"http://(?:[^./]/.)*?(%s)/\w{12}" % "|".join(hosterList) + regexp = r"http://(?:[^/]*\.)?(%s)/\w{12}" % "|".join(sorted(hosterList)) self.logDebug("Added %d hosters" % len(hosterList)) - self.logDebug(regexp) + #self.logDebug(regexp) dict = self.core.pluginManager.hosterPlugins['XFileSharingPro'] dict["pattern"] = regexp diff --git a/module/plugins/hoster/BayfilesCom.py b/module/plugins/hoster/BayfilesCom.py index a69dd3ea9..190d9a952 100644 --- a/module/plugins/hoster/BayfilesCom.py +++ b/module/plugins/hoster/BayfilesCom.py @@ -26,13 +26,13 @@ class BayfilesCom(SimpleHoster): __name__ = "BayfilesCom" __type__ = "hoster" __pattern__ = r"http://(?:www\.)?bayfiles\.com/file/\w+/\w+/.*" - __version__ = "0.02" + __version__ = "0.04" __description__ = """Bayfiles.com plugin - free only""" __author_name__ = ("zoidberg") __author_mail__ = ("zoidberg@mujmail.cz") FILE_INFO_PATTERN = r'<p title="(?P<N>[^"]+)">[^<]*<strong>(?P<S>[0-9., ]+)(?P<U>[kKMG])i?B</strong></p>' - FILE_OFFLINE_PATTERN = r'<p>The requested file could not be found.</p>' + FILE_OFFLINE_PATTERN = r'(<p>The requested file could not be found.</p>|<title>404 Not Found</title>)' WAIT_PATTERN = r'>Your IP [0-9.]* has recently downloaded a file\. Upgrade to premium or wait (\d+) minutes\.<' VARS_PATTERN = r'var vfid = (\d+);\s*var delay = (\d+);' @@ -82,12 +82,12 @@ class BayfilesCom(SimpleHoster): self.download(url) # check download check = self.checkDownload({ - "waitforfreeslots": re.compile(r"^<title>BayFiles</title>$") + "waitforfreeslots": re.compile(r"<title>BayFiles</title>"), + "notfound": re.compile(r"<title>404 Not Found</title>") }) if check == "waitforfreeslots": - self.waitForFreeSlot() - - def waitForFreeSlot(self): - self.retry(60, 300, "Wait for free slot") + self.retry(60, 300, "Wait for free slot") + elif check == "notfound": + self.retry(60, 300, "404 Not found") getInfo = create_getInfo(BayfilesCom) diff --git a/module/plugins/hoster/BitshareCom.py b/module/plugins/hoster/BitshareCom.py index 1c7d79510..6d6b9c26d 100644 --- a/module/plugins/hoster/BitshareCom.py +++ b/module/plugins/hoster/BitshareCom.py @@ -46,7 +46,7 @@ class BitshareCom(Hoster): __name__ = "BitshareCom" __type__ = "hoster" __pattern__ = r"http://(www\.)?bitshare\.com/(files/(?P<id1>[a-zA-Z0-9]+)(/(?P<name>.*?)\.html)?|\?f=(?P<id2>[a-zA-Z0-9]+))" - __version__ = "0.42" + __version__ = "0.44" __description__ = """Bitshare.Com File Download Hoster""" __author_name__ = ("paulking", "fragonib") __author_mail__ = (None, "fragonib[AT]yahoo[DOT]es") @@ -58,10 +58,12 @@ class BitshareCom(Hoster): CAPTCHA_KEY_PATTERN = r"http://api\.recaptcha\.net/challenge\?k=(.*?) " def setup(self): - self.multiDL = False + self.multiDL = self.premium self.chunkLimit = 1 def process(self, pyfile): + if self.premium: + self.account.relogin(self.user) self.pyfile = pyfile @@ -116,8 +118,13 @@ class BitshareCom(Hoster): # Waiting if wait > 0: self.logDebug("Waiting %d seconds." % wait) - self.setWait(wait, True) - self.wait() + if wait < 120: + self.setWait(wait, False) + self.wait() + else: + self.setWait(wait - 55, True) + self.wait() + self.retry() # Resolve captcha if captcha == 1: @@ -142,10 +149,12 @@ class BitshareCom(Hoster): url = response.split("#")[-1] return url - + def handleErrors(self, response, separator): self.logDebug("Checking response [%s]" % response) - if "ERROR" in response: + if "ERROR:Session timed out" in response: + self.retry() + elif "ERROR" in response: msg = response.split(separator)[-1] self.fail(msg) @@ -154,5 +163,7 @@ class BitshareCom(Hoster): if "SUCCESS" in response: self.correctCaptcha() return True + elif "ERROR:SESSION ERROR" in response: + self.retry() self.logDebug("Wrong captcha") self.invalidCaptcha()
\ No newline at end of file diff --git a/module/plugins/hoster/CzshareCom.py b/module/plugins/hoster/CzshareCom.py index 0ef9c267c..71c698811 100644 --- a/module/plugins/hoster/CzshareCom.py +++ b/module/plugins/hoster/CzshareCom.py @@ -45,7 +45,7 @@ class CzshareCom(SimpleHoster): __name__ = "CzshareCom" __type__ = "hoster" __pattern__ = r"http://(\w*\.)*czshare\.(com|cz)/(\d+/|download.php\?).*" - __version__ = "0.86" + __version__ = "0.87" __description__ = """CZshare.com""" __author_name__ = ("zoidberg") @@ -149,7 +149,7 @@ class CzshareCom(SimpleHoster): check = self.checkDownload({ "tempoffline": re.compile(r"^Soubor je do.asn. nedostupn.$"), "multi_dl": re.compile(self.MULTIDL_PATTERN), - "captcha_err": re.compile(self.FREE_FORM_PATTERN) + "captcha_err": "<li>Zadaný ověřovací kód nesouhlasí!</li>" }) if check == "tempoffline": diff --git a/module/plugins/hoster/DateiTo.py b/module/plugins/hoster/DateiTo.py new file mode 100644 index 000000000..529a5a06f --- /dev/null +++ b/module/plugins/hoster/DateiTo.py @@ -0,0 +1,92 @@ +# -*- 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: zoidberg +""" + +import re +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo +from module.plugins.ReCaptcha import ReCaptcha + +class DateiTo(SimpleHoster): + __name__ = "DateiTo" + __type__ = "hoster" + __pattern__ = r"http://(?:www\.)?datei\.to/datei/(?P<ID>\w+)\.html" + __version__ = "0.01" + __description__ = """Datei.to plugin - free only""" + __author_name__ = ("zoidberg") + __author_mail__ = ("zoidberg@mujmail.cz") + + FILE_NAME_PATTERN = r'Dateiname:</td>\s*<td colspan="2"><strong>(?P<N>.*?)</' + FILE_SIZE_PATTERN = r'Dateigröße:</td>\s*<td colspan="2">(?P<S>.*?)</' + FILE_OFFLINE_PATTERN = r'>Datei wurde nicht gefunden<|>Bitte wähle deine Datei aus... <' + PARALELL_PATTERN = r'>Du lädst bereits eine Datei herunter<' + + WAIT_PATTERN = r'countdown\({seconds: (\d+)' + DATA_PATTERN = r'url: "(.*?)", data: "(.*?)",' + RECAPTCHA_KEY_PATTERN = r'Recaptcha.create\("(.*?)"' + + def handleFree(self): + url = 'http://datei.to/ajax/download.php' + data = {'P': 'I', 'ID': self.file_info['ID']} + + recaptcha = ReCaptcha(self) + + for i in range(10): + self.logDebug("URL", url, "POST", data) + self.html = self.load(url, post = data) + self.checkErrors() + + if url.endswith('download.php') and 'P' in data: + if data['P'] == 'I': + self.doWait() + + elif data['P'] == 'IV': + break + + found = re.search(self.DATA_PATTERN, self.html) + if not found: self.parseError('data') + url = 'http://datei.to/' + found.group(1) + data = dict(x.split('=') for x in found.group(2).split('&')) + + if url.endswith('recaptcha.php'): + found = re.search(self.RECAPTCHA_KEY_PATTERN, self.html) + recaptcha_key = found.group(1) if found else "6LdBbL8SAAAAAI0vKUo58XRwDd5Tu_Ze1DA7qTao" + + data['recaptcha_challenge_field'], data['recaptcha_response_field'] = recaptcha.challenge(recaptcha_key) + + else: + self.fail('Too bad...') + + download_url = self.html + self.logDebug('Download URL', download_url) + self.download(download_url) + + def checkErrors(self): + found = re.search(self.PARALELL_PATTERN, self.html) + if found: + self.setWait(wait_time + 1, False) + self.wait(300) + self.retry() + + def doWait(self): + found = re.search(self.WAIT_PATTERN, self.html) + wait_time = int(found.group(1)) if found else 30 + self.setWait(wait_time + 1, False) + + self.load('http://datei.to/ajax/download.php', post = {'P': 'Ads'}) + self.wait() + +getInfo = create_getInfo(DateiTo) diff --git a/module/plugins/hoster/DdlstorageCom.py b/module/plugins/hoster/DdlstorageCom.py new file mode 100644 index 000000000..31c4f4605 --- /dev/null +++ b/module/plugins/hoster/DdlstorageCom.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +from module.plugins.hoster.XFileSharingPro import XFileSharingPro, create_getInfo + +class DdlstorageCom(XFileSharingPro): + __name__ = "DdlstorageCom" + __type__ = "hoster" + __pattern__ = r"http://(?:\w*\.)*?ddlstorage.com/\w{12}" + __version__ = "0.01" + __description__ = """DDLStorage.com hoster plugin""" + __author_name__ = ("zoidberg") + __author_mail__ = ("zoidberg@mujmail.cz") + + def setup(self): + self.resumeDownload = self.multiDL = self.premium + +getInfo = create_getInfo(DdlstorageCom)
\ No newline at end of file diff --git a/module/plugins/hoster/DepositfilesCom.py b/module/plugins/hoster/DepositfilesCom.py index be5e65d52..9ff6b0b55 100644 --- a/module/plugins/hoster/DepositfilesCom.py +++ b/module/plugins/hoster/DepositfilesCom.py @@ -11,12 +11,13 @@ class DepositfilesCom(SimpleHoster): __name__ = "DepositfilesCom" __type__ = "hoster" __pattern__ = r"http://[\w\.]*?depositfiles\.com(/\w{1,3})?/files/[\w]+" - __version__ = "0.39" + __version__ = "0.41" __description__ = """Depositfiles.com Download Hoster""" __author_name__ = ("spoob", "zoidberg") __author_mail__ = ("spoob@pyload.org", "zoidberg@mujmail.cz") - FILE_INFO_PATTERN = r'File name: <b title="(?P<N>[^"]+)">.*\s*<span class="nowrap">File size: <b>(?P<S>[0-9.]+) (?P<U>[kKMG])i?B</b>' + FILE_NAME_PATTERN = r'File name: <b title="(?P<N>[^"]+)' + FILE_SIZE_PATTERN = r'File size: <b>(?P<S>[0-9.]+) (?P<U>[kKMG])i?B</b>' FILE_OFFLINE_PATTERN = r'<span class="html_download_api-not_exists"></span>' FILE_URL_REPLACEMENTS = [(r"\.com(/.*?)?/files", ".com/en/files"), (r"\.html$", "")] @@ -100,7 +101,7 @@ class DepositfilesCom(SimpleHoster): self.logWarning("Download limit reached") self.retry(25, 3600, "Download limit reached") elif 'onClick="show_gold_offer' in self.html: - self.account.relogin() + self.account.relogin(self.user) self.retry() link = unquote(re.search('<div id="download_url">\s*<a href="(http://.+?\.depositfiles.com/.+?)"', self.html).group(1)) self.multiDL = True diff --git a/module/plugins/hoster/EasybytezCom.py b/module/plugins/hoster/EasybytezCom.py index 49214ba99..5b9925e97 100644 --- a/module/plugins/hoster/EasybytezCom.py +++ b/module/plugins/hoster/EasybytezCom.py @@ -24,7 +24,7 @@ class EasybytezCom(XFileSharingPro): __name__ = "EasybytezCom" __type__ = "hoster" __pattern__ = r"http://(?:\w*\.)?easybytez.com/(\w+).*" - __version__ = "0.08" + __version__ = "0.09" __description__ = """easybytez.com""" __author_name__ = ("zoidberg") __author_mail__ = ("zoidberg@mujmail.cz") @@ -49,7 +49,7 @@ class EasybytezCom(XFileSharingPro): self.startDownload(found.group(1)) def handleOverriden(self): - self.html = self.load(self.HOSTER_URL) + self.html = self.load(self.HOSTER_NAME) action, inputs = self.parseHtmlForm('') upload_id = "%012d" % int(random()*10**12) action += upload_id + "&js_on=1&utype=prem&upload_type=url" @@ -73,4 +73,4 @@ class EasybytezCom(XFileSharingPro): self.pyfile.url = found.group(1) self.retry() -getInfo = create_getInfo(EasybytezCom) +getInfo = create_getInfo(EasybytezCom)
\ No newline at end of file diff --git a/module/plugins/hoster/FilefactoryCom.py b/module/plugins/hoster/FilefactoryCom.py index 4f6666675..135dd90a1 100644 --- a/module/plugins/hoster/FilefactoryCom.py +++ b/module/plugins/hoster/FilefactoryCom.py @@ -4,6 +4,7 @@ from module.plugins.Hoster import Hoster from module.plugins.ReCaptcha import ReCaptcha from module.utils import parseFileSize from module.plugins.Plugin import chunks +from module.common.json_layer import json_loads import re @@ -16,7 +17,7 @@ def checkFile(plugin, urls): url_ids = url_dict.keys() urls = map(lambda url_id: 'http://www.filefactory.com/file/' + url_id, url_ids) - html = getURL("http://filefactory.com/tool/links.php", post = {"func": "links", "links": "\n".join(urls)}, decode=True) + html = getURL("http://www.filefactory.com/tool/links.php", post = {"func": "links", "links": "\n".join(urls)}, decode=True) for m in re.finditer(plugin.LC_INFO_PATTERN, html): if m.group('id') in url_ids: @@ -34,29 +35,28 @@ class FilefactoryCom(Hoster): __name__ = "FilefactoryCom" __type__ = "hoster" __pattern__ = r"http://(?:www\.)?filefactory\.com/file/(?P<id>[a-zA-Z0-9]+).*" # URLs given out are often longer but this is the requirement - __version__ = "0.33" + __version__ = "0.34" __description__ = """Filefactory.Com File Download Hoster""" __author_name__ = ("paulking", "zoidberg") - LC_INFO_PATTERN = r'<tr class="(even|odd)">\s*<td>\s*<a href="http://www.filefactory.com/file/(?P<id>\w+)[^"]*">(?P<name>[^<]+)</a>\s*.*\s*</td>\s*<td>(?P<size>[0-9.]+ \w+)</td>' - LC_OFFLINE_PATTERN = r'<li class="(even|odd)">\s*<div class="metadata">http://www.filefactory.com/file/(?P<id>\w+)/</div>' - + LC_INFO_PATTERN = r'<h1 class="name">(?P<name>[^<]+) \((?P<size>[0-9.]+ \w+)\)</h1>\s*<p>http://www.filefactory.com/file/(?P<id>\w+)/' + LC_OFFLINE_PATTERN = r'<p>http://www.filefactory.com/file/(?P<id>\w+)/</p>\s*<p class="errorResponse">' + FILE_OFFLINE_PATTERN = r'<title>File Not Found' FILE_NAME_PATTERN = r'<span class="last">(?P<name>.*?)</span>' FILE_INFO_PATTERN = r'<span>(?P<size>\d(\d|\.)*) (?P<units>..) file uploaded' - FILE_CHECK_PATTERN = r'check:\'(?P<check>.*?)\'' - CAPTCHA_KEY_PATTERN = r'Recaptcha.create\("(?P<recaptchakey>.*?)",' - WAIT_PATH_PATTERN = r'path:"(?P<path>.*?)"' + FILE_CHECK_PATTERN = r'check:\s*\'(?P<check>.*?)\'' + CAPTCHA_KEY_PATTERN = r'Recaptcha.create\(\s*"(.*?)",' WAIT_PATTERN = r'id="startWait" value="(?P<wait>\d+)"' - FILE_URL_PATTERN = r'<a href="(?P<url>.*?)" id="downloadLinkTarget">' + FILE_URL_PATTERN = r'<p[^>]*?id="downloadLinkTarget"[^>]*>\s*<a href="(?P<url>.*?)"' def setup(self): self.multiDL = self.resumeDownloads = self.premium def process(self, pyfile): # Check file - pyfile.name, pyfile.size, status, self.url = checkFile(self, [pyfile.url])[0] + pyfile.name, pyfile.size, status, self.url = checkFile(self, [pyfile.url])[0] if status != 2: self.offline() self.logDebug("File Name: %s Size: %d" % (pyfile.name, pyfile.size)) @@ -93,42 +93,41 @@ class FilefactoryCom(Hoster): # Check Id self.check = re.search(self.FILE_CHECK_PATTERN, self.html).group('check') - self.log.debug("%s: File check code is [%s]" % (self.__name__, self.check)) + self.logDebug("File check code is [%s]" % self.check) # Resolve captcha - self.log.debug("%s: File is captcha protected" % self.__name__) - id = re.search(self.CAPTCHA_KEY_PATTERN, self.html).group('recaptchakey') + found = re.search(self.CAPTCHA_KEY_PATTERN, self.html) + recaptcha_key = found.group(1) if found else "6LeN8roSAAAAAPdC1zy399Qei4b1BwmSBSsBN8zm" + recaptcha = ReCaptcha(self) + # Try up to 5 times - for i in range(5): - self.log.debug("%s: Resolving ReCaptcha with key [%s], round %d" % (self.__name__, id, i+1)) - recaptcha = ReCaptcha(self) - challenge, code = recaptcha.challenge(id) - response = self.load("http://www.filefactory.com/file/checkCaptcha.php", - post={"check" : self.check, "recaptcha_challenge_field" : challenge, "recaptcha_response_field" : code}) - captchavalid = self.handleCaptchaErrors(response) - if captchavalid: + for i in range(5): + challenge, code = recaptcha.challenge(recaptcha_key) + response = json_loads(self.load("http://www.filefactory.com/file/checkCaptcha.php", + post={"check" : self.check, "recaptcha_challenge_field" : challenge, "recaptcha_response_field" : code})) + if response['status'] == 'ok': + self.correctCaptcha() break - if not captchavalid: + else: + self.invalidCaptcha() + else: self.fail("No valid captcha after 5 attempts") - - # Get wait URL - waitpath = re.search(self.WAIT_PATH_PATTERN, response).group('path') - waiturl = "http://www.filefactory.com" + waitpath # This will take us to a wait screen - self.log.debug("%s: fetching wait with url [%s]" % (self.__name__, waiturl)) + waiturl = "http://www.filefactory.com" + response['path'] + self.logDebug("Fetching wait with url [%s]" % waiturl) waithtml = self.load(waiturl, decode=True) # Find the wait value and wait wait = int(re.search(self.WAIT_PATTERN, waithtml).group('wait')) - self.log.debug("%s: Waiting %d seconds." % (self.__name__, wait)) + self.logDebug("Waiting %d seconds." % wait) self.setWait(wait, True) self.wait() # Now get the real download url and retrieve the file url = re.search(self.FILE_URL_PATTERN,waithtml).group('url') # this may either download our file or forward us to an error page - self.log.debug("%s: download url %s" % (self.__name__, url)) + self.logDebug("Download URL: %s" % url) dl = self.download(url) check = self.checkDownload({"multiple": "You are currently downloading too many files at once.", @@ -136,20 +135,11 @@ class FilefactoryCom(Hoster): if check == "multiple": self.setWait(15*60) - self.log.debug("%s: Parallel downloads detected waiting 15 minutes" % self.__name__) + self.logDebug("Parallel downloads detected; waiting 15 minutes") self.wait() self.retry() elif check == "error": self.fail("Unknown error") - - def handleCaptchaErrors(self, response): - self.log.debug("%s: Result of captcha resolving [%s]" % (self.__name__, response)) - if 'status:"ok"' in response: - self.correctCaptcha() - return True - - self.log.debug("%s: Wrong captcha" % self.__name__) - self.invalidCaptcha() def handlePremium(self): self.fail('Please enable direct downloads') diff --git a/module/plugins/hoster/GigapetaCom.py b/module/plugins/hoster/GigapetaCom.py new file mode 100644 index 000000000..28ba35abe --- /dev/null +++ b/module/plugins/hoster/GigapetaCom.py @@ -0,0 +1,73 @@ +# -*- 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: zoidberg +""" + +import re +from random import randint +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo +from pycurl import FOLLOWLOCATION + +class GigapetaCom(SimpleHoster): + __name__ = "GigapetaCom" + __type__ = "hoster" + __pattern__ = r"http://(?:www\.)?gigapeta\.com/dl/\w+" + __version__ = "0.01" + __description__ = """GigaPeta.com plugin - free only""" + __author_name__ = ("zoidberg") + __author_mail__ = ("zoidberg@mujmail.cz") + + SH_COOKIES = [("http://gigapeta.com", "lang", "us")] + FILE_NAME_PATTERN = r'<img src=".*" alt="file" />-->\s*(?P<N>.*?)\s*</td>' + FILE_SIZE_PATTERN = r'<th>\s*Size\s*</th>\s*<td>\s*(?P<S>.*?)\s*</td>' + FILE_OFFLINE_PATTERN = r'<div id="page_error">' + + def handleFree(self): + captcha_key = str(randint(1,100000000)) + captcha_url = "http://gigapeta.com/img/captcha.gif?x=%s" % captcha_key + + self.req.http.c.setopt(FOLLOWLOCATION, 0) + + for i in range(5): + self.checkErrors() + + captcha = self.decryptCaptcha(captcha_url) + self.html = self.load(self.pyfile.url, post = { + "captcha_key": captcha_key, + "captcha": captcha, + "download": "Download"}) + + found = re.search(r"Location\s*:\s*(.*)", self.req.http.header, re.I) + if found: + download_url = found.group(1) + break + elif "Entered figures don`t coincide with the picture" in self.html: + self.invalidCaptcha() + else: + self.fail("No valid captcha code entered") + + self.req.http.c.setopt(FOLLOWLOCATION, 1) + 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") + self.setWait(300, True) + self.wait() + self.retry() + +getInfo = create_getInfo(GigapetaCom)
\ No newline at end of file diff --git a/module/plugins/hoster/JumbofilesCom.py b/module/plugins/hoster/JumbofilesCom.py new file mode 100644 index 000000000..a338b31cc --- /dev/null +++ b/module/plugins/hoster/JumbofilesCom.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +import re +from module.plugins.hoster.XFileSharingPro import XFileSharingPro, create_getInfo +from module.utils import html_unescape + +class JumbofilesCom(XFileSharingPro): + __name__ = "JumbofilesCom" + __type__ = "hoster" + __pattern__ = r"http://(?:\w*\.)*(jumbofiles.com)/\w{12}" + __version__ = "0.01" + __description__ = """JumboFiles.com hoster plugin""" + __author_name__ = ("zoidberg") + __author_mail__ = ("zoidberg@mujmail.cz") + + FILE_INFO_PATTERN = '<TR><TD>(?P<N>[^<]+?)\s*<small>\((?P<S>[\d.]+)\s*(?P<U>[KMG][bB])\)</small></TD></TR>' + FILE_OFFLINE_PATTERN = 'Not Found or Deleted / Disabled due to inactivity or DMCA' + DIRECT_LINK_PATTERN = '<FORM METHOD="LINK" ACTION="(.*?)"' + +getInfo = create_getInfo(JumbofilesCom)
\ No newline at end of file diff --git a/module/plugins/hoster/LetitbitNet.py b/module/plugins/hoster/LetitbitNet.py index e5fc055c0..88e708bf5 100644 --- a/module/plugins/hoster/LetitbitNet.py +++ b/module/plugins/hoster/LetitbitNet.py @@ -24,7 +24,7 @@ from module.common.json_layer import json_loads class LetitbitNet(SimpleHoster): __name__ = "LetitbitNet" __type__ = "hoster" - __pattern__ = r"http://(?:\w*\.)*letitbit.net/download/.*" + __pattern__ = r"http://(?:\w*\.)*(letitbit|shareflare).net/download/.*" __version__ = "0.19" __description__ = """letitbit.net""" __author_name__ = ("zoidberg") @@ -35,8 +35,9 @@ class LetitbitNet(SimpleHoster): FILE_INFO_PATTERN = r'<h1[^>]*>File:.*?<span>(?P<N>[^<]+)</span>.*?\[<span>(?P<S>[^<]+)</span>]</h1>' FILE_OFFLINE_PATTERN = r'>File not found<' - + DOMAIN = "http://letitbit.net" + FILE_URL_REPLACEMENTS = [(r"(?<=http://)([^/]+)", "letitbit.net")] def setup(self): self.resumeDownload = self.multiDL = True @@ -106,4 +107,4 @@ class LetitbitNet(SimpleHoster): else: self.fail("Download did not finish correctly") -getInfo = create_getInfo(LetitbitNet) +getInfo = create_getInfo(LetitbitNet)
\ No newline at end of file diff --git a/module/plugins/hoster/MediafireCom.py b/module/plugins/hoster/MediafireCom.py index c1d6e3595..717143880 100644 --- a/module/plugins/hoster/MediafireCom.py +++ b/module/plugins/hoster/MediafireCom.py @@ -58,7 +58,7 @@ class MediafireCom(SimpleHoster): __name__ = "MediafireCom" __type__ = "hoster" __pattern__ = r"http://(\w*\.)*mediafire\.com/(file/|(download.php)?\?)(\w{11}|\w{15})($|/)" - __version__ = "0.74" + __version__ = "0.75" __description__ = """Mediafire.com plugin - free only""" __author_name__ = ("zoidberg") __author_mail__ = ("zoidberg@mujmail.cz") @@ -104,6 +104,7 @@ class MediafireCom(SimpleHoster): else: self.fail("No or incorrect password") + """ links = re.findall(self.DOWNLOAD_LINK_PATTERN, self.html) link_count = len(links) self.logDebug('LINKS ', links) @@ -131,6 +132,11 @@ class MediafireCom(SimpleHoster): else: zindex, download_url = links[0] + """ + found = re.search(r'kNO = "(http://.*?)";', self.html) + if not found: self.parseError("Download URL") + download_url = found.group(1) + self.logDebug("DOWNLOAD LINK:", download_url) self.download(download_url) diff --git a/module/plugins/hoster/NetloadIn.py b/module/plugins/hoster/NetloadIn.py index 4aa1cd888..fa2f3ddef 100644 --- a/module/plugins/hoster/NetloadIn.py +++ b/module/plugins/hoster/NetloadIn.py @@ -55,7 +55,7 @@ class NetloadIn(Hoster): __name__ = "NetloadIn" __type__ = "hoster" __pattern__ = r"http://.*netload\.in/(?:datei(.*?)(?:\.htm|/)|index.php?id=10&file_id=)" - __version__ = "0.39" + __version__ = "0.40" __description__ = """Netload.in Download Hoster""" __author_name__ = ("spoob", "RaNaN", "Gregy") __author_mail__ = ("spoob@pyload.org", "ranan@pyload.org", "gregy@gregy.cz") @@ -98,8 +98,8 @@ class NetloadIn(Hoster): self.api_data = False return - apiurl = "http://netload.in/share/fileinfos2.php" - src = self.load(apiurl, cookies=False, get={"file_id": match.group(1)}, decode = True).strip() + apiurl = "http://api.netload.in/info.php" + src = self.load(apiurl, cookies=False, get={"file_id": match.group(1), "auth": "Zf9SnQh9WiReEsb18akjvQGqT0I830e8", "bz": "1", "md5": "1"}, decode = True).strip() if not src and n <= 3: sleep(0.2) self.download_api_data(n+1) diff --git a/module/plugins/hoster/RapidgatorNet.py b/module/plugins/hoster/RapidgatorNet.py index a8c55f0ba..8a6ab6150 100644 --- a/module/plugins/hoster/RapidgatorNet.py +++ b/module/plugins/hoster/RapidgatorNet.py @@ -27,7 +27,7 @@ class RapidgatorNet(SimpleHoster): __name__ = "RapidgatorNet" __type__ = "hoster" __pattern__ = r"http://(?:www\.)?(rapidgator.net)/file/(\d+)" - __version__ = "0.01" + __version__ = "0.03" __description__ = """rapidgator.net""" __author_name__ = ("zoidberg") @@ -39,6 +39,9 @@ class RapidgatorNet(SimpleHoster): RECAPTCHA_KEY_PATTERN = r'"http://api.recaptcha.net/challenge?k=(.*?)"' def handleFree(self): + if "You can download files up to 500 MB in free mode" in self.html: + self.fail("File too large for free download") + self.checkWait() jsvars = dict(re.findall(self.JSVARS_PATTERN, self.html)) diff --git a/module/plugins/hoster/ShareRapidCom.py b/module/plugins/hoster/ShareRapidCom.py index b9ce61e18..6859b3d9f 100644 --- a/module/plugins/hoster/ShareRapidCom.py +++ b/module/plugins/hoster/ShareRapidCom.py @@ -23,7 +23,7 @@ class ShareRapidCom(SimpleHoster): __name__ = "ShareRapidCom" __type__ = "hoster" __pattern__ = r"http://(?:www\.)?((share(-?rapid\.(biz|com|cz|info|eu|net|org|pl|sk)|-(central|credit|free|net)\.cz|-ms\.net)|(s-?rapid|rapids)\.(cz|sk))|(e-stahuj|mediatack|premium-rapidshare|rapidshare-premium|qiuck)\.cz|kadzet\.com|stahuj-zdarma\.eu|strelci\.net|universal-share\.com)/(stahuj/.+)" - __version__ = "0.47" + __version__ = "0.48" __description__ = """Share-rapid.com plugin - premium only""" __author_name__ = ("MikyWoW", "zoidberg") __author_mail__ = ("MikyWoW@seznam.cz", "zoidberg@mujmail.cz") @@ -60,7 +60,7 @@ class ShareRapidCom(SimpleHoster): else: self.logError("Download URL not found") if re.search(self.ERR_LOGIN_PATTERN, self.html): - self.relogin() + self.relogin(self.user) self.retry(3,0,"User login failed") elif re.search(self.ERR_CREDIT_PATTERN, self.html): self.fail("Not enough credit left") diff --git a/module/plugins/hoster/ShareonlineBiz.py b/module/plugins/hoster/ShareonlineBiz.py index cb624e7a2..719235565 100644 --- a/module/plugins/hoster/ShareonlineBiz.py +++ b/module/plugins/hoster/ShareonlineBiz.py @@ -43,7 +43,7 @@ class ShareonlineBiz(Hoster): __name__ = "ShareonlineBiz" __type__ = "hoster" __pattern__ = r"http://[\w\.]*?(share\-online\.biz|egoshare\.com)/(download.php\?id\=|dl/)[\w]+" - __version__ = "0.27" + __version__ = "0.29" __description__ = """Shareonline.biz Download Hoster""" __author_name__ = ("spoob", "mkaay", "zoidberg") __author_mail__ = ("spoob@pyload.org", "mkaay@mkaay.de", "zoidberg@mujmail.cz") @@ -73,6 +73,10 @@ class ShareonlineBiz(Hoster): if self.premium: self.account.getAccountInfo(self.user, True) self.retry(reason=_("Invalid download ticket")) + + self.logDebug('DOWNLOAD SIZE: %d B (%d expected)' % (self.pyfile.size , self.exp_size)) + if self.pyfile.size != self.exp_size: + self.retry(reason="Incorrect file size: %d B" % self.pyfile.size) def downloadAPIData(self): api_url_base = "http://api.share-online.biz/linkcheck.php?md5=1" @@ -91,7 +95,7 @@ class ShareonlineBiz(Hoster): def handleFree(self): self.downloadAPIData() self.pyfile.name = self.api_data["filename"] - self.pyfile.size = self.api_data["size"] + self.pyfile.size = self.exp_size = int(self.api_data["size"]) self.html = self.load(self.pyfile.url, cookies = True) #refer, stuff self.setWait(3) @@ -129,7 +133,7 @@ class ShareonlineBiz(Hoster): self.download(download_url) def handleAPIPremium(self): #should be working better - self.account.getAccountInfo(self.user) + self.account.getAccountInfo(self.user, True) src = self.load("http://api.share-online.biz/account.php?username=%s&password=%s&act=download&lid=%s" % (self.user, self.account.accounts[self.user]["password"], self.file_id), post={}) self.api_data = dlinfo = {} for line in src.splitlines(): @@ -141,7 +145,7 @@ class ShareonlineBiz(Hoster): self.offline() self.pyfile.name = dlinfo["name"] - self.pyfile.size = dlinfo["size"] + self.pyfile.size = self.exp_size = int(dlinfo["size"]) dlLink = dlinfo["url"] if dlLink == "server_under_maintenance": diff --git a/module/plugins/hoster/StahnuTo.py b/module/plugins/hoster/StahnuTo.py index a78615dba..354a99b1a 100644 --- a/module/plugins/hoster/StahnuTo.py +++ b/module/plugins/hoster/StahnuTo.py @@ -32,29 +32,32 @@ def getInfo(urls): class StahnuTo(SimpleHoster): __name__ = "StahnuTo" __type__ = "hoster" - __pattern__ = r"http://(\w*\.)?stahnu.to/(files/get/|.*\?file=)([^/]+).*" - __version__ = "0.12" + __pattern__ = r"http://(?:\w*\.)?stahnu.to/(?:files/get/|.*\?file=)(?P<ID>[^/]+).*" + __version__ = "0.14" __description__ = """stahnu.to""" __author_name__ = ("zoidberg") - FILE_NAME_PATTERN = r"<div class='nadpis-01'><h2>(?<N>[^<]+)</h2></div>" - FILE_SIZE_PATTERN = r'<td>Velikost souboru<br /><span>(?<S>[^<]+)\s*(?<U>[kKMG])i?[Bb]</span></td>' + FILE_NAME_PATTERN = r"<td colspan='2'>Název souboru<br /><span>(?P<N>[^<]+)</span>" + FILE_SIZE_PATTERN = r'<td>Velikost souboru<br /><span>(?P<S>[^<]+)\s*(?P<U>[kKMG])i?[Bb]</span></td>' FILE_OFFLINE_PATTERN = r'<!-- Obsah - start -->\s*<!-- Obsah - end -->' - #FILE_OFFLINE_PATTERN = r'<h2 align="center">Tento soubor neexistuje nebo byl odstraněn! </h2>' - CAPTCHA_PATTERN = r'<img src="captcha/captcha.php" id="captcha" /></td>' def setup(self): self.multiDL = True def process(self, pyfile): + if not self.account: + self.fail("Please enter your stahnu.to account") + found = re.search(self.__pattern__, pyfile.url) - file_id = found.group(3) + file_id = found.group(1) - self.html = self.load("http://stahnu.to/?file=" + file_id, decode=True) + self.html = self.load("http://www.stahnu.to/getfile.php?file=%s" % file_id, decode=True) self.getFileInfo() + + if "K stažení souboru se musíte <strong>zdarma</strong> přihlásit!" in self.html: + self.account.relogin(self.user) + self.retry() - self.download("http://stahnu.to/files/gen/" + file_id, post={ - "file": file_id, - "user": "Anonym", - "commenttext": "" + self.download("http://www.stahnu.to/files/gen/" + file_id, post={ + "downloadbutton": u"STÁHNOUT" }) diff --git a/module/plugins/hoster/TurbobitNet.py b/module/plugins/hoster/TurbobitNet.py index 95fcae7f2..9de7f9bd0 100644 --- a/module/plugins/hoster/TurbobitNet.py +++ b/module/plugins/hoster/TurbobitNet.py @@ -26,8 +26,8 @@ from pycurl import HTTPHEADER class TurbobitNet(SimpleHoster): __name__ = "TurbobitNet" __type__ = "hoster" - __pattern__ = r"http://(?:\w*\.)?turbobit.net/(?:download/free/)?(?P<ID>\w+).*" - __version__ = "0.03" + __pattern__ = r"http://(?:\w*\.)?(turbobit.net|unextfiles.com)/(?:download/free/)?(?P<ID>\w+).*" + __version__ = "0.05" __description__ = """Turbobit.net plugin""" __author_name__ = ("zoidberg") __author_mail__ = ("zoidberg@mujmail.cz") @@ -35,12 +35,12 @@ class TurbobitNet(SimpleHoster): FILE_INFO_PATTERN = r"<span class='file-icon1[^>]*>(?P<N>[^<]+)</span>\s*\((?P<S>[^\)]+)\)\s*</h1>" #long filenames are shortened FILE_NAME_PATTERN = r'<meta name="keywords" content="\s*(?P<N>[^,]+)' #full name but missing on page2 FILE_OFFLINE_PATTERN = r'<h2>File Not Found</h2>' - FILE_URL_REPLACEMENTS = [(r'(?<=http://)(.*?)(?=turbobit.net/)', '')] + FILE_URL_REPLACEMENTS = [(r"(?<=http://)([^/]+)", "turbobit.net")] SH_COOKIES = [("turbobit.net", "user_lang", "en")] CAPTCHA_KEY_PATTERN = r'src="http://api\.recaptcha\.net/challenge\?k=([^"]+)"' DOWNLOAD_URL_PATTERN = r'(?P<url>/download/redirect/[^"\']+)' - LIMIT_WAIT_PATTERN = r'<div id="time-limit-text">\s*.*?<span id=\'timeout\'>(\d+)</span> seconds' + LIMIT_WAIT_PATTERN = r'<div id="time-limit-text">\s*.*?<span id=\'timeout\'>(\d+)</span>' CAPTCHA_SRC_PATTERN = r'<img alt="Captcha" src="(.*?)"' def handleFree(self): @@ -53,7 +53,8 @@ class TurbobitNet(SimpleHoster): for i in range(5): found = re.search(self.LIMIT_WAIT_PATTERN, self.html) if found: - self.setWait(int(found.group(1)), True) + wait_time = int(found.group(1)) + self.setWait(wait_time, wait_time > 60) self.wait() self.retry() diff --git a/module/plugins/hoster/UlozTo.py b/module/plugins/hoster/UlozTo.py index de60cb7c7..dc9f9a733 100644 --- a/module/plugins/hoster/UlozTo.py +++ b/module/plugins/hoster/UlozTo.py @@ -27,7 +27,7 @@ class UlozTo(SimpleHoster): __name__ = "UlozTo" __type__ = "hoster" __pattern__ = r"http://(\w*\.)?(uloz\.to|ulozto\.(cz|sk|net)|bagruj.cz|zachowajto.pl)/(?:live/)?(?P<id>\w+/[^/?]*)" - __version__ = "0.86" + __version__ = "0.87" __description__ = """uloz.to""" __author_name__ = ("zoidberg") @@ -102,8 +102,9 @@ class UlozTo(SimpleHoster): self.download("http://www.ulozto.net" + action, post=inputs, cookies=True) def handlePremium(self): - parsed_url = self.findDownloadURL(premium=True) - self.download(parsed_url, post={"download": "Download"}) + self.download(self.pyfile.url + "?do=directDownload") + #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") diff --git a/module/plugins/hoster/UploadheroCom.py b/module/plugins/hoster/UploadheroCom.py new file mode 100644 index 000000000..eb7b5fb23 --- /dev/null +++ b/module/plugins/hoster/UploadheroCom.py @@ -0,0 +1,84 @@ +# -*- 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: zoidberg +""" + +import re +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo + +class UploadheroCom(SimpleHoster): + __name__ = "UploadheroCom" + __type__ = "hoster" + __pattern__ = r"http://(?:www\.)?uploadhero\.com/dl/\w+" + __version__ = "0.12" + __description__ = """UploadHero.com plugin""" + __author_name__ = ("mcmyst", "zoidberg") + __author_mail__ = ("mcmyst@hotmail.fr", "zoidberg@mujmail.cz") + + SH_COOKIES = [("http://uploadhero.com", "lang", "en")] + FILE_NAME_PATTERN = r'<div class="nom_de_fichier">(?P<N>.*?)</div>' + FILE_SIZE_PATTERN = r'Taille du fichier : </span><strong>(?P<S>.*?)</strong>' + FILE_OFFLINE_PATTERN = r'<p class="titre_dl_2">|<div class="raison"><strong>Le lien du fichier ci-dessus n\'existe plus.' + + DOWNLOAD_URL_PATTERN = r'<a href="([^"]+)" id="downloadnow"' + + IP_BLOCKED_PATTERN = r'href="(/lightbox_block_download.php\?min=.*?)"' + IP_WAIT_PATTERN = r'<span id="minutes">(\d+)</span>.*\s*<span id="seconds">(\d+)</span>' + + CAPTCHA_PATTERN = r'"(/captchadl\.php\?[a-z0-9]+)"' + FREE_URL_PATTERN = r'var magicomfg = \'<a href="(http://[^<>"]*?)"|"(http://storage\d+\.uploadhero\.com/\?d=[A-Za-z0-9]+/[^<>"/]+)"' + + def handleFree(self): + self.checkErrors() + + found = re.search(self.CAPTCHA_PATTERN, self.html) + if not found: self.parseError("Captcha URL") + captcha_url = "http://uploadhero.com" + found.group(1) + + for i in range(5): + captcha = self.decryptCaptcha(captcha_url) + self.html = self.load(self.pyfile.url, get = {"code": captcha}) + found = re.search(self.FREE_URL_PATTERN, self.html) + if found: + self.correctCaptcha() + download_url = found.group(1) or found.group(2) + break + else: + self.invalidCaptcha() + else: + self.fail("No valid captcha code entered") + + self.download(download_url) + + def handlePremium(self): + self.log.debug("%s: Use Premium Account" % self.__name__) + self.html = self.load(self.pyfile.url) + link = re.search(self.DOWNLOAD_URL_PATTERN, self.html).group(1) + self.log.debug("Downloading link : '%s'" % link) + self.download(link) + + def checkErrors(self): + found = re.search(self.IP_BLOCKED_PATTERN, self.html) + if found: + self.html = self.load("http://uploadhero.com%s" % found.group(1)) + + found = re.search(self.IP_WAIT_PATTERN, self.html) + wait_time = (int(found.group(1)) * 60 + int(found.group(2))) if found else 300 + self.setWait(wait_time, True) + self.wait() + self.retry() + +getInfo = create_getInfo(UploadheroCom)
\ No newline at end of file diff --git a/module/plugins/hoster/WrzucTo.py b/module/plugins/hoster/WrzucTo.py new file mode 100644 index 000000000..4a5e89f22 --- /dev/null +++ b/module/plugins/hoster/WrzucTo.py @@ -0,0 +1,58 @@ +# -*- 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: zoidberg +""" + +import re +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo +from pycurl import HTTPHEADER + +class WrzucTo(SimpleHoster): + __name__ = "WrzucTo" + __type__ = "hoster" + __pattern__ = r"http://(?:\w+\.)*?wrzuc\.to/([a-zA-Z0-9]+(\.wt|\.html)|(\w+/?linki/[a-zA-Z0-9]+))" + __version__ = "0.01" + __description__ = """Wrzuc.to plugin - free only""" + __author_name__ = ("zoidberg") + __author_mail__ = ("zoidberg@mujmail.cz") + + SH_COOKIES = [("http://www.wrzuc.to", "language", "en")] + FILE_SIZE_PATTERN = r'class="info">\s*<tr>\s*<td>(?P<S>.*?)</td>' + FILE_NAME_PATTERN = r'id="file_info">\s*<strong>(?P<N>.*?)</strong>' + + def setup(self): + self.multiDL = True + + def handleFree(self): + data = dict(re.findall(r'(md5|file): "(.*?)"', self.html)) + if len(data) != 2: self.parseError('File ID') + + self.req.http.c.setopt(HTTPHEADER, ["X-Requested-With: XMLHttpRequest"]) + self.req.http.lastURL = self.pyfile.url + self.load("http://www.wrzuc.to/ajax/server/prepair", post = {"md5": data['md5']}) + + self.req.http.lastURL = self.pyfile.url + self.html = self.load("http://www.wrzuc.to/ajax/server/download_link", post = {"file": data['file']}) + + data.update(re.findall(r'"(download_link|server_id)":"(.*?)"', self.html)) + if len(data) != 4: self.parseError('Download URL') + + download_url = "http://%s.wrzuc.to/pobierz/%s" % (data['server_id'], data['download_link']) + self.logDebug("Download URL: %s" % download_url) + self.download(download_url) + +getInfo = create_getInfo(WrzucTo) + diff --git a/module/plugins/hoster/XFileSharingPro.py b/module/plugins/hoster/XFileSharingPro.py index 0d44300af..6b98b4d08 100644 --- a/module/plugins/hoster/XFileSharingPro.py +++ b/module/plugins/hoster/XFileSharingPro.py @@ -34,7 +34,7 @@ class XFileSharingPro(SimpleHoster): __name__ = "XFileSharingPro" __type__ = "hoster" __pattern__ = r"http://(?:\w*\.)*((aieshare|amonshare|asixfiles|azsharing|banashare|batubia|bebasupload|boosterking|buckshare|bulletupload|crocshare|ddlanime|divxme|dopeshare|downupload|eyesfile|eyvx|fik1|file(4safe|4sharing|band|beep|bit|box|dove|fat|forth|made|mak|planet|playgroud|race|rio|strack|upper|velocity)|fooget|4bytez|freefilessharing|glumbouploads|grupload|heftyfile|hipfile|host4desi|hulkshare.com|idupin|imageporter|isharefast|jalurcepat|kingsupload|laoupload|linkzhost|loombo|maknyos|migahost|mlfat4arab|movreel|netuploaded|ok2upload|180upload|1hostclick|ovfile|putshare|pyramidfiles|q4share|queenshare|ravishare|rockdizfile|sendmyway|share(76|beast|hut|run|swift)|sharingonline|6ybh-upload|skipfile|spaadyshare|space4file|speedoshare|upload(baz|boost|c|dot|floor|ic|dville)|uptobox|vidbull|zalaa|zomgupload)\.com|(kupload|movbay|multishare|omegave|toucansharing|uflinq)\.org|(annonhost|fupload|muchshare|supashare|tusfiles|usershare|xuploading)\.net|(banicrazy|flowhot|upbrasil)\.info|(shareyourfilez)|.biz|(bzlink|)\.us|(cloudcache|fileserver)\.cc|(farshare|kingshare)\.to|(filemaze|filehost)\.ws|(goldfile|xfileshare)\.eu|(filestock|moidisk)\.ru|4up\.me|kfiles\.kz|odsiebie\.pl|upchi\.co\.il|upit\.in|verzend\.be)/\w{12}" - __version__ = "0.02" + __version__ = "0.05" __description__ = """XFileSharingPro common hoster base""" __author_name__ = ("zoidberg") __author_mail__ = ("zoidberg@mujmail.cz") @@ -47,13 +47,15 @@ class XFileSharingPro(SimpleHoster): WAIT_PATTERN = r'<span id="countdown_str">.*?>(\d+)</span>' OVR_DOWNLOAD_LINK_PATTERN = r'<h2>Download Link</h2>\s*<textarea[^>]*>([^<]+)' OVR_KILL_LINK_PATTERN = r'<h2>Delete Link</h2>\s*<textarea[^>]*>([^<]+)' - CAPTCHA_URL_PATTERN = r'(http://[^"\']+?/captchas/[^"\']+)' + CAPTCHA_URL_PATTERN = r'(http://[^"\']+?/captchas?/[^"\']+)' RECAPTCHA_URL_PATTERN = r'http://[^"\']+?recaptcha[^"\']+?\?k=([^"\']+)"' - ERROR_PATTERN = r'class="err">(.*?)<' + CAPTCHA_DIV_PATTERN = r'<b>Enter code.*?<div.*?>(.*?)</div>' + ERROR_PATTERN = r'class=["\']err["\'][^>]*>(.*?)</' DIRECT_LINK_PATTERN = r'This direct link.*?href=["\'](.*?)["\']' def setup(self): + self.__pattern__ = self.core.pluginManager.hosterPlugins[self.__name__]['pattern'] self.HOSTER_NAME = re.search(self.__pattern__, self.pyfile.url).group(1) self.multiDL = True @@ -152,8 +154,14 @@ class XFileSharingPro(SimpleHoster): self.wait() elif 'captcha' in self.errmsg: self.invalidCaptcha() - elif 'countdown' in self.errmsg: + elif 'countdown' or 'Expired session' in self.errmsg: self.retry(3) + elif 'maintenance' in self.errmsg: + self.tempOffline() + elif 'download files up to' in self.errmsg: + self.fail("File too large for free download") + elif 'requires premium' in self.errmsg: + self.fail("File can be downloaded by premium users only") else: self.errmsg = None @@ -222,6 +230,15 @@ class XFileSharingPro(SimpleHoster): captcha_url = found.group(1) inputs['code'] = self.decryptCaptcha(captcha_url) return 2 + else: + found = re.search(self.CAPTCHA_DIV_PATTERN, self.html, re.S) + if found: + captcha_div = found.group(1) + self.logDebug(captcha_div) + numerals = re.findall('<span.*?padding-left\s*:\s*(\d+).*?>(\d)</span>', html_unescape(captcha_div)) + inputs['code'] = "".join([a[1] for a in sorted(numerals, key = lambda num: int(num[0]))]) + self.logDebug("CAPTCHA", inputs['code'], numerals) + return 3 return 0 getInfo = create_getInfo(XFileSharingPro)
\ No newline at end of file diff --git a/module/plugins/internal/XFSPAccount.py b/module/plugins/internal/XFSPAccount.py new file mode 100644 index 000000000..f187109b7 --- /dev/null +++ b/module/plugins/internal/XFSPAccount.py @@ -0,0 +1,65 @@ +# -*- 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: zoidberg +""" + +import re +from time import mktime, strptime +from module.plugins.Account import Account + +class XFSPAccount(Account): + __name__ = "XFSPAccount" + __version__ = "0.01" + __type__ = "account" + __description__ = """XFileSharingPro account base""" + __author_name__ = ("zoidberg") + __author_mail__ = ("zoidberg@mujmail.cz") + + MAIN_PAGE = None + + VALID_UNTIL_PATTERN = r'<TR><TD>Premium account expire:</TD><TD><b>([^<]+)</b>' + TRAFFIC_LEFT_PATTERN = r'<TR><TD>Traffic available today:</TD><TD><b>(?P<S>[^<]+)</b>' + + def loadAccountInfo(self, user, req): + html = req.load(self.MAIN_PAGE + "?op=my_account", decode = True) + + validuntil = -1 + found = re.search(self.VALID_UNTIL_PATTERN, html) + if found: + premium = True + try: + self.logDebug(found.group(1)) + validuntil = mktime(strptime(found.group(1), "%d %B %Y")) + except Exception, e: + self.logError(e) + else: + premium = False + + trafficleft = -1 + + return ({"validuntil": validuntil, "trafficleft": trafficleft, "premium": premium}) + + def login(self, user, data, req): + html = req.load(self.MAIN_PAGE, post = { + "login": user, + "op": "login", + "password": data['password'], + "redirect": self.MAIN_PAGE + }, decode = True) + + if 'Incorrect Login or Password' in html: + self.wrongPassword()
\ No newline at end of file |