start of refactoring
[zanchey/dispense2.git] / sql-edition / servers / VendServer.py
index 7ac7071..e896920 100755 (executable)
@@ -238,21 +238,155 @@ def idle_step():
                choose_idler()
        idler.next()
 
+class VendState:
+       def __init__(self,v):
+               self.mk = MessageKeeper(v)
+               self.cur_user = ''
+               self.cur_pin = ''
+               self.cur_selection = ''
+               self.time_to_autologout = None
+               self.time_to_idle = None
+               self.last_timeout_refresh = None
+
+
+def handle_door_event(event, params, v, vstatus):
+       if params == 0:
+               door_open_mode(v);
+               vstatus.cur_user = ''
+               vstatus.cur_pin = ''
+               vstatus.mk.set_message(GREETING)
+
+def handle_switch_event(event, params, v, vstatus):
+       # don't care right now.
+       pass
+
+def handle_key_event(event, params, v, vstatus):
+       key = params
+       # complicated key handling here:
+       if len(vstatus.cur_user) < 5:
+               if key == 11:
+                       vstatus.cur_user = ''
+                       vstatus.mk.set_message(GREETING)
+                       return
+               vstatus.cur_user += chr(key + ord('0'))
+               vstatus.mk.set_message('UID: '+vstatus.cur_user)
+               if len(vstatus.cur_user) == 5:
+                       uid = int(vstatus.cur_user)
+                       if not has_good_pin(uid):
+                               logging.info('user '+vstatus.cur_user+' has a bad PIN')
+                               #mk.set_messages(
+                                       #[(center('INVALID'), False, 0.7),
+                                        #(center('PIN'), False, 0.7),
+                                        #(center('SETUP'), False, 1.0),
+                                        #(GREETING, False, None)])
+                               vstatus.mk.set_messages(
+                                       [(' '*10+'INVALID PIN SETUP'+' '*10, False, 3),
+                                        (GREETING, False, None)])
+                               vstatus.cur_user = ''
+                               vstatus.cur_pin = ''
+                               return
+                       vstatus.cur_pin = ''
+                       vstatus.mk.set_message('PIN: ')
+                       logging.info('need pin for user %s'%vstatus.cur_user)
+                       return
+       elif len(vstatus.cur_pin) < PIN_LENGTH:
+               if key == 11:
+                       if vstatus.cur_pin == '':
+                               vstatus.cur_user = ''
+                               vstatus.mk.set_message(GREETING)
+                               return
+                       vstatus.cur_pin = ''
+                       vstatus.mk.set_message('PIN: ')
+                       return
+               vstatus.cur_pin += chr(key + ord('0'))
+               vstatus.mk.set_message('PIN: '+'X'*len(vstatus.cur_pin))
+               if len(vstatus.cur_pin) == PIN_LENGTH:
+                       username = verify_user_pin(int(vstatus.cur_user), int(vstatus.cur_pin))
+                       if username:
+                               v.beep(0, False)
+                               vstatus.cur_selection = ''
+                               scroll_options(username, vstatus.mk, True)
+                               return
+                       else:
+                               v.beep(40, False)
+                               vstatus.mk.set_messages(
+                                       [(center('BAD PIN'), False, 1.0),
+                                        (center('SORRY'), False, 0.5),
+                                        (GREETING, False, None)])
+                               vstatus.cur_user = ''
+                               vstatus.cur_pin = ''
+                               return
+       elif len(vstatus.cur_selection) == 0:
+               if key == 11:
+                       vstatus.cur_pin = ''
+                       vstatus.cur_user = ''
+                       vstatus.cur_selection = ''
+                       vstatus.mk.set_messages(
+                               [(center('BYE!'), False, 1.5),
+                                (GREETING, False, None)])
+                       return
+               vstatus.cur_selection += chr(key + ord('0'))
+               vstatus.mk.set_message('SELECT: '+vstatus.cur_selection)
+               vstatus.time_to_autologout = None
+       elif len(vstatus.cur_selection) == 1:
+               if key == 11:
+                       vstatus.cur_selection = ''
+                       vstatus.time_to_autologout = None
+                       scroll_options(username, vstatus.mk)
+                       return
+               else:
+                       vstatus.cur_selection += chr(key + ord('0'))
+                       #make_selection(cur_selection)
+                       # XXX this should move somewhere else:
+                       if vstatus.cur_selection == '55':
+                               vstatus.mk.set_message('OPENSESAME')
+                               logging.info('dispensing a door for %s'%username)
+                               if geteuid() == 0:
+                                       ret = os.system('su - "%s" -c "dispense door"'%username)
+                               else:
+                                       ret = os.system('dispense door')
+                               if ret == 0:
+                                       logging.info('door opened')
+                                       vstatus.mk.set_message(center('DOOR OPEN'))
+                               else:
+                                       logging.warning('user %s tried to dispense a bad door'%username)
+                                       vstatus.mk.set_message(center('BAD DOOR'))
+                               sleep(1)
+                       elif vstatus.cur_selection == '91':
+                               cookie(v)
+                       elif vstatus.cur_selection == '99':
+                               scroll_options(username, vstatus.mk)
+                               vstatus.cur_selection = ''
+                               return
+                       elif vstatus.cur_selection[1] == '8':
+                               v.display('GOT COKE?')
+                               if ((os.system('su - "%s" -c "dispense %s"'%(username, vstatus.cur_selection[0])) >> 8) != 0):
+                                       v.display('SEEMS NOT')
+                               else:
+                                       v.display('GOT COKE!')
+                       else:
+                               v.display(vstatus.cur_selection+' - $1.00')
+                               if ((os.system('su - "%s" -c "dispense snack"'%(username)) >> 8) == 0):
+                                       v.vend(vstatus.cur_selection)
+                                       v.display('THANK YOU')
+                               else:
+                                       v.display('NO MONEY?')
+                       sleep(1)
+                       vstatus.cur_selection = ''
+                       vstatus.time_to_autologout = time() + 8
+                       vstatus.last_timeout_refresh = None
+
+
 def run_forever(rfh, wfh, options, cf):
        v = VendingMachine(rfh, wfh)
