microproduct/atmosphericDelay/ISCEApp/site-packages/wx/tools/wxget.py

255 lines
8.5 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#----------------------------------------------------------------------
# Name: wx.tools.wxget
# Purpose: wx Based alternative to wget
#
# Author: Steve Barnes
#
# Created: 06-Aug-2017
# Copyright: (c) 2017-2018 by Steve Barnes
# Licence: wxWindows license
# Tags: phoenix-port, py3-port
#
# Module to allow cross platform downloads originally from answers to:
# https://stackoverflow.com/questions/22676/how-do-i-download-a-file-over-http-using-python
# by Stan and PabloG then converted to wx.
#----------------------------------------------------------------------
"""
wxget.py -- wx Version of wget utility for platform that don't have it already.
Usage:
wxget URL [DEST_DIR]
Where URL is a file URL and the optional DEST_DIR is a destination directory to
download to, (default is to prompt the user).
The --trusted option can be used to surpress certificate checks.
"""
from __future__ import (division, absolute_import, print_function, unicode_literals)
import sys
import os
import wx
import subprocess
import ssl
import pip
if sys.version_info >= (3,):
from urllib.error import (HTTPError, URLError)
import urllib.request as urllib2
import urllib.parse as urlparse
else:
import urllib2
from urllib2 import (HTTPError, URLError)
import urlparse
def get_docs_demo_url(demo=False):
""" Get the URL for the docs or demo."""
if demo:
pkg = 'demo'
else:
pkg = 'docs'
base_url = "https://extras.wxpython.org/wxPython4/extras/%s/wxPython-%s-%s.tar.gz"
ver = wx.version().split(' ')[0]
major = ver.split('.')[0]
if major != '4':
raise ValueError("wx Versions before 4 not supported!")
return base_url % (ver, pkg, ver)
def get_save_path(url, dest_dir, force=False):
""" Get the file save location."""
old_dir = os.getcwd()
if not dest_dir:
dest_dir = os.getcwd()
else:
if not os.path.exists(dest_dir):
os.makedirs(dest_dir)
os.chdir(dest_dir)
filename = os.path.basename(urlparse.urlsplit(url)[2])
if not filename:
filename = 'downloaded.file'
if not force:
with wx.FileDialog(
None, message="Save As ...", defaultDir=dest_dir,
defaultFile=filename, style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT
) as dlg:
if dlg.ShowModal() == wx.ID_OK:
dest_dir, filename = os.path.split(dlg.GetPath())
else:
url = None
else:
if not os.path.exists(dest_dir):
os.makedirs(dest_dir)
elif not os.path.isdir(dest_dir):
url = None
if dest_dir:
filename = os.path.join(dest_dir, filename)
os.chdir(old_dir)
return (url, filename)
def download_wget(url, filename, trusted=False):
""" Try to donwload via wget."""
result = False
try:
cmd = ["wget", url, '-O', filename]
if trusted:
cmd.append('--no-check-certificate')
print("Trying:\n ", ' '.join(cmd))
result = subprocess.check_call(cmd)
# note some users may need to add "--no-check-certificate" on some sites
result = result == 0
except Exception:
print("wget did not work or not installed - trying urllib")
return result
def download_urllib(url, filename):
""" Try to donwload via urllib."""
print("Trying to Download via urllib from:\n ", url)
keep_going = True
try:
url_res = urllib2.urlopen(url)
except (HTTPError, URLError, ssl.CertificateError) as err:
print("Error: %s" % err)
return False
with open(filename, 'wb') as outfile:
block_sz = 8192
meta = url_res.info()
meta_func = meta.getheaders if hasattr(meta, 'getheaders') else meta.get_all
meta_length = meta_func("Content-Length")
file_size = None
if meta_length:
file_size = int(meta_length[0])
message = "Downloading: {0}\nBytes: {1}\n".format(url, file_size)
dstyle = wx.PD_APP_MODAL | wx.PD_CAN_ABORT | wx.PD_AUTO_HIDE
if file_size:
progress = wx.ProgressDialog('Downloading', message,
maximum=1+file_size/block_sz, style=dstyle)
else:
progress = wx.ProgressDialog('Downloading', message, style=dstyle)
file_size_dl = 0
while keep_going:
read_buffer = url_res.read(block_sz)
if not read_buffer:
progress.Update(file_size_dl / block_sz, "message+\nDONE!")
wx.Sleep(0.2)
break
file_size_dl += len(read_buffer)
outfile.write(read_buffer)
status = "{0:16}".format(file_size_dl)
if file_size:
status += " [{0:6.2f}%]".format(file_size_dl * 100 / file_size)
(keep_going, dummy_skip) = progress.Update(file_size_dl / block_sz,
message+status)
wx.Sleep(0.08) # Give the GUI some update time
progress.Destroy()
result = os.path.exists(filename) and os.stat(filename).st_size > 0
return result
def download_pip(url, filename, force=False, trusted=False):
""" Try to donwload via pip."""
download_dir = os.path.split(filename)[0]
if len(download_dir) == 0:
download_dir = '.'
print("Trying to use pip to download From:\n ", url, 'To:\n ', filename)
cmds = ['pip', 'download', url, '--dest', download_dir, "--no-deps",
'--exists-action', 'i']
if force:
cmds.append('--no-cache-dir')
if trusted:
host = '/'.join(url.split('/')[:3]) # take up to http://something/ as host
cmds.extend(['--trusted-host', host])
if force and os.path.exists(filename):
print("Delete Existing", filename)
os.unlink(filename)
print("Running pip", ' '.join(cmds))
try:
print("\nAbusing pip so expect possible error(s) in the next few lines.")
result = subprocess.check_call(cmds)
print(result)
except (FileNotFoundError, subprocess.CalledProcessError) as Error:
print("Download via pip may have Failed!")
print(Error)
result = 0
result = os.path.exists(filename) and os.stat(filename).st_size > 0
return result
def download_file(url, dest=None, force=False, trusted=False):
"""
Download and save a file specified by url to dest directory, with force will
operate silently and overwrite any existing file.
"""
url, filename = get_save_path(url, dest, force)
keep_going = True
success = False
if url is None:
return 'Aborted!'
if url:
success = download_wget(url, filename, trusted) # Try wget
if not success:
success = download_urllib(url, filename) # Try urllib
if not success:
success = download_pip(url, filename, force, trusted) # Try urllib
if not success:
split_url = url.split('/')
msg = '\n'.join([
"\n\nERROR in Web Access! - You may be behind a firewall!",
"-" * 52,
"You should be able to bybass this by using a browser to download:",
"\t%s\nfrom:\t%s\nthen copying the download file to:\n\t%s" % (
split_url[-1], '/'.join(split_url[:-1]), filename),
])
print(msg, '\n')
wx.MessageBox(msg, caption='WDOWNLOAD ERROR!',
style=wx.OK|wx.CENTRE|wx.ICON_ERROR)
return "FAILURE or Abort!"
return filename
def main(args=sys.argv):
""" Entry point for wxget."""
APP = wx.App()
dest_dir = '.'
force_flag = '--force'
trusted_flag = '--trusted'
force = False
trusted = False
if force_flag in args:
force = True
args.remove(force_flag)
if trusted_flag in args:
trusted = True
args.remove(force_flag)
if len(args) > 2:
dest_dir = args[2]
else:
dest_dir = None
if len(args) > 1:
url = args[1]
else:
print(__doc__)
yes_no = wx.MessageBox(__doc__+"\n\nRUN TEST?", "wxget",
wx.YES_NO|wx.CENTER)
if yes_no == wx.YES:
print("Testing with wxDemo")
url = get_docs_demo_url()
else:
url = None
if url:
FILENAME = download_file(url=url, dest=dest_dir, force=force, trusted=trusted)
print(FILENAME)
if __name__ == "__main__": # Only run if this file is called directly
main()