import csv import json import urllib3 import os import sys from io import StringIO from lxml import etree from lxml.builder import ElementMaker import requests 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 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) try: config = json.load( open(os.path.dirname(os.path.abspath(__file__)) + "/config.json")) except NameError: 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(",") def getMembershipworksData(folders, columns): """ Pull the members csv from the membershipworks api folders: a list of the names of the folders to get (see folder_map in this function for mapping to ids) columns: which columns to get""" BASE_URL = "https://api.membershipworks.com/v1/" folder_map = {'members': '5ae37979f033bfe8534f8799', 'staff': '5771675edcdf126302a2f6b9', 'misc': '5b69ee9bf033bf8e7346c434'} # login r = requests.post(BASE_URL + 'usr', data={"_st": "all", "eml": MEMBERSHIPWORKS_USERNAME, "org": "10000", "pwd": MEMBERSHIPWORKS_PASSWORD}) if r.status_code != 200 or 'SF' not in r.json(): print("MembershipWorks Login Error: ", r.status_code, r.reason) print(r.text) sys.exit(1) login_data = r.json() # get list of member/staff IDs r = requests.get(BASE_URL + "ylp", params={"SF": login_data['SF'], "lbl": ",".join([folder_map[f] for f in folders]), "org": login_data['org'], "var": "_id,nam,ctc"}) if r.status_code != 200 or 'usr' not in r.json(): print("MembershipWorks User Listing Error: ", r.status_code, r.reason) print(r.text) sys.exit(1) ids = [user['uid'] for user in r.json()['usr']] # get members CSV # TODO: maybe can just use previous get instead? would return JSON r = requests.post(BASE_URL + "csv", params={"SF": login_data['SF']}, data={"_rt": "946702800", # unknown "mux": "", # unknown "tid": ",".join(ids), # ids of members to get "var": columns}) if r.status_code != 200: print("MembershipWorks CSV Generation Error: ", r.status_code, r.reason) print(r.text) sys.exit(1) return list(csv.DictReader(StringIO(r.text))) def doImportRequest(ip, params=None, files=None): """Send a request to the door control import script""" r = requests.post( 'https://' + ip + '/cgi-bin/import.cgi', params=params, files=files, auth=requests.auth.HTTPDigestAuth(DOOR_USERNAME, DOOR_PASSWORD), timeout=60, verify=False) # ignore insecure SSL xml = etree.XML(r.content) if r.status_code != 200 \ or len(xml.findall("{http://www.hidglobal.com/VertX}Error")) > 0: print("Door Updating Error: ", r.status_code, r.reason) print(r.text) sys.exit(1) def doCSVImport(doorIP, csv): """Do the CSV import procedure on a door control""" doImportRequest(doorIP, {"task": "importInit"}) doImportRequest(doorIP, {"task": "importCardsPeople", "name": "cardspeopleschedule.csv"}, {"importCardsPeopleButton": ("cardspeopleschedule.csv", csv, 'text/csv')}) doImportRequest(doorIP, {"task": "importDone"}) def doXMLRequest(doorIP, xml, prefix=b''): if not isinstance(xml, str): xml = etree.tostring(xml) r = requests.get( 'https://' + doorIP + '/cgi-bin/vertx_xml.cgi', params={'XML': prefix + xml}, auth=requests.auth.HTTPDigestAuth(DOOR_USERNAME, DOOR_PASSWORD), verify=False) resp_xml = etree.XML(r.content) # probably meed to be more sane about this if r.status_code != 200 \ or len(resp_xml.findall("{*}Error")) > 0: print("Door Updating Error: ", r.status_code, r.reason) print(r.text) sys.exit(1) return resp_xml