add GCAP interface
Showing
3 changed files
with
402 additions
and
0 deletions
... | @@ -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><Request><Framework><UserName>SFCHINA\qqcout0</UserName><GUID>70d0efcb-3bc2-4018-ac4e-681c8f3131b6</GUID><DetailedTracingEnabled>False</DetailedTracingEnabled><ServiceName>AMSWebService</ServiceName><SupportsRedirection>true</SupportsRedirection><ServiceType>Service</ServiceType></Framework><Parms><InputXML type="string">&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;InputXML&gt; &lt;Result&gt; {0} &lt;/Result&gt;&lt;AuthorizationData&gt;&lt;ServiceComponent&gt;OCR&lt;/ServiceComponent&gt;&lt;RoleId/&gt;&lt;CompanyId/&gt;&lt;/AuthorizationData&gt;&lt;/InputXML&gt;</InputXML></Parms></Request></strXMLParm></Exec>]]>""" | ||
1020 | ... | ... |
src/apps/doc/ocr/gcap.py
0 → 100644
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 |
src/common/tools/dict_to_xml.py
0 → 100644
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('&', '&') | ||
89 | s = s.replace('"', '&quot;') | ||
90 | s = s.replace('\'', '&apos;') | ||
91 | s = s.replace('<', '&lt;') | ||
92 | s = s.replace('>', '&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) |
-
Please register or sign in to post a comment