This repository has been archived on 2024-02-23. You can view files and clone it, but cannot push or open issues or pull requests.
memberPlumbing/doorUpdater.py

134 lines
4.6 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
import sys
2018-05-07 18:02:04 -04:00
import requests
import csv
from io import StringIO
from hashlib import md5
import os
2018-05-07 18:02:04 -04:00
from common import *
2018-05-07 18:02:04 -04:00
2018-05-07 18:25:14 -04:00
# mapping of member levels to schedules
2018-05-07 18:02:04 -04:00
memberLevels = {"CMS Staff": "7x24",
"CMS Weekends Only": "Weekends Only",
"CMS Weekdays Only": "Weekdays Only",
"CMS Unlimited": "Unlimited",
"CMS Nights & Weekends": "Nights and Weekends"}
2018-05-07 18:25:14 -04:00
# door access permissions to controller IP addresses
2018-05-07 18:02:04 -04:00
doors = {
"Rental Studio": ["172.18.51.11"],
"Storage Closet": ["172.18.51.12"],
"Metal Shop": ["172.18.51.13"],
"Wood Shop": ["172.18.51.14", "172.18.51.15"]
}
2018-05-07 18:25:14 -04:00
2018-05-07 18:02:04 -04:00
def getMembershipworksData():
2018-05-07 18:25:14 -04:00
""" Pull the members csv from the membershipworks api """
2018-05-07 18:02:04 -04:00
BASE_URL = "https://api.membershipworks.com/v1/"
2018-05-07 18:25:14 -04:00
# login
r = requests.post(BASE_URL + 'usr',
data={"_st": "all",
"eml": MEMBERSHIPWORKS_USERNAME,
"org": "10000",
"pwd": MEMBERSHIPWORKS_PASSWORD})
if r.status_code != 200 or 'SF' not in r.json():
print("MembershipWorks Login Error: ", r.status_code, r.reason)
print(r.text)
sys.exit(1)
2018-05-07 18:02:04 -04:00
SFtoken = r.json()['SF']
2018-05-07 18:25:14 -04:00
# get list of member/staff IDs
r = requests.get(BASE_URL + "ylp",
params={"SF": SFtoken,
"lbl": "5ae37979f033bfe8534f8799,5771675edcdf126302a2f6b9", # members and staff
"org": "15475", # unknown
"var": "_id,nam,ctc"})
if r.status_code != 200 or 'usr' not in r.json():
print("MembershipWorks User Listing Error: ", r.status_code, r.reason)
print(r.text)
sys.exit(1)
2018-05-07 18:02:04 -04:00
ids = [user['_id'] for user in r.json()['usr']]
2018-05-07 18:25:14 -04:00
# get members CSV
# TODO: maybe can just use previous get instead? would return JSON
r = requests.post(BASE_URL + "csv",
params={"SF": SFtoken},
data={"_rt": "946702800", # unknown
"mux": "", # unknown
"tid": ",".join(ids), # ids of members to get
2018-05-08 20:35:33 -04:00
"var": "lvl,xws,xms,xsc,xrs,xfd,xac,phn,eml,lbl,xcf,nam"}) # which columns to get
if r.status_code != 200:
print("MembershipWorks CSV Generation Error: ", r.status_code, r.reason)
print(r.text)
sys.exit(1)
2018-05-07 18:02:04 -04:00
newHash = md5(bytes(r.text, 'utf8')).hexdigest()
if os.path.exists('/tmp/doorUpdaterLastHash'):
with open('/tmp/doorUpdaterLastHash', 'r') as f:
if newHash == f.read():
print("hashes are the same, not updating")
sys.exit(0)
return r.text, newHash
2018-05-07 18:02:04 -04:00
def makeMember(member, doorAuth):
2018-05-07 18:25:14 -04:00
"""Create an output CSV row for the member"""
2018-05-07 18:02:04 -04:00
if member["Access Card Number"] == "":
#print(member["First Name"], member["Last Name"], " has no card number, ignoring")
return
out = {"Forename": member["First Name"],
2018-05-07 18:25:14 -04:00
"Surname": member["Last Name"],
"Initial": "",
"CardNumber": member["Access Card Number"],
2018-05-08 20:35:33 -04:00
"CardFormat": "A901146A-" + member["Access Card Facility Code"],
2018-05-07 18:25:14 -04:00
"PinRequired": "0",
"ExtendedAccess": "0",
"ExpiryDate": "",
"Email": member["Email"],
"Phone": member["Phone"]}
2018-05-07 18:02:04 -04:00
2018-05-08 20:27:32 -04:00
if member[doorAuth] == "Y" \
and not member["Account on Hold"] == "Account on Hold":
2018-05-07 18:02:04 -04:00
memberLevel = [v for k, v in memberLevels.items() if member[k] == k]
if len(memberLevel) == 1:
out["Schedule1"] = memberLevel[0]
else:
print(member["First Name"], member["Last Name"], "has no/too many member levels!")
return out
def makeDoor(doorName, doorIPs, members):
2018-05-07 18:25:14 -04:00
"""Create a CSV for the given door"""
2018-05-07 18:02:04 -04:00
outString = StringIO()
writer = csv.DictWriter(outString, fieldnames)
writer.writeheader()
for member in members:
2018-05-08 20:27:32 -04:00
member = makeMember(member, "Access " + doorName + "?")
2018-05-07 18:02:04 -04:00
if member is not None:
writer.writerow(member)
print(outString.getvalue())
for doorIP in doorIPs:
outString.seek(0)
doCSVImport(doorIP, outString)
2018-05-07 18:02:04 -04:00
pass
def main():
data, newHash = getMembershipworksData()
2018-05-07 18:02:04 -04:00
reader = csv.DictReader(StringIO(data))
members = list(reader)
for doorName, doorIP in doors.items():
makeDoor(doorName, doorIP, members)
# write out hash if we sucessfully got here
with open('/tmp/doorUpdaterLastHash', 'w') as f:
f.write(newHash)
2018-05-07 18:02:04 -04:00
if __name__ == '__main__':
main()