summaryrefslogtreecommitdiff
path: root/compose/progress_stream.py
diff options
context:
space:
mode:
authorAanand Prasad <aanand.prasad@gmail.com>2015-01-12 14:59:05 +0000
committerAanand Prasad <aanand.prasad@gmail.com>2015-01-20 21:00:23 +0000
commit2af7693e64010e11ba53f7fd923bb97f29b10063 (patch)
treee6a5bfb9e32fead0114bb52f7d26b5685c2536bb /compose/progress_stream.py
parent7be8b4c06d4b16bd2101228ffdda127f91f21d54 (diff)
WIP: rename Fig to Compose
Signed-off-by: Aanand Prasad <aanand.prasad@gmail.com>
Diffstat (limited to 'compose/progress_stream.py')
-rw-r--r--compose/progress_stream.py85
1 files changed, 85 insertions, 0 deletions
diff --git a/compose/progress_stream.py b/compose/progress_stream.py
new file mode 100644
index 00000000..39aab5ff
--- /dev/null
+++ b/compose/progress_stream.py
@@ -0,0 +1,85 @@
+import json
+import os
+import codecs
+
+
+class StreamOutputError(Exception):
+ pass
+
+
+def stream_output(output, stream):
+ is_terminal = hasattr(stream, 'fileno') and os.isatty(stream.fileno())
+ stream = codecs.getwriter('utf-8')(stream)
+ all_events = []
+ lines = {}
+ diff = 0
+
+ for chunk in output:
+ event = json.loads(chunk)
+ all_events.append(event)
+
+ if 'progress' in event or 'progressDetail' in event:
+ image_id = event.get('id')
+ if not image_id:
+ continue
+
+ if image_id in lines:
+ diff = len(lines) - lines[image_id]
+ else:
+ lines[image_id] = len(lines)
+ stream.write("\n")
+ diff = 0
+
+ if is_terminal:
+ # move cursor up `diff` rows
+ stream.write("%c[%dA" % (27, diff))
+
+ print_output_event(event, stream, is_terminal)
+
+ if 'id' in event and is_terminal:
+ # move cursor back down
+ stream.write("%c[%dB" % (27, diff))
+
+ stream.flush()
+
+ return all_events
+
+
+def print_output_event(event, stream, is_terminal):
+ if 'errorDetail' in event:
+ raise StreamOutputError(event['errorDetail']['message'])
+
+ terminator = ''
+
+ if is_terminal and 'stream' not in event:
+ # erase current line
+ stream.write("%c[2K\r" % 27)
+ terminator = "\r"
+ pass
+ elif 'progressDetail' in event:
+ return
+
+ if 'time' in event:
+ stream.write("[%s] " % event['time'])
+
+ if 'id' in event:
+ stream.write("%s: " % event['id'])
+
+ if 'from' in event:
+ stream.write("(from %s) " % event['from'])
+
+ status = event.get('status', '')
+
+ if 'progress' in event:
+ stream.write("%s %s%s" % (status, event['progress'], terminator))
+ elif 'progressDetail' in event:
+ detail = event['progressDetail']
+ if 'current' in detail:
+ percentage = float(detail['current']) / float(detail['total']) * 100
+ stream.write('%s (%.1f%%)%s' % (status, percentage, terminator))
+ else:
+ stream.write('%s%s' % (status, terminator))
+ elif 'stream' in event:
+ stream.write("%s%s" % (event['stream'], terminator))
+ else:
+ stream.write("%s%s\n" % (status, terminator))