1
0
mirror of https://github.com/certbot/certbot.git synced 2026-01-21 19:01:07 +03:00
Files
certbot/letsencrypt/reporter.py
2015-09-28 15:45:31 -07:00

98 lines
3.1 KiB
Python

"""Collects and displays information to the user."""
import collections
import logging
import os
import Queue
import sys
import textwrap
import zope.interface
from letsencrypt import interfaces
from letsencrypt import le_util
logger = logging.getLogger(__name__)
class Reporter(object):
"""Collects and displays information to the user.
:ivar `Queue.PriorityQueue` messages: Messages to be displayed to
the user.
"""
zope.interface.implements(interfaces.IReporter)
HIGH_PRIORITY = 0
"""High priority constant. See `add_message`."""
MEDIUM_PRIORITY = 1
"""Medium priority constant. See `add_message`."""
LOW_PRIORITY = 2
"""Low priority constant. See `add_message`."""
_msg_type = collections.namedtuple('ReporterMsg', 'priority text on_crash')
def __init__(self):
self.messages = Queue.PriorityQueue()
def add_message(self, msg, priority, on_crash=True):
"""Adds msg to the list of messages to be printed.
:param str msg: Message to be displayed to the user.
:param int priority: One of `HIGH_PRIORITY`, `MEDIUM_PRIORITY`,
or `LOW_PRIORITY`.
:param bool on_crash: Whether or not the message should be
printed if the program exits abnormally.
"""
assert self.HIGH_PRIORITY <= priority <= self.LOW_PRIORITY
self.messages.put(self._msg_type(priority, msg, on_crash))
logger.info("Reporting to user: %s", msg)
def atexit_print_messages(self, pid=os.getpid()):
"""Function to be registered with atexit to print messages.
:param int pid: Process ID
"""
# This ensures that messages are only printed from the process that
# created the Reporter.
if pid == os.getpid():
self.print_messages()
def print_messages(self):
"""Prints messages to the user and clears the message queue.
If there is an unhandled exception, only messages for which
``on_crash`` is ``True`` are printed.
"""
bold_on = False
if not self.messages.empty():
no_exception = sys.exc_info()[0] is None
bold_on = sys.stdout.isatty()
if bold_on:
print le_util.ANSI_SGR_BOLD
print 'IMPORTANT NOTES:'
first_wrapper = textwrap.TextWrapper(
initial_indent=' - ', subsequent_indent=(' ' * 3))
next_wrapper = textwrap.TextWrapper(
initial_indent=first_wrapper.subsequent_indent,
subsequent_indent=first_wrapper.subsequent_indent)
while not self.messages.empty():
msg = self.messages.get()
if no_exception or msg.on_crash:
if bold_on and msg.priority > self.HIGH_PRIORITY:
sys.stdout.write(le_util.ANSI_SGR_RESET)
bold_on = False
lines = msg.text.splitlines()
print first_wrapper.fill(lines[0])
if len(lines) > 1:
print "\n".join(
next_wrapper.fill(line) for line in lines[1:])
if bold_on:
sys.stdout.write(le_util.ANSI_SGR_RESET)