doorUpdater: Reuse more code/flow between new and existing members

This commit is contained in:
Adam Goldsmith 2020-03-29 00:10:25 -04:00
parent e832851fc4
commit 952852badb

View File

@ -1,5 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import copy
from common import doors, membershipworks, memberLevels, doorSpecificSchedules from common import doors, membershipworks, memberLevels, doorSpecificSchedules
from lib.hid.Credential import Credential from lib.hid.Credential import Credential
from lib.hid.DoorController import ROOT, E from lib.hid.DoorController import ROOT, E
@ -155,76 +157,80 @@ def update_door(door, members):
# TODO: can I combine requests? # TODO: can I combine requests?
for membershipworksMember in members: for membershipworksMember in members:
member = membershipworksMember.to_DoorMember(door) member = membershipworksMember.to_DoorMember(door)
# cardholder exists, compare contents # cardholder did not exist, so add them
if member.membershipWorksID in cardholders: if member.membershipWorksID not in cardholders:
ch = cardholders.pop(member.membershipWorksID) print("- Adding Member {member.forename} {member.surname}:")
member.cardholderID = ch.cardholderID print(f" - {member.attribs()}")
if member.attribs() != ch.attribs(): # update cardholder attributes
print(f"- Updating profile for {member.forename} {member.surname}")
print(f" - Old: {ch.attribs()}")
print(f" - New: {member.attribs()}")
door.doXMLRequest(ROOT(
E.Cardholders(
{"action": "UD", "cardholderID": member.cardholderID},
E.CardHolder(member.attribs()))))
if member.credentials != ch.credentials:
print(f"- Updating card for {member.forename} {member.surname}")
print(f" - {ch.credentials} -> {member.credentials}")
oldCards = ch.credentials
newCards = member.credentials
allNewCards = set(
card for m in members if m != membershipworksMember
for card in m.credentials)
# cards removed, and won't be reassigned to someone else
for card in (oldCards - newCards) - allNewCards:
door.doXMLRequest(ROOT(E.Credentials(
{"action": "UD",
"rawCardNumber": card.hex,
"isCard": "true"},
E.Credential({"cardholderID": ""}))))
if newCards - oldCards: # cards added
for card in newCards & allNewCards: # new card exists in another member
print([m for m in members
for card in m.credentials
if card in newCards])
raise Exception(f"Duplicate Card in input data! {card}")
# card existed in door, and needs to be reassigned
for card in newCards & allCredentials:
door.doXMLRequest(ROOT(E.Credentials(
{"action": "UD",
"rawCardNumber": card.hex,
"isCard": "true"},
E.Credential({"cardholderID": member.cardholderID}))))
# cards that never existed, and need to be created
if newCards - allCredentials:
door.doXMLRequest(ROOT(member.make_credentials(
newCards - allCredentials, cardFormats)))
if member.schedules != ch.schedules:
print("- Updating schedule for" +
f" {member.forename} {member.surname}:" +
f" {ch.schedules} -> {member.schedules}")
door.doXMLRequest(ROOT(
member.make_schedules(schedulesMap)))
else: # cardholder did not exist, so add them
print(f"- Adding Member:")
print(member)
resp = door.doXMLRequest(ROOT( resp = door.doXMLRequest(ROOT(
E.Cardholders( E.Cardholders(
{"action": "AD"}, {"action": "AD"},
E.Cardholder(member.attribs())))) E.Cardholder(member.attribs()))))
member.cardholderID = resp.find('{*}Cardholders/{*}Cardholder') \ member.cardholderID = resp.find('{*}Cardholders/{*}Cardholder') \
.attrib["cardholderID"] .attrib["cardholderID"]
# create a dummy ch to force an update
# TODO: probably a cleaner way to do this
ch = copy.copy(member)
ch.schedules = []
ch.credentials = set()
# cardholder exists, compare contents
else:
ch = cardholders.pop(member.membershipWorksID)
member.cardholderID = ch.cardholderID
if member.attribs() != ch.attribs(): # update cardholder attributes
print(f"- Updating profile for {member.forename} {member.surname}")
print(f" - Old: {ch.attribs()}")
print(f" - New: {member.attribs()}")
door.doXMLRequest(ROOT( door.doXMLRequest(ROOT(
member.make_credentials(member.credentials, cardFormats), E.Cardholders(
member.make_schedules(schedulesMap))) {"action": "UD", "cardholderID": member.cardholderID},
E.CardHolder(member.attribs()))))
if member.credentials != ch.credentials:
print(f"- Updating card for {member.forename} {member.surname}")
print(f" - {ch.credentials} -> {member.credentials}")
oldCards = ch.credentials
newCards = member.credentials
allNewCards = set(
card for m in members if m != membershipworksMember
for card in m.credentials)
# cards removed, and won't be reassigned to someone else
for card in (oldCards - newCards) - allNewCards:
door.doXMLRequest(ROOT(E.Credentials(
{"action": "UD",
"rawCardNumber": card.hex,
"isCard": "true"},
E.Credential({"cardholderID": ""}))))
if newCards - oldCards: # cards added
for card in newCards & allNewCards: # new card exists in another member
print([m for m in members
for card in m.credentials
if card in newCards])
raise Exception(f"Duplicate Card in input data! {card}")
# card existed in door, and needs to be reassigned
for card in newCards & allCredentials:
door.doXMLRequest(ROOT(E.Credentials(
{"action": "UD",
"rawCardNumber": card.hex,
"isCard": "true"},
E.Credential({"cardholderID": member.cardholderID}))))
# cards that never existed, and need to be created
if newCards - allCredentials:
door.doXMLRequest(ROOT(member.make_credentials(
newCards - allCredentials, cardFormats)))
if member.schedules != ch.schedules:
print("- Updating schedule for" +
f" {member.forename} {member.surname}:" +
f" {ch.schedules} -> {member.schedules}")
door.doXMLRequest(ROOT(member.make_schedules(schedulesMap)))
# TODO: delete cardholders that are no longer members? # TODO: delete cardholders that are no longer members?