--- /dev/null
+from DispenseInterface import DispenseInterface
+import os
+import re
+import pwd
+from subprocess import Popen, PIPE
+from LDAPConnector import get_uid,get_uname, set_card_id
+
+"""
+Author: Mitchell Pomery (bobgeorge33)
+
+System to connect to OpenDispense2.
+Most of this code has been copied out of VendServer.py, then had variables updated so that it runs.
+This is so VendServer can easily operate regardless of the current accounting backend.
+Documentation for this code can be found inder Dispence.DispenceInterface
+"""
+class OpenDispense(DispenseInterface):
+ _username = None
+ _disabled = True
+ _loggedIn = False
+ _userId = None
+
+ def __init__(self, userId=None, username=None, loggedIn=False):
+ self._username = username
+ self._loggedIn = loggedIn
+ self._userId = userId
+
+ acct, unused = Popen(['dispense', 'acct', self._username], close_fds=True, stdout=PIPE).communicate()
+ # this is fucking appalling
+ flags = acct[acct.find("(")+1:acct.find(")")].strip()
+ if 'disabled' in flags:
+ self._disabled = True
+ if 'internal' in flags:
+ self._disabled = True
+ self._disabled = False
+
+ @staticmethod
+ def authUserIdPin(userId, pin):
+ try:
+ # Get info from
+ info = pwd.getpwuid(userId)
+ except KeyError:
+ logging.info('getting pin for uid %d: user not in password file'%uid)
+ return None
+
+ if info.pw_dir == None: return False
+ pinfile = os.path.join(info.pw_dir, '.pin')
+ try:
+ s = os.stat(pinfile)
+ except OSError:
+ logging.info('getting pin for uid %d: .pin not found in home directory'%uid)
+ return None
+ if s.st_mode & 077:
+ logging.info('getting pin for uid %d: .pin has wrong permissions. Fixing.'%uid)
+ os.chmod(pinfile, 0600)
+ try:
+ f = file(pinfile)
+ except IOError:
+ logging.info('getting pin for uid %d: I cannot read pin file'%uid)
+ return None
+ pinstr = f.readline().strip()
+ f.close()
+ if not re.search('^[0-9]{4}$', pinstr):
+ logging.info('getting pin for uid %d: %s not a good pin'%(uid,repr(pinstr)))
+ return None
+ return OpenDispense(userId, info.pw_name, (int(pin)==int(pinstr)))
+
+ @staticmethod
+ def authMifareCard(cardId):
+ return OpenDispense(get_uid(cardId), get_uname(get_uid(cardId)), True)
+
+ def addCard(self, cardId):
+ set_card_id(self._userId, cardId)
+
+ def isLoggedIn(self):
+ return self._loggedIn
+
+ def getUsername(self):
+ return self._username
+
+ def getBalance(self):
+ # Balance checking
+ acct, unused = Popen(['dispense', 'acct', self._username], close_fds=True, stdout=PIPE).communicate()
+ # this is fucking appalling
+ balance = acct[acct.find("$")+1:acct.find("(")].strip()
+ return balance
+
+ def getItemInfo(itemId):
+ itemId = OpenDispenseMapping.vendingMachineToOpenDispense(itemId)
+ args = ('dispense', 'iteminfo', itemId)
+ info, unused = Popen(args, close_fds=True, stdout=PIPE).communicate()
+ m = re.match("\s*[a-z]+:\d+\s+(\d+)\.(\d\d)\s+([^\n]+)", info)
+ cents = int(m.group(1))*100 + int(m.group(2))
+ # return (name, price in cents)
+ return (m.group(3), cents)
+
+ def isDisabled(self):
+ return False
+
+ def dispenseItem(self, itemId):
+ itemId = OpenDispenseMapping.vendingMachineToOpenDispense(itemId)
+ if itemId == "":
+ return False
+ else:
+ print('dispense -u "%s" %s'%(self._username, itemId))
+ os.system('dispense -u "%s" %s'%(self._username, itemId))
+ return True
+
+"""
+This class abstracts the idea of item numbers.
+It removes the need for VendServer to know the mappings between inputted numbers
+and the equivalent itemId in OpenDispense.
+"""
+class OpenDispenseMapping():
+
+ @staticmethod
+ def vendingMachineToOpenDispense(itemId):
+ _mappingFile = "OpenDispenseMappings.conf"
+ fh = open(_mappingFile)
+ map = ""
+ for line in fh:
+ #line = line.strip()
+ if line.startswith(str(itemId) + " "):
+ map = line[len(str(itemId)) + 1:].strip()
+ print(map)
+ return map
+