Rearranging file and adding comments
[uccvend-vendserver.git] / VendServer / OpenDispense.py
1 from DispenseInterface import DispenseInterface
2 import os
3 import re
4 import pwd
5 from subprocess import Popen, PIPE
6 from LDAPConnector import get_uid,get_uname, set_card_id
7
8 """
9 Author: Mitchell Pomery (bobgeorge33)
10
11 System to connect to OpenDispense2.
12 Most of this code has been copied out of VendServer.py, then had variables updated so that it runs.
13 This is so VendServer can easily operate regardless of the current accounting backend.
14 Documentation for this code can be found inder Dispence.DispenceInterface
15 """
16 class OpenDispense(DispenseInterface):
17         _username = None
18         _disabled = True
19         _loggedIn = False
20         _userId = None
21
22         def __init__(self, userId=None, username=None, loggedIn=False):
23                 self._username = username
24                 self._loggedIn = loggedIn
25                 self._userId = userId
26                 
27                 acct, unused = Popen(['dispense', 'acct', self._username], close_fds=True, stdout=PIPE).communicate()
28                 # this is fucking appalling
29                 flags = acct[acct.find("(")+1:acct.find(")")].strip()
30                 if 'disabled' in flags:
31                         self._disabled = True
32                 if 'internal' in flags:
33                         self._disabled = True
34                 self._disabled = False
35
36         @staticmethod
37         def authUserIdPin(userId, pin):
38                 try:
39                         # Get info from 
40                         info = pwd.getpwuid(userId)
41                 except KeyError:
42                         logging.info('getting pin for uid %d: user not in password file'%uid)
43                         return None
44
45                 if info.pw_dir == None: return False
46                 pinfile = os.path.join(info.pw_dir, '.pin')
47                 try:
48                         s = os.stat(pinfile)
49                 except OSError:
50                         logging.info('getting pin for uid %d: .pin not found in home directory'%uid)
51                         return None
52                 if s.st_mode & 077:
53                         logging.info('getting pin for uid %d: .pin has wrong permissions. Fixing.'%uid)
54                         os.chmod(pinfile, 0600)
55                 try:
56                         f = file(pinfile)
57                 except IOError:
58                         logging.info('getting pin for uid %d: I cannot read pin file'%uid)
59                         return None
60                 pinstr = f.readline().strip()
61                 f.close()
62                 if not re.search('^[0-9]{4}$', pinstr):
63                         logging.info('getting pin for uid %d: %s not a good pin'%(uid,repr(pinstr)))
64                         return None
65                 return OpenDispense(userId, info.pw_name, (int(pin)==int(pinstr)))
66
67         @staticmethod
68         def authMifareCard(cardId):
69                 return OpenDispense(get_uid(cardId), get_uname(get_uid(cardId)), True)
70
71         def addCard(self, cardId):
72                 set_card_id(self._userId, cardId)
73
74         def isLoggedIn(self):
75                 return self._loggedIn
76
77         def getUsername(self):
78                 return self._username
79
80         def getBalance(self):
81                 # Balance checking
82                 acct, unused = Popen(['dispense', 'acct', self._username], close_fds=True, stdout=PIPE).communicate()
83                 # this is fucking appalling
84                 balance = acct[acct.find("$")+1:acct.find("(")].strip()
85                 return balance
86
87         def getItemInfo(itemId):
88                 itemId = OpenDispenseMapping.vendingMachineToOpenDispense(itemId)
89                 args = ('dispense', 'iteminfo', itemId)
90                 info, unused = Popen(args, close_fds=True, stdout=PIPE).communicate()
91                 m = re.match("\s*[a-z]+:\d+\s+(\d+)\.(\d\d)\s+([^\n]+)", info)
92                 cents = int(m.group(1))*100 + int(m.group(2))
93                 # return (name, price in cents)
94                 return (m.group(3), cents)
95
96         def isDisabled(self):
97                 return False
98
99         def dispenseItem(self, itemId):
100                 itemId = OpenDispenseMapping.vendingMachineToOpenDispense(itemId)
101                 if itemId == "":
102                         return False
103                 else:
104                         print('dispense -u "%s" %s'%(self._username, itemId))
105                         os.system('dispense -u "%s" %s'%(self._username, itemId))
106                         return True
107
108 """
109 This class abstracts the idea of item numbers.
110 It removes the need for VendServer to know the mappings between inputted numbers
111 and the equivalent itemId in OpenDispense.
112 """
113 class OpenDispenseMapping():
114
115         @staticmethod
116         def vendingMachineToOpenDispense(itemId):
117                 _mappingFile = "OpenDispenseMappings.conf"
118                 fh = open(_mappingFile)
119                 map = ""
120                 for line in fh:
121                         #line = line.strip()
122                         if line.startswith(str(itemId) + " "):
123                                 map = line[len(str(itemId)) + 1:].strip()
124                                 print(map)
125                 return map
126

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