Skip to content
Snippets Groups Projects
Commit 060a7374 authored by Mitchell Pomery's avatar Mitchell Pomery Committed by Mark Tearle
Browse files

Rearranging file and adding comments

parent 3dbb7110
No related merge requests found
......@@ -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')
......
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