diff options
Diffstat (limited to 'module/plugins')
32 files changed, 2997 insertions, 2997 deletions
diff --git a/module/plugins/accounts/AlldebridCom.py b/module/plugins/accounts/AlldebridCom.py index beaddeac9..baaa9d264 100644 --- a/module/plugins/accounts/AlldebridCom.py +++ b/module/plugins/accounts/AlldebridCom.py @@ -1,46 +1,46 @@ -from module.plugins.Account import Account
-import xml.dom.minidom as dom
-from BeautifulSoup import BeautifulSoup
-from time import time
-import re
+from module.plugins.Account import Account +import xml.dom.minidom as dom +from BeautifulSoup import BeautifulSoup +from time import time +import re import urllib -
-class AlldebridCom(Account):
- __name__ = "AlldebridCom"
- __version__ = "0.21"
- __type__ = "account"
- __description__ = """AllDebrid.com account plugin"""
- __author_name__ = ("Andy, Voigt")
- __author_mail__ = ("spamsales@online.de")
-
- def loadAccountInfo(self, user, req):
- data = self.getAccountData(user)
- page = req.load("http://www.alldebrid.com/account/")
- soup=BeautifulSoup(page)
- #Try to parse expiration date directly from the control panel page (better accuracy)
- try:
- time_text=soup.find('div',attrs={'class':'remaining_time_text'}).strong.string
- self.log.debug("Account expires in: %s" % time_text)
- p = re.compile('\d+')
- exp_data=p.findall(time_text)
- exp_time=time()+int(exp_data[0])*24*60*60+int(exp_data[1])*60*60+(int(exp_data[2])-1)*60
- #Get expiration date from API
- except:
- data = self.getAccountData(user)
- page = req.load("http://www.alldebrid.com/api.php?action=info_user&login=%s&pw=%s" % (user, data["password"]))
- self.log.debug(page)
- xml = dom.parseString(page)
- exp_time=time()+int(xml.getElementsByTagName("date")[0].childNodes[0].nodeValue)*86400
- account_info = {"validuntil": exp_time, "trafficleft": -1}
- return account_info
-
- def login(self, user, data, req):
+ +class AlldebridCom(Account): + __name__ = "AlldebridCom" + __version__ = "0.21" + __type__ = "account" + __description__ = """AllDebrid.com account plugin""" + __author_name__ = ("Andy, Voigt") + __author_mail__ = ("spamsales@online.de") + + def loadAccountInfo(self, user, req): + data = self.getAccountData(user) + page = req.load("http://www.alldebrid.com/account/") + soup=BeautifulSoup(page) + #Try to parse expiration date directly from the control panel page (better accuracy) + try: + time_text=soup.find('div',attrs={'class':'remaining_time_text'}).strong.string + self.log.debug("Account expires in: %s" % time_text) + p = re.compile('\d+') + exp_data=p.findall(time_text) + exp_time=time()+int(exp_data[0])*24*60*60+int(exp_data[1])*60*60+(int(exp_data[2])-1)*60 + #Get expiration date from API + except: + data = self.getAccountData(user) + page = req.load("http://www.alldebrid.com/api.php?action=info_user&login=%s&pw=%s" % (user, data["password"])) + self.log.debug(page) + xml = dom.parseString(page) + exp_time=time()+int(xml.getElementsByTagName("date")[0].childNodes[0].nodeValue)*86400 + account_info = {"validuntil": exp_time, "trafficleft": -1} + return account_info + + def login(self, user, data, req): urlparams = urllib.urlencode({'action':'login','login_login':user,'login_password':data["password"]}) page = req.load("http://www.alldebrid.com/register/?%s" % (urlparams)) -
- if "This login doesn't exist" in page:
- self.wrongPassword()
+ + if "This login doesn't exist" in page: + self.wrongPassword() if "The password is not valid" in page: self.wrongPassword() diff --git a/module/plugins/accounts/Premium4Me.py b/module/plugins/accounts/Premium4Me.py index c95b9b129..fbca3ce84 100644 --- a/module/plugins/accounts/Premium4Me.py +++ b/module/plugins/accounts/Premium4Me.py @@ -1,23 +1,23 @@ -from module.plugins.Account import Account
-
-class Premium4Me(Account):
- __name__ = "Premium4Me"
- __version__ = "0.03"
- __type__ = "account"
- __description__ = """Premium.to account plugin"""
- __author_name__ = ("RaNaN", "zoidberg", "stickell")
- __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz", "l.stickell@yahoo.it")
-
- def loadAccountInfo(self, user, req):
- traffic = req.load("http://premium.to/api/traffic.php?authcode=%s" % self.authcode)
-
- account_info = {"trafficleft": int(traffic) / 1024,
- "validuntil": -1}
-
- return account_info
-
- def login(self, user, data, req):
- self.authcode = req.load("http://premium.to/api/getauthcode.php?username=%s&password=%s" % (user, data["password"])).strip()
-
- if "wrong username" in self.authcode:
+from module.plugins.Account import Account + +class Premium4Me(Account): + __name__ = "Premium4Me" + __version__ = "0.03" + __type__ = "account" + __description__ = """Premium.to account plugin""" + __author_name__ = ("RaNaN", "zoidberg", "stickell") + __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz", "l.stickell@yahoo.it") + + def loadAccountInfo(self, user, req): + traffic = req.load("http://premium.to/api/traffic.php?authcode=%s" % self.authcode) + + account_info = {"trafficleft": int(traffic) / 1024, + "validuntil": -1} + + return account_info + + def login(self, user, data, req): + self.authcode = req.load("http://premium.to/api/getauthcode.php?username=%s&password=%s" % (user, data["password"])).strip() + + if "wrong username" in self.authcode: self.wrongPassword()
\ No newline at end of file diff --git a/module/plugins/accounts/PremiumizeMe.py b/module/plugins/accounts/PremiumizeMe.py index 1a446b842..696fdf88f 100644 --- a/module/plugins/accounts/PremiumizeMe.py +++ b/module/plugins/accounts/PremiumizeMe.py @@ -1,44 +1,44 @@ -from module.plugins.Account import Account
-
-from module.common.json_layer import json_loads
-
-class PremiumizeMe(Account):
- __name__ = "PremiumizeMe"
- __version__ = "0.11"
- __type__ = "account"
- __description__ = """Premiumize.Me account plugin"""
-
- __author_name__ = ("Florian Franzen")
- __author_mail__ = ("FlorianFranzen@gmail.com")
-
- def loadAccountInfo(self, user, req):
-
- # Get user data from premiumize.me
- status = self.getAccountStatus(user, req)
- self.logDebug(status)
-
- # Parse account info
- account_info = {"validuntil": float(status['result']['expires']),
- "trafficleft": max(0, status['result']['trafficleft_bytes'] / 1024)}
-
- if status['result']['type'] == 'free':
- account_info['premium'] = False
-
- return account_info
-
- def login(self, user, data, req):
-
- # Get user data from premiumize.me
- status = self.getAccountStatus(user, req)
-
- # Check if user and password are valid
- if status['status'] != 200:
- self.wrongPassword()
-
-
- def getAccountStatus(self, user, req):
-
- # Use premiumize.me API v1 (see https://secure.premiumize.me/?show=api) to retrieve account info and return the parsed json answer
- answer = req.load("https://api.premiumize.me/pm-api/v1.php?method=accountstatus¶ms[login]=%s¶ms[pass]=%s" % (user, self.accounts[user]['password']))
- return json_loads(answer)
-
+from module.plugins.Account import Account + +from module.common.json_layer import json_loads + +class PremiumizeMe(Account): + __name__ = "PremiumizeMe" + __version__ = "0.11" + __type__ = "account" + __description__ = """Premiumize.Me account plugin""" + + __author_name__ = ("Florian Franzen") + __author_mail__ = ("FlorianFranzen@gmail.com") + + def loadAccountInfo(self, user, req): + + # Get user data from premiumize.me + status = self.getAccountStatus(user, req) + self.logDebug(status) + + # Parse account info + account_info = {"validuntil": float(status['result']['expires']), + "trafficleft": max(0, status['result']['trafficleft_bytes'] / 1024)} + + if status['result']['type'] == 'free': + account_info['premium'] = False + + return account_info + + def login(self, user, data, req): + + # Get user data from premiumize.me + status = self.getAccountStatus(user, req) + + # Check if user and password are valid + if status['status'] != 200: + self.wrongPassword() + + + def getAccountStatus(self, user, req): + + # Use premiumize.me API v1 (see https://secure.premiumize.me/?show=api) to retrieve account info and return the parsed json answer + answer = req.load("https://api.premiumize.me/pm-api/v1.php?method=accountstatus¶ms[login]=%s¶ms[pass]=%s" % (user, self.accounts[user]['password'])) + return json_loads(answer) + diff --git a/module/plugins/accounts/RealdebridCom.py b/module/plugins/accounts/RealdebridCom.py index adbd090db..847a925d4 100644 --- a/module/plugins/accounts/RealdebridCom.py +++ b/module/plugins/accounts/RealdebridCom.py @@ -1,25 +1,25 @@ -from module.plugins.Account import Account
-import xml.dom.minidom as dom
-
-class RealdebridCom(Account):
- __name__ = "RealdebridCom"
- __version__ = "0.41"
- __type__ = "account"
- __description__ = """Real-Debrid.com account plugin"""
- __author_name__ = ("Devirex, Hazzard")
- __author_mail__ = ("naibaf_11@yahoo.de")
-
- def loadAccountInfo(self, user, req):
- page = req.load("http://real-debrid.com/api/account.php")
- xml = dom.parseString(page)
- account_info = {"validuntil": int(xml.getElementsByTagName("expiration")[0].childNodes[0].nodeValue),
- "trafficleft": -1}
-
- return account_info
-
- def login(self, user, data, req):
- page = req.load("https://real-debrid.com/ajax/login.php", get = {"user": user, "pass": data["password"]})
- #page = req.load("https://real-debrid.com/login.html", post={"user": user, "pass": data["password"]}, cookies=True)
-
- if "Your login informations are incorrect" in page:
- self.wrongPassword()
+from module.plugins.Account import Account +import xml.dom.minidom as dom + +class RealdebridCom(Account): + __name__ = "RealdebridCom" + __version__ = "0.41" + __type__ = "account" + __description__ = """Real-Debrid.com account plugin""" + __author_name__ = ("Devirex, Hazzard") + __author_mail__ = ("naibaf_11@yahoo.de") + + def loadAccountInfo(self, user, req): + page = req.load("http://real-debrid.com/api/account.php") + xml = dom.parseString(page) + account_info = {"validuntil": int(xml.getElementsByTagName("expiration")[0].childNodes[0].nodeValue), + "trafficleft": -1} + + return account_info + + def login(self, user, data, req): + page = req.load("https://real-debrid.com/ajax/login.php", get = {"user": user, "pass": data["password"]}) + #page = req.load("https://real-debrid.com/login.html", post={"user": user, "pass": data["password"]}, cookies=True) + + if "Your login informations are incorrect" in page: + self.wrongPassword() diff --git a/module/plugins/accounts/UploadheroCom.py b/module/plugins/accounts/UploadheroCom.py index f1e0649e6..18ed69ae6 100644 --- a/module/plugins/accounts/UploadheroCom.py +++ b/module/plugins/accounts/UploadheroCom.py @@ -1,35 +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:
+#!/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/accounts/X7To.py b/module/plugins/accounts/X7To.py index 8c2bf245a..90f65d55e 100644 --- a/module/plugins/accounts/X7To.py +++ b/module/plugins/accounts/X7To.py @@ -1,66 +1,66 @@ -# -*- 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: ernieb
-"""
-
-import re
-from time import strptime, mktime
-
-from module.plugins.Account import Account
-
-class X7To(Account):
- __name__ = "X7To"
- __version__ = "0.1"
- __type__ = "account"
- __description__ = """X7.To account plugin"""
- __author_name__ = ("ernieb")
- __author_mail__ = ("ernieb")
-
- def loadAccountInfo(self, user, req):
- page = req.load("http://www.x7.to/my")
-
- validCheck = re.search("Premium-Mitglied bis ([0-9]*-[0-9]*-[0-9]*)", page, re.IGNORECASE)
- if validCheck:
- valid = validCheck.group(1)
- valid = int(mktime(strptime(valid, "%Y-%m-%d")))
- else:
- validCheck = re.search("Premium member until ([0-9]*-[0-9]*-[0-9]*)", page, re.IGNORECASE)
- if validCheck:
- valid = validCheck.group(1)
- valid = int(mktime(strptime(valid, "%Y-%m-%d")))
- else:
- valid = 0
-
- trafficleft = re.search(r'<em style="white-space:nowrap">([\d]*[,]?[\d]?[\d]?) (KB|MB|GB)</em>', page, re.IGNORECASE)
- if trafficleft:
- units = float(trafficleft.group(1).replace(",", "."))
- pow = {'KB': 0, 'MB': 1, 'GB': 2}[trafficleft.group(2)]
- trafficleft = int(units * 1024 ** pow)
- else:
- trafficleft = -1
-
- return {"trafficleft": trafficleft, "validuntil": valid}
-
-
- def login(self, user, data, req):
- #req.cj.setCookie("share.cx", "lang", "english")
- page = req.load("http://x7.to/lang/en", None, {})
- page = req.load("http://x7.to/james/login", None,
- {"redirect": "http://www.x7.to/", "id": user, "pw": data['password'], "submit": "submit"})
-
- if "Username and password are not matching." in page:
- self.wrongPassword()
+# -*- 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: ernieb +""" + +import re +from time import strptime, mktime + +from module.plugins.Account import Account + +class X7To(Account): + __name__ = "X7To" + __version__ = "0.1" + __type__ = "account" + __description__ = """X7.To account plugin""" + __author_name__ = ("ernieb") + __author_mail__ = ("ernieb") + + def loadAccountInfo(self, user, req): + page = req.load("http://www.x7.to/my") + + validCheck = re.search("Premium-Mitglied bis ([0-9]*-[0-9]*-[0-9]*)", page, re.IGNORECASE) + if validCheck: + valid = validCheck.group(1) + valid = int(mktime(strptime(valid, "%Y-%m-%d"))) + else: + validCheck = re.search("Premium member until ([0-9]*-[0-9]*-[0-9]*)", page, re.IGNORECASE) + if validCheck: + valid = validCheck.group(1) + valid = int(mktime(strptime(valid, "%Y-%m-%d"))) + else: + valid = 0 + + trafficleft = re.search(r'<em style="white-space:nowrap">([\d]*[,]?[\d]?[\d]?) (KB|MB|GB)</em>', page, re.IGNORECASE) + if trafficleft: + units = float(trafficleft.group(1).replace(",", ".")) + pow = {'KB': 0, 'MB': 1, 'GB': 2}[trafficleft.group(2)] + trafficleft = int(units * 1024 ** pow) + else: + trafficleft = -1 + + return {"trafficleft": trafficleft, "validuntil": valid} + + + def login(self, user, data, req): + #req.cj.setCookie("share.cx", "lang", "english") + page = req.load("http://x7.to/lang/en", None, {}) + page = req.load("http://x7.to/james/login", None, + {"redirect": "http://www.x7.to/", "id": user, "pw": data['password'], "submit": "submit"}) + + if "Username and password are not matching." in page: + self.wrongPassword() diff --git a/module/plugins/crypter/ILoadTo.py b/module/plugins/crypter/ILoadTo.py index 9815ae266..100ba2bc6 100644 --- a/module/plugins/crypter/ILoadTo.py +++ b/module/plugins/crypter/ILoadTo.py @@ -1,62 +1,62 @@ -
-import re
-import urllib
-
-from module.plugins.Crypter import Crypter
-from module.lib.BeautifulSoup import BeautifulSoup
-
-class ILoadTo(Crypter):
- __name__ = "ILoadTo"
- __type__ = "crypter"
- __pattern__ = r"http://iload\.to/go/\d+-[\w\.-]+/"
- __config__ = []
- __version__ = "0.1"
- __description__ = """iload.to Crypter Plugin"""
- __author_name__ = ("hzpz")
- __author_mail__ = ("none")
-
-
- def decrypt(self, pyfile):
- url = pyfile.url
- src = self.req.load(str(url))
- soup = BeautifulSoup(src)
-
- # find captcha URL and decrypt
- captchaTag = soup.find("img", attrs={"id": "Captcha"})
- if not captchaTag:
- self.fail("Cannot find Captcha")
-
- captchaUrl = "http://iload.to" + captchaTag["src"]
- self.logDebug("Captcha URL: %s" % captchaUrl)
- result = self.decryptCaptcha(str(captchaUrl))
-
- # find captcha form URL
- formTag = soup.find("form", attrs={"id": "CaptchaForm"})
- formUrl = "http://iload.to" + formTag["action"]
- self.logDebug("Form URL: %s" % formUrl)
-
- # submit decrypted captcha
- self.req.lastURL = url
- src = self.req.load(str(formUrl), post={'captcha': result})
-
- # find decrypted links
- links = re.findall(r"<a href=\"(.+)\" style=\"text-align:center;font-weight:bold;\" class=\"button\" target=\"_blank\" onclick=\"this.className\+=' success';\">", src)
-
- if not len(links) > 0:
- self.retry()
-
- self.correctCaptcha()
-
- cleanedLinks = []
- for link in links:
- if link.startswith("http://dontknow.me/at/?"):
- cleanedLink = urllib.unquote(link[23:])
- else:
- cleanedLink = link
- self.logDebug("Link: %s" % cleanedLink)
- cleanedLinks.append(cleanedLink)
-
- self.logDebug("Decrypted %d links" % len(links))
-
- self.pyfile.package().password = "iload.to"
+ +import re +import urllib + +from module.plugins.Crypter import Crypter +from module.lib.BeautifulSoup import BeautifulSoup + +class ILoadTo(Crypter): + __name__ = "ILoadTo" + __type__ = "crypter" + __pattern__ = r"http://iload\.to/go/\d+-[\w\.-]+/" + __config__ = [] + __version__ = "0.1" + __description__ = """iload.to Crypter Plugin""" + __author_name__ = ("hzpz") + __author_mail__ = ("none") + + + def decrypt(self, pyfile): + url = pyfile.url + src = self.req.load(str(url)) + soup = BeautifulSoup(src) + + # find captcha URL and decrypt + captchaTag = soup.find("img", attrs={"id": "Captcha"}) + if not captchaTag: + self.fail("Cannot find Captcha") + + captchaUrl = "http://iload.to" + captchaTag["src"] + self.logDebug("Captcha URL: %s" % captchaUrl) + result = self.decryptCaptcha(str(captchaUrl)) + + # find captcha form URL + formTag = soup.find("form", attrs={"id": "CaptchaForm"}) + formUrl = "http://iload.to" + formTag["action"] + self.logDebug("Form URL: %s" % formUrl) + + # submit decrypted captcha + self.req.lastURL = url + src = self.req.load(str(formUrl), post={'captcha': result}) + + # find decrypted links + links = re.findall(r"<a href=\"(.+)\" style=\"text-align:center;font-weight:bold;\" class=\"button\" target=\"_blank\" onclick=\"this.className\+=' success';\">", src) + + if not len(links) > 0: + self.retry() + + self.correctCaptcha() + + cleanedLinks = [] + for link in links: + if link.startswith("http://dontknow.me/at/?"): + cleanedLink = urllib.unquote(link[23:]) + else: + cleanedLink = link + self.logDebug("Link: %s" % cleanedLink) + cleanedLinks.append(cleanedLink) + + self.logDebug("Decrypted %d links" % len(links)) + + self.pyfile.package().password = "iload.to" self.packages.append((self.pyfile.package().name, cleanedLinks, self.pyfile.package().folder))
\ No newline at end of file diff --git a/module/plugins/crypter/LinkSaveIn.py b/module/plugins/crypter/LinkSaveIn.py index 30cc61055..e021316bf 100644 --- a/module/plugins/crypter/LinkSaveIn.py +++ b/module/plugins/crypter/LinkSaveIn.py @@ -1,227 +1,227 @@ -# -*- coding: utf-8 -*-
-
-#
-# v2.01 - hagg
-# * cnl2 and web links are skipped if JS is not available (instead of failing the package)
-# * only best available link source is used (priority: cnl2>rsdf>ccf>dlc>web
-#
-
-from Crypto.Cipher import AES
-from module.plugins.Crypter import Crypter
-from module.unescape import unescape
-import base64
-import binascii
-import re
-
-class LinkSaveIn(Crypter):
- __name__ = "LinkSaveIn"
- __type__ = "crypter"
- __pattern__ = r"http://(www\.)?linksave.in/(?P<id>\w+)$"
- __version__ = "2.01"
- __description__ = """LinkSave.in Crypter Plugin"""
- __author_name__ = ("fragonib")
- __author_mail__ = ("fragonib[AT]yahoo[DOT]es")
-
- # Constants
- _JK_KEY_ = "jk"
- _CRYPTED_KEY_ = "crypted"
- HOSTER_DOMAIN = "linksave.in"
-
- def setup(self):
- self.html = None
- self.fileid = None
- self.captcha = False
- self.package = None
- self.preferred_sources = ['cnl2', 'rsdf', 'ccf', 'dlc', 'web']
-
- def decrypt(self, pyfile):
-
- # Init
- self.package = pyfile.package()
- self.fileid = re.match(self.__pattern__, pyfile.url).group('id')
- self.req.cj.setCookie(self.HOSTER_DOMAIN, "Linksave_Language", "english")
-
- # Request package
- self.html = self.load(self.pyfile.url)
- if not self.isOnline():
- self.offline()
-
- # Check for protection
- if self.isPasswordProtected():
- self.unlockPasswordProtection()
- self.handleErrors()
-
- if self.isCaptchaProtected():
- self.captcha = True
- self.unlockCaptchaProtection()
- self.handleErrors()
-
- # Get package name and folder
- (package_name, folder_name) = self.getPackageInfo()
-
- # Extract package links
- package_links = []
- for type_ in self.preferred_sources:
- package_links.extend(self.handleLinkSource(type_))
- if package_links: # use only first source which provides links
- break
- package_links = set(package_links)
-
- # Pack
- if package_links:
- self.packages = [(package_name, package_links, folder_name)]
- else:
- self.fail('Could not extract any links')
-
- def isOnline(self):
- if "<big>Error 404 - Folder not found!</big>" in self.html:
- self.logDebug("File not found")
- return False
- return True
-
- def isPasswordProtected(self):
- if re.search(r'''<input.*?type="password"''', self.html):
- self.logDebug("Links are password protected")
- return True
-
- def isCaptchaProtected(self):
- if "<b>Captcha:</b>" in self.html:
- self.logDebug("Links are captcha protected")
- return True
- return False
-
- def unlockPasswordProtection(self):
- password = self.getPassword()
- self.logDebug("Submitting password [%s] for protected links" % password)
- post = {"id": self.fileid, "besucherpasswort": password, 'login': 'submit'}
- self.html = self.load(self.pyfile.url, post=post)
-
- def unlockCaptchaProtection(self):
- captcha_hash = re.search(r'name="hash" value="([^"]+)', self.html).group(1)
- captcha_url = re.search(r'src=".(/captcha/cap.php\?hsh=[^"]+)', self.html).group(1)
- captcha_code = self.decryptCaptcha("http://linksave.in" + captcha_url, forceUser=True)
- self.html = self.load(self.pyfile.url, post={"id": self.fileid, "hash": captcha_hash, "code": captcha_code})
-
- def getPackageInfo(self):
- name = self.pyfile.package().name
- folder = self.pyfile.package().folder
- self.logDebug("Defaulting to pyfile name [%s] and folder [%s] for package" % (name, folder))
- return name, folder
-
- def handleErrors(self):
- if "The visitorpassword you have entered is wrong" in self.html:
- self.logDebug("Incorrect password, please set right password on 'Edit package' form and retry")
- self.fail("Incorrect password, please set right password on 'Edit package' form and retry")
-
- if self.captcha:
- if "Wrong code. Please retry" in self.html:
- self.logDebug("Invalid captcha, retrying")
- self.invalidCaptcha()
- self.retry()
- else:
- self.correctCaptcha()
-
- def handleLinkSource(self, type_):
- if type_ == 'cnl2':
- return self.handleCNL2()
- elif type_ in ('rsdf', 'ccf', 'dlc'):
- return self.handleContainer(type_)
- elif type_ == 'web':
- return self.handleWebLinks()
- else:
- self.fail('unknown source type "%s" (this is probably a bug)' % type_)
-
- def handleWebLinks(self):
- package_links = []
- self.logDebug("Search for Web links")
- if not self.js:
- self.logDebug("no JS -> skip Web links")
- else:
- #@TODO: Gather paginated web links
- pattern = r'<a href="http://linksave\.in/(\w{43})"'
- ids = re.findall(pattern, self.html)
- self.logDebug("Decrypting %d Web links" % len(ids))
- for i, weblink_id in enumerate(ids):
- try:
- webLink = "http://linksave.in/%s" % weblink_id
- self.logDebug("Decrypting Web link %d, %s" % (i+1, webLink))
- fwLink = "http://linksave.in/fw-%s" % weblink_id
- response = self.load(fwLink)
- jscode = re.findall(r'<script type="text/javascript">(.*)</script>', response)[-1]
- jseval = self.js.eval("document = { write: function(e) { return e; } }; %s" % jscode)
- dlLink = re.search(r'http://linksave\.in/dl-\w+', jseval).group(0)
- self.logDebug("JsEngine returns value [%s] for redirection link" % dlLink)
- response = self.load(dlLink)
- link = unescape(re.search(r'<iframe src="(.+?)"', response).group(1))
- package_links.append(link)
- except Exception, detail:
- self.logDebug("Error decrypting Web link %s, %s" % (webLink, detail))
- return package_links
-
- def handleContainer(self, type_):
- package_links = []
- type_ = type_.lower()
- self.logDebug('Seach for %s Container links' % type_.upper())
- if not type_.isalnum(): # check to prevent broken re-pattern (cnl2,rsdf,ccf,dlc,web are all alpha-numeric)
- self.fail('unknown container type "%s" (this is probably a bug)' % type_)
- pattern = r"\('%s_link'\).href=unescape\('(.*?\.%s)'\)" % (type_, type_)
- containersLinks = re.findall(pattern, self.html)
- self.logDebug("Found %d %s Container links" % (len(containersLinks), type_.upper()))
- for containerLink in containersLinks:
- link = "http://linksave.in/%s" % unescape(containerLink)
- package_links.append(link)
- return package_links
-
- def handleCNL2(self):
- package_links = []
- self.logDebug("Search for CNL2 links")
- if not self.js:
- self.logDebug("no JS -> skip CNL2 links")
- elif 'cnl2_load' in self.html:
- try:
- (vcrypted, vjk) = self._getCipherParams()
- for (crypted, jk) in zip(vcrypted, vjk):
- package_links.extend(self._getLinks(crypted, jk))
- except:
- self.fail("Unable to decrypt CNL2 links")
- return package_links
-
- def _getCipherParams(self):
-
- # Get jk
- jk_re = r'<INPUT.*?NAME="%s".*?VALUE="(.*?)"' % LinkSaveIn._JK_KEY_
- vjk = re.findall(jk_re, self.html)
-
- # Get crypted
- crypted_re = r'<INPUT.*?NAME="%s".*?VALUE="(.*?)"' % LinkSaveIn._CRYPTED_KEY_
- vcrypted = re.findall(crypted_re, self.html)
-
- # Log and return
- self.logDebug("Detected %d crypted blocks" % len(vcrypted))
- return vcrypted, vjk
-
- def _getLinks(self, crypted, jk):
-
- # Get key
- jreturn = self.js.eval("%s f()" % jk)
- self.logDebug("JsEngine returns value [%s]" % jreturn)
- key = binascii.unhexlify(jreturn)
-
- # Decode crypted
- crypted = base64.standard_b64decode(crypted)
-
- # Decrypt
- Key = key
- IV = key
- obj = AES.new(Key, AES.MODE_CBC, IV)
- text = obj.decrypt(crypted)
-
- # Extract links
- text = text.replace("\x00", "").replace("\r", "")
- links = text.split("\n")
- links = filter(lambda x: x != "", links)
-
- # Log and return
- self.logDebug("Package has %d links" % len(links))
- return links
-
+# -*- coding: utf-8 -*- + +# +# v2.01 - hagg +# * cnl2 and web links are skipped if JS is not available (instead of failing the package) +# * only best available link source is used (priority: cnl2>rsdf>ccf>dlc>web +# + +from Crypto.Cipher import AES +from module.plugins.Crypter import Crypter +from module.unescape import unescape +import base64 +import binascii +import re + +class LinkSaveIn(Crypter): + __name__ = "LinkSaveIn" + __type__ = "crypter" + __pattern__ = r"http://(www\.)?linksave.in/(?P<id>\w+)$" + __version__ = "2.01" + __description__ = """LinkSave.in Crypter Plugin""" + __author_name__ = ("fragonib") + __author_mail__ = ("fragonib[AT]yahoo[DOT]es") + + # Constants + _JK_KEY_ = "jk" + _CRYPTED_KEY_ = "crypted" + HOSTER_DOMAIN = "linksave.in" + + def setup(self): + self.html = None + self.fileid = None + self.captcha = False + self.package = None + self.preferred_sources = ['cnl2', 'rsdf', 'ccf', 'dlc', 'web'] + + def decrypt(self, pyfile): + + # Init + self.package = pyfile.package() + self.fileid = re.match(self.__pattern__, pyfile.url).group('id') + self.req.cj.setCookie(self.HOSTER_DOMAIN, "Linksave_Language", "english") + + # Request package + self.html = self.load(self.pyfile.url) + if not self.isOnline(): + self.offline() + + # Check for protection + if self.isPasswordProtected(): + self.unlockPasswordProtection() + self.handleErrors() + + if self.isCaptchaProtected(): + self.captcha = True + self.unlockCaptchaProtection() + self.handleErrors() + + # Get package name and folder + (package_name, folder_name) = self.getPackageInfo() + + # Extract package links + package_links = [] + for type_ in self.preferred_sources: + package_links.extend(self.handleLinkSource(type_)) + if package_links: # use only first source which provides links + break + package_links = set(package_links) + + # Pack + if package_links: + self.packages = [(package_name, package_links, folder_name)] + else: + self.fail('Could not extract any links') + + def isOnline(self): + if "<big>Error 404 - Folder not found!</big>" in self.html: + self.logDebug("File not found") + return False + return True + + def isPasswordProtected(self): + if re.search(r'''<input.*?type="password"''', self.html): + self.logDebug("Links are password protected") + return True + + def isCaptchaProtected(self): + if "<b>Captcha:</b>" in self.html: + self.logDebug("Links are captcha protected") + return True + return False + + def unlockPasswordProtection(self): + password = self.getPassword() + self.logDebug("Submitting password [%s] for protected links" % password) + post = {"id": self.fileid, "besucherpasswort": password, 'login': 'submit'} + self.html = self.load(self.pyfile.url, post=post) + + def unlockCaptchaProtection(self): + captcha_hash = re.search(r'name="hash" value="([^"]+)', self.html).group(1) + captcha_url = re.search(r'src=".(/captcha/cap.php\?hsh=[^"]+)', self.html).group(1) + captcha_code = self.decryptCaptcha("http://linksave.in" + captcha_url, forceUser=True) + self.html = self.load(self.pyfile.url, post={"id": self.fileid, "hash": captcha_hash, "code": captcha_code}) + + def getPackageInfo(self): + name = self.pyfile.package().name + folder = self.pyfile.package().folder + self.logDebug("Defaulting to pyfile name [%s] and folder [%s] for package" % (name, folder)) + return name, folder + + def handleErrors(self): + if "The visitorpassword you have entered is wrong" in self.html: + self.logDebug("Incorrect password, please set right password on 'Edit package' form and retry") + self.fail("Incorrect password, please set right password on 'Edit package' form and retry") + + if self.captcha: + if "Wrong code. Please retry" in self.html: + self.logDebug("Invalid captcha, retrying") + self.invalidCaptcha() + self.retry() + else: + self.correctCaptcha() + + def handleLinkSource(self, type_): + if type_ == 'cnl2': + return self.handleCNL2() + elif type_ in ('rsdf', 'ccf', 'dlc'): + return self.handleContainer(type_) + elif type_ == 'web': + return self.handleWebLinks() + else: + self.fail('unknown source type "%s" (this is probably a bug)' % type_) + + def handleWebLinks(self): + package_links = [] + self.logDebug("Search for Web links") + if not self.js: + self.logDebug("no JS -> skip Web links") + else: + #@TODO: Gather paginated web links + pattern = r'<a href="http://linksave\.in/(\w{43})"' + ids = re.findall(pattern, self.html) + self.logDebug("Decrypting %d Web links" % len(ids)) + for i, weblink_id in enumerate(ids): + try: + webLink = "http://linksave.in/%s" % weblink_id + self.logDebug("Decrypting Web link %d, %s" % (i+1, webLink)) + fwLink = "http://linksave.in/fw-%s" % weblink_id + response = self.load(fwLink) + jscode = re.findall(r'<script type="text/javascript">(.*)</script>', response)[-1] + jseval = self.js.eval("document = { write: function(e) { return e; } }; %s" % jscode) + dlLink = re.search(r'http://linksave\.in/dl-\w+', jseval).group(0) + self.logDebug("JsEngine returns value [%s] for redirection link" % dlLink) + response = self.load(dlLink) + link = unescape(re.search(r'<iframe src="(.+?)"', response).group(1)) + package_links.append(link) + except Exception, detail: + self.logDebug("Error decrypting Web link %s, %s" % (webLink, detail)) + return package_links + + def handleContainer(self, type_): + package_links = [] + type_ = type_.lower() + self.logDebug('Seach for %s Container links' % type_.upper()) + if not type_.isalnum(): # check to prevent broken re-pattern (cnl2,rsdf,ccf,dlc,web are all alpha-numeric) + self.fail('unknown container type "%s" (this is probably a bug)' % type_) + pattern = r"\('%s_link'\).href=unescape\('(.*?\.%s)'\)" % (type_, type_) + containersLinks = re.findall(pattern, self.html) + self.logDebug("Found %d %s Container links" % (len(containersLinks), type_.upper())) + for containerLink in containersLinks: + link = "http://linksave.in/%s" % unescape(containerLink) + package_links.append(link) + return package_links + + def handleCNL2(self): + package_links = [] + self.logDebug("Search for CNL2 links") + if not self.js: + self.logDebug("no JS -> skip CNL2 links") + elif 'cnl2_load' in self.html: + try: + (vcrypted, vjk) = self._getCipherParams() + for (crypted, jk) in zip(vcrypted, vjk): + package_links.extend(self._getLinks(crypted, jk)) + except: + self.fail("Unable to decrypt CNL2 links") + return package_links + + def _getCipherParams(self): + + # Get jk + jk_re = r'<INPUT.*?NAME="%s".*?VALUE="(.*?)"' % LinkSaveIn._JK_KEY_ + vjk = re.findall(jk_re, self.html) + + # Get crypted + crypted_re = r'<INPUT.*?NAME="%s".*?VALUE="(.*?)"' % LinkSaveIn._CRYPTED_KEY_ + vcrypted = re.findall(crypted_re, self.html) + + # Log and return + self.logDebug("Detected %d crypted blocks" % len(vcrypted)) + return vcrypted, vjk + + def _getLinks(self, crypted, jk): + + # Get key + jreturn = self.js.eval("%s f()" % jk) + self.logDebug("JsEngine returns value [%s]" % jreturn) + key = binascii.unhexlify(jreturn) + + # Decode crypted + crypted = base64.standard_b64decode(crypted) + + # Decrypt + Key = key + IV = key + obj = AES.new(Key, AES.MODE_CBC, IV) + text = obj.decrypt(crypted) + + # Extract links + text = text.replace("\x00", "").replace("\r", "") + links = text.split("\n") + links = filter(lambda x: x != "", links) + + # Log and return + self.logDebug("Package has %d links" % len(links)) + return links + diff --git a/module/plugins/crypter/NCryptIn.py b/module/plugins/crypter/NCryptIn.py index e1cd30475..821636821 100644 --- a/module/plugins/crypter/NCryptIn.py +++ b/module/plugins/crypter/NCryptIn.py @@ -1,251 +1,251 @@ -# -*- coding: utf-8 -*-
-
-from Crypto.Cipher import AES
-from module.plugins.Crypter import Crypter
-from module.plugins.ReCaptcha import ReCaptcha
-import base64
-import binascii
-import re
-
-class NCryptIn(Crypter):
- __name__ = "NCryptIn"
- __type__ = "crypter"
- __pattern__ = r"http://(?:www\.)?ncrypt.in/folder-([^/\?]+)"
- __version__ = "1.22"
- __description__ = """NCrypt.in Crypter Plugin"""
- __author_name__ = ("fragonib")
- __author_mail__ = ("fragonib[AT]yahoo[DOT]es")
-
- # Constants
- _JK_KEY_ = "jk"
- _CRYPTED_KEY_ = "crypted"
-
- def setup(self):
- self.html = None
- self.cleanedHtml = None
- self.captcha = False
- self.package = None
-
- def decrypt(self, pyfile):
-
- # Init
- self.package = pyfile.package()
-
- # Request package
- self.html = self.load(self.pyfile.url)
- self.cleanedHtml = self.removeCrap(self.html)
- if not self.isOnline():
- self.offline()
-
- # Check for protection
- if self.isProtected():
- self.html = self.unlockProtection()
- self.cleanedHtml = self.removeCrap(self.html)
- self.handleErrors()
-
- # Get package name and folder
- (package_name, folder_name) = self.getPackageInfo()
-
- # Extract package links
- package_links = []
- package_links.extend(self.handleWebLinks())
- package_links.extend(self.handleContainers())
- package_links.extend(self.handleCNL2())
- package_links = self.removeContainers(package_links)
- package_links = set(package_links)
-
- # Pack
- self.packages = [(package_name, package_links, folder_name)]
-
- def removeCrap(self, content):
- patterns = (r'(type="hidden".*?(name=".*?")?.*?value=".*?")',
- r'display:none;">(.*?)</(div|span)>',
- r'<div\s+class="jdownloader"(.*?)</div>',
- r'<iframe\s+style="display:none(.*?)</iframe>')
- for pattern in patterns:
- rexpr = re.compile(pattern, re.DOTALL)
- content = re.sub(rexpr, "", content)
- return content
-
- def removeContainers(self,package_links):
- tmp_package_links = package_links[:]
- for link in tmp_package_links:
- self.logDebug(link)
- if ".dlc" in link or ".ccf" in link or ".rsdf" in link:
- self.logDebug("Removing [%s] from package_links" % link)
- package_links.remove(link)
-
- if len(package_links) > 0:
- return package_links
- else:
- return tmp_package_links
-
- def isOnline(self):
- if "Your folder does not exist" in self.cleanedHtml:
- self.logDebug("File not found")
- return False
- return True
-
- def isProtected(self):
- if re.search(r'''<form.*?name.*?protected.*?>''', self.cleanedHtml):
- self.logDebug("Links are protected")
- return True
- return False
-
- def getPackageInfo(self):
- title_re = r'<h2><span.*?class="arrow".*?>(?P<title>[^<]+).*?</span>.*?</h2>'
- m = re.findall(title_re, self.html, re.DOTALL)
- if m is not None:
- title = m[-1].strip()
- name = folder = title
- self.logDebug("Found name [%s] and folder [%s] in package info" % (name, folder))
- else:
- name = self.package.name
- folder = self.package.folder
- self.logDebug("Package info not found, defaulting to pyfile name [%s] and folder [%s]" % (name, folder))
- return name, folder
-
- def unlockProtection(self):
-
- postData = {}
-
- form = re.search(r'''<form\ name="protected"(.*?)</form>''', self.cleanedHtml, re.DOTALL).group(1)
-
- # Submit package password
- if "password" in form:
- password = self.getPassword()
- self.logDebug("Submitting password [%s] for protected links" % password)
- postData['password'] = password
-
- # Resolve anicaptcha
- if "anicaptcha" in form:
- self.captcha = True
- self.logDebug("Captcha protected, resolving captcha")
- captchaUri = re.search(r'src="(/temp/anicaptcha/[^"]+)', form).group(1)
- captcha = self.decryptCaptcha("http://ncrypt.in" + captchaUri)
- self.logDebug("Captcha resolved [%s]" % captcha)
- postData['captcha'] = captcha
-
- # Resolve recaptcha
- if "recaptcha" in form:
- self.captcha = True
- id = re.search(r'\?k=(.*?)"', form).group(1)
- self.logDebug("Resolving ReCaptcha with key [%s]" % id)
- recaptcha = ReCaptcha(self)
- challenge, code = recaptcha.challenge(id)
- postData['recaptcha_challenge_field'] = challenge
- postData['recaptcha_response_field'] = code
-
- # Resolve circlecaptcha
- if "circlecaptcha" in form:
- self.captcha = True
- self.logDebug("Captcha protected")
- captcha_img_url = "http://ncrypt.in/classes/captcha/circlecaptcha.php"
- coords = self.decryptCaptcha(captcha_img_url, forceUser=True, imgtype="png", result_type='positional')
- self.logDebug("Captcha resolved, coords [%s]" % str(coords))
- self.captcha_post_url = self.pyfile.url
-
- postData['circle.x'] = coords[0]
- postData['circle.y'] = coords[1]
-
-
- # Unlock protection
- postData['submit_protected'] = 'Continue to folder '
- return self.load(self.pyfile.url, post=postData)
-
- def handleErrors(self):
-
- if "This password is invalid!" in self.cleanedHtml:
- self.logDebug("Incorrect password, please set right password on 'Edit package' form and retry")
- self.fail("Incorrect password, please set right password on 'Edit package' form and retry")
-
- if self.captcha:
- if "The securitycheck was wrong!" in self.cleanedHtml:
- self.logDebug("Invalid captcha, retrying")
- self.invalidCaptcha()
- self.retry()
- else:
- self.correctCaptcha()
-
- def handleWebLinks(self):
- package_links = []
- self.logDebug("Handling Web links")
-
- pattern = r"(http://ncrypt\.in/link-.*?=)"
- links = re.findall(pattern, self.html)
- self.logDebug("Decrypting %d Web links" % len(links))
- for i, link in enumerate(links):
- self.logDebug("Decrypting Web link %d, %s" % (i+1, link))
- try:
- url = link.replace("link-", "frame-")
- link = self.load(url, just_header=True)['location']
- package_links.append(link)
- except Exception, detail:
- self.logDebug("Error decrypting Web link %s, %s" % (link, detail))
- return package_links
-
- def handleContainers(self):
- package_links = []
- self.logDebug("Handling Container links")
-
- pattern = r"/container/(rsdf|dlc|ccf)/([a-z0-9]+)"
- containersLinks = re.findall(pattern, self.html)
- self.logDebug("Decrypting %d Container links" % len(containersLinks))
- for containerLink in containersLinks:
- link = "http://ncrypt.in/container/%s/%s.%s" % (containerLink[0], containerLink[1], containerLink[0])
- package_links.append(link)
- return package_links
-
- def handleCNL2(self):
- package_links = []
- self.logDebug("Handling CNL2 links")
-
- if 'cnl2_output' in self.cleanedHtml:
- try:
- (vcrypted, vjk) = self._getCipherParams()
- for (crypted, jk) in zip(vcrypted, vjk):
- package_links.extend(self._getLinks(crypted, jk))
- except:
- self.fail("Unable to decrypt CNL2 links")
- return package_links
-
- def _getCipherParams(self):
-
- pattern = r'<input.*?name="%s".*?value="(.*?)"'
-
- # Get jk
- jk_re = pattern % NCryptIn._JK_KEY_
- vjk = re.findall(jk_re, self.html)
-
- # Get crypted
- crypted_re = pattern % NCryptIn._CRYPTED_KEY_
- vcrypted = re.findall(crypted_re, self.html)
-
- # Log and return
- self.logDebug("Detected %d crypted blocks" % len(vcrypted))
- return vcrypted, vjk
-
- def _getLinks(self, crypted, jk):
-
- # Get key
- jreturn = self.js.eval("%s f()" % jk)
- self.logDebug("JsEngine returns value [%s]" % jreturn)
- key = binascii.unhexlify(jreturn)
-
- # Decode crypted
- crypted = base64.standard_b64decode(crypted)
-
- # Decrypt
- Key = key
- IV = key
- obj = AES.new(Key, AES.MODE_CBC, IV)
- text = obj.decrypt(crypted)
-
- # Extract links
- text = text.replace("\x00", "").replace("\r", "")
- links = text.split("\n")
- links = filter(lambda x: x != "", links)
-
- # Log and return
- self.logDebug("Block has %d links" % len(links))
- return links
+# -*- coding: utf-8 -*- + +from Crypto.Cipher import AES +from module.plugins.Crypter import Crypter +from module.plugins.ReCaptcha import ReCaptcha +import base64 +import binascii +import re + +class NCryptIn(Crypter): + __name__ = "NCryptIn" + __type__ = "crypter" + __pattern__ = r"http://(?:www\.)?ncrypt.in/folder-([^/\?]+)" + __version__ = "1.22" + __description__ = """NCrypt.in Crypter Plugin""" + __author_name__ = ("fragonib") + __author_mail__ = ("fragonib[AT]yahoo[DOT]es") + + # Constants + _JK_KEY_ = "jk" + _CRYPTED_KEY_ = "crypted" + + def setup(self): + self.html = None + self.cleanedHtml = None + self.captcha = False + self.package = None + + def decrypt(self, pyfile): + + # Init + self.package = pyfile.package() + + # Request package + self.html = self.load(self.pyfile.url) + self.cleanedHtml = self.removeCrap(self.html) + if not self.isOnline(): + self.offline() + + # Check for protection + if self.isProtected(): + self.html = self.unlockProtection() + self.cleanedHtml = self.removeCrap(self.html) + self.handleErrors() + + # Get package name and folder + (package_name, folder_name) = self.getPackageInfo() + + # Extract package links + package_links = [] + package_links.extend(self.handleWebLinks()) + package_links.extend(self.handleContainers()) + package_links.extend(self.handleCNL2()) + package_links = self.removeContainers(package_links) + package_links = set(package_links) + + # Pack + self.packages = [(package_name, package_links, folder_name)] + + def removeCrap(self, content): + patterns = (r'(type="hidden".*?(name=".*?")?.*?value=".*?")', + r'display:none;">(.*?)</(div|span)>', + r'<div\s+class="jdownloader"(.*?)</div>', + r'<iframe\s+style="display:none(.*?)</iframe>') + for pattern in patterns: + rexpr = re.compile(pattern, re.DOTALL) + content = re.sub(rexpr, "", content) + return content + + def removeContainers(self,package_links): + tmp_package_links = package_links[:] + for link in tmp_package_links: + self.logDebug(link) + if ".dlc" in link or ".ccf" in link or ".rsdf" in link: + self.logDebug("Removing [%s] from package_links" % link) + package_links.remove(link) + + if len(package_links) > 0: + return package_links + else: + return tmp_package_links + + def isOnline(self): + if "Your folder does not exist" in self.cleanedHtml: + self.logDebug("File not found") + return False + return True + + def isProtected(self): + if re.search(r'''<form.*?name.*?protected.*?>''', self.cleanedHtml): + self.logDebug("Links are protected") + return True + return False + + def getPackageInfo(self): + title_re = r'<h2><span.*?class="arrow".*?>(?P<title>[^<]+).*?</span>.*?</h2>' + m = re.findall(title_re, self.html, re.DOTALL) + if m is not None: + title = m[-1].strip() + name = folder = title + self.logDebug("Found name [%s] and folder [%s] in package info" % (name, folder)) + else: + name = self.package.name + folder = self.package.folder + self.logDebug("Package info not found, defaulting to pyfile name [%s] and folder [%s]" % (name, folder)) + return name, folder + + def unlockProtection(self): + + postData = {} + + form = re.search(r'''<form\ name="protected"(.*?)</form>''', self.cleanedHtml, re.DOTALL).group(1) + + # Submit package password + if "password" in form: + password = self.getPassword() + self.logDebug("Submitting password [%s] for protected links" % password) + postData['password'] = password + + # Resolve anicaptcha + if "anicaptcha" in form: + self.captcha = True + self.logDebug("Captcha protected, resolving captcha") + captchaUri = re.search(r'src="(/temp/anicaptcha/[^"]+)', form).group(1) + captcha = self.decryptCaptcha("http://ncrypt.in" + captchaUri) + self.logDebug("Captcha resolved [%s]" % captcha) + postData['captcha'] = captcha + + # Resolve recaptcha + if "recaptcha" in form: + self.captcha = True + id = re.search(r'\?k=(.*?)"', form).group(1) + self.logDebug("Resolving ReCaptcha with key [%s]" % id) + recaptcha = ReCaptcha(self) + challenge, code = recaptcha.challenge(id) + postData['recaptcha_challenge_field'] = challenge + postData['recaptcha_response_field'] = code + + # Resolve circlecaptcha + if "circlecaptcha" in form: + self.captcha = True + self.logDebug("Captcha protected") + captcha_img_url = "http://ncrypt.in/classes/captcha/circlecaptcha.php" + coords = self.decryptCaptcha(captcha_img_url, forceUser=True, imgtype="png", result_type='positional') + self.logDebug("Captcha resolved, coords [%s]" % str(coords)) + self.captcha_post_url = self.pyfile.url + + postData['circle.x'] = coords[0] + postData['circle.y'] = coords[1] + + + # Unlock protection + postData['submit_protected'] = 'Continue to folder ' + return self.load(self.pyfile.url, post=postData) + + def handleErrors(self): + + if "This password is invalid!" in self.cleanedHtml: + self.logDebug("Incorrect password, please set right password on 'Edit package' form and retry") + self.fail("Incorrect password, please set right password on 'Edit package' form and retry") + + if self.captcha: + if "The securitycheck was wrong!" in self.cleanedHtml: + self.logDebug("Invalid captcha, retrying") + self.invalidCaptcha() + self.retry() + else: + self.correctCaptcha() + + def handleWebLinks(self): + package_links = [] + self.logDebug("Handling Web links") + + pattern = r"(http://ncrypt\.in/link-.*?=)" + links = re.findall(pattern, self.html) + self.logDebug("Decrypting %d Web links" % len(links)) + for i, link in enumerate(links): + self.logDebug("Decrypting Web link %d, %s" % (i+1, link)) + try: + url = link.replace("link-", "frame-") + link = self.load(url, just_header=True)['location'] + package_links.append(link) + except Exception, detail: + self.logDebug("Error decrypting Web link %s, %s" % (link, detail)) + return package_links + + def handleContainers(self): + package_links = [] + self.logDebug("Handling Container links") + + pattern = r"/container/(rsdf|dlc|ccf)/([a-z0-9]+)" + containersLinks = re.findall(pattern, self.html) + self.logDebug("Decrypting %d Container links" % len(containersLinks)) + for containerLink in containersLinks: + link = "http://ncrypt.in/container/%s/%s.%s" % (containerLink[0], containerLink[1], containerLink[0]) + package_links.append(link) + return package_links + + def handleCNL2(self): + package_links = [] + self.logDebug("Handling CNL2 links") + + if 'cnl2_output' in self.cleanedHtml: + try: + (vcrypted, vjk) = self._getCipherParams() + for (crypted, jk) in zip(vcrypted, vjk): + package_links.extend(self._getLinks(crypted, jk)) + except: + self.fail("Unable to decrypt CNL2 links") + return package_links + + def _getCipherParams(self): + + pattern = r'<input.*?name="%s".*?value="(.*?)"' + + # Get jk + jk_re = pattern % NCryptIn._JK_KEY_ + vjk = re.findall(jk_re, self.html) + + # Get crypted + crypted_re = pattern % NCryptIn._CRYPTED_KEY_ + vcrypted = re.findall(crypted_re, self.html) + + # Log and return + self.logDebug("Detected %d crypted blocks" % len(vcrypted)) + return vcrypted, vjk + + def _getLinks(self, crypted, jk): + + # Get key + jreturn = self.js.eval("%s f()" % jk) + self.logDebug("JsEngine returns value [%s]" % jreturn) + key = binascii.unhexlify(jreturn) + + # Decode crypted + crypted = base64.standard_b64decode(crypted) + + # Decrypt + Key = key + IV = key + obj = AES.new(Key, AES.MODE_CBC, IV) + text = obj.decrypt(crypted) + + # Extract links + text = text.replace("\x00", "").replace("\r", "") + links = text.split("\n") + links = filter(lambda x: x != "", links) + + # Log and return + self.logDebug("Block has %d links" % len(links)) + return links diff --git a/module/plugins/crypter/ShareLinksBiz.py b/module/plugins/crypter/ShareLinksBiz.py index 1ffa5d41a..b0e735896 100644 --- a/module/plugins/crypter/ShareLinksBiz.py +++ b/module/plugins/crypter/ShareLinksBiz.py @@ -1,269 +1,269 @@ -# -*- coding: utf-8 -*-
-
-from Crypto.Cipher import AES
-from module.plugins.Crypter import Crypter
-from module.plugins.ReCaptcha import ReCaptcha
-import base64
-import binascii
-import re
-
-
-class ShareLinksBiz(Crypter):
- __name__ = "ShareLinksBiz"
- __type__ = "crypter"
- __pattern__ = r"(?P<base>http://[\w\.]*?(share-links|s2l)\.biz)/(?P<id>_?[0-9a-z]+)(/.*)?"
- __version__ = "1.12"
- __description__ = """Share-Links.biz Crypter"""
- __author_name__ = ("fragonib")
- __author_mail__ = ("fragonib[AT]yahoo[DOT]es")
-
-
- def setup(self):
- self.baseUrl = None
- self.fileId = None
- self.package = None
- self.html = None
- self.captcha = False
-
- def decrypt(self, pyfile):
-
- # Init
- self.initFile(pyfile)
-
- # Request package
- url = self.baseUrl + '/' + self.fileId
- self.html = self.load(url, decode=True)
-
- # Unblock server (load all images)
- self.unblockServer()
-
- # Check for protection
- if self.isPasswordProtected():
- self.unlockPasswordProtection()
- self.handleErrors()
-
- if self.isCaptchaProtected():
- self.captcha = True
- self.unlockCaptchaProtection()
- self.handleErrors()
-
- # Extract package links
- package_links = []
- package_links.extend(self.handleWebLinks())
- package_links.extend(self.handleContainers())
- package_links.extend(self.handleCNL2())
- package_links = set(package_links)
-
- # Get package info
- package_name, package_folder = self.getPackageInfo()
-
- # Pack
- self.packages = [(package_name, package_links, package_folder)]
-
- def initFile(self, pyfile):
- url = pyfile.url
- if 's2l.biz' in url:
- url = self.load(url, just_header=True)['location']
- self.baseUrl = re.search(self.__pattern__, url).group(1)
- self.fileId = re.match(self.__pattern__, url).group('id')
- self.package = pyfile.package()
-
- def isOnline(self):
- if "No usable content was found" in self.html:
- self.logDebug("File not found")
- return False
- return True
-
- def isPasswordProtected(self):
- if re.search(r'''<form.*?id="passwordForm".*?>''', self.html):
- self.logDebug("Links are protected")
- return True
- return False
-
- def isCaptchaProtected(self):
- if '<map id="captchamap"' in self.html:
- self.logDebug("Links are captcha protected")
- return True
- return False
-
- def unblockServer(self):
- imgs = re.findall("(/template/images/.*?\.gif)", self.html)
- for img in imgs:
- self.load(self.baseUrl + img)
-
- def unlockPasswordProtection(self):
- password = self.getPassword()
- self.logDebug("Submitting password [%s] for protected links" % password)
- post = {"password": password, 'login': 'Submit form'}
- url = self.baseUrl + '/' + self.fileId
- self.html = self.load(url, post=post, decode=True)
-
- def unlockCaptchaProtection(self):
- # Get captcha map
- captchaMap = self._getCaptchaMap()
- self.logDebug("Captcha map with [%d] positions" % len(captchaMap.keys()))
-
- # Request user for captcha coords
- m = re.search(r'<img src="/captcha.gif\?d=(.*?)&PHPSESSID=(.*?)&legend=1"', self.html)
- captchaUrl = self.baseUrl + '/captcha.gif?d=%s&PHPSESSID=%s' % (m.group(1), m.group(2))
- self.logDebug("Waiting user for correct position")
- coords = self.decryptCaptcha(captchaUrl, forceUser=True, imgtype="gif", result_type='positional')
- self.logDebug("Captcha resolved, coords [%s]" % str(coords))
-
- # Resolve captcha
- href = self._resolveCoords(coords, captchaMap)
- if href is None:
- self.logDebug("Invalid captcha resolving, retrying")
- self.invalidCaptcha()
- self.setWait(5, False)
- self.wait()
- self.retry()
- url = self.baseUrl + href
- self.html = self.load(url, decode=True)
-
- def _getCaptchaMap(self):
- map = {}
- for m in re.finditer(r'<area shape="rect" coords="(.*?)" href="(.*?)"', self.html):
- rect = eval('(' + m.group(1) + ')')
- href = m.group(2)
- map[rect] = href
- return map
-
- def _resolveCoords(self, coords, captchaMap):
- x, y = coords
- for rect, href in captchaMap.items():
- x1, y1, x2, y2 = rect
- if (x>=x1 and x<=x2) and (y>=y1 and y<=y2):
- return href
-
- def handleErrors(self):
- if "The inserted password was wrong" in self.html:
- self.logDebug("Incorrect password, please set right password on 'Edit package' form and retry")
- self.fail("Incorrect password, please set right password on 'Edit package' form and retry")
-
- if self.captcha:
- if "Your choice was wrong" in self.html:
- self.logDebug("Invalid captcha, retrying")
- self.invalidCaptcha()
- self.setWait(5)
- self.wait()
- self.retry()
- else:
- self.correctCaptcha()
-
- def getPackageInfo(self):
- name = folder = None
-
- # Extract from web package header
- title_re = r'<h2><img.*?/>(.*)</h2>'
- m = re.search(title_re, self.html, re.DOTALL)
- if m is not None:
- title = m.group(1).strip()
- if 'unnamed' not in title:
- name = folder = title
- self.logDebug("Found name [%s] and folder [%s] in package info" % (name, folder))
-
- # Fallback to defaults
- if not name or not folder:
- name = self.package.name
- folder = self.package.folder
- self.logDebug("Package info not found, defaulting to pyfile name [%s] and folder [%s]" % (name, folder))
-
- # Return package info
- return name, folder
-
- def handleWebLinks(self):
- package_links = []
- self.logDebug("Handling Web links")
-
- #@TODO: Gather paginated web links
- pattern = r"javascript:_get\('(.*?)', \d+, ''\)"
- ids = re.findall(pattern, self.html)
- self.logDebug("Decrypting %d Web links" % len(ids))
- for i, id in enumerate(ids):
- try:
- self.logDebug("Decrypting Web link %d, [%s]" % (i+1, id))
- dwLink = self.baseUrl + "/get/lnk/" + id
- response = self.load(dwLink)
- code = re.search(r'frm/(\d+)', response).group(1)
- fwLink = self.baseUrl + "/get/frm/" + code
- response = self.load(fwLink)
- jscode = re.search(r'<script language="javascript">\s*eval\((.*)\)\s*</script>', response, re.DOTALL).group(1)
- jscode = self.js.eval("f = %s" % jscode)
- jslauncher = "window=''; parent={frames:{Main:{location:{href:''}}},location:''}; %s; parent.frames.Main.location.href"
- dlLink = self.js.eval(jslauncher % jscode)
- self.logDebug("JsEngine returns value [%s] for redirection link" % dlLink)
- package_links.append(dlLink)
- except Exception, detail:
- self.logDebug("Error decrypting Web link [%s], %s" % (id, detail))
- return package_links
-
- def handleContainers(self):
- package_links = []
- self.logDebug("Handling Container links")
-
- pattern = r"javascript:_get\('(.*?)', 0, '(rsdf|ccf|dlc)'\)"
- containersLinks = re.findall(pattern, self.html)
- self.logDebug("Decrypting %d Container links" % len(containersLinks))
- for containerLink in containersLinks:
- link = "%s/get/%s/%s" % (self.baseUrl, containerLink[1], containerLink[0])
- package_links.append(link)
- return package_links
-
- def handleCNL2(self):
- package_links = []
- self.logDebug("Handling CNL2 links")
-
- if '/lib/cnl2/ClicknLoad.swf' in self.html:
- try:
- (crypted, jk) = self._getCipherParams()
- package_links.extend(self._getLinks(crypted, jk))
- except:
- self.fail("Unable to decrypt CNL2 links")
- return package_links
-
- def _getCipherParams(self):
-
- # Request CNL2
- code = re.search(r'ClicknLoad.swf\?code=(.*?)"', self.html).group(1)
- url = "%s/get/cnl2/%s" % (self.baseUrl, code)
- response = self.load(url)
- params = response.split(";;")
-
- # Get jk
- strlist = list(base64.standard_b64decode(params[1]))
- strlist.reverse()
- jk = ''.join(strlist)
-
- # Get crypted
- strlist = list(base64.standard_b64decode(params[2]))
- strlist.reverse()
- crypted = ''.join(strlist)
-
- # Log and return
- return crypted, jk
-
- def _getLinks(self, crypted, jk):
-
- # Get key
- jreturn = self.js.eval("%s f()" % jk)
- self.logDebug("JsEngine returns value [%s]" % jreturn)
- key = binascii.unhexlify(jreturn)
-
- # Decode crypted
- crypted = base64.standard_b64decode(crypted)
-
- # Decrypt
- Key = key
- IV = key
- obj = AES.new(Key, AES.MODE_CBC, IV)
- text = obj.decrypt(crypted)
-
- # Extract links
- text = text.replace("\x00", "").replace("\r", "")
- links = text.split("\n")
- links = filter(lambda x: x != "", links)
-
- # Log and return
- self.logDebug("Block has %d links" % len(links))
+# -*- coding: utf-8 -*- + +from Crypto.Cipher import AES +from module.plugins.Crypter import Crypter +from module.plugins.ReCaptcha import ReCaptcha +import base64 +import binascii +import re + + +class ShareLinksBiz(Crypter): + __name__ = "ShareLinksBiz" + __type__ = "crypter" + __pattern__ = r"(?P<base>http://[\w\.]*?(share-links|s2l)\.biz)/(?P<id>_?[0-9a-z]+)(/.*)?" + __version__ = "1.12" + __description__ = """Share-Links.biz Crypter""" + __author_name__ = ("fragonib") + __author_mail__ = ("fragonib[AT]yahoo[DOT]es") + + + def setup(self): + self.baseUrl = None + self.fileId = None + self.package = None + self.html = None + self.captcha = False + + def decrypt(self, pyfile): + + # Init + self.initFile(pyfile) + + # Request package + url = self.baseUrl + '/' + self.fileId + self.html = self.load(url, decode=True) + + # Unblock server (load all images) + self.unblockServer() + + # Check for protection + if self.isPasswordProtected(): + self.unlockPasswordProtection() + self.handleErrors() + + if self.isCaptchaProtected(): + self.captcha = True + self.unlockCaptchaProtection() + self.handleErrors() + + # Extract package links + package_links = [] + package_links.extend(self.handleWebLinks()) + package_links.extend(self.handleContainers()) + package_links.extend(self.handleCNL2()) + package_links = set(package_links) + + # Get package info + package_name, package_folder = self.getPackageInfo() + + # Pack + self.packages = [(package_name, package_links, package_folder)] + + def initFile(self, pyfile): + url = pyfile.url + if 's2l.biz' in url: + url = self.load(url, just_header=True)['location'] + self.baseUrl = re.search(self.__pattern__, url).group(1) + self.fileId = re.match(self.__pattern__, url).group('id') + self.package = pyfile.package() + + def isOnline(self): + if "No usable content was found" in self.html: + self.logDebug("File not found") + return False + return True + + def isPasswordProtected(self): + if re.search(r'''<form.*?id="passwordForm".*?>''', self.html): + self.logDebug("Links are protected") + return True + return False + + def isCaptchaProtected(self): + if '<map id="captchamap"' in self.html: + self.logDebug("Links are captcha protected") + return True + return False + + def unblockServer(self): + imgs = re.findall("(/template/images/.*?\.gif)", self.html) + for img in imgs: + self.load(self.baseUrl + img) + + def unlockPasswordProtection(self): + password = self.getPassword() + self.logDebug("Submitting password [%s] for protected links" % password) + post = {"password": password, 'login': 'Submit form'} + url = self.baseUrl + '/' + self.fileId + self.html = self.load(url, post=post, decode=True) + + def unlockCaptchaProtection(self): + # Get captcha map + captchaMap = self._getCaptchaMap() + self.logDebug("Captcha map with [%d] positions" % len(captchaMap.keys())) + + # Request user for captcha coords + m = re.search(r'<img src="/captcha.gif\?d=(.*?)&PHPSESSID=(.*?)&legend=1"', self.html) + captchaUrl = self.baseUrl + '/captcha.gif?d=%s&PHPSESSID=%s' % (m.group(1), m.group(2)) + self.logDebug("Waiting user for correct position") + coords = self.decryptCaptcha(captchaUrl, forceUser=True, imgtype="gif", result_type='positional') + self.logDebug("Captcha resolved, coords [%s]" % str(coords)) + + # Resolve captcha + href = self._resolveCoords(coords, captchaMap) + if href is None: + self.logDebug("Invalid captcha resolving, retrying") + self.invalidCaptcha() + self.setWait(5, False) + self.wait() + self.retry() + url = self.baseUrl + href + self.html = self.load(url, decode=True) + + def _getCaptchaMap(self): + map = {} + for m in re.finditer(r'<area shape="rect" coords="(.*?)" href="(.*?)"', self.html): + rect = eval('(' + m.group(1) + ')') + href = m.group(2) + map[rect] = href + return map + + def _resolveCoords(self, coords, captchaMap): + x, y = coords + for rect, href in captchaMap.items(): + x1, y1, x2, y2 = rect + if (x>=x1 and x<=x2) and (y>=y1 and y<=y2): + return href + + def handleErrors(self): + if "The inserted password was wrong" in self.html: + self.logDebug("Incorrect password, please set right password on 'Edit package' form and retry") + self.fail("Incorrect password, please set right password on 'Edit package' form and retry") + + if self.captcha: + if "Your choice was wrong" in self.html: + self.logDebug("Invalid captcha, retrying") + self.invalidCaptcha() + self.setWait(5) + self.wait() + self.retry() + else: + self.correctCaptcha() + + def getPackageInfo(self): + name = folder = None + + # Extract from web package header + title_re = r'<h2><img.*?/>(.*)</h2>' + m = re.search(title_re, self.html, re.DOTALL) + if m is not None: + title = m.group(1).strip() + if 'unnamed' not in title: + name = folder = title + self.logDebug("Found name [%s] and folder [%s] in package info" % (name, folder)) + + # Fallback to defaults + if not name or not folder: + name = self.package.name + folder = self.package.folder + self.logDebug("Package info not found, defaulting to pyfile name [%s] and folder [%s]" % (name, folder)) + + # Return package info + return name, folder + + def handleWebLinks(self): + package_links = [] + self.logDebug("Handling Web links") + + #@TODO: Gather paginated web links + pattern = r"javascript:_get\('(.*?)', \d+, ''\)" + ids = re.findall(pattern, self.html) + self.logDebug("Decrypting %d Web links" % len(ids)) + for i, id in enumerate(ids): + try: + self.logDebug("Decrypting Web link %d, [%s]" % (i+1, id)) + dwLink = self.baseUrl + "/get/lnk/" + id + response = self.load(dwLink) + code = re.search(r'frm/(\d+)', response).group(1) + fwLink = self.baseUrl + "/get/frm/" + code + response = self.load(fwLink) + jscode = re.search(r'<script language="javascript">\s*eval\((.*)\)\s*</script>', response, re.DOTALL).group(1) + jscode = self.js.eval("f = %s" % jscode) + jslauncher = "window=''; parent={frames:{Main:{location:{href:''}}},location:''}; %s; parent.frames.Main.location.href" + dlLink = self.js.eval(jslauncher % jscode) + self.logDebug("JsEngine returns value [%s] for redirection link" % dlLink) + package_links.append(dlLink) + except Exception, detail: + self.logDebug("Error decrypting Web link [%s], %s" % (id, detail)) + return package_links + + def handleContainers(self): + package_links = [] + self.logDebug("Handling Container links") + + pattern = r"javascript:_get\('(.*?)', 0, '(rsdf|ccf|dlc)'\)" + containersLinks = re.findall(pattern, self.html) + self.logDebug("Decrypting %d Container links" % len(containersLinks)) + for containerLink in containersLinks: + link = "%s/get/%s/%s" % (self.baseUrl, containerLink[1], containerLink[0]) + package_links.append(link) + return package_links + + def handleCNL2(self): + package_links = [] + self.logDebug("Handling CNL2 links") + + if '/lib/cnl2/ClicknLoad.swf' in self.html: + try: + (crypted, jk) = self._getCipherParams() + package_links.extend(self._getLinks(crypted, jk)) + except: + self.fail("Unable to decrypt CNL2 links") + return package_links + + def _getCipherParams(self): + + # Request CNL2 + code = re.search(r'ClicknLoad.swf\?code=(.*?)"', self.html).group(1) + url = "%s/get/cnl2/%s" % (self.baseUrl, code) + response = self.load(url) + params = response.split(";;") + + # Get jk + strlist = list(base64.standard_b64decode(params[1])) + strlist.reverse() + jk = ''.join(strlist) + + # Get crypted + strlist = list(base64.standard_b64decode(params[2])) + strlist.reverse() + crypted = ''.join(strlist) + + # Log and return + return crypted, jk + + def _getLinks(self, crypted, jk): + + # Get key + jreturn = self.js.eval("%s f()" % jk) + self.logDebug("JsEngine returns value [%s]" % jreturn) + key = binascii.unhexlify(jreturn) + + # Decode crypted + crypted = base64.standard_b64decode(crypted) + + # Decrypt + Key = key + IV = key + obj = AES.new(Key, AES.MODE_CBC, IV) + text = obj.decrypt(crypted) + + # Extract links + text = text.replace("\x00", "").replace("\r", "") + links = text.split("\n") + links = filter(lambda x: x != "", links) + + # Log and return + self.logDebug("Block has %d links" % len(links)) return links
\ No newline at end of file diff --git a/module/plugins/crypter/UploadedToFolder.py b/module/plugins/crypter/UploadedToFolder.py index c514f23d0..88d4e04e8 100644 --- a/module/plugins/crypter/UploadedToFolder.py +++ b/module/plugins/crypter/UploadedToFolder.py @@ -1,50 +1,50 @@ -# -*- coding: utf-8 -*-
-
-############################################################################
-# This program is free software: you can redistribute it and/or modify #
-# it under the terms of the GNU Affero 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 Affero General Public License for more details. #
-# #
-# You should have received a copy of the GNU Affero General Public License #
-# along with this program. If not, see <http://www.gnu.org/licenses/>. #
-############################################################################
-
-import re
-
-from module.plugins.internal.SimpleCrypter import SimpleCrypter
-
-
-class UploadedToFolder(SimpleCrypter):
- __name__ = "UploadedToFolder"
- __type__ = "crypter"
- __pattern__ = r"http://(?:www\.)?(uploaded|ul)\.(to|net)/(f|folder|list)/(?P<id>\w+)"
- __version__ = "0.3"
- __description__ = """UploadedTo Crypter Plugin"""
- __author_name__ = ("stickell")
- __author_mail__ = ("l.stickell@yahoo.it")
-
- PLAIN_PATTERN = r'<small class="date"><a href="(?P<plain>[\w/]+)" onclick='
- TITLE_PATTERN = r'<title>(?P<title>[^<]+)</title>'
-
- def decrypt(self, pyfile):
- self.html = self.load(pyfile.url)
-
- package_name, folder_name = self.getPackageNameAndFolder()
-
- m = re.search(self.PLAIN_PATTERN, self.html)
- if m:
- plain_link = 'http://uploaded.net/' + m.group('plain')
- else:
- self.fail('Parse error - Unable to find plain url list')
-
- self.html = self.load(plain_link)
- package_links = self.html.split('\n')[:-1]
- self.logDebug('Package has %d links' % len(package_links))
-
- self.packages = [(package_name, package_links, folder_name)]
+# -*- coding: utf-8 -*- + +############################################################################ +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU Affero 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 Affero General Public License for more details. # +# # +# You should have received a copy of the GNU Affero General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +############################################################################ + +import re + +from module.plugins.internal.SimpleCrypter import SimpleCrypter + + +class UploadedToFolder(SimpleCrypter): + __name__ = "UploadedToFolder" + __type__ = "crypter" + __pattern__ = r"http://(?:www\.)?(uploaded|ul)\.(to|net)/(f|folder|list)/(?P<id>\w+)" + __version__ = "0.3" + __description__ = """UploadedTo Crypter Plugin""" + __author_name__ = ("stickell") + __author_mail__ = ("l.stickell@yahoo.it") + + PLAIN_PATTERN = r'<small class="date"><a href="(?P<plain>[\w/]+)" onclick=' + TITLE_PATTERN = r'<title>(?P<title>[^<]+)</title>' + + def decrypt(self, pyfile): + self.html = self.load(pyfile.url) + + package_name, folder_name = self.getPackageNameAndFolder() + + m = re.search(self.PLAIN_PATTERN, self.html) + if m: + plain_link = 'http://uploaded.net/' + m.group('plain') + else: + self.fail('Parse error - Unable to find plain url list') + + self.html = self.load(plain_link) + package_links = self.html.split('\n')[:-1] + self.logDebug('Package has %d links' % len(package_links)) + + self.packages = [(package_name, package_links, folder_name)] diff --git a/module/plugins/crypter/WiiReloadedOrg.py b/module/plugins/crypter/WiiReloadedOrg.py index 574a147c4..ba101892d 100644 --- a/module/plugins/crypter/WiiReloadedOrg.py +++ b/module/plugins/crypter/WiiReloadedOrg.py @@ -1,52 +1,52 @@ -
-import re
-
-from module.plugins.Crypter import Crypter
-
-class WiiReloadedOrg(Crypter):
- __name__ = "WiiReloadedOrg"
- __type__ = "crypter"
- __pattern__ = r"http://www\.wii-reloaded\.org/protect/get\.php\?i=.+"
- __config__ = [("changeName", "bool", "Use Wii-Reloaded.org folder name", "True")]
- __version__ = "0.1"
- __description__ = """Wii-Reloaded.org Crypter Plugin"""
- __author_name__ = ("hzpz")
- __author_mail__ = ("none")
-
-
- def decrypt(self, pyfile):
- url = pyfile.url
- src = self.req.load(str(url))
-
- ids = re.findall(r"onClick=\"popup_dl\((.+)\)\"", src)
- if len(ids) == 0:
- self.fail("Unable to decrypt links, this plugin probably needs to be updated")
-
- packageName = self.pyfile.package().name
- if self.getConfig("changeName"):
- packageNameMatch = re.search(r"<div id=\"foldername\">(.+)</div>", src)
- if not packageNameMatch:
- self.logWarning("Unable to get folder name, this plugin probably needs to be updated")
- else:
- packageName = packageNameMatch.group(1)
-
- self.pyfile.package().password = "wii-reloaded.info"
-
- self.logDebug("Processing %d links" % len(ids))
- links = []
- for id in ids:
- self.req.lastURL = str(url)
- header = self.req.load("http://www.wii-reloaded.org/protect/hastesosiehtsaus.php?i=" + id, just_header=True)
- self.logDebug("Header:\n" + header)
- redirectLocationMatch = re.search(r"^Location: (.+)$", header, flags=re.MULTILINE)
- if not redirectLocationMatch:
- self.offline()
- redirectLocation = redirectLocationMatch.group(1)
- self.logDebug(len(redirectLocation))
- if not redirectLocation.startswith("http"):
- self.offline()
- self.logDebug("Decrypted link: %s" % redirectLocation)
- links.append(redirectLocation)
-
- self.logDebug("Decrypted %d links" % len(links))
+ +import re + +from module.plugins.Crypter import Crypter + +class WiiReloadedOrg(Crypter): + __name__ = "WiiReloadedOrg" + __type__ = "crypter" + __pattern__ = r"http://www\.wii-reloaded\.org/protect/get\.php\?i=.+" + __config__ = [("changeName", "bool", "Use Wii-Reloaded.org folder name", "True")] + __version__ = "0.1" + __description__ = """Wii-Reloaded.org Crypter Plugin""" + __author_name__ = ("hzpz") + __author_mail__ = ("none") + + + def decrypt(self, pyfile): + url = pyfile.url + src = self.req.load(str(url)) + + ids = re.findall(r"onClick=\"popup_dl\((.+)\)\"", src) + if len(ids) == 0: + self.fail("Unable to decrypt links, this plugin probably needs to be updated") + + packageName = self.pyfile.package().name + if self.getConfig("changeName"): + packageNameMatch = re.search(r"<div id=\"foldername\">(.+)</div>", src) + if not packageNameMatch: + self.logWarning("Unable to get folder name, this plugin probably needs to be updated") + else: + packageName = packageNameMatch.group(1) + + self.pyfile.package().password = "wii-reloaded.info" + + self.logDebug("Processing %d links" % len(ids)) + links = [] + for id in ids: + self.req.lastURL = str(url) + header = self.req.load("http://www.wii-reloaded.org/protect/hastesosiehtsaus.php?i=" + id, just_header=True) + self.logDebug("Header:\n" + header) + redirectLocationMatch = re.search(r"^Location: (.+)$", header, flags=re.MULTILINE) + if not redirectLocationMatch: + self.offline() + redirectLocation = redirectLocationMatch.group(1) + self.logDebug(len(redirectLocation)) + if not redirectLocation.startswith("http"): + self.offline() + self.logDebug("Decrypted link: %s" % redirectLocation) + links.append(redirectLocation) + + self.logDebug("Decrypted %d links" % len(links)) self.packages.append((packageName, links, packageName))
\ No newline at end of file diff --git a/module/plugins/hooks/Captcha9kw.py b/module/plugins/hooks/Captcha9kw.py index 3bc00d8c2..cd622b7cd 100755 --- a/module/plugins/hooks/Captcha9kw.py +++ b/module/plugins/hooks/Captcha9kw.py @@ -1,163 +1,163 @@ -# -*- 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: mkaay, RaNaN, zoidberg
-"""
-from __future__ import with_statement
-
-from thread import start_new_thread
-from base64 import b64encode
-import cStringIO
-import pycurl
-import time
-
-from module.network.RequestFactory import getURL, getRequest
-from module.network.HTTPRequest import BadHeader
-
-from module.plugins.Hook import Hook
-
-class Captcha9kw(Hook):
- __name__ = "Captcha9kw"
- __version__ = "0.07"
- __description__ = """send captchas to 9kw.eu"""
- __config__ = [("activated", "bool", "Activated", False),
- ("force", "bool", "Force CT even if client is connected", True),
- ("https", "bool", "Enable HTTPS", "False"),
- ("confirm", "bool", "Confirm Captcha (Cost +6)", "False"),
- ("captchaperhour", "int", "Captcha per hour (max. 9999)", "9999"),
- ("prio", "int", "Prio 1-10 (Cost +1-10)", "0"),
- ("timeout", "int", "Timeout (max. 300)", "220"),
- ("passkey", "password", "API key", ""),]
- __author_name__ = ("RaNaN")
- __author_mail__ = ("RaNaN@pyload.org")
-
- API_URL = "://www.9kw.eu/index.cgi"
-
- def setup(self):
- self.API_URL = "https"+self.API_URL if self.getConfig("https") else "http"+self.API_URL
- self.info = {}
-
- def getCredits(self):
- response = getURL(self.API_URL, get = { "apikey": self.getConfig("passkey"), "pyload": "1", "source": "pyload", "action": "usercaptchaguthaben" })
-
- if response.isdigit():
- self.logInfo(_("%s credits left") % response)
- self.info["credits"] = credits = int(response)
- return credits
- else:
- self.logError(response)
- return 0
-
- def processCaptcha(self, task):
- result = None
-
- with open(task.captchaFile, 'rb') as f:
- data = f.read()
- data = b64encode(data)
- self.logDebug("%s : %s" % (task.captchaFile, data))
- if task.isPositional():
- mouse = 1
- else:
- mouse = 0
-
- response = getURL(self.API_URL, post = {
- "apikey": self.getConfig("passkey"),
- "prio": self.getConfig("prio"),
- "confirm": self.getConfig("confirm"),
- "captchaperhour": self.getConfig("captchaperhour"),
- "maxtimeout": self.getConfig("timeout"),
- "pyload": "1",
- "source": "pyload",
- "base64": "1",
- "mouse": mouse,
- "file-upload-01": data,
- "action": "usercaptchaupload" })
-
- if response.isdigit():
- self.logInfo(_("New CaptchaID from upload: %s : %s") % (response,task.captchaFile))
-
- for i in range(1, 100, 1):
- response2 = getURL(self.API_URL, get = { "apikey": self.getConfig("passkey"), "id": response,"pyload": "1","source": "pyload", "action": "usercaptchacorrectdata" })
-
- if(response2 != ""):
- break;
-
- time.sleep(3)
-
- result = response2
- task.data["ticket"] = response
- self.logInfo("result %s : %s" % (response, result))
- task.setResult(result)
- else:
- self.logError("Bad upload: %s" % response)
- return False
-
- def newCaptchaTask(self, task):
- if not task.isTextual() and not task.isPositional():
- return False
-
- if not self.getConfig("passkey"):
- return False
-
- if self.core.isClientConnected() and not self.getConfig("force"):
- return False
-
- if self.getCredits() > 0:
- task.handler.append(self)
- task.setWaiting(self.getConfig("timeout"))
- start_new_thread(self.processCaptcha, (task,))
-
- else:
- self.logError(_("Your Captcha 9kw.eu Account has not enough credits"))
-
- def captchaCorrect(self, task):
- if "ticket" in task.data:
-
- try:
- response = getURL(self.API_URL,
- post={ "action": "usercaptchacorrectback",
- "apikey": self.getConfig("passkey"),
- "api_key": self.getConfig("passkey"),
- "correct": "1",
- "pyload": "1",
- "source": "pyload",
- "id": task.data["ticket"] }
- )
- self.logInfo("Request correct: %s" % response)
-
- except BadHeader, e:
- self.logError("Could not send correct request.", str(e))
- else:
- self.logError("No CaptchaID for correct request (task %s) found." % task)
-
- def captchaInvalid(self, task):
- if "ticket" in task.data:
-
- try:
- response = getURL(self.API_URL,
- post={ "action": "usercaptchacorrectback",
- "apikey": self.getConfig("passkey"),
- "api_key": self.getConfig("passkey"),
- "correct": "2",
- "pyload": "1",
- "source": "pyload",
- "id": task.data["ticket"] }
- )
- self.logInfo("Request refund: %s" % response)
-
- except BadHeader, e:
- self.logError("Could not send refund request.", str(e))
- else:
- self.logError("No CaptchaID for not correct request (task %s) found." % task)
+# -*- 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: mkaay, RaNaN, zoidberg +""" +from __future__ import with_statement + +from thread import start_new_thread +from base64 import b64encode +import cStringIO +import pycurl +import time + +from module.network.RequestFactory import getURL, getRequest +from module.network.HTTPRequest import BadHeader + +from module.plugins.Hook import Hook + +class Captcha9kw(Hook): + __name__ = "Captcha9kw" + __version__ = "0.07" + __description__ = """send captchas to 9kw.eu""" + __config__ = [("activated", "bool", "Activated", False), + ("force", "bool", "Force CT even if client is connected", True), + ("https", "bool", "Enable HTTPS", "False"), + ("confirm", "bool", "Confirm Captcha (Cost +6)", "False"), + ("captchaperhour", "int", "Captcha per hour (max. 9999)", "9999"), + ("prio", "int", "Prio 1-10 (Cost +1-10)", "0"), + ("timeout", "int", "Timeout (max. 300)", "220"), + ("passkey", "password", "API key", ""),] + __author_name__ = ("RaNaN") + __author_mail__ = ("RaNaN@pyload.org") + + API_URL = "://www.9kw.eu/index.cgi" + + def setup(self): + self.API_URL = "https"+self.API_URL if self.getConfig("https") else "http"+self.API_URL + self.info = {} + + def getCredits(self): + response = getURL(self.API_URL, get = { "apikey": self.getConfig("passkey"), "pyload": "1", "source": "pyload", "action": "usercaptchaguthaben" }) + + if response.isdigit(): + self.logInfo(_("%s credits left") % response) + self.info["credits"] = credits = int(response) + return credits + else: + self.logError(response) + return 0 + + def processCaptcha(self, task): + result = None + + with open(task.captchaFile, 'rb') as f: + data = f.read() + data = b64encode(data) + self.logDebug("%s : %s" % (task.captchaFile, data)) + if task.isPositional(): + mouse = 1 + else: + mouse = 0 + + response = getURL(self.API_URL, post = { + "apikey": self.getConfig("passkey"), + "prio": self.getConfig("prio"), + "confirm": self.getConfig("confirm"), + "captchaperhour": self.getConfig("captchaperhour"), + "maxtimeout": self.getConfig("timeout"), + "pyload": "1", + "source": "pyload", + "base64": "1", + "mouse": mouse, + "file-upload-01": data, + "action": "usercaptchaupload" }) + + if response.isdigit(): + self.logInfo(_("New CaptchaID from upload: %s : %s") % (response,task.captchaFile)) + + for i in range(1, 100, 1): + response2 = getURL(self.API_URL, get = { "apikey": self.getConfig("passkey"), "id": response,"pyload": "1","source": "pyload", "action": "usercaptchacorrectdata" }) + + if(response2 != ""): + break; + + time.sleep(3) + + result = response2 + task.data["ticket"] = response + self.logInfo("result %s : %s" % (response, result)) + task.setResult(result) + else: + self.logError("Bad upload: %s" % response) + return False + + def newCaptchaTask(self, task): + if not task.isTextual() and not task.isPositional(): + return False + + if not self.getConfig("passkey"): + return False + + if self.core.isClientConnected() and not self.getConfig("force"): + return False + + if self.getCredits() > 0: + task.handler.append(self) + task.setWaiting(self.getConfig("timeout")) + start_new_thread(self.processCaptcha, (task,)) + + else: + self.logError(_("Your Captcha 9kw.eu Account has not enough credits")) + + def captchaCorrect(self, task): + if "ticket" in task.data: + + try: + response = getURL(self.API_URL, + post={ "action": "usercaptchacorrectback", + "apikey": self.getConfig("passkey"), + "api_key": self.getConfig("passkey"), + "correct": "1", + "pyload": "1", + "source": "pyload", + "id": task.data["ticket"] } + ) + self.logInfo("Request correct: %s" % response) + + except BadHeader, e: + self.logError("Could not send correct request.", str(e)) + else: + self.logError("No CaptchaID for correct request (task %s) found." % task) + + def captchaInvalid(self, task): + if "ticket" in task.data: + + try: + response = getURL(self.API_URL, + post={ "action": "usercaptchacorrectback", + "apikey": self.getConfig("passkey"), + "api_key": self.getConfig("passkey"), + "correct": "2", + "pyload": "1", + "source": "pyload", + "id": task.data["ticket"] } + ) + self.logInfo("Request refund: %s" % response) + + except BadHeader, e: + self.logError("Could not send refund request.", str(e)) + else: + self.logError("No CaptchaID for not correct request (task %s) found." % task) diff --git a/module/plugins/hooks/Premium4Me.py b/module/plugins/hooks/Premium4Me.py index 16b02ce87..edbdfbdb9 100644 --- a/module/plugins/hooks/Premium4Me.py +++ b/module/plugins/hooks/Premium4Me.py @@ -1,33 +1,33 @@ -# -*- coding: utf-8 -*-
-
-from module.network.RequestFactory import getURL
-from module.plugins.internal.MultiHoster import MultiHoster
-
-class Premium4Me(MultiHoster):
- __name__ = "Premium4Me"
- __version__ = "0.03"
- __type__ = "hook"
-
- __config__ = [("activated", "bool", "Activated", "False"),
- ("hosterListMode", "all;listed;unlisted", "Use for downloads from supported hosters:", "all"),
- ("hosterList", "str", "Hoster list (comma separated)", "")]
- __description__ = """Premium.to hook plugin"""
- __author_name__ = ("RaNaN", "zoidberg", "stickell")
- __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz", "l.stickell@yahoo.it")
-
- def getHoster(self):
-
- page = getURL("http://premium.to/api/hosters.php?authcode=%s" % self.account.authcode)
- return [x.strip() for x in page.replace("\"", "").split(";")]
-
- def coreReady(self):
-
- self.account = self.core.accountManager.getAccountPlugin("Premium4Me")
-
- user = self.account.selectAccount()[0]
-
- if not user:
- self.logError(_("Please add your premium.to account first and restart pyLoad"))
- return
-
+# -*- coding: utf-8 -*- + +from module.network.RequestFactory import getURL +from module.plugins.internal.MultiHoster import MultiHoster + +class Premium4Me(MultiHoster): + __name__ = "Premium4Me" + __version__ = "0.03" + __type__ = "hook" + + __config__ = [("activated", "bool", "Activated", "False"), + ("hosterListMode", "all;listed;unlisted", "Use for downloads from supported hosters:", "all"), + ("hosterList", "str", "Hoster list (comma separated)", "")] + __description__ = """Premium.to hook plugin""" + __author_name__ = ("RaNaN", "zoidberg", "stickell") + __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz", "l.stickell@yahoo.it") + + def getHoster(self): + + page = getURL("http://premium.to/api/hosters.php?authcode=%s" % self.account.authcode) + return [x.strip() for x in page.replace("\"", "").split(";")] + + def coreReady(self): + + self.account = self.core.accountManager.getAccountPlugin("Premium4Me") + + user = self.account.selectAccount()[0] + + if not user: + self.logError(_("Please add your premium.to account first and restart pyLoad")) + return + return MultiHoster.coreReady(self)
\ No newline at end of file diff --git a/module/plugins/hoster/AlldebridCom.py b/module/plugins/hoster/AlldebridCom.py index 08a1d1cf9..cdb5ccc08 100644 --- a/module/plugins/hoster/AlldebridCom.py +++ b/module/plugins/hoster/AlldebridCom.py @@ -1,84 +1,84 @@ -# -*- coding: utf-8 -*-
-
-import re
-from urllib import unquote
-from random import randrange
-from module.plugins.Hoster import Hoster
-from module.common.json_layer import json_loads
-from module.utils import parseFileSize
-
-
-class AlldebridCom(Hoster):
- __name__ = "AlldebridCom"
- __version__ = "0.33"
- __type__ = "hoster"
-
- __pattern__ = r"https?://.*alldebrid\..*"
- __description__ = """Alldebrid.com hoster plugin"""
- __author_name__ = ("Andy, Voigt")
- __author_mail__ = ("spamsales@online.de")
-
- def getFilename(self, url):
- try:
- name = unquote(url.rsplit("/", 1)[1])
- except IndexError:
- name = "Unknown_Filename..."
- if name.endswith("..."): #incomplete filename, append random stuff
- name += "%s.tmp" % randrange(100, 999)
- return name
-
- def init(self):
- self.tries = 0
- self.chunkLimit = 3
- self.resumeDownload = True
-
- def process(self, pyfile):
- if not self.account:
- self.logError(_("Please enter your %s account or deactivate this plugin") % "AllDebrid")
- self.fail("No AllDebrid account provided")
-
- self.logDebug("AllDebrid: Old URL: %s" % pyfile.url)
- if re.match(self.__pattern__, pyfile.url):
- new_url = pyfile.url
- else:
- password = self.getPassword().splitlines()
- password = "" if not password else password[0]
-
- url = "http://www.alldebrid.com/service.php?link=%s&json=true&pw=%s" % (pyfile.url, password)
- page = self.load(url)
- data = json_loads(page)
-
- self.logDebug("Json data: %s" % str(data))
-
- if data["error"]:
- if data["error"] == "This link isn't available on the hoster website.":
- self.offline()
- else:
- self.logWarning(data["error"])
- self.tempOffline()
- else:
- if self.pyfile.name and not self.pyfile.name.endswith('.tmp'):
- self.pyfile.name = data["filename"]
- self.pyfile.size = parseFileSize(data["filesize"])
- new_url = data["link"]
-
- if self.getConfig("https"):
- new_url = new_url.replace("http://", "https://")
- else:
- new_url = new_url.replace("https://", "http://")
-
- self.logDebug("AllDebrid: New URL: %s" % new_url)
-
- if pyfile.name.startswith("http") or pyfile.name.startswith("Unknown"):
- #only use when name wasnt already set
- pyfile.name = self.getFilename(new_url)
-
- self.download(new_url, disposition=True)
-
- check = self.checkDownload({"error": "<title>An error occured while processing your request</title>",
- "empty": re.compile(r"^$")})
-
- if check == "error":
- self.retry(reason="An error occured while generating link.", wait_time=60)
- elif check == "empty":
- self.retry(reason="Downloaded File was empty.", wait_time=60)
+# -*- coding: utf-8 -*- + +import re +from urllib import unquote +from random import randrange +from module.plugins.Hoster import Hoster +from module.common.json_layer import json_loads +from module.utils import parseFileSize + + +class AlldebridCom(Hoster): + __name__ = "AlldebridCom" + __version__ = "0.33" + __type__ = "hoster" + + __pattern__ = r"https?://.*alldebrid\..*" + __description__ = """Alldebrid.com hoster plugin""" + __author_name__ = ("Andy, Voigt") + __author_mail__ = ("spamsales@online.de") + + def getFilename(self, url): + try: + name = unquote(url.rsplit("/", 1)[1]) + except IndexError: + name = "Unknown_Filename..." + if name.endswith("..."): #incomplete filename, append random stuff + name += "%s.tmp" % randrange(100, 999) + return name + + def init(self): + self.tries = 0 + self.chunkLimit = 3 + self.resumeDownload = True + + def process(self, pyfile): + if not self.account: + self.logError(_("Please enter your %s account or deactivate this plugin") % "AllDebrid") + self.fail("No AllDebrid account provided") + + self.logDebug("AllDebrid: Old URL: %s" % pyfile.url) + if re.match(self.__pattern__, pyfile.url): + new_url = pyfile.url + else: + password = self.getPassword().splitlines() + password = "" if not password else password[0] + + url = "http://www.alldebrid.com/service.php?link=%s&json=true&pw=%s" % (pyfile.url, password) + page = self.load(url) + data = json_loads(page) + + self.logDebug("Json data: %s" % str(data)) + + if data["error"]: + if data["error"] == "This link isn't available on the hoster website.": + self.offline() + else: + self.logWarning(data["error"]) + self.tempOffline() + else: + if self.pyfile.name and not self.pyfile.name.endswith('.tmp'): + self.pyfile.name = data["filename"] + self.pyfile.size = parseFileSize(data["filesize"]) + new_url = data["link"] + + if self.getConfig("https"): + new_url = new_url.replace("http://", "https://") + else: + new_url = new_url.replace("https://", "http://") + + self.logDebug("AllDebrid: New URL: %s" % new_url) + + if pyfile.name.startswith("http") or pyfile.name.startswith("Unknown"): + #only use when name wasnt already set + pyfile.name = self.getFilename(new_url) + + self.download(new_url, disposition=True) + + check = self.checkDownload({"error": "<title>An error occured while processing your request</title>", + "empty": re.compile(r"^$")}) + + if check == "error": + self.retry(reason="An error occured while generating link.", wait_time=60) + elif check == "empty": + self.retry(reason="Downloaded File was empty.", wait_time=60) diff --git a/module/plugins/hoster/EgoFilesCom.py b/module/plugins/hoster/EgoFilesCom.py index e203e2a1b..274286cf1 100644 --- a/module/plugins/hoster/EgoFilesCom.py +++ b/module/plugins/hoster/EgoFilesCom.py @@ -1,103 +1,103 @@ -# -*- coding: utf-8 -*-
-
-############################################################################
-# This program is free software: you can redistribute it and/or modify #
-# it under the terms of the GNU Affero 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 Affero General Public License for more details. #
-# #
-# You should have received a copy of the GNU Affero General Public License #
-# along with this program. If not, see <http://www.gnu.org/licenses/>. #
-############################################################################
-
-# Test link (random.bin):
-# http://egofiles.com/mOZfMI1WLZ6HBkGG/random.bin
-
-import re
-
-from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
-from module.plugins.internal.CaptchaService import ReCaptcha
-
-
-class EgoFilesCom(SimpleHoster):
- __name__ = "EgoFilesCom"
- __type__ = "hoster"
- __pattern__ = r"https?://(www\.)?egofiles.com/(\w+)"
- __version__ = "0.13"
- __description__ = """Egofiles.com Download Hoster"""
- __author_name__ = ("stickell")
- __author_mail__ = ("l.stickell@yahoo.it")
-
- FILE_INFO_PATTERN = r'<div class="down-file">\s+(?P<N>[^\t]+)\s+<div class="file-properties">\s+(File size|Rozmiar): (?P<S>[\w.]+) (?P<U>\w+) \|'
- FILE_OFFLINE_PATTERN = r'(File size|Rozmiar): 0 KB'
- WAIT_TIME_PATTERN = r'For next free download you have to wait <strong>((?P<m>\d*)m)? ?((?P<s>\d+)s)?</strong>'
- DIRECT_LINK_PATTERN = r'<a href="(?P<link>[^"]+)">Download ></a>'
- RECAPTCHA_KEY = '6LeXatQSAAAAAHezcjXyWAni-4t302TeYe7_gfvX'
-
- def init(self):
- self.file_info = {}
- # Set English language
- self.load("https://egofiles.com/ajax/lang.php?lang=en", just_header=True)
-
- def process(self, pyfile):
- if self.premium and (not self.SH_CHECK_TRAFFIC or self.checkTrafficLeft()):
- self.handlePremium()
- else:
- self.handleFree()
-
- def handleFree(self):
- self.html = self.load(self.pyfile.url, decode=True)
- self.getFileInfo()
-
- # Wait time between free downloads
- if 'For next free download you have to wait' in self.html:
- m = re.search(self.WAIT_TIME_PATTERN, self.html).groupdict('0')
- waittime = int(m['m']) * 60 + int(m['s'])
- self.setWait(waittime, True)
- self.wait()
-
- downloadURL = ''
- recaptcha = ReCaptcha(self)
- for i in xrange(5):
- challenge, response = recaptcha.challenge(self.RECAPTCHA_KEY)
- post_data = {'recaptcha_challenge_field': challenge,
- 'recaptcha_response_field': response}
- self.html = self.load(self.pyfile.url, post=post_data, decode=True)
- m = re.search(self.DIRECT_LINK_PATTERN, self.html)
- if not m:
- self.logInfo('Wrong captcha')
- self.invalidCaptcha()
- elif hasattr(m, 'group'):
- downloadURL = m.group('link')
- self.correctCaptcha()
- break
- else:
- self.fail('Unknown error - Plugin may be out of date')
-
- if not downloadURL:
- self.fail("No Download url retrieved/all captcha attempts failed")
-
- self.download(downloadURL, disposition=True)
-
- def handlePremium(self):
- header = self.load(self.pyfile.url, just_header=True)
- if header.has_key('location'):
- self.logDebug('DIRECT LINK from header: ' + header['location'])
- self.download(header['location'])
- else:
- self.html = self.load(self.pyfile.url, decode=True)
- self.getFileInfo()
- m = re.search(r'<a href="(?P<link>[^"]+)">Download ></a>', self.html)
- if not m:
- self.parseError('Unable to detect direct download url')
- else:
- self.logDebug('DIRECT URL from html: ' + m.group('link'))
- self.download(m.group('link'), disposition=True)
-
-
-getInfo = create_getInfo(EgoFilesCom)
+# -*- coding: utf-8 -*- + +############################################################################ +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU Affero 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 Affero General Public License for more details. # +# # +# You should have received a copy of the GNU Affero General Public License # +# along with this program. If not, see <http://www.gnu.org/licenses/>. # +############################################################################ + +# Test link (random.bin): +# http://egofiles.com/mOZfMI1WLZ6HBkGG/random.bin + +import re + +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo +from module.plugins.internal.CaptchaService import ReCaptcha + + +class EgoFilesCom(SimpleHoster): + __name__ = "EgoFilesCom" + __type__ = "hoster" + __pattern__ = r"https?://(www\.)?egofiles.com/(\w+)" + __version__ = "0.13" + __description__ = """Egofiles.com Download Hoster""" + __author_name__ = ("stickell") + __author_mail__ = ("l.stickell@yahoo.it") + + FILE_INFO_PATTERN = r'<div class="down-file">\s+(?P<N>[^\t]+)\s+<div class="file-properties">\s+(File size|Rozmiar): (?P<S>[\w.]+) (?P<U>\w+) \|' + FILE_OFFLINE_PATTERN = r'(File size|Rozmiar): 0 KB' + WAIT_TIME_PATTERN = r'For next free download you have to wait <strong>((?P<m>\d*)m)? ?((?P<s>\d+)s)?</strong>' + DIRECT_LINK_PATTERN = r'<a href="(?P<link>[^"]+)">Download ></a>' + RECAPTCHA_KEY = '6LeXatQSAAAAAHezcjXyWAni-4t302TeYe7_gfvX' + + def init(self): + self.file_info = {} + # Set English language + self.load("https://egofiles.com/ajax/lang.php?lang=en", just_header=True) + + def process(self, pyfile): + if self.premium and (not self.SH_CHECK_TRAFFIC or self.checkTrafficLeft()): + self.handlePremium() + else: + self.handleFree() + + def handleFree(self): + self.html = self.load(self.pyfile.url, decode=True) + self.getFileInfo() + + # Wait time between free downloads + if 'For next free download you have to wait' in self.html: + m = re.search(self.WAIT_TIME_PATTERN, self.html).groupdict('0') + waittime = int(m['m']) * 60 + int(m['s']) + self.setWait(waittime, True) + self.wait() + + downloadURL = '' + recaptcha = ReCaptcha(self) + for i in xrange(5): + challenge, response = recaptcha.challenge(self.RECAPTCHA_KEY) + post_data = {'recaptcha_challenge_field': challenge, + 'recaptcha_response_field': response} + self.html = self.load(self.pyfile.url, post=post_data, decode=True) + m = re.search(self.DIRECT_LINK_PATTERN, self.html) + if not m: + self.logInfo('Wrong captcha') + self.invalidCaptcha() + elif hasattr(m, 'group'): + downloadURL = m.group('link') + self.correctCaptcha() + break + else: + self.fail('Unknown error - Plugin may be out of date') + + if not downloadURL: + self.fail("No Download url retrieved/all captcha attempts failed") + + self.download(downloadURL, disposition=True) + + def handlePremium(self): + header = self.load(self.pyfile.url, just_header=True) + if header.has_key('location'): + self.logDebug('DIRECT LINK from header: ' + header['location']) + self.download(header['location']) + else: + self.html = self.load(self.pyfile.url, decode=True) + self.getFileInfo() + m = re.search(r'<a href="(?P<link>[^"]+)">Download ></a>', self.html) + if not m: + self.parseError('Unable to detect direct download url') + else: + self.logDebug('DIRECT URL from html: ' + m.group('link')) + self.download(m.group('link'), disposition=True) + + +getInfo = create_getInfo(EgoFilesCom) diff --git a/module/plugins/hoster/FreakshareCom.py b/module/plugins/hoster/FreakshareCom.py index e34edd165..156f697c3 100644 --- a/module/plugins/hoster/FreakshareCom.py +++ b/module/plugins/hoster/FreakshareCom.py @@ -1,167 +1,167 @@ -#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import re
-from module.plugins.Hoster import Hoster
-from module.plugins.internal.CaptchaService import ReCaptcha
-
-class FreakshareCom(Hoster):
- __name__ = "FreakshareCom"
- __type__ = "hoster"
- __pattern__ = r"http://(?:www\.)?freakshare\.(net|com)/files/\S*?/"
- __version__ = "0.37"
- __description__ = """Freakshare.com Download Hoster"""
- __author_name__ = ("sitacuisses","spoob","mkaay", "Toilal")
- __author_mail__ = ("sitacuisses@yahoo.de","spoob@pyload.org","mkaay@mkaay.de", "toilal.dev@gmail.com")
-
- def setup(self):
- self.html = None
- self.wantReconnect = False
- self.multiDL = False
- self.req_opts = []
-
- def process(self, pyfile):
- self.pyfile = pyfile
-
- pyfile.url = pyfile.url.replace("freakshare.net/","freakshare.com/")
-
- if self.account:
- self.html = self.load(pyfile.url, cookies=False)
- pyfile.name = self.get_file_name()
- self.download(pyfile.url)
-
- else:
- self.prepare()
- self.get_file_url()
-
- self.download(self.pyfile.url, post=self.req_opts)
-
-
- check = self.checkDownload({"bad": "bad try",
- "paralell": "> Sorry, you cant download more then 1 files at time. <",
- "empty": "Warning: Unknown: Filename cannot be empty",
- "wrong_captcha": "Wrong Captcha!"})
-
- if check == "bad":
- self.fail("Bad Try.")
- if check == "paralell":
- self.setWait(300, True)
- self.wait()
- self.retry()
- if check == "empty":
- self.fail("File not downloadable")
- if check == "wrong_captcha":
- self.invalidCaptcha()
- self.retry()
-
- def prepare(self):
- pyfile = self.pyfile
-
- self.wantReconnect = False
-
- self.download_html()
-
- if not self.file_exists():
- self.offline()
-
- self.setWait( self.get_waiting_time() )
-
- pyfile.name = self.get_file_name()
- pyfile.size = self.get_file_size()
-
- self.wait()
-
- return True
-
- def download_html(self):
- self.load("http://freakshare.com/index.php", {"language": "EN"}); # Set english language in server session
- self.html = self.load(self.pyfile.url)
-
- def get_file_url(self):
- """ returns the absolute downloadable filepath
- """
- if self.html is None:
- self.download_html()
- if not self.wantReconnect:
- self.req_opts = self.get_download_options() # get the Post options for the Request
- #file_url = self.pyfile.url
- #return file_url
- else:
- self.offline()
-
- def get_file_name(self):
- if self.html is None:
- self.download_html()
- if not self.wantReconnect:
- file_name = re.search(r"<h1\sclass=\"box_heading\"\sstyle=\"text-align:center;\">([^ ]+)", self.html)
- if file_name is not None:
- file_name = file_name.group(1)
- else:
- file_name = self.pyfile.url
- return file_name
- else:
- return self.pyfile.url
-
- def get_file_size(self):
- size = 0
- if self.html is None:
- self.download_html()
- if not self.wantReconnect:
- file_size_check = re.search(r"<h1\sclass=\"box_heading\"\sstyle=\"text-align:center;\">[^ ]+ - ([^ ]+) (\w\w)yte", self.html)
- if file_size_check is not None:
- units = float(file_size_check.group(1).replace(",", ""))
- pow = {'KB': 1, 'MB': 2, 'GB': 3}[file_size_check.group(2)]
- size = int(units * 1024 ** pow)
-
- return size
-
- def get_waiting_time(self):
- if self.html is None:
- self.download_html()
-
- if "Your Traffic is used up for today" in self.html:
- self.wantReconnect = True
- return 24*3600
-
- timestring = re.search('\s*var\s(?:downloadWait|time)\s=\s(\d*)[.\d]*;', self.html)
- if timestring:
- return int(timestring.group(1)) + 1 #add 1 sec as tenths of seconds are cut off
- else:
- return 60
-
-
- def file_exists(self):
- """ returns True or False
- """
- if self.html is None:
- self.download_html()
- if re.search(r"This file does not exist!", self.html) is not None:
- return False
- else:
- return True
-
- def get_download_options(self):
- re_envelope = re.search(r".*?value=\"Free\sDownload\".*?\n*?(.*?<.*?>\n*)*?\n*\s*?</form>", self.html).group(0) #get the whole request
- to_sort = re.findall(r"<input\stype=\"hidden\"\svalue=\"(.*?)\"\sname=\"(.*?)\"\s\/>", re_envelope)
- request_options = dict((n, v) for (v, n) in to_sort)
-
- herewego = self.load(self.pyfile.url, None, request_options) # the actual download-Page
-
- # comment this in, when it doesnt work
- # with open("DUMP__FS_.HTML", "w") as fp:
- # fp.write(herewego)
-
- to_sort = re.findall(r"<input\stype=\".*?\"\svalue=\"(\S*?)\".*?name=\"(\S*?)\"\s.*?\/>", herewego)
- request_options = dict((n, v) for (v, n) in to_sort)
-
- # comment this in, when it doesnt work as well
- #print "\n\n%s\n\n" % ";".join(["%s=%s" % x for x in to_sort])
-
- challenge = re.search(r"http://api\.recaptcha\.net/challenge\?k=([0-9A-Za-z]+)", herewego)
-
- if challenge:
- re_captcha = ReCaptcha(self)
- request_options["recaptcha_challenge_field"], request_options["recaptcha_response_field"] \
- = re_captcha.challenge(challenge.group(1))
-
- return request_options
+#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import re +from module.plugins.Hoster import Hoster +from module.plugins.internal.CaptchaService import ReCaptcha + +class FreakshareCom(Hoster): + __name__ = "FreakshareCom" + __type__ = "hoster" + __pattern__ = r"http://(?:www\.)?freakshare\.(net|com)/files/\S*?/" + __version__ = "0.37" + __description__ = """Freakshare.com Download Hoster""" + __author_name__ = ("sitacuisses","spoob","mkaay", "Toilal") + __author_mail__ = ("sitacuisses@yahoo.de","spoob@pyload.org","mkaay@mkaay.de", "toilal.dev@gmail.com") + + def setup(self): + self.html = None + self.wantReconnect = False + self.multiDL = False + self.req_opts = [] + + def process(self, pyfile): + self.pyfile = pyfile + + pyfile.url = pyfile.url.replace("freakshare.net/","freakshare.com/") + + if self.account: + self.html = self.load(pyfile.url, cookies=False) + pyfile.name = self.get_file_name() + self.download(pyfile.url) + + else: + self.prepare() + self.get_file_url() + + self.download(self.pyfile.url, post=self.req_opts) + + + check = self.checkDownload({"bad": "bad try", + "paralell": "> Sorry, you cant download more then 1 files at time. <", + "empty": "Warning: Unknown: Filename cannot be empty", + "wrong_captcha": "Wrong Captcha!"}) + + if check == "bad": + self.fail("Bad Try.") + if check == "paralell": + self.setWait(300, True) + self.wait() + self.retry() + if check == "empty": + self.fail("File not downloadable") + if check == "wrong_captcha": + self.invalidCaptcha() + self.retry() + + def prepare(self): + pyfile = self.pyfile + + self.wantReconnect = False + + self.download_html() + + if not self.file_exists(): + self.offline() + + self.setWait( self.get_waiting_time() ) + + pyfile.name = self.get_file_name() + pyfile.size = self.get_file_size() + + self.wait() + + return True + + def download_html(self): + self.load("http://freakshare.com/index.php", {"language": "EN"}); # Set english language in server session + self.html = self.load(self.pyfile.url) + + def get_file_url(self): + """ returns the absolute downloadable filepath + """ + if self.html is None: + self.download_html() + if not self.wantReconnect: + self.req_opts = self.get_download_options() # get the Post options for the Request + #file_url = self.pyfile.url + #return file_url + else: + self.offline() + + def get_file_name(self): + if self.html is None: + self.download_html() + if not self.wantReconnect: + file_name = re.search(r"<h1\sclass=\"box_heading\"\sstyle=\"text-align:center;\">([^ ]+)", self.html) + if file_name is not None: + file_name = file_name.group(1) + else: + file_name = self.pyfile.url + return file_name + else: + return self.pyfile.url + + def get_file_size(self): + size = 0 + if self.html is None: + self.download_html() + if not self.wantReconnect: + file_size_check = re.search(r"<h1\sclass=\"box_heading\"\sstyle=\"text-align:center;\">[^ ]+ - ([^ ]+) (\w\w)yte", self.html) + if file_size_check is not None: + units = float(file_size_check.group(1).replace(",", "")) + pow = {'KB': 1, 'MB': 2, 'GB': 3}[file_size_check.group(2)] + size = int(units * 1024 ** pow) + + return size + + def get_waiting_time(self): + if self.html is None: + self.download_html() + + if "Your Traffic is used up for today" in self.html: + self.wantReconnect = True + return 24*3600 + + timestring = re.search('\s*var\s(?:downloadWait|time)\s=\s(\d*)[.\d]*;', self.html) + if timestring: + return int(timestring.group(1)) + 1 #add 1 sec as tenths of seconds are cut off + else: + return 60 + + + def file_exists(self): + """ returns True or False + """ + if self.html is None: + self.download_html() + if re.search(r"This file does not exist!", self.html) is not None: + return False + else: + return True + + def get_download_options(self): + re_envelope = re.search(r".*?value=\"Free\sDownload\".*?\n*?(.*?<.*?>\n*)*?\n*\s*?</form>", self.html).group(0) #get the whole request + to_sort = re.findall(r"<input\stype=\"hidden\"\svalue=\"(.*?)\"\sname=\"(.*?)\"\s\/>", re_envelope) + request_options = dict((n, v) for (v, n) in to_sort) + + herewego = self.load(self.pyfile.url, None, request_options) # the actual download-Page + + # comment this in, when it doesnt work + # with open("DUMP__FS_.HTML", "w") as fp: + # fp.write(herewego) + + to_sort = re.findall(r"<input\stype=\".*?\"\svalue=\"(\S*?)\".*?name=\"(\S*?)\"\s.*?\/>", herewego) + request_options = dict((n, v) for (v, n) in to_sort) + + # comment this in, when it doesnt work as well + #print "\n\n%s\n\n" % ";".join(["%s=%s" % x for x in to_sort]) + + challenge = re.search(r"http://api\.recaptcha\.net/challenge\?k=([0-9A-Za-z]+)", herewego) + + if challenge: + re_captcha = ReCaptcha(self) + request_options["recaptcha_challenge_field"], request_options["recaptcha_response_field"] \ + = re_captcha.challenge(challenge.group(1)) + + return request_options diff --git a/module/plugins/hoster/Ftp.py b/module/plugins/hoster/Ftp.py index 3bda3b32e..c68f3b237 100644 --- a/module/plugins/hoster/Ftp.py +++ b/module/plugins/hoster/Ftp.py @@ -1,91 +1,91 @@ -# -*- 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: jeix
- @author: mkaay
-"""
-from urlparse import urlparse, urljoin
-from urllib import quote, unquote
-import pycurl, re
-
-from module.plugins.Hoster import Hoster
-from module.network.HTTPRequest import BadHeader
-
-class Ftp(Hoster):
- __name__ = "Ftp"
- __version__ = "0.41"
- __pattern__ = r'(ftps?|sftp)://(.*?:.*?@)?.*?/.*' # ftp://user:password@ftp.server.org/path/to/file
- __type__ = "hoster"
- __description__ = """A Plugin that allows you to download from an from an ftp directory"""
- __author_name__ = ("jeix", "mkaay", "zoidberg")
- __author_mail__ = ("jeix@hasnomail.com", "mkaay@mkaay.de", "zoidberg@mujmail.cz")
-
- def setup(self):
- self.chunkLimit = -1
- self.resumeDownload = True
-
- def process(self, pyfile):
- parsed_url = urlparse(pyfile.url)
- netloc = parsed_url.netloc
-
- pyfile.name = parsed_url.path.rpartition('/')[2]
- try:
- pyfile.name = unquote(str(pyfile.name)).decode('utf8')
- except:
- pass
-
- if not "@" in netloc:
- servers = [ x['login'] for x in self.account.getAllAccounts() ] if self.account else []
-
- if netloc in servers:
- self.logDebug("Logging on to %s" % netloc)
- self.req.addAuth(self.account.accounts[netloc]["password"])
- else:
- for pwd in pyfile.package().password.splitlines():
- if ":" in pwd:
- self.req.addAuth(pwd.strip())
- break
-
- self.req.http.c.setopt(pycurl.NOBODY, 1)
-
- try:
- response = self.load(pyfile.url)
- except pycurl.error, e:
- self.fail("Error %d: %s" % e.args)
-
- self.req.http.c.setopt(pycurl.NOBODY, 0)
- self.logDebug(self.req.http.header)
-
- found = re.search(r"Content-Length:\s*(\d+)", response)
- if found:
- pyfile.size = int(found.group(1))
- self.download(pyfile.url)
- else:
- #Naive ftp directory listing
- if re.search(r'^25\d.*?"', self.req.http.header, re.M):
- pyfile.url = pyfile.url.rstrip('/')
- pkgname = "/".join((pyfile.package().name,urlparse(pyfile.url).path.rpartition('/')[2]))
- pyfile.url += '/'
- self.req.http.c.setopt(48, 1) # CURLOPT_DIRLISTONLY
- response = self.load(pyfile.url, decode = False)
- links = [ pyfile.url + quote(x) for x in response.splitlines() ]
- self.logDebug("LINKS", links)
- self.core.api.addPackage(pkgname, links, 1)
- #self.core.files.addLinks(links, pyfile.package().id)
- else:
- self.fail("Unexpected server response")
-
+# -*- 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: jeix + @author: mkaay +""" +from urlparse import urlparse, urljoin +from urllib import quote, unquote +import pycurl, re + +from module.plugins.Hoster import Hoster +from module.network.HTTPRequest import BadHeader + +class Ftp(Hoster): + __name__ = "Ftp" + __version__ = "0.41" + __pattern__ = r'(ftps?|sftp)://(.*?:.*?@)?.*?/.*' # ftp://user:password@ftp.server.org/path/to/file + __type__ = "hoster" + __description__ = """A Plugin that allows you to download from an from an ftp directory""" + __author_name__ = ("jeix", "mkaay", "zoidberg") + __author_mail__ = ("jeix@hasnomail.com", "mkaay@mkaay.de", "zoidberg@mujmail.cz") + + def setup(self): + self.chunkLimit = -1 + self.resumeDownload = True + + def process(self, pyfile): + parsed_url = urlparse(pyfile.url) + netloc = parsed_url.netloc + + pyfile.name = parsed_url.path.rpartition('/')[2] + try: + pyfile.name = unquote(str(pyfile.name)).decode('utf8') + except: + pass + + if not "@" in netloc: + servers = [ x['login'] for x in self.account.getAllAccounts() ] if self.account else [] + + if netloc in servers: + self.logDebug("Logging on to %s" % netloc) + self.req.addAuth(self.account.accounts[netloc]["password"]) + else: + for pwd in pyfile.package().password.splitlines(): + if ":" in pwd: + self.req.addAuth(pwd.strip()) + break + + self.req.http.c.setopt(pycurl.NOBODY, 1) + + try: + response = self.load(pyfile.url) + except pycurl.error, e: + self.fail("Error %d: %s" % e.args) + + self.req.http.c.setopt(pycurl.NOBODY, 0) + self.logDebug(self.req.http.header) + + found = re.search(r"Content-Length:\s*(\d+)", response) + if found: + pyfile.size = int(found.group(1)) + self.download(pyfile.url) + else: + #Naive ftp directory listing + if re.search(r'^25\d.*?"', self.req.http.header, re.M): + pyfile.url = pyfile.url.rstrip('/') + pkgname = "/".join((pyfile.package().name,urlparse(pyfile.url).path.rpartition('/')[2])) + pyfile.url += '/' + self.req.http.c.setopt(48, 1) # CURLOPT_DIRLISTONLY + response = self.load(pyfile.url, decode = False) + links = [ pyfile.url + quote(x) for x in response.splitlines() ] + self.logDebug("LINKS", links) + self.core.api.addPackage(pkgname, links, 1) + #self.core.files.addLinks(links, pyfile.package().id) + else: + self.fail("Unexpected server response") +
\ No newline at end of file diff --git a/module/plugins/hoster/LuckyShareNet.py b/module/plugins/hoster/LuckyShareNet.py index 5a4a583ff..08e44d9f6 100644 --- a/module/plugins/hoster/LuckyShareNet.py +++ b/module/plugins/hoster/LuckyShareNet.py @@ -1,72 +1,72 @@ -# -*- coding: utf-8 -*-
-
-import re
-from module.lib.bottle import json_loads
-
-from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo
-from module.plugins.internal.CaptchaService import ReCaptcha
-
-
-class LuckyShareNet(SimpleHoster):
- __name__ = "LuckyShareNet"
- __type__ = "hoster"
- __pattern__ = r"https?://(www\.)?luckyshare.net/(?P<ID>\d{10,})"
- __version__ = "0.02"
- __description__ = """LuckyShare.net Download Hoster"""
- __author_name__ = ("stickell")
- __author_mail__ = ("l.stickell@yahoo.it")
-
- FILE_INFO_PATTERN = r"<h1 class='file_name'>(?P<N>\S+)</h1>\s*<span class='file_size'>Filesize: (?P<S>[\d.]+)(?P<U>\w+)</span>"
- FILE_OFFLINE_PATTERN = 'There is no such file available'
- RECAPTCHA_KEY = '6LdivsgSAAAAANWh-d7rPE1mus4yVWuSQIJKIYNw'
-
- def parseJson(self, rep):
- if 'AJAX Error' in rep:
- html = self.load(self.pyfile.url, decode=True)
- m = re.search(r"waitingtime = (\d+);", html)
- if m:
- waittime = int(m.group(1))
- self.logDebug('You have to wait %d seconds between free downloads' % waittime)
- self.retry(wait_time=waittime)
- else:
- self.parseError('Unable to detect wait time between free downloads')
- elif 'Hash expired' in rep:
- self.retry(reason='Hash expired')
- return json_loads(rep)
-
- # TODO: There should be a filesize limit for free downloads
- # TODO: Some files could not be downloaded in free mode
- def handleFree(self):
- file_id = re.search(self.__pattern__, self.pyfile.url).group('ID')
- self.logDebug('File ID: ' + file_id)
- rep = self.load(r"http://luckyshare.net/download/request/type/time/file/" + file_id, decode=True)
- self.logDebug('JSON: ' + rep)
- json = self.parseJson(rep)
-
- self.setWait(int(json['time']))
- self.wait()
-
- recaptcha = ReCaptcha(self)
- for i in xrange(5):
- challenge, response = recaptcha.challenge(self.RECAPTCHA_KEY)
- rep = self.load(r"http://luckyshare.net/download/verify/challenge/%s/response/%s/hash/%s" %
- (challenge, response, json['hash']), decode=True)
- self.logDebug('JSON: ' + rep)
- if 'link' in rep:
- json.update(self.parseJson(rep))
- self.correctCaptcha()
- break
- elif 'Verification failed' in rep:
- self.logInfo('Wrong captcha')
- self.invalidCaptcha()
- else:
- self.parseError('Unable to get downlaod link')
-
- if not json['link']:
- self.fail("No Download url retrieved/all captcha attempts failed")
-
- self.logDebug('Direct URL: ' + json['link'])
- self.download(json['link'])
-
-
-getInfo = create_getInfo(LuckyShareNet)
+# -*- coding: utf-8 -*- + +import re +from module.lib.bottle import json_loads + +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo +from module.plugins.internal.CaptchaService import ReCaptcha + + +class LuckyShareNet(SimpleHoster): + __name__ = "LuckyShareNet" + __type__ = "hoster" + __pattern__ = r"https?://(www\.)?luckyshare.net/(?P<ID>\d{10,})" + __version__ = "0.02" + __description__ = """LuckyShare.net Download Hoster""" + __author_name__ = ("stickell") + __author_mail__ = ("l.stickell@yahoo.it") + + FILE_INFO_PATTERN = r"<h1 class='file_name'>(?P<N>\S+)</h1>\s*<span class='file_size'>Filesize: (?P<S>[\d.]+)(?P<U>\w+)</span>" + FILE_OFFLINE_PATTERN = 'There is no such file available' + RECAPTCHA_KEY = '6LdivsgSAAAAANWh-d7rPE1mus4yVWuSQIJKIYNw' + + def parseJson(self, rep): + if 'AJAX Error' in rep: + html = self.load(self.pyfile.url, decode=True) + m = re.search(r"waitingtime = (\d+);", html) + if m: + waittime = int(m.group(1)) + self.logDebug('You have to wait %d seconds between free downloads' % waittime) + self.retry(wait_time=waittime) + else: + self.parseError('Unable to detect wait time between free downloads') + elif 'Hash expired' in rep: + self.retry(reason='Hash expired') + return json_loads(rep) + + # TODO: There should be a filesize limit for free downloads + # TODO: Some files could not be downloaded in free mode + def handleFree(self): + file_id = re.search(self.__pattern__, self.pyfile.url).group('ID') + self.logDebug('File ID: ' + file_id) + rep = self.load(r"http://luckyshare.net/download/request/type/time/file/" + file_id, decode=True) + self.logDebug('JSON: ' + rep) + json = self.parseJson(rep) + + self.setWait(int(json['time'])) + self.wait() + + recaptcha = ReCaptcha(self) + for i in xrange(5): + challenge, response = recaptcha.challenge(self.RECAPTCHA_KEY) + rep = self.load(r"http://luckyshare.net/download/verify/challenge/%s/response/%s/hash/%s" % + (challenge, response, json['hash']), decode=True) + self.logDebug('JSON: ' + rep) + if 'link' in rep: + json.update(self.parseJson(rep)) + self.correctCaptcha() + break + elif 'Verification failed' in rep: + self.logInfo('Wrong captcha') + self.invalidCaptcha() + else: + self.parseError('Unable to get downlaod link') + + if not json['link']: + self.fail("No Download url retrieved/all captcha attempts failed") + + self.logDebug('Direct URL: ' + json['link']) + self.download(json['link']) + + +getInfo = create_getInfo(LuckyShareNet) diff --git a/module/plugins/hoster/PornhostCom.py b/module/plugins/hoster/PornhostCom.py index a4124c4a4..ef7961d81 100644 --- a/module/plugins/hoster/PornhostCom.py +++ b/module/plugins/hoster/PornhostCom.py @@ -1,76 +1,76 @@ -#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import re
-from module.plugins.Hoster import Hoster
-
-class PornhostCom(Hoster):
- __name__ = "PornhostCom"
- __type__ = "hoster"
- __pattern__ = r'http://[\w\.]*?pornhost\.com/([0-9]+/[0-9]+\.html|[0-9]+)'
- __version__ = "0.2"
- __description__ = """Pornhost.com Download Hoster"""
- __author_name__ = ("jeix")
- __author_mail__ = ("jeix@hasnomail.de")
-
- def process(self, pyfile):
- self.download_html()
- if not self.file_exists():
- self.offline()
-
- pyfile.name = self.get_file_name()
- self.download(self.get_file_url())
-
-
- ### old interface
- def download_html(self):
- url = self.pyfile.url
- self.html = self.load(url)
-
- def get_file_url(self):
- """ returns the absolute downloadable filepath
- """
- if self.html is None:
- self.download_html()
-
- file_url = re.search(r'download this file</label>.*?<a href="(.*?)"', self.html)
- if not file_url:
- file_url = re.search(r'"(http://dl[0-9]+\.pornhost\.com/files/.*?/.*?/.*?/.*?/.*?/.*?\..*?)"', self.html)
- if not file_url:
- file_url = re.search(r'width: 894px; height: 675px">.*?<img src="(.*?)"', self.html)
- if not file_url:
- file_url = re.search(r'"http://file[0-9]+\.pornhost\.com/[0-9]+/.*?"', self.html) # TODO: fix this one since it doesn't match
-
- file_url = file_url.group(1).strip()
-
- return file_url
-
- def get_file_name(self):
- if self.html is None:
- self.download_html()
-
- name = re.search(r'<title>pornhost\.com - free file hosting with a twist - gallery(.*?)</title>', self.html)
- if not name:
- name = re.search(r'id="url" value="http://www\.pornhost\.com/(.*?)/"', self.html)
- if not name:
- name = re.search(r'<title>pornhost\.com - free file hosting with a twist -(.*?)</title>', self.html)
- if not name:
- name = re.search(r'"http://file[0-9]+\.pornhost\.com/.*?/(.*?)"', self.html)
-
- name = name.group(1).strip() + ".flv"
-
- return name
-
- def file_exists(self):
- """ returns True or False
- """
- if self.html is None:
- self.download_html()
-
- if re.search(r'gallery not found', self.html) is not None \
- or re.search(r'You will be redirected to', self.html) is not None:
- return False
- else:
- return True
-
-
+#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import re +from module.plugins.Hoster import Hoster + +class PornhostCom(Hoster): + __name__ = "PornhostCom" + __type__ = "hoster" + __pattern__ = r'http://[\w\.]*?pornhost\.com/([0-9]+/[0-9]+\.html|[0-9]+)' + __version__ = "0.2" + __description__ = """Pornhost.com Download Hoster""" + __author_name__ = ("jeix") + __author_mail__ = ("jeix@hasnomail.de") + + def process(self, pyfile): + self.download_html() + if not self.file_exists(): + self.offline() + + pyfile.name = self.get_file_name() + self.download(self.get_file_url()) + + + ### old interface + def download_html(self): + url = self.pyfile.url + self.html = self.load(url) + + def get_file_url(self): + """ returns the absolute downloadable filepath + """ + if self.html is None: + self.download_html() + + file_url = re.search(r'download this file</label>.*?<a href="(.*?)"', self.html) + if not file_url: + file_url = re.search(r'"(http://dl[0-9]+\.pornhost\.com/files/.*?/.*?/.*?/.*?/.*?/.*?\..*?)"', self.html) + if not file_url: + file_url = re.search(r'width: 894px; height: 675px">.*?<img src="(.*?)"', self.html) + if not file_url: + file_url = re.search(r'"http://file[0-9]+\.pornhost\.com/[0-9]+/.*?"', self.html) # TODO: fix this one since it doesn't match + + file_url = file_url.group(1).strip() + + return file_url + + def get_file_name(self): + if self.html is None: + self.download_html() + + name = re.search(r'<title>pornhost\.com - free file hosting with a twist - gallery(.*?)</title>', self.html) + if not name: + name = re.search(r'id="url" value="http://www\.pornhost\.com/(.*?)/"', self.html) + if not name: + name = re.search(r'<title>pornhost\.com - free file hosting with a twist -(.*?)</title>', self.html) + if not name: + name = re.search(r'"http://file[0-9]+\.pornhost\.com/.*?/(.*?)"', self.html) + + name = name.group(1).strip() + ".flv" + + return name + + def file_exists(self): + """ returns True or False + """ + if self.html is None: + self.download_html() + + if re.search(r'gallery not found', self.html) is not None \ + or re.search(r'You will be redirected to', self.html) is not None: + return False + else: + return True + + diff --git a/module/plugins/hoster/PornhubCom.py b/module/plugins/hoster/PornhubCom.py index e1ed612b9..c431004d8 100644 --- a/module/plugins/hoster/PornhubCom.py +++ b/module/plugins/hoster/PornhubCom.py @@ -1,83 +1,83 @@ -#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import re
-from module.plugins.Hoster import Hoster
-
-class PornhubCom(Hoster):
- __name__ = "PornhubCom"
- __type__ = "hoster"
- __pattern__ = r'http://[\w\.]*?pornhub\.com/view_video\.php\?viewkey=[\w\d]+'
- __version__ = "0.5"
- __description__ = """Pornhub.com Download Hoster"""
- __author_name__ = ("jeix")
- __author_mail__ = ("jeix@hasnomail.de")
-
- def process(self, pyfile):
- self.download_html()
- if not self.file_exists():
- self.offline()
-
- pyfile.name = self.get_file_name()
- self.download(self.get_file_url())
-
- def download_html(self):
- url = self.pyfile.url
- self.html = self.load(url)
-
- def get_file_url(self):
- """ returns the absolute downloadable filepath
- """
- if self.html is None:
- self.download_html()
-
- url = "http://www.pornhub.com//gateway.php"
- video_id = self.pyfile.url.split('=')[-1]
- # thanks to jD team for this one v
- post_data = "\x00\x03\x00\x00\x00\x01\x00\x0c\x70\x6c\x61\x79\x65\x72\x43\x6f\x6e\x66\x69\x67\x00\x02\x2f\x31\x00\x00\x00\x44\x0a\x00\x00\x00\x03\x02\x00"
- post_data += chr(len(video_id))
- post_data += video_id
- post_data += "\x02\x00\x02\x2d\x31\x02\x00\x20"
- post_data += "add299463d4410c6d1b1c418868225f7"
-
- content = self.req.load(url, post=str(post_data))
-
- new_content = ""
- for x in content:
- if ord(x) < 32 or ord(x) > 176:
- new_content += '#'
- else:
- new_content += x
-
- content = new_content
-
- file_url = re.search(r'flv_url.*(http.*?)##post_roll', content).group(1)
-
- return file_url
-
- def get_file_name(self):
- if self.html is None:
- self.download_html()
-
- match = re.search(r'<title[^>]+>([^<]+) - ', self.html)
- if match:
- name = match.group(1)
- else:
- matches = re.findall('<h1>(.*?)</h1>', self.html)
- if len(matches) > 1:
- name = matches[1]
- else:
- name = matches[0]
-
- return name + '.flv'
-
- def file_exists(self):
- """ returns True or False
- """
- if self.html is None:
- self.download_html()
-
- if re.search(r'This video is no longer in our database or is in conversion', self.html) is not None:
- return False
- else:
- return True
+#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import re +from module.plugins.Hoster import Hoster + +class PornhubCom(Hoster): + __name__ = "PornhubCom" + __type__ = "hoster" + __pattern__ = r'http://[\w\.]*?pornhub\.com/view_video\.php\?viewkey=[\w\d]+' + __version__ = "0.5" + __description__ = """Pornhub.com Download Hoster""" + __author_name__ = ("jeix") + __author_mail__ = ("jeix@hasnomail.de") + + def process(self, pyfile): + self.download_html() + if not self.file_exists(): + self.offline() + + pyfile.name = self.get_file_name() + self.download(self.get_file_url()) + + def download_html(self): + url = self.pyfile.url + self.html = self.load(url) + + def get_file_url(self): + """ returns the absolute downloadable filepath + """ + if self.html is None: + self.download_html() + + url = "http://www.pornhub.com//gateway.php" + video_id = self.pyfile.url.split('=')[-1] + # thanks to jD team for this one v + post_data = "\x00\x03\x00\x00\x00\x01\x00\x0c\x70\x6c\x61\x79\x65\x72\x43\x6f\x6e\x66\x69\x67\x00\x02\x2f\x31\x00\x00\x00\x44\x0a\x00\x00\x00\x03\x02\x00" + post_data += chr(len(video_id)) + post_data += video_id + post_data += "\x02\x00\x02\x2d\x31\x02\x00\x20" + post_data += "add299463d4410c6d1b1c418868225f7" + + content = self.req.load(url, post=str(post_data)) + + new_content = "" + for x in content: + if ord(x) < 32 or ord(x) > 176: + new_content += '#' + else: + new_content += x + + content = new_content + + file_url = re.search(r'flv_url.*(http.*?)##post_roll', content).group(1) + + return file_url + + def get_file_name(self): + if self.html is None: + self.download_html() + + match = re.search(r'<title[^>]+>([^<]+) - ', self.html) + if match: + name = match.group(1) + else: + matches = re.findall('<h1>(.*?)</h1>', self.html) + if len(matches) > 1: + name = matches[1] + else: + name = matches[0] + + return name + '.flv' + + def file_exists(self): + """ returns True or False + """ + if self.html is None: + self.download_html() + + if re.search(r'This video is no longer in our database or is in conversion', self.html) is not None: + return False + else: + return True diff --git a/module/plugins/hoster/Premium4Me.py b/module/plugins/hoster/Premium4Me.py index 63b3baa83..9a359b9cb 100644 --- a/module/plugins/hoster/Premium4Me.py +++ b/module/plugins/hoster/Premium4Me.py @@ -1,70 +1,70 @@ -#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from urllib import quote
-from os.path import exists
-from os import remove
-
-from module.plugins.Hoster import Hoster
-from module.utils import fs_encode
-
-
-class Premium4Me(Hoster):
- __name__ = "Premium4Me"
- __version__ = "0.08"
- __type__ = "hoster"
-
- __pattern__ = r"http://premium.to/.*"
- __description__ = """Premium.to hoster plugin"""
- __author_name__ = ("RaNaN", "zoidberg", "stickell")
- __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz", "l.stickell@yahoo.it")
-
- def setup(self):
- self.resumeDownload = True
- self.chunkLimit = 1
-
- def process(self, pyfile):
- if not self.account:
- self.logError(_("Please enter your %s account or deactivate this plugin") % "premium.to")
- self.fail("No premium.to account provided")
-
- self.logDebug("premium.to: Old URL: %s" % pyfile.url)
-
- tra = self.getTraffic()
-
- #raise timeout to 2min
- self.req.setOption("timeout", 120)
-
- self.download(
- "http://premium.to/api/getfile.php?authcode=%s&link=%s" % (self.account.authcode, quote(pyfile.url, "")),
- disposition=True)
-
- check = self.checkDownload({"nopremium": "No premium account available"})
-
- if check == "nopremium":
- self.retry(60, 300, 'No premium account available')
-
- err = ''
- if self.req.http.code == '420':
- # Custom error code send - fail
- lastDownload = fs_encode(self.lastDownload)
-
- if exists(lastDownload):
- f = open(lastDownload, "rb")
- err = f.read(256).strip()
- f.close()
- remove(lastDownload)
- else:
- err = 'File does not exist'
-
- trb = self.getTraffic()
- self.logInfo("Filesize: %d, Traffic used %d, traffic left %d" % (pyfile.size, tra - trb, trb))
-
- if err: self.fail(err)
-
- def getTraffic(self):
- try:
- traffic = int(self.load("http://premium.to/api/traffic.php?authcode=%s" % self.account.authcode))
- except:
- traffic = 0
- return traffic
+#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from urllib import quote +from os.path import exists +from os import remove + +from module.plugins.Hoster import Hoster +from module.utils import fs_encode + + +class Premium4Me(Hoster): + __name__ = "Premium4Me" + __version__ = "0.08" + __type__ = "hoster" + + __pattern__ = r"http://premium.to/.*" + __description__ = """Premium.to hoster plugin""" + __author_name__ = ("RaNaN", "zoidberg", "stickell") + __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz", "l.stickell@yahoo.it") + + def setup(self): + self.resumeDownload = True + self.chunkLimit = 1 + + def process(self, pyfile): + if not self.account: + self.logError(_("Please enter your %s account or deactivate this plugin") % "premium.to") + self.fail("No premium.to account provided") + + self.logDebug("premium.to: Old URL: %s" % pyfile.url) + + tra = self.getTraffic() + + #raise timeout to 2min + self.req.setOption("timeout", 120) + + self.download( + "http://premium.to/api/getfile.php?authcode=%s&link=%s" % (self.account.authcode, quote(pyfile.url, "")), + disposition=True) + + check = self.checkDownload({"nopremium": "No premium account available"}) + + if check == "nopremium": + self.retry(60, 300, 'No premium account available') + + err = '' + if self.req.http.code == '420': + # Custom error code send - fail + lastDownload = fs_encode(self.lastDownload) + + if exists(lastDownload): + f = open(lastDownload, "rb") + err = f.read(256).strip() + f.close() + remove(lastDownload) + else: + err = 'File does not exist' + + trb = self.getTraffic() + self.logInfo("Filesize: %d, Traffic used %d, traffic left %d" % (pyfile.size, tra - trb, trb)) + + if err: self.fail(err) + + def getTraffic(self): + try: + traffic = int(self.load("http://premium.to/api/traffic.php?authcode=%s" % self.account.authcode)) + except: + traffic = 0 + return traffic diff --git a/module/plugins/hoster/PremiumizeMe.py b/module/plugins/hoster/PremiumizeMe.py index af21c578a..004bc4074 100644 --- a/module/plugins/hoster/PremiumizeMe.py +++ b/module/plugins/hoster/PremiumizeMe.py @@ -1,50 +1,50 @@ -from module.plugins.Hoster import Hoster
-
-from module.common.json_layer import json_loads
-
-class PremiumizeMe(Hoster):
- __name__ = "PremiumizeMe"
- __version__ = "0.12"
- __type__ = "hoster"
- __description__ = """Premiumize.Me hoster plugin"""
-
- # Since we want to allow the user to specify the list of hoster to use we let MultiHoster.coreReady create the regex patterns for us using getHosters in our PremiumizeMe hook.
- __pattern__ = None
-
- __author_name__ = ("Florian Franzen")
- __author_mail__ = ("FlorianFranzen@gmail.com")
-
- def process(self, pyfile):
- # Check account
- if not self.account or not self.account.canUse():
- self.logError(_("Please enter your %s account or deactivate this plugin") % "premiumize.me")
- self.fail("No valid premiumize.me account provided")
-
- # In some cases hostsers do not supply us with a filename at download, so we are going to set a fall back filename (e.g. for freakshare or xfileshare)
- self.pyfile.name = self.pyfile.name.split('/').pop() # Remove everthing before last slash
-
- # Correction for automatic assigned filename: Removing html at end if needed
- suffix_to_remove = ["html", "htm", "php", "php3", "asp", "shtm", "shtml", "cfml", "cfm"]
- temp = self.pyfile.name.split('.')
- if temp.pop() in suffix_to_remove:
- self.pyfile.name = ".".join(temp)
-
- # Get account data
- (user, data) = self.account.selectAccount()
-
- # Get rewritten link using the premiumize.me api v1 (see https://secure.premiumize.me/?show=api)
- answer = self.load("https://api.premiumize.me/pm-api/v1.php?method=directdownloadlink¶ms[login]=%s¶ms[pass]=%s¶ms[link]=%s" % (user, data['password'], self.pyfile.url))
- data = json_loads(answer)
-
- # Check status and decide what to do
- status = data['status']
- if status == 200:
- self.download(data['result']['location'], disposition=True)
- elif status == 400:
- self.fail("Invalid link")
- elif status == 404:
- self.offline()
- elif status >= 500:
- self.tempOffline()
- else:
- self.fail(data['statusmessage'])
+from module.plugins.Hoster import Hoster + +from module.common.json_layer import json_loads + +class PremiumizeMe(Hoster): + __name__ = "PremiumizeMe" + __version__ = "0.12" + __type__ = "hoster" + __description__ = """Premiumize.Me hoster plugin""" + + # Since we want to allow the user to specify the list of hoster to use we let MultiHoster.coreReady create the regex patterns for us using getHosters in our PremiumizeMe hook. + __pattern__ = None + + __author_name__ = ("Florian Franzen") + __author_mail__ = ("FlorianFranzen@gmail.com") + + def process(self, pyfile): + # Check account + if not self.account or not self.account.canUse(): + self.logError(_("Please enter your %s account or deactivate this plugin") % "premiumize.me") + self.fail("No valid premiumize.me account provided") + + # In some cases hostsers do not supply us with a filename at download, so we are going to set a fall back filename (e.g. for freakshare or xfileshare) + self.pyfile.name = self.pyfile.name.split('/').pop() # Remove everthing before last slash + + # Correction for automatic assigned filename: Removing html at end if needed + suffix_to_remove = ["html", "htm", "php", "php3", "asp", "shtm", "shtml", "cfml", "cfm"] + temp = self.pyfile.name.split('.') + if temp.pop() in suffix_to_remove: + self.pyfile.name = ".".join(temp) + + # Get account data + (user, data) = self.account.selectAccount() + + # Get rewritten link using the premiumize.me api v1 (see https://secure.premiumize.me/?show=api) + answer = self.load("https://api.premiumize.me/pm-api/v1.php?method=directdownloadlink¶ms[login]=%s¶ms[pass]=%s¶ms[link]=%s" % (user, data['password'], self.pyfile.url)) + data = json_loads(answer) + + # Check status and decide what to do + status = data['status'] + if status == 200: + self.download(data['result']['location'], disposition=True) + elif status == 400: + self.fail("Invalid link") + elif status == 404: + self.offline() + elif status >= 500: + self.tempOffline() + else: + self.fail(data['statusmessage']) diff --git a/module/plugins/hoster/RealdebridCom.py b/module/plugins/hoster/RealdebridCom.py index 98aca68d9..73baff5b3 100644 --- a/module/plugins/hoster/RealdebridCom.py +++ b/module/plugins/hoster/RealdebridCom.py @@ -1,88 +1,88 @@ -#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import re
-from time import time
-from urllib import quote, unquote
-from random import randrange
-
-from module.utils import parseFileSize, remove_chars
-from module.common.json_layer import json_loads
-from module.plugins.Hoster import Hoster
-
-class RealdebridCom(Hoster):
- __name__ = "RealdebridCom"
- __version__ = "0.51"
- __type__ = "hoster"
-
- __pattern__ = r"https?://.*real-debrid\..*"
- __description__ = """Real-Debrid.com hoster plugin"""
- __author_name__ = ("Devirex, Hazzard")
- __author_mail__ = ("naibaf_11@yahoo.de")
-
- def getFilename(self, url):
- try:
- name = unquote(url.rsplit("/", 1)[1])
- except IndexError:
- name = "Unknown_Filename..."
- if not name or name.endswith(".."): #incomplete filename, append random stuff
- name += "%s.tmp" % randrange(100,999)
- return name
-
- def init(self):
- self.tries = 0
- self.chunkLimit = 3
- self.resumeDownload = True
-
-
- def process(self, pyfile):
- if not self.account:
- self.logError(_("Please enter your %s account or deactivate this plugin") % "Real-debrid")
- self.fail("No Real-debrid account provided")
-
- self.logDebug("Real-Debrid: Old URL: %s" % pyfile.url)
- if re.match(self.__pattern__, pyfile.url):
- new_url = pyfile.url
- else:
- password = self.getPassword().splitlines()
- if not password: password = ""
- else: password = password[0]
-
- url = "http://real-debrid.com/ajax/unrestrict.php?lang=en&link=%s&password=%s&time=%s" % (quote(pyfile.url, ""), password, int(time()*1000))
- page = self.load(url)
- data = json_loads(page)
-
- self.logDebug("Returned Data: %s" % data)
-
- if data["error"] != 0:
- if data["message"] == "Your file is unavailable on the hoster.":
- self.offline()
- else:
- self.logWarning(data["message"])
- self.tempOffline()
- else:
- if self.pyfile.name is not None and self.pyfile.name.endswith('.tmp') and data["file_name"]:
- self.pyfile.name = data["file_name"]
- self.pyfile.size = parseFileSize(data["file_size"])
- new_url = data['generated_links'][0][-1]
-
- if self.getConfig("https"):
- new_url = new_url.replace("http://", "https://")
- else:
- new_url = new_url.replace("https://", "http://")
-
- self.logDebug("Real-Debrid: New URL: %s" % new_url)
-
- if pyfile.name.startswith("http") or pyfile.name.startswith("Unknown") or pyfile.name.endswith('..'):
- #only use when name wasnt already set
- pyfile.name = self.getFilename(new_url)
-
- self.download(new_url, disposition=True)
-
- check = self.checkDownload(
- {"error": "<title>An error occured while processing your request</title>"})
-
- if check == "error":
- #usual this download can safely be retried
- self.retry(reason="An error occured while generating link.", wait_time=60)
-
+#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import re +from time import time +from urllib import quote, unquote +from random import randrange + +from module.utils import parseFileSize, remove_chars +from module.common.json_layer import json_loads +from module.plugins.Hoster import Hoster + +class RealdebridCom(Hoster): + __name__ = "RealdebridCom" + __version__ = "0.51" + __type__ = "hoster" + + __pattern__ = r"https?://.*real-debrid\..*" + __description__ = """Real-Debrid.com hoster plugin""" + __author_name__ = ("Devirex, Hazzard") + __author_mail__ = ("naibaf_11@yahoo.de") + + def getFilename(self, url): + try: + name = unquote(url.rsplit("/", 1)[1]) + except IndexError: + name = "Unknown_Filename..." + if not name or name.endswith(".."): #incomplete filename, append random stuff + name += "%s.tmp" % randrange(100,999) + return name + + def init(self): + self.tries = 0 + self.chunkLimit = 3 + self.resumeDownload = True + + + def process(self, pyfile): + if not self.account: + self.logError(_("Please enter your %s account or deactivate this plugin") % "Real-debrid") + self.fail("No Real-debrid account provided") + + self.logDebug("Real-Debrid: Old URL: %s" % pyfile.url) + if re.match(self.__pattern__, pyfile.url): + new_url = pyfile.url + else: + password = self.getPassword().splitlines() + if not password: password = "" + else: password = password[0] + + url = "http://real-debrid.com/ajax/unrestrict.php?lang=en&link=%s&password=%s&time=%s" % (quote(pyfile.url, ""), password, int(time()*1000)) + page = self.load(url) + data = json_loads(page) + + self.logDebug("Returned Data: %s" % data) + + if data["error"] != 0: + if data["message"] == "Your file is unavailable on the hoster.": + self.offline() + else: + self.logWarning(data["message"]) + self.tempOffline() + else: + if self.pyfile.name is not None and self.pyfile.name.endswith('.tmp') and data["file_name"]: + self.pyfile.name = data["file_name"] + self.pyfile.size = parseFileSize(data["file_size"]) + new_url = data['generated_links'][0][-1] + + if self.getConfig("https"): + new_url = new_url.replace("http://", "https://") + else: + new_url = new_url.replace("https://", "http://") + + self.logDebug("Real-Debrid: New URL: %s" % new_url) + + if pyfile.name.startswith("http") or pyfile.name.startswith("Unknown") or pyfile.name.endswith('..'): + #only use when name wasnt already set + pyfile.name = self.getFilename(new_url) + + self.download(new_url, disposition=True) + + check = self.checkDownload( + {"error": "<title>An error occured while processing your request</title>"}) + + if check == "error": + #usual this download can safely be retried + self.retry(reason="An error occured while generating link.", wait_time=60) + diff --git a/module/plugins/hoster/RedtubeCom.py b/module/plugins/hoster/RedtubeCom.py index 9ffafd905..c2083e679 100644 --- a/module/plugins/hoster/RedtubeCom.py +++ b/module/plugins/hoster/RedtubeCom.py @@ -1,56 +1,56 @@ -#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import re
-from module.plugins.Hoster import Hoster
-from module.unescape import unescape
-
-class RedtubeCom(Hoster):
- __name__ = "RedtubeCom"
- __type__ = "hoster"
- __pattern__ = r'http://[\w\.]*?redtube\.com/\d+'
- __version__ = "0.2"
- __description__ = """Redtube.com Download Hoster"""
- __author_name__ = ("jeix")
- __author_mail__ = ("jeix@hasnomail.de")
-
- def process(self, pyfile):
- self.download_html()
- if not self.file_exists():
- self.offline()
-
- pyfile.name = self.get_file_name()
- self.download(self.get_file_url())
-
- def download_html(self):
- url = self.pyfile.url
- self.html = self.load(url)
-
- def get_file_url(self):
- """ returns the absolute downloadable filepath
- """
- if self.html is None:
- self.download_html()
-
- file_url = unescape(re.search(r'hashlink=(http.*?)"', self.html).group(1))
-
- return file_url
-
- def get_file_name(self):
- if self.html is None:
- self.download_html()
-
- name = re.search('<title>(.*?)- RedTube - Free Porn Videos</title>', self.html).group(1).strip() + ".flv"
- return name
-
- def file_exists(self):
- """ returns True or False
- """
- if self.html is None:
- self.download_html()
-
- if re.search(r'This video has been removed.', self.html) is not None:
- return False
- else:
- return True
-
+#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import re +from module.plugins.Hoster import Hoster +from module.unescape import unescape + +class RedtubeCom(Hoster): + __name__ = "RedtubeCom" + __type__ = "hoster" + __pattern__ = r'http://[\w\.]*?redtube\.com/\d+' + __version__ = "0.2" + __description__ = """Redtube.com Download Hoster""" + __author_name__ = ("jeix") + __author_mail__ = ("jeix@hasnomail.de") + + def process(self, pyfile): + self.download_html() + if not self.file_exists(): + self.offline() + + pyfile.name = self.get_file_name() + self.download(self.get_file_url()) + + def download_html(self): + url = self.pyfile.url + self.html = self.load(url) + + def get_file_url(self): + """ returns the absolute downloadable filepath + """ + if self.html is None: + self.download_html() + + file_url = unescape(re.search(r'hashlink=(http.*?)"', self.html).group(1)) + + return file_url + + def get_file_name(self): + if self.html is None: + self.download_html() + + name = re.search('<title>(.*?)- RedTube - Free Porn Videos</title>', self.html).group(1).strip() + ".flv" + return name + + def file_exists(self): + """ returns True or False + """ + if self.html is None: + self.download_html() + + if re.search(r'This video has been removed.', self.html) is not None: + return False + else: + return True + diff --git a/module/plugins/hoster/ShareplaceCom.py b/module/plugins/hoster/ShareplaceCom.py index 24536d351..c55f6703a 100644 --- a/module/plugins/hoster/ShareplaceCom.py +++ b/module/plugins/hoster/ShareplaceCom.py @@ -1,84 +1,84 @@ -#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import re
-import urllib
-from module.plugins.Hoster import Hoster
-
-class ShareplaceCom(Hoster):
- __name__ = "ShareplaceCom"
- __type__ = "hoster"
- __pattern__ = r"(http://)?(www\.)?shareplace\.(com|org)/\?[a-zA-Z0-9]+"
- __version__ = "0.11"
- __description__ = """Shareplace.com Download Hoster"""
- __author_name__ = ("ACCakut, based on YourfilesTo by jeix and skydancer")
- __author_mail__ = ("none")
-
- def setup(self):
- self.html = None
- self.multiDL = True
-
- def process(self,pyfile):
- self.pyfile = pyfile
- self.prepare()
- self.download(self.get_file_url())
-
- def prepare(self):
- if not self.file_exists():
- self.offline()
-
- self.pyfile.name = self.get_file_name()
-
- wait_time = self.get_waiting_time()
- self.setWait(wait_time)
- self.logDebug("%s: Waiting %d seconds." % (self.__name__,wait_time))
- self.wait()
-
- def get_waiting_time(self):
- if self.html is None:
- self.download_html()
-
- #var zzipitime = 15;
- m = re.search(r'var zzipitime = (\d+);', self.html)
- if m:
- sec = int(m.group(1))
- else:
- sec = 0
-
- return sec
-
- def download_html(self):
- url = re.sub("shareplace.com\/\?", "shareplace.com//index1.php/?a=", self.pyfile.url)
- self.html = self.load(url, decode=True)
-
- def get_file_url(self):
- """ returns the absolute downloadable filepath
- """
- url = re.search(r"var beer = '(.*?)';", self.html)
- if url:
- url = url.group(1)
- url = urllib.unquote(url.replace("http://http:/", "").replace("vvvvvvvvv", "").replace("lllllllll", "").replace("teletubbies", ""))
- self.logDebug("URL: %s" % url)
- return url
- else:
- self.fail("absolute filepath could not be found. offline? ")
-
- def get_file_name(self):
- if self.html is None:
- self.download_html()
-
- return re.search("<title>\s*(.*?)\s*</title>", self.html).group(1)
-
- def file_exists(self):
- """ returns True or False
- """
- if self.html is None:
- self.download_html()
-
- if re.search(r"HTTP Status 404", self.html) is not None:
- return False
- else:
- return True
-
-
-
+#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import re +import urllib +from module.plugins.Hoster import Hoster + +class ShareplaceCom(Hoster): + __name__ = "ShareplaceCom" + __type__ = "hoster" + __pattern__ = r"(http://)?(www\.)?shareplace\.(com|org)/\?[a-zA-Z0-9]+" + __version__ = "0.11" + __description__ = """Shareplace.com Download Hoster""" + __author_name__ = ("ACCakut, based on YourfilesTo by jeix and skydancer") + __author_mail__ = ("none") + + def setup(self): + self.html = None + self.multiDL = True + + def process(self,pyfile): + self.pyfile = pyfile + self.prepare() + self.download(self.get_file_url()) + + def prepare(self): + if not self.file_exists(): + self.offline() + + self.pyfile.name = self.get_file_name() + + wait_time = self.get_waiting_time() + self.setWait(wait_time) + self.logDebug("%s: Waiting %d seconds." % (self.__name__,wait_time)) + self.wait() + + def get_waiting_time(self): + if self.html is None: + self.download_html() + + #var zzipitime = 15; + m = re.search(r'var zzipitime = (\d+);', self.html) + if m: + sec = int(m.group(1)) + else: + sec = 0 + + return sec + + def download_html(self): + url = re.sub("shareplace.com\/\?", "shareplace.com//index1.php/?a=", self.pyfile.url) + self.html = self.load(url, decode=True) + + def get_file_url(self): + """ returns the absolute downloadable filepath + """ + url = re.search(r"var beer = '(.*?)';", self.html) + if url: + url = url.group(1) + url = urllib.unquote(url.replace("http://http:/", "").replace("vvvvvvvvv", "").replace("lllllllll", "").replace("teletubbies", "")) + self.logDebug("URL: %s" % url) + return url + else: + self.fail("absolute filepath could not be found. offline? ") + + def get_file_name(self): + if self.html is None: + self.download_html() + + return re.search("<title>\s*(.*?)\s*</title>", self.html).group(1) + + def file_exists(self): + """ returns True or False + """ + if self.html is None: + self.download_html() + + if re.search(r"HTTP Status 404", self.html) is not None: + return False + else: + return True + + + diff --git a/module/plugins/hoster/UploadStationCom.py b/module/plugins/hoster/UploadStationCom.py index d24682e4d..96dc7b577 100644 --- a/module/plugins/hoster/UploadStationCom.py +++ b/module/plugins/hoster/UploadStationCom.py @@ -1,21 +1,21 @@ -# -*- coding: utf-8 -*-
-from module.plugins.hoster.FileserveCom import FileserveCom, checkFile
-from module.plugins.Plugin import chunks
-
-class UploadStationCom(FileserveCom):
- __name__ = "UploadStationCom"
- __type__ = "hoster"
- __pattern__ = r"http://(?:www\.)?uploadstation\.com/file/(?P<id>[A-Za-z0-9]+)"
- __version__ = "0.51"
- __description__ = """UploadStation.Com File Download Hoster"""
- __author_name__ = ("fragonib", "zoidberg")
- __author_mail__ = ("fragonib[AT]yahoo[DOT]es", "zoidberg@mujmail.cz")
-
- URLS = ['http://www.uploadstation.com/file/', 'http://www.uploadstation.com/check-links.php', 'http://www.uploadstation.com/checkReCaptcha.php']
- LINKCHECK_TR = r'<div class="details (?:white|grey)">(.*?)\t{9}</div>'
- LINKCHECK_TD = r'<div class="(?:col )?col\d">(?:<[^>]*>| )*([^<]*)'
-
- LONG_WAIT_PATTERN = r'<h1>You have to wait (\d+) (\w+) to download the next file\.</h1>'
-
-def getInfo(urls):
+# -*- coding: utf-8 -*- +from module.plugins.hoster.FileserveCom import FileserveCom, checkFile +from module.plugins.Plugin import chunks + +class UploadStationCom(FileserveCom): + __name__ = "UploadStationCom" + __type__ = "hoster" + __pattern__ = r"http://(?:www\.)?uploadstation\.com/file/(?P<id>[A-Za-z0-9]+)" + __version__ = "0.51" + __description__ = """UploadStation.Com File Download Hoster""" + __author_name__ = ("fragonib", "zoidberg") + __author_mail__ = ("fragonib[AT]yahoo[DOT]es", "zoidberg@mujmail.cz") + + URLS = ['http://www.uploadstation.com/file/', 'http://www.uploadstation.com/check-links.php', 'http://www.uploadstation.com/checkReCaptcha.php'] + LINKCHECK_TR = r'<div class="details (?:white|grey)">(.*?)\t{9}</div>' + LINKCHECK_TD = r'<div class="(?:col )?col\d">(?:<[^>]*>| )*([^<]*)' + + LONG_WAIT_PATTERN = r'<h1>You have to wait (\d+) (\w+) to download the next file\.</h1>' + +def getInfo(urls): for chunk in chunks(urls, 100): yield checkFile(UploadStationCom, chunk)
\ No newline at end of file diff --git a/module/plugins/hoster/UploadingCom.py b/module/plugins/hoster/UploadingCom.py index 3037cfd20..a98c3bf71 100644 --- a/module/plugins/hoster/UploadingCom.py +++ b/module/plugins/hoster/UploadingCom.py @@ -1,110 +1,110 @@ -#!/usr/bin/env python
-# -*- 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: jeix
-"""
-
-import re
-from pycurl import HTTPHEADER
-from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, timestamp
-from module.common.json_layer import json_loads
-
-class UploadingCom(SimpleHoster):
- __name__ = "UploadingCom"
- __type__ = "hoster"
- __pattern__ = r"http://(?:www\.)?uploading\.com/files/(?:get/)?(?P<ID>[\w\d]+)"
- __version__ = "0.33"
- __description__ = """Uploading.Com File Download Hoster"""
- __author_name__ = ("jeix", "mkaay", "zoidberg")
- __author_mail__ = ("jeix@hasnomail.de", "mkaay@mkaay.de", "zoidberg@mujmail.cz")
-
- FILE_NAME_PATTERN = r'<title>Download (?P<N>.*?) for free on uploading.com</title>'
- FILE_SIZE_PATTERN = r'<span>File size: (?P<S>.*?)</span>'
- FILE_OFFLINE_PATTERN = r'<h2.*?>The requested file is not found</h2>'
-
- def process(self, pyfile):
- # set lang to english
- self.req.cj.setCookie("uploading.com", "lang", "1")
- self.req.cj.setCookie("uploading.com", "language", "1")
- self.req.cj.setCookie("uploading.com", "setlang", "en")
- self.req.cj.setCookie("uploading.com", "_lang", "en")
-
- if not "/get/" in self.pyfile.url:
- self.pyfile.url = self.pyfile.url.replace("/files", "/files/get")
-
- self.html = self.load(pyfile.url, decode = True)
- self.file_info = self.getFileInfo()
-
- if self.premium:
- self.handlePremium()
- else:
- self.handleFree()
-
- def handlePremium(self):
- postData = {'action': 'get_link',
- 'code': self.file_info['ID'],
- 'pass': 'undefined'}
-
- self.html = self.load('http://uploading.com/files/get/?JsHttpRequest=%d-xml' % timestamp(), post=postData)
- url = re.search(r'"link"\s*:\s*"(.*?)"', self.html)
- if url:
- url = url.group(1).replace("\\/", "/")
- self.download(url)
-
- raise Exception("Plugin defect.")
-
- def handleFree(self):
- found = re.search('<h2>((Daily )?Download Limit)</h2>', self.html)
- if found:
- self.pyfile.error = found.group(1)
- self.logWarning(self.pyfile.error)
- self.retry(max_tries=6, wait_time = 21600 if found.group(2) else 900, reason = self.pyfile.error)
-
- ajax_url = "http://uploading.com/files/get/?ajax"
- self.req.http.c.setopt(HTTPHEADER, ["X-Requested-With: XMLHttpRequest"])
- self.req.http.lastURL = self.pyfile.url
-
- response = json_loads(self.load(ajax_url, post = {'action': 'second_page', 'code': self.file_info['ID']}))
- if 'answer' in response and 'wait_time' in response['answer']:
- wait_time = int(response['answer']['wait_time'])
- self.logInfo("%s: Waiting %d seconds." % (self.__name__, wait_time))
- self.setWait(wait_time)
- self.wait()
- else:
- self.pluginParseError("AJAX/WAIT")
-
- response = json_loads(self.load(ajax_url, post = {'action': 'get_link', 'code': self.file_info['ID'], 'pass': 'false'}))
- if 'answer' in response and 'link' in response['answer']:
- url = response['answer']['link']
- else:
- self.pluginParseError("AJAX/URL")
-
- self.html = self.load(url)
- found = re.search(r'<form id="file_form" action="(.*?)"', self.html)
- if found:
- url = found.group(1)
- else:
- self.pluginParseError("URL")
-
- self.download(url)
-
- check = self.checkDownload({"html" : re.compile("\A<!DOCTYPE html PUBLIC")})
- if check == "html":
- self.logWarning("Redirected to a HTML page, wait 10 minutes and retry")
- self.setWait(600, True)
- self.wait()
-
+#!/usr/bin/env python +# -*- 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: jeix +""" + +import re +from pycurl import HTTPHEADER +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, timestamp +from module.common.json_layer import json_loads + +class UploadingCom(SimpleHoster): + __name__ = "UploadingCom" + __type__ = "hoster" + __pattern__ = r"http://(?:www\.)?uploading\.com/files/(?:get/)?(?P<ID>[\w\d]+)" + __version__ = "0.33" + __description__ = """Uploading.Com File Download Hoster""" + __author_name__ = ("jeix", "mkaay", "zoidberg") + __author_mail__ = ("jeix@hasnomail.de", "mkaay@mkaay.de", "zoidberg@mujmail.cz") + + FILE_NAME_PATTERN = r'<title>Download (?P<N>.*?) for free on uploading.com</title>' + FILE_SIZE_PATTERN = r'<span>File size: (?P<S>.*?)</span>' + FILE_OFFLINE_PATTERN = r'<h2.*?>The requested file is not found</h2>' + + def process(self, pyfile): + # set lang to english + self.req.cj.setCookie("uploading.com", "lang", "1") + self.req.cj.setCookie("uploading.com", "language", "1") + self.req.cj.setCookie("uploading.com", "setlang", "en") + self.req.cj.setCookie("uploading.com", "_lang", "en") + + if not "/get/" in self.pyfile.url: + self.pyfile.url = self.pyfile.url.replace("/files", "/files/get") + + self.html = self.load(pyfile.url, decode = True) + self.file_info = self.getFileInfo() + + if self.premium: + self.handlePremium() + else: + self.handleFree() + + def handlePremium(self): + postData = {'action': 'get_link', + 'code': self.file_info['ID'], + 'pass': 'undefined'} + + self.html = self.load('http://uploading.com/files/get/?JsHttpRequest=%d-xml' % timestamp(), post=postData) + url = re.search(r'"link"\s*:\s*"(.*?)"', self.html) + if url: + url = url.group(1).replace("\\/", "/") + self.download(url) + + raise Exception("Plugin defect.") + + def handleFree(self): + found = re.search('<h2>((Daily )?Download Limit)</h2>', self.html) + if found: + self.pyfile.error = found.group(1) + self.logWarning(self.pyfile.error) + self.retry(max_tries=6, wait_time = 21600 if found.group(2) else 900, reason = self.pyfile.error) + + ajax_url = "http://uploading.com/files/get/?ajax" + self.req.http.c.setopt(HTTPHEADER, ["X-Requested-With: XMLHttpRequest"]) + self.req.http.lastURL = self.pyfile.url + + response = json_loads(self.load(ajax_url, post = {'action': 'second_page', 'code': self.file_info['ID']})) + if 'answer' in response and 'wait_time' in response['answer']: + wait_time = int(response['answer']['wait_time']) + self.logInfo("%s: Waiting %d seconds." % (self.__name__, wait_time)) + self.setWait(wait_time) + self.wait() + else: + self.pluginParseError("AJAX/WAIT") + + response = json_loads(self.load(ajax_url, post = {'action': 'get_link', 'code': self.file_info['ID'], 'pass': 'false'})) + if 'answer' in response and 'link' in response['answer']: + url = response['answer']['link'] + else: + self.pluginParseError("AJAX/URL") + + self.html = self.load(url) + found = re.search(r'<form id="file_form" action="(.*?)"', self.html) + if found: + url = found.group(1) + else: + self.pluginParseError("URL") + + self.download(url) + + check = self.checkDownload({"html" : re.compile("\A<!DOCTYPE html PUBLIC")}) + if check == "html": + self.logWarning("Redirected to a HTML page, wait 10 minutes and retry") + self.setWait(600, True) + self.wait() + getInfo = create_getInfo(UploadingCom)
\ No newline at end of file diff --git a/module/plugins/hoster/X7To.py b/module/plugins/hoster/X7To.py index 79adf2a3f..965d84543 100644 --- a/module/plugins/hoster/X7To.py +++ b/module/plugins/hoster/X7To.py @@ -1,93 +1,93 @@ -# -*- coding: utf-8 -*-
-import re
-
-from module.plugins.Hoster import Hoster
-
-from module.network.RequestFactory import getURL
-
-def getInfo(urls):
- yield [(url, 0, 1, url) for url in urls]
-
-
-class X7To(Hoster):
- __name__ = "X7To"
- __type__ = "hoster"
- __pattern__ = r"http://(?:www.)?x7.to/"
- __version__ = "0.3"
- __description__ = """X7.To File Download Hoster"""
- __author_name__ = ("ernieb")
- __author_mail__ = ("ernieb")
-
- FILE_INFO_PATTERN=r'<meta name="description" content="Download: (.*?) \(([0-9,.]+) (KB|MB|GB)\)'
-
- def init(self):
- if self.premium:
- self.multiDL = False
- self.resumeDownload = False
- self.chunkLimit = 1
- else:
- self.multiDL = False
-
- self.file_id = re.search(r"http://x7.to/([a-zA-Z0-9]+)", self.pyfile.url).group(1)
- self.logDebug("file id is %s" % self.file_id)
- self.pyfile.url = "http://x7.to/" + self.file_id
-
- def process(self, pyfile):
- self.fail("Hoster not longer available")
-
- def handlePremium(self):
- # check if over limit first
- overLimit = re.search(r'<a onClick="cUser.buyTraffic\(\)" id="DL">', self.html)
- if overLimit:
- self.logDebug("over limit, falling back to free")
- self.handleFree()
- else:
- realurl = re.search(r'<a href="(http://stor.*?)" id="DL">', self.html)
- if realurl:
- realurl = realurl.group(1)
- self.logDebug("premium url found %s" % realurl)
- else:
- self.logDebug("premium link not found")
- self.download(realurl)
-
- def handleFree(self):
- # find file id
- file_id = re.search(r"var dlID = '(.*?)'", self.html)
- if not file_id:
- self.fail("Free download id not found")
-
- file_url = "http://x7.to/james/ticket/dl/" + file_id.group(1)
- self.logDebug("download id %s" % file_id.group(1))
-
- self.html = self.load(file_url, ref=False, decode=True)
-
- # deal with errors
- if "limit-dl" in self.html:
- self.logDebug("Limit reached ... waiting")
- self.setWait(900,True)
- self.wait()
- self.retry()
-
- if "limit-parallel" in self.html:
- self.fail("Cannot download in parallel")
-
- # no waiting required, go to download
- waitCheck = re.search(r"wait:(\d*),", self.html)
- if waitCheck:
- waitCheck = int(waitCheck.group(1))
- self.setWait(waitCheck)
- self.wait()
-
- urlCheck = re.search(r"url:'(.*?)'", self.html)
- url = None
- if urlCheck:
- url = urlCheck.group(1)
- self.logDebug("free url found %s" % url)
-
- if url:
- try:
- self.download(url)
- except:
- self.logDebug("downloading url failed: %s" % url)
- else:
- self.fail("Free download url found")
+# -*- coding: utf-8 -*- +import re + +from module.plugins.Hoster import Hoster + +from module.network.RequestFactory import getURL + +def getInfo(urls): + yield [(url, 0, 1, url) for url in urls] + + +class X7To(Hoster): + __name__ = "X7To" + __type__ = "hoster" + __pattern__ = r"http://(?:www.)?x7.to/" + __version__ = "0.3" + __description__ = """X7.To File Download Hoster""" + __author_name__ = ("ernieb") + __author_mail__ = ("ernieb") + + FILE_INFO_PATTERN=r'<meta name="description" content="Download: (.*?) \(([0-9,.]+) (KB|MB|GB)\)' + + def init(self): + if self.premium: + self.multiDL = False + self.resumeDownload = False + self.chunkLimit = 1 + else: + self.multiDL = False + + self.file_id = re.search(r"http://x7.to/([a-zA-Z0-9]+)", self.pyfile.url).group(1) + self.logDebug("file id is %s" % self.file_id) + self.pyfile.url = "http://x7.to/" + self.file_id + + def process(self, pyfile): + self.fail("Hoster not longer available") + + def handlePremium(self): + # check if over limit first + overLimit = re.search(r'<a onClick="cUser.buyTraffic\(\)" id="DL">', self.html) + if overLimit: + self.logDebug("over limit, falling back to free") + self.handleFree() + else: + realurl = re.search(r'<a href="(http://stor.*?)" id="DL">', self.html) + if realurl: + realurl = realurl.group(1) + self.logDebug("premium url found %s" % realurl) + else: + self.logDebug("premium link not found") + self.download(realurl) + + def handleFree(self): + # find file id + file_id = re.search(r"var dlID = '(.*?)'", self.html) + if not file_id: + self.fail("Free download id not found") + + file_url = "http://x7.to/james/ticket/dl/" + file_id.group(1) + self.logDebug("download id %s" % file_id.group(1)) + + self.html = self.load(file_url, ref=False, decode=True) + + # deal with errors + if "limit-dl" in self.html: + self.logDebug("Limit reached ... waiting") + self.setWait(900,True) + self.wait() + self.retry() + + if "limit-parallel" in self.html: + self.fail("Cannot download in parallel") + + # no waiting required, go to download + waitCheck = re.search(r"wait:(\d*),", self.html) + if waitCheck: + waitCheck = int(waitCheck.group(1)) + self.setWait(waitCheck) + self.wait() + + urlCheck = re.search(r"url:'(.*?)'", self.html) + url = None + if urlCheck: + url = urlCheck.group(1) + self.logDebug("free url found %s" % url) + + if url: + try: + self.download(url) + except: + self.logDebug("downloading url failed: %s" % url) + else: + self.fail("Free download url found") diff --git a/module/plugins/hoster/Xdcc.py b/module/plugins/hoster/Xdcc.py index 92b77f73a..d0630bd29 100644 --- a/module/plugins/hoster/Xdcc.py +++ b/module/plugins/hoster/Xdcc.py @@ -1,229 +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: jeix
-"""
-
-from os.path import join
-from os.path import exists
-from os import makedirs
-import re
-import sys
-import time
-import socket, struct
-from select import select
-from module.utils import save_join
-
-from module.plugins.Hoster import Hoster
-
-
-class Xdcc(Hoster):
- __name__ = "Xdcc"
- __version__ = "0.32"
- __pattern__ = r'xdcc://.*?(/#?.*?)?/.*?/#?\d+/?' # xdcc://irc.Abjects.net/#channel/[XDCC]|Shit/#0004/
- __type__ = "hoster"
- __config__ = [
- ("nick", "str", "Nickname", "pyload"),
- ("ident", "str", "Ident", "pyloadident"),
- ("realname", "str", "Realname", "pyloadreal")
- ]
- __description__ = """A Plugin that allows you to download from an IRC XDCC bot"""
- __author_name__ = ("jeix")
- __author_mail__ = ("jeix@hasnomail.com")
-
- def setup(self):
- self.debug = 0 #0,1,2
- self.timeout = 30
- self.multiDL = False
-
-
-
- def process(self, pyfile):
- # change request type
- self.req = pyfile.m.core.requestFactory.getRequest(self.__name__, type="XDCC")
-
- self.pyfile = pyfile
- for i in range(0,3):
- try:
- nmn = self.doDownload(pyfile.url)
- self.logDebug("%s: Download of %s finished." % (self.__name__, nmn))
- return
- except socket.error, e:
- if hasattr(e, "errno"):
- errno = e.errno
- else:
- errno = e.args[0]
-
- if errno in (10054,):
- self.logDebug("XDCC: Server blocked our ip, retry in 5 min")
- self.setWait(300)
- self.wait()
- continue
-
- self.fail("Failed due to socket errors. Code: %d" % errno)
-
- self.fail("Server blocked our ip, retry again later manually")
-
-
- def doDownload(self, url):
- self.pyfile.setStatus("waiting") # real link
-
- download_folder = self.config['general']['download_folder']
- location = join(download_folder, self.pyfile.package().folder.decode(sys.getfilesystemencoding()))
- if not exists(location):
- makedirs(location)
-
- m = re.search(r'xdcc://(.*?)/#?(.*?)/(.*?)/#?(\d+)/?', url)
- server = m.group(1)
- chan = m.group(2)
- bot = m.group(3)
- pack = m.group(4)
- nick = self.getConfig('nick')
- ident = self.getConfig('ident')
- real = self.getConfig('realname')
-
- temp = server.split(':')
- ln = len(temp)
- if ln == 2:
- host, port = temp
- elif ln == 1:
- host, port = temp[0], 6667
- else:
- self.fail("Invalid hostname for IRC Server (%s)" % server)
-
-
- #######################
- # CONNECT TO IRC AND IDLE FOR REAL LINK
- dl_time = time.time()
-
- sock = socket.socket()
- sock.connect((host, int(port)))
- if nick == "pyload":
- nick = "pyload-%d" % (time.time() % 1000) # last 3 digits
- sock.send("NICK %s\r\n" % nick)
- sock.send("USER %s %s bla :%s\r\n" % (ident, host, real))
- time.sleep(3)
- sock.send("JOIN #%s\r\n" % chan)
- sock.send("PRIVMSG %s :xdcc send #%s\r\n" % (bot, pack))
-
- # IRC recv loop
- readbuffer = ""
- done = False
- retry = None
- m = None
- while True:
-
- # done is set if we got our real link
- if done:
- break
-
- if retry:
- if time.time() > retry:
- retry = None
- dl_time = time.time()
- sock.send("PRIVMSG %s :xdcc send #%s\r\n" % (bot, pack))
-
- else:
- if (dl_time + self.timeout) < time.time(): # todo: add in config
- sock.send("QUIT :byebye\r\n")
- sock.close()
- self.fail("XDCC Bot did not answer")
-
-
- fdset = select([sock], [], [], 0)
- if sock not in fdset[0]:
- continue
-
- readbuffer += sock.recv(1024)
- temp = readbuffer.split("\n")
- readbuffer = temp.pop()
-
- for line in temp:
- if self.debug is 2: print "*> " + unicode(line, errors='ignore')
- line = line.rstrip()
- first = line.split()
-
- if first[0] == "PING":
- sock.send("PONG %s\r\n" % first[1])
-
- if first[0] == "ERROR":
- self.fail("IRC-Error: %s" % line)
-
- msg = line.split(None, 3)
- if len(msg) != 4:
- continue
-
- msg = { \
- "origin":msg[0][1:], \
- "action":msg[1], \
- "target":msg[2], \
- "text" :msg[3][1:] \
- }
-
-
- if nick == msg["target"][0:len(nick)] and "PRIVMSG" == msg["action"]:
- if msg["text"] == "\x01VERSION\x01":
- self.logDebug("XDCC: Sending CTCP VERSION.")
- sock.send("NOTICE %s :%s\r\n" % (msg['origin'], "pyLoad! IRC Interface"))
- elif msg["text"] == "\x01TIME\x01":
- self.logDebug("Sending CTCP TIME.")
- sock.send("NOTICE %s :%d\r\n" % (msg['origin'], time.time()))
- elif msg["text"] == "\x01LAG\x01":
- pass # don't know how to answer
-
- if not (bot == msg["origin"][0:len(bot)]
- and nick == msg["target"][0:len(nick)]
- and msg["action"] in ("PRIVMSG", "NOTICE")):
- continue
-
- if self.debug is 1:
- print "%s: %s" % (msg["origin"], msg["text"])
-
- if "You already requested that pack" in msg["text"]:
- retry = time.time() + 300
-
- if "you must be on a known channel to request a pack" in msg["text"]:
- self.fail("Wrong channel")
-
- m = re.match('\x01DCC SEND (.*?) (\d+) (\d+)(?: (\d+))?\x01', msg["text"])
- if m:
- done = True
-
- # get connection data
- ip = socket.inet_ntoa(struct.pack('L', socket.ntohl(int(m.group(2)))))
- port = int(m.group(3))
- packname = m.group(1)
-
- if len(m.groups()) > 3:
- self.req.filesize = int(m.group(4))
-
- self.pyfile.name = packname
- filename = save_join(location, packname)
- self.logInfo("XDCC: Downloading %s from %s:%d" % (packname, ip, port))
-
- self.pyfile.setStatus("downloading")
- newname = self.req.download(ip, port, filename, sock, self.pyfile.setProgress)
- if newname and newname != filename:
- self.logInfo("%(name)s saved as %(newname)s" % {"name": self.pyfile.name, "newname": newname})
- filename = newname
-
- # kill IRC socket
- # sock.send("QUIT :byebye\r\n")
- sock.close()
-
- self.lastDownload = filename
- return self.lastDownload
-
+# -*- 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: jeix +""" + +from os.path import join +from os.path import exists +from os import makedirs +import re +import sys +import time +import socket, struct +from select import select +from module.utils import save_join + +from module.plugins.Hoster import Hoster + + +class Xdcc(Hoster): + __name__ = "Xdcc" + __version__ = "0.32" + __pattern__ = r'xdcc://.*?(/#?.*?)?/.*?/#?\d+/?' # xdcc://irc.Abjects.net/#channel/[XDCC]|Shit/#0004/ + __type__ = "hoster" + __config__ = [ + ("nick", "str", "Nickname", "pyload"), + ("ident", "str", "Ident", "pyloadident"), + ("realname", "str", "Realname", "pyloadreal") + ] + __description__ = """A Plugin that allows you to download from an IRC XDCC bot""" + __author_name__ = ("jeix") + __author_mail__ = ("jeix@hasnomail.com") + + def setup(self): + self.debug = 0 #0,1,2 + self.timeout = 30 + self.multiDL = False + + + + def process(self, pyfile): + # change request type + self.req = pyfile.m.core.requestFactory.getRequest(self.__name__, type="XDCC") + + self.pyfile = pyfile + for i in range(0,3): + try: + nmn = self.doDownload(pyfile.url) + self.logDebug("%s: Download of %s finished." % (self.__name__, nmn)) + return + except socket.error, e: + if hasattr(e, "errno"): + errno = e.errno + else: + errno = e.args[0] + + if errno in (10054,): + self.logDebug("XDCC: Server blocked our ip, retry in 5 min") + self.setWait(300) + self.wait() + continue + + self.fail("Failed due to socket errors. Code: %d" % errno) + + self.fail("Server blocked our ip, retry again later manually") + + + def doDownload(self, url): + self.pyfile.setStatus("waiting") # real link + + download_folder = self.config['general']['download_folder'] + location = join(download_folder, self.pyfile.package().folder.decode(sys.getfilesystemencoding())) + if not exists(location): + makedirs(location) + + m = re.search(r'xdcc://(.*?)/#?(.*?)/(.*?)/#?(\d+)/?', url) + server = m.group(1) + chan = m.group(2) + bot = m.group(3) + pack = m.group(4) + nick = self.getConfig('nick') + ident = self.getConfig('ident') + real = self.getConfig('realname') + + temp = server.split(':') + ln = len(temp) + if ln == 2: + host, port = temp + elif ln == 1: + host, port = temp[0], 6667 + else: + self.fail("Invalid hostname for IRC Server (%s)" % server) + + + ####################### + # CONNECT TO IRC AND IDLE FOR REAL LINK + dl_time = time.time() + + sock = socket.socket() + sock.connect((host, int(port))) + if nick == "pyload": + nick = "pyload-%d" % (time.time() % 1000) # last 3 digits + sock.send("NICK %s\r\n" % nick) + sock.send("USER %s %s bla :%s\r\n" % (ident, host, real)) + time.sleep(3) + sock.send("JOIN #%s\r\n" % chan) + sock.send("PRIVMSG %s :xdcc send #%s\r\n" % (bot, pack)) + + # IRC recv loop + readbuffer = "" + done = False + retry = None + m = None + while True: + + # done is set if we got our real link + if done: + break + + if retry: + if time.time() > retry: + retry = None + dl_time = time.time() + sock.send("PRIVMSG %s :xdcc send #%s\r\n" % (bot, pack)) + + else: + if (dl_time + self.timeout) < time.time(): # todo: add in config + sock.send("QUIT :byebye\r\n") + sock.close() + self.fail("XDCC Bot did not answer") + + + fdset = select([sock], [], [], 0) + if sock not in fdset[0]: + continue + + readbuffer += sock.recv(1024) + temp = readbuffer.split("\n") + readbuffer = temp.pop() + + for line in temp: + if self.debug is 2: print "*> " + unicode(line, errors='ignore') + line = line.rstrip() + first = line.split() + + if first[0] == "PING": + sock.send("PONG %s\r\n" % first[1]) + + if first[0] == "ERROR": + self.fail("IRC-Error: %s" % line) + + msg = line.split(None, 3) + if len(msg) != 4: + continue + + msg = { \ + "origin":msg[0][1:], \ + "action":msg[1], \ + "target":msg[2], \ + "text" :msg[3][1:] \ + } + + + if nick == msg["target"][0:len(nick)] and "PRIVMSG" == msg["action"]: + if msg["text"] == "\x01VERSION\x01": + self.logDebug("XDCC: Sending CTCP VERSION.") + sock.send("NOTICE %s :%s\r\n" % (msg['origin'], "pyLoad! IRC Interface")) + elif msg["text"] == "\x01TIME\x01": + self.logDebug("Sending CTCP TIME.") + sock.send("NOTICE %s :%d\r\n" % (msg['origin'], time.time())) + elif msg["text"] == "\x01LAG\x01": + pass # don't know how to answer + + if not (bot == msg["origin"][0:len(bot)] + and nick == msg["target"][0:len(nick)] + and msg["action"] in ("PRIVMSG", "NOTICE")): + continue + + if self.debug is 1: + print "%s: %s" % (msg["origin"], msg["text"]) + + if "You already requested that pack" in msg["text"]: + retry = time.time() + 300 + + if "you must be on a known channel to request a pack" in msg["text"]: + self.fail("Wrong channel") + + m = re.match('\x01DCC SEND (.*?) (\d+) (\d+)(?: (\d+))?\x01', msg["text"]) + if m: + done = True + + # get connection data + ip = socket.inet_ntoa(struct.pack('L', socket.ntohl(int(m.group(2))))) + port = int(m.group(3)) + packname = m.group(1) + + if len(m.groups()) > 3: + self.req.filesize = int(m.group(4)) + + self.pyfile.name = packname + filename = save_join(location, packname) + self.logInfo("XDCC: Downloading %s from %s:%d" % (packname, ip, port)) + + self.pyfile.setStatus("downloading") + newname = self.req.download(ip, port, filename, sock, self.pyfile.setProgress) + if newname and newname != filename: + self.logInfo("%(name)s saved as %(newname)s" % {"name": self.pyfile.name, "newname": newname}) + filename = newname + + # kill IRC socket + # sock.send("QUIT :byebye\r\n") + sock.close() + + self.lastDownload = filename + return self.lastDownload + diff --git a/module/plugins/hoster/YourfilesTo.py b/module/plugins/hoster/YourfilesTo.py index c2183f8a8..4a192b32a 100644 --- a/module/plugins/hoster/YourfilesTo.py +++ b/module/plugins/hoster/YourfilesTo.py @@ -1,83 +1,83 @@ -#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import re
-import urllib
-from module.plugins.Hoster import Hoster
-
-class YourfilesTo(Hoster):
- __name__ = "YourfilesTo"
- __type__ = "hoster"
- __pattern__ = r"(http://)?(www\.)?yourfiles\.(to|biz)/\?d=[a-zA-Z0-9]+"
- __version__ = "0.21"
- __description__ = """Youfiles.to Download Hoster"""
- __author_name__ = ("jeix", "skydancer")
- __author_mail__ = ("jeix@hasnomail.de", "skydancer@hasnomail.de")
-
- def setup(self):
- self.html = None
- self.multiDL = True
-
- def process(self,pyfile):
- self.pyfile = pyfile
- self.prepare()
- self.download(self.get_file_url())
-
- def prepare(self):
- if not self.file_exists():
- self.offline()
-
- self.pyfile.name = self.get_file_name()
-
- wait_time = self.get_waiting_time()
- self.setWait(wait_time)
- self.logDebug("%s: Waiting %d seconds." % (self.__name__,wait_time))
- self.wait()
-
- def get_waiting_time(self):
- if self.html is None:
- self.download_html()
-
- #var zzipitime = 15;
- m = re.search(r'var zzipitime = (\d+);', self.html)
- if m:
- sec = int(m.group(1))
- else:
- sec = 0
-
- return sec
-
- def download_html(self):
- url = self.pyfile.url
- self.html = self.load(url)
-
- def get_file_url(self):
- """ returns the absolute downloadable filepath
- """
- url = re.search(r"var bla = '(.*?)';", self.html)
- if url:
- url = url.group(1)
- url = urllib.unquote(url.replace("http://http:/http://", "http://").replace("dumdidum", ""))
- return url
- else:
- self.fail("absolute filepath could not be found. offline? ")
-
- def get_file_name(self):
- if self.html is None:
- self.download_html()
-
- return re.search("<title>(.*)</title>", self.html).group(1)
-
- def file_exists(self):
- """ returns True or False
- """
- if self.html is None:
- self.download_html()
-
- if re.search(r"HTTP Status 404", self.html) is not None:
- return False
- else:
- return True
-
-
-
+#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import re +import urllib +from module.plugins.Hoster import Hoster + +class YourfilesTo(Hoster): + __name__ = "YourfilesTo" + __type__ = "hoster" + __pattern__ = r"(http://)?(www\.)?yourfiles\.(to|biz)/\?d=[a-zA-Z0-9]+" + __version__ = "0.21" + __description__ = """Youfiles.to Download Hoster""" + __author_name__ = ("jeix", "skydancer") + __author_mail__ = ("jeix@hasnomail.de", "skydancer@hasnomail.de") + + def setup(self): + self.html = None + self.multiDL = True + + def process(self,pyfile): + self.pyfile = pyfile + self.prepare() + self.download(self.get_file_url()) + + def prepare(self): + if not self.file_exists(): + self.offline() + + self.pyfile.name = self.get_file_name() + + wait_time = self.get_waiting_time() + self.setWait(wait_time) + self.logDebug("%s: Waiting %d seconds." % (self.__name__,wait_time)) + self.wait() + + def get_waiting_time(self): + if self.html is None: + self.download_html() + + #var zzipitime = 15; + m = re.search(r'var zzipitime = (\d+);', self.html) + if m: + sec = int(m.group(1)) + else: + sec = 0 + + return sec + + def download_html(self): + url = self.pyfile.url + self.html = self.load(url) + + def get_file_url(self): + """ returns the absolute downloadable filepath + """ + url = re.search(r"var bla = '(.*?)';", self.html) + if url: + url = url.group(1) + url = urllib.unquote(url.replace("http://http:/http://", "http://").replace("dumdidum", "")) + return url + else: + self.fail("absolute filepath could not be found. offline? ") + + def get_file_name(self): + if self.html is None: + self.download_html() + + return re.search("<title>(.*)</title>", self.html).group(1) + + def file_exists(self): + """ returns True or False + """ + if self.html is None: + self.download_html() + + if re.search(r"HTTP Status 404", self.html) is not None: + return False + else: + return True + + + diff --git a/module/plugins/hoster/ZeveraCom.py b/module/plugins/hoster/ZeveraCom.py index 3ad662bb6..92f9e4dcd 100644 --- a/module/plugins/hoster/ZeveraCom.py +++ b/module/plugins/hoster/ZeveraCom.py @@ -1,108 +1,108 @@ -#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from module.plugins.Hoster import Hoster
-from module.utils import html_unescape
-from urllib import quote, unquote
-from time import sleep
-
-class ZeveraCom(Hoster):
- __name__ = "ZeveraCom"
- __version__ = "0.21"
- __type__ = "hoster"
- __pattern__ = r"http://zevera.com/.*"
- __description__ = """zevera.com hoster plugin"""
- __author_name__ = ("zoidberg")
- __author_mail__ = ("zoidberg@mujmail.cz")
-
- def setup(self):
- self.resumeDownload = self.multiDL = True
- self.chunkLimit = 1
-
- def process(self, pyfile):
- if not self.account:
- self.logError(_("Please enter your %s account or deactivate this plugin") % "zevera.com")
- self.fail("No zevera.com account provided")
-
- self.logDebug("zevera.com: Old URL: %s" % pyfile.url)
-
- if self.account.getAPIData(self.req, cmd = "checklink", olink = pyfile.url) != "Alive":
- self.fail("Offline or not downloadable - contact Zevera support")
-
- header = self.account.getAPIData(self.req, just_header = True, cmd="generatedownloaddirect", olink = pyfile.url)
- if not "location" in header:
- self.fail("Unable to initialize download - contact Zevera support")
-
- self.download(header['location'], disposition = True)
-
- check = self.checkDownload({"error" : 'action="ErrorDownload.aspx'})
- if check == "error":
- self.fail("Error response received - contact Zevera support")
-
- """
- # BitAPI not used - defunct, probably abandoned by Zevera
-
- api_url = "http://zevera.com/API.ashx"
-
- def process(self, pyfile):
- if not self.account:
- self.logError(_("Please enter your zevera.com account or deactivate this plugin"))
- self.fail("No zevera.com account provided")
-
- self.logDebug("zevera.com: Old URL: %s" % pyfile.url)
-
- last_size = retries = 0
- olink = self.pyfile.url #quote(self.pyfile.url.encode('utf_8'))
-
- for i in range(100):
- self.retData = self.account.loadAPIRequest(self.req, cmd = 'download_request', olink = olink)
- self.checkAPIErrors(self.retData)
-
- if self.retData['FileInfo']['StatusID'] == 100:
- break
- elif self.retData['FileInfo']['StatusID'] == 99:
- self.fail('Failed to initialize download (99)')
- else:
- if self.retData['FileInfo']['Progress']['BytesReceived'] <= last_size:
- if retries >= 6:
- self.fail('Failed to initialize download (%d)' % self.retData['FileInfo']['StatusID'] )
- retries += 1
- else:
- retries = 0
-
- last_size = self.retData['FileInfo']['Progress']['BytesReceived']
-
- self.setWait(self.retData['Update_Wait'])
- self.wait()
-
- pyfile.name = self.retData['FileInfo']['RealFileName']
- pyfile.size = self.retData['FileInfo']['FileSizeInBytes']
-
- self.retData = self.account.loadAPIRequest(self.req, cmd = 'download_start', FileID = self.retData['FileInfo']['FileID'])
- self.checkAPIErrors(self.retData)
-
- self.download(self.api_url, get = {
- 'cmd': "open_stream",
- 'login': self.account.loginname,
- 'pass': self.account.password,
- 'FileID': self.retData['FileInfo']['FileID'],
- 'startBytes': 0
- }
- )
-
- def checkAPIErrors(self, retData):
- if not retData:
- self.fail('Unknown API response')
-
- if retData['ErrorCode']:
- self.logError(retData['ErrorCode'], retData['ErrorMessage'])
- #self.fail('ERROR: ' + retData['ErrorMessage'])
-
- if self.pyfile.size / 1024000 > retData['AccountInfo']['AvailableTODAYTrafficForUseInMBytes']:
- self.logWarning("Not enough data left to download the file")
-
- def crazyDecode(self, ustring):
- # accepts decoded ie. unicode string - API response is double-quoted, double-utf8-encoded
- # no idea what the proper order of calling these functions would be :-/
- return html_unescape(unquote(unquote(ustring.replace('@DELIMITER@','#'))).encode('raw_unicode_escape').decode('utf-8'))
+#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from module.plugins.Hoster import Hoster +from module.utils import html_unescape +from urllib import quote, unquote +from time import sleep + +class ZeveraCom(Hoster): + __name__ = "ZeveraCom" + __version__ = "0.21" + __type__ = "hoster" + __pattern__ = r"http://zevera.com/.*" + __description__ = """zevera.com hoster plugin""" + __author_name__ = ("zoidberg") + __author_mail__ = ("zoidberg@mujmail.cz") + + def setup(self): + self.resumeDownload = self.multiDL = True + self.chunkLimit = 1 + + def process(self, pyfile): + if not self.account: + self.logError(_("Please enter your %s account or deactivate this plugin") % "zevera.com") + self.fail("No zevera.com account provided") + + self.logDebug("zevera.com: Old URL: %s" % pyfile.url) + + if self.account.getAPIData(self.req, cmd = "checklink", olink = pyfile.url) != "Alive": + self.fail("Offline or not downloadable - contact Zevera support") + + header = self.account.getAPIData(self.req, just_header = True, cmd="generatedownloaddirect", olink = pyfile.url) + if not "location" in header: + self.fail("Unable to initialize download - contact Zevera support") + + self.download(header['location'], disposition = True) + + check = self.checkDownload({"error" : 'action="ErrorDownload.aspx'}) + if check == "error": + self.fail("Error response received - contact Zevera support") + + """ + # BitAPI not used - defunct, probably abandoned by Zevera + + api_url = "http://zevera.com/API.ashx" + + def process(self, pyfile): + if not self.account: + self.logError(_("Please enter your zevera.com account or deactivate this plugin")) + self.fail("No zevera.com account provided") + + self.logDebug("zevera.com: Old URL: %s" % pyfile.url) + + last_size = retries = 0 + olink = self.pyfile.url #quote(self.pyfile.url.encode('utf_8')) + + for i in range(100): + self.retData = self.account.loadAPIRequest(self.req, cmd = 'download_request', olink = olink) + self.checkAPIErrors(self.retData) + + if self.retData['FileInfo']['StatusID'] == 100: + break + elif self.retData['FileInfo']['StatusID'] == 99: + self.fail('Failed to initialize download (99)') + else: + if self.retData['FileInfo']['Progress']['BytesReceived'] <= last_size: + if retries >= 6: + self.fail('Failed to initialize download (%d)' % self.retData['FileInfo']['StatusID'] ) + retries += 1 + else: + retries = 0 + + last_size = self.retData['FileInfo']['Progress']['BytesReceived'] + + self.setWait(self.retData['Update_Wait']) + self.wait() + + pyfile.name = self.retData['FileInfo']['RealFileName'] + pyfile.size = self.retData['FileInfo']['FileSizeInBytes'] + + self.retData = self.account.loadAPIRequest(self.req, cmd = 'download_start', FileID = self.retData['FileInfo']['FileID']) + self.checkAPIErrors(self.retData) + + self.download(self.api_url, get = { + 'cmd': "open_stream", + 'login': self.account.loginname, + 'pass': self.account.password, + 'FileID': self.retData['FileInfo']['FileID'], + 'startBytes': 0 + } + ) + + def checkAPIErrors(self, retData): + if not retData: + self.fail('Unknown API response') + + if retData['ErrorCode']: + self.logError(retData['ErrorCode'], retData['ErrorMessage']) + #self.fail('ERROR: ' + retData['ErrorMessage']) + + if self.pyfile.size / 1024000 > retData['AccountInfo']['AvailableTODAYTrafficForUseInMBytes']: + self.logWarning("Not enough data left to download the file") + + def crazyDecode(self, ustring): + # accepts decoded ie. unicode string - API response is double-quoted, double-utf8-encoded + # no idea what the proper order of calling these functions would be :-/ + return html_unescape(unquote(unquote(ustring.replace('@DELIMITER@','#'))).encode('raw_unicode_escape').decode('utf-8')) """
\ No newline at end of file |