<commit_before>"""Let's Encrypt display."""
import os
import textwrap

import dialog
import zope.interface

from letsencrypt import interfaces
from letsencrypt import errors

WIDTH = 72
HEIGHT = 20

# Display exit codes
OK = "ok"
"""Display exit code indicating user acceptance."""

CANCEL = "cancel"
"""Display exit code for a user canceling the display."""

HELP = "help"
"""Display exit code when for when the user requests more help."""

def _wrap_lines(msg):
    """Format lines nicely to 80 chars.

    :param str msg: Original message

    :returns: Formatted message respecting newlines in message
    :rtype: str

    """
    lines = msg.splitlines()
    fixed_l = []
    for line in lines:
        fixed_l.append(textwrap.fill(line, 80))
    return os.linesep.join(fixed_l)

class NcursesDisplay(object):
    """Ncurses-based display."""

    zope.interface.implements(interfaces.IDisplay)

    def __init__(self, width=WIDTH, height=HEIGHT):
        super(NcursesDisplay, self).__init__()
        self.dialog = dialog.Dialog()
        self.width = width
        self.height = height

    def notification(self, message, height=10, pause=False):
        # pylint: disable=unused-argument
        """Display a notification to the user and wait for user acceptance.

        .. todo:: It probably makes sense to use one of the transient message
            types for pause. It isn't straightforward how best to approach
            the matter though given the context of our messages.
            http://pythondialog.sourceforge.net/doc/widgets.html#displaying-transient-messages

        :param str message: Message to display
        :param int height: Height of the dialog box
        :param bool pause: Not applicable to NcursesDisplay

        """
        self.dialog.msgbox(message, height, width=self.width)

    def menu(self, message, choices, ok_label="OK", cancel_label="Cancel",
             help_label="", **_kwargs):
        """Display a menu.

        :param str message: title of menu

        :param choices: menu lines, len must be > 0
        :type choices: list of tuples (`tag`, `item`) tags must be unique or
            list of items (tags will be enumerated)

        :param str ok_label: label of the OK button
        :param str help_label: label of the help button
        :param dict _kwargs: absorbs default / cli_args

        :returns: tuple of the form (code, tag) where
            code - int display exit code
            tag - str corresponding to the item chosen
        :rtype: tuple

        """
        menu_options = {
            "choices": choices,
            "ok_label": ok_label,
            "cancel_label": cancel_label,
            "help_button": bool(help_label),
            "help_label": help_label,
            "width": self.width,
            "height": self.height,
            "menu_height": self.height - 6,
        }

        # Can accept either tuples or just the actual choices
        if choices and isinstance(choices[0], tuple):
            # pylint: disable=star-args
            code, selection = self.dialog.menu(message, **menu_options)

            # Return the selection index
            for i, choice in enumerate(choices):
                if choice[0] == selection:
                    return code, i

            return code, -1

        else:
            # "choices" is not formatted the way the dialog.menu expects...
            menu_options["choices"] = [
                (str(i), choice) for i, choice in enumerate(choices, 1)
            ]
            # pylint: disable=star-args
            code, tag = self.dialog.menu(message, **menu_options)

            if code == CANCEL:
                return code, -1

            return code, int(tag) - 1


    def input(self, message, **_kwargs):
        """Display an input box to the user.

        :param str message: Message to display that asks for input.
        :param dict _kwargs: absorbs default / cli_args

        :returns: tuple of the form (code, string) where
            `code` - int display exit code
            `string` - input entered by the user

        """
        sections = message.split("\n")
        # each section takes at least one line, plus extras if it's longer than self.width
        wordlines = [1 + (len(section)/self.width) for section in sections]
        height = 6 + sum(wordlines) + len(sections)
        return self.dialog.inputbox(message, width=self.width, height=height)


    def yesno(self, message, yes_label="Yes", no_label="No", **_kwargs):
        """Display a Yes/No dialog box.

        Yes and No label must begin with different letters.

        :param str message: message to display to user
        :param str yes_label: label on the "yes" button
        :param str no_label: label on the "no" button
        :param dict _kwargs: absorbs default / cli_args

        :returns: if yes_label was selected
        :rtype: bool

        """
        return self.dialog.DIALOG_OK == self.dialog.yesno(
            message, self.height, self.width,
            yes_label=yes_label, no_label=no_label)

    def checklist(self, message, tags, default_status=True, **_kwargs):
        """Displays a checklist.

        :param message: Message to display before choices
        :param list tags: where each is of type :class:`str` len(tags) > 0
        :param bool default_status: If True, items are in a selected state by
            default.
        :param dict _kwargs: absorbs default / cli_args


        :returns: tuple of the form (code, list_tags) where<commit_msg>Use sphinx backticks more consistently<commit_after>"""Let's Encrypt display."""
import os
import textwrap

import dialog
import zope.interface

from letsencrypt import interfaces
from letsencrypt import errors

