Source code for rattail.progress
# -*- coding: utf-8; -*-
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2019 Lance Edgar
#
# This file is part of Rattail.
#
# Rattail is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# Rattail. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
Console Stuff
"""
from __future__ import unicode_literals, absolute_import
import os
import sys
import json
import socket
import six
from progress.bar import Bar
[docs]
class ProgressBase(object):
"""
Base class for all progress implementations.
"""
def __init__(self, message, maximum):
self.message = message
self.maximum = maximum
def update(self, value):
return True
def finish(self):
pass
def destroy(self):
self.finish()
[docs]
class ConsoleProgress(ProgressBase):
"""
Provides a console-based progress bar.
"""
def __init__(self, message, maximum, stdout=None):
self.stdout = stdout or sys.stderr
self.stdout.write("\n{}...\n".format(message))
self.bar = Bar(message='', max=maximum, width=70,
suffix='%(index)d/%(max)d %(percent)d%% ETA %(eta)ds')
def update(self, value):
self.bar.next()
return True
def finish(self):
self.bar.finish()
[docs]
class FileProgress(ProgressBase):
"""
Progress indicator which writes progress info to the given file object.
"""
def __init__(self, path):
self.path = path
def __call__(self, message, maximum):
self.message = message
self.maximum = maximum
self.value = 0
self.write_info()
return self
def write_info(self):
info = {
'message': self.message,
'maximum': self.maximum,
'value': self.value,
}
with open(self.path, 'wt') as f:
f.write(json.dumps(info))
f.flush()
def update(self, value):
self.value = value
self.write_info()
return True
def finish(self):
if os.path.exists(self.path):
os.remove(self.path)
[docs]
class SocketProgress(ProgressBase):
"""
Progress indicator which writes progress info to the given socket object.
"""
def __init__(self, host, port, suffix=None):
self.host = host
self.port = port
if suffix:
self.suffix = suffix
else:
self.suffix = "\n\n.".encode('utf_8')
def __call__(self, message, maximum):
self.connection = socket.create_connection((self.host, self.port))
self.message = message
self.maximum = maximum
self.value = 0
self.write_progress()
return self
def write_data(self, data):
data = json.dumps(data)
if six.PY3:
data = data.encode('utf_8')
self.connection.send(data)
self.connection.send(self.suffix)
def write_progress(self):
self.write_data({
'message': self.message,
'maximum': self.maximum,
'value': self.value,
})
def update(self, value):
self.value = value
self.write_progress()
return True
def finish(self):
self.write_data({
'process_complete': True,
})
self.connection.close()