Remove redundant code associated with Bernard Postgres Dispense prototype
[uccvend-vendserver.git] / VendServer / OpenDispense.py
1 """
2 Author: Mitchell Pomery (bobgeorge33)
3
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
8 """
9
10 from DispenseInterface import DispenseInterface
11 import os
12 import logging
13 import re
14 import pwd
15 from subprocess import Popen, PIPE
16 from LDAPConnector import get_uid,get_uname, set_card_id
17
18 class OpenDispense(DispenseInterface):
19         _username = ""
20         _disabled = True
21         _loggedIn = False
22         _userId = None
23
24         def __init__(self, username=None, secret=False):
25                 pass
26
27         def authUserIdPin(self, userId, pin):
28                 userId = int(userId)
29
30                 try:
31                         # Get info from 
32                         info = pwd.getpwuid(userId)
33                 except KeyError:
34                         logging.info('getting pin for uid %d: user not in password file'%userId)
35                         return False
36
37                 if info.pw_dir == None: return False
38                 pinfile = os.path.join(info.pw_dir, '.pin')
39                 try:
40                         s = os.stat(pinfile)
41                 except OSError:
42                         logging.info('getting pin for uid %d: .pin not found in home directory'%userId)
43                         return False
44                 if s.st_mode & 077:
45                         logging.info('getting pin for uid %d: .pin has wrong permissions. Fixing.'%userId)
46                         os.chmod(pinfile, 0600)
47                 try:
48                         f = file(pinfile)
49                 except IOError:
50                         logging.info('getting pin for uid %d: I cannot read pin file'%userId)
51                         return False
52                 pinstr = f.readline().strip()
53                 f.close()
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)))
56                         return False
57
58                 if pinstr == str(pin):
59                         #Login Successful
60                         self._userid = userId
61                         self._loggedIn = True
62                         self._disabled = False
63                         self._username = info.pw_name
64                         return True
65                 
66                 # Login Unsuccessful
67                 return False
68
69         def authMifareCard(self, cardId):
70                 # Get the users ID
71                 self._userid = get_uid(cardId)
72
73                 # Check for thier username
74                 try:
75                         # Get info from 
76                         info = pwd.getpwuid(userId)
77                 except KeyError:
78                         logging.info('getting pin for uid %d: user not in password file'%uid)
79                         return False
80
81                 # If we get this far all is good
82                 self._loggedIn = True
83                 self._disabled = False
84                 self._username = info.pw_name
85                 return True
86
87         def addCard(self, cardId):
88                 if self.isLoggedIn():
89                         set_card_id(self._userId, cardId)
90                 return True
91
92         def isLoggedIn(self):
93                 return self._loggedIn
94
95         def getUsername(self):
96                 return self._username
97
98         def getBalance(self):
99                 # Balance checking
100                 if self.isLoggedIn():
101                         acct, unused = Popen(['dispense', 'acct', self._username], close_fds=True, stdout=PIPE).communicate()
102                 else:
103                         return None
104                 balance = acct[acct.find("$")+1:acct.find("(")].strip()
105                 return balance
106
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)
112                 if m == None:
113                         return("dead", 0)
114                 cents = int(m.group(1))*100 + int(m.group(2))
115                 # return (name, price in cents)
116                 return (m.group(3), cents)
117
118         def isDisabled(self):
119                 return self._disabled
120
121         def dispenseItem(self, itemId):
122                 if not self.isLoggedIn() or self.getItemInfo(itemId)[0] == "dead":
123                         return False
124                 else:
125                         print('dispense -u "%s" %s'%(self._username, itemId))
126                         #os.system('dispense -u "%s" %s'%(self._username, itemId))
127                         return True
128
129         def logOut(self):
130                 self._username = ""
131                 self._disabled = True
132                 self._loggedIn = False
133                 self._userId = None
134
135 """
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.
139 """
140 class OpenDispenseMapping():
141
142         @staticmethod
143         def vendingMachineToOpenDispense(itemId):
144                 _mappingFile = "OpenDispenseMappings.conf"
145                 fh = open(_mappingFile)
146                 map = ""
147                 for line in fh:
148                         #line = line.strip()
149                         if line.startswith(str(itemId) + " "):
150                                 map = line[len(str(itemId)) + 1:].strip()
151                                 print(map)
152                 return map
153

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