Add SIGUSR1 traceback (made by jimbo, committed by TPG)
[uccvend-vendserver.git] / VendServer / VendServer.py
index 6c52933..cf9c8bb 100755 (executable)
@@ -20,6 +20,7 @@ from SnackConfig import get_snack#, get_snacks
 import socket
 from posix import geteuid
 from OpenDispense import OpenDispense as Dispense
+import TracebackPrinter
 
 CREDITS="""
 This vending machine software brought to you by:
@@ -140,8 +141,6 @@ class VendServer():
                # If the user has just logged in, show them their balance
                if welcome:
                        balance = self.dispense.getBalance()
-                       balance = balance[:-4] + '.' + balance[-4] + balance[-2:]   # Work around display bug
-                       
                        msg = [(self.center('WELCOME'), False, TEXT_SPEED),
                                   (self.center(self.dispense.getUsername()), False, TEXT_SPEED),
                                   (self.center(balance), False, TEXT_SPEED),]
@@ -336,12 +335,14 @@ class VendServer():
                                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
+                       self.dispense.logOut()
                        self.reset_idler()
 
                ### State fully logged out ... reset variables
@@ -370,7 +371,8 @@ class VendServer():
                                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
@@ -381,11 +383,12 @@ class VendServer():
                        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'))
-                               if self.vstatus.cur_user:
+                               if self.dispense.isLoggedIn():
                                        self.make_selection()
                                        self.vstatus.cur_selection = ''
                                        self.vstatus.time_to_autologout = time() + 8
@@ -394,7 +397,6 @@ class VendServer():
                                        # Price check mode.
                                        (name,price) = self.dispense.getItemInfo(self.vstatus.cur_selection)
                                        dollarprice = "$%.2f" % ( price / 100.0 )
-                                       dollarprice = dollarprice[:-4] + '.' + dollarprice[-4] + dollarprice[-2:]   # Work around display bug
                                        self.v.display( self.vstatus.cur_selection+' - %s'%dollarprice)
 
                                        self.vstatus.cur_selection = ''
@@ -405,6 +407,7 @@ class VendServer():
        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')
@@ -443,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
-                               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')
+                                       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
+                                       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?')
@@ -470,7 +474,8 @@ class VendServer():
                        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 = ''
@@ -479,8 +484,7 @@ 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.dispense.authUserIdPin(self.vstatus.cur_user, self.vstatus.cur_pin)
-                               if self.dispense.getUsername():
+                               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 = ''
@@ -518,6 +522,7 @@ class VendServer():
                if len(self.vstatus.cur_user) <8:
                        if key == 11:
                                self.vstatus.cur_user = ''
+                               self.dispense.logOut()
 
                                self.reset_idler()
                                return
@@ -597,6 +602,7 @@ class VendServer():
                key = params
                if key == 11:
                        self.vstatus.cur_user = ''
+                       self.dispense.logOut()
                        self.reset_idler()
                        return
                
@@ -761,6 +767,7 @@ class VendServer():
                        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
@@ -781,9 +788,7 @@ class VendServer():
 
                self._last_card_id = card_id
                
-               self.dispense.authMifareCard(card_id)
-               logging.info('Mapped card id to uid %s'%self.dispense.getUsername())
-               if not self.dispense.isLoggedIn():
+               if not self.dispense.authMifareCard(card_id):
                        self.v.beep(40, False)
                        self.vstatus.mk.set_messages(
                                [(self.center('BAD CARD'), False, 1.0),
@@ -795,6 +800,7 @@ class VendServer():
                        self.reset_idler(2)
                        return
                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.center('ACCT DISABLED'), False, 1.0),
@@ -803,6 +809,9 @@ class VendServer():
                        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)
@@ -955,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('--traceback-file', dest='traceback_file', default='', help='destination to print tracebacks when receiving SIGUSR1')
        options, args = op.parse_args()
 
        if len(args) != 0:
@@ -983,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.traceback_file != '': TracebackPrinter.traceback_init(options.traceback_file)
        return options, config_opts
 
 def clean_up_nicely(options, config_opts):
@@ -1047,7 +1057,7 @@ def do_vend_server(options, config_opts):
                        continue
                
 #              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