Simple download/unpack CLI progress

This commit is contained in:
Disassembler 2020-02-17 23:07:18 +01:00
parent dae215424e
commit 4497e1e793
No known key found for this signature in database
GPG Key ID: 524BD33A0EE29499
5 changed files with 56 additions and 29 deletions

View File

@ -5,7 +5,7 @@ import argparse
import os
from spoc import publisher
from spoc.utils import readable_size
from spoc.cli import readable_size
ACTION_LIST = 1
ACTION_INSTALL = 2

View File

@ -8,7 +8,7 @@ from spoc import repo_online
from spoc import repo_publish
from spoc.image import Image
from spoc.imagebuilder import ImageBuilder
from spoc.utils import ActionItem, readable_size
from spoc.cli import ActionQueue, ActionItem, readable_size
ACTION_LIST = 1
ACTION_DOWNLOAD = 2
@ -36,15 +36,14 @@ def listing(repo_type):
print(image)
def download(image_name):
plan = []
actionqueue = ActionQueue()
local_images = repo_local.get_images()
for layer in repo_online.get_image(image_name)['layers']:
if layer not in local_images:
image = Image(layer, False)
plan.append(ActionItem(f'Downloading {image_name}', image.download))
plan.append(ActionItem(f'Unpacking {image_name}', image.unpack_downloaded))
for item in plan:
item.run()
actionqueue.append(ActionItem(f'Downloading {image_name}', image.download))
actionqueue.append(ActionItem(f'Unpacking {image_name}', image.unpack_downloaded))
actionqueue.process()
def delete(image_name):
Image(image_name, False).delete()

View File

@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
import time
from concurrent.futures import ThreadPoolExecutor
SIZE_PREFIXES = ('', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
class ActionQueue:
def __init__(self):
self.queue = []
def append(self, actionitem):
self.queue.append(actionitem)
def process(self):
index = 0
queue_length = len(self.queue)
for item in self.queue:
index += 1
item.text = f'[{index}/{queue_length}] {item.text}'
item.run()
class ActionItem:
def __init__(self, text, action):
self.text = text
self.action = action
self.units_total = 0
self.units_done = 0
def run(self):
with ThreadPoolExecutor() as executor:
future = executor.submit(self.action, self)
while not future.done():
time.sleep(0.2)
self.print_status()
# Get the result of the future and let it raise exception, if there was any
data = future.result()
self.print_status('\n')
def print_status(self, end='\r'):
print(f'\x1b[K{self.text} ({self.units_done}/{self.units_total}) [{self.units_done/self.units_total*100:.2f} %]', end=end)
def readable_size(bytes):
i = 0
while bytes > 1024:
i += 1
bytes /= 1024
return f'{bytes:.2f} {SIZE_PREFIXES[i]}B'

View File

@ -55,7 +55,7 @@ def download_archive(archive_url, archive_path, expected_hash, observer):
# Download archive via http(s) and store in temporary directory
with open(archive_path, 'wb') as f, requests.Session() as session:
resource = session.get(archive_url, stream=True)
for chunk in resource.iter_content(chunk_size=None):
for chunk in resource.iter_content(chunk_size=64*1024):
if chunk:
observer.units_done += f.write(chunk)

View File

@ -1,21 +0,0 @@
# -*- coding: utf-8 -*-
SIZE_PREFIXES = ('', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
class ActionItem:
def __init__(self, text, action):
self.text = text
self.action = action
self.units_total = 0
self.units_done = 0
def run(self):
print(self.text)
self.action(self)
def readable_size(bytes):
i = 0
while bytes > 1024:
i += 1
bytes /= 1024
return f'{bytes:.2f} {SIZE_PREFIXES[i]}B'