Repository: certbot/certbot

Issue:
Using dialog in small terminals
We have hard coded that the dialog window be 24 characters tall and 72 characters wide in `letsencrypt/display/util.py`. If the terminal is smaller than that, `dialog` raises an exception. This exception may be unnecessary because the requested `dialog` widget may fit in a terminal smaller than 24 x 72.

`dialog` has the ability to [autosize widgets](http://pythondialog.sourceforge.net/doc/Dialog_class_overview.html#autowidgetsize) which we might want to use. If we take this route, we should do the following:
1. Make sure this works on all system with both new and old version of `dialog`.
2. Make sure we're happy with how the autosized widgets look.



Discussion:

Resolving patch:
diff --git a/certbot/display/util.py b/certbot/display/util.py
--- a/certbot/display/util.py
+++ b/certbot/display/util.py
@@ -82,7 +82,7 @@ class NcursesDisplay(object):
 
     def __init__(self, width=WIDTH, height=HEIGHT):
         super(NcursesDisplay, self).__init__()
-        self.dialog = dialog.Dialog()
+        self.dialog = dialog.Dialog(autowidgetsize=True)
         assert OK == self.dialog.DIALOG_OK, "What kind of absurdity is this?"
         self.width = width
         self.height = height
@@ -101,7 +101,7 @@ def notification(self, message, height=10, pause=False):
         :param bool pause: Not applicable to NcursesDisplay
 
         """
-        self.dialog.msgbox(message, height, width=self.width)
+        self.dialog.msgbox(message)
 
     def menu(self, message, choices, ok_label="OK", cancel_label="Cancel",
              help_label="", **unused_kwargs):
@@ -170,11 +170,7 @@ def input(self, message, **unused_kwargs):
             `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 _clean(self.dialog.inputbox(message, width=self.width, height=height))
+        return self.dialog.inputbox(message)
 
     def yesno(self, message, yes_label="Yes", no_label="No", **unused_kwargs):
         """Display a Yes/No dialog box.
@@ -191,8 +187,7 @@ def yesno(self, message, yes_label="Yes", no_label="No", **unused_kwargs):
 
         """
         return self.dialog.DIALOG_OK == self.dialog.yesno(
-            message, self.height, self.width,
-            yes_label=yes_label, no_label=no_label)
+            message, yes_label=yes_label, no_label=no_label)
 
     def checklist(self, message, tags, default_status=True, **unused_kwargs):
         """Displays a checklist.
@@ -210,8 +205,7 @@ def checklist(self, message, tags, default_status=True, **unused_kwargs):
 
         """
         choices = [(tag, "", default_status) for tag in tags]
-        return _clean(self.dialog.checklist(
-            message, width=self.width, height=self.height, choices=choices))
+        return self.dialog.checklist(message, choices=choices)
 
     def directory_select(self, message, **unused_kwargs):
         """Display a directory selection screen.
@@ -224,9 +218,8 @@ def directory_select(self, message, **unused_kwargs):
 
         """
         root_directory = os.path.abspath(os.sep)
-        return _clean(self.dialog.dselect(
-            filepath=root_directory, width=self.width,
-            height=self.height, help_button=True, title=message))
+        return self.dialog.dselect(
+            filepath=root_directory, help_button=True, title=message)
 
 
 @zope.interface.implementer(interfaces.IDisplay)


Test patch:
diff --git a/certbot/tests/display/util_test.py b/certbot/tests/display/util_test.py
--- a/certbot/tests/display/util_test.py
+++ b/certbot/tests/display/util_test.py
@@ -107,8 +107,7 @@ def test_yesno(self, mock_yesno):
         self.assertTrue(self.displayer.yesno("message"))
 
         mock_yesno.assert_called_with(
-            "message", display_util.HEIGHT, display_util.WIDTH,
-            yes_label="Yes", no_label="No")
+            "message", yes_label="Yes", no_label="No")
 
     @mock.patch("certbot.display.util."
                 "dialog.Dialog.checklist")
@@ -121,9 +120,7 @@ def test_checklist(self, mock_checklist):
             (TAGS[1], "", True),
             (TAGS[2], "", True),
         ]
-        mock_checklist.assert_called_with(
-            "message", width=display_util.WIDTH, height=display_util.HEIGHT,
-            choices=choices)
+        mock_checklist.assert_called_with("message", choices=choices)
 
     @mock.patch("certbot.display.util.dialog.Dialog.dselect")
     def test_directory_select(self, mock_dselect):