-
Notifications
You must be signed in to change notification settings - Fork 7
/
utils.py
165 lines (126 loc) · 5.24 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
"""
Utils for dump2polarion.
"""
import datetime
import logging
import os
import random
import re
import string
from collections import OrderedDict
import requests
import urllib3
from lxml import etree
from polarion_tools_common import utils
from dump2polarion.exceptions import Dump2PolarionException
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# pylint: disable=invalid-name
logger = logging.getLogger(__name__)
NO_BLANKS_PARSER = etree.XMLParser(remove_blank_text=True)
# from https://stackoverflow.com/a/25920392
VALID_XML_RE = re.compile("[^\u0020-\uD7FF\u0009\u000A\u000D\uE000-\uFFFD\U00010000-\U0010FFFF]+")
def get_unicode_str(obj):
"""Makes sure obj is a valid XML unicode string."""
return VALID_XML_RE.sub("", utils.get_unicode_str(obj))
def init_log(log_level):
"""Initializes logging."""
log_level = log_level or "INFO"
logging.basicConfig(
format="%(name)s:%(levelname)s:%(message)s",
level=getattr(logging, log_level.upper(), logging.INFO),
)
def _get_filename(output_loc=None, filename=None):
filename = filename or "output-{:%Y%m%d%H%M%S}-{}.xml".format(
datetime.datetime.now(), "".join(random.sample(string.ascii_lowercase, 5))
)
if output_loc:
filename_fin = os.path.expanduser(output_loc)
if os.path.isdir(filename_fin):
filename_fin = os.path.join(filename_fin, filename)
else:
filename_fin = filename
return filename_fin
def write_xml(xml_str, output_loc=None, filename=None):
"""Outputs the XML content (string) into a file.
If `output_loc` is supplied and it's a file (not directory), the output
will be saved there and the `filename` is ignored.
Args:
xml_str: string with XML document
output_loc: file or directory for saving the file
filename: file name that will be used if `output_loc` is directory
If it is needed and is not supplied, it will be generated
"""
if not xml_str:
raise Dump2PolarionException("No data to write.")
filename_fin = _get_filename(output_loc=output_loc, filename=filename)
with open(filename_fin, "w", encoding="utf-8") as xml_file:
xml_file.write(get_unicode_str(xml_str))
logger.info("Data written to '%s'", filename_fin)
def write_xml_root(xml_root, output_loc=None, filename=None):
"""Outputs the XML content (from XML element) into a file.
If `output_loc` is supplied and it's a file (not directory), the output
will be saved there and the `filename` is ignored.
Args:
xml_root: root element ot the XML document
output_loc: file or directory for saving the file
filename: file name that will be used if `output_loc` is directory
If it is needed and is not supplied, it will be generated
"""
if xml_root is None:
raise Dump2PolarionException("No data to write.")
filename_fin = _get_filename(output_loc=output_loc, filename=filename)
et = etree.ElementTree(xml_root)
et.write(filename_fin, xml_declaration=True, pretty_print=True, encoding="utf-8")
logger.info("Data written to '%s'", filename_fin)
def get_xml_root(xml_file):
"""Returns XML root."""
try:
xml_root = etree.parse(os.path.expanduser(xml_file), NO_BLANKS_PARSER).getroot()
# pylint: disable=broad-except
except Exception as err:
raise Dump2PolarionException("Failed to parse XML file '{}': {}".format(xml_file, err))
return xml_root
def get_xml_root_from_str(xml_str):
"""Returns XML root from string."""
try:
xml_root = etree.fromstring(xml_str.encode("utf-8"), NO_BLANKS_PARSER)
# pylint: disable=broad-except
except Exception as err:
raise Dump2PolarionException("Failed to parse XML string: {}".format(err))
return xml_root
def etree_to_string(xml_root):
"""Returns string representation of element tree."""
return get_unicode_str(etree.tostring(xml_root, encoding="utf-8"))
def prettify_xml(xml_root):
"""Returns pretty-printed string representation of element tree."""
xml_string = etree.tostring(xml_root, encoding="utf-8", xml_declaration=True, pretty_print=True)
return get_unicode_str(xml_string)
def get_session(credentials, config):
"""Gets requests session."""
session = requests.Session()
session.verify = False
auth_url = config.get("auth_url")
if auth_url:
cookie = session.post(
auth_url,
data={
"j_username": credentials[0],
"j_password": credentials[1],
"submit": "Log In",
"rememberme": "true",
},
headers={"Content-Type": "application/x-www-form-urlencoded"},
)
if not cookie:
raise Dump2PolarionException("Cookie was not retrieved from {}.".format(auth_url))
else:
# TODO: can be removed once basic auth is discontinued on prod
session.auth = credentials
return session
def get_testrun_id_config(config):
"""Gets testrun ID defined in config file."""
config_testrun_id = config.get("xunit_import_properties") or {}
return config_testrun_id.get("polarion-testrun-id")
def sorted_dict(dictionary):
"""Returns sorted dictionary."""
return OrderedDict(sorted(dictionary.items()))