1 """Menu objects for the MUFF Engine"""
3 # Copyright (c) 2005 MUDpy, The Fungi <fungi@yuggoth.org>, all rights reserved.
4 # Licensed per terms in the LICENSE file distributed with this software.
6 # muff uses menu data stored in ini-style files supported by ConfigParser
9 # os.listdir is needed to get a file listing from a config directory
12 # re.match is used to find menu options based on the choice_ prefix
15 # hack to load all modules in the muff package
17 for module in muff.__all__:
18 exec("import " + module)
20 # see if the menupath can be retrieved from muffconf
22 if muffconf.config_data.get("files", "menus"): pass
24 # otherwise, reload muffconf
25 except AttributeError:
28 # build a list of files in the menus directory
30 menu_path = muffconf.config_data.get("files", "menus")
31 for each_file in os.listdir(menu_path):
32 menu_files.append(menu_path + "/" + each_file)
35 menu_data = ConfigParser.SafeConfigParser()
36 menu_data.read(menu_files)
38 def get_default(user):
39 """Return the default choice for a menu."""
40 return menu_data.get(user.state, "default")
43 """Show the correct menu text to a user."""
45 # the menu hasn't been shown yet since the user's last input
46 if not user.menu_seen:
48 # echo is currently on for the user, so don't add an extra eol
52 # echo is currently off for the user, so add an extra eol
56 # if the user has echo on and the menu specifies it should be
57 # turned off, send: iac + will + echo + null
59 if menu_data.get(user.state, "echo") == "off" and user.echoing:
60 echo = chr(255) + chr(251) + chr(1) + chr(0)
65 # if echo is not set to off in the menu and the user curently
66 # has echo off, send: iac + wont + echo + null
69 echo = chr(255) + chr(252) + chr(1) + chr(0)
74 # and error condition was raised by the handler
77 # try to get an error message matching the condition
80 description = "$(red)" + menu_data.get(user.state, "error_" + user.error) + "$(nrm)$(eol)$(eol)"
82 # otherwise, use a generic one
84 description = "$(red)That is not a valid choice...$(nrm)$(eol)$(eol)"
86 # now clear the error condition
89 # there was no error condition raised by the handler
92 # try to get a menu description for the current state
94 description = menu_data.get(user.state, "description") + "$(eol)$(eol)"
96 # otherwise, leave it blank
100 # try to get menu choices for the current state
103 # build a dict of choice:meaning
105 for option in menu_data.options(user.state):
106 if re.match("choice_", option):
107 choices[option.split("_")[1]] = menu_data.get(user.state, option)
109 # make a sorted list of choices
110 choice_keys = choices.keys()
113 # concatenate them all into a list for display
115 for choice in choice_keys:
116 choicestring += " [$(red)" + choice + "$(nrm)] " + choices[choice] + "$(eol)"
118 # throw in an additional blank line after the choices,
121 choicestring += "$(eol)"
123 # there were no choices, so leave them blank
127 # try to get a prompt, if it was defined
129 prompt = menu_data.get(user.state, "prompt") + " "
131 # otherwise, leave it blank
135 # throw in the default choice, if it exists
137 default = "[$(red)" + menu_data.get(user.state, "default") + "$(nrm)] "
139 # otherwise, leave it blank
143 # echo is on, so don't display a message about it
147 # echo is off, so let the user know
149 echoing = "(won't echo) "
151 # assemble and send the various strings defined above
152 user.send(echo + spacer + description + choicestring + prompt + default + echoing, "")
154 # flag that the menu has now been displayed
155 user.menu_seen = True