1
import urllib.request
import urllib
import shutil
import os
import os.path
import sys
import time
import threading

class downloadFile:

    def __init__(self, downloadLink, downloadPath, onDiskName):
        self.downloadSize = urllib.request.urlopen(downloadLink).length
        self.downloadLink = downloadLink
        self.downloadPath = downloadPath
        self.onDiskName = onDiskName
        self.hardPath = os.path.join(self.downloadPath, self.onDiskName)

    def returnMode(self, returnMode = 'stats'):
        if returnMode == 'stats':
            return [self.downloadLink, self.downloadPath, self.onDiskName, self.downloadSize]
        elif returnMode == 'printedStats':
            print('self.downloadLink = ' + self.downloadLink)
            print('self.downloadPath = ' + self.downloadPath)
            print('self.onDiskName = ' + self.onDiskName)
            print('self.downloadSize = ' + self.downloadSize)
            print('self.hardPath = ' + self.hardPath)
            return [self.downloadLink, self.downloadPath, self.onDiskName, self.downloadSize, self.hardPath]

    def executeDownload(self):
        self.downloadStart = time.strftime("[%H:%M:%S] ")
        with urllib.request.urlopen(self.downloadLink) as response, open(self.hardPath, 'wb') as currentFile:
            shutil.copyfileobj(response, currentFile)
        currentFile.close()
        self.downloadEnd = time.strftime("[%H:%M:%S] ")

    def downloadStats(self):
        currentFileSize = os.path.getsize(self.hardPath)
        percentManifested = int(currentFileSize/(self.downloadSize/100))
        return [currentFileSize, percentManifested]

    def liveDownloadStats(self):
        if os.path.isfile(self.hardPath) == False:
            time.sleep(1)
        statList = self.downloadStats()
        while statList[0] < self.downloadSize:
            sys.stdout.write("\r" + self.downloadStart + " Downloading {0}... ".format(self.onDiskName) + "[{0}%]".format(statList[1]))
            sys.stdout.flush()
        sys.stdout.write("\r" + self.downloadStart + " Downloading {0}... ".format(self.onDiskName) + "[{0}%]".format(statList[1]))
        sys.stdout.write("\n")


server = downloadFile("https://s3.amazonaws.com/Minecraft.Download/versions/1.8/minecraft_server.1.8.jar", "C:/Users/my-username/Desktop/", "minecraftServer.jar")
t1 = threading.Thread(target=server.executeDownload())
t2 = threading.Thread(target=server.liveDownloadStats())
t2.start()
t1.start()
time.sleep(100)

This is supposed to start printing the percentage downloaded of the file being downloaded once the file appears. What I am seeing is that the file appears and then moments later I get the output saying that it is 100% downloaded. I can't see exactly what I'm doing wrong here.

2
  • Maybe it downloads too quickly? Commented Nov 20, 2014 at 4:45
  • I have tested that, when I download using the self.executeDownload() method it takes about 15 seconds to completely download. At that point I should have at least gotten a 0% and a 100%. I don't think it is download speed. Update: I have checked it, and I can right click properties and see that it is not done downloading yet. So it isn't a speed problem. Commented Nov 20, 2014 at 4:48

1 Answer 1

1

The problem was the fact that every time it checked the current downloaded data to the data that needed to be downloaded, it never updated the variables. So when the loop came around, it was comparing the same numbers until something. It was stuck in this loop and when something caused it to exit, I'm not sure what, it continued to the next line of code printing that it was finished downloading.

import urllib.request
import urllib
import shutil
import os
import os.path
import sys
import time
import threading

class downloadFile:

    def __init__(self, downloadLink, downloadPath, onDiskName):
        self.downloadSize = urllib.request.urlopen(downloadLink).length
        self.downloadLink = downloadLink
        self.downloadPath = downloadPath
        self.onDiskName = onDiskName
        self.hardPath = os.path.join(self.downloadPath, self.onDiskName)

    def returnMode(self, returnMode = 'stats'):
        if returnMode == 'stats':
            return [self.downloadLink, self.downloadPath, self.onDiskName, self.downloadSize]
        elif returnMode == 'printedStats':
            print('self.downloadLink = ' + self.downloadLink)
            print('self.downloadPath = ' + self.downloadPath)
            print('self.onDiskName = ' + self.onDiskName)
            print('self.downloadSize = ' + self.downloadSize)
            print('self.hardPath = ' + self.hardPath)
            return [self.downloadLink, self.downloadPath, self.onDiskName, self.downloadSize, self.hardPath]

    def executeDownload(self):
        self.downloadStart = time.strftime("[%H:%M:%S] ")
        with urllib.request.urlopen(self.downloadLink) as response, open(self.hardPath, 'wb') as currentFile:
            shutil.copyfileobj(response, currentFile)
        currentFile.close()
        self.downloadEnd = time.strftime("[%H:%M:%S] ")

    def downloadStats(self):
        currentFileSize = os.path.getsize(self.hardPath)
        percentManifested = int(currentFileSize/(self.downloadSize/100))
        return [currentFileSize, percentManifested]

    def liveDownloadStats(self):
        if os.path.isfile(self.hardPath) == False:
            time.sleep(1)
        statList = self.downloadStats()
        while statList[0] < self.downloadSize:
            sys.stdout.write("\r" + self.downloadStart + " Downloading {0}... ".format(self.onDiskName) + "[{0}%]".format(statList[1]))
            sys.stdout.flush()
            statList = self.downloadStats() #This is the extra line of code used to update the variable before comparing on the next while loop.
        sys.stdout.write("\r" + self.downloadStart + " Downloading {0}... ".format(self.onDiskName) + "[{0}%]".format(statList[1]))
        sys.stdout.write("\n")

def Main():
    server = downloadFile("https://s3.amazonaws.com/Minecraft.Download/versions/1.8/minecraft_server.1.8.jar", "C:/Users/my-username/Desktop/", "minecraftServer.jar")
    t1 = threading.Thread(target=server.executeDownload, args=())
    t2 = threading.Thread(target=server.liveDownloadStats, args=())
    t1.start()
    t2.start()

if __name__ == "__main__":
    Main()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.