Commit ed50c28e authored by Mitchell Pomery's avatar Mitchell Pomery Committed by Mark Tearle
Browse files

DispenseInterface and OpenDispense Implimentation created and tested. Not...

DispenseInterface and OpenDispense Implimentation created and tested. Not curruntly used by VendServer
parent fc542240
"""
Author: Mitchell Pomery (bobgeorge33)
Dispense is an abstract class that allows easy configuration between different systems. Anything that is
intended to talk to OpenDispense or similar should comply with this class. Using this class in particular
will cause you a lot of problems.
"""
class DispenseInterface(object):
"""
Create a new dispense object.
"""
def __init__(self, username=None, loggedIn=False, disabled=False):
pass
"""
Create a new dispense interface as the supplied user.
"""
@staticmethod
def authUsernamePin(username, pin):
pass
"""
Create a new dispense interface as the supplied user.
"""
@staticmethod
def authMifare(cardId):
pass
"""
Check if creating the user worked correctly.
"""
def isLoggedIn(self):
pass
"""
Get the users username.
"""
def getUsername(self, user):
pass
"""
Get the users current balance.
"""
def getBalance(self, user):
pass
"""
Get the name and price of an item.
itemId is the number entered into the vending machine
"""
@staticmethod
def getItemInfo(itemId):
pass
"""
Check if the user is disabled.
"""
def isDisabled(self):
pass
"""
Dispense an item for the current user.
itemId is the number entered into the vending machine
"""
def dispenseItem(self, itemId):
pass
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
# This file is used to map things from vending machine inputs into OpenDispense items
# Lines that start with a # are comments
# Lines that contain only white space are ignored
# The top three rows only contain 5 slots for items
11 snack:11
31 snack:31
51 snack:51
71 snack:71
91 snack:91
12 snack:12
32 snack:32
52 snack:52
72 snack:72
92 snack:92
13 snack:13
33 snack:33
53 snack:53
73 snack:73
93 snack:93
# This row has 10
04 snack:04
14 snack:14
24 snack:24
34 snack:34
44 snack:44
54 snack:54
64 snack:64
74 snack:74
84 snack:84
94 snack:94
# Row 5 is used only for door
55 door
# The next two rows have 10 items each
06 snack:06
16 snack:16
26 snack:26
36 snack:36
46 snack:46
56 snack:56
66 snack:66
76 snack:76
86 snack:86
96 snack:96
07 snack:07
17 snack:17
27 snack:27
37 snack:37
47 snack:47
57 snack:57
67 snack:67
77 snack:77
87 snack:87
97 snack:97
# This last lot is for coke
08 coke:0
18 coke:1
28 coke:2
38 coke:3
48 coke:4
58 coke:5
68 coke:6
# There is no row 9
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment