4 import sys, os, string, time, re, pwd
6 from LATClient import LATClient
7 from VendingMachine import VendingMachine
8 from ConfigParser import ConfigParser
10 GREETING = 'UCC SNACKS'
17 class DispenseDatabase:
18 def __init__(self, vending_machine, host, name, user, password):
19 self.vending_machine = vending_machine
20 self.db = pg.DB(dbname = name, host = host, user = user, passwd = password)
21 self.db.query('LISTEN vend_requests')
23 def process_requests(self):
25 query = 'SELECT request_id, request_slot FROM vend_requests WHERE request_handled = false'
27 outstanding = self.db.query(query).getresult()
28 except (pg.error,), db_err:
29 sys.stderr.write('Failed to query database: %s\n'%(db_err.strip()))
31 for (id, slot) in outstanding:
32 (worked, code, string) = self.vending_machine.vend(slot)
33 print (worked, code, string)
35 query = 'SELECT vend_success(%s)'%id
36 self.db.query(query).getresult()
38 query = 'SELECT vend_failed(%s)'%id
39 self.db.query(query).getresult()
41 def handle_events(self):
42 notifier = self.db.getnotify()
43 while notifier is not None:
44 self.process_requests()
45 notify = self.db.getnotify()
49 info = pwd.getpwuid(uid)
52 if info.pw_dir == None: return False
53 pinfile = os.path.join(info.pw_dir, '.pin')
66 if not re.search('^'+'[0-9]'*PIN_LENGTH+'$', pinstr):
70 def has_good_pin(uid):
71 return get_pin(uid) != None
73 def verify_user_pin(uid, pin):
74 if get_pin(uid) == pin:
75 info = pwd.getpwuid(uid)
80 def door_open_mode(vending_machine):
81 print "Entering open door mode"
82 v.display("DOOR OPEN")
88 if params == 1: # door closed
95 return ' '*((LEN-len(str))/2)+str
97 if __name__ == '__main__':
99 cp.read('/etc/dispense/servers.conf')
100 DBServer = cp.get('Database', 'Server')
101 DBName = cp.get('Database', 'Name')
102 DBUser = cp.get('VendingMachine', 'DBUser')
103 DBPassword = cp.get('VendingMachine', 'DBPassword')
105 ServiceName = cp.get('VendingMachine', 'ServiceName')
106 ServicePassword = cp.get('VendingMachine', 'Password')
107 # Open vending machine via LAT
108 latclient = LATClient(service = ServiceName, password = ServicePassword)
109 (rfh, wfh) = latclient.get_fh()
110 v = VendingMachine(rfh, wfh)
111 print 'PING is', v.ping()
112 #print 'BEEP is', v.beep()
113 #print 'VEND 11 is', v.vend('11')
114 #print 'SILENCE is', v.silence()
115 #print 'DISPLAY is', v.display('WELCOME')
116 print 'S is', v.get_switches()
118 db = DispenseDatabase(v, DBServer, DBName, DBUser, DBPassword)
119 db.process_requests()
124 scrolling_message = [GREETING]
125 scrolling_wraps = False
128 last_tick = time.time()
131 if time.time() > last_tick+1:
132 if timeout != None and timeout > 0: timeout -= 1
133 if len(scrolling_message) > 0:
135 last_tick = time.time()
136 if need_repaint and len(scrolling_message) > 0:
137 v.display(scrolling_message[0])
139 scrolling_message.append(scrolling_message[0])
140 del scrolling_message[0]
147 scrolling_message = [GREETING]
148 scrolling_wraps = False
153 #print 'waiting for event'
156 #print 'waiting harder for event'
157 e = v.next_event(0.1)
159 #print 'no event. passing'
169 scrolling_message = [GREETING]
170 scrolling_wraps = False
172 elif event == SWITCH:
173 # don't care right now.
177 # complicated key handling here:
178 if len(cur_user) < 5:
181 scrolling_message = [GREETING]
182 scrolling_wraps = False
185 cur_user += chr(key + ord('0'))
186 scrolling_message = []
187 v.display('UID: '+cur_user)
188 if len(cur_user) == 5:
190 if not has_good_pin(uid):
191 scrolling_message = map(center, ['INVALID','PIN','SETUP',GREETING])
192 scrolling_wraps = False
199 scrolling_message = []
201 elif len(cur_pin) < PIN_LENGTH:
205 scrolling_message = [GREETING]
206 scrolling_wraps = False
211 scrolling_message = []
213 cur_pin += chr(key + ord('0'))
214 v.display('PIN: '+'X'*len(cur_pin))
215 scrolling_message = []
216 if len(cur_pin) == PIN_LENGTH:
217 username = verify_user_pin(int(cur_user), int(cur_pin))
222 scrolling_message = [' WELCOME ', username]
223 scrolling_message.append('OR A SNACK')
224 scrolling_wraps = True
229 scrolling_message = [' BAD PIN ', ' SORRY ', GREETING]
230 scrolling_wraps = False
236 elif len(cur_selection) == 0:
243 scrolling_message = [GREETING]
244 scrolling_wraps = False
247 cur_selection += chr(key + ord('0'))
248 scrolling_message = []
249 v.display('SELECT: '+cur_selection)
250 elif len(cur_selection) == 1:
253 scrolling_message = []
254 v.display('SELECT: ')
257 cur_selection += chr(key + ord('0'))
258 #make_selection(cur_selection)
259 # XXX this should move somewhere else:
260 if cur_selection == '55':
261 v.display('GOT DOOR?')
262 os.system('su - "%s" -c "dispense door"'%username)
263 elif cur_selection[1] == '8':
264 v.display('GOT COKE?')
265 os.system('su - "%s" -c "dispense %s"'%(username, cur_selection[0]))
267 v.display('HERES A '+cur_selection)
268 v.vend(cur_selection)
270 v.display('THANK YOU')
273 scrolling_message = [
281 scrolling_wraps = True