2 Author: Mitchell Pomery (bobgeorge33)
4 System to connect to OpenDispense2.
5 Most of this code has been copied out of VendServer.py, then had variables updated so that it runs.
6 This is so VendServer can easily operate regardless of the current accounting backend.
7 Documentation for this code can be found inder Dispence.DispenceInterface
10 from DispenseInterface import DispenseInterface
15 from subprocess import Popen, PIPE
16 from LDAPConnector import get_uid,get_uname, set_card_id
18 class OpenDispense(DispenseInterface):
24 def __init__(self, username=None, secret=False):
27 def authUserIdPin(self, userId, pin):
32 info = pwd.getpwuid(userId)
34 logging.info('getting pin for uid %d: user not in password file'%userId)
37 if info.pw_dir == None: return False
38 pinfile = os.path.join(info.pw_dir, '.pin')
42 logging.info('getting pin for uid %d: .pin not found in home directory'%userId)
45 logging.info('getting pin for uid %d: .pin has wrong permissions. Fixing.'%userId)
46 os.chmod(pinfile, 0600)
50 logging.info('getting pin for uid %d: I cannot read pin file'%userId)
52 pinstr = f.readline().strip()
54 if not re.search('^[0-9]{4}$', pinstr):
55 logging.info('getting pin for uid %d: %s not a good pin'%(userId,repr(pinstr)))
58 if pinstr == str(pin):
62 self._disabled = False
63 self._username = info.pw_name
69 def authMifareCard(self, cardId):
71 self._userid = get_uid(cardId)
73 # Check for thier username
76 info = pwd.getpwuid(userId)
78 logging.info('getting pin for uid %d: user not in password file'%uid)
81 # If we get this far all is good
83 self._disabled = False
84 self._username = info.pw_name
87 def addCard(self, cardId):
89 set_card_id(self._userId, cardId)
95 def getUsername(self):
100 if self.isLoggedIn():
101 acct, unused = Popen(['dispense', 'acct', self._username], close_fds=True, stdout=PIPE).communicate()
104 balance = acct[acct.find("$")+1:acct.find("(")].strip()
107 def getItemInfo(self, itemId):
108 itemId = OpenDispenseMapping.vendingMachineToOpenDispense(itemId)
109 args = ('dispense', 'iteminfo', itemId)
110 info, unused = Popen(args, close_fds=True, stdout=PIPE).communicate()
111 m = re.match("\s*[a-z]+:\d+\s+(\d+)\.(\d\d)\s+([^\n]+)", info)
114 cents = int(m.group(1))*100 + int(m.group(2))
115 # return (name, price in cents)
116 return (m.group(3), cents)
118 def isDisabled(self):
119 return self._disabled
121 def dispenseItem(self, itemId):
122 if not self.isLoggedIn() or self.getItemInfo(itemId)[0] == "dead":
125 print('dispense -u "%s" %s'%(self._username, itemId))
126 #os.system('dispense -u "%s" %s'%(self._username, itemId))
131 self._disabled = True
132 self._loggedIn = False
136 This class abstracts the idea of item numbers.
137 It removes the need for VendServer to know the mappings between inputted numbers
138 and the equivalent itemId in OpenDispense.
140 class OpenDispenseMapping():
143 def vendingMachineToOpenDispense(itemId):
144 _mappingFile = "OpenDispenseMappings.conf"
145 fh = open(_mappingFile)
149 if line.startswith(str(itemId) + " "):
150 map = line[len(str(itemId)) + 1:].strip()