WIDTH = 72
HEIGHT = 20

# Display exit codes
OK = "ok"
"""Display exit code indicating user acceptance."""

CANCEL = "cancel"
"""Display exit code for a user canceling the display."""

HELP = "help"
"""Display exit code when for when the user requests more help."""

def _wrap_lines(msg):
    """Format lines nicely to 80 chars.

    :param str msg: Original message

    :returns: Formatted message respecting newlines in message
    :rtype: str

    """
    lines = msg.splitlines()
    fixed_l = []
    for line in lines:
        fixed_l.append(textwrap.fill(line, 80))
    return os.linesep.join(fixed_l)

class NcursesDisplay(object):
    """Ncurses-based display."""

    zope.interface.implements(interfaces.IDisplay)

    def __init__(self, width=WIDTH, height=HEIGHT):
        super(NcursesDisplay, self).__init__()
        self.dialog = dialog.Dialog()
        self.width = width
        self.height = height

    def notification(self, message, height=10, pause=False):
        # pylint: disable=unused-argument
        """Display a notification to the user and wait for user acceptance.

        .. todo:: It probably makes sense to use one of the transient message
            types for pause. It isn't straightforward how best to approach
            the matter though given the context of our messages.
            http://pythondialog.sourceforge.net/doc/widgets.html#displaying-transient-messages

        :param str message: Message to display
        :param int height: Height of the dialog box
        :param bool pause: Not applicable to NcursesDisplay

        """
        self.dialog.msgbox(message, height, width=self.width)

    def menu(self, message, choices, ok_label="OK", cancel_label="Cancel",
             help_label="", **_kwargs):
        """Display a menu.

        :param str message: title of menu

        :param choices: menu lines, len must be > 0
        :type choices: list of tuples (`tag`, `item`) tags must be unique or
            list of items (tags will be enumerated)

        :param str ok_label: label of the OK button
        :param str help_label: label of the help button
        :param dict _kwargs: absorbs default / cli_args

        :returns: tuple of the form (`code`, `tag`) where
            `code` - int display exit code
            `tag` - str corresponding to the item chosen
        :rtype: tuple

        """
        menu_options = {
            "choices": choices,
            "ok_label": ok_label,
            "cancel_label": cancel_label,
            "help_button": bool(help_label),
            "help_label": help_label,
            "width": self.width,
            "height": self.height,
            "menu_height": self.height - 6,
        }

        # Can accept either tuples or just the actual choices
        if choices and isinstance(choices[0], tuple):
            # pylint: disable=star-args
            code, selection = self.dialog.menu(message, **menu_options)

            # Return the selection index
            for i, choice in enumerate(choices):
                if choice[0] == selection:
                    return code, i

            return code, -1

        else:
            # "choices" is not formatted the way the dialog.menu expects...
            menu_options["choices"] = [
                (str(i), choice) for i, choice in enumerate(choices, 1)
            ]
            # pylint: disable=star-args
            code, tag = self.dialog.menu(message, **menu_options)

            if code == CANCEL:
                return code, -1

            return code, int(tag) - 1


    def input(self, message, **_kwargs):
        """Display an input box to the user.

        :param str message: Message to display that asks for input.
        :param dict _kwargs: absorbs default / cli_args

        :returns: tuple of the form (`code`, `string`) where
            `code` - int display exit code
            `string` - input entered by the user

        """
        sections = message.split("\n")
        # each section takes at least one line, plus extras if it's longer than self.width
        wordlines = [1 + (len(section)/self.width) for section in sections]
        height = 6 + sum(wordlines) + len(sections)
        return self.dialog.inputbox(message, width=self.width, height=height)


    def yesno(self, message, yes_label="Yes", no_label="No", **_kwargs):
        """Display a Yes/No dialog box.

        Yes and No label must begin with different letters.

        :param str message: message to display to user
        :param str yes_label: label on the "yes" button
        :param str no_label: label on the "no" button
        :param dict _kwargs: absorbs default / cli_args

        :returns: if yes_label was selected
        :rtype: bool

        """
        return self.dialog.DIALOG_OK == self.dialog.yesno(
            message, self.height, self.width,
            yes_label=yes_label, no_label=no_label)

    def checklist(self, message, tags, default_status=True, **_kwargs):
        """Displays a checklist.

        :param message: Message to display before choices
        :param list tags: where each is of type :class:`str` len(tags) > 0
        :param bool default_status: If True, items are in a selected state by
            default.
        :param dict _kwargs: absorbs default / cli_args


        :returns: tuple of the form (`code`, `list_tags`) where
{'fraction_non_alphanumeric': 0.09321957790749888, 'fraction_numerical': 0.0037718904355635383, 'mean_word_length': 2.2839870244765557, 'pattern_counts': {'":': 16, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2945109', 'n_tokens_mistral': 3099, 'n_tokens_neox': 2942, 'n_words': 1117}