U
    ÓZj(U  ã                   @   sø   d Z ddlZddlZddlZddlZddlmZ ddlmZ ddlm	Z	 ddl
mZ ddl
mZ ddlmZ e e¡Zd	Zd
ZdZdZdZdZdd„ Zddd„Zej e	j¡G dd„ deƒƒZdd„ Zej e	j¡G dd„ deƒƒZ dd„ Z!dd„ Z"dS )zCertbot display.é    N)Ú	constants)Úerrors)Ú
interfaces)Úmisc)Úos)Ú	completeréH   ÚokÚcancelÚhelpÚesczO- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -c              	   C   s8   |   ¡ }g }|D ]}| tj|dddd�¡ qd |¡S )zœFormat lines nicely to 80 chars.

    :param str msg: Original message

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

    éP   F)Úbreak_long_wordsÚbreak_on_hyphensÚ
)Ú
splitlinesÚappendÚtextwrapÚfillÚjoin)ÚmsgÚlinesZfixed_lÚline© r   úW/var/www/html/TRUCKING_PROJECT/venv/lib/python3.8/site-packages/certbot/display/util.pyÚ_wrap_lines%   s    	ü
r   ç     ”á@c                 C   s8   | rt j | ¡ t j ¡  t || ¡}|s.t‚| d¡S )a  Get user input with a timeout.

    Behaves the same as six.moves.input, however, an error is raised if
    a user doesn't answer after timeout seconds. The default timeout
    value was chosen to place it just under 12 hours for users following
    our advice and running Certbot twice a day.

    :param str prompt: prompt to provide for input
    :param float timeout: maximum number of seconds to wait for input

    :returns: user response
    :rtype: str

    :raises errors.Error if no answer is given before the timeout

    r   )ÚsysÚstdoutÚwriteÚflushr   Zreadline_with_timeoutÚEOFErrorÚrstrip)ÚpromptÚtimeoutr   r   r   r   Úinput_with_timeout;   s    
r%   c                       s„   e Zd ZdZ‡ fdd„Zddd„Zd d	d
„Zd!dd„Zd"dd„Zd#dd„Z	dd„ Z
dd„ Zd$dd„Zdd„ Zdd„ Zdd„ Z‡  ZS )%ÚFileDisplayzFile-based display.c                    s$   t t| ƒ ¡  || _|| _d| _d S )NF)Úsuperr&   Ú__init__ÚoutfileÚforce_interactiveÚskipped_interaction)Úselfr)   r*   ©Ú	__class__r   r   r(   _   s    zFileDisplay.__init__TFc                 C   sT   |rt |ƒ}| j djdt|d�¡ | j ¡  |rP|  |¡rFtdƒ n
t 	d¡ dS )a­  Displays a notification and waits for user acceptance.

        :param str message: Message to display
        :param bool pause: Whether or not the program should pause for the
            user's confirmation
        :param bool wrap: Whether or not the application should wrap text
        :param bool force_interactive: True if it's safe to prompt the user
            because it won't cause any workflow regressions

        ú+{line}{frame}{line}{msg}{line}{frame}{line}r   ©r   Úframer   zPress Enter to Continuez!Not pausing for user confirmationN)
r   r)   r   ÚformatÚ
SIDE_FRAMEr    Ú_can_interactr%   ÚloggerÚdebug)r,   ÚmessageÚpauseÚwrapr*   r   r   r   Únotificatione   s      ÿÿ


zFileDisplay.notificationNc	                 K   sB   |   ||||¡rt|fS |  ||¡ |  t|ƒ¡\}
}|
|d fS )aC  Display a menu.

        .. todo:: This doesn't enable the help label/button (I wasn't sold on
           any interface I came up with for this). It would be a nice feature

        :param str message: title of menu
        :param choices: Menu lines, len must be > 0
        :type choices: list of tuples (tag, item) or
            list of descriptions (tags will be enumerated)
        :param default: default value to return (if one exists)
        :param str cli_flag: option used to set this value with the CLI
        :param bool force_interactive: True if it's safe to prompt the user
            because it won't cause any workflow regressions

        :returns: tuple of (`code`, `index`) where
            `code` - str display exit code
            `index` - int index of the user's selection

        :rtype: tuple

        é   )Ú_return_defaultÚOKÚ_print_menuÚ_get_valid_int_ansÚlen)r,   r7   ÚchoicesÚok_labelÚcancel_labelÚ
help_labelÚdefaultÚcli_flagr*   Úunused_kwargsÚcodeÚ	selectionr   r   r   Úmenu}   s
    zFileDisplay.menuc                 K   sP   |   ||||¡rt|fS td| ƒd }t|ƒ}|dks@|dkrHtdfS t|fS )a  Accept input from the user.

        :param str message: message to display to the user
        :param default: default value to return (if one exists)
        :param str cli_flag: option used to set this value with the CLI
        :param bool force_interactive: True if it's safe to prompt the user
            because it won't cause any workflow regressions

        :returns: tuple of (`code`, `input`) where
            `code` - str display exit code
            `input` - str of the user's input
        :rtype: tuple

        z%s (Enter 'c' to cancel):ú ÚcÚCz-1)r<   r=   r   r%   ÚCANCEL)r,   r7   rE   rF   r*   rG   Úansr   r   r   Úinputž   s    zFileDisplay.inputÚYesÚNoc           	      K   s¶   |   ||||¡r|S t|ƒ}| j djtjttj |d�¡ | j ¡  t	djt
|ƒt
|ƒd�ƒ}| |d  ¡ ¡s„| |d  ¡ ¡rˆdS | |d  ¡ ¡s¬| |d  ¡ ¡rFdS qFdS )	až  Query the user with a yes/no question.

        Yes and No label must begin with different letters, and must contain at
        least one letter each.

        :param str message: question for the user
        :param str yes_label: Label of the "Yes" parameter
        :param str no_label: Label of the "No" parameter
        :param default: default value to return (if one exists)
        :param str cli_flag: option used to set this value with the CLI
        :param bool force_interactive: True if it's safe to prompt the user
            because it won't cause any workflow regressions

        :returns: True for "Yes", False for "No"
        :rtype: bool

        z{0}{frame}{msg}{0}{frame})r1   r   z{yes}/{no}: )ÚyesÚnor   TFN)r<   r   r)   r   r2   r   Úlinesepr3   r    r%   Ú_parens_around_charÚ
startswithÚlowerÚupper)	r,   r7   Ú	yes_labelÚno_labelrE   rF   r*   rG   rO   r   r   r   Úyesno¹   s*    
  ÿ
þÿÿzFileDisplay.yesnoc                 K   s´   |   ||||¡rt|fS |  ||¡ | jddd�\}}|tkr¦| ¡ shd dd„ tdt|ƒd ƒD ƒ¡}t|ƒ}	|  	|	|¡}
|
rˆ||
fS | j
 dtj ¡ | j
 ¡  q|g fS qd	S )
aC  Display a checklist.

        :param str message: Message to display to user
        :param list tags: `str` tags to select, len(tags) > 0
        :param default: default value to return (if one exists)
        :param str cli_flag: option used to set this value with the CLI
        :param bool force_interactive: True if it's safe to prompt the user
            because it won't cause any workflow regressions

        :returns: tuple of (`code`, `tags`) where
            `code` - str display exit code
            `tags` - list of selected tags
        :rtype: tuple

        zrSelect the appropriate numbers separated by commas and/or spaces, or leave input blank to select all options shownT)r*   rK   c                 s   s   | ]}t |ƒV  qd S ©N©Ústr)Ú.0Úxr   r   r   Ú	<genexpr>  s     z(FileDisplay.checklist.<locals>.<genexpr>r;   z!** Error - Invalid selection **%sN)r<   r=   r>   rP   Ústripr   Úranger@   Úseparate_list_inputÚ_scrub_checklist_inputr)   r   r   rU   r    )r,   r7   ÚtagsrE   rF   r*   rG   rH   rO   ÚindicesZselected_tagsr   r   r   Ú	checklistã   s$    ý
"ÿzFileDisplay.checklistc                 C   sT   |   |¡rdS |dkr>d |¡}|r2|d |¡7 }t |¡‚nt d||¡ dS dS )aÌ  Should we return the default instead of prompting the user?

        :param str prompt: prompt for the user
        :param default: default answer to prompt
        :param str cli_flag: command line option for setting an answer
            to this question
        :param bool force_interactive: if interactivity is forced by the
            IDisplay call

        :returns: True if we should return the default without prompting
        :rtype: bool

        FNz-Unable to get an answer for the question:
{0}zA
You can provide an answer on the command line with the {0} flag.z-Falling back to default %s for the prompt:
%sT)r4   r2   r   ÚErrorr5   r6   )r,   r#   rE   rF   r*   r   r   r   r   r<     s"    

ÿÿ þzFileDisplay._return_defaultc                 C   s@   | j s|stj ¡ r"| j ¡ r"dS | js<t dtj	¡ d| _dS )zêCan we safely interact with the user?

        :param bool force_interactive: if interactivity is forced by the
            IDisplay call

        :returns: True if the display can interact with the user
        :rtype: bool

        Tz�Skipped user interaction because Certbot doesn't appear to be running in a terminal. You should probably include --non-interactive or %s on the command line.F)
r*   r   ÚstdinÚisattyr)   r+   r5   Úwarningr   ZFORCE_INTERACTIVE_FLAG)r,   r*   r   r   r   r4   +  s    

ÿÿüzFileDisplay._can_interactc              
   K   s0   t  ¡ � |  ||||¡W  5 Q R £ S Q R X dS )a
  Display a directory selection screen.

        :param str message: prompt to give the user
        :param default: default value to return (if one exists)
        :param str cli_flag: option used to set this value with the CLI
        :param bool force_interactive: True if it's safe to prompt the user
            because it won't cause any workflow regressions

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

        N)r   Z	CompleterrP   )r,   r7   rE   rF   r*   rG   r   r   r   Údirectory_selectA  s    
zFileDisplay.directory_selectc                    sp   zdd„ |D ƒ}W n t k
r*   g  Y S X tt|ƒƒ}|D ] }|dk sT|tˆ ƒkr<g   S q<‡ fdd„|D ƒS )zþValidate input and transform indices to appropriate tags.

        :param list indices: input
        :param list tags: Original tags of the checklist

        :returns: valid tags the user selected
        :rtype: :class:`list` of :class:`str`

        c                 S   s   g | ]}t |ƒ‘qS r   )Úint©r`   Úindexr   r   r   Ú
<listcomp>`  s     z6FileDisplay._scrub_checklist_input.<locals>.<listcomp>r;   c                    s   g | ]}ˆ |d   ‘qS )r;   r   rp   ©rg   r   r   rr   l  s     )Ú
ValueErrorÚlistÚsetr@   )r,   rh   rg   rq   r   rs   r   rf   S  s    

z"FileDisplay._scrub_checklist_inputc                 C   sª   |r t |d tƒr dd„ |D ƒ}| j djtj|d�¡ | j ttj ¡ t|dƒD ]4\}}dj||d�}| j t	|ƒ¡ | j tj¡ qT| j ttj ¡ | j 
¡  d	S )
zãPrint a menu on the screen.

        :param str message: title of menu
        :param choices: Menu lines
        :type choices: list of tuples (tag, item) or
            list of descriptions (tags will be enumerated)

        r   c                 S   s    g | ]}d |d |d f ‘qS )z%s - %sr   r;   r   )r`   rL   r   r   r   rr   y  s     z+FileDisplay._print_menu.<locals>.<listcomp>z{new}{msg}{new})Únewr   r;   z{num}: {desc})ÚnumÚdescN)Ú
isinstanceÚtupler)   r   r2   r   rU   r3   Ú	enumerater   r    )r,   r7   rA   Úiry   r   r   r   r   r>   n  s    
ÿzFileDisplay._print_menuc                 C   s¬   d}|dkrdj |d�}nd}|dk r¤t|ƒ}| d¡sB| d¡rJtdfS z$t|ƒ}|dk sd||krld}t‚W q tk
r    | j d  tj	¡¡ | j 
¡  Y qX qt|fS )	a5  Get a numerical selection.

        :param int max: The maximum entry (len of choices), must be positive

        :returns: tuple of the form (`code`, `selection`) where
            `code` - str display exit code ('ok' or cancel')
            `selection` - int user's selection
        :rtype: tuple

        éÿÿÿÿr;   zMSelect the appropriate number [1-{max_}] then [enter] (press 'c' to cancel): )Úmax_z@Press 1 [enter] to confirm the selection (press 'c' to cancel): rL   rM   z{0}** Invalid input **{0})r2   r%   rW   rN   ro   rt   r)   r   r   rU   r    r=   )r,   r   rI   Z	input_msgrO   r   r   r   r?   ‹  s*    þ
ÿzFileDisplay._get_valid_int_ans)TTF)NNNNNF)NNF)rQ   rR   NNF)NNF)NNF)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r(   r:   rJ   rP   r\   ri   r<   r4   rn   rf   r>   r?   Ú__classcell__r   r   r-   r   r&   Y   s@       ÿ
       þ
!    ÿ
    ÿ
*    ÿ
*  ÿ
r&   c                 C   s4   d  | ¡}|r|d  |¡7 }|dk	s0|s0t|ƒ‚dS )aN  Verify that provided arguments is a valid IDisplay call.

    :param str prompt: prompt for the user
    :param default: default answer to prompt
    :param str cli_flag: command line option for setting an answer
        to this question
    :param bool force_interactive: if interactivity is forced by the
        IDisplay call

    z*Invalid IDisplay call for this prompt:
{0}z7
You can set an answer to this prompt with the {0} flagN)r2   ÚAssertionError)r#   rE   rF   r*   r   r   r   r   Úassert_valid_call°  s    
ÿr†   c                       sf   e Zd ZdZ‡ fdd„Zddd„Zdd	d
„Zddd„Zddd„Zddd„Z	ddd„Z
ddd„Z‡  ZS )ÚNoninteractiveDisplayzEAn iDisplay implementation that never asks for interactive user inputc                    s   t t| ƒ ¡  || _d S r]   )r'   r‡   r(   r)   )r,   r)   Zunused_argsrG   r-   r   r   r(   Æ  s    zNoninteractiveDisplay.__init__Ú c                 C   s<   d}||7 }|r|d| 7 }|r.|d  |¡7 }t |¡‚dS )zBError out in case of an attempt to interact in noninteractive modez<Missing command line flag or config entry for this setting:
r   z&

(You can set this with the {0} flag)N)r2   r   ZMissingCommandlineFlag)r,   r7   rF   Úextrar   r   r   r   Ú_interaction_failÊ  s    z'NoninteractiveDisplay._interaction_failFTc                 K   s4   |rt |ƒ}| j djtjt|d�¡ | j ¡  dS )a  Displays a notification without waiting for user acceptance.

        :param str message: Message to display to stdout
        :param bool pause: The NoninteractiveDisplay waits for no keyboard
        :param bool wrap: Whether or not the application should wrap text

        r/   r0   N)r   r)   r   r2   r   rU   r3   r    )r,   r7   r8   r9   rG   r   r   r   r:   Ô  s      ÿÿz"NoninteractiveDisplay.notificationNc           	      K   s&   |dkr|   ||dt|ƒ ¡ t|fS )a_  Avoid displaying a menu.

        :param str message: title of menu
        :param choices: Menu lines, len must be > 0
        :type choices: list of tuples (tag, item) or
            list of descriptions (tags will be enumerated)
        :param int default: the default choice
        :param dict kwargs: absorbs various irrelevant labelling arguments

        :returns: tuple of (`code`, `index`) where
            `code` - str display exit code
            `index` - int index of the user's selection
        :rtype: tuple
        :raises errors.MissingCommandlineFlag: if there was no default

        Nz	Choices: )rŠ   Úreprr=   )	r,   r7   rA   rB   rC   rD   rE   rF   rG   r   r   r   rJ   ã  s    zNoninteractiveDisplay.menuc                 K   s   |dkr|   ||¡ t|fS )aK  Accept input from the user.

        :param str message: message to display to the user

        :returns: tuple of (`code`, `input`) where
            `code` - str display exit code
            `input` - str of the user's input
        :rtype: tuple
        :raises errors.MissingCommandlineFlag: if there was no default

        N)rŠ   r=   ©r,   r7   rE   rF   rG   r   r   r   rP   û  s    zNoninteractiveDisplay.inputc                 K   s   |dkr|   ||¡ |S )a+  Decide Yes or No, without asking anybody

        :param str message: question for the user
        :param dict kwargs: absorbs yes_label, no_label

        :raises errors.MissingCommandlineFlag: if there was no default
        :returns: True for "Yes", False for "No"
        :rtype: bool

        N)rŠ   )r,   r7   rZ   r[   rE   rF   rG   r   r   r   r\     s    zNoninteractiveDisplay.yesnoc                 K   s$   |dkr|   ||d |¡¡ t|fS )aj  Display a checklist.

        :param str message: Message to display to user
        :param list tags: `str` tags to select, len(tags) > 0
        :param dict kwargs: absorbs default_status arg

        :returns: tuple of (`code`, `tags`) where
            `code` - str display exit code
            `tags` - list of selected tags
        :rtype: tuple

        Nz? )rŠ   r   r=   )r,   r7   rg   rE   rF   rG   r   r   r   ri     s    zNoninteractiveDisplay.checklistc                 K   s   |   |||¡S )a“  Simulate prompting the user for a directory.

        This function returns default if it is not ``None``, otherwise,
        an exception is raised explaining the problem. If cli_flag is
        not ``None``, the error message will include the flag that can
        be used to set this value with the CLI.

        :param str message: prompt to give the user
        :param default: default value to return (if one exists)
        :param str cli_flag: option used to set this value with the CLI

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

        )rP   rŒ   r   r   r   rn   -  s    z&NoninteractiveDisplay.directory_select)rˆ   )FT)NNNNN)NN)NNNN)NN)NN)r€   r�   r‚   rƒ   r(   rŠ   r:   rJ   rP   r\   ri   rn   r„   r   r   r-   r   r‡   Â  s(   


      ÿ

    ÿ
  ÿ
  ÿr‡   c                 C   s   |   dd¡}dd„ | ¡ D ƒS )zƒSeparate a comma or space separated list.

    :param str input_: input from the user

    :returns: strings
    :rtype: list

    ú,rK   c                 S   s   g | ]}t |ƒ‘qS r   r^   )r`   Ústringr   r   r   rr   N  s     z'separate_list_input.<locals>.<listcomp>)ÚreplaceÚsplit)Zinput_Z	no_commasr   r   r   re   B  s    	re   c                 C   s   dj | d | dd… d�S )znPlace parens around first character of label.

    :param str label: Must contain at least one character

    z({first}){rest}r   r;   N)ÚfirstÚrest)r2   )Úlabelr   r   r   rV   Q  s    rV   )Nr   )#rƒ   Úloggingr   r   Zzope.interfaceZzopeZcertbotr   r   r   Zcertbot.compatr   r   Zcertbot.displayr   Ú	getLoggerr€   r5   ZWIDTHr=   rN   ZHELPZESCr3   r   r%   Z	interfaceZimplementerZIDisplayÚobjectr&   r†   r‡   re   rV   r   r   r   r   Ú<module>   s8   

  X