Convert to lxml instead of xml.etree

This commit is contained in:
Adam Goldsmith 2018-08-16 12:52:25 -04:00
parent 48333d1e6d
commit 7ae175baf0
3 changed files with 43 additions and 43 deletions

View File

@ -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:
config = json.load(
open(os.path.dirname(os.path.abspath(__file__)) + "/config.json")) open(os.path.dirname(os.path.abspath(__file__)) + "/config.json"))
except NameError:
ET.register_namespace("hid", "http://www.hidglobal.com/VertX") config = json.load(open("config.json"))
ET.register_namespace("hid", "http://www.hidcorp.com/VertX")
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

View File

@ -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():

View File

@ -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, ET.tostring(eventsXMLIn)) eventsXMLOut = doXMLRequest(doorIP, 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)