Commit 060a7374 authored by Mitchell Pomery's avatar Mitchell Pomery Committed by Mark Tearle
Browse files

Rearranging file and adding comments

parent 3dbb7110
......@@ -75,6 +75,33 @@ _last_card_id = -1
idlers = []
idler = None
config_options = {
'DBServer': ('Database', 'Server'),
'DBName': ('Database', 'Name'),
'DBUser': ('VendingMachine', 'DBUser'),
'DBPassword': ('VendingMachine', 'DBPassword'),
'ServiceName': ('VendingMachine', 'ServiceName'),
'ServicePassword': ('VendingMachine', 'Password'),
'ServerName': ('DecServer', 'Name'),
'ConnectPassword': ('DecServer', 'ConnectPassword'),
'PrivPassword': ('DecServer', 'PrivPassword'),
}
class VendConfigFile:
def __init__(self, config_file, options):
try:
cp = ConfigParser.ConfigParser()
cp.read(config_file)
for option in options:
section, name = options[option]
value = cp.get(section, name)
self.__dict__[option] = value
except ConfigParser.Error, e:
raise SystemExit("Error reading config file "+config_file+": " + str(e))
class DispenseDatabaseException(Exception): pass
......@@ -106,7 +133,9 @@ class DispenseDatabase:
while notifier is not None:
self.process_requests()
notify = self.db.getnotify()
"""
This class manages the current state of the vending machine.
"""
class VendState:
def __init__(self,v):
self.state_table = {}
......@@ -124,22 +153,16 @@ class VendState:
def change_state(self,newstate,newcounter=None):
if self.state != newstate:
#print "Changing state from: ",
#print self.state,
#print " to ",
#print newstate
self.state = newstate
if newcounter is not None and self.counter != newcounter:
#print "Changing counter from: ",
#print self.counter,
#print " to ",
#print newcounter
self.counter = newcounter
"""
Show information to the user as to what can be dispensed.
"""
def scroll_options(username, mk, welcome = False):
# If the user has just logged in, show them their balance
if welcome:
# Balance checking
acct, unused = Popen(['dispense', 'acct', username], close_fds=True, stdout=PIPE).communicate()
......@@ -153,7 +176,7 @@ def scroll_options(username, mk, welcome = False):
msg = []
choices = ' '*10+'CHOICES: '
# Get coke contents
# Show what is in the coke machine
cokes = []
for i in range(0, 7):
args = ('dispense', 'iteminfo', 'coke:%i' % i)
......@@ -168,23 +191,19 @@ def scroll_options(username, mk, welcome = False):
if slot_name == 'dead': continue
choices += '%s-(%sc)-%s8 '%(slot_name, price, slot_num)
# we don't want to print snacks for now since it'll be too large
# and there's physical bits of paper in the machine anyway - matt
# try:
# snacks = get_snacks()
# except:
# snacks = {}
#
# for slot, ( name, price ) in snacks.items():
# choices += '%s8-%s (%sc) ' % ( slot, name, price )
# Show the final few options
choices += '55-DOOR '
choices += 'OR ANOTHER SNACK. '
choices += '99 TO READ AGAIN. '
choices += 'CHOICE? '
msg.append((choices, False, None))
# Send it to the display
mk.set_messages(msg)
"""
Verify the users pin
"""
def _check_pin(uid, pin):
global _pin_uid
global _pin_uname
......@@ -227,6 +246,9 @@ def _check_pin(uid, pin):
logging.info("Pin incorrect for %d",uid)
return pin == int(pinstr)
"""
Check if the users account has been disabled
"""
def acct_is_disabled(name=None):
global _pin_uname
if name == None:
......@@ -240,9 +262,15 @@ def acct_is_disabled(name=None):
return True
return False
"""
Check that the user has a valid pin set
"""
def has_good_pin(uid):
return _check_pin(uid, None) != None
"""
Verify the users pin.
"""
def verify_user_pin(uid, pin, skip_pin_check=False):
if skip_pin_check or _check_pin(uid, pin) == True:
info = pwd.getpwuid(uid)
......@@ -258,7 +286,9 @@ def verify_user_pin(uid, pin, skip_pin_check=False):
logging.info('refused pin for uid %d'%(uid))
return None
"""
In here just for fun.
"""
def cookie(v):
seed(time())
messages = [' WASSUP! ', 'PINK FISH ', ' SECRETS ', ' ESKIMO ', ' FORTUNES ', 'MORE MONEY']
......@@ -283,10 +313,16 @@ def cookie(v):
s += msg[i]
v.display(s)
"""
Format text so it will appear centered on the screen.
"""
def center(str):
LEN = 10
return ' '*((LEN-len(str))/2)+str
"""
Configure the things that will appear on screen whil the machine is idling.
"""
def setup_idlers(v):
global idlers, idler
idlers = [
......@@ -322,6 +358,9 @@ def setup_idlers(v):
disabled = [
]
"""
Go back to the default idler.
"""
def reset_idler(v, vstatus, t = None):
global idlers, idler
idler = GreetingIdler(v, t)
......@@ -330,6 +369,9 @@ def reset_idler(v, vstatus, t = None):
vstatus.time_to_autologout = None
vstatus.change_state(STATE_IDLE, 1)
"""
Change to a random idler.
"""
def choose_idler():
global idlers, idler
......@@ -359,7 +401,9 @@ def choose_idler():
if idler:
idler.reset()
"""
Run every step while the machine is idling.
"""
def idle_step(vstatus):
global idler
if idler.finished():
......@@ -370,8 +414,9 @@ def idle_step(vstatus):
nextidle = IDLE_SPEED
vstatus.time_of_next_idlestep = time()+nextidle
"""
These next two events trigger no response in the code.
"""
def handle_tick_event(event, params, v, vstatus):
# don't care right now.
pass
......@@ -380,11 +425,16 @@ def handle_switch_event(event, params, v, vstatus):
# don't care right now.
pass
"""
Don't do anything for this event.
"""
def do_nothing(state, event, params, v, vstatus):
print "doing nothing (s,e,p)", state, " ", event, " ", params
pass
"""
These next few entrie tell us to do nothing while we are idling
"""
def handle_getting_uid_idle(state, event, params, v, vstatus):
# don't care right now.
pass
......@@ -393,6 +443,9 @@ def handle_getting_pin_idle(state, event, params, v, vstatus):
# don't care right now.
pass
"""
While logged in and waiting for user input, slowly get closer to logging out.
"""
def handle_get_selection_idle(state, event, params, v, vstatus):
global _last_card_id
# don't care right now.
......@@ -429,8 +482,9 @@ def handle_get_selection_idle(state, event, params, v, vstatus):
# need to check
vstatus.mk.update_display()
"""
Triggered on user input while logged in.
"""
def handle_get_selection_key(state, event, params, v, vstatus):
global _last_card_id
key = params
......@@ -466,13 +520,15 @@ def handle_get_selection_key(state, event, params, v, vstatus):
vstatus.time_to_autologout = None
vstatus.last_timeout_refresh = None
"""
Triggered when the user has entered the id of something they would like to purchase.
"""
def make_selection(v, vstatus):
# should use sudo here
if vstatus.cur_selection == '55':
vstatus.mk.set_message('OPENSESAME')
logging.info('dispensing a door for %s'%vstatus.username)
if geteuid() == 0:
#ret = os.system('su - "%s" -c "dispense door"'%vstatus.username)
ret = os.system('dispense -u "%s" door'%vstatus.username)
else:
ret = os.system('dispense door')
......@@ -503,8 +559,6 @@ def make_selection(v, vstatus):
price, shortname, name = get_snack( '--' )
dollarprice = "$%.2f" % ( price / 100.0 )
v.display(vstatus.cur_selection+' - %s'%dollarprice)
# exitcode = os.system('dispense -u "%s" give \>snacksales %d "%s"'%(vstatus.username, price, name)) >> 8
# exitcode = os.system('dispense -u "%s" give \>sales\:snack %d "%s"'%(vstatus.username, price, name)) >> 8
exitcode = os.system('dispense -u "%s" snack:%s'%(vstatus.username, vstatus.cur_selection)) >> 8
if (exitcode == 0):
# magic dispense syslog service
......@@ -526,7 +580,9 @@ def make_selection(v, vstatus):
v.display('UNK ERROR')
sleep(1)
"""
Find the price of an item.
"""
def price_check(v, vstatus):
if vstatus.cur_selection[1] == '8':
args = ('dispense', 'iteminfo', 'coke:' + vstatus.cur_selection[0])
......@@ -541,7 +597,9 @@ def price_check(v, vstatus):
dollarprice = "$%.2f" % ( price / 100.0 )
v.display(vstatus.cur_selection+' - %s'%dollarprice)
"""
Triggered when the user presses a button while entering their pin.
"""
def handle_getting_pin_key(state, event, params, v, vstatus):
#print "handle_getting_pin_key (s,e,p)", state, " ", event, " ", params
key = params
......@@ -577,7 +635,9 @@ def handle_getting_pin_key(state, event, params, v, vstatus):
return
"""
Triggered when the user presses a button while entering their user id.
"""
def handle_getting_uid_key(state, event, params, v, vstatus):
#print "handle_getting_uid_key (s,e,p)", state, " ", event, " ", params
key = params
......@@ -677,7 +737,9 @@ Wouldn't you prefer a nice game of chess?
vstatus.change_state(STATE_GETTING_PIN)
return
"""
Triggered when a key is pressed and the machine is idling.
"""
def handle_idle_key(state, event, params, v, vstatus):
#print "handle_idle_key (s,e,p)", state, " ", event, " ", params
......@@ -691,7 +753,9 @@ def handle_idle_key(state, event, params, v, vstatus):
vstatus.change_state(STATE_GETTING_UID)
run_handler(event, key, v, vstatus)
"""
What to do when there is nothing to do.
"""
def handle_idle_tick(state, event, params, v, vstatus):
### State idling
if vstatus.mk.done():
......@@ -709,6 +773,9 @@ def handle_idle_tick(state, event, params, v, vstatus):
run_handler(event, params, v, vstatus)
sleep(0.05)
"""
Manages the beeps for the grandfather clock
"""
def beep_on(when, before=0):
start = int(when - before)
end = int(when)
......@@ -813,6 +880,9 @@ def handle_grandfather_tick(state, event, params, v, vstatus):
if go_idle and vstatus.mk.done():
vstatus.change_state(STATE_IDLE,1)
"""
What to do when the door is open.
"""
def handle_door_idle(state, event, params, v, vstatus):
def twiddle(clock,v,wise = 2):
if (clock % 4 == 0):
......@@ -832,7 +902,9 @@ def handle_door_idle(state, event, params, v, vstatus):
else:
twiddle(now, v, wise=0)
"""
What to do when the door is opened or closed.
"""
def handle_door_event(state, event, params, v, vstatus):
if params == 0: #door open
vstatus.change_state(STATE_DOOR_OPENING)
......@@ -848,7 +920,9 @@ def handle_door_event(state, event, params, v, vstatus):
logging.warning('Leaving open door mode')
v.display("-YUM YUM!-")
"""
Triggered when a user swipes their caed, and the machine is logged out.
"""
def handle_mifare_event(state, event, params, v, vstatus):
global _last_card_id
card_id = params
......@@ -895,6 +969,9 @@ def handle_mifare_event(state, event, params, v, vstatus):
reset_idler(v, vstatus, 2)
return
"""
Triggered when a user swipes their card and the machine is logged in.
"""
def handle_mifare_add_user_event(state, event, params, v, vstatus):
global _last_card_id
card_id = params
......@@ -927,6 +1004,9 @@ def handle_mifare_add_user_event(state, event, params, v, vstatus):
def return_to_idle(state,event,params,v,vstatus):
reset_idler(v, vstatus)
"""
Maps what to do when the state changes.
"""
def create_state_table(vstatus):
vstatus.state_table[(STATE_IDLE,TICK,1)] = handle_idle_tick
vstatus.state_table[(STATE_IDLE,KEY,1)] = handle_idle_key
......@@ -966,6 +1046,9 @@ def create_state_table(vstatus):
vstatus.state_table[(STATE_GRANDFATHER_CLOCK,KEY,2)] = do_nothing
vstatus.state_table[(STATE_GRANDFATHER_CLOCK,MIFARE,1)] = handle_mifare_event
"""
Get what to do on a state change.
"""
def get_state_table_handler(vstatus, state, event, counter):
return vstatus.state_table[(state,event,counter)]
......@@ -989,17 +1072,6 @@ def run_forever(rfh, wfh, options, cf):
setup_idlers(v)
reset_idler(v, vstatus)
# This main loop was hideous and the work of the devil.
# This has now been fixed (mostly) - mtearle
#
#
# notes for later surgery
# (event, counter, ' ')
# V
# d[ ] = (method)
#
# ( return state - not currently implemented )
while True:
if USE_DB:
try:
......@@ -1013,14 +1085,14 @@ def run_forever(rfh, wfh, options, cf):
run_handler(event, params, v, vstatus)
# logging.debug('Got event: ' + repr(e))
def run_handler(event, params, v, vstatus):
handler = get_state_table_handler(vstatus,vstatus.state,event,vstatus.counter)
if handler:
handler(vstatus.state, event, params, v, vstatus)
"""
Connect to the machine.
"""
def connect_to_vend(options, cf):
if options.use_lat:
......@@ -1045,6 +1117,9 @@ def connect_to_vend(options, cf):
return rfh, wfh
"""
Parse arguments from the command line
"""
def parse_args():
from optparse import OptionParser
......@@ -1068,34 +1143,6 @@ def parse_args():
return options
config_options = {
'DBServer': ('Database', 'Server'),
'DBName': ('Database', 'Name'),
'DBUser': ('VendingMachine', 'DBUser'),
'DBPassword': ('VendingMachine', 'DBPassword'),
'ServiceName': ('VendingMachine', 'ServiceName'),
'ServicePassword': ('VendingMachine', 'Password'),
'ServerName': ('DecServer', 'Name'),
'ConnectPassword': ('DecServer', 'ConnectPassword'),
'PrivPassword': ('DecServer', 'PrivPassword'),
}
class VendConfigFile:
def __init__(self, config_file, options):
try:
cp = ConfigParser.ConfigParser()
cp.read(config_file)
for option in options:
section, name = options[option]
value = cp.get(section, name)
self.__dict__[option] = value
except ConfigParser.Error, e:
raise SystemExit("Error reading config file "+config_file+": " + str(e))
def create_pid_file(name):
try:
pid_file = file(name, 'w')
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment