Add SIGUSR1 traceback (made by jimbo, committed by TPG)
[uccvend-vendserver.git] / VendServer / VendServer.py
index d6a07a0..cf9c8bb 100755 (executable)
@@ -1,14 +1,12 @@
 #!/usr/bin/python
 #!/usr/bin/python
-# vim:ts=4
+# vim: ts=4 sts=4 sw=4 noexpandtab
 
 
-USE_DB = 0
 USE_MIFARE = 1
 
 import ConfigParser
 import sys, os, string, re, pwd, signal, math, syslog
 import logging, logging.handlers
 from traceback import format_tb
 USE_MIFARE = 1
 
 import ConfigParser
 import sys, os, string, re, pwd, signal, math, syslog
 import logging, logging.handlers
 from traceback import format_tb
-if USE_DB: import pg
 from time import time, sleep, mktime, localtime
 from subprocess import Popen, PIPE
 from LATClient import LATClient, LATClientException
 from time import time, sleep, mktime, localtime
 from subprocess import Popen, PIPE
 from LATClient import LATClient, LATClientException
@@ -21,8 +19,8 @@ from Idler import GreetingIdler,TrainIdler,GrayIdler,StringIdler,ClockIdler,Fort
 from SnackConfig import get_snack#, get_snacks
 import socket
 from posix import geteuid
 from SnackConfig import get_snack#, get_snacks
 import socket
 from posix import geteuid
-from LDAPConnector import get_uid,get_uname, set_card_id
 from OpenDispense import OpenDispense as Dispense
 from OpenDispense import OpenDispense as Dispense
+import TracebackPrinter
 
 CREDITS="""
 This vending machine software brought to you by:
 
 CREDITS="""
 This vending machine software brought to you by:
@@ -95,36 +93,6 @@ class VendConfigFile:
                except ConfigParser.Error, e:
                        raise SystemExit("Error reading config file "+config_file+": " + str(e))
 
                except ConfigParser.Error, e:
                        raise SystemExit("Error reading config file "+config_file+": " + str(e))
 
-class DispenseDatabaseException(Exception): pass
-
-class DispenseDatabase:
-       def __init__(self, vending_machine, host, name, user, password):
-               self.vending_machine = vending_machine
-               self.db = pg.DB(dbname = name, host = host, user = user, passwd = password)
-               self.db.query('LISTEN vend_requests')
-
-       def process_requests(self):
-               logging.debug('database processing')
-               query = 'SELECT request_id, request_slot FROM vend_requests WHERE request_handled = false'
-               try:
-                       outstanding = self.db.query(query).getresult()
-               except (pg.error,), db_err:
-                       raise DispenseDatabaseException('Failed to query database: %s\n'%(db_err.strip()))
-               for (id, slot) in outstanding:
-                       (worked, code, string) = self.vending_machine.vend(slot)
-                       logging.debug (str((worked, code, string)))
-                       if worked:
-                               query = 'SELECT vend_success(%s)'%id
-                               self.db.query(query).getresult()
-                       else:
-                               query = 'SELECT vend_failed(%s)'%id
-                               self.db.query(query).getresult()
-
-       def handle_events(self):
-               notifier = self.db.getnotify()
-               while notifier is not None:
-                       self.process_requests()
-                       notify = self.db.getnotify()
 """
 This class manages the current state of the vending machine.
 """
 """
 This class manages the current state of the vending machine.
 """
@@ -164,38 +132,32 @@ class VendServer():
        _pin_pin = '----'
        _last_card_id = -1
 
        _pin_pin = '----'
        _last_card_id = -1
 
+       dispense = None
+
        """
        Show information to the user as to what can be dispensed.
        """
        def scroll_options(self, username, mk, welcome = False):
                # If the user has just logged in, show them their balance
                if welcome:
        """
        Show information to the user as to what can be dispensed.
        """
        def scroll_options(self, 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()
-                       # this is fucking appalling
-                       balance = acct[acct.find("$")+1:acct.find("(")].strip()
-                       
+                       balance = self.dispense.getBalance()
                        msg = [(self.center('WELCOME'), False, TEXT_SPEED),
                        msg = [(self.center('WELCOME'), False, TEXT_SPEED),
-                                  (self.center(username), False, TEXT_SPEED),
+                                  (self.center(self.dispense.getUsername()), False, TEXT_SPEED),
                                   (self.center(balance), False, TEXT_SPEED),]
                else:
                        msg = []
                choices = ' '*10+'CHOICES: '
 
                # Show what is in the coke machine
                                   (self.center(balance), False, TEXT_SPEED),]
                else:
                        msg = []
                choices = ' '*10+'CHOICES: '
 
                # Show what is in the coke machine
+               # Need to update this so it uses the abstracted system
                cokes = []
                cokes = []
-               for i in range(0, 7):
-                       args = ('dispense', 'iteminfo', 'coke:%i' % i)
-                       info, unused = Popen(args, close_fds=True, stdout=PIPE).communicate()
-                       m = re.match("\s*[a-z]+:\d+\s+(\d+)\.(\d\d)\s+([^\n]+)", info)
-                       cents = int(m.group(1))*100 + int(m.group(2))
-                       cokes.append('%i %i %s' % (i, cents, m.group(3)));
+               for i in ['08', '18', '28', '38', '48', '58', '68']:
+                       cokes.append((i, self.dispense.getItemInfo(i)))
 
                for c in cokes:
 
                for c in cokes:
-                       c = c.strip()
-                       (slot_num, price, slot_name) = c.split(' ', 2)
-                       if slot_name == 'dead': continue
-                       choices += '%s-(%sc)-%s8 '%(slot_name, price, slot_num)
+                       if c[1][0] == 'dead':
+                               continue
+                       choices += '%s-(%sc)-%s8 '%(c[1][0], c[1][1], c[0])
 
                # Show the final few options
                choices += '55-DOOR '
 
                # Show the final few options
                choices += '55-DOOR '
@@ -206,88 +168,6 @@ class VendServer():
                # Send it to the display
                mk.set_messages(msg)
 
                # Send it to the display
                mk.set_messages(msg)
 
-
-       """
-       Verify the users pin
-       """
-       def _check_pin(self, uid, pin):
-               print "_check_pin('",uid,"',---)"
-               if uid != self._pin_uid:
-                       try:
-                               info = pwd.getpwuid(uid)
-                       except KeyError:
-                               logging.info('getting pin for uid %d: user not in password file'%uid)
-                               return None
-                       if info.pw_dir == None: return False
-                       pinfile = os.path.join(info.pw_dir, '.pin')
-                       try:
-                               s = os.stat(pinfile)
-                       except OSError:
-                               logging.info('getting pin for uid %d: .pin not found in home directory'%uid)
-                               return None
-                       if s.st_mode & 077:
-                               logging.info('getting pin for uid %d: .pin has wrong permissions. Fixing.'%uid)
-                               os.chmod(pinfile, 0600)
-                       try:
-                               f = file(pinfile)
-                       except IOError:
-                               logging.info('getting pin for uid %d: I cannot read pin file'%uid)
-                               return None
-                       pinstr = f.readline()
-                       f.close()
-                       if not re.search('^'+'[0-9]'*PIN_LENGTH+'$', pinstr):
-                               logging.info('getting pin for uid %d: %s not a good pin'%(uid,repr(pinstr)))
-                               return None
-                       self._pin_uid = uid
-                       self._pin_pin = pinstr
-                       self._pin_uname = info.pw_name
-               else:
-                       pinstr = self._pin_pin
-               if pin == int(pinstr):
-                       logging.info("Pin correct for %d",uid)
-               else:
-                       logging.info("Pin incorrect for %d",uid)
-               return pin == int(pinstr)
-
-       """
-       Check if the users account has been disabled
-       """
-       def acct_is_disabled(self, name=None):
-               if name == None:
-                       name = self._pin_uname
-               acct, unused = Popen(['dispense', 'acct', self._pin_uname], close_fds=True, stdout=PIPE).communicate()
-               # this is fucking appalling
-               flags = acct[acct.find("(")+1:acct.find(")")].strip()
-               if 'disabled' in flags:
-                       return True
-               if 'internal' in flags:
-                       return True
-               return False
-
-       """
-       Check that the user has a valid pin set
-       """
-       def has_good_pin(self, uid):
-               return self._check_pin(uid, None) != None
-
-       """
-       Verify the users pin.
-       """
-       def verify_user_pin(self, uid, pin, skip_pin_check=False):
-               if skip_pin_check or self._check_pin(uid, pin) == True:
-                       info = pwd.getpwuid(uid)
-                       if skip_pin_check:
-                               if self.acct_is_disabled(info.pw_name):
-                                       logging.info('refused mifare for disabled acct uid %d (%s)'%(uid,info.pw_name))
-                                       return '-disabled-'
-                               logging.info('accepted mifare for uid %d (%s)'%(uid,info.pw_name))
-                       else:
-                               logging.info('accepted pin for uid %d (%s)'%(uid,info.pw_name))
-                       return info.pw_name
-               else:
-                       logging.info('refused pin for uid %d'%(uid))
-                       return None
-
        """
        In here just for fun.
        """
        """
        In here just for fun.
        """
@@ -455,12 +335,14 @@ class VendServer():
                                self.vstatus.last_timeout_refresh = int(time_left)
                                self.vstatus.cur_selection = ''
 
                                self.vstatus.last_timeout_refresh = int(time_left)
                                self.vstatus.cur_selection = ''
 
+               # Login timed out: Log out the current user.
                if self.vstatus.time_to_autologout != None and self.vstatus.time_to_autologout - time() <= 0:
                        self.vstatus.time_to_autologout = None
                        self.vstatus.cur_user = ''
                        self.vstatus.cur_pin = ''
                        self.vstatus.cur_selection = ''
                        self._last_card_id = -1
                if self.vstatus.time_to_autologout != None and self.vstatus.time_to_autologout - time() <= 0:
                        self.vstatus.time_to_autologout = None
                        self.vstatus.cur_user = ''
                        self.vstatus.cur_pin = ''
                        self.vstatus.cur_selection = ''
                        self._last_card_id = -1
+                       self.dispense.logOut()
                        self.reset_idler()
 
                ### State fully logged out ... reset variables
                        self.reset_idler()
 
                ### State fully logged out ... reset variables
@@ -489,7 +371,8 @@ class VendServer():
                                self.vstatus.cur_pin = ''
                                self.vstatus.cur_user = ''
                                self.vstatus.cur_selection = ''
                                self.vstatus.cur_pin = ''
                                self.vstatus.cur_user = ''
                                self.vstatus.cur_selection = ''
-                               _last_card_id = -1
+                               self._last_card_id = -1
+                               self.dispense.logOut()
                                self.vstatus.mk.set_messages([(self.center('BYE!'), False, 1.5)])
                                self.reset_idler(2)
                                return
                                self.vstatus.mk.set_messages([(self.center('BYE!'), False, 1.5)])
                                self.reset_idler(2)
                                return
@@ -500,18 +383,22 @@ class VendServer():
                        if key == 11:
                                self.vstatus.cur_selection = ''
                                self.vstatus.time_to_autologout = None
                        if key == 11:
                                self.vstatus.cur_selection = ''
                                self.vstatus.time_to_autologout = None
+                               self.dispense.logOut()
                                self.scroll_options(self.vstatus.username, self.vstatus.mk)
                                return
                        else:
                                self.vstatus.cur_selection += chr(key + ord('0'))
                                self.scroll_options(self.vstatus.username, self.vstatus.mk)
                                return
                        else:
                                self.vstatus.cur_selection += chr(key + ord('0'))
-                               if self.vstatus.cur_user:
+                               if self.dispense.isLoggedIn():
                                        self.make_selection()
                                        self.vstatus.cur_selection = ''
                                        self.vstatus.time_to_autologout = time() + 8
                                        self.vstatus.last_timeout_refresh = None
                                else:
                                        # Price check mode.
                                        self.make_selection()
                                        self.vstatus.cur_selection = ''
                                        self.vstatus.time_to_autologout = time() + 8
                                        self.vstatus.last_timeout_refresh = None
                                else:
                                        # Price check mode.
-                                       self.price_check()
+                                       (name,price) = self.dispense.getItemInfo(self.vstatus.cur_selection)
+                                       dollarprice = "$%.2f" % ( price / 100.0 )
+                                       self.v.display( self.vstatus.cur_selection+' - %s'%dollarprice)
+
                                        self.vstatus.cur_selection = ''
                                        self.vstatus.time_to_autologout = None
                                        self.vstatus.last_timeout_refresh = None
                                        self.vstatus.cur_selection = ''
                                        self.vstatus.time_to_autologout = None
                                        self.vstatus.last_timeout_refresh = None
@@ -520,6 +407,7 @@ class VendServer():
        Triggered when the user has entered the id of something they would like to purchase.
        """
        def make_selection(self):
        Triggered when the user has entered the id of something they would like to purchase.
        """
        def make_selection(self):
+               logging.debug('Dispense item "%s"' % (self.vstatus.cur_selection,))
                # should use sudo here
                if self.vstatus.cur_selection == '55':
                        self.vstatus.mk.set_message('OPENSESAME')
                # should use sudo here
                if self.vstatus.cur_selection == '55':
                        self.vstatus.mk.set_message('OPENSESAME')
@@ -558,12 +446,13 @@ class VendServer():
                        exitcode = os.system('dispense -u "%s" snack:%s'%(self.vstatus.username, self.vstatus.cur_selection)) >> 8
                        if (exitcode == 0):
                                # magic dispense syslog service
                        exitcode = os.system('dispense -u "%s" snack:%s'%(self.vstatus.username, self.vstatus.cur_selection)) >> 8
                        if (exitcode == 0):
                                # magic dispense syslog service
-                               syslog.syslog(syslog.LOG_INFO | syslog.LOG_LOCAL4, "vended %s (slot %s) for %s" % (name, self.vstatus.cur_selection, self.vstatus.username))
                                (worked, code, string) = self.v.vend(self.vstatus.cur_selection)
                                if worked:
                                        self.v.display('THANK YOU')
                                (worked, code, string) = self.v.vend(self.vstatus.cur_selection)
                                if worked:
                                        self.v.display('THANK YOU')
+                                       syslog.syslog(syslog.LOG_INFO | syslog.LOG_LOCAL4, "vended %s (slot %s) for %s" % (name, self.vstatus.cur_selection, self.vstatus.username))
                                else:
                                        print "Vend Failed:", code, string
                                else:
                                        print "Vend Failed:", code, string
+                                       syslog.syslog(syslog.LOG_WARNING | syslog.LOG_LOCAL4, "vending %s (slot %s) for %s FAILED %r %r" % (name, self.vstatus.cur_selection, self.vstatus.username, code, string))
                                        self.v.display('VEND FAIL')
                        elif (exitcode == 5):   # RV_BALANCE
                                self.v.display('NO MONEY?')
                                        self.v.display('VEND FAIL')
                        elif (exitcode == 5):   # RV_BALANCE
                                self.v.display('NO MONEY?')
@@ -576,23 +465,6 @@ class VendServer():
                                self.v.display('UNK ERROR')
                sleep(1)
 
                                self.v.display('UNK ERROR')
                sleep(1)
 
-       """
-       Find the price of an item.
-       """
-       def price_check():
-               if self.vstatus.cur_selection[1] == '8':
-                       args = ('dispense', 'iteminfo', 'coke:' + self.vstatus.cur_selection[0])
-                       info, unused = Popen(args, close_fds=True, stdout=PIPE).communicate()
-                       dollarprice = re.match("\s*[a-z]+:\d+\s+(\d+\.\d\d)\s+([^\n]+)", info).group(1)
-               else:
-                       # first see if it's a named slot
-                       try:
-                               price, shortname, name = get_snack( self.vstatus.cur_selection )
-                       except:
-                               price, shortname, name = get_snack( '--' )
-                       dollarprice = "$%.2f" % ( price / 100.0 )
-               self.v.display(self.vstatus.cur_selection+' - %s'%dollarprice)
-
        """
        Triggered when the user presses a button while entering their pin.
        """
        """
        Triggered when the user presses a button while entering their pin.
        """
@@ -602,7 +474,8 @@ class VendServer():
                        if key == 11:
                                if self.vstatus.cur_pin == '':
                                        self.vstatus.cur_user = ''
                        if key == 11:
                                if self.vstatus.cur_pin == '':
                                        self.vstatus.cur_user = ''
-                                       slef.reset_idler()
+                                       self.dispense.logOut()
+                                       self.reset_idler()
 
                                        return
                                self.vstatus.cur_pin = ''
 
                                        return
                                self.vstatus.cur_pin = ''
@@ -611,8 +484,8 @@ class VendServer():
                        self.vstatus.cur_pin += chr(key + ord('0'))
                        self.vstatus.mk.set_message('PIN: '+'X'*len(self.vstatus.cur_pin))
                        if len(self.vstatus.cur_pin) == PIN_LENGTH:
                        self.vstatus.cur_pin += chr(key + ord('0'))
                        self.vstatus.mk.set_message('PIN: '+'X'*len(self.vstatus.cur_pin))
                        if len(self.vstatus.cur_pin) == PIN_LENGTH:
-                               self.vstatus.username = self.verify_user_pin(int(self.vstatus.cur_user), int(self.vstatus.cur_pin))
-                               if self.vstatus.username:
+                               if self.dispense.authUserIdPin(self.vstatus.cur_user, self.vstatus.cur_pin):
+                                       self.vstatus.username = self.dispense.getUsername()
                                        self.v.beep(0, False)
                                        self.vstatus.cur_selection = ''
                                        self.vstatus.change_state(STATE_GET_SELECTION)
                                        self.v.beep(0, False)
                                        self.vstatus.cur_selection = ''
                                        self.vstatus.change_state(STATE_GET_SELECTION)
@@ -642,13 +515,14 @@ class VendServer():
                        self.vstatus.time_to_autologout = None
                        self.vstatus.mk.set_message('PRICECHECK')
                        sleep(0.5)
                        self.vstatus.time_to_autologout = None
                        self.vstatus.mk.set_message('PRICECHECK')
                        sleep(0.5)
-                       self.scroll_options('', vstatus.mk)
+                       self.scroll_options('', self.vstatus.mk)
                        self.vstatus.change_state(STATE_GET_SELECTION)
                        return
 
                if len(self.vstatus.cur_user) <8:
                        if key == 11:
                                self.vstatus.cur_user = ''
                        self.vstatus.change_state(STATE_GET_SELECTION)
                        return
 
                if len(self.vstatus.cur_user) <8:
                        if key == 11:
                                self.vstatus.cur_user = ''
+                               self.dispense.logOut()
 
                                self.reset_idler()
                                return
 
                                self.reset_idler()
                                return
@@ -702,18 +576,9 @@ class VendServer():
 
                                return
 
 
                                return
 
-                       if not self.has_good_pin(uid):
-                               logging.info('user '+self.vstatus.cur_user+' has a bad PIN')
-                               self.vstatus.mk.set_messages(
-                                       [(' '*10+'INVALID PIN SETUP'+' '*11, False, 3)])
-                               self.vstatus.cur_user = ''
-                               self.vstatus.cur_pin = ''
-                               
-                               self.reset_idler(3)
-
-                               return
-                       
-                       if self.acct_is_disabled():
+                       # TODO Fix this up do we can check before logging in
+                       """
+                       if self.dispense.isDisabled():
                                logging.info('user '+self.vstatus.cur_user+' is disabled')
                                self.vstatus.mk.set_messages(
                                        [(' '*11+'ACCOUNT DISABLED'+' '*11, False, 3)])
                                logging.info('user '+self.vstatus.cur_user+' is disabled')
                                self.vstatus.mk.set_messages(
                                        [(' '*11+'ACCOUNT DISABLED'+' '*11, False, 3)])
@@ -722,7 +587,7 @@ class VendServer():
                                
                                self.reset_idler(3)
                                return
                                
                                self.reset_idler(3)
                                return
-
+                       """
 
                        self.vstatus.cur_pin = ''
                        self.vstatus.mk.set_message('PIN: ')
 
                        self.vstatus.cur_pin = ''
                        self.vstatus.mk.set_message('PIN: ')
@@ -737,6 +602,7 @@ class VendServer():
                key = params
                if key == 11:
                        self.vstatus.cur_user = ''
                key = params
                if key == 11:
                        self.vstatus.cur_user = ''
+                       self.dispense.logOut()
                        self.reset_idler()
                        return
                
                        self.reset_idler()
                        return
                
@@ -901,6 +767,7 @@ class VendServer():
                        logging.warning("Entering open door mode")
                        self.v.display("-FEED  ME-")
                        #door_open_mode(v);
                        logging.warning("Entering open door mode")
                        self.v.display("-FEED  ME-")
                        #door_open_mode(v);
+                       self.dispense.logOut()
                        self.vstatus.cur_user = ''
                        self.vstatus.cur_pin = ''
                elif params == 1:  #door closed
                        self.vstatus.cur_user = ''
                        self.vstatus.cur_pin = ''
                elif params == 1:  #door closed
@@ -921,47 +788,39 @@ class VendServer():
 
                self._last_card_id = card_id
                
 
                self._last_card_id = card_id
                
-               try:
-                       self.vstatus.cur_user = get_uid(card_id)
-                       logging.info('Mapped card id to uid %s'%vstatus.cur_user)
-                       self.vstatus.username = get_uname(vstatus.cur_user)
-                       if self.acct_is_disabled(self.vstatus.username):
-                               self.vstatus.username = '-disabled-'
-               except ValueError:
-                       self.vstatus.username = None
-               if self.vstatus.username == '-disabled-':
+               if not self.dispense.authMifareCard(card_id):
                        self.v.beep(40, False)
                        self.vstatus.mk.set_messages(
                        self.v.beep(40, False)
                        self.vstatus.mk.set_messages(
-                               [(self.center('ACCT DISABLED'), False, 1.0),
+                               [(self.center('BAD CARD'), False, 1.0),
                                 (self.center('SORRY'), False, 0.5)])
                        self.vstatus.cur_user = ''
                        self.vstatus.cur_pin = ''
                                 (self.center('SORRY'), False, 0.5)])
                        self.vstatus.cur_user = ''
                        self.vstatus.cur_pin = ''
-                       self.vstatus.username = None
+                       self._last_card_id = -1
                
                        self.reset_idler(2)
                        return
                
                        self.reset_idler(2)
                        return
-               elif self.vstatus.username:
-                       self.v.beep(0, False)
-                       self.vstatus.cur_selection = ''
-                       self.vstatus.change_state(STATE_GET_SELECTION)
-                       self.scroll_options(self.vstatus.username, self.vstatus.mk, True)
-                       return
-               else:
+               elif self.dispense.isDisabled():
+                       logging.info('Mapped card id to uid %s'%self.dispense.getUsername())
                        self.v.beep(40, False)
                        self.vstatus.mk.set_messages(
                        self.v.beep(40, False)
                        self.vstatus.mk.set_messages(
-                               [(self.center('BAD CARD'), False, 1.0),
+                               [(self.center('ACCT DISABLED'), False, 1.0),
                                 (self.center('SORRY'), False, 0.5)])
                                 (self.center('SORRY'), False, 0.5)])
-                       self.vstatus.cur_user = ''
-                       self.vstatus.cur_pin = ''
-                       self._last_card_id = -1
-               
+                       self.dispense.logOut()
                        self.reset_idler(2)
                        return
                        self.reset_idler(2)
                        return
+               else:
+                       logging.info('Mapped card id to uid %s'%self.dispense.getUsername())
+                       self.vstatus.cur_user = '----'
+                       self.vstatus.username = self.dispense.getUsername()
+                       self.vstatus.cur_selection = ''
+                       self.vstatus.change_state(STATE_GET_SELECTION)
+                       self.scroll_options(self.vstatus.username, self.vstatus.mk, True)
+                       return
 
        """
        Triggered when a user swipes their card and the machine is logged in.
        """
 
        """
        Triggered when a user swipes their card and the machine is logged in.
        """
-       def handle_mifare_add_user_event(self, evnt, params):
+       def handle_mifare_add_user_event(self, event, params):
                card_id = params
 
                # Translate card_id into uid.
                card_id = params
 
                # Translate card_id into uid.
@@ -969,25 +828,15 @@ class VendServer():
                        return
 
                self._last_card_id = card_id
                        return
 
                self._last_card_id = card_id
-               
-               try:
-                       if get_uid(card_id) != None:
-                               self.vstatus.mk.set_messages(
-                                       [(self.center('ALREADY'), False, 0.5),
-                                        (self.center('ENROLLED'), False, 0.5)])
-
-                               # scroll_options(vstatus.username, vstatus.mk)
-                               return
-               except ValueError:
-                       pass
-
-               logging.info('Enrolling card %s to uid %s (%s)'%(card_id, vstatus.cur_user, vstatus.username))
-               self.set_card_id(self.vstatus.cur_user, card_id)
-               self.vstatus.mk.set_messages(
-                       [(self.center('CARD'), False, 0.5),
-                        (self.center('ENROLLED'), False, 0.5)])
 
 
-               # scroll_options(vstatus.username, vstatus.mk)
+               if not self.dispense.addCard(card_id):
+                       self.vstatus.mk.set_messages(
+                               [(self.center('ALREADY'), False, 0.5),
+                                (self.center('ENROLLED'), False, 0.5)])
+               else:
+                       self.vstatus.mk.set_messages(
+                               [(self.center('CARD'), False, 0.5),
+                                (self.center('ENROLLED'), False, 0.5)])
 
        def return_to_idle(self, event, params):
                self.reset_idler()
 
        def return_to_idle(self, event, params):
                self.reset_idler()
@@ -1050,23 +899,16 @@ class VendServer():
 
        def run_forever(self, rfh, wfh, options, cf):
                self.v = VendingMachine(rfh, wfh, USE_MIFARE)
 
        def run_forever(self, rfh, wfh, options, cf):
                self.v = VendingMachine(rfh, wfh, USE_MIFARE)
+               self.dispense = Dispense()
                self.vstatus = VendState(self.v)
                self.create_state_table()
 
                logging.debug('PING is ' + str(self.v.ping()))
 
                self.vstatus = VendState(self.v)
                self.create_state_table()
 
                logging.debug('PING is ' + str(self.v.ping()))
 
-               if USE_DB: db = DispenseDatabase(v, cf.DBServer, cf.DBName, cf.DBUser, cf.DBPassword)
-
                self.setup_idlers()
                self.reset_idler()
 
                while True:
                self.setup_idlers()
                self.reset_idler()
 
                while True:
-                       if USE_DB:
-                               try:
-                                       db.handle_events()
-                               except DispenseDatabaseException, e:
-                                       logging.error('Database error: '+str(e))
-
                        timeout = self.time_to_next_update()
                        (event, params) = self.v.next_event(timeout)
                        self.run_handler(event, params)
                        timeout = self.time_to_next_update()
                        (event, params) = self.v.next_event(timeout)
                        self.run_handler(event, params)
@@ -1085,11 +927,11 @@ def connect_to_vend(options, cf):
                logging.info('Connecting to vending machine using LAT')
                latclient = LATClient(service = cf.ServiceName, password = cf.ServicePassword, server_name = cf.ServerName, connect_password = cf.ConnectPassword, priv_password = cf.PrivPassword)
                rfh, wfh = latclient.get_fh()
                logging.info('Connecting to vending machine using LAT')
                latclient = LATClient(service = cf.ServiceName, password = cf.ServicePassword, server_name = cf.ServerName, connect_password = cf.ConnectPassword, priv_password = cf.PrivPassword)
                rfh, wfh = latclient.get_fh()
-       #elif options.use_serial:
-       #       # Open vending machine via serial.
-       #       logging.info('Connecting to vending machine using serial')
-       #       serialclient = SerialClient(port = '/dev/ttyS1', baud = 9600)
-       #       rfh,wfh = serialclient.get_fh()
+       elif options.use_serial:
+               # Open vending machine via serial.
+               logging.info('Connecting to vending machine using serial')
+               serialclient = SerialClient(port = '/dev/ttyS1', baud = 9600)
+               rfh,wfh = serialclient.get_fh()
        else:
                #(rfh, wfh) = popen2('../../virtualvend/vvend.py')
                logging.info('Connecting to virtual vending machine on %s:%d'%(options.host,options.port))
        else:
                #(rfh, wfh) = popen2('../../virtualvend/vvend.py')
                logging.info('Connecting to virtual vending machine on %s:%d'%(options.host,options.port))
@@ -1110,7 +952,7 @@ def parse_args():
        from optparse import OptionParser
 
        op = OptionParser(usage="%prog [OPTION]...")
        from optparse import OptionParser
 
        op = OptionParser(usage="%prog [OPTION]...")
-       op.add_option('-f', '--config-file', default='./servers.conf', metavar='FILE', dest='config_file', help='use the specified config file instead of /etc/dispense/servers.conf')
+       op.add_option('-f', '--config-file', default='/etc/dispense2/servers.conf', metavar='FILE', dest='config_file', help='use the specified config file instead of /etc/dispense/servers.conf')
        op.add_option('--serial', action='store_true', default=False, dest='use_serial', help='use the serial port')
        op.add_option('--lat', action='store_true', default=False, dest='use_lat', help='use LAT')
        op.add_option('--virtualvend', action='store_false', default=True, dest='use_serial', help='use the virtual vending server instead of LAT')
        op.add_option('--serial', action='store_true', default=False, dest='use_serial', help='use the serial port')
        op.add_option('--lat', action='store_true', default=False, dest='use_lat', help='use LAT')
        op.add_option('--virtualvend', action='store_false', default=True, dest='use_serial', help='use the virtual vending server instead of LAT')
@@ -1122,6 +964,7 @@ def parse_args():
        op.add_option('-v', '--verbose', dest='verbose', action='store_true', default=False, help='spit out lots of debug output')
        op.add_option('-q', '--quiet', dest='quiet', action='store_true', default=False, help='only report errors')
        op.add_option('--pid-file', dest='pid_file', metavar='FILE', default='', help='store daemon\'s pid in the given file')
        op.add_option('-v', '--verbose', dest='verbose', action='store_true', default=False, help='spit out lots of debug output')
        op.add_option('-q', '--quiet', dest='quiet', action='store_true', default=False, help='only report errors')
        op.add_option('--pid-file', dest='pid_file', metavar='FILE', default='', help='store daemon\'s pid in the given file')
+        op.add_option('--traceback-file', dest='traceback_file', default='', help='destination to print tracebacks when receiving SIGUSR1')
        options, args = op.parse_args()
 
        if len(args) != 0:
        options, args = op.parse_args()
 
        if len(args) != 0:
@@ -1150,7 +993,7 @@ def set_stuff_up():
        if options.daemon: become_daemon()
        set_up_logging(options)
        if options.pid_file != '': create_pid_file(options.pid_file)
        if options.daemon: become_daemon()
        set_up_logging(options)
        if options.pid_file != '': create_pid_file(options.pid_file)
-
+       if options.traceback_file != '': TracebackPrinter.traceback_init(options.traceback_file)
        return options, config_opts
 
 def clean_up_nicely(options, config_opts):
        return options, config_opts
 
 def clean_up_nicely(options, config_opts):
@@ -1214,7 +1057,7 @@ def do_vend_server(options, config_opts):
                        continue
                
 #              run_forever(rfh, wfh, options, config_opts)
                        continue
                
 #              run_forever(rfh, wfh, options, config_opts)
-               
+
                try:
                        vserver = VendServer()
                        vserver.run_forever(rfh, wfh, options, config_opts)
                try:
                        vserver = VendServer()
                        vserver.run_forever(rfh, wfh, options, config_opts)

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