forked from CMS/memberPlumbing
Move various functionality from doorUpdater to DoorController
This commit is contained in:
parent
5401e8b185
commit
4d38ac5840
@ -178,48 +178,14 @@ class DoorMember(Member):
|
||||
"custom2": self.membershipWorksID,
|
||||
}
|
||||
|
||||
def make_schedules(self, schedulesMap):
|
||||
roles = [
|
||||
E.Role(
|
||||
{
|
||||
"roleID": self.cardholderID,
|
||||
"scheduleID": schedulesMap[schedule],
|
||||
"resourceID": "0",
|
||||
}
|
||||
)
|
||||
for schedule in self.schedules
|
||||
]
|
||||
|
||||
return E.RoleSet(
|
||||
{"action": "UD", "roleSetID": self.cardholderID}, E.Roles(*roles)
|
||||
)
|
||||
|
||||
def make_credentials(self, newCredentials, cardFormats):
|
||||
out = [
|
||||
E.Credential(
|
||||
{
|
||||
"formatName": str(credential.code[0]),
|
||||
"cardNumber": str(credential.code[1]),
|
||||
"formatID": cardFormats[str(credential.code[0])],
|
||||
"isCard": "true",
|
||||
"cardholderID": self.cardholderID,
|
||||
}
|
||||
)
|
||||
for credential in newCredentials
|
||||
]
|
||||
|
||||
return E.Credentials({"action": "AD"}, *out)
|
||||
|
||||
|
||||
def update_door(door, members):
|
||||
cardFormats = door.get_cardFormats()
|
||||
cardholders = {
|
||||
member.membershipWorksID: member
|
||||
for member in [
|
||||
DoorMember.from_cardholder(ch, door) for ch in door.get_cardholders()
|
||||
]
|
||||
}
|
||||
schedulesMap = door.get_scheduleMap()
|
||||
allCredentials = set(
|
||||
Credential(hex=c.attrib["rawCardNumber"]) for c in door.get_credentials()
|
||||
)
|
||||
@ -231,9 +197,7 @@ def update_door(door, members):
|
||||
if member.membershipWorksID not in cardholders:
|
||||
print("- Adding Member {member.forename} {member.surname}:")
|
||||
print(f" - {member.attribs()}")
|
||||
resp = door.doXMLRequest(
|
||||
ROOT(E.Cardholders({"action": "AD"}, E.Cardholder(member.attribs())))
|
||||
)
|
||||
resp = door.add_cardholder(member.attribs)
|
||||
member.cardholderID = resp.find("{*}Cardholders/{*}Cardholder").attrib[
|
||||
"cardholderID"
|
||||
]
|
||||
@ -252,14 +216,7 @@ def update_door(door, members):
|
||||
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()),
|
||||
)
|
||||
)
|
||||
)
|
||||
door.update_cardholder(member.cardholderID, member.attribs)
|
||||
|
||||
if member.credentials != ch.credentials:
|
||||
print(f"- Updating card for {member.forename} {member.surname}")
|
||||
@ -277,18 +234,7 @@ def update_door(door, members):
|
||||
|
||||
# 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": ""}),
|
||||
)
|
||||
)
|
||||
)
|
||||
door.assign_credential(card, None)
|
||||
|
||||
if newCards - oldCards: # cards added
|
||||
for card in newCards & allNewCards: # new card exists in another member
|
||||
@ -304,28 +250,11 @@ def update_door(door, members):
|
||||
|
||||
# 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}),
|
||||
)
|
||||
)
|
||||
)
|
||||
door.assign_credential(card, member.cardholderID)
|
||||
|
||||
# cards that never existed, and need to be created
|
||||
if newCards - allCredentials:
|
||||
door.doXMLRequest(
|
||||
ROOT(
|
||||
member.make_credentials(
|
||||
newCards - allCredentials, cardFormats
|
||||
)
|
||||
)
|
||||
)
|
||||
door.add_credentials(newCards - allCredentials, member.cardholderID)
|
||||
|
||||
if member.schedules != ch.schedules:
|
||||
print(
|
||||
@ -333,7 +262,7 @@ def update_door(door, members):
|
||||
+ f" {member.forename} {member.surname}:"
|
||||
+ f" {ch.schedules} -> {member.schedules}"
|
||||
)
|
||||
door.doXMLRequest(ROOT(member.make_schedules(schedulesMap)))
|
||||
door.set_cardholder_schedules(member.cardholderID, member.schedules)
|
||||
|
||||
# TODO: delete cardholders that are no longer members?
|
||||
|
||||
|
@ -40,6 +40,19 @@ class DoorController:
|
||||
self.name = name
|
||||
self.access = access
|
||||
|
||||
# lazy evaluated, hopefully won't change for the lifetime of this object
|
||||
@property
|
||||
def cardFormats(self):
|
||||
if not self._cardFormats:
|
||||
self._cardFormats = self.get_cardFormats()
|
||||
return self._cardFormats
|
||||
|
||||
@property
|
||||
def schedulesMap(self):
|
||||
if not self._schedulesMap:
|
||||
self._schedulesMap = self.get_schedulesMap()
|
||||
return self._schedulesMap
|
||||
|
||||
def doImport(self, params=None, files=None):
|
||||
"""Send a request to the door control import script"""
|
||||
r = requests.post(
|
||||
@ -131,6 +144,24 @@ class DoorController:
|
||||
# load new schedules
|
||||
self.doXMLRequest(schedules)
|
||||
|
||||
def set_cardholder_schedules(self, cardholderID, schedules):
|
||||
roles = [
|
||||
E.Role(
|
||||
{
|
||||
"roleID": cardholderID,
|
||||
"scheduleID": self.schedulesMap[schedule],
|
||||
"resourceID": "0",
|
||||
}
|
||||
)
|
||||
for schedule in schedules
|
||||
]
|
||||
|
||||
roleSet = E.RoleSet(
|
||||
{"action": "UD", "roleSetID": cardholderID}, E.Roles(*roles)
|
||||
)
|
||||
|
||||
return self.doXMLRequest(ROOT(roleSet))
|
||||
|
||||
def get_cardFormats(self):
|
||||
cardFormats = self.doXMLRequest(
|
||||
ROOT(E.CardFormats({"action": "LR", "responseFormat": "expanded"}))
|
||||
@ -192,9 +223,60 @@ class DoorController:
|
||||
def get_cardholders(self):
|
||||
return self.get_records(E.Cardholders, 1000, {"responseFormat": "expanded"})
|
||||
|
||||
def add_cardholder(self, attribs):
|
||||
return self.doXMLRequest(
|
||||
ROOT(E.Cardholders({"action": "AD"}, E.Cardholder(attribs)))
|
||||
)
|
||||
|
||||
def update_cardholder(self, cardholderID, attribs):
|
||||
return self.doXMLRequest(
|
||||
ROOT(
|
||||
E.Cardholders(
|
||||
{"action": "UD", "cardholderID": cardholderID},
|
||||
E.CardHolder(attribs),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
def get_credentials(self):
|
||||
return self.get_records(E.Credentials, 1000)
|
||||
|
||||
def add_credentials(self, credentials, cardholderID=None):
|
||||
"""Create new Credentials. If a cardholderID is provided, assign the
|
||||
new credentials to that cardholder"""
|
||||
creds = [
|
||||
E.Credential(
|
||||
{
|
||||
"formatName": str(credential.code[0]),
|
||||
"cardNumber": str(credential.code[1]),
|
||||
"formatID": self.cardFormats[str(credential.code[0])],
|
||||
"isCard": "true",
|
||||
**({"cardholderID": cardholderID} if cardholderID else {}),
|
||||
}
|
||||
)
|
||||
for credential in credentials
|
||||
]
|
||||
|
||||
return self.doXMLRequest(ROOT(E.Credentials({"action": "AD"}, *creds)))
|
||||
|
||||
def assign_credential(self, credential, cardholderID=None):
|
||||
# empty string removes assignment
|
||||
if cardholderID is None:
|
||||
cardholderID = ""
|
||||
|
||||
return self.doXMLRequest(
|
||||
ROOT(
|
||||
E.Credentials(
|
||||
{
|
||||
"action": "UD",
|
||||
"rawCardNumber": credential.hex,
|
||||
"isCard": "true",
|
||||
},
|
||||
E.Credential({"cardholderID": cardholderID}),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
def get_events(self, threshold):
|
||||
def event_newer_than_threshold(event):
|
||||
return datetime.fromisoformat(event.attrib["timestamp"]) > threshold
|
||||
|
Loading…
Reference in New Issue
Block a user