diff --git a/doorUpdater.py b/doorUpdater.py index 0bcd2f1..d7f3165 100644 --- a/doorUpdater.py +++ b/doorUpdater.py @@ -5,16 +5,19 @@ import urllib3 from passwords import * +# it's fine, ssl certs are for losers anyway urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) fieldnames = "CardNumber,CardFormat,PinRequired,PinCode,ExtendedAccess,ExpiryDate,Forename,Initial,Surname,Email,Phone,Custom1,Custom2,Schedule1,Schedule2,Schedule3,Schedule4,Schedule5,Schedule6,Schedule7,Schedule8".split(",") +# mapping of member levels to schedules memberLevels = {"CMS Staff": "7x24", "CMS Weekends Only": "Weekends Only", "CMS Weekdays Only": "Weekdays Only", "CMS Unlimited": "Unlimited", "CMS Nights & Weekends": "Nights and Weekends"} +# door access permissions to controller IP addresses doors = { "Rental Studio": ["172.18.51.11"], "Storage Closet": ["172.18.51.12"], @@ -22,9 +25,12 @@ doors = { "Wood Shop": ["172.18.51.14", "172.18.51.15"] } + def getMembershipworksData(): + """ Pull the members csv from the membershipworks api """ BASE_URL = "https://api.membershipworks.com/v1/" + # login sess = requests.Session() r = sess.post(BASE_URL + 'usr', data={"_st": "all", @@ -33,37 +39,41 @@ def getMembershipworksData(): "pwd": MEMBERSHIPWORKS_PASSWORD}) SFtoken = r.json()['SF'] + # get list of member/staff IDs r = sess.get(BASE_URL + "ylp", params={"SF": SFtoken, - "lbl": "5ae37979f033bfe8534f8799,5771675edcdf126302a2f6b9", - "org": "15475", + "lbl": "5ae37979f033bfe8534f8799,5771675edcdf126302a2f6b9", # members and staff + "org": "15475", # unknown "var": "_id,nam,ctc"}) ids = [user['_id'] for user in r.json()['usr']] + # get members CSV + # TODO: maybe can just use previous get instead? would return JSON r = sess.post(BASE_URL + "csv", params={"SF": SFtoken}, - data={"_rt": "946702800", - "mux": "", - "tid": ",".join(ids), - "var": "lvl,xws,xms,xsc,xrs,xfd,xac,phn,eml,lbl,nam"}) + data={"_rt": "946702800", # unknown + "mux": "", # unknown + "tid": ",".join(ids), # ids of members to get + "var": "lvl,xws,xms,xsc,xrs,xfd,xac,phn,eml,lbl,nam"}) # which columns to get return r.text def makeMember(member, doorAuth): + """Create an output CSV row for the member""" if member["Access Card Number"] == "": #print(member["First Name"], member["Last Name"], " has no card number, ignoring") return out = {"Forename": member["First Name"], - "Surname": member["Last Name"], - "Initial": "", - "CardNumber": member["Access Card Number"], - "CardFormat": "A901146A-241", - "PinRequired": "0", - "ExtendedAccess": "0", - "ExpiryDate": "", - "Email": member["Email"], - "Phone": member["Phone"]} + "Surname": member["Last Name"], + "Initial": "", + "CardNumber": member["Access Card Number"], + "CardFormat": "A901146A-241", + "PinRequired": "0", + "ExtendedAccess": "0", + "ExpiryDate": "", + "Email": member["Email"], + "Phone": member["Phone"]} if doorAuth: memberLevel = [v for k, v in memberLevels.items() if member[k] == k] @@ -75,15 +85,18 @@ def makeMember(member, doorAuth): return out def doRequest(ip, params=None, files=None): + """Send a request to the door control import script""" r = requests.post( 'https://' + ip + '/cgi-bin/import.cgi', params=params, files=files, auth=requests.auth.HTTPDigestAuth(DOOR_USERNAME, DOOR_PASSWORD), - verify=False) + verify=False) # ignore insecure SSL print(r.text) def updateDoor(doorIP, csv): + """Do the update import procedure on a door control""" + doRequest(doorIP, {"task": "importInit"}) doRequest(doorIP, {"task": "importCardsPeople", "name": "cardspeopleschedule.csv"}, @@ -91,6 +104,7 @@ def updateDoor(doorIP, csv): doRequest(doorIP, {"task": "importDone"}) def makeDoor(doorName, doorIPs, members): + """Create a CSV for the given door""" outString = StringIO() writer = csv.DictWriter(outString, fieldnames) writer.writeheader()