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

103 lines
3.4 KiB
Python
Executable File

#!/usr/bin/env python3
import sys
import requests
import csv
from collections import OrderedDict
from io import StringIO
from hashlib import md5
import os
from common import *
from hid.DoorController import fieldnames
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-" + member["Access Card Facility Code"],
"PinRequired": "0",
"ExtendedAccess": "0",
"ExpiryDate": "",
"Email": member["Email"],
"Phone": member["Phone"]}
if member[doorAuth] == "Y" \
and not member["Account on Hold"] == "Account on Hold":
levels = OrderedDict(sorted([(k, v) for k, v in memberLevels.items() if member[k] == k]))
out["Custom1"] = "|".join(levels.keys()).replace("&", "and")
for index, schedule in enumerate(levels.values(), 1):
#TODO: error if people have more than 8?
out["Schedule" + str(index)] = schedule
return out
def makeDoor(door, members, hashes):
"""Create a CSV for the given door"""
outString = StringIO()
writer = csv.DictWriter(outString, fieldnames)
writer.writeheader()
for member in members:
member = makeMember(member, "Access " + door.access + "?")
if member is not None:
writer.writerow(member)
import datetime as DT
timestamp = DT.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
with open("/tmp/" + door.name + timestamp + ".csv", "w") as f:
f.write(outString.getvalue())
outString.seek(0)
doorHash = md5(bytes(outString.getvalue(), 'utf8')).hexdigest()
if doorHash == hashes.get(door.name):
print("Door", door.name, "not changed, not updating")
else:
print("Door", door.name, "changed, trying to update")
hashes[door.name] = doorHash
try:
door.doCSVImport(outString)
except (requests.ReadTimeout, requests.ConnectionError):
print(f"Import failed on door {door.name}, trying to power cycle it")
cycleDoor(door)
# write out hash if we sucessfully updated this door
with open('/tmp/doorUpdaterLastHash', 'w') as f:
json.dump(hashes, f)
def cycleDoor(door):
if door.mac is None:
print(f"Cannot power cycle to door {door.name}, no mac address defined")
return
doorControllerClient = unifiController.get_client(door.mac)
print(doorControllerClient)
unifiController._api_write(
'cmd/devmgr',
{"cmd": "power-cycle",
"mac": doorControllerClient["sw_mac"],
"port_idx": doorControllerClient["sw_port"]})
def main():
members = getMembershipworksData(
['members', 'staff', 'misc'],
"lvl,xws,xms,xsc,xas,xfd,xac,phn,eml,lbl,xcf,nam")
members.sort(key=lambda x: x['Last Name'])
if os.path.exists('/tmp/doorUpdaterLastHash'):
with open('/tmp/doorUpdaterLastHash', 'r') as f:
hashes = json.load(f)
else:
hashes = {}
for door in doors.values():
print(door.name, door.ip)
makeDoor(door, members, hashes)
if __name__ == '__main__':
main()