Simple download/unpack CLI progress
This commit is contained in:
parent
dae215424e
commit
4497e1e793
@ -5,7 +5,7 @@ import argparse
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from spoc import publisher
|
from spoc import publisher
|
||||||
from spoc.utils import readable_size
|
from spoc.cli import readable_size
|
||||||
|
|
||||||
ACTION_LIST = 1
|
ACTION_LIST = 1
|
||||||
ACTION_INSTALL = 2
|
ACTION_INSTALL = 2
|
||||||
|
@ -8,7 +8,7 @@ from spoc import repo_online
|
|||||||
from spoc import repo_publish
|
from spoc import repo_publish
|
||||||
from spoc.image import Image
|
from spoc.image import Image
|
||||||
from spoc.imagebuilder import ImageBuilder
|
from spoc.imagebuilder import ImageBuilder
|
||||||
from spoc.utils import ActionItem, readable_size
|
from spoc.cli import ActionQueue, ActionItem, readable_size
|
||||||
|
|
||||||
ACTION_LIST = 1
|
ACTION_LIST = 1
|
||||||
ACTION_DOWNLOAD = 2
|
ACTION_DOWNLOAD = 2
|
||||||
@ -36,15 +36,14 @@ def listing(repo_type):
|
|||||||
print(image)
|
print(image)
|
||||||
|
|
||||||
def download(image_name):
|
def download(image_name):
|
||||||
plan = []
|
actionqueue = ActionQueue()
|
||||||
local_images = repo_local.get_images()
|
local_images = repo_local.get_images()
|
||||||
for layer in repo_online.get_image(image_name)['layers']:
|
for layer in repo_online.get_image(image_name)['layers']:
|
||||||
if layer not in local_images:
|
if layer not in local_images:
|
||||||
image = Image(layer, False)
|
image = Image(layer, False)
|
||||||
plan.append(ActionItem(f'Downloading {image_name}', image.download))
|
actionqueue.append(ActionItem(f'Downloading {image_name}', image.download))
|
||||||
plan.append(ActionItem(f'Unpacking {image_name}', image.unpack_downloaded))
|
actionqueue.append(ActionItem(f'Unpacking {image_name}', image.unpack_downloaded))
|
||||||
for item in plan:
|
actionqueue.process()
|
||||||
item.run()
|
|
||||||
|
|
||||||
def delete(image_name):
|
def delete(image_name):
|
||||||
Image(image_name, False).delete()
|
Image(image_name, False).delete()
|
||||||
|
49
usr/lib/python3.8/spoc/cli.py
Normal file
49
usr/lib/python3.8/spoc/cli.py
Normal 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'
|
@ -55,7 +55,7 @@ def download_archive(archive_url, archive_path, expected_hash, observer):
|
|||||||
# Download archive via http(s) and store in temporary directory
|
# Download archive via http(s) and store in temporary directory
|
||||||
with open(archive_path, 'wb') as f, requests.Session() as session:
|
with open(archive_path, 'wb') as f, requests.Session() as session:
|
||||||
resource = session.get(archive_url, stream=True)
|
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:
|
if chunk:
|
||||||
observer.units_done += f.write(chunk)
|
observer.units_done += f.write(chunk)
|
||||||
|
|
||||||
|
@ -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'
|
|
Loading…
Reference in New Issue
Block a user