Update for new dispense binary/syntax by [MRD]/[BOB]/[TPG]
[zanchey/dispense2.git] / sql-edition / servers / VendServer.py
index fa5ba5b..9da6648 100755 (executable)
@@ -2,6 +2,7 @@
 # vim:ts=4
 
 USE_DB = 0
+USE_MIFARE = 1
 
 import ConfigParser
 import sys, os, string, re, pwd, signal, math, syslog
@@ -20,6 +21,7 @@ from Idler import GreetingIdler,TrainIdler,GrayIdler,StringIdler,ClockIdler,Fort
 from SnackConfig import get_snacks, get_snack
 import socket
 from posix import geteuid
+from LDAPConnector import get_uid, set_card_id
 
 CREDITS="""
 This vending machine software brought to you by:
@@ -56,7 +58,7 @@ STATE_GET_SELECTION,
 STATE_GRANDFATHER_CLOCK,
 ) = range(1,8)
 
-TEXT_SPEED = 0.6
+TEXT_SPEED = 0.8
 IDLE_SPEED = 0.05
 
 class DispenseDatabaseException(Exception): pass
@@ -92,10 +94,13 @@ class DispenseDatabase:
 
 def scroll_options(username, mk, welcome = False):
        if welcome:
-           # Balance checking: crap code, [DAA]'s fault
-           acct = os.popen('dispense acct %s' % username)
-               balance = acct.read()[15:22]
-               acct.close()
+               # Balance checking: crap code, [DAA]'s fault
+               # Updated 2011 to handle new dispense [MRD]
+               raw_acct = os.popen('dispense acct %s' % username)
+               acct = raw_acct.read()
+               # this is fucking appalling
+               balance = acct[acct.find("$")+1:acct.find("(")].strip()
+               raw_acct.close()
         
                msg = [(center('WELCOME'), False, TEXT_SPEED),
                           (center(username), False, TEXT_SPEED),
@@ -167,7 +172,10 @@ def has_good_pin(uid):
 def verify_user_pin(uid, pin, skip_pin_check=False):
        if skip_pin_check or get_pin(uid) == pin:
                info = pwd.getpwuid(uid)
-               logging.info('accepted pin for uid %d (%s)'%(uid,info.pw_name))
+               if skip_pin_check:
+                       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))
@@ -432,7 +440,7 @@ 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('su - "%s" -c "dispense give oday %d"'%(vstatus.username, price)) >> 8
+               exitcode = os.system('su - "%s" -c "dispense give \>snacksales %d \'%s\'"'%(vstatus.username, price, name)) >> 8
                if (exitcode == 0):
                        # magic dispense syslog service
                        syslog.syslog(syslog.LOG_INFO | syslog.LOG_LOCAL4, "vended %s (slot %s) for %s" % (name, vstatus.cur_selection, vstatus.username))
@@ -754,10 +762,17 @@ def handle_door_event(state, event, params, v, vstatus):
                v.display("-YUM YUM!-")
 
 def handle_mifare_event(state, event, params, v, vstatus):
-       card_uid = params
+       card_id = params
        # Translate card_id into uid.
-       vstatus.cur_user = str(card_uid)
-       vstatus.username = verify_user_pin(int(card_uid), None, True)
+       if card_id == None:
+               return
+
+       try:
+               vstatus.cur_user = get_uid(card_id)
+               logging.info('Mapped card id to uid %s'%vstatus.cur_user)
+               vstatus.username = verify_user_pin(int(vstatus.cur_user), None, True)
+       except ValueError:
+               vstatus.username = None
        if vstatus.username:
                v.beep(0, False)
                vstatus.cur_selection = ''
@@ -775,6 +790,32 @@ def handle_mifare_event(state, event, params, v, vstatus):
                reset_idler(v, vstatus, 2)
                return
 
+def handle_mifare_add_user_event(state, event, params, v, vstatus):
+       card_id = params
+
+       # Translate card_id into uid.
+       if card_id == None:
+               return
+
+       try:
+               if get_uid(card_id) != None:
+                       vstatus.mk.set_messages(
+                               [(center('ALREADY'), False, 0.5),
+                                (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))
+       set_card_id(vstatus.cur_user, card_id)
+       vstatus.mk.set_messages(
+               [(center('CARD'), False, 0.5),
+                (center('ENROLLED'), False, 0.5)])
+
+       # scroll_options(vstatus.username, vstatus.mk)
+
 def return_to_idle(state,event,params,v,vstatus):
        reset_idler(v, vstatus)
 
@@ -807,7 +848,7 @@ def create_state_table(vstatus):
        vstatus.state_table[(STATE_GET_SELECTION,TICK,1)] = handle_get_selection_idle
        vstatus.state_table[(STATE_GET_SELECTION,DOOR,1)] = do_nothing
        vstatus.state_table[(STATE_GET_SELECTION,KEY,1)] = handle_get_selection_key
-       vstatus.state_table[(STATE_GET_SELECTION,MIFARE,1)] = do_nothing
+       vstatus.state_table[(STATE_GET_SELECTION,MIFARE,1)] = handle_mifare_add_user_event
 
        vstatus.state_table[(STATE_GRANDFATHER_CLOCK,TICK,1)] = handle_idle_grandfather_tick
        vstatus.state_table[(STATE_GRANDFATHER_CLOCK,TICK,2)] = handle_grandfather_tick
@@ -829,7 +870,7 @@ def time_to_next_update(vstatus):
        return idle_update
 
 def run_forever(rfh, wfh, options, cf):
-       v = VendingMachine(rfh, wfh)
+       v = VendingMachine(rfh, wfh, USE_MIFARE)
        vstatus = VendState(v)
        create_state_table(vstatus)
 
@@ -891,6 +932,8 @@ def connect_to_vend(options, cf):
                sock.connect((options.host, options.port))
                rfh = sock.makefile('r')
                wfh = sock.makefile('w')
+               global USE_MIFARE
+               USE_MIFARE = 0
                
        return rfh, wfh
 

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