downloader.py 4.7 KB
Newer Older
W
wuzewu 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
from __future__ import print_function
from __future__ import division
from __future__ import print_function

import shutil
import os
import sys
import time
import hashlib
import requests
import tarfile

FLUSH_INTERVAL = 0.1
lasttime = time.time()


def progress(str, end=False):
    global lasttime
    if end:
        str += "\n"
        lasttime = 0
    if time.time() - lasttime >= FLUSH_INTERVAL:
        sys.stdout.write("\r%s" % str)
        lasttime = time.time()
        sys.stdout.flush()


class Downloader(object):
    def download_file(self,
                      url,
                      save_path,
                      save_name=None,
                      retry_limit=3,
                      print_progress=False,
                      replace=False):
        if not os.path.exists(save_path):
            os.makedirs(save_path)
        save_name = url.split('/')[-1] if save_name is None else save_name
        file_name = os.path.join(save_path, save_name)
        retry_times = 0

        if replace and os.path.exists(file_name):
            os.remove(file_name)

        while not (os.path.exists(file_name)):
            if retry_times < retry_limit:
                retry_times += 1
            else:
                tips = "Cannot download {0} within retry limit {1}".format(
                    url, retry_limit)
                return False, tips, None
            r = requests.get(url, stream=True)
            total_length = r.headers.get('content-length')

            if total_length is None:
                with open(file_name, 'wb') as f:
                    shutil.copyfileobj(r.raw, f)
            else:
                with open(file_name, 'wb') as f:
                    dl = 0
                    total_length = int(total_length)
                    starttime = time.time()
                    if print_progress:
                        print("Downloading %s" % save_name)
                    for data in r.iter_content(chunk_size=4096):
                        dl += len(data)
                        f.write(data)
                        if print_progress:
                            done = int(50 * dl / total_length)
                            progress(
                                "[%-50s] %.2f%%" %
                                ('=' * done, float(dl / total_length * 100)))
                if print_progress:
                    progress("[%-50s] %.2f%%" % ('=' * 50, 100), end=True)

        tips = "File %s download completed!" % (file_name)
        return True, tips, file_name

    def uncompress(self,
                   file,
                   dirname=None,
                   delete_file=False,
                   print_progress=False):
        dirname = os.path.dirname(file) if dirname is None else dirname
        if print_progress:
            print("Uncompress %s" % file)
        flag = "r:gz" if file.endswith("tar.gz") else "r:"
        with tarfile.open(file, flag) as tar:
            file_names = tar.getnames()
            size = len(file_names) - 1
            module_dir = os.path.join(dirname, file_names[0])
            for index, file_name in enumerate(file_names):
                if print_progress:
                    done = int(50 * float(index) / size)
                    progress("[%-50s] %.2f%%" % ('=' * done,
                                                 float(index / size * 100)))
                tar.extract(file_name, dirname)

            if print_progress:
                progress("[%-50s] %.2f%%" % ('=' * 50, 100), end=True)
        if delete_file:
            os.remove(file)

        return True, "File %s uncompress completed!" % file, module_dir

    def download_file_and_uncompress(self,
                                     url,
                                     save_path,
                                     save_name=None,
                                     retry_limit=3,
                                     delete_file=True,
                                     print_progress=False,
                                     replace=False):
        result, tips_1, file = self.download_file(
            url=url,
            save_path=save_path,
            save_name=save_name,
            retry_limit=retry_limit,
            print_progress=print_progress,
            replace=replace)
        if not result:
            return result, tips_1, file
        result, tips_2, file = self.uncompress(
            file, delete_file=delete_file, print_progress=print_progress)
        if not result:
            return result, tips_2, file
        if save_name:
            save_name = os.path.join(save_path, save_name)
            shutil.move(file, save_name)
            return result, "%s\n%s" % (tips_1, tips_2), save_name
        return result, "%s\n%s" % (tips_1, tips_2), file


downloader = Downloader()