Reimplementert confirm som meny; mer tegnkodingshakking.

Har nå mulighet for default-valg i confirm (default-en vises med stor
bokstav, som i '(Y/n)', og velges hvis man skriver en tom linje), og
confirm leser input på samme måte som alt annet (via Menu.input_str).

Har laget en funksjon safe_str som prøver å gjøre om et vilkårlig
objekt til noe Python kan printe uten å bli sur.  Tok i bruk denne i
raw_input-kallet i Menu.input_str (det viser seg at raw_input blir
muggen hvis den får et unicode-objekt som inneholder ikke-ASCII-tegn).
This commit is contained in:
Øystein Ingmar Skartsæterhagen 2010-05-11 19:23:52 +00:00
parent 29220ebe3d
commit c2342397eb
2 changed files with 91 additions and 52 deletions

View File

@ -20,56 +20,56 @@ def search_product(string, session):
Product.name.ilike('%'+string+'%'))).all()
return product_list
def guess_data_type(string):
if string.startswith('NTNU'):
return 'card'
if string.isdigit():
return 'bar_code'
if string.isalpha() and string.islower():
return 'username'
return 'product_name'
# def guess_data_type(string):
# if string.startswith('NTNU'):
# return 'card'
# if string.isdigit():
# return 'bar_code'
# if string.isalpha() and string.islower():
# return 'username'
# return 'product_name'
def retrieve_user(string, session):
# first = session.query(User).filter(or_(User.name==string, User.card==string)).first()
search = search_user(string,session)
if isinstance(search,User):
print "Found user "+search.name
return search
else:
if len(search) == 0:
print "No users found matching your search"
return None
if len(search) == 1:
print "Found one user: "+list[0].name
if confirm():
return list[0]
else:
return None
else:
print "Found "+str(len(search))+" users:"
return select_from_list(search)
# def retrieve_user(string, session):
# # first = session.query(User).filter(or_(User.name==string, User.card==string)).first()
# search = search_user(string,session)
# if isinstance(search,User):
# print "Found user "+search.name
# return search
# else:
# if len(search) == 0:
# print "No users found matching your search"
# return None
# if len(search) == 1:
# print "Found one user: "+list[0].name
# if confirm():
# return list[0]
# else:
# return None
# else:
# print "Found "+str(len(search))+" users:"
# return select_from_list(search)
def confirm(prompt='Confirm? (y/n) '):
while True:
input = raw_input(prompt)
if input in ["y","yes"]:
return True
elif input in ["n","no"]:
return False
else:
print "Nonsense!"
# def confirm(prompt='Confirm? (y/n) '):
# while True:
# input = raw_input(prompt)
# if input in ["y","yes"]:
# return True
# elif input in ["n","no"]:
# return False
# else:
# print "Nonsense!"
def select_from_list(list):
while True:
for i in range(len(list)):
print i+1, " ) ", list[i].name
choice = raw_input("Select user :\n")
if choice in [str(x+1) for x in range(len(list))]:
return list[int(choice)-1]
else:
return None
# def select_from_list(list):
# while True:
# for i in range(len(list)):
# print i+1, " ) ", list[i].name
# choice = raw_input("Select user :\n")
# if choice in [str(x+1) for x in range(len(list))]:
# return list[int(choice)-1]
# else:
# return None
def argmax(d, all=False, value=None):
maxarg = None
@ -85,3 +85,17 @@ def argmax(d, all=False, value=None):
if all:
return filter(lambda k: d[k] == d[maxarg], d.keys())
return maxarg
def safe_str(obj):
'''
Ugly hack to avoid Python complaining about encodings.
Call this on any object to turn it into a string which is
(hopefully) safe for printing.
'''
if isinstance(obj, str):
return obj
if isinstance(obj, unicode):
return obj.encode('utf8')
else:
return safe_str(unicode(obj))

View File

@ -35,7 +35,7 @@ class Menu():
print self.exit_disallowed_msg
return
if self.exit_confirm_msg != None:
if not confirm(self.exit_confirm_msg):
if not self.confirm(self.exit_confirm_msg):
return
raise ExitMenu()
@ -105,7 +105,7 @@ class Menu():
prompt = self.prompt
while True:
try:
result = raw_input(prompt)
result = raw_input(safe_str(prompt))
except EOFError:
print 'quit'
self.exit_menu()
@ -193,6 +193,9 @@ class Menu():
return 2
return 1
def confirm(self, prompt, default=None):
return ConfirmMenu(prompt, default).execute()
def print_header(self):
print
print self.header_format % self.name
@ -248,6 +251,7 @@ product name or barcode.
else:
return self.item_value(item_i)
class Selector(Menu):
def __init__(self, name, items=[], prompt='select> ',
return_index=True,
@ -269,6 +273,26 @@ class Selector(Menu):
print self.help_text
class ConfirmMenu(Menu):
def __init__(self, prompt='confirm?', default=None):
Menu.__init__(self, 'question', prompt=prompt,
exit_disallowed_msg='Please answer yes or no')
self.default=default
def _execute(self):
options = {True: 'Y/n', False: 'y/N', None: 'y/n'}[self.default]
while True:
result = self.input_str('%s (%s) ' % (self.prompt, options))
if result in ['y','yes']:
return True
if result in ['n','no']:
return False
if self.default != None and result == '':
return self.default
print 'Please answer yes or no'
# class ChargeMenu(Menu):
# def __init__(self):
# self.name = "Add credits to a user account"
@ -479,7 +503,8 @@ When finished, write an empty line to confirm the purchase.
thing = self.input_thing(empty_input_permitted=True)
if thing == None:
if not self.complete_input():
if confirm('Not enough information entered. Abort purchase? (y/n) '):
if self.confirm('Not enough information entered. Abort purchase?',
default=True):
return False
continue
break
@ -607,9 +632,9 @@ def search_ui2(search_str, result, thing, session):
print 'No %ss matching "%s"' % (thing, search_str)
return None
if len(result) == 1:
msg = 'One %s matching "%s": %s. Use this? (y/n) ' %\
(thing, search_str, result[0])
if confirm(msg):
msg = 'One %s matching "%s": %s. Use this?' %\
(thing, search_str, unicode(result[0]))
if ConfirmMenu(msg, default=True).execute():
return result[0]
return None
limit = 9
@ -640,7 +665,7 @@ main = Menu('Dibbler main menu',
AddProductMenu(), EditProductMenu()])
],
exit_msg='happy happy joy joy',
exit_confirm_msg='Really quit Dibbler? (y/n) ')
exit_confirm_msg='Really quit Dibbler?')
if not conf.quit_allowed:
main.exit_disallowed_msg = 'You can check out any time you like, but you can never leave.'
while True: