Imported from archive.
[mudpy.git] / lib / muff / muffmenu.py
index 0a9989b..b84f783 100644 (file)
 """Menu objects for the MUFF Engine"""
 
-# Copyright (c) 2005 mudpy, Jeremy Stanley <fungi@yuggoth.org>
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-#    - Redistributions of source code must retain the above copyright
-#      notice, this list of conditions and the following disclaimer.
-#    - Redistributions in binary form must reproduce the above
-#      copyright notice, this list of conditions and the following
-#      disclaimer in the documentation and/or other materials provided
-#      with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
+# Copyright (c) 2005 mudpy, Jeremy Stanley <fungi@yuggoth.org>, all rights reserved.
+# Licensed per terms in the LICENSE file distributed with this software.
 
+# muff uses menu data stored in ini-style files supported by ConfigParser
 import ConfigParser
+
+# os.listdir is needed to get a file listing from a config directory
 import os
+
+# re.match is used to find menu options based on the choice_ prefix
 import re
-import string
 
+# hack to load all modules in the muff package
 import muff
 for module in muff.__all__:
        exec("import " + module)
 
+# see if the menupath can be retrieved from muffconf
 try:
-       if muffconf.config_data.get("general", "menu_path"):
-               pass
+       if muffconf.config_data.get("files", "menus"): pass
+
+# otherwise, reload muffconf
 except AttributeError:
        reload(muffconf)
 
+# build a list of files in the menus directory
 menu_files = []
-menu_path = muffconf.config_data.get("general", "menu_path")
+menu_path = muffconf.config_data.get("files", "menus")
 for each_file in os.listdir(menu_path):
        menu_files.append(menu_path + "/" + each_file)
+
+# read the menu files
 menu_data = ConfigParser.SafeConfigParser()
 menu_data.read(menu_files)
 
 def get_default(user):
+       """Return the default choice for a menu."""
        return menu_data.get(user.state, "default")
 
 def get_menu(user):
+       """Show the correct menu text to a user."""
+
+       # the menu hasn't been shown yet since the user's last input
        if not user.menu_seen:
+
+               # echo is currently on for the user, so don't add an extra eol
                if user.echoing:
                        spacer = ""
+
+               # echo is currently off for the user, so add an extra eol
                else:
                        spacer = "$(eol)"
+
+               # if the user has echo on and the menu specifies it should be
+               # turned off, send: iac + will + echo + null
                try:
                        if menu_data.get(user.state, "echo") == "off" and user.echoing:
                                echo = chr(255) + chr(251) + chr(1) + chr(0)
                                user.echoing = False
                        else:
                                echo = ""
+
+               # if echo is not set to off in the menu and the user curently
+               # has echo off, send: iac + wont + echo + null
                except:
                        if not user.echoing:
                                echo = chr(255) + chr(252) + chr(1) + chr(0)
                                user.echoing = True
                        else:
                                echo = ""
+
+               # and error condition was raised by the handler
                if user.error:
+
+                       # try to get an error message matching the condition
+                       # and current state
                        try:
                                description = "$(red)" + menu_data.get(user.state, "error_" + user.error) + "$(nrm)$(eol)$(eol)"
+
+                       # otherwise, use a generic one
                        except:
                                description = "$(red)That is not a valid choice...$(nrm)$(eol)$(eol)"
+
+                       # now clear the error condition
                        user.error = ""
+
+               # there was no error condition raised by the handler
                else:
+
+                       # try to get a menu description for the current state
                        try:
                                description = menu_data.get(user.state, "description") + "$(eol)$(eol)"
+
+                       # otherwise, leave it blank
                        except:
                                description = ""
+
+               # try to get menu choices for the current state
                try:
+
+                       # build a dict of choice:meaning
                        choices = {}
                        for option in menu_data.options(user.state):
                                if re.match("choice_", option):
                                        choices[option.split("_")[1]] = menu_data.get(user.state, option)
+
+                       # make a sorted list of choices
                        choice_keys = choices.keys()
                        choice_keys.sort()
+
+                       # concatenate them all into a list for display
                        choicestring = ""
                        for choice in choice_keys:
                                choicestring += "   [$(red)" + choice + "$(nrm)]  " + choices[choice] + "$(eol)"
+
+                       # throw in an additional blank line after the choices,
+                       # if there were any
                        if choicestring:
                                choicestring += "$(eol)"
+
+               # there were no choices, so leave them blank
                except:
                        choicestring = ""
+
+               # try to get a prompt, if it was defined
                try:
                        prompt = menu_data.get(user.state, "prompt") + " "
+
+               # otherwise, leave it blank
                except:
                        prompt = ""
+
+               # throw in the default choice, if it exists
                try:
                        default = "[$(red)" + menu_data.get(user.state, "default") + "$(nrm)] "
+
+               # otherwise, leave it blank
                except:
                        default = ""
+
+               # echo is on, so don't display a message about it
                if user.echoing:
                        echoing = ""
+
+               # echo is off, so let the user know
                else:
                        echoing = "(won't echo) "
+
+               # assemble and send the various strings defined above
                user.send(echo + spacer + description + choicestring + prompt + default + echoing, "")
+
+               # flag that the menu has now been displayed
                user.menu_seen = True