import xml.etree.ElementTree as ET import re import base64 import sys class XMLQuery: def __init__(self, xml = None): self._format = 'xml' self._layout = '' self._parameter = {} if xml: self._parse_xml(xml) def _parse_xml(self, xml): self._tree = ET.fromstring(xml) layout_b64 = self._tree.find('layout').text self._layout = base64.b64decode(layout_b64).decode('utf-8') self._format = self._tree.find('format').get('type') self._parameter = {} for p in self._tree.findall('parameters/parameter'): self._parameter[p.get('name')] = p.text def execute(self, url, user, password): # curl -X POST --basic -u schilli:chili03 --data @tms_activity_interval.xml https://tmsxd104.ecbt1.tadnet.net:9443/report/ import requests from requests.auth import HTTPBasicAuth data = str(self) basic = HTTPBasicAuth(user, password) response = requests.post(url, data=data, auth=basic, verify=False) if response.status_code == 200: response.encoding = "utf-8" return response.text else: return None def describe(self, url, user, password): orig_format = self.format self.format = 'xml' ret = self.execute(url, user, password) m = re.match('^.*?\.*?\<\/PlainRow\>', ret, re.DOTALL) s = m[0] + '\n' tree = ET.fromstring(s) ret = [] row = tree.find('PlainRow') for c in row.findall('Column'): #name = c.get('name') name = c.text type = c.get('type') if type == 'unknown': type = 'integer' ret.append((name, type)) return ret def describe_simple(url, user, password, xml): query = XMLQuery(xml) query.format='xml' ret = query.execute(url = url, user = user, password = password) tree = ET.fromstring(ret) ret = [] row = tree.find('PlainRow') for c in row.findall('Column'): #name = c.get('name') name = c.text type = c.get('type') if type == 'unknown': type = 'integer' ret.append((name, type)) return ret def normalize_output(self, date_format = 'dd/MM/yyyy', time_format = 'HH:mm:ss'): lines = self.layout.splitlines() lines = [re.sub(r'^date_format\s*=.*', 'date_format=' + date_format, l) for l in lines] lines = [re.sub(r'^time_format\s*=.*', 'time_format=' + time_format, l) for l in lines] lines = [re.sub(r'^NoNumberFormatting\s*=.*', 'NoNumberFormatting=1', l) for l in lines] self.layout = '\n'.join(lines) def __setattr__(self, name, value): if name == 'format' and value not in ('bin','xml','xml3','html','txt','csv','standard_csv', 'scsv', 'pdf'): raise Exception("Invalid report format '" + value + "'") if not name.startswith('_'): name = '_' + name if name == '_layout' and not value.endswith('\n'): value = value + '\n' if name == '_xml': self._parse_xml(value) return try: self.__dict__[name] = value except KeyError: raise AttributeError def __getattr__(self, name): if not name.startswith('_'): name = '_' + name try: return self.__dict__[name] except KeyError: raise AttributeError(name) def __str__(self): parameters = '' for k in self._parameter: parameters = parameters + "\n%s" % (k, self._parameter[k]) layout_b64 = base64.b64encode(self.layout.encode('utf-8')).decode('utf-8') return ('\n' + \ '\n' + \ ' \n' + \ ' \n%s\n' + \ ' %s\n' + \ '') % (self._format, layout_b64, parameters) if __name__ == "__main__": file = sys.argv[1] print(file) with open(file) as f: xml = f.read() query = XMLQuery(xml) print(query.layout) query.normalize_output() print(query.layout) #query.format='xml' #ret = query.execute(url = 'https://tmsxd104.ecbt1.tadnet.net:9443/report/', user = 'schilli', password = 'chili03') #print(ret) desc = XMLQuery.describe_simple(url = 'https://tmsxd104.ecbt1.tadnet.net:9443/report/', user = 'schilli', password = 'chili03', xml = xml) print(str(desc))