cli: Teach quizzer.cli.main() the --ui option
authorW. Trevor King <wking@tremily.us>
Wed, 13 Mar 2013 21:23:26 +0000 (17:23 -0400)
committerW. Trevor King <wking@tremily.us>
Wed, 13 Mar 2013 21:41:23 +0000 (17:41 -0400)
This uses the new quizzer.ui.INTERFACES and quizzer.ui.get_ui() to
select from among the available interfaces (currently just the command
line interface).

quizzer/cli.py
quizzer/ui/__init__.py

index e0d0ced3d76aa743761bde0bb1ab01b4c8c67840..0115f4b30968b41940ed0a2201f9e6d417b0bbba 100644 (file)
@@ -21,7 +21,7 @@ from . import __doc__ as _module_doc
 from . import __version__
 from . import answerdb as _answerdb
 from . import quiz as _quiz
-from .ui import cli as _cli
+from . import ui as _ui
 
 
 def main():
@@ -51,6 +51,9 @@ def main():
         '--questions', action='store_const', const=True, default=False,
         help=('instead of running the quiz, '
               'print a list of questions on the stack'))
+    parser.add_argument(
+        '-u', '--ui', choices=_ui.INTERFACES, default=_ui.INTERFACES[0],
+        help='select a user interface')
     parser.add_argument(
         'quiz', metavar='QUIZ',
         help='path to a quiz file')
@@ -85,7 +88,8 @@ def main():
             print(q.format_prompt())
             print()
         return
-    ui = _cli.CommandLineInterface(quiz=quiz, answers=answers, stack=stack)
+    ui_class = _ui.get_ui(args.ui)
+    ui = ui_class(quiz=quiz, answers=answers, stack=stack)
     try:
         ui.run()
     finally:
index 0db903cb53ef5a876aab4fd19bae3628c4958514..333c6c02c24cc9fb76f92ca4f54abb0e5dc40090 100644 (file)
 # You should have received a copy of the GNU General Public License along with
 # quizzer.  If not, see <http://www.gnu.org/licenses/>.
 
+import importlib as _importlib
+
 from .. import answerdb as _answerdb
 
 
+INTERFACES = ['cli']
+
+
 class UserInterface (object):
     "Give a quiz over a generic user interface"
     def __init__(self, quiz=None, answers=None, stack=None):
@@ -44,3 +49,21 @@ class UserInterface (object):
             for qid in reversed(question.dependencies):
                 self.stack.insert(0, self.quiz.get(id=qid))
         return correct
+
+
+def get_ui(name):
+    """Get the UserInterface subclass from a UI submodule
+
+    >>> get_ui('cli')
+    <class 'quizzer.ui.cli.CommandLineInterface'>
+    """
+    module = _importlib.import_module('{}.{}'.format(__name__, name))
+    for name in dir(module):
+        obj = getattr(module, name)
+        try:
+            subclass = issubclass(obj, UserInterface)
+        except TypeError as e:  # obj is not a class
+            continue
+        if subclass:
+            return obj
+    raise ValueError(name)