I am working with the following script from https://github.com/Isaacdelly/Plutus/blob/master/plutus.py
The script works for wallet addresses in the 2^160 range. I am curious where in the script I can change this to look at the 2^128 range or 2^n range. Would it be possible to even have a window? Like 2^0 - 2^100?
Not trying to do anything malicious, just trying to get data to show that even selecting ranges is futile due to the large number of addresses.
# Plutus Bitcoin Brute Forcer
# Made by Isaac Delly
# https://github.com/Isaacdelly/Plutus
try:
import sys
import os
import time
import hashlib
import binascii
import multiprocessing
from multiprocessing import Process, Queue
from multiprocessing.pool import ThreadPool
import threading
import base58
import ecdsa
import requests
except ImportError:
import subprocess
subprocess.check_call(["python", '-m', 'pip', 'install', 'base58==1.0.0'])
subprocess.check_call(["python", '-m', 'pip', 'install', 'ecdsa==0.13'])
subprocess.check_call(["python", '-m', 'pip', 'install', 'requests==2.19.1'])
import base58
import ecdsa
import requests
def generate_private_key():
return binascii.hexlify(os.urandom(32)).decode('utf-8')
def private_key_to_WIF(private_key):
var80 = "80" + str(private_key)
var = hashlib.sha256(binascii.unhexlify(hashlib.sha256(binascii.unhexlify(var80)).hexdigest())).hexdigest()
return str(base58.b58encode(binascii.unhexlify(str(var80) + str(var[0:8]))), 'utf-8')
def private_key_to_public_key(private_key):
sign = ecdsa.SigningKey.from_string(binascii.unhexlify(private_key), curve = ecdsa.SECP256k1)
return ('04' + binascii.hexlify(sign.verifying_key.to_string()).decode('utf-8'))
def public_key_to_address(public_key):
alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
count = 0; val = 0
var = hashlib.new('ripemd160')
var.update(hashlib.sha256(binascii.unhexlify(public_key.encode())).digest())
doublehash = hashlib.sha256(hashlib.sha256(binascii.unhexlify(('00' + var.hexdigest()).encode())).digest()).hexdigest()
address = '00' + var.hexdigest() + doublehash[0:8]
for char in address:
if (char != '0'):
break
count += 1
count = count // 2
n = int(address, 16)
output = []
while (n > 0):
n, remainder = divmod (n, 58)
output.append(alphabet[remainder])
while (val < count):
output.append(alphabet[0])
val += 1
return ''.join(output[::-1])
def get_balance(address):
try:
response = requests.get("https://bitaps.com/api/address/" + str(address))
return int(response.json()['balance'])
except:
return -1
def data_export(queue):
while True:
private_key = generate_private_key()
public_key = private_key_to_public_key(private_key)
address = public_key_to_address(public_key)
data = (private_key, address)
queue.put(data, block = False)
def worker(queue):
while True:
if not queue.empty():
data = queue.get(block = True)
balance = get_balance(data[1])
process(data, balance)
def process(data, balance):
private_key = data[0]
address = data[1]
if (balance == 0):
print("{:<34}".format(str(address)) + ": " + str(balance))
if (balance > 0):
file = open("plutus.txt","a")
file.write("address: " + str(address) + "\n" +
"private key: " + str(private_key) + "\n" +
"WIF private key: " + str(private_key_to_WIF(private_key)) + "\n" +
"public key: " + str(private_key_to_public_key(private_key)).upper() + "\n" +
"balance: " + str(balance) + "\n\n")
file.close()
def thread(iterator):
processes = []
data = Queue()
data_factory = Process(target = data_export, args = (data,))
data_factory.daemon = True
processes.append(data_factory)
data_factory.start()
work = Process(target = worker, args = (data,))
work.daemon = True
processes.append(work)
work.start()
data_factory.join()
if __name__ == '__main__':
try:
pool = ThreadPool(processes = multiprocessing.cpu_count()*2)
pool.map(thread, range(0, 10))
except:
pool.close()
exit()
Thank you
You seem to be misunderstanding the purpose of the 2^160 bit range.
Each standard bitcoin address is tied to the HASH160 of the public key. A HASH160 is 160 bits long, which is why your search space is 2^160. If you are able to find two private keys for which the HASH160 of the public keys are equal, any of those two private keys can spend coins sent to that address.
Searching a smaller space does not make sense since you are no longer searching for bitcoin addresses. If you just want to search random hash functions, then you simply need to replace RIPEMD160 hash function with another one that has an output in whatever bitsize you wish to search.
Note that if you do that, the rest of the code talking about checking balances etc. will be of no use, since your output will no longer be a bitcoin address.
Related
how do i input bits rather than bytes in os.urandom(n) function? I want to set the n value to 66 bits that is 8.25 bytes and floating numbers are not supported in it? or is there any other function that help me set the value of n to 66 bits?
import time
import datetime as dt
import smtplib
import os
import multiprocessing
from multiprocessing import Pool
import binascii, hashlib, base58, ecdsa
import pandas as pd
def ripemd160(x):
d = hashlib.new('ripemd160')
d.update(x)
return d
r = 0
cores=6
def seek(r, df_handler):
global num_threads
LOG_EVERY_N = 1000
start_time = dt.datetime.today().timestamp()
i = 0
print("Core " + str(r) +": Searching Private Key..")
while True:
i=i+1
# generate private key , uncompressed WIF starts with "5"
priv_key = os.urandom(32)
fullkey = '80' + binascii.hexlify(priv_key).decode()
sha256a = hashlib.sha256(binascii.unhexlify(fullkey)).hexdigest()
sha256b = hashlib.sha256(binascii.unhexlify(sha256a)).hexdigest()
WIF = base58.b58encode(binascii.unhexlify(fullkey+sha256b[:8]))
# get public key , uncompressed address starts with "1"
sk = ecdsa.SigningKey.from_string(priv_key, curve=ecdsa.SECP256k1)
vk = sk.get_verifying_key()
publ_key = '04' + binascii.hexlify(vk.to_string()).decode()
hash160 = ripemd160(hashlib.sha256(binascii.unhexlify(publ_key)).digest()).digest()
publ_addr_a = b"\x00" + hash160
checksum = hashlib.sha256(hashlib.sha256(publ_addr_a).digest()).digest()[:4]
publ_addr_b = base58.b58encode(publ_addr_a + checksum)
priv = WIF.decode()
pub = publ_addr_b.decode()
time_diff = dt.datetime.today().timestamp() - start_time
if (i % LOG_EVERY_N) == 0:
print('Core :'+str(r)+" K/s = "+ str(i / time_diff))
#print ('Worker '+str(r)+':'+ str(i) + '.- # '+pub + ' # -------- # '+ priv+' # ')
pub = pub + '\n'
filename = 'bit.txt'
with open(filename) as f:
for line in f:
if pub in line:
msg = "\nPublic:
" + str(pub) + " ---- Private: " + str(priv) + "YEI"
text = msg
#UNCOMMENT IF 2FA from gmail is activated, or risk missing your winning ticket;)
#server = smtplib.SMTP("smtp.gmail.com", 587)
#server.ehlo()
#server.starttls()
#server.login("example#gmail.com", "password")
#fromaddr = "example#gmail.com"
#toaddr = "example#gmail.com"
#server.sendmail(fromaddr, toaddr, text)
print(text)
with open('Wallets.txt','a') as f:
f.write(priv)
f.write(' ')
f.write(pub)
f.write('\n')
f.close()
time.sleep(30)
print ('WINNER WINNER CHICKEN DINNER!!! ---- ' +dt.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), pub, priv)
break
contador=0
if __name__ == '__main__':
jobs = []
df_handler = pd.read_csv(open('bit.txt', 'r'))
for r in range(cores):
p = multiprocessing.Process(target=seek, args=(r,df_handler))
jobs.append(p)
p.start()
this is the code and i want the os.urandom(32) to be 8.25 bytes (66 bit)
If you want an integer with 66 random bits using the same random source as os.urandom() uses,
>>> import random
>>> x = random.SystemRandom().getrandbits(66)
46111822109486537585
If you want that integer as a "binary string" of length 66,
>>> bin(x)[2:].rjust(66, '0')
'100111111111101110000110011110010111001101111100101101101101110001'
(bin()'s output has a 0b prefix, so we slice that off. In case any of the high-order bits are zero, they wouldn't be in the bin() output, so we pad the string to the desired length with zeroes.)
I have multiples files but two are relevant.
The first one is PacketStrings.py and it looks something like this:
import re
from scapy.all import *
def packetString(pkt):
global attacker_ip
global tcp_payload
out = ""
if (IP in pkt):
attacker_ip = pkt[IP].src
out += ipString(pkt[IP])
elif (IPv6 in pkt):
# TODO
pass
if (TCP in pkt):
tcp_payload = payloadString(pkt[TCP])
out += tcpString(pkt[TCP])
out += "[TCP Payload]" + "\n"
out+= payloadString(pkt[TCP])
elif (UDP in pkt):
out += udpString(pkt[UDP])
out += "[UDP Payload]" + "\n"
out += payloadString(pkt[UDP])
return out
The second one is intrusion.py and it looks something like this
from PacketStrings import *
import json
from datetime import datetime
import urllib.parse
from scapy.all import *
SQLinjections = json.loads(open('/redpot/IDS/src_code/attacks/SQLinjections.json').read())
LOG = open("/redpot/logs/IDS/intrusions.log", "a")
def SQLintrusion(pkt):
ip = PacketStrings.attacker_ip
sus = PacketStrings.tcp_payload
if (len(sus) != 0):
for x in SQLinjections:
if (conf.route.route("0.0.0.0")[2] != ip and urllib.parse.quote_plus(x) in sus):
LOG.write(datetime.now().strftime("%d/%m/%Y %H:%M:%S")+" | Possible Intrusion Detected | Type = SQLinjection | IP = "+ip+" | Payload = "+str(x)+"\r\r\n")
When I run the function inside the second file sometimes it works without error and other times it raises the error :
AttributeError: module 'PacketStrings' has no attribute 'attacker_ip'
I wrote a little crypto switcher which checks profit and switches miners. But it works some time and then the loop stops without any error (it may work 15 min or 20 hours but it will stop, tested for 10 days).
code:
import os
import subprocess
import time
import copy
import requests
import configparser
from datetime import datetime
def config_read ():
config = configparser.ConfigParser()
config.read('config.ini')
return config.sections
def start_miner(info):
if info['algorithm'] == 'Equihash':
subprocess.Popen('F:\Claymore\start — music — Peon.bat', cwd='F:\Claymore',
creationflags=subprocess.CREATE_NEW_CONSOLE)
elif info['algorithm'] == 'Ethash':
subprocess.Popen('F:\Claymore\start — music — Peon.bat', cwd='F:\Claymore',
creationflags=subprocess.CREATE_NEW_CONSOLE)
return info
def stop_miner():
os.system("taskkill /f /t /im miner.exe")
os.system("taskkill /f /t /im EthDcrMiner64.exe")
def request_coins():
coins = None
while coins is None:
try:
coins = ((requests.get(
url='https://whattomine.com/coins.json?utf8=✓ð=true&factor%5Beth_hr%5D=79.0&factor%5Beth_p%5D=0.0&factor%5Bgro_hr%5D=0.0&factor%5Bgro_p%5D=0.0&factor%5Bx11g_hr%5D=20.0&factor%5Bx11g_p%5D=0.0&factor%5Bcn_hr%5D=0.0&factor%5Bcn_p%5D=0.0&eq=true&factor%5Beq_hr%5D=1000.0&factor%5Beq_p%5D=0.0&factor%5Blrev2_hr%5D=80000.0&factor%5Blrev2_p%5D=0.0&factor%5Bns_hr%5D=0.0&factor%5Bns_p%5D=0.0&factor%5Blbry_hr%5D=0.0&factor%5Blbry_p%5D=0.0&factor%5Bbk2b_hr%5D=0.0&factor%5Bbk2b_p%5D=0.0&factor%5Bbk14_hr%5D=0.0&factor%5Bbk14_p%5D=0.0&factor%5Bpas_hr%5D=0.0&factor%5Bpas_p%5D=0.0&bkv=true&factor%5Bbkv_hr%5D=0.0&factor%5Bbkv_p%5D=0.0&factor%5Bcost%5D=0.06&sort=Profitability24&volume=0&revenue=24h&factor%5Bexchanges%5D%5B%5D=&factor%5Bexchanges%5D%5B%5D=bittrex&factor%5Bexchanges%5D%5B%5D=bleutrade&factor%5Bexchanges%5D%5B%5D=btc_e&factor%5Bexchanges%5D%5B%5D=bter&factor%5Bexchanges%5D%5B%5D=c_cex&factor%5Bexchanges%5D%5B%5D=cryptopia&factor%5Bexchanges%5D%5B%5D=poloniex&factor%5Bexchanges%5D%5B%5D=yobit&dataset=Main&commit=Calculate&adapt_q_280x=0&adapt_q_380=0&adapt_q_fury=0&adapt_q_470=0&adapt_q_480=0&adapt_q_750Ti=0&adapt_q_10606=3&adapt_q_1070=0&adapt_q_1080=0&adapt_q_1080Ti=0%27')).json())[
'coins']
except:
print("Site didn't respond. Reconnecting in 10 sec")
time.sleep(10)
return coins
def miner_chose(config, info):
user_coins = {}
coins = request_coins()
for key, value in config['Currency'].items():
if value == 'True':
tag = key.upper()
for key_coin, value_coin in coins.items():
if value_coin['tag'] == info['temp_currency']:
info['temp_profit'] = value_coin['btc_revenue24']
if value_coin['tag'] == info['currency']:
info['profit'] = value_coin['btc_revenue24']
if value_coin['tag'] == tag:
user_coins[key_coin] = value_coin
for key, value in user_coins.items():
if float(value['btc_revenue24']) >= float(info['profit']) * (float(config['CheckOptions']['profitprocent']) +100) / 100:
if not info['currency'] == value['tag']:
if float(value['btc_revenue24']) > float(info['temp_profit']):
if not info['temp_currency'] == value['tag']:
info['check_times'] = 0
info['temp_profit'] = value['btc_revenue24']
info['temp_currency'] = value['tag']
info['check_times'] += 1
if int(info['check_times']) >= int(config['CheckOptions']['times']):
info['profit'] = value['btc_revenue24']
info['currency'] = value['tag']
info['algorithm'] = value['algorithm']
info['check_times'] = 0
return info
Part of code that uses while loop and stops:
def main():
info = {'profit': 0, 'check_times': 200, 'currency': None, 'temp_profit': 0, 'temp_currency': None}
config = config_read()
while True:
if info['profit'] == 0:
stop_miner()
info = start_miner(miner_chose(config,info))
print(str(datetime.now()) + " - Starting miner first time. Currency: " + info['currency'] + '. Profit: ' +
info['profit'] + ' BTC/Day')
time.sleep(int(config['CheckOptions']['period']) * 60)
else:
old_info = copy.deepcopy(info)
info = miner_chose(config, info)
print(
str(datetime.now()) + ' - Checking profit. Current currency: ' + info['currency'] + '. Profit: ' + info[
'profit'] + ' BTC/Day')
if info['currency'] != old_info['currency']:
print('Changing miner. Currency ' + info['currency'] + '. Profit: ' + info['profit'] + ' BTC/Day')
elif info['currency'] == old_info['currency']:
print('Curency SAME')
# stop_miner()
# start_miner(info)
time.sleep(int(config['CheckOptions']['period']) * 60)
I want that after sleeping time.sleep(int(config['CheckOptions']['period']) * 60) script have to start again and make all check again but sometimes script sleep for time i have put in config and don't want to check again. It may stop after 10 or 20 check without any errors.
Need to add to coins = ((requests.get(url='https://whattomine.com/coins.json', timeout=3)).json())['coins'] cause the server something stack and don't send response.
So what i'm trying to do is to make a multi-threaded server that creates threads for each client that connects to it, and replies back the string sent from the client.
It sort of works, but my server doesn't actually end properly. My KerboardInterrupt catch doesn't seem to work in windows command prompt, only thing that lets me exit the process would be ctrl + pause/break. Can anyone help me think of a way to get the server to end gracefully?
Server Code:
import socket
import threading
import time
import datetime
import sys
def getTime():
ts = time.time()
timeStamp = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m- %d_%H:%M:%S')
return timeStamp
def ThreadFunction(clientsocket, clientaddr):
global ReceivedData
global SentData
while True:
#Receive data from client
data = clientsocket.recv(bufferSize)
#Get client IP and port
clientIP, clientSocket = clientsocket.getpeername()
#Add to total amount of data transfered
ReceiveDataSize = len(data)
ReceivedData += ReceiveDataSize
#LOg the received data
text_file.write(str(getTime()) + "__ Size of data received (" + clientIP + ":" + str(clientSocket) + ") = " + str(ReceiveDataSize) + '\n')
#Send data
clientsocket.send(data)
SentDataSize = len(data)
SentData += SentDataSize
#Log the sent data
text_file.write(str(getTime()) + "__ Size of data sent (" + clientIP + ":" + str(clientSocket) + ") = " + str(SentDataSize) + '\n')
def Close(counter, ReceivedData, SentData):
print ("Shutting down Server...")
serversocket.close()
text_file.write("\n\nTotal # of connections: " + str(counter))
text_file.write("\nTotal data received: " + str(ReceivedData))
text_file.write("\nTotal data sent: " + str(SentData))
text_file.close()
sys.exit()
if __name__ == '__main__':
serverIP = raw_input('Enter your server IP \n')
port = int(raw_input('What port would you like to use?\n'))
# Maintain how many connections
connections = []
counter = 0
# Maintain amount of data sent to and from server
ReceivedData = 0
SentData = 0
bufferSize = 1024
# Create and initialize the text file with the date in the filename in the logfiles directory
text_file = open("MultiThreadedServerLog.txt", "w")
address = (serverIP, port)
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind server to port
serversocket.bind(address)
# The listen backlog queue size
serversocket.listen(50)
print ("Server is listening for connections\n")
try:
while 1:
# Accept client connections, increment number of connections
clientsocket, clientaddr = serversocket.accept()
counter += 1
# Log client information
print (str(clientaddr) + " : " + " Just Connected. \n Currently connected clients: " + str(counter) + "\n")
text_file.write(str(getTime()) + " - " + str(clientaddr) + " : " + " Just Connected. \n Currently connected clients: " + str(counter) + "\n")
clientThread = threading.Thread(target=ThreadFunction, args=(clientsocket, clientaddr))
clientThread.start()
except KeyboardInterrupt:
print ("Keyboard interrupt occurred.")
Close(counter, ReceivedData, SentData)
Client Code:
from socket import *
import threading
import time
import random
import sys
import datetime
serverIP = ""
port = 8005
message = ""
msgMultiple = 1
def getTime():
ts = time.time()
timeStamp = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d_%H:%M:%S')
return timeStamp
def run(clientNumber):
buffer = 1024
global totalTime
s = socket(AF_INET, SOCK_STREAM)
s.connect((serverIP, port))
threadRTT = 0
while 1:
for _ in range(msgMultiple):
cData = message + " From: Client " + str(clientNumber)
# Start timer and send data
start = time.time()
s.send(cData.encode('utf-8'))
print "Sent: " + cData
# Stop timer when data is received
sData = s.recv(buffer)
end = time.time()
# Keep track of RTT and update total time
response_time = end - start
threadRTT += end - start
totalTime += response_time
print "Received: " + cData + '\n'
t = random.randint(0, 9)
time.sleep(t)
# Log information of Client
text_file.write(
"\nClient " + str(clientNumber) + " RTT time taken for " + str(msgMultiple) + " messages was: " + str(
threadRTT) + " seconds.")
threadRTT = 0
break
if __name__ == '__main__':
serverIP = raw_input('Enter the server IP: ')
port = int(input('Enter the port: '))
clients = int(input('Enter number of clients: '))
message = raw_input('Enter a message to send: ')
msgMultiple = int(input('Enter the number of times you would like to send the message: '))
# Initialize Log file
text_file = open("ClientLog.txt", "w")
# Used to maintain list of all running threads
threads = []
totalTime = 0
# Create a seperate thread for each client
for x in range(clients):
thread = threading.Thread(target=run, args=[x])
thread.start()
threads.append(thread)
for thread in threads:
thread.join()
# Calculations for log data
bytes = sys.getsizeof(message)
totalRequests = clients * msgMultiple
totalBytes = totalRequests * bytes
averageRTT = totalTime / totalRequests
# Output data
print("Bytes sent in message was : " + str(bytes))
print("Total Data sent was : " + str(totalBytes) + " Bytes.")
print("Average RTT was : " + str(averageRTT) + " seconds.")
print("Requests was : " + str(totalRequests))
# Write data to log file
text_file.write("\n\n Bytes sent in message was : " + str(bytes))
text_file.write("\nTotal Data sent was : " + str(totalBytes) + " Bytes.")
text_file.write("\nAverage RTT was : " + str(averageRTT) + " seconds.")
text_file.write("\nRequests was : " + str(totalRequests))
Also if anyone else has any general improvements they would add to this code, let me know. I'm still pretty new at python, and still rough at it.
Here is the normal intended input i'm getting from my server.
But when it gets to the last client that connects, it starts to drag on for some reason.
The last picture, the inputs go on for the majority of the text file, for a very long time. Seems like something isn't ending properly.
Solved by adding an if statement that checks for a byte < 0 , if it is, end the socket.
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.
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()