installer/progressbar.py
f4d17450
 #! /usr/bin/python2
 #
 #    Copyright (C) 2015 vmware inc.
 #
 #    Author: Mahmoud Bassiouny <mbassiouny@vmware.com>
 
 import curses
 import threading
 import math
 from curses import panel
 
 class ProgressBar(object):
     def __init__(self, starty, startx, width):
         self.timer = None
         self.loadding_timer = None
         self.timer_lock = threading.Lock()
         self.loadding_timer_lock = threading.Lock()
 
         self.loading_interval = 0.4
         self.loading_chars = ['    ', '.   ', '..  ', '... ', '....']
         self.loading_count = 0
 
         self.width = width - 1
 
         self.window = curses.newwin(5, width)
         self.window.bkgd(' ', curses.color_pair(2)) #defaultbackground color
         self.progress = 0
 
         self.panel = panel.new_panel(self.window)
         self.panel.move(starty, startx)
         self.panel.hide()
         panel.update_panels()
 
6b3c4668
     def initialize(self, init_message):
         self.num_items = 0
f4d17450
         self.message = init_message
         self.time_elapsed = 0
         self.time_remaining = 60
         self.timer = threading.Timer(1, self.update_time)
         self.timer.start()
 
6b3c4668
     def update_num_items(self, num_items):
         self.num_items = num_items
 
f4d17450
     def update_message(self, message):
         self.message = message
         self.render_message()
 
     def increment(self, step = 1):
         self.progress += step
         self.render_progress()
 
     def update_time(self):
         with self.timer_lock:
             if self.timer != None:
                 self.timer = threading.Timer(1, self.update_time)
                 self.timer.start()
 
         self.time_elapsed += 1
         if self.progress == 0:
             self.time_remaining = 60
         else:
             self.time_remaining = int(math.ceil(self.time_elapsed * self.num_items / float(self.progress))) - self.time_elapsed
         self.render_time()
 
     def render_message(self):
         text = self.message + (' ' * (self.width - len(self.message)))
         self.window.addstr(2, 0, text)
         self.window.refresh()
 
     def render_progress(self):
6b3c4668
         if self.num_items == 0:
             return
f4d17450
         completed = self.progress * 100 / self.num_items
         completed_width = completed * self.width / 100
         completed_str, remaining_str = self.get_spaces(completed_width, self.width, completed)
 
         self.window.addstr(0, 0, completed_str, curses.color_pair(3))
         self.window.addstr(0, completed_width, remaining_str, curses.color_pair(1))
         self.window.refresh()
 
     def render_time(self):
         timemessage = 'Elapsed time: {0} secs'.format(self.time_elapsed)
         #timemessage += ', remaining time: {0} secs'.format(self.time_remaining)
         text = timemessage + (' ' * (self.width - len(timemessage)))
         self.window.addstr(4, 0, text)
         self.window.refresh()
 
     def refresh(self):
         self.window.clear()
         self.render_message()
         self.render_time()
         self.render_progress()
 
     def show(self):
         self.refresh()
         self.panel.top()
         self.panel.show()
         panel.update_panels()
         curses.doupdate()
 
     def update_loading_symbol(self):
         with self.loadding_timer_lock:
             if self.loadding_timer != None:
                 self.loadding_timer = threading.Timer(self.loading_interval, self.update_loading_symbol)
                 self.loadding_timer.start()
 
         self.loading_count += 1
         self.render_loading()
 
     def render_loading(self):
         self.window.addstr(0, self.message_len + 1, self.loading_chars[self.loading_count % len(self.loading_chars)])
         self.window.refresh()
 
     def show_loading(self, message):
         self.loadding_timer = threading.Timer(self.loading_interval, self.update_loading_symbol)
         self.loadding_timer.start()
8a85a8a1
         self.update_loading_message(message)
f4d17450
 
8a85a8a1
     def update_loading_message(self, message):
f4d17450
         self.message_len = len(message)
         spaces = ' ' * self.width
         self.update_message(' ')
         self.window.addstr(0, 0, spaces)
         self.window.addstr(0, 0, message)
         self.render_loading()
 
     def hide(self):
         with self.timer_lock:
             if self.timer != None:
                 self.timer.cancel()
                 self.timer = None
         with self.loadding_timer_lock:
             if self.loadding_timer != None:
                 self.loadding_timer.cancel()
                 self.loadding_timer = None
 
         self.panel.hide()
         panel.update_panels()
 
     def get_spaces(self, completed_width, total_width, per):
         per = str(per) + '%'
 
         start = (total_width + 2 - len(per)) / 2
         end = start + len(per)
 
         index = 0
 
         completed_spaces = ''
         remaining_spaces = ''
         for i in range(completed_width):
             if (i in range(start, end)):
                 completed_spaces += per[index]
                 index += 1
             else:
                 completed_spaces += ' '
 
         for i in range(completed_width, total_width):
             if (i in range(start, end)):
                 remaining_spaces += per[index]
                 index += 1
             else:
                 remaining_spaces += ' '
 
         return completed_spaces, remaining_spaces