Pberndt V4
Direkt zum Inhalt springen
Quellcode rsDownload.py
Sourcecode
import urllib2
import urllib
import urlparse
import re
import os
import threading
import sys
import random
import time
import getopt
import cookielib
import optparse
import termios
import tty
from htmlentitydefs import name2codepoint
def restartRouter():
"""
Restart router to get a new IP
"""
os.system("routerReset")
return True
def doneHook(flags):
"""
Called when a download is finished
See handler.HANDLER_* for values of flags
"""
return
if not flags & handler.HANDLER_WAS_REDIRECTED:
os.system("aplay -q /usr/share/sounds/k3b_success1.wav 2>&1 >/dev/null &")
def errorHook():
"""
Called when an error occurred
"""
return
os.system("aplay -q /usr/share/sounds/k3b_error1.wav 2>&1 >/dev/null &")
def captchaHook(data, caller):
"""
Called when a captcha is to be deciphered
data holds the raw data of the image!
Use caller to check which handler is calling this
Return False or the code
"""
# Anticaptcha does not work ATM
if False and caller == "rapidshare" and os.system("which anticaptcha 2>&1 >/dev/null") == 0:
# Call anticaptcha
fileName = os.path.abspath(impFilename("captcha.jpg"))
file = open(fileName, "w")
file.write(data)
file.close()
try:
captcha = os.popen("anticaptcha %r --method 22a" % fileName).read().strip()
except:
os.unlink(fileName)
return False
os.unlink(fileName)
if len(captcha) != 4:
return False
ui.info("Anticaptcha detected captcha successfully: %s" % captcha)
return captcha
else:
# Play sound to inform the user that interaction is needed
os.system("aplay -q /usr/share/sounds/k3b_wait_media1.wav 2>&1 >/dev/null &")
return False
RSDOWNLOD_VERSION = "0.8"
cookieJar = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookieJar))
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
urllib2.install_opener(opener)
fileList = []
doneList = []
class ui(object):
_COLOR = {
"error": "\033[00;31m",
"info": "\033[00;32m",
"warn": "\033[00;33m",
"info2": "\033[00;34m",
"def": "\033[0m"
}
@staticmethod
def _getTerminalWidth():
if sys.stdin.isatty():
oldSettings = termios.tcgetattr(sys.stdin.fileno())
tty.setraw(sys.stdin.fileno())
print "\033[18t",
size = ""
while "t" not in size:
size += sys.stdin.read(1)
termios.tcsetattr(sys.stdin.fileno(), termios.TCSADRAIN, oldSettings)
return int(size[size.find(";") + 1:-1])
else:
return 80
@staticmethod
def endProgress():
"""
Erase the current console line
(End progress())
"""
print "\033[2K\r", # Erase line
#print "\033[1A", # Move line up
#print "\033[2K\r", # Erase line
sys.stdout.flush()
_progressData = {}
@staticmethod
def startProgress():
"""
Start progress()
"""
ui._progressData = {
'start': time.time(),
'last': time.time(),
'data': 0,
'lastDsp': time.time()
}
@staticmethod
def _formatSize(size):
units = [ "b", "Kb", "Mb", "Gb" ]
ret = units.pop(0)
while size > 1024:
size /= 1024.0
ret = units.pop(0)
return "%03.2f%s" % (size, ret)
@staticmethod
def _formatTime(seconds):
hours = 0
minutes = 0
while seconds >= 3600:
hours += 1
seconds -= 3600
while seconds >= 60:
minutes += 1
seconds -= 60
return "%02d:%02d:%02d" % (hours, minutes, seconds)
@staticmethod
def progress(done, length):
"""
Diplay a progress message
"""
timeNow = time.time()
timeElapsed = timeNow - ui._progressData["start"]
avgSpeed = done * 1.0 / timeElapsed
timeLast = ui._progressData["last"]
speed = (done - ui._progressData["data"]) * 1.0 / (timeNow - timeLast)
ui._progressData["last"] = time.time()
ui._progressData["data"] = done
if length > 0:
pdone = done * 1.0 / length
timeToGo = 0
if pdone > 0:
timeToGo = (timeElapsed / pdone) - timeElapsed
info = " %02d%% %s/%s %8s/s %s" % (pdone * 100, ui._formatSize(done),
ui._formatSize(length), ui._formatSize(speed),
ui._formatTime(timeToGo))
if sys.stdout.isatty():
if ui._progressData["lastDsp"] + 0.5 > timeNow:
return
ui._progressData["lastDsp"] = timeNow
print "\033[2K\r", # Erase line
if length > 0:
barWidth = ui._getTerminalWidth() - len(info) - 5 - 2
barFilled = int(barWidth * pdone)
bar = ""
if barFilled > 0:
bar = "-" * (barFilled - 1) + ">"
bar += " " * (barWidth - len(bar))
bar = "[%s]" % bar
print " %s%s" % (bar, info),
else:
print " %s downloaded, %8s/s" % (ui._formatSize(done),
ui._formatSize(speed)),
else:
if ui._progressData["lastDsp"] + 5 < timeNow:
ui._progressData["lastDsp"] = timeNow
if length > 0:
print info
else:
print " %s downloaded, %8s/s" % (ui._formatSize(done),
ui._formatSize(speed))
sys.stdout.flush()
@staticmethod
def _gt(color):
"""
Return a colored ">>>" string
"""
if sys.stdout.isatty():
return "%s>>>%s" % (ui._COLOR[color], ui._COLOR["def"])
else:
return ">>>"
@staticmethod
def error(message):
"""
Output error message
"""
print >> sys.stderr, ui._gt("error"), message
@staticmethod
def info(message, type=1):
"""
Output info message
Don't use the type parameter, it's meant for use in
this script's main function only!
"""
if type == 1:
print ui._gt("info"), message
else:
print ui._gt("info2"), message
@staticmethod
def warn(message):
"""
Output warning message
"""
print ui._gt("warn"), message
@staticmethod
def wait(message, seconds):
"""
Wait for something. Message should contain a %d (which
will be replaced by the remaining seconds)
"""
if sys.stdout.isatty():
while seconds > 0:
print "\033[2K\r", # Erase line
print ui._gt("warn"), message % seconds,
sys.stdout.flush()
seconds -= 1
time.sleep(1)
print "\033[2K\r", # Erase line
else:
print ui._gt("warn"), message % seconds
sys.stdout.flush()
while seconds > 0:
seconds -= 1
time.sleep(1)
sys.stdout.flush()
@staticmethod
def getCaptcha(url, caller=None):
"""
Decipher the captcha from the given URL.
Will execute the function captchaHook or, if it fails,
display a GTK+ dialog, asking for the code (with
console / imagemagick as a fallback)
"""
try:
request = urllib2.urlopen(url)
data = request.read()
except:
ui.error("Failed to load captcha ")
return False
# Try hook first
response = captchaHook(data, caller)
if response:
return response
# Then try GTK+
try:
import gtk
loader = gtk.gdk.PixbufLoader()
try:
loader.write(data)
loader.close()
except:
ui.error("Failed to load captcha ")
return False
dialog = gtk.Dialog(u"Get captcha", buttons=(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
image = gtk.Image()
image.set_from_pixbuf(loader.get_pixbuf())
dialog.vbox.add(image)
entry = gtk.Entry()
def returnOnReturn(widget, event):
if event.keyval == gtk.keysyms.Return:
dialog.response(gtk.RESPONSE_ACCEPT)
entry.connect("key-press-event", returnOnReturn)
dialog.vbox.add(entry)
dialog.show_all()
dialog.run()
dialog.hide()
gtk.main_iteration()
gtk.main_iteration()
if entry.get_text() == "":
return False
return entry.get_text()
except:
return False
# Try console finally
ui.info("Please enter the captcha from the following image")
display = os.popen("display -", "w")
display.write(data)
display.close()
return raw_input(" Captcha: ").strip()
class handler(object):
HANDLER_WAS_REDIRECTED = 2 ** 0
options = {} # Will be set by __main__
NAME = "Base handler"
@staticmethod
def canHandle(url):
"""
Return if this handler is able to handle
this url
"""
pass
@staticmethod
def handle(url):
"""
Handles an URL
May append files to the global download list
Returns either
- True: Successful download
- False: Download failed
- bool, bitmask:
Additional information, see constants above
"""
pass
def matchGet(rex, string):
"""
Match regular expresion rex on string
Returns
- False if rex does not match anywhere in string
- The matched part of string if rex does not contain
parentheses
- The first group if only one group exists
- A touple with all group values elsewise
"""
match = re.search(rex, string)
if match:
if len(match.groups()) == 0:
return string[match.span()[0]:match.span()[1]]
if len(match.groups()) == 1:
return match.groups()[0]
else:
return match.groups()
return False
class WouldDispositException(Exception):
pass
def GET(url):
"""
Place a GET request on URL, return data
"""
try:
request = urllib2.urlopen(url)
if "Content-Disposition" in request.info():
raise WouldDispositException()
return request.read()
except WouldDispositException:
raise WouldDispositException()
except:
ui.error("Failed to download %s" % url)
return False
def POST(url, data):
"""
Place a POST request with data on URL,
return data
"""
try:
return urllib2.urlopen(url, data).read()
except:
ui.error("Failed to download %s" % url)
return False
def addDownload(url, redirected=False):
"""
Add a download to the download list
"""
global fileList
fileList.insert(0, url)
if not redirected:
ui.info("Added new download %s" % url)
def download(url, postData = None, targetFileName = None):
"""
Download url to targetFileName (will be extracted from url /
the content-disposition header if omitted)
Returns False on failure and the file name elsewise.
"""
try:
if postData:
request = urllib2.urlopen(url, postData)
else:
request = urllib2.urlopen(url)
if not targetFileName and "Content-disposition" in request.info():
dispositionHeader = request.info()["Content-disposition"]
targetFileName = matchGet("filename=(.)(.+)\\1$", dispositionHeader)
if targetFileName:
targetFileName = targetFileName[1]
if not targetFileName:
targetFileName = os.path.basename(request.geturl())
targetFileName = impFilename(targetFileName)
if "Content-Length" in request.info():
length = int(request.info()["Content-Length"])
else:
length = 0
displayDone = 0
done = 0
ui.info("Downloading %s to %s" % (url, targetFileName))
targetFile = open(targetFileName, "w")
ui.startProgress()
while True:
data = request.read(1024 * 5)
if not data:
break
targetFile.write(data)
done += len(data)
ui.progress(done, length)
ui.endProgress()
ui.info("Download complete")
targetFile.close()
return targetFileName
except:
try:
if os.access(targetFileName, os.F_OK):
os.unlink(targetFileName)
except:
pass
print
ui.error("Download failed: %s" % sys.exc_info()[1])
return False
def impFilename(fileName):
"""
Return fileName or, if this file does already exists,
fileName~nnn.
"""
i = 0
if os.access(fileName, os.F_OK):
fileName = "%s~%%d" % fileName
while os.access(fileName % i, os.F_OK):
i += 1
fileName = fileName % i
return fileName
def getFileSize(name):
return os.stat(name)[6]
def htmlEntityDecode(text):
"""
Decode HTML entities
"""
def entSubst(arg):
if arg.group(1) == "#":
return unichr(int(arg.group(2)))
else:
cp = name2codepoint.get(arg.group(2))
if cp:
cp = unichr(cp)
else:
cp = arg.group(2)
return cp
return re.sub("&(#?)(\d{1,5}|\w{1,8});", entSubst, text)
def getScriptPath():
return os.path.abspath(os.path.dirname(sys.argv[0]))
class letItBitNet(handler):
NAME = "letitbit.net"
@staticmethod
def canHandle(url):
return matchGet("^http://(?:www\.)?letitbit.net/download/", url) != False
@staticmethod
def handle(url):
data = GET(url)
form = {}
form["uid"] = matchGet('name="uid" value="([^"]{13}[^"]+)"', data)
form["frameset"] = "Download file"
form["fix"] = 1
data = POST("http://letitbit.net/download3.php", urllib.urlencode(form))
url2 = matchGet('src="(/tmpl/tmpl_frame_top[^"]+)', data)
if not url2:
ui.error("Page syntax error")
return False
data = GET('http://letitbit.net%s' % url2)
downloadUrl = matchGet(
'<a href="(http://[a-z0-9]+\.letitbit.net/download[0-9]+/[^<"]+)"', data)
if not downloadUrl:
ui.error("Failed to get download url")
return False
wait = matchGet('name="errt">([0-9]+)<', data)
if wait:
ui.wait("Waiting %d seconds for download", int(wait))
return download(downloadUrl)
class filesAg(handler):
NAME = "files.ag"
@staticmethod
def canHandle(url):
return matchGet("^http://(?:www\.)?files.ag/files/[0-9]+/.+", url) != False
@staticmethod
def handle(url):
data = POST(url, "start=Free")
downloadUrl = matchGet('action="([^"]+)"', data)
if not downloadUrl:
ui.error("Failed to get download url")
return False
wait = matchGet('download-timeout">([^<]+)<', data)
if wait:
ui.wait("Waiting %d seconds for download slot", int(wait))
return download("http://files.ag" + downloadUrl)
class anonymTo(handler):
NAME = "Anonym.To Redirector"
@staticmethod
def canHandle(url):
return matchGet("^http://(?:www\.)?anonym.to", url) != False
@staticmethod
def handle(url):
match = matchGet("^http://(?:www\.)?anonym.to/\?(.+)$", url)
if match:
addDownload(urllib.unquote(match), True)
return True, handler.HANDLER_WAS_REDIRECTED
return False
class depositfilesCom(handler):
NAME = "depositfiles.com"
@staticmethod
def canHandle(url):
return matchGet("^http://(?:www\.)?depositfiles.com", url) != False
@staticmethod
def handle(url):
data = GET(url)
target = matchGet('<form[^>]+action="(.+)" [^>]+ id="gateway_form"', data)
if not target:
ui.error('Failed to get download form')
return False
data = POST("http://depositfiles.com" + target, "gateway_result=1")
wait = int(matchGet('id="download_waiter_remain">([^<]+)<\/', data))
formData = {}
for field in ( "file_password", "gateway_result", "icid", "go" ):
formData[field] = matchGet('name="%s" value="([^"]+)"' % field, data)
if formData[field] == None:
ui.error("Failed to get download field '%s'" % field)
return False
if matchGet("var img_code_url = '([^']+)'", data):
captcha = "http://depositfiles.com" + matchGet("var img_code_url = '([^']+)'", data) + "&rnd=1211011667"
formData["img_code"] = ui.getCaptcha(captcha, "depositfilesCom")
ui.wait("Waiting %d seconds for download", wait + 2)
alt = matchGet('dwnsrc = "([^"]+)"', data)
if alt:
return download(alt)
else:
return download("http://depositfiles.com" + target, urllib.urlencode(formData))
class binloadTo(handler):
NAME = "binload.to"
@staticmethod
def canHandle(url):
return matchGet("^http://(www\.)?binload.to/file/[a-z0-9]+", url) != False
@staticmethod
def handle(url):
data = GET(url)
if not data:
ui.error("Failed to load %s" % url)
return False
urlData = matchGet('action="(http://[^.]+.binload.to/download.php[^"]+)"', data)
dlSession = matchGet('dlSession"\s+value="([^"]+)"', data)
fileName = matchGet('Download: (.+?)<\/h3>', data)
if not urlData or not fileName or not dlSession:
ui.error("Failed to get download link from binload.to page")
return False
wait = matchGet('cdLength = ([0-9]+)', data)
if wait:
# Ugly but needed - netload adds some time to the time given in the JS oO
ui.wait("Waiting %d seconds for download ticket.", int(wait) * 2)
postData = "dlSession=%s&down=Download&login_nickname=&login_passwort=" % dlSession
downloadedFile = download(urlData, postData, fileName)
if not downloadedFile:
return False
if getFileSize(downloadedFile) < 1024 ** 2:
data = open(downloadedFile).read()
msg = matchGet('^<script[^(]+\("([^"]+)"\);', data)
if msg:
ui.error("Error while downloading: %s" % msg)
os.unlink(downloadedFile)
return False
return True
class fastloadNet(handler):
NAME = "fast-load.net"
@staticmethod
def canHandle(url):
return matchGet("^http://(www\.)?fast-load.net/", url) != False
@staticmethod
def handle(url):
data = GET(url)
if not data:
ui.error("Failed to load %s" % url)
return False
fid = matchGet('name="fid"\s+value="([^"]+)"', data)
file = matchGet('<font style="font-color:grey; font-size:8pt;">([^<]+)<\/font>', data)
if not fid:
ui.error("Failed to get download link")
return False
captcha = ui.getCaptcha("http://www.fast-load.net//includes/captcha.php", "fastloadNet")
if not captcha:
return False
downloadedFile = download("http://www.fast-load.net//download.php", "fid=%s&captcha_code=%s" % (fid, captcha), file)
if not downloadedFile:
return False
if getFileSize(downloadedFile) < 1024 ** 2:
data = open(downloadedFile).read()
msg = matchGet('^wrong captcha', data)
ui.error("Wrong captcha")
return False
return True
class datenschleuderCC(handler):
NAME = "datenschleuder.cc Redirector"
@staticmethod
def canHandle(url):
return matchGet("^http://(?:www\.)?datenschleuder.cc", url) != False
@staticmethod
def handle(url):
data = GET(url)
if not data:
ui.error("Failed to load %s" % url)
return False
if handler.options.prefer == "rapidshare":
mirror = "rapidshare"
dlUrl = 'http://rapidshare.com/[^"]+'
elif handler.options.prefer == "uploaded.to":
mirror = "uploaded"
dlUrl = 'http://(?:www\.)?uploaded.to/[^"]+'
elif handler.options.prefer == "netload.in":
mirror = "netload"
dlUrl = 'http://netload.in/[^"]+'
redir = matchGet('http://www.datenschleuder.cc/redir.php\?\S+mirror=%s[^"]+' % mirror,
data)
if not redir:
ui.error("Failed to get download frame link")
return False
data = GET(redir)
if not data:
ui.error("Failed to load %s" % redir)
return False
redir = matchGet(dlUrl, data)
if not redir:
ui.error("Failed to get download link")
return False
addDownload(redir)
return True, handler.HANDLER_WAS_REDIRECTED
class freeClipsCh(handler):
NAME = "free-clips.ch Redirector"
@staticmethod
def canHandle(url):
return matchGet("^http://(?:www.)?free-clips.ch/", url) != False
@staticmethod
def handle(url):
data = GET(url)
links = matchGet('<textarea name="links" id="links" '
'readonly="readonly">([^<]+)<\/textarea>', data)
if not links:
ui.error("Failed to get download links")
for link in links.split("\n"):
addDownload(htmlEntityDecode(link.strip()))
if links:
return True, handler.HANDLER_WAS_REDIRECTED
else:
return False
class linkSafeToClan(handler):
NAME = "link-safe.to-clan.de Redirector"
@staticmethod
def canHandle(url):
return matchGet("^http://(?:www.)?link-safe.to-clan.de/", url) != False
@staticmethod
def handle(url):
data = GET(url)
iframe = matchGet('<iframe[^>]+src="([^"]+)"', data)
if not iframe:
ui.error("Failed to get linked page")
return False
addDownload(iframe, True)
return True, handler.HANDLER_WAS_REDIRECTED
class linkedMoney(handler):
NAME = "linkedmoney.com Redirector"
@staticmethod
def canHandle(url):
return matchGet("^http://(?:www\.)?linkedmoney.com", url) != False
@staticmethod
def handle(url):
data = GET(url)
url = matchGet('<iframe id="linkedmoney_frame"[^>]+src="([^"]+)"', data)
if url:
addDownload(htmlEntityDecode(url), True)
return True, handler.HANDLER_WAS_REDIRECTED
return False
class megauploadCom(handler):
NAME = "megaupload.com"
@staticmethod
def canHandle(url):
return matchGet("^http://(www\.)?megaupload.com", url) != False
@staticmethod
def handle(url):
data = GET(url)
if not data:
ui.error("Failed to load %s" % url)
return False
formFields = {}
for field in [ "d", "imagecode", "megavar" ]:
formFields[field] = matchGet('name="%s"\s+value="([^"]+)"' % field, data)
if not formFields[field]:
ui.error("Failed to get field %s from page" % field)
return False
fileName = matchGet("<b>(?:Dateiname|Filename):</b>\s*(.*?)<", data)
captchaURL = matchGet('src="(/capgen.php[^"]+)"', data)
formFields["imagestring"] = ui.getCaptcha("http://www.megaupload.com/" + captchaURL,
"megaupload")
if not formFields["imagestring"]:
ui.error("Failed to get captcha")
return False
data = POST("http://www.megaupload.com/", urllib.urlencode(formFields))
field1 = matchGet("var . = String.fromCharCode\(Math.abs\(([-0-9]+)", data)
field2 = matchGet("var . = '(.)' \+ String.fromCharCode\(Math.sqrt\(([0-9]+)", data)
durl = matchGet('href="(http://www[0-9]+\.megaupload.com/[^\'"]+)\'[^\'"]+\'([^"]+)"',
data)
try:
durl = durl[0] + field2[0] + chr(int(int(field2[1]) ** 0.5)) + \
chr(abs(int(field1))) + durl[1]
except:
ui.error("Failed to reconstruct download URL")
ui.warn("Either the page changed it's design or you entered the captcha wrong")
return False
ui.wait("Waiting %2d seconds for download ticket", 45)
return download(durl, targetFileName=fileName) != False
class netfolderIn(handler):
NAME = "netfolder.in Redirector"
@staticmethod
def canHandle(url):
return matchGet("^http://(?:www.)?netfolder.in/", url) != False
@staticmethod
def handle(url):
data = GET(url)
if not data:
ui.error("Failed to load %s" % url)
return False
urls = map(htmlEntityDecode, re.findall('href="(http://netload.in/[^"]+)', data))
if urls:
for url in urls:
addDownload(url)
return True, handler.HANDLER_WAS_REDIRECTED
else:
return False
class netloadIn(handler):
NAME = "netload.in"
USED_BEFORE = False
@staticmethod
def canHandle(url):
return matchGet("^http://(?:www.)?netload.in/", url) != False
@staticmethod
def handle(url):
if netloadIn.USED_BEFORE == True:
restartRouter()
netloadIn.USED_BEFORE = False
data = GET(url)
if not data:
ui.error("Failed to load %s" % url)
return False
# Step 1: Get captcha page
nurl = matchGet('href="(index.php\?[^"]+captcha=1)"', data)
if nurl:
if not nurl:
ui.error("Failed to get captcha page url")
return False
nurl = "http://netload.in/" + htmlEntityDecode(nurl)
data = GET(nurl)
if not data:
ui.error("Failed to load %s" % nurl)
return False
# Step 2: Get captcha
curl = matchGet('src="(share/includes/captcha.php[^"]+)"', data)
if not curl:
ui.error("Failed to get captcha url")
return False
captcha = ui.getCaptcha("http://netload.in/" + htmlEntityDecode(curl), "netload")
if not captcha:
ui.error("Failed to get captcha")
return False
# Step 3: Countdown
wait = matchGet("countdown\(([0-9]+)", data)
# Step 4: Door page
faction = matchGet('action="(index.php\?[^"]+)"', data)
fileId = matchGet('name="file_id"[^>]+value="([^"]+)"', data)
if not faction or not fileId:
ui.error("Failed to get download form data")
return False
faction = "http://netload.in/" + urllib2.unquote(faction)
postData = "file_id=%s&captcha_check=%s&start=" % (fileId, urllib.quote(captcha))
data = POST(faction, postData)
# Step 5: Countdown
wait = matchGet("countdown\(([0-9]+)", data)
if wait:
ui.wait("Waiting %2d seconds for download ticket.", int(wait) / 100)
# Step 6: Download
downloadUrl = matchGet('class="Orange_Link"\s+href="([^"]+)"', data)
if not downloadUrl:
ui.error("Failed to get download url.")
ui.warn("Did you enter the correct captcha code?!")
ui.warn("Consider restarting your router")
return False
netloadIn.USED_BEFORE = True
return download(htmlEntityDecode(downloadUrl)) != False
class rapidShare(handler):
NAME = "Rapidshare"
USED_BEFORE = False
@staticmethod
def canHandle(url):
return matchGet("^http://(?:www\.|rs[0-9]+\.)?rapidshare.com", url) != False
@staticmethod
def handle(url):
try:
data = GET(url)
except WouldDispositException:
ui.info("Direct download")
file = download(url)
return file
if "The uploader has removed this file from the server" in data:
ui.error("The uploader has removed this file from the server")
return False
url = matchGet('<form[^>]+action="([^"]+)', data)
if not url:
ui.error("Failed to get download page url")
return False
data = POST(url, "dl.start=Free")
if "You have reached the limit for Free users" in data:
time = matchGet('you can wait ([0-9]+) minutes', data)
ui.warn("You'd have to wait %s minutes" % time)
ui.warn("Download limit reached. Restarting router.")
if not restartRouter():
ui.warn("Router restart failed.")
ui.wait("Waiting %d seconds", int(time) * 60)
return rapidShare.handle(url)
if "Download your file without security questions" in data:
ui.info("Happy hour!")
postData = "actionstring=1"
else:
seconds = matchGet('var c=([0-9]+)', data)
if not seconds:
ui.error("Failed to get security data from page")
return False
import time
seconds = time.time() + int(seconds)
captchaUrl = matchGet('<img src="([^"]+access[^"]+)"', data)
if not captchaUrl:
ui.info("Happy hour?")
if seconds - time.time() > 0:
ui.wait("Waiting %d seconds for download", seconds - time.time())
postData = ""
else:
captchaUrl = re.sub("'\s+\+\s+'", "", captchaUrl)
if seconds - time.time() > 0:
ui.wait("Waiting %d seconds for download", seconds - time.time())
captcha = ui.getCaptcha(captchaUrl, "rapidshare")
postData = "accesscode=%s" % captcha
dlTarget = matchGet('<form[^>]+name="dlf?" action="([^"]+)', data)
file = download(dlTarget, postData)
if file and getFileSize(file) < 10*1024:
content = open(file).read()
if "Wrong access code" in content:
os.unlink(file)
ui.warn("Captcha code wrong")
return rapidShare.handle(url)
return file
class rapidLayerIn(handler):
NAME = "Rapidlayer.In Redirector"
@staticmethod
def canHandle(url):
return matchGet("^http://(?:www\.)?rapidlayer.in", url) != False
@staticmethod
def handle(url):
data = GET(url)
if not data:
ui.error("Failed to download %s" % url)
return False
urlEncoded = matchGet('}[a-z]="([^"]+)"', data)
sub = matchGet("([a-z])=\\1-([0-9]+)", data)
if not sub:
return False
sub = int(sub[1])
def decode(schar):
char = ord(schar)
if char < 128:
char -= sub
if char < 32:
char = 127 + (char - 32)
return chr(char)
url = "".join(map(decode, urlEncoded))
if url:
url = htmlEntityDecode(url)
addDownload(urllib.unquote(url), True)
return True, handler.HANDLER_WAS_REDIRECTED
return False
class relinkUs(handler):
NAME = "Relink.us Redirector"
@staticmethod
def canHandle(url):
return matchGet("^http://(?:www\.)?relink.us", url) != False
@staticmethod
def handle(url):
data = GET(url)
links = re.findall("action='(go.php[^']+)", data)
if not links:
return False
for link in links:
data = POST("http://relink.us/" + link, "")
nurl = matchGet('<iframe[^>]+src="([^"]+)"', data)
if nurl:
addDownload(nurl, True)
else:
ui.error("Failed to get URL for at least one file: %s" % nurl)
return True, handler.HANDLER_WAS_REDIRECTED
class securedIn(handler):
NAME = "Secured.In Redirector"
@staticmethod
def canHandle(url):
try:
import gtkmozembed
hasEmbed = True
except:
hasEmbed = False
ok = matchGet("^http://(?:www\.)?secured.in", url) != False
if ok and hasEmbed:
return True
elif ok:
ui.error("You need gtkmozembed (gnome-python extras) for this to work")
return False
@staticmethod
def handle(url):
data = GET(url)
if not data:
ui.error("Failed to download %s" % url)
return False
captchaUrl = matchGet('src="(captcha-[^"]+.jpg)"', data)
captchaHash = matchGet('id="captcha_hash"[^>]+value="([^"]+)"', data)
if not captchaUrl or not captchaHash:
ui.error("Failed to get captcha url")
return False
captcha = ui.getCaptcha("http://secured.in/" + captchaUrl, "secured.in")
if not captcha:
ui.error("Failed to get captcha")
return False
postData = "captcha_key=%s&captcha_hash=%s" % (urllib.quote(captcha), captchaHash)
data = POST(url, postData)
if not data:
ui.error("Failed to download %s" % url)
return False
dlIds = re.findall("accessDownload\([0-9]+, [0-9]+, '([^']+)'", data)
if not dlIds:
ui.error("Captcha code wrong")
return False
for dlId in dlIds:
data = POST("http://secured.in/ajax-handler.php",
"cmd=download&download_id=%s" % dlId)
if data == "error":
ui.error("Failed to download dl id %s" % dlId)
continue
# Call decipher
# Debian has problems here, execute
# export LD_LIBRARY_PATH=/usr/lib/firefox
# export MOZILLA_FIVE_HOME=/usr/lib/firefox
# to fix them
import gtkmozembed
import gtk
moz = gtkmozembed.MozEmbed()
win = gtk.Window()
win.add(moz)
win.show_all()
data = ('<script src="http://secured.in/scripts/cypher.js"></script>' +
'<script>b=%r;' % data +
'document.title=cypher(b);</script>')
moz.render_data(data, long(len(data)), 'file:///', 'text/html')
moz.connect("title",