From 060a73740d793c8f1643554829c90a0dd442ca79 Mon Sep 17 00:00:00 2001 From: Mitchell Pomery Date: Sun, 8 Mar 2015 23:44:19 +0800 Subject: [PATCH] Rearranging file and adding comments --- VendServer/VendServer.py | 209 ++++++++++++++++++++++++--------------- 1 file changed, 128 insertions(+), 81 deletions(-) diff --git a/VendServer/VendServer.py b/VendServer/VendServer.py index 4eb2986..860c1c8 100755 --- a/VendServer/VendServer.py +++ b/VendServer/VendServer.py @@ -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') -- 2.20.1