
    M/eW                     t   d 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	 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 ddlmZ  ej*                  e      ZdZ	 dZ	 dZ	  G d d      Z e       Z e
d      Z G d d      Z G d d      Zdeeef   fdZ deeef   ddfdZ!y)zFThis modules define the actual display implementations used in Certbot    N)Any)Iterable)List)Optional)TextIO)Tuple)TypeVar)Union)errors)	constants)	completer)util)osokcancelzO- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -c                       e Zd ZddZy)_DisplayServiceNc                     d | _         y Ndisplay)selfs    ?/usr/lib/python3/dist-packages/certbot/_internal/display/obj.py__init__z_DisplayService.__init__)   s	    LP    )returnN)__name__
__module____qualname__r    r   r   r   r   (   s    Qr   r   Tc                       e Zd ZdZdededdf fdZ	 	 d#deded	eded
eddfdZ	 	 	 d$dede	e
eeef      e
e   f   dee   dee   dee   dee   dee   dededeeef   fdZ	 	 d%dedee   dee   dededeeef   fdZ	 	 	 d&dedededee   dee   dededefdZ	 	 d%dede
e   dee
e      dee   dededeee
e   f   fdZdedee   dee   dedee   f
dZdedefdZ	 	 d%dedee   dee   dededeeef   fdZdee	eef      de
e   de
e   fdZdede	e
eeef      e
e   f   ddfd Zd!edeeef   fd"Z xZS )'FileDisplayzFile-based display.outfileforce_interactiver   Nc                 L    t         |           || _        || _        d| _        y )NF)superr   r$   r%   skipped_interaction)r   r$   r%   	__class__s      r   r   zFileDisplay.__init__6   s%    !2#( r   messagepausewrapdecoratec                    |rt        j                  |      }t        j                  d|       | j                  j                  |rdnddz   |rdndz   j                  t        j                  t        |             | j                  j                          |r=| j                  |      rt        j                  d       y	t        j                  d       y	y	)
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
        :param bool decorate: Whether to surround the message with a
            decorated frame

        Notifying user: %s{line}{frame}{line} {msg}{line}{frame}{line}lineframemsgzPress Enter to Continuez!Not pausing for user confirmationN)r   
wrap_linesloggerdebugr$   writeformatr   linesep
SIDE_FRAMEflush_can_interactinput_with_timeout)r   r*   r+   r,   r%   r-   s         r   notificationzFileDisplay.notification<   s     oog.G)73'/#R!)or3 RZZzwG		
 	!!"34''(AB@A	 r   choicesok_labelcancel_label
help_labeldefaultcli_flagunused_kwargsc	                     | j                  ||||      }
|
t        |
fS | j                  ||       | j                  t	        |            \  }}||dz
  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   r*   rC   rD   rE   rF   rG   rH   r%   rI   return_defaultcode	selections                r   menuzFileDisplay.menu]   sc    4 --gwJ[\%~%%'*11#g,?iY]""r   c                     | j                  ||||      }|t        |fS t        j                  d|z        dz   }t        j                  |      }|dv rt
        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)rL   rM   r   r8   rA   CANCEL)r   r*   rG   rH   r%   rI   rQ   anss           r   inputzFileDisplay.input   sr      --gwJ[\%~%% //"="GH3N%%g.*4<3wr   	yes_labelno_labelc                    | j                  ||||      }||S t        j                  |      }| j                  j	                  dj                  t        j                  t        t        j                  z   |             | j                  j                          	 t        j                  dj                  t        j                  |      t        j                  |                  }	|	j                  |d   j                               s"|	j                  |d   j                               ry|	j                  |d   j                               s"|	j                  |d   j                               ry)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})r6   r7   Tz{yes}/{no}: )yesnor   F)rL   r   r8   r$   r;   r<   r   r=   r>   r?   rA   parens_around_char
startswithlowerupper)
r   r*   r\   r]   rG   rH   r%   rI   rQ   rZ   s
             r   yesnozFileDisplay.yesno   s3   ( --gwJ[\%!!//'*6==JJj2::57 > D 	E)).*?*?++I6**84 +@ +6 7C y|1134y|1134x{0023x{0023 r   tagsc           	         | j                  ||||      }|t        |fS 	 | j                  ||       | j                  dd      \  }}	|t        k(  r|	j	                         s.dj                  d t        dt        |      dz         D              }	t        j                  |	      }
| j                  |
|      }|r||fS | j                  j                  dt        j                  z         | j                  j                          n|g f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

        TzrSelect the appropriate numbers separated by commas and/or spaces, or leave input blank to select all options shown)r%   rV   c              3   2   K   | ]  }t        |        y wr   )str).0xs     r   	<genexpr>z(FileDisplay.checklist.<locals>.<genexpr>   s     "Ia3q6"Is   rK   z!** Error - Invalid selection **%s)rL   rM   rN   r[   stripjoinrangerP   r   separate_list_input_scrub_checklist_inputr$   r;   r   r=   r?   )r   r*   rf   rG   rH   r%   rI   rQ   rR   rZ   indicesselected_tagss               r   	checklistzFileDisplay.checklist   s   $ --gwJ[\%~%%Wd+

 $G 6: # ;ID#
 rzyy{(("I5CIaK3H"IIC2237 $ ; ;GT J ..""7"**DF""$Rx' r   promptc                     | j                  |      ry|<dj                  |      }|r|dj                  |      z  }t        j                  |      t        j                  d||       |S )a  Should we return the default instead of prompting the user?

        :param str prompt: prompt for the user
        :param T 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

        :returns: The default value if we should return it else `None`
        :rtype: T or `None`

        Nz-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:
%s)r@   r<   r   Errorr9   r:   )r   ru   rG   rH   r%   r7   s         r   rL   zFileDisplay._return_default   st     /0?BII&QC66<fX6FH ,,s##<V	 r   c                     | j                   s:|s8t        j                  j                         r| j                  j                         ry| j
                  s+t        j                  dt        j                         d| _        y)zCan we safely interact with the user?

        :param bool force_interactive: if interactivity is forced

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

        TzSkipped 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%   sysstdinisattyr$   r(   r9   warningr   FORCE_INTERACTIVE_FLAG)r   r%   s     r   r@   zFileDisplay._can_interact  sd     ""&7II4<<#6#6#8''NN? 00	2
 (,D$r   c                 ~    t        j                         5  | j                  ||||      cddd       S # 1 sw Y   yxY w)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   	Completerr[   )r   r*   rG   rH   r%   rI   s         r   directory_selectzFileDisplay.directory_select'  s<        " 	M::gw:KL	M 	M 	Ms   3<rr   c                     	 |D cg c]  }t        |       }}t        t        |            }|D ]  }|dk  s|t	        |      kD  sg c S  |D cg c]
  }||dz
      c}S c c}w # t        $ r g cY S w xY wc c}w )zValidate 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`

        rK   )int
