Skip to content

Instantly share code, notes, and snippets.

@pudquick
Last active June 30, 2021 21:57
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save pudquick/5562741 to your computer and use it in GitHub Desktop.
Save pudquick/5562741 to your computer and use it in GitHub Desktop.
import os.path, sys, os, SimpleHTTPServer, SocketServer, clipboard, webbrowser, shutil, zipfile, console
__mega_acct__ = 'yourname@example.com'
__mega_pass__ = 'passwordhere'
def _unzip(a_zip=None, path='.', altpath='unzipped'):
if a_zip is None:
return
filename = os.path.abspath(a_zip)
if not os.path.isfile(filename):
return
# PK magic marker check
f = open(filename, 'rb')
try:
pk_check = f.read(2)
except Exception:
pk_check = ''
finally:
f.close()
if pk_check != 'PK':
print "unzip: %s: does not appear to be a zip file" % a_zip
else:
altpath = os.path.join(os.path.dirname(filename), altpath)
location = os.path.abspath(altpath)
if not os.path.exists(location):
os.makedirs(location)
zipfp = open(filename, 'rb')
try:
zipf = zipfile.ZipFile(zipfp)
# check for a leading directory common to all files and remove it
dirnames = [os.path.join(os.path.dirname(x), '') for x in zipf.namelist()]
common_dir = os.path.commonprefix(dirnames or ['/'])
# Check to make sure there aren't 2 or more sub directories with the same prefix
if not common_dir.endswith('/'):
common_dir = os.path.join(os.path.dirname(common_dir), '')
for name in zipf.namelist():
data = zipf.read(name)
fn = name
if common_dir:
if fn.startswith(common_dir):
fn = fn.split(common_dir, 1)[-1]
elif fn.startswith('/' + common_dir):
fn = fn.split('/' + common_dir, 1)[-1]
fn = fn.lstrip('/')
fn = os.path.join(location, fn)
dirf = os.path.dirname(fn)
if not os.path.exists(dirf):
os.makedirs(dirf)
if fn.endswith('/'):
# A directory
if not os.path.exists(fn):
os.makedirs(fn)
else:
fp = open(fn, 'wb')
try:
fp.write(data)
finally:
fp.close()
except Exception:
zipfp.close()
print "unzip: %s: zip file is corrupt" % a_zip
return
zipfp.close()
return os.path.abspath(location)
def req12_setup():
import requests as old_req
relative_dir = os.path.abspath(os.path.dirname(__file__))
curdir = os.getcwd()
os.chdir(relative_dir)
print '!!! requests-1.2.0 not installed, downloading rev.d06908d ...'
zip_url = 'https://github.com/kennethreitz/requests/archive/v1.2.0.zip'
print ' * Downloading: requests_1.2.0.zip (565KB)...'
f = open('requests_1.2.0.zip', 'wb')
try:
f.write(old_req.get(zip_url).content)
except Exception:
sys.exc_clear()
f.close()
# Unload built-in requests module
del old_req
print "!!! zip downloaded, extracting ..."
try:
shutil.rmtree('requests_zip', ignore_errors=True)
except Exception:
sys.exc_clear()
_ = _unzip('requests_1.2.0.zip', altpath='requests_zip')
print "!!! Extraction complete, re-arranging ..."
try:
shutil.rmtree('requests_1_2', ignore_errors=True)
except Exception:
sys.exc_clear()
os.rename('requests_zip/requests', 'requests_1_2')
print "!!! Re-arranging complete, cleaning up ..."
try:
os.remove('requests_1.2.0.zip')
shutil.rmtree('requests_zip', ignore_errors=True)
except Exception:
sys.exc_clear()
os.chdir(curdir)
def mega_setup():
print '!!! richardasaurus/mega.py not installed, downloading rev.878f095056 ...'
base_git = 'https://raw.github.com/richardasaurus/mega.py/878f095056b31d5f675aa96fecb59ffcaa180143/mega/'
relative_dir = os.path.abspath(os.path.dirname(__file__))
# Change directory to the one containing this script
curdir = os.getcwd()
os.chdir(relative_dir)
if not os.path.exists('mega'):
os.makedirs('mega')
os.chdir('mega')
for fname in ['__init__.py', 'crypto.py', 'errors.py', 'mega.py']:
print ' * Downloading: ', fname, '...'
f = open(fname, 'wb')
try:
f.write(requests.get(base_git + fname).content)
except Exception:
sys.exc_clear()
f.close()
print "!!! Complete, attempting to import again ..."
os.chdir(curdir)
def mega_patch():
# Need to patch mega to use requests_1_2
relative_dir = os.path.abspath(os.path.dirname(__file__))
curdir = os.getcwd()
os.chdir(relative_dir)
f = open('mega/mega.py','r')
old_mega = f.read()
f.close()
if 'import requests\n' in old_mega:
print '!!! Patching mega/mega.py to use requests_1_2 ...'
new_mega = old_mega.replace('import requests\n', 'import requests_1_2 as requests\n')
f = open('mega/mega.py','w')
f.write(new_mega)
f.close()
os.chdir(curdir)
def sizeof_fmt(num):
for x in ['bytes','KB','MB','GB']:
if num < 1024.0 and num > -1024.0:
return "%3.1f%s" % (num, x)
num /= 1024.0
return "%3.1f%s" % (num, 'TB')
class SmarterHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
server_version = 'SimpleHTTP/0.6'
file_name = ''
file_delete = True
def do_GET(self):
if self.path.startswith('/transfer'):
self.get_transfer()
else:
f = self.send_head()
if f:
self.copyfile(f, self.wfile)
f.close()
def get_transfer(self):
global ready_to_stop
print '* Transferring to browser ...'
# Perform the actual file download
self.send_response(200)
# Content-Disposition: attachment; filename="fname.ext"
self.send_header('Content-Disposition', 'attachment; filename="%s"' % (self.file_name))
self.send_header('Content-Length', '%s' % (os.path.getsize('mega_dl/' + self.file_name)))
self.send_header('Content-Type', 'application/octet-stream')
self.end_headers()
f = open('mega_dl/' + self.file_name, 'rb')
self.copyfile(f, self.wfile)
f.close()
if self.file_delete:
os.remove('mega_dl/' + self.file_name)
print '* Download complete, file deleted.'
else:
print '* Download complete, file preserved.'
ready_to_stop = True
def log_message(self, format, *args):
return
class SmarterHTTPD(SocketServer.ThreadingTCPServer):
keep_running = True
requests_left = None
did_timeout = False
def serve_limited(self, timeout=None, max_requests=None):
global ready_to_stop
self.timeout = timeout
if max_requests is None:
self.requests_left = None
else:
self.requests_left = abs(int(max_requests))
self.keep_running = True
self.did_timeout = False
while self.keep_running:
self.handle_request()
# print "Request handled."
if self.requests_left is not None:
self.requests_left -= 1
if self.requests_left <= 0:
self.keep_running = False
# print "EXIT: HIT MAX REQUESTS"
continue
if ready_to_stop:
self.keep_running = False
# print "EXIT: TOLD TO STOP"
continue
def handle_timeout(self):
self.did_timeout = True
def release(self):
try:
self.server_close()
except Exception:
sys.exc_clear()
try:
self.socket.close()
except Exception:
sys.exc_clear()
def do_download():
# Get what's on the clipboard
try:
down_url = clipboard.get()
except Exception:
down_url = ''
# Make sure it's the right format
if not down_url.startswith('https://mega.co.nz/#'):
print '!!! Clipboard contents are not a mega URL, aborting. Please try again.'
sys.exit()
# Log in
print '* Logging into Mega ...'
mega = Mega({'verbose': True})
m = mega.login(__mega_acct__, __mega_pass__)
# Check file stats
print '* Looking up URL file details ...'
details = m.get_public_url_info(down_url)
print '* Filename:', details['name']
print '* Size:', sizeof_fmt(details['size'])
# Download
print '* Downloading ...'
if not os.path.exists('mega_dl'):
os.makedirs('mega_dl')
m.download_url(down_url, 'mega_dl')
print "Download complete."
# Interactive choices
answer = raw_input('Transfer out using Safari (for Open In ...)? [Y/n]: ')
if not answer.strip().lower() in ['', 'y', 'yes']:
# Quit here, they must be using iFunbox or something
print '* Complete.'
sys.exit()
# Delete afterwards?
answer = raw_input('Delete when complete? [Y/n]: ')
if not answer.strip().lower() in ['', 'y', 'yes']:
mega_file_delete = False
print '* Preserving file after transfer.'
else:
mega_file_delete = True
print '* Will delete file when transfer ends.'
# Prep webserver
global ready_to_stop
ready_to_stop = False
port = 8000
handler = SmarterHTTPRequestHandler
# Configure transfer settings
handler.file_name = details['name']
handler.file_delete = mega_file_delete
httpd = SmarterHTTPD(("", port), handler, False)
httpd.allow_reuse_address = True
httpd.server_bind()
httpd.server_activate()
# print "serving at port", port
download_url = 'http://localhost:8000/transfer'
download_url = download_url.replace('http://', 'safari-http://')
webbrowser.open(download_url)
# print 'OPEN: http://localhost:8000/transfer'
httpd.serve_limited(timeout=3,max_requests=4)
httpd.release()
print '* Complete.'
sys.exit()
def main():
console.clear()
global requests
# Ensure that the requests v.1.2.0 module is available
requests = None
init_tries = 3
while init_tries > 0:
try:
import requests_1_2 as requests
init_tries = 0
except:
print "!!! Init failure %s of 3 ..." % (4 - init_tries)
sys.exc_clear()
req12_setup()
init_tries -= 1
if not requests:
print '!!! Please check your network connection and try again.'
sys.exit()
global Mega
# Ensure that the mega module is available
Mega = None
init_tries = 3
while init_tries > 0:
try:
from mega import Mega
init_tries = 0
except:
print "!!! Init failure %s of 3 ..." % (4 - init_tries)
sys.exc_clear()
mega_setup()
mega_patch()
init_tries -= 1
if not Mega:
print '!!! Please check your network connection and try again.'
sys.exit()
# Begin download
do_download()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment