Funkiness.
[zanchey/dispense2.git] / sql-edition / servers / VendServer.py
index 09bfe66..184546c 100755 (executable)
@@ -1,13 +1,17 @@
 #!/usr/bin/python
 # vim:ts=4
 
 #!/usr/bin/python
 # vim:ts=4
 
+USE_DB = 0
+
 import sys, os, string, re, pwd
 import sys, os, string, re, pwd
-import pg
+if USE_DB: import pg
 from time import time, sleep
 from popen2 import popen2
 from LATClient import LATClient
 from VendingMachine import VendingMachine
 from ConfigParser import ConfigParser
 from time import time, sleep
 from popen2 import popen2
 from LATClient import LATClient
 from VendingMachine import VendingMachine
 from ConfigParser import ConfigParser
+from HorizScroll import HorizScroll
+from random import random, seed
 
 GREETING = 'UCC SNACKS'
 PIN_LENGTH = 4
 
 GREETING = 'UCC SNACKS'
 PIN_LENGTH = 4
@@ -46,6 +50,32 @@ class DispenseDatabase:
                        self.process_requests()
                        notify = self.db.getnotify()
 
                        self.process_requests()
                        notify = self.db.getnotify()
 
+def scroll_options(username, mk, welcome = False):
+       if welcome:
+               msg = [(center('WELCOME'), False, 0.8),
+                          (center(username), False, 0.8)]
+       else:
+               msg = []
+       choices = ' '*10+'CHOICES: '
+       try:
+               coke_machine = file('/home/other/coke/coke_contents')
+               cokes = coke_machine.readlines()
+               coke_machine.close()
+       except:
+               cokes = []
+               pass
+       for c in cokes:
+               c = c.strip()
+               (slot_num, price, slot_name) = c.split(' ', 2)
+               if slot_name == 'dead': continue
+               choices += '%s8-%s (%sc) '%(slot_num, slot_name, price)
+       choices += '55-DOOR '
+       choices += 'OR A SNACK. '
+       choices += '99 TO READ AGAIN. '
+       choices += 'CHOICE?   '
+       msg.append((choices, False, None))
+       mk.set_messages(msg)
+
 def get_pin(uid):
        try:
                info = pwd.getpwuid(uid)
 def get_pin(uid):
        try:
                info = pwd.getpwuid(uid)
@@ -81,23 +111,108 @@ def verify_user_pin(uid, pin):
 
 def door_open_mode(vending_machine):
        print "Entering open door mode"
 
 def door_open_mode(vending_machine):
        print "Entering open door mode"
-       v.display("DOOR  OPEN")
+       v.display("-FEED  ME-")
        while True:
                e = v.next_event()
                if e == None: break
                (event, params) = e
                if event == DOOR:
                        if params == 1: # door closed
        while True:
                e = v.next_event()
                if e == None: break
                (event, params) = e
                if event == DOOR:
                        if params == 1: # door closed
-                               v.display("BYE BYE!")
+                               v.display("-YUM YUM!-")
                                sleep(1)
                                return
 
                                sleep(1)
                                return
 
+class Idler:
+       def __init__(self, v):
+               self.idle_state = 0
+               self.v = v
+
+       def put_shark(self, s, l):
+               if self.s[l] == ' ':
+                       self.s[l] = s
+               elif self.s[l] == 'X':
+                       self.s[l] = '*'
+               else:
+                       self.s[l] = 'X'
+
+       def next(self):
+               # does the next stage of a dance
+               self.s = [' ']*10
+               shark1 = self.idle_state % 18
+               if shark1 < 9:
+                       self.put_shark('^', shark1)
+               else:
+                       self.put_shark('^', 18-shark1)
+
+               shark2 = ((self.idle_state+4) % 36)/2
+               if shark2 < 9:
+                       self.put_shark('<', shark2)
+               else:
+                       self.put_shark('<', 18-shark2)
+
+               shark3 = ((self.idle_state+7) % 54)/3
+               if shark3 < 9:
+                       self.put_shark('>', 9-shark3)
+               else:
+                       self.put_shark('>', 9-(18-shark3))
+
+               train1 = ((self.idle_state%(18*36)))
+               train1_start = 122
+               if train1 > train1_start and train1 < train1_start+(10*2):
+                       for i in range(5):
+                               ptr = i+train1-train1_start-5
+                               if ptr >= 0 and ptr < 10: self.s[ptr] = '#'
+
+               train2 = ((self.idle_state%(18*36)))
+               train2_start = 400
+               if train2 > train2_start and train2 < train2_start+(10*2):
+                       for i in range(5):
+                               ptr = i+train2-train2_start-5
+                               if ptr >= 0 and ptr < 10: self.s[9-ptr] = '#'
+
+               train3 = ((self.idle_state%(18*36)))
+               train3_start = 230
+               if train3 > train3_start and train3 < train3_start+(10*2):
+                       for i in range(10):
+                               ptr = i+train3-train3_start-10
+                               if ptr >= 0 and ptr < 10: self.s[ptr] = '-'
+
+               self.v.display(string.join(self.s, ''))
+               self.idle_state += 1
+               self.idle_state %= 18*36*54
+
+def cookie(v):
+       seed(time())
+       messages = ['  WASSUP! ', 'PINK FISH ', ' SECRETS ']
+       choice = int(random()*len(messages))
+       msg = messages[choice]
+       left = range(len(msg))
+       for i in range(len(msg)):
+               if msg[i] == ' ': left.remove(i)
+       reveal = 1
+       while left:
+               s = ''
+               for i in range(0, len(msg)):
+                       if i in left:
+                               if reveal == 0:
+                                       left.remove(i)
+                                       s += msg[i]
+                               else:
+                                       s += chr(int(random()*26)+ord('A'))
+                       else:
+                               s += msg[i]
+                       reveal += 1
+                       reveal %= 173
+               v.display(s)
+
 def center(str):
        LEN = 10
        return ' '*((LEN-len(str))/2)+str
 
 class MessageKeeper:
        def __init__(self, vendie):
 def center(str):
        LEN = 10
        return ' '*((LEN-len(str))/2)+str
 
 class MessageKeeper:
        def __init__(self, vendie):
+               # Each element of scrolling_message should be a 3-tuple of
+               # ('message', True/False if it is to be repeated, time to display)
                self.scrolling_message = []
                self.v = vendie
                self.next_update = None
                self.scrolling_message = []
                self.v = vendie
                self.next_update = None
@@ -114,6 +229,18 @@ class MessageKeeper:
                if not forced and self.next_update != None and time() < self.next_update:
                        return
                if len(self.scrolling_message) > 0:
                if not forced and self.next_update != None and time() < self.next_update:
                        return
                if len(self.scrolling_message) > 0:
+                       if len(self.scrolling_message[0][0]) > 10:
+                               (m, r, t) = self.scrolling_message[0]
+                               a = []
+                               exp = HorizScroll(m).expand(padding = 0, wraparound = True)
+                               if t == None:
+                                       t = 0.1
+                               else:
+                                       t = t / len(exp)
+                               for x in exp:
+                                       a.append((x, r, t))
+                               del self.scrolling_message[0]
+                               self.scrolling_message = a + self.scrolling_message
                        newmsg = self.scrolling_message[0]
                        if newmsg[2] != None:
                                self.next_update = time() + newmsg[2]
                        newmsg = self.scrolling_message[0]
                        if newmsg[2] != None:
                                self.next_update = time() + newmsg[2]
@@ -124,6 +251,9 @@ class MessageKeeper:
                                self.scrolling_message.append(self.scrolling_message[0])
                        del self.scrolling_message[0]
 
                                self.scrolling_message.append(self.scrolling_message[0])
                        del self.scrolling_message[0]
 
+       def done(self):
+               return len(self.scrolling_message) == 0
+
 if __name__ == '__main__':
        cp = ConfigParser()
        cp.read('/etc/dispense/servers.conf')
 if __name__ == '__main__':
        cp = ConfigParser()
        cp.read('/etc/dispense/servers.conf')
@@ -148,32 +278,45 @@ if __name__ == '__main__':
        v = VendingMachine(rfh, wfh)
        print 'PING is', v.ping()
 
        v = VendingMachine(rfh, wfh)
        print 'PING is', v.ping()
 
-       db = DispenseDatabase(v, DBServer, DBName, DBUser, DBPassword)
+       if USE_DB: db = DispenseDatabase(v, DBServer, DBName, DBUser, DBPassword)
        cur_user = ''
        cur_pin = ''
        cur_selection = ''
 
        mk = MessageKeeper(v)
        mk.set_message(GREETING)
        cur_user = ''
        cur_pin = ''
        cur_selection = ''
 
        mk = MessageKeeper(v)
        mk.set_message(GREETING)
-       logout_timeout = None
+       time_to_autologout = None
+       idler = Idler(v)
+       time_to_idle = None
        last_timeout_refresh = None
 
        while True:
        last_timeout_refresh = None
 
        while True:
-               db.handle_events()
+               if USE_DB: db.handle_events()
 
 
-               if logout_timeout != None:
-                       time_left = logout_timeout - time()
-                       if time_left < 10 and last_timeout_refresh > time_left:
+               if time_to_autologout != None:
+                       time_left = time_to_autologout - time()
+                       if time_left < 5 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)
                                mk.set_message('LOGOUT: '+str(int(time_left)))
                                last_timeout_refresh = int(time_left)
+                               cur_selection = ''
 
 
-               if logout_timeout != None and logout_timeout - time() <= 0:
-                       logout_timeout = None
+               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)
 
                        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:
+                       # start autologout
+                       time_to_autologout = time() + 15
+
+               if time_to_idle == None and cur_user == '': time_to_idle = time() + 60
+               if time_to_idle != None and cur_user != '': time_to_idle = None
+               if time_to_idle is not None and time() > time_to_idle: idler.next()
+
                mk.update_display()
 
                e = v.next_event(0)
                mk.update_display()
 
                e = v.next_event(0)
@@ -232,13 +375,7 @@ if __name__ == '__main__':
                                        if username:
                                                v.beep(0, False)
                                                cur_selection = ''
                                        if username:
                                                v.beep(0, False)
                                                cur_selection = ''
-
-                                               msg = [(center('WELCOME'), False, 0.8),
-                                                          (center(username), False, 0.9)]
-                                               msg.append(('CHOICES :', True, 1))
-                                               msg.append(('55 - DOOR', True, 1))
-                                               msg.append(('OR A SNACK', True, 1))
-                                               mk.set_messages(msg)
+                                               scroll_options(username, mk, True)
                                                continue
                                        else:
                                                v.beep(40, False)
                                                continue
                                        else:
                                                v.beep(40, False)
@@ -260,10 +397,12 @@ if __name__ == '__main__':
                                        continue
                                cur_selection += chr(key + ord('0'))
                                mk.set_message('SELECT: '+cur_selection)
                                        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 = ''
                        elif len(cur_selection) == 1:
                                if key == 11:
                                        cur_selection = ''
-                                       mk.set_message('SELECT: ')
+                                       time_to_autologout = None
+                                       scroll_options(username, mk)
                                        continue
                                else:
                                        cur_selection += chr(key + ord('0'))
                                        continue
                                else:
                                        cur_selection += chr(key + ord('0'))
@@ -272,6 +411,12 @@ if __name__ == '__main__':
                                        if cur_selection == '55':
                                                v.display('GOT DOOR?')
                                                os.system('su - "%s" -c "dispense door"'%username)
                                        if cur_selection == '55':
                                                v.display('GOT DOOR?')
                                                os.system('su - "%s" -c "dispense door"'%username)
+                                       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?')
                                                os.system('su - "%s" -c "dispense %s"'%(username, cur_selection[0]))
                                        elif cur_selection[1] == '8':
                                                v.display('GOT COKE?')
                                                os.system('su - "%s" -c "dispense %s"'%(username, cur_selection[0]))
@@ -282,4 +427,4 @@ if __name__ == '__main__':
                                        v.display('THANK YOU')
                                        sleep(0.5)
                                        cur_selection = ''
                                        v.display('THANK YOU')
                                        sleep(0.5)
                                        cur_selection = ''
-                                       logout_timeout = time() + 10
+                                       time_to_autologout = time() + 10

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