[game-data-packager] 12/24: Improve progress info
Simon McVittie
smcv at debian.org
Tue Dec 30 01:32:04 UTC 2014
This is an automated email from the git hooks/post-receive script.
smcv pushed a commit to branch master
in repository game-data-packager.
commit eca3aeb6860607ca3e725d00bd0e442c819e618a
Author: Simon McVittie <smcv at debian.org>
Date: Mon Dec 29 15:27:36 2014 +0000
Improve progress info
---
lib/game_data_packager/__init__.py | 59 ++++++++++++++++++++++++++++++++------
lib/game_data_packager/util.py | 11 +++++++
2 files changed, 61 insertions(+), 9 deletions(-)
diff --git a/lib/game_data_packager/__init__.py b/lib/game_data_packager/__init__.py
index 0e6a73b..2f87adb 100644
--- a/lib/game_data_packager/__init__.py
+++ b/lib/game_data_packager/__init__.py
@@ -26,13 +26,14 @@ import random
import re
import shutil
import subprocess
+import sys
import tarfile
import tempfile
import urllib.request
import yaml
-from .util import TemporaryUmask, mkdir_p
+from .util import TemporaryUmask, mkdir_p, human_size, MEBIBYTE
logging.basicConfig()
logger = logging.getLogger('game-data-packager')
@@ -41,6 +42,11 @@ logger = logging.getLogger('game-data-packager')
DATADIR = os.environ['DATADIR']
if os.environ.get('DEBUG'):
logging.getLogger().setLevel(logging.DEBUG)
+else:
+ logging.getLogger().setLevel(logging.INFO)
+
+# arbitrary cutoff for providing progress bars
+QUITE_LARGE = 50 * MEBIBYTE
MD5SUM_DIVIDER = re.compile(r' [ *]?')
@@ -52,15 +58,37 @@ class HashedFile(object):
self.sha256 = None
@classmethod
- def from_file(cls, name, f, write_to=None):
+ def from_file(cls, name, f, write_to=None, size=None, progress=False):
md5 = hashlib.new('md5')
sha1 = hashlib.new('sha1')
sha256 = hashlib.new('sha256')
+ done = 0
+
+ if progress and sys.stderr.isatty():
+ pad = [' ']
+ def update_progress(s):
+ if len(pad[0]) <= len(s):
+ pad[0] = ' ' * len(s)
+ print(' %s \r %s\r' % (pad[0], s), end='', file=sys.stderr)
+ else:
+ update_progress = lambda s: None
while True:
+ if size is None:
+ update_progress(human_size(done))
+ else:
+ update_progress('%.0f%% %s/%s' % (
+ 100 * done / size,
+ human_size(done),
+ human_size(size)))
+
blob = f.read(io.DEFAULT_BUFFER_SIZE)
if not blob:
+ update_progress('')
break
+
+ done += len(blob)
+
md5.update(blob)
sha1.update(blob)
sha256.update(blob)
@@ -353,7 +381,10 @@ class GameDataPackage(object):
return False
if hashes is None:
- hashes = HashedFile.from_file(path, open(path, 'rb'))
+ if size > QUITE_LARGE:
+ logger.info('checking %s', path)
+ hashes = HashedFile.from_file(path, open(path, 'rb'), size=size,
+ progress=(size > QUITE_LARGE))
if not hashes.matches(wanted):
logger.warning('found possible %s\n' +
@@ -383,10 +414,13 @@ class GameDataPackage(object):
def consider_file(self, path, really_should_match_something):
match_path = '/' + path.lower()
+ size = os.path.getsize(path)
if really_should_match_something:
- logger.debug('considering %s', path)
- hashes = HashedFile.from_file(path, open(path, 'rb'))
+ if size > QUITE_LARGE:
+ logger.info('identifying %s', path)
+ hashes = HashedFile.from_file(path, open(path, 'rb'), size=size,
+ progress=(size > QUITE_LARGE))
else:
hashes = None
@@ -398,7 +432,6 @@ class GameDataPackage(object):
return
if wanted.distinctive_size:
- size = os.path.getsize(path)
if wanted.size == size:
self.use_file(wanted, path, hashes)
@@ -451,8 +484,14 @@ class GameDataPackage(object):
mkdir_p(tmpdir)
wf = open(tmp, 'wb')
+ if entry.size > QUITE_LARGE:
+ logger.info('extracting %s from %s', entry.name, name)
+ else:
+ logger.debug('extracting %s from %s', entry.name, name)
hf = HashedFile.from_file(
- name + '//' + entry.name, entryfile, wf)
+ name + '//' + entry.name, entryfile, wf,
+ size=entry.size,
+ progress=(entry.size > QUITE_LARGE))
wf.close()
if not self.use_file(wanted, tmp, hf):
@@ -512,14 +551,16 @@ class GameDataPackage(object):
tmpdir = os.path.dirname(tmp)
mkdir_p(tmpdir)
wf = open(tmp, 'wb')
- hf = HashedFile.from_file(url, rf, wf)
+ logger.info('downloading %s', url)
+ hf = HashedFile.from_file(url, rf, wf,
+ size=provider.size, progress=True)
wf.close()
if self.use_file(provider, tmp, hf):
break
else:
os.remove(tmp)
- except Exception as e:
+ except (Exception, KeyboardInterrupt) as e:
logger.warning('Failed to download "%s": %s', url,
e)
self.download_failed.add(url)
diff --git a/lib/game_data_packager/util.py b/lib/game_data_packager/util.py
index d946551..c963bdc 100644
--- a/lib/game_data_packager/util.py
+++ b/lib/game_data_packager/util.py
@@ -17,6 +17,9 @@
import os
+KIBIBYTE = 1024
+MEBIBYTE = KIBIBYTE * KIBIBYTE
+
class TemporaryUmask(object):
"""Context manager to set the umask. Not thread-safe.
@@ -40,3 +43,11 @@ def mkdir_p(path):
if not os.path.isdir(path):
with TemporaryUmask(0o022):
os.makedirs(path)
+
+def human_size(size):
+ # 0.0 KiB up to 1024.0 KiB
+ if size < MEBIBYTE:
+ return '%.1f KiB' % (size / KIBIBYTE)
+
+ # 1.0 MiB or more
+ return '%.1f MiB' % (size / (MEBIBYTE))
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/game-data-packager.git
More information about the Pkg-games-commits
mailing list