Imported from archive.
[mudpy.git] / lib / muff / muffmenu.py
1 """Menu objects for the MUFF Engine"""
2
3 # Copyright (c) 2005 mudpy, Jeremy Stanley <fungi@yuggoth.org>, all rights reserved.
4 # Licensed per terms in the LICENSE file distributed with this software.
5
6 # muff uses menu data stored in ini-style files supported by ConfigParser
7 import ConfigParser
8
9 # os.listdir is needed to get a file listing from a config directory
10 import os
11
12 # re.match is used to find menu options based on the choice_ prefix
13 import re
14
15 # hack to load all modules in the muff package
16 import muff
17 for module in muff.__all__:
18         exec("import " + module)
19
20 # see if the menupath can be retrieved from muffconf
21 try:
22         if muffconf.get("files", "menus"): pass
23
24 # otherwise, reload muffconf
25 except AttributeError:
26         reload(muffconf)
27
28 # now we can safely nab the menu path setting and build a list of data files
29 menu_path = muffconf.get("files", "menus")
30 menu_files_index = ConfigParser.SafeConfigParser()
31 menu_files_index.read(menu_path + "/index")
32 menu_files = []
33 for each_file in menu_files_index.get("index", "files").split():
34         menu_files.append(menu_path + "/" + each_file)
35
36 # read the menu files
37 menu_data = ConfigParser.SafeConfigParser()
38 menu_data.read(menu_files)
39
40 def get_default(user):
41         """Return the default choice for a menu."""
42         return menu_data.get(user.state, "default")
43
44 def get_menu(user):
45         """Show the correct menu text to a user."""
46
47         # the menu hasn't been shown yet since the user's last input
48         if not user.menu_seen:
49
50                 # echo is currently on for the user, so don't add an extra eol
51                 if user.echoing:
52                         spacer = ""
53
54                 # echo is currently off for the user, so add an extra eol
55                 else:
56                         spacer = "$(eol)"
57
58                 # if the user has echo on and the menu specifies it should be
59                 # turned off, send: iac + will + echo + null
60                 try:
61                         if menu_data.get(user.state, "echo") == "off" and user.echoing:
62                                 echo = chr(255) + chr(251) + chr(1) + chr(0)
63                                 user.echoing = False
64                         else:
65                                 echo = ""
66
67                 # if echo is not set to off in the menu and the user curently
68                 # has echo off, send: iac + wont + echo + null
69                 except:
70                         if not user.echoing:
71                                 echo = chr(255) + chr(252) + chr(1) + chr(0)
72                                 user.echoing = True
73                         else:
74                                 echo = ""
75
76                 # and error condition was raised by the handler
77                 if user.error:
78
79                         # try to get an error message matching the condition
80                         # and current state
81                         try:
82                                 description = "$(red)" + menu_data.get(user.state, "error_" + user.error) + "$(nrm)$(eol)$(eol)"
83
84                         # otherwise, use a generic one
85                         except:
86                                 description = "$(red)That is not a valid choice...$(nrm)$(eol)$(eol)"
87
88                         # now clear the error condition
89                         user.error = ""
90
91                 # there was no error condition raised by the handler
92                 else:
93
94                         # try to get a menu description for the current state
95                         try:
96                                 description = menu_data.get(user.state, "description") + "$(eol)$(eol)"
97
98                         # otherwise, leave it blank
99                         except:
100                                 description = ""
101
102                 # try to get menu choices for the current state
103                 try:
104
105                         # build a dict of choice:meaning
106                         choices = {}
107                         for option in menu_data.options(user.state):
108                                 if re.match("choice_", option):
109                                         choices[option.split("_")[1]] = menu_data.get(user.state, option)
110
111                         # make a sorted list of choices
112                         choice_keys = choices.keys()
113                         choice_keys.sort()
114
115                         # concatenate them all into a list for display
116                         choicestring = ""
117                         for choice in choice_keys:
118                                 choicestring += "   [$(red)" + choice + "$(nrm)]  " + choices[choice] + "$(eol)"
119
120                         # throw in an additional blank line after the choices,
121                         # if there were any
122                         if choicestring:
123                                 choicestring += "$(eol)"
124
125                 # there were no choices, so leave them blank
126                 except:
127                         choicestring = ""
128
129                 # try to get a prompt, if it was defined
130                 try:
131                         prompt = menu_data.get(user.state, "prompt") + " "
132
133                 # otherwise, leave it blank
134                 except:
135                         prompt = ""
136
137                 # throw in the default choice, if it exists
138                 try:
139                         default = "[$(red)" + menu_data.get(user.state, "default") + "$(nrm)] "
140
141                 # otherwise, leave it blank
142                 except:
143                         default = ""
144
145                 # echo is on, so don't display a message about it
146                 if user.echoing:
147                         echoing = ""
148
149                 # echo is off, so let the user know
150                 else:
151                         echoing = "(won't echo) "
152
153                 # assemble and send the various strings defined above
154                 user.send(echo + spacer + description + choicestring + prompt + default + echoing, "")
155
156                 # flag that the menu has now been displayed
157                 user.menu_seen = True
158