forked from CMS/memberPlumbing
Convert to lxml instead of xml.etree
This commit is contained in:
parent
48333d1e6d
commit
7ae175baf0
26
common.py
26
common.py
@ -4,19 +4,24 @@ import urllib3
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from xml.etree import ElementTree as ET
|
from lxml import etree
|
||||||
|
from lxml.builder import ElementMaker
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from passwords import *
|
from passwords import *
|
||||||
|
|
||||||
|
E_plain = ElementMaker(nsmap={"hid": "http://www.hidglobal.com/VertX"})
|
||||||
|
E = ElementMaker(namespace="http://www.hidglobal.com/VertX",
|
||||||
|
nsmap={"hid": "http://www.hidglobal.com/VertX"})
|
||||||
|
|
||||||
# it's fine, ssl certs are for losers anyway
|
# it's fine, ssl certs are for losers anyway
|
||||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
config = json.load(
|
try:
|
||||||
open(os.path.dirname(os.path.abspath(__file__)) + "/config.json"))
|
config = json.load(
|
||||||
|
open(os.path.dirname(os.path.abspath(__file__)) + "/config.json"))
|
||||||
ET.register_namespace("hid", "http://www.hidglobal.com/VertX")
|
except NameError:
|
||||||
ET.register_namespace("hid", "http://www.hidcorp.com/VertX")
|
config = json.load(open("config.json"))
|
||||||
|
|
||||||
fieldnames = "CardNumber,CardFormat,PinRequired,PinCode,ExtendedAccess,ExpiryDate,Forename,Initial,Surname,Email,Phone,Custom1,Custom2,Schedule1,Schedule2,Schedule3,Schedule4,Schedule5,Schedule6,Schedule7,Schedule8".split(",")
|
fieldnames = "CardNumber,CardFormat,PinRequired,PinCode,ExtendedAccess,ExpiryDate,Forename,Initial,Surname,Email,Phone,Custom1,Custom2,Schedule1,Schedule2,Schedule3,Schedule4,Schedule5,Schedule6,Schedule7,Schedule8".split(",")
|
||||||
|
|
||||||
@ -78,7 +83,7 @@ def doImportRequest(ip, params=None, files=None):
|
|||||||
auth=requests.auth.HTTPDigestAuth(DOOR_USERNAME, DOOR_PASSWORD),
|
auth=requests.auth.HTTPDigestAuth(DOOR_USERNAME, DOOR_PASSWORD),
|
||||||
timeout=60,
|
timeout=60,
|
||||||
verify=False) # ignore insecure SSL
|
verify=False) # ignore insecure SSL
|
||||||
xml = ET.XML(r.text)
|
xml = etree.XML(r.content)
|
||||||
if r.status_code != 200 \
|
if r.status_code != 200 \
|
||||||
or len(xml.findall("{http://www.hidglobal.com/VertX}Error")) > 0:
|
or len(xml.findall("{http://www.hidglobal.com/VertX}Error")) > 0:
|
||||||
print("Door Updating Error: ", r.status_code, r.reason)
|
print("Door Updating Error: ", r.status_code, r.reason)
|
||||||
@ -94,16 +99,17 @@ def doCSVImport(doorIP, csv):
|
|||||||
doImportRequest(doorIP, {"task": "importDone"})
|
doImportRequest(doorIP, {"task": "importDone"})
|
||||||
|
|
||||||
def doXMLRequest(doorIP, xml, prefix=b'<?xml version="1.0" encoding="UTF-8"?>'):
|
def doXMLRequest(doorIP, xml, prefix=b'<?xml version="1.0" encoding="UTF-8"?>'):
|
||||||
|
if not isinstance(xml, str): xml = etree.tostring(xml)
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
'https://' + doorIP + '/cgi-bin/vertx_xml.cgi',
|
'https://' + doorIP + '/cgi-bin/vertx_xml.cgi',
|
||||||
params={'XML': prefix + xml},
|
params={'XML': prefix + xml},
|
||||||
auth=requests.auth.HTTPDigestAuth(DOOR_USERNAME, DOOR_PASSWORD),
|
auth=requests.auth.HTTPDigestAuth(DOOR_USERNAME, DOOR_PASSWORD),
|
||||||
verify=False)
|
verify=False)
|
||||||
xml = ET.XML(r.text)
|
resp_xml = etree.XML(r.content)
|
||||||
# probably meed to be more sane about this
|
# probably meed to be more sane about this
|
||||||
if r.status_code != 200 \
|
if r.status_code != 200 \
|
||||||
or len(xml.findall("{http://www.hidglobal.com/VertX}Error")) > 0:
|
or len(resp_xml.findall("{*}Error")) > 0:
|
||||||
print("Door Updating Error: ", r.status_code, r.reason)
|
print("Door Updating Error: ", r.status_code, r.reason)
|
||||||
print(r.text)
|
print(r.text)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
return xml
|
return resp_xml
|
||||||
|
33
doorUtil.py
33
doorUtil.py
@ -1,6 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import requests
|
import requests
|
||||||
from xml.etree import ElementTree as ET
|
|
||||||
import csv
|
import csv
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
|
||||||
@ -27,11 +26,10 @@ def sendSchedule(target_ip):
|
|||||||
doCSVImport(target_ip, outString)
|
doCSVImport(target_ip, outString)
|
||||||
|
|
||||||
# clear all schedules
|
# clear all schedules
|
||||||
delXML = ET.Element("VertXMessage")
|
delXML = E_plain.VertXMessage(
|
||||||
for ii in range(1, 8):
|
*[E.Schedules({"action": "DD", "scheduleID": str(ii)})
|
||||||
ET.SubElement(delXML, "hid:Schedules",
|
for ii in range(1, 8)])
|
||||||
attrib={"action": "DD", "scheduleID": str(ii)})
|
doXMLRequest(target_ip, delXML)
|
||||||
doXMLRequest(target_ip, ET.tostring(delXML))
|
|
||||||
|
|
||||||
# load new schedules
|
# load new schedules
|
||||||
with open("schedules.xml", "rb") as f:
|
with open("schedules.xml", "rb") as f:
|
||||||
@ -41,21 +39,18 @@ def sendCardFormat(targetIP, formatName, templateID, facilityCode):
|
|||||||
# TODO: add delete formats
|
# TODO: add delete formats
|
||||||
# delete example: <hid:CardFormats action="DD" formatID="7-1-244"/>
|
# delete example: <hid:CardFormats action="DD" formatID="7-1-244"/>
|
||||||
|
|
||||||
el = ET.Element("VertXMessage")
|
el = E_plain.VertXMessage(
|
||||||
formats = ET.SubElement(el, "hid:CardFormats", attrib={"action": "AD"})
|
E.CardFormats({"action": "AD"},
|
||||||
fmt = ET.SubElement(formats, "hid:CardFormat",
|
E.CardFormat({"formatName": formatName,
|
||||||
attrib={"formatName": formatName,
|
"templateID": str(templateID)}
|
||||||
"templateID": str(templateID)})
|
E.FixedField({"value": str(facilityCode)}))))
|
||||||
ET.SubElement(fmt, "hid:FixedField",
|
return doXMLRequest(targetIP, el)
|
||||||
attrib={"value": str(facilityCode)})
|
|
||||||
return doXMLRequest(targetIP, ET.tostring(el))
|
|
||||||
|
|
||||||
def lockOrUnlockDoor(targetIP, lock=True):
|
def lockOrUnlockDoor(targetIP, lock=True):
|
||||||
el = ET.Element("VertXMessage")
|
el = E_plain.VertXMessage(
|
||||||
ET.SubElement(el, "hid:Doors",
|
E.Doors({"action": "CM",
|
||||||
attrib={"action": "CM",
|
"command": "lockDoor" if lock else "unlockDoor"}))
|
||||||
"command": "lockDoor" if lock else "unlockDoor"})
|
return doXMLRequest(targetIP, el)
|
||||||
return doXMLRequest(targetIP, ET.tostring(el))
|
|
||||||
|
|
||||||
def forEachDoor(fxn):
|
def forEachDoor(fxn):
|
||||||
for doorName, doorData in config["doors"].items():
|
for doorName, doorData in config["doors"].items():
|
||||||
|
27
events.py
27
events.py
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from xml.etree import ElementTree as ET
|
from lxml import etree
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import requests
|
import requests
|
||||||
@ -20,14 +20,14 @@ def getStrings(targetIP):
|
|||||||
def getMessages(doorName, doorIP):
|
def getMessages(doorName, doorIP):
|
||||||
# get parameters for messages to get?
|
# get parameters for messages to get?
|
||||||
# honestly not really sure why this is required, their API is confusing
|
# honestly not really sure why this is required, their API is confusing
|
||||||
parXMLIn = ET.Element("VertXMessage")
|
parXMLIn = E_plain.VertXMessage(
|
||||||
ET.SubElement(parXMLIn, "hid:EventMessages", attrib={"action": "LR"})
|
E.EventMessages({"action": "LR"}))
|
||||||
parXMLOut = doXMLRequest(doorIP, ET.tostring(parXMLIn))
|
parXMLOut = doXMLRequest(doorIP, parXMLIn)
|
||||||
ET.dump(parXMLOut)
|
etree.dump(parXMLOut)
|
||||||
|
|
||||||
if os.path.exists("logs/" + doorName + ".xml"):
|
if os.path.exists("logs/" + doorName + ".xml"):
|
||||||
# read last log
|
# read last log
|
||||||
tree = ET.ElementTree(None, "logs/" + doorName + ".xml")
|
tree = etree.ElementTree(file="logs/" + doorName + ".xml")
|
||||||
root = tree.getroot()
|
root = tree.getroot()
|
||||||
recordCount = int(parXMLOut[0].attrib["historyRecordMarker"]) - \
|
recordCount = int(parXMLOut[0].attrib["historyRecordMarker"]) - \
|
||||||
int(root[0][0].attrib["recordMarker"])
|
int(root[0][0].attrib["recordMarker"])
|
||||||
@ -41,20 +41,19 @@ def getMessages(doorName, doorIP):
|
|||||||
return
|
return
|
||||||
print("Getting", recordCount, "records")
|
print("Getting", recordCount, "records")
|
||||||
# get the actual messages
|
# get the actual messages
|
||||||
eventsXMLIn = ET.Element("VertXMessage")
|
eventsXMLIn = E_plain.VertXMessage(
|
||||||
ET.SubElement(eventsXMLIn, "hid:EventMessages",
|
E.EventMessages({"action": "LR",
|
||||||
attrib={"action": "LR",
|
"recordCount": str(recordCount),
|
||||||
"recordCount": str(recordCount),
|
"historyRecordMarker": parXMLOut[0].attrib["historyRecordMarker"],
|
||||||
"historyRecordMarker": parXMLOut[0].attrib["historyRecordMarker"],
|
"historyTimestamp": parXMLOut[0].attrib["historyTimestamp"]}))
|
||||||
"historyTimestamp": parXMLOut[0].attrib["historyTimestamp"]})
|
eventsXMLOut = doXMLRequest(doorIP, eventsXMLIn)
|
||||||
eventsXMLOut = doXMLRequest(doorIP, ET.tostring(eventsXMLIn))
|
|
||||||
#TODO: handle modeRecords=true
|
#TODO: handle modeRecords=true
|
||||||
|
|
||||||
for index, event in enumerate(eventsXMLOut[0]):
|
for index, event in enumerate(eventsXMLOut[0]):
|
||||||
event.attrib["recordMarker"] = str(int(parXMLOut[0].attrib["historyRecordMarker"]) - index)
|
event.attrib["recordMarker"] = str(int(parXMLOut[0].attrib["historyRecordMarker"]) - index)
|
||||||
|
|
||||||
if root is None:
|
if root is None:
|
||||||
tree = ET.ElementTree(eventsXMLOut)
|
tree = etree.ElementTree(eventsXMLOut)
|
||||||
else:
|
else:
|
||||||
for event in reversed(eventsXMLOut[0]):
|
for event in reversed(eventsXMLOut[0]):
|
||||||
root[0].insert(0, event)
|
root[0].insert(0, event)
|
||||||
|
Loading…
Reference in New Issue
Block a user