Hjelp.
This commit is contained in:
parent
daf5ae2294
commit
94e38d6f7e
156
text_based.py
156
text_based.py
|
@ -2,24 +2,56 @@ import sqlalchemy
|
||||||
import re
|
import re
|
||||||
from helpers import *
|
from helpers import *
|
||||||
|
|
||||||
exit_commands = ['exit', 'abort', 'quit']
|
exit_commands = ['exit', 'abort', 'quit', 'bye', 'eat flaming death']
|
||||||
|
help_commands = ['help', '?']
|
||||||
|
context_commands = ['what', '??']
|
||||||
|
local_help_commands = ['help!', '???']
|
||||||
|
|
||||||
class ExitMenu(Exception):
|
class ExitMenu(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Menu():
|
class Menu():
|
||||||
def __init__(self, name, items=[], prompt='> ',
|
def __init__(self, name, items=[], prompt='> ',
|
||||||
return_index=True, exit_msg=None):
|
return_index=True,
|
||||||
|
exit_msg=None, exit_confirm_msg=None,
|
||||||
|
help_text=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.items = items
|
self.items = items
|
||||||
self.prompt = prompt
|
self.prompt = prompt
|
||||||
self.return_index = return_index
|
self.return_index = return_index
|
||||||
self.exit_msg = exit_msg
|
self.exit_msg = exit_msg
|
||||||
|
self.exit_confirm_msg = exit_confirm_msg
|
||||||
|
self.help_text = help_text
|
||||||
|
self.context = None
|
||||||
|
self.header_format = '[%s]'
|
||||||
|
|
||||||
|
def exit_menu(self):
|
||||||
|
if self.exit_confirm_msg != None:
|
||||||
|
if not confirm(self.exit_confirm_msg):
|
||||||
|
return
|
||||||
|
raise ExitMenu()
|
||||||
|
|
||||||
def at_exit(self):
|
def at_exit(self):
|
||||||
if self.exit_msg:
|
if self.exit_msg:
|
||||||
print self.exit_msg
|
print self.exit_msg
|
||||||
|
|
||||||
|
def set_context(self, string, display=True):
|
||||||
|
self.context = string
|
||||||
|
if self.context != None and display:
|
||||||
|
print self.context
|
||||||
|
|
||||||
|
def printc(self, string):
|
||||||
|
print string
|
||||||
|
if self.context == None:
|
||||||
|
self.context = string
|
||||||
|
else:
|
||||||
|
self.context += '\n' + string
|
||||||
|
|
||||||
|
def show_context(self):
|
||||||
|
print self.header_format % self.name
|
||||||
|
if self.context != None:
|
||||||
|
print self.context
|
||||||
|
|
||||||
def item_is_submenu(self, i):
|
def item_is_submenu(self, i):
|
||||||
return isinstance(self.items[i], Menu)
|
return isinstance(self.items[i], Menu)
|
||||||
|
|
||||||
|
@ -63,16 +95,28 @@ class Menu():
|
||||||
return result
|
return result
|
||||||
if prompt == None:
|
if prompt == None:
|
||||||
prompt = self.prompt
|
prompt = self.prompt
|
||||||
try:
|
while True:
|
||||||
result = raw_input(prompt)
|
try:
|
||||||
except EOFError:
|
result = raw_input(prompt)
|
||||||
print 'quit'
|
except EOFError:
|
||||||
raise ExitMenu()
|
print 'quit'
|
||||||
if result in exit_commands:
|
self.exit_menu()
|
||||||
raise ExitMenu()
|
continue
|
||||||
if empty_string_is_none and result == '':
|
if result in exit_commands:
|
||||||
return None
|
self.exit_menu()
|
||||||
return result
|
continue
|
||||||
|
if result in help_commands:
|
||||||
|
self.general_help()
|
||||||
|
continue
|
||||||
|
if result in local_help_commands:
|
||||||
|
self.local_help()
|
||||||
|
continue
|
||||||
|
if result in context_commands:
|
||||||
|
self.show_context()
|
||||||
|
continue
|
||||||
|
if empty_string_is_none and result == '':
|
||||||
|
return None
|
||||||
|
return result
|
||||||
|
|
||||||
def input_int(self, prompt=None, allowed_range=(None,None)):
|
def input_int(self, prompt=None, allowed_range=(None,None)):
|
||||||
if prompt == None:
|
if prompt == None:
|
||||||
|
@ -143,11 +187,35 @@ class Menu():
|
||||||
|
|
||||||
def print_header(self):
|
def print_header(self):
|
||||||
print
|
print
|
||||||
print '[%s]' % self.name
|
print self.header_format % self.name
|
||||||
|
|
||||||
def pause(self):
|
def pause(self):
|
||||||
self.input_str('.')
|
self.input_str('.')
|
||||||
|
|
||||||
|
def general_help(self):
|
||||||
|
print '''
|
||||||
|
DIBBLER HELP
|
||||||
|
|
||||||
|
The following commands are recognized (almost) everywhere:
|
||||||
|
|
||||||
|
help, ? -- display this help
|
||||||
|
what, ?? -- redisplay the current context
|
||||||
|
help!, ??? -- display context-specific help (if any)
|
||||||
|
exit, quit, etc. -- exit from the current menu
|
||||||
|
|
||||||
|
When prompted for a user, you can type (parts of) the user name or
|
||||||
|
card number. When prompted for a product, you can type (parts of) the
|
||||||
|
product name or barcode.
|
||||||
|
'''
|
||||||
|
|
||||||
|
def local_help(self):
|
||||||
|
if self.help_text == None:
|
||||||
|
print 'no help here'
|
||||||
|
else:
|
||||||
|
print 'Help for %s' % (self.header_format%self.name)
|
||||||
|
print
|
||||||
|
print self.help_text
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
try:
|
try:
|
||||||
return self._execute()
|
return self._execute()
|
||||||
|
@ -158,12 +226,13 @@ class Menu():
|
||||||
def _execute(self):
|
def _execute(self):
|
||||||
while True:
|
while True:
|
||||||
self.print_header()
|
self.print_header()
|
||||||
|
self.set_context(None)
|
||||||
if len(self.items)==0:
|
if len(self.items)==0:
|
||||||
print '(empty menu)'
|
self.printc('(empty menu)')
|
||||||
self.pause()
|
self.pause()
|
||||||
return None
|
return None
|
||||||
for i in range(len(self.items)):
|
for i in range(len(self.items)):
|
||||||
print '%d ) %s' % (i+1, self.item_name(i))
|
self.printc('%d ) %s' % (i+1, self.item_name(i)))
|
||||||
item_i = self.input_int(self.prompt, (1,len(self.items)))-1
|
item_i = self.input_int(self.prompt, (1,len(self.items)))-1
|
||||||
if self.item_is_submenu(item_i):
|
if self.item_is_submenu(item_i):
|
||||||
self.items[item_i].execute()
|
self.items[item_i].execute()
|
||||||
|
@ -172,11 +241,23 @@ class Menu():
|
||||||
|
|
||||||
class Selector(Menu):
|
class Selector(Menu):
|
||||||
def __init__(self, name, items=[], prompt='select> ',
|
def __init__(self, name, items=[], prompt='select> ',
|
||||||
return_index=True, exit_msg=None):
|
return_index=True,
|
||||||
|
exit_msg=None, exit_confirm_msg=None,
|
||||||
|
help_text=None):
|
||||||
Menu.__init__(self, name, items, prompt, return_index, exit_msg)
|
Menu.__init__(self, name, items, prompt, return_index, exit_msg)
|
||||||
|
self.header_format = '%s'
|
||||||
|
|
||||||
def print_header(self):
|
def print_header(self):
|
||||||
print self.name
|
print self.header_format % self.name
|
||||||
|
|
||||||
|
def local_help(self):
|
||||||
|
if self.help_text == None:
|
||||||
|
print 'This is a selection menu. Enter one of the listed numbers, or'
|
||||||
|
print '\'exit\' to go out and do something else.'
|
||||||
|
else:
|
||||||
|
print 'Help for selector (%s)' % self.name
|
||||||
|
print
|
||||||
|
print self.help_text
|
||||||
|
|
||||||
|
|
||||||
# class ChargeMenu(Menu):
|
# class ChargeMenu(Menu):
|
||||||
|
@ -253,7 +334,7 @@ class EditUserMenu(Menu):
|
||||||
self.print_header()
|
self.print_header()
|
||||||
self.session = Session()
|
self.session = Session()
|
||||||
user = self.input_user('User> ')
|
user = self.input_user('User> ')
|
||||||
print 'Editing user %s' % user.name
|
self.printc('Editing user %s' % user.name)
|
||||||
user.card = self.input_str('Card number (currently "%s")> ' % user.card,
|
user.card = self.input_str('Card number (currently "%s")> ' % user.card,
|
||||||
User.card_re, (0,10),
|
User.card_re, (0,10),
|
||||||
empty_string_is_none=True)
|
empty_string_is_none=True)
|
||||||
|
@ -295,6 +376,7 @@ class EditProductMenu(Menu):
|
||||||
self.print_header()
|
self.print_header()
|
||||||
self.session = Session()
|
self.session = Session()
|
||||||
product = self.input_product('Product> ')
|
product = self.input_product('Product> ')
|
||||||
|
self.printc('Editing product %s' % product.name)
|
||||||
while True:
|
while True:
|
||||||
selector = Selector('Do what with %s?' % product.name,
|
selector = Selector('Do what with %s?' % product.name,
|
||||||
items=[('name', 'Edit name'),
|
items=[('name', 'Edit name'),
|
||||||
|
@ -331,14 +413,15 @@ class ShowUserMenu(Menu):
|
||||||
self.pause()
|
self.pause()
|
||||||
|
|
||||||
def print_transactions(self, user):
|
def print_transactions(self, user):
|
||||||
limit = 20
|
limit = 10
|
||||||
if len(user.transactions) == 0:
|
num_trans = len(user.transactions)
|
||||||
|
if num_trans == 0:
|
||||||
print 'No transactions'
|
print 'No transactions'
|
||||||
return
|
return
|
||||||
if len(user.transactions) <= limit:
|
if num_trans <= limit:
|
||||||
print 'Transactions:'
|
print 'Transactions (%d):' % num_trans
|
||||||
else:
|
else:
|
||||||
print 'Transactions (last %d):' % limit
|
print 'Transactions (%d, showing only last %d):' % (num_trans,limit)
|
||||||
for t in user.transactions[-limit:]:
|
for t in user.transactions[-limit:]:
|
||||||
string = ' * %s: %s %d kr, ' % \
|
string = ' * %s: %s %d kr, ' % \
|
||||||
(t.time.strftime('%Y-%m-%d %H:%M'),
|
(t.time.strftime('%Y-%m-%d %H:%M'),
|
||||||
|
@ -357,6 +440,15 @@ class ShowUserMenu(Menu):
|
||||||
class BuyMenu(Menu):
|
class BuyMenu(Menu):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Menu.__init__(self, 'Buy')
|
Menu.__init__(self, 'Buy')
|
||||||
|
self.help_text = '''
|
||||||
|
Each purchase may contain one or more products and one or more buyers.
|
||||||
|
|
||||||
|
Enter products (by name or bar code) and buyers (by name or bar code)
|
||||||
|
in any order. The information gathered so far is displayed after each
|
||||||
|
addition, and you can type 'what' at any time to redisplay it.
|
||||||
|
|
||||||
|
When finished, write an empty line to confirm the purchase.
|
||||||
|
'''
|
||||||
|
|
||||||
def _execute(self):
|
def _execute(self):
|
||||||
self.print_header()
|
self.print_header()
|
||||||
|
@ -364,12 +456,12 @@ class BuyMenu(Menu):
|
||||||
self.purchase = Purchase()
|
self.purchase = Purchase()
|
||||||
while True:
|
while True:
|
||||||
self.print_purchase()
|
self.print_purchase()
|
||||||
print {(False,False): 'Enter user or product identification',
|
self.printc({(False,False): 'Enter user or product identification',
|
||||||
(False,True): 'Enter user identification or more products',
|
(False,True): 'Enter user identification or more products',
|
||||||
(True,False): 'Enter product identification or more users',
|
(True,False): 'Enter product identification or more users',
|
||||||
(True,True): 'Enter more products or users, or an empty line to confirm'
|
(True,True): 'Enter more products or users, or an empty line to confirm'
|
||||||
}[(len(self.purchase.transactions) > 0,
|
}[(len(self.purchase.transactions) > 0,
|
||||||
len(self.purchase.entries) > 0)]
|
len(self.purchase.entries) > 0)])
|
||||||
thing = self.input_thing(empty_input_permitted=True)
|
thing = self.input_thing(empty_input_permitted=True)
|
||||||
if thing == None:
|
if thing == None:
|
||||||
if not self.complete_input():
|
if not self.complete_input():
|
||||||
|
@ -426,7 +518,7 @@ class BuyMenu(Menu):
|
||||||
def print_purchase(self):
|
def print_purchase(self):
|
||||||
info = self.format_purchase()
|
info = self.format_purchase()
|
||||||
if info != None:
|
if info != None:
|
||||||
print info
|
self.set_context(info)
|
||||||
|
|
||||||
|
|
||||||
class AdjustCreditMenu(Menu): # reimplements ChargeMenu; these should be combined to one
|
class AdjustCreditMenu(Menu): # reimplements ChargeMenu; these should be combined to one
|
||||||
|
@ -438,6 +530,7 @@ class AdjustCreditMenu(Menu): # reimplements ChargeMenu; these should be combine
|
||||||
self.session = Session()
|
self.session = Session()
|
||||||
user = self.input_user('User> ')
|
user = self.input_user('User> ')
|
||||||
print 'User %s\'s credit is %d kr' % (user.name, user.credit)
|
print 'User %s\'s credit is %d kr' % (user.name, user.credit)
|
||||||
|
self.set_context('Adjusting credit for user %s' % user.name, display=False)
|
||||||
amount = self.input_int('Add amount> ', (-100000,100000))
|
amount = self.input_int('Add amount> ', (-100000,100000))
|
||||||
description = self.input_str('Log message> ', length_range=(0,50))
|
description = self.input_str('Log message> ', length_range=(0,50))
|
||||||
if description == '':
|
if description == '':
|
||||||
|
@ -532,7 +625,8 @@ main = Menu('Dibbler main menu',
|
||||||
items=[AddUserMenu(), EditUserMenu(),
|
items=[AddUserMenu(), EditUserMenu(),
|
||||||
AddProductMenu(), EditProductMenu()])
|
AddProductMenu(), EditProductMenu()])
|
||||||
],
|
],
|
||||||
exit_msg='happy happy joy joy')
|
exit_msg='happy happy joy joy',
|
||||||
|
exit_confirm_msg='Really quit Dibbler? (y/n) ')
|
||||||
main.execute()
|
main.execute()
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue