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,
|
"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):
|
def update_door(door, members):
|
||||||
cardFormats = door.get_cardFormats()
|
|
||||||
cardholders = {
|
cardholders = {
|
||||||
member.membershipWorksID: member
|
member.membershipWorksID: member
|
||||||
for member in [
|
for member in [
|
||||||
DoorMember.from_cardholder(ch, door) for ch in door.get_cardholders()
|
DoorMember.from_cardholder(ch, door) for ch in door.get_cardholders()
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
schedulesMap = door.get_scheduleMap()
|
|
||||||
allCredentials = set(
|
allCredentials = set(
|
||||||
Credential(hex=c.attrib["rawCardNumber"]) for c in door.get_credentials()
|
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:
|
if member.membershipWorksID not in cardholders:
|
||||||
print("- Adding Member {member.forename} {member.surname}:")
|
print("- Adding Member {member.forename} {member.surname}:")
|
||||||
print(f" - {member.attribs()}")
|
print(f" - {member.attribs()}")
|
||||||
resp = door.doXMLRequest(
|
resp = door.add_cardholder(member.attribs)
|
||||||
ROOT(E.Cardholders({"action": "AD"}, E.Cardholder(member.attribs())))
|
|
||||||
)
|
|
||||||
member.cardholderID = resp.find("{*}Cardholders/{*}Cardholder").attrib[
|
member.cardholderID = resp.find("{*}Cardholders/{*}Cardholder").attrib[
|
||||||
"cardholderID"
|
"cardholderID"
|
||||||
]
|
]
|
||||||
@ -252,14 +216,7 @@ def update_door(door, members):
|
|||||||
print(f"- Updating profile for {member.forename} {member.surname}")
|
print(f"- Updating profile for {member.forename} {member.surname}")
|
||||||
print(f" - Old: {ch.attribs()}")
|
print(f" - Old: {ch.attribs()}")
|
||||||
print(f" - New: {member.attribs()}")
|
print(f" - New: {member.attribs()}")
|
||||||
door.doXMLRequest(
|
door.update_cardholder(member.cardholderID, member.attribs)
|
||||||
ROOT(
|
|
||||||
E.Cardholders(
|
|
||||||
{"action": "UD", "cardholderID": member.cardholderID},
|
|
||||||
E.CardHolder(member.attribs()),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if member.credentials != ch.credentials:
|
if member.credentials != ch.credentials:
|
||||||
print(f"- Updating card for {member.forename} {member.surname}")
|
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
|
# cards removed, and won't be reassigned to someone else
|
||||||
for card in (oldCards - newCards) - allNewCards:
|
for card in (oldCards - newCards) - allNewCards:
|
||||||
door.doXMLRequest(
|
door.assign_credential(card, None)
|
||||||
ROOT(
|
|
||||||
E.Credentials(
|
|
||||||
{
|
|
||||||
"action": "UD",
|
|
||||||
"rawCardNumber": card.hex,
|
|
||||||
"isCard": "true",
|
|
||||||
},
|
|
||||||
E.Credential({"cardholderID": ""}),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if newCards - oldCards: # cards added
|
if newCards - oldCards: # cards added
|
||||||
for card in newCards & allNewCards: # new card exists in another member
|
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
|
# card existed in door, and needs to be reassigned
|
||||||
for card in newCards & allCredentials:
|
for card in newCards & allCredentials:
|
||||||
door.doXMLRequest(
|
door.assign_credential(card, member.cardholderID)
|
||||||
ROOT(
|
|
||||||
E.Credentials(
|
|
||||||
{
|
|
||||||
"action": "UD",
|
|
||||||
"rawCardNumber": card.hex,
|
|
||||||
"isCard": "true",
|
|
||||||
},
|
|
||||||
E.Credential({"cardholderID": member.cardholderID}),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# cards that never existed, and need to be created
|
# cards that never existed, and need to be created
|
||||||
if newCards - allCredentials:
|
if newCards - allCredentials:
|
||||||
door.doXMLRequest(
|
door.add_credentials(newCards - allCredentials, member.cardholderID)
|
||||||
ROOT(
|
|
||||||
member.make_credentials(
|
|
||||||
newCards - allCredentials, cardFormats
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if member.schedules != ch.schedules:
|
if member.schedules != ch.schedules:
|
||||||
print(
|
print(
|
||||||
@ -333,7 +262,7 @@ def update_door(door, members):
|
|||||||
+ f" {member.forename} {member.surname}:"
|
+ f" {member.forename} {member.surname}:"
|
||||||
+ f" {ch.schedules} -> {member.schedules}"
|
+ 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?
|
# TODO: delete cardholders that are no longer members?
|
||||||
|
|
||||||
|
@ -40,6 +40,19 @@ class DoorController:
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.access = access
|
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):
|
def doImport(self, params=None, files=None):
|
||||||
"""Send a request to the door control import script"""
|
"""Send a request to the door control import script"""
|
||||||
r = requests.post(
|
r = requests.post(
|
||||||
@ -131,6 +144,24 @@ class DoorController:
|
|||||||
# load new schedules
|
# load new schedules
|
||||||
self.doXMLRequest(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):
|
def get_cardFormats(self):
|
||||||
cardFormats = self.doXMLRequest(
|
cardFormats = self.doXMLRequest(
|
||||||
ROOT(E.CardFormats({"action": "LR", "responseFormat": "expanded"}))
|
ROOT(E.CardFormats({"action": "LR", "responseFormat": "expanded"}))
|
||||||
@ -192,9 +223,60 @@ class DoorController:
|
|||||||
def get_cardholders(self):
|
def get_cardholders(self):
|
||||||
return self.get_records(E.Cardholders, 1000, {"responseFormat": "expanded"})
|
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):
|
def get_credentials(self):
|
||||||
return self.get_records(E.Credentials, 1000)
|
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 get_events(self, threshold):
|
||||||
def event_newer_than_threshold(event):
|
def event_newer_than_threshold(event):
|
||||||
return datetime.fromisoformat(event.attrib["timestamp"]) > threshold
|
return datetime.fromisoformat(event.attrib["timestamp"]) > threshold
|
||||||
|
Loading…
Reference in New Issue
Block a user