display_ops.py
1 """Contains UI methods for Apache operations.""" 2 import logging 3 import os 4 5 import zope.component 6 7 from letsencrypt import interfaces 8 9 import letsencrypt.display.util as display_util 10 11 12 logger = logging.getLogger(__name__) 13 14 15 def select_vhost(domain, vhosts): 16 """Select an appropriate Apache Vhost. 17 18 :param vhosts: Available Apache Virtual Hosts 19 :type vhosts: :class:`list` of type `~obj.Vhost` 20 21 :returns: VirtualHost or `None` 22 :rtype: `~obj.Vhost` or `None` 23 24 """ 25 if not vhosts: 26 return None 27 while True: 28 code, tag = _vhost_menu(domain, vhosts) 29 if code == display_util.HELP: 30 _more_info_vhost(vhosts[tag]) 31 elif code == display_util.OK: 32 return vhosts[tag] 33 else: 34 return None 35 36 37 def _vhost_menu(domain, vhosts): 38 """Select an appropriate Apache Vhost. 39 40 :param vhosts: Available Apache Virtual Hosts 41 :type vhosts: :class:`list` of type `~obj.Vhost` 42 43 :returns: Display tuple - ('code', tag') 44 :rtype: `tuple` 45 46 """ 47 # Free characters in the line of display text (9 is for ' | ' formatting) 48 free_chars = display_util.WIDTH - len("HTTPS") - len("Enabled") - 9 49 50 if free_chars < 2: 51 logger.debug("Display size is too small for " 52 "letsencrypt_apache.display_ops._vhost_menu()") 53 # This runs the edge off the screen, but it doesn't cause an "error" 54 filename_size = 1 55 disp_name_size = 1 56 else: 57 # Filename is a bit more important and probably longer with 000-* 58 filename_size = int(free_chars * .6) 59 disp_name_size = free_chars - filename_size 60 61 choices = [] 62 for vhost in vhosts: 63 if len(vhost.get_names()) == 1: 64 disp_name = next(iter(vhost.get_names())) 65 elif len(vhost.get_names()) == 0: 66 disp_name = "" 67 else: 68 disp_name = "Multiple Names" 69 70 choices.append( 71 "{fn:{fn_size}s} | {name:{name_size}s} | {https:5s} | " 72 "{active:7s}".format( 73 fn=os.path.basename(vhost.filep)[:filename_size], 74 name=disp_name[:disp_name_size], 75 https="HTTPS" if vhost.ssl else "", 76 active="Enabled" if vhost.enabled else "", 77 fn_size=filename_size, 78 name_size=disp_name_size) 79 ) 80 81 code, tag = zope.component.getUtility(interfaces.IDisplay).menu( 82 "We were unable to find a vhost with a ServerName or Address of {0}.{1}" 83 "Which virtual host would you like to choose?".format( 84 domain, os.linesep), 85 choices, help_label="More Info", ok_label="Select") 86 87 return code, tag 88 89 90 def _more_info_vhost(vhost): 91 zope.component.getUtility(interfaces.IDisplay).notification( 92 "Virtual Host Information:{0}{1}{0}{2}".format( 93 os.linesep, "-" * (display_util.WIDTH - 4), str(vhost)), 94 height=display_util.HEIGHT)