+       vstatus = VendState(v)
+
        logging.debug('PING is ' + str(v.ping()))
 
        if USE_DB: db = DispenseDatabase(v, cf.DBServer, cf.DBName, cf.DBUser, cf.DBPassword)
-       cur_user = ''
-       cur_pin = ''
-       cur_selection = ''
 
-       mk = MessageKeeper(v)
-       mk.set_message(GREETING)
-       time_to_autologout = None
+       vstatus.mk.set_message(GREETING)
        setup_idlers(v)
-       time_to_idle = None
-       last_timeout_refresh = None
 
 
        # This main loop is hideous and the work of the devil - mtearle
@@ -272,170 +406,53 @@ def run_forever(rfh, wfh, options, cf):
                        except DispenseDatabaseException, e:
                                logging.error('Database error: '+str(e))
 
-               if time_to_autologout != None:
-                       time_left = time_to_autologout - time()
-                       if time_left < 6 and (last_timeout_refresh is None or last_timeout_refresh > time_left):
-                               mk.set_message('LOGOUT: '+str(int(time_left)))
-                               last_timeout_refresh = int(time_left)
-                               cur_selection = ''
-
-               if time_to_autologout != None and time_to_autologout - time() <= 0:
-                       time_to_autologout = None
-                       cur_user = ''
-                       cur_pin = ''
-                       cur_selection = ''
-                       mk.set_message(GREETING)
-
-               if time_to_autologout and not mk.done(): time_to_autologout = None
-               if cur_user == '' and time_to_autologout: time_to_autologout = None
-               if len(cur_pin) == PIN_LENGTH and mk.done() and time_to_autologout == None:
+               if vstatus.time_to_autologout != None:
+                       time_left = vstatus.time_to_autologout - time()
+                       if time_left < 6 and (vstatus.last_timeout_refresh is None or vstatus.last_timeout_refresh > time_left):
+                               vstatus.mk.set_message('LOGOUT: '+str(int(time_left)))
+                               vstatus.last_timeout_refresh = int(time_left)
+                               vstatus.cur_selection = ''
+
+               if vstatus.time_to_autologout != None and vstatus.time_to_autologout - time() <= 0:
+                       vstatus.time_to_autologout = None
+                       vstatus.cur_user = ''
+                       vstatus.cur_pin = ''
+                       vstatus.cur_selection = ''
+                       vstatus.mk.set_message(GREETING)
+
+               if vstatus.time_to_autologout and not vstatus.mk.done(): vstatus.time_to_autologout = None
+               if vstatus.cur_user == '' and vstatus.time_to_autologout: vstatus.time_to_autologout = None
+               if len(vstatus.cur_pin) == PIN_LENGTH and vstatus.mk.done() and vstatus.time_to_autologout == None:
                        # start autologout
-                       time_to_autologout = time() + 15
-                       last_timeout_refresh = None
+                       vstatus.time_to_autologout = time() + 15
+                       vstatus.last_timeout_refresh = None
 
-               if time_to_idle == None and cur_user == '':
-                       time_to_idle = time() + 5
+               if vstatus.time_to_idle == None and vstatus.cur_user == '':
+                       vstatus.time_to_idle = time() + 5
                        choose_idler()
-               if time_to_idle is not None and cur_user != '': time_to_idle = None
-               if time_to_idle is not None and time() > time_to_idle: idle_step()
-               if time_to_idle is not None and time() > time_to_idle + 300:
-                       time_to_idle = time()
+               if vstatus.time_to_idle is not None and vstatus.cur_user != '': vstatus.time_to_idle = None
+               if vstatus.time_to_idle is not None and time() > vstatus.time_to_idle: idle_step()
+               if vstatus.time_to_idle is not None and time() > vstatus.time_to_idle + 300:
+                       vstatus.time_to_idle = time()
                        choose_idler()
 
-               mk.update_display()
+               vstatus.mk.update_display()
 
                e = v.next_event(0)
                if e == None:
                        e = v.next_event(0.05)
                        if e == None:
                                continue
-               time_to_idle = None
+               vstatus.time_to_idle = None
                (event, params) = e
                logging.debug('Got event: ' + repr(e))
+
                if event == DOOR:
-                       if params == 0:
-                               door_open_mode(v);
-                               cur_user = ''
-                               cur_pin = ''
-                               mk.set_message(GREETING)
+                       handle_door_event(event, params, v, vstatus)
                elif event == SWITCH:
-                       # don't care right now.
-                       pass
+                       handle_switch_event(event, params, v, vstatus)
                elif event == KEY:
-                       key = params
-                       # complicated key handling here:
-                       if len(cur_user) < 5:
-                               if key == 11:
-                                       cur_user = ''
-                                       mk.set_message(GREETING)
-                                       continue
-                               cur_user += chr(key + ord('0'))
-                               mk.set_message('UID: '+cur_user)
-                               if len(cur_user) == 5:
-                                       uid = int(cur_user)
-                                       if not has_good_pin(uid):
-                                               logging.info('user '+cur_user+' has a bad PIN')
-                                               #mk.set_messages(
-                                                       #[(center('INVALID'), False, 0.7),
-                                                        #(center('PIN'), False, 0.7),
-                                                        #(center('SETUP'), False, 1.0),
-                                                        #(GREETING, False, None)])
-                                               mk.set_messages(
-                                                       [(' '*10+'INVALID PIN SETUP'+' '*10, False, 3),
-                                                        (GREETING, False, None)])
-                                               cur_user = ''
-                                               cur_pin = ''
-                                               continue
-                                       cur_pin = ''
-                                       mk.set_message('PIN: ')
-                                       logging.info('need pin for user %s'%cur_user)
-                                       continue
-                       elif len(cur_pin) < PIN_LENGTH:
-                               if key == 11:
-                                       if cur_pin == '':
-                                               cur_user = ''
-                                               mk.set_message(GREETING)
-                                               continue
-                                       cur_pin = ''
-                                       mk.set_message('PIN: ')
-                                       continue
-                               cur_pin += chr(key + ord('0'))
-                               mk.set_message('PIN: '+'X'*len(cur_pin))
-                               if len(cur_pin) == PIN_LENGTH:
-                                       username = verify_user_pin(int(cur_user), int(cur_pin))
-                                       if username:
-                                               v.beep(0, False)
-                                               cur_selection = ''
-                                               scroll_options(username, mk, True)
-                                               continue
-                                       else:
-                                               v.beep(40, False)
-                                               mk.set_messages(
-                                                       [(center('BAD PIN'), False, 1.0),
-                                                        (center('SORRY'), False, 0.5),
-                                                        (GREETING, False, None)])
-                                               cur_user = ''
-                                               cur_pin = ''
-                                               continue
-                       elif len(cur_selection) == 0:
-                               if key == 11:
-                                       cur_pin = ''
-                                       cur_user = ''
-                                       cur_selection = ''
-                                       mk.set_messages(
-                                               [(center('BYE!'), False, 1.5),
-                                                (GREETING, False, None)])
-                                       continue
-                               cur_selection += chr(key + ord('0'))
-                               mk.set_message('SELECT: '+cur_selection)
-                               time_to_autologout = None
-                       elif len(cur_selection) == 1:
-                               if key == 11:
-                                       cur_selection = ''
-                                       time_to_autologout = None
-                                       scroll_options(username, mk)
-                                       continue
-                               else:
-                                       cur_selection += chr(key + ord('0'))
-                                       #make_selection(cur_selection)
-                                       # XXX this should move somewhere else:
-                                       if cur_selection == '55':
-                                               mk.set_message('OPENSESAME')
-                                               logging.info('dispensing a door for %s'%username)
-                                               if geteuid() == 0:
-                                                       ret = os.system('su - "%s" -c "dispense door"'%username)
-                                               else:
-                                                       ret = os.system('dispense door')
-                                               if ret == 0:
-                                                       logging.info('door opened')
-                                                       mk.set_message(center('DOOR OPEN'))
-                                               else:
-                                                       logging.warning('user %s tried to dispense a bad door'%username)
-                                                       mk.set_message(center('BAD DOOR'))
-                                               sleep(1)
-                                       elif cur_selection == '91':
-                                               cookie(v)
-                                       elif cur_selection == '99':
-                                               scroll_options(username, mk)
-                                               cur_selection = ''
-                                               continue
-                                       elif cur_selection[1] == '8':
-                                               v.display('GOT COKE?')
-                                               if ((os.system('su - "%s" -c "dispense %s"'%(username, cur_selection[0])) >> 8) != 0):
-                                                       v.display('SEEMS NOT')
-                                               else:
-                                                       v.display('GOT COKE!')
-                                       else:
-                                               v.display(cur_selection+' - $1.00')
-                                               if ((os.system('su - "%s" -c "dispense snack"'%(username)) >> 8) == 0):
-                                                       v.vend(cur_selection)
-                                                       v.display('THANK YOU')
-                                               else:
-                                                       v.display('NO MONEY?')
-                                       sleep(1)
-                                       cur_selection = ''
-                                       time_to_autologout = time() + 8
-                                       last_timeout_refresh = None
+                       handle_key_event(event, params, v, vstatus)
 
 def connect_to_vend(options, cf):
 

UCC git Repository :: git.ucc.asn.au