ValueErrorlistsetrP   )r   rr   rf   indexindices_ints        r   rq   z"FileDisplay._scrub_checklist_input:  s    	3:;%3u:;K;
 3{+, ! 	EqyECI-		 .99EUQY99 < 	I	 :s'   A' A"A' A8"A' 'A54A5c                    |r-t        |d   t              r|D cg c]  }|d    d|d     }}| j                  j                  t        j
                   | t        j
                          | j                  j                  t        t        j
                  z          t        |d      D ]c  \  }}| d| }| j                  j                  t        j                  |             | j                  j                  t        j
                         e | j                  j                  t        t        j
                  z          | j                  j                          yc c}w )zPrint 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   z - rK   z: N)
isinstancetupler$   r;   r   r=   r>   	enumerater   r8   r?   )r   r*   rC   rW   idescr7   s          r   rN   zFileDisplay._print_menuU  s    z'!*e43:;a!A$s1Q4&);G; 	bjj\'2::,?@:

23 !!, 	+GAtCr$.CLLts34 LLrzz*	+ 	:

23 <s   Emax_c                    d}|dkD  rdj                  |      }nd}|dk  rdt        j                  |      }|j                  d      s|j                  d      rt        dfS 	 t        |      }|dk  s||kD  rd}t        	 |dk  rdt        |fS # t        $ rU | j                  j                  dj                  t        j                               | j                  j                          Y kw xY w)	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

        rK   zMSelect the appropriate number [1-{max_}] then [enter] (press 'c' to cancel): )r   z@Press 1 [enter] to confirm the selection (press 'c' to cancel): rW   rX   z{0}** Invalid input **{0})r<   r   rA   rb   rY   r   r   r$   r;   r   r=   r?   rM   )r   r   rS   	input_msgrZ   s        r   rO   zFileDisplay._get_valid_int_ansr  s     	!8%%+VV%6 3I!m)))4C~~c"cnnS&9rz!	%H	q=I$4 "I$$ %5 !m 9}  %""/66rzzBD""$%s   "B AC,+C,)TTFT)NNNNNF)NNF)YesNoNNF)r   r   r   __doc__r   boolr   ri   rB   r
   r   r   r   r   r   rT   r[   re   rt   r!   rL   r@   r   r   rq   rN   rO   __classcell__r)   s   @r   r#   r#   2   s1   ) )4 )D ) KOGKBC B B4 B(,B@DBPTBD LPHLGL"#C "#%U38_0EtCy0P*Q "#}"#;CC="#!#"#8@"#  }"# AE"# "	"# ',CHo	"#H \`(-S 8C= 8TW= !%@CHMcSVh: KOHL(-*S *S *C *~*8@*!%*@C*HL*X W[LQ)  ) DI ) c@S ) $SM) EI) #&) +0d3i+@) Vc HQK "*3-DHMUVW[:t  * GKSXM Mhsm M#+C=MLPM*-M27S/M&:huS#X.G :%)#Y:379:63 "4c3h#8$s)#CDIM:"s "uS#X "r   r#   c                       e Zd ZdZdedededdf fdZ	 dded	ee   d
ede	j                  fdZ	 	 ddedededededdfdZ	 	 	 ddedeeeeef      ee   f   dee   dee   dee   dee   d	ee   dedeeef   fdZd dedee   d	ee   dedeeef   f
dZ	 	 d!dedee   dee   dee   d	ee   dedefdZ	 	 d dedee   deee      d	ee   dedeeee   f   fdZ	 	 d dedee   d	ee   dedeeef   f
dZ xZS )"NoninteractiveDisplayzKA display utility implementation that never asks for interactive user inputr$   unused_argsrI   r   Nc                 0    t         |           || _        y r   )r'   r   r$   )r   r$   r   rI   r)   s       r   r   zNoninteractiveDisplay.__init__  s    r   r*   rH   extrac                 z    d}||z  }|r|d|z   z  }|r|dj                  |      z  }t        j                  |      S )zNReturn error to raise in case of an attempt to interact in noninteractive modez<Missing command line flag or config entry for this setting:

z&

(You can set this with the {0} flag))r<   r   MissingCommandlineFlag)r   r*   rH   r   r7   s        r   _interaction_failz'NoninteractiveDisplay._interaction_fail  sN     Nw4%<C=DDXNNC,,S11r   r+   r,   r-   c                 ,   |rt        j                  |      }t        j                  d|       | j                  j                  |rdnddz   |rdndz   j                  t        j                  t        |             | j                  j                          y)ae  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
        :param bool decorate: Whether to apply a decorated frame to the message

        r/   r0   r1   r2   r3   r4   N)r   r8   r9   r:   r$   r;   r<   r   r=   r>   r?   )r   r*   r+   r,   r-   rI   s         r   rB   z"NoninteractiveDisplay.notification  sz     oog.G)73'/#R!)or3 RZZzwG		
 	r   rC   rD   rE   rF   rG   c                 T    || j                  ||dt        |      z         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

        z	Choices: )r   reprrM   )	r   r*   rC   rD   rE   rF   rG   rH   rI   s	            r   rT   zNoninteractiveDisplay.menu  s1    * ?(((K$w-<WXX7{r   c                 :    || j                  ||      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

        )r   rM   r   r*   rG   rH   rI   s        r   r[   zNoninteractiveDisplay.input  s&     ?(((;;7{r   r\   r]   c                 .    || j                  ||      |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

        )r   )r   r*   r\   r]   rG   rH   rI   s          r   re   zNoninteractiveDisplay.yesno  s!     ?(((;;r   rf   c                 `    |%| j                  ||dj                  |      dz         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

        z? ?)r   rn   rM   )r   r*   rf   rG   rH   rI   s         r   rt   zNoninteractiveDisplay.checklist  s5     ?(((DIIdOc<QRR7{r   c                 (    | j                  |||      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

        )r[   r   s        r   r   z&NoninteractiveDisplay.directory_select  s    $ zz'7H55r   )r1   )FTT)NNNNN)NN)NNNN)r   r   r   r   r   r   r   ri   r   r   r   r   r   rB   r
   r   r   r   rT   r[   re   r   rt   r   r   r   s   @r   r   r     sh   U c C TX 
 (*	2 	2 	2!$	2.4.K.K	2 LP&*C  D #=@EI0 LPHL'+C %U38_0EtCy0P*Q };CC=!#8@  } ?B GLCQTHo4S 8C= 8TW= "',S#X" ^bHLS Xc] XVY] ~8@"'+" [_,0 HSM HTRUYDW $SMCFKPQTVZ[^V_Q_K`$ GK376 6hsm 6#+C=6JM6RWX[]`X`Ra6r   r   r   c                  X    t         j                  st        d      t         j                  S )zGet the display utility.

    :return: the display utility
    :rtype: Union[FileDisplay, NoninteractiveDisplay]
    :raise: ValueError if the display utility is not configured yet.

    zlThis function was called too early in Certbot's execution as the display utility hasn't been configured yet.)_SERVICEr   r   r    r   r   get_displayr   #  s.      N O 	Or   r   c                     | t         _        y)zqSet the display service.

    :param Union[FileDisplay, NoninteractiveDisplay] display: the display service

    N)r   r   r   s    r   set_displayr   1  s     Hr   )"r   loggingry   typingr   r   r   r   r   r   r	   r
   certbotr   certbot._internalr   certbot._internal.displayr   r   certbot.compatr   	getLoggerr   r9   rM   rY   r>   r   r   r!   r#   r   r   r   r    r   r   <module>r      s    L  
          ' / * 			8	$ 
 3	 9 
Q Q
 CLb bJI6 I6XU;(==> {,AAB t r   