ab5ef471 by 周伟奇

add GCAP interface

1 parent e5726dfc
...@@ -1004,3 +1004,17 @@ ID_TYPE = ['ITARI', 'ITHKM', 'ITPRC', 'ITPSP', 'ITRES', 'ITTID', 'ITUSC', 'ITCCU ...@@ -1004,3 +1004,17 @@ ID_TYPE = ['ITARI', 'ITHKM', 'ITPRC', 'ITPSP', 'ITRES', 'ITTID', 'ITUSC', 'ITCCU
1004 SECOND_ID_TYPE = ['ITARI', 'ITHKM', 'ITPRC', 'ITPSP', 'ITRES', 'ITTID'] 1004 SECOND_ID_TYPE = ['ITARI', 'ITHKM', 'ITPRC', 'ITPSP', 'ITRES', 'ITTID']
1005 SUB_TYPE = ['CSIBM', 'CSOTH', 'CSSME'] 1005 SUB_TYPE = ['CSIBM', 'CSOTH', 'CSSME']
1006 1006
1007 # GCAP 请求体
1008 BASE_XML_TEXT = """<?xml version="1.0" encoding="utf-8"?>
1009
1010 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="http://guardean.net/webservices/workflow/vatra_bmwservice/types">
1011 <soapenv:Header/>
1012 <soapenv:Body>
1013 <typ:executeRequest>
1014 <request>{0}</request>
1015 </typ:executeRequest>
1016 </soapenv:Body>
1017 </soapenv:Envelope>"""
1018
1019 CDATA_TEXT = """<![CDATA[<Exec xmlns="http://tempuri.org/"><strXMLParm>&lt;Request&gt;&lt;Framework&gt;&lt;UserName&gt;SFCHINA\qqcout0&lt;/UserName&gt;&lt;GUID&gt;70d0efcb-3bc2-4018-ac4e-681c8f3131b6&lt;/GUID&gt;&lt;DetailedTracingEnabled&gt;False&lt;/DetailedTracingEnabled&gt;&lt;ServiceName&gt;AMSWebService&lt;/ServiceName&gt;&lt;SupportsRedirection&gt;true&lt;/SupportsRedirection&gt;&lt;ServiceType&gt;Service&lt;/ServiceType&gt;&lt;/Framework&gt;&lt;Parms&gt;&lt;InputXML type="string"&gt;&amp;lt;?xml version="1.0" encoding="utf-16"?&amp;gt;&amp;lt;InputXML&amp;gt; &amp;lt;Result&amp;gt; {0} &amp;lt;/Result&amp;gt;&amp;lt;AuthorizationData&amp;gt;&amp;lt;ServiceComponent&amp;gt;OCR&amp;lt;/ServiceComponent&amp;gt;&amp;lt;RoleId/&amp;gt;&amp;lt;CompanyId/&amp;gt;&amp;lt;/AuthorizationData&amp;gt;&amp;lt;/InputXML&amp;gt;&lt;/InputXML&gt;&lt;/Parms&gt;&lt;/Request&gt;</strXMLParm></Exec>]]>"""
1020
......
1 import requests
2 from requests.auth import HTTPBasicAuth
3 from settings import conf
4 from common.tools.dict_to_xml import dicttoxml, escape_xml
5 from apps.doc import consts
6
7
8 class GCAP:
9
10 def __init__(self):
11 self.url = conf.GCAP_URL
12 self.headers = {
13 'Content-Type': 'text/plain',
14 }
15 self.auth = HTTPBasicAuth(conf.GCAP_AUTH_USER, conf.GCAP_AUTH_PWD)
16
17 @staticmethod
18 def dict_to_xml(comparison_res):
19 comparison_xml = dicttoxml(comparison_res, root=False, attr_type=False)
20 return consts.BASE_XML_TEXT.format(consts.CDATA_TEXT.format(escape_xml(comparison_xml))).encode('utf-8')
21
22 def send(self, comparison_res):
23 data = self.dict_to_xml(comparison_res)
24 response = requests.post(self.url, headers=self.headers, data=data, verify=False, auth=self.auth)
25 return response
26
27
28
29
1 #!/usr/bin/env python
2 # coding: utf-8
3
4 """
5 Converts a Python dictionary or other native data type into a valid XML string.
6 Supports item (`int`, `float`, `long`, `decimal.Decimal`, `bool`, `str`, `unicode`, `datetime`, `none` and other number-like objects) and collection (`list`, `set`, `tuple` and `dict`, as well as iterable and dict-like objects) data types, with arbitrary nesting for the collections. Items with a `datetime` type are converted to ISO format strings. Items with a `None` type become empty XML elements.
7 This module works with both Python 2 and 3.
8 """
9
10 from __future__ import unicode_literals
11
12 from random import randint
13 import collections
14 import numbers
15 from xml.dom.minidom import parseString
16
17 # python 3 doesn't have a unicode type
18 unicode = str
19
20 # python 3 doesn't have a long type
21 long = int
22
23
24 def set_debug(debug=True, filename='dicttoxml.log'):
25 if debug:
26 import datetime
27 print('Debug mode is on. Events are logged at: %s' % (filename))
28 else:
29 print('Debug mode is off.')
30
31
32 def unicode_me(something):
33 """Converts strings with non-ASCII characters to unicode for LOG.
34 Python 3 doesn't have a `unicode()` function, so `unicode()` is an alias
35 for `str()`, but `str()` doesn't take a second argument, hence this kludge.
36 """
37 try:
38 return unicode(something, 'utf-8')
39 except:
40 return unicode(something)
41
42
43 ids = [] # initialize list of unique ids
44
45
46 def make_id(element, start=100000, end=999999):
47 """Returns a random integer"""
48 return '%s_%s' % (element, randint(start, end))
49
50
51 def get_unique_id(element):
52 """Returns a unique id for a given element"""
53 this_id = make_id(element)
54 dup = True
55 while dup:
56 if this_id not in ids:
57 dup = False
58 ids.append(this_id)
59 else:
60 this_id = make_id(element)
61 return ids[-1]
62
63
64 def get_xml_type(val):
65 """Returns the data type for the xml type attribute"""
66 if type(val).__name__ in ('str', 'unicode'):
67 return 'str'
68 if type(val).__name__ in ('int', 'long'):
69 return 'int'
70 if type(val).__name__ == 'float':
71 return 'float'
72 if type(val).__name__ == 'bool':
73 return 'bool'
74 if isinstance(val, numbers.Number):
75 return 'number'
76 if type(val).__name__ == 'NoneType':
77 return 'null'
78 if isinstance(val, dict):
79 return 'dict'
80 if isinstance(val, collections.Iterable):
81 return 'list'
82 return type(val).__name__
83
84
85 def escape_xml(s):
86 if type(s) in (str, unicode):
87 s = unicode_me(s) # avoid UnicodeDecodeError
88 s = s.replace('&', '&amp;')
89 s = s.replace('"', '&amp;quot;')
90 s = s.replace('\'', '&amp;apos;')
91 s = s.replace('<', '&amp;lt;')
92 s = s.replace('>', '&amp;gt;')
93 return s
94
95
96 def make_attrstring(attr):
97 """Returns an attribute string in the form key="val" """
98 attrstring = ' '.join(['%s="%s"' % (k, v) for k, v in attr.items()])
99 return '%s%s' % (' ' if attrstring != '' else '', attrstring)
100
101
102 def key_is_valid_xml(key):
103 """Checks that a key is a valid XML name"""
104 test_xml = '<?xml version="1.0" encoding="UTF-8" ?><%s>foo</%s>' % (key, key)
105 try:
106 parseString(test_xml)
107 return True
108 except Exception: # minidom does not implement exceptions well
109 return False
110
111
112 def make_valid_xml_name(key, attr):
113 """Tests an XML name and fixes it if invalid"""
114 key = escape_xml(key)
115 attr = escape_xml(attr)
116
117 # pass through if key is already valid
118 if key_is_valid_xml(key):
119 return key, attr
120
121 # prepend a lowercase n if the key is numeric
122 if key.isdigit():
123 return 'n%s' % (key), attr
124
125 # replace spaces with underscores if that fixes the problem
126 if key_is_valid_xml(key.replace(' ', '_')):
127 return key.replace(' ', '_'), attr
128
129 # key is still invalid - move it into a name attribute
130 attr['name'] = key
131 key = 'key'
132 return key, attr
133
134
135 def wrap_cdata(s):
136 """Wraps a string into CDATA sections"""
137 s = unicode_me(s).replace(']]>', ']]]]><![CDATA[>')
138 return '<![CDATA[' + s + ']]>'
139
140
141 def default_item_func(parent):
142 return 'item'
143
144
145 def convert(obj, ids, attr_type, item_func, cdata, parent='root'):
146 """Routes the elements of an object to the right function to convert them
147 based on their data type"""
148
149 item_name = item_func(parent)
150
151 if isinstance(obj, numbers.Number) or type(obj) in (str, unicode):
152 return convert_kv(item_name, obj, attr_type, cdata)
153
154 if hasattr(obj, 'isoformat'):
155 return convert_kv(item_name, obj.isoformat(), attr_type, cdata)
156
157 if type(obj) == bool:
158 return convert_bool(item_name, obj, attr_type, cdata)
159
160 if obj is None:
161 return convert_none(item_name, '', attr_type, cdata)
162
163 if isinstance(obj, dict):
164 return convert_dict(obj, ids, parent, attr_type, item_func, cdata)
165
166 if isinstance(obj, collections.Iterable):
167 return convert_list(obj, ids, parent, attr_type, item_func, cdata)
168
169 raise TypeError('Unsupported data type: %s (%s)' % (obj, type(obj).__name__))
170
171
172 def convert_dict(obj, ids, parent, attr_type, item_func, cdata):
173 """Converts a dict into an XML string."""
174 output = []
175 addline = output.append
176
177 item_name = item_func(parent)
178
179 for key, val in obj.items():
180
181 attr = {} if not ids else {'id': '%s' % (get_unique_id(parent))}
182
183 key, attr = make_valid_xml_name(key, attr)
184
185 if isinstance(val, numbers.Number) or type(val) in (str, unicode):
186 addline(convert_kv(key, val, attr_type, attr, cdata))
187
188 elif hasattr(val, 'isoformat'): # datetime
189 addline(convert_kv(key, val.isoformat(), attr_type, attr, cdata))
190
191 elif type(val) == bool:
192 addline(convert_bool(key, val, attr_type, attr, cdata))
193
194 elif isinstance(val, dict):
195 if attr_type:
196 attr['type'] = get_xml_type(val)
197 addline('<%s%s>%s</%s>' % (
198 key, make_attrstring(attr),
199 convert_dict(val, ids, key, attr_type, item_func, cdata),
200 key
201 )
202 )
203
204 elif isinstance(val, collections.Iterable):
205 if attr_type:
206 attr['type'] = get_xml_type(val)
207 # addline('<%s%s>%s</%s>' % (
208 # key,
209 # make_attrstring(attr),
210 # convert_list(val, ids, key, attr_type, item_func, cdata),
211 # key
212 # )
213 item_func = lambda x: key
214 addline('%s' % (
215 convert_list(val, ids, key, attr_type, item_func, cdata),
216 ))
217
218 elif val is None:
219 addline(convert_none(key, val, attr_type, attr, cdata))
220
221 else:
222 raise TypeError('Unsupported data type: %s (%s)' % (
223 val, type(val).__name__)
224 )
225
226 return ''.join(output)
227
228
229 def convert_list(items, ids, parent, attr_type, item_func, cdata):
230 """Converts a list into an XML string."""
231 output = []
232 addline = output.append
233
234 item_name = item_func(parent)
235
236 if ids:
237 this_id = get_unique_id(parent)
238
239 for i, item in enumerate(items):
240 attr = {} if not ids else {'id': '%s_%s' % (this_id, i + 1)}
241 if isinstance(item, numbers.Number) or type(item) in (str, unicode):
242 addline(convert_kv(item_name, item, attr_type, attr, cdata))
243
244 elif hasattr(item, 'isoformat'): # datetime
245 addline(convert_kv(item_name, item.isoformat(), attr_type, attr, cdata))
246
247 elif type(item) == bool:
248 addline(convert_bool(item_name, item, attr_type, attr, cdata))
249
250 elif isinstance(item, dict):
251 if not attr_type:
252 addline('<%s>%s</%s>' % (
253 item_name,
254 convert_dict(item, ids, parent, attr_type, item_func, cdata),
255 item_name,
256 )
257 )
258 else:
259 addline('<%s type="dict">%s</%s>' % (
260 item_name,
261 convert_dict(item, ids, parent, attr_type, item_func, cdata),
262 item_name,
263 )
264 )
265
266 elif isinstance(item, collections.Iterable):
267 if not attr_type:
268 addline('<%s %s>%s</%s>' % (
269 item_name, make_attrstring(attr),
270 convert_list(item, ids, item_name, attr_type, item_func, cdata),
271 item_name,
272 )
273 )
274 else:
275 addline('<%s type="list"%s>%s</%s>' % (
276 item_name, make_attrstring(attr),
277 convert_list(item, ids, item_name, attr_type, item_func, cdata),
278 item_name,
279 )
280 )
281
282 elif item is None:
283 addline(convert_none(item_name, None, attr_type, attr, cdata))
284
285 else:
286 raise TypeError('Unsupported data type: %s (%s)' % (
287 item, type(item).__name__)
288 )
289 return ''.join(output)
290
291
292 def convert_kv(key, val, attr_type, attr={}, cdata=False):
293 """Converts a number or string into an XML element"""
294
295 key, attr = make_valid_xml_name(key, attr)
296
297 if attr_type:
298 attr['type'] = get_xml_type(val)
299 attrstring = make_attrstring(attr)
300 return '<%s%s>%s</%s>' % (
301 key, attrstring,
302 wrap_cdata(val) if cdata == True else escape_xml(val),
303 key
304 )
305
306
307 def convert_bool(key, val, attr_type, attr={}, cdata=False):
308 """Converts a boolean into an XML element"""
309
310 key, attr = make_valid_xml_name(key, attr)
311
312 if attr_type:
313 attr['type'] = get_xml_type(val)
314 attrstring = make_attrstring(attr)
315 return '<%s%s>%s</%s>' % (key, attrstring, unicode(val).lower(), key)
316
317
318 def convert_none(key, val, attr_type, attr={}, cdata=False):
319 """Converts a null value into an XML element"""
320
321 key, attr = make_valid_xml_name(key, attr)
322
323 if attr_type:
324 attr['type'] = get_xml_type(val)
325 attrstring = make_attrstring(attr)
326 return '<%s%s></%s>' % (key, attrstring, key)
327
328
329 def dicttoxml(obj, root=True, custom_root='root', ids=False, attr_type=True,
330 item_func=default_item_func, cdata=False):
331 """Converts a python object into XML.
332 Arguments:
333 - root specifies whether the output is wrapped in an XML root element
334 Default is True
335 - custom_root allows you to specify a custom root element.
336 Default is 'root'
337 - ids specifies whether elements get unique ids.
338 Default is False
339 - attr_type specifies whether elements get a data type attribute.
340 Default is True
341 - item_func specifies what function should generate the element name for
342 items in a list.
343 Default is 'item'
344 - cdata specifies whether string values should be wrapped in CDATA sections.
345 Default is False
346 """
347 output = []
348 addline = output.append
349 if root == True:
350 addline('<?xml version="1.0" encoding="UTF-8" ?>')
351 addline('<%s>%s</%s>' % (
352 custom_root,
353 convert(obj, ids, attr_type, item_func, cdata, parent=custom_root),
354 custom_root,
355 )
356 )
357 else:
358 addline(convert(obj, ids, attr_type, item_func, cdata, parent=''))
359 return ''.join(output)
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!