pyxecm 1.6__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyxecm might be problematic. Click here for more details.
- pyxecm/__init__.py +6 -4
- pyxecm/avts.py +673 -246
- pyxecm/coreshare.py +686 -467
- pyxecm/customizer/__init__.py +16 -4
- pyxecm/customizer/__main__.py +58 -0
- pyxecm/customizer/api/__init__.py +5 -0
- pyxecm/customizer/api/__main__.py +6 -0
- pyxecm/customizer/api/app.py +914 -0
- pyxecm/customizer/api/auth.py +154 -0
- pyxecm/customizer/api/metrics.py +92 -0
- pyxecm/customizer/api/models.py +13 -0
- pyxecm/customizer/api/payload_list.py +865 -0
- pyxecm/customizer/api/settings.py +103 -0
- pyxecm/customizer/browser_automation.py +332 -139
- pyxecm/customizer/customizer.py +1007 -1130
- pyxecm/customizer/exceptions.py +35 -0
- pyxecm/customizer/guidewire.py +322 -0
- pyxecm/customizer/k8s.py +713 -378
- pyxecm/customizer/log.py +107 -0
- pyxecm/customizer/m365.py +2867 -909
- pyxecm/customizer/nhc.py +1169 -0
- pyxecm/customizer/openapi.py +258 -0
- pyxecm/customizer/payload.py +16817 -7467
- pyxecm/customizer/pht.py +699 -285
- pyxecm/customizer/salesforce.py +516 -342
- pyxecm/customizer/sap.py +58 -41
- pyxecm/customizer/servicenow.py +593 -371
- pyxecm/customizer/settings.py +442 -0
- pyxecm/customizer/successfactors.py +408 -346
- pyxecm/customizer/translate.py +83 -48
- pyxecm/helper/__init__.py +5 -2
- pyxecm/helper/assoc.py +83 -43
- pyxecm/helper/data.py +2406 -870
- pyxecm/helper/logadapter.py +27 -0
- pyxecm/helper/web.py +229 -101
- pyxecm/helper/xml.py +527 -171
- pyxecm/maintenance_page/__init__.py +5 -0
- pyxecm/maintenance_page/__main__.py +6 -0
- pyxecm/maintenance_page/app.py +51 -0
- pyxecm/maintenance_page/settings.py +28 -0
- pyxecm/maintenance_page/static/favicon.avif +0 -0
- pyxecm/maintenance_page/templates/maintenance.html +165 -0
- pyxecm/otac.py +234 -140
- pyxecm/otawp.py +1436 -557
- pyxecm/otcs.py +7716 -3161
- pyxecm/otds.py +2150 -919
- pyxecm/otiv.py +36 -21
- pyxecm/otmm.py +1272 -325
- pyxecm/otpd.py +231 -127
- pyxecm-2.0.0.dist-info/METADATA +145 -0
- pyxecm-2.0.0.dist-info/RECORD +54 -0
- {pyxecm-1.6.dist-info → pyxecm-2.0.0.dist-info}/WHEEL +1 -1
- pyxecm-1.6.dist-info/METADATA +0 -53
- pyxecm-1.6.dist-info/RECORD +0 -32
- {pyxecm-1.6.dist-info → pyxecm-2.0.0.dist-info/licenses}/LICENSE +0 -0
- {pyxecm-1.6.dist-info → pyxecm-2.0.0.dist-info}/top_level.txt +0 -0
pyxecm/customizer/translate.py
CHANGED
|
@@ -1,78 +1,101 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Experimental module to automate translations
|
|
3
|
-
|
|
4
|
-
Class: Translator
|
|
5
|
-
Methods:
|
|
6
|
-
|
|
7
|
-
__init__ : class initializer
|
|
8
|
-
config: Return the configuration parameters
|
|
9
|
-
translate: Translate a string from one language to another using the Google Translate V2 API
|
|
10
|
-
translateV3: Translate a string from one language to another using the Google Translate V3 API
|
|
11
|
-
|
|
12
|
-
"""
|
|
1
|
+
"""Experimental module to automate translations."""
|
|
13
2
|
|
|
14
3
|
__author__ = "Dr. Marc Diefenbruch"
|
|
15
|
-
__copyright__ = "Copyright 2024, OpenText"
|
|
4
|
+
__copyright__ = "Copyright (C) 2024-2025, OpenText"
|
|
16
5
|
__credits__ = ["Kai-Philip Gatzweiler"]
|
|
17
6
|
__maintainer__ = "Dr. Marc Diefenbruch"
|
|
18
7
|
__email__ = "mdiefenb@opentext.com"
|
|
19
8
|
|
|
20
9
|
import logging
|
|
10
|
+
|
|
21
11
|
import requests
|
|
22
12
|
|
|
23
|
-
|
|
13
|
+
default_logger = logging.getLogger("pyxecm.customizer.translate")
|
|
14
|
+
|
|
15
|
+
REQUEST_TIMEOUT = 60
|
|
24
16
|
|
|
25
17
|
|
|
26
18
|
class Translator:
|
|
27
|
-
"""Class for translation of of strings based on the Google Translate API.
|
|
28
|
-
|
|
19
|
+
"""Class Translator is used for translation of of strings based on the Google Translate API.
|
|
20
|
+
|
|
21
|
+
The class supports V2 and V3 translation APIs.
|
|
29
22
|
"""
|
|
30
23
|
|
|
24
|
+
logger: logging.Logger = default_logger
|
|
25
|
+
|
|
31
26
|
_config = None
|
|
32
27
|
_headers = None
|
|
33
28
|
|
|
34
|
-
def __init__(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
29
|
+
def __init__(
|
|
30
|
+
self,
|
|
31
|
+
api_key: str,
|
|
32
|
+
project_key: str = "",
|
|
33
|
+
domain: str = "",
|
|
34
|
+
logger: logging.Logger = default_logger,
|
|
35
|
+
) -> None:
|
|
36
|
+
"""Initialize the Translate objects.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
api_key (str):
|
|
40
|
+
The Google Translate API key.
|
|
41
|
+
project_key (str, optional):
|
|
42
|
+
The Google project. Defaults to "".
|
|
43
|
+
domain (str, optional):
|
|
44
|
+
The domain. Defaults to "".
|
|
45
|
+
logger (logging.Logger, optional):
|
|
46
|
+
The logging object to log all messages. Defaults to default_logger.
|
|
47
|
+
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
if logger != default_logger:
|
|
51
|
+
self.logger = logger.getChild("translator")
|
|
52
|
+
for logfilter in logger.filters:
|
|
53
|
+
self.logger.addFilter(logfilter)
|
|
54
|
+
|
|
55
|
+
translate_config = {}
|
|
56
|
+
|
|
57
|
+
translate_config["apiKey"] = api_key
|
|
58
|
+
translate_config["translateUrlV2"] = "https://translation.googleapis.com/language/translate/v2"
|
|
59
|
+
translate_config["translateUrlV3"] = "https://translation.googleapis.com/v3/projects/{}:translateText".format(
|
|
60
|
+
project_key,
|
|
45
61
|
)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
62
|
+
translate_config["project"] = project_key
|
|
63
|
+
translate_config["parent"] = "projects/{}/locations/global".format(project_key)
|
|
64
|
+
translate_config["model"] = f"nmt{':{}'.format(domain) if domain else ''}"
|
|
49
65
|
|
|
50
66
|
self._headers = {
|
|
51
67
|
"Authorization": f"Bearer {api_key}",
|
|
52
68
|
"Content-Type": "application/json; charset=utf-8",
|
|
53
69
|
}
|
|
54
70
|
|
|
55
|
-
self._config =
|
|
71
|
+
self._config = translate_config
|
|
56
72
|
|
|
57
73
|
def config(self) -> dict:
|
|
58
|
-
"""Return the configuration parameters
|
|
74
|
+
"""Return the configuration parameters.
|
|
59
75
|
|
|
60
76
|
Returns:
|
|
61
|
-
dict:
|
|
77
|
+
dict:
|
|
78
|
+
The onfiguration parameters.
|
|
79
|
+
|
|
62
80
|
"""
|
|
63
81
|
|
|
64
82
|
return self._config
|
|
65
83
|
|
|
66
84
|
def translate(self, source_language: str, target_language: str, text: str) -> str:
|
|
67
|
-
"""Translate a string from one language to another using the Google Translate V2 API
|
|
85
|
+
"""Translate a string from one language to another using the Google Translate V2 API.
|
|
68
86
|
|
|
69
87
|
Args:
|
|
70
|
-
source_language (str):
|
|
71
|
-
|
|
72
|
-
|
|
88
|
+
source_language (str):
|
|
89
|
+
The source language.
|
|
90
|
+
target_language (str):
|
|
91
|
+
The target language.
|
|
92
|
+
text (str):
|
|
93
|
+
The string to translate.
|
|
73
94
|
|
|
74
95
|
Returns:
|
|
75
|
-
str:
|
|
96
|
+
str:
|
|
97
|
+
The translated string.
|
|
98
|
+
|
|
76
99
|
"""
|
|
77
100
|
|
|
78
101
|
params = {
|
|
@@ -84,10 +107,14 @@ class Translator:
|
|
|
84
107
|
|
|
85
108
|
request_url = self.config()["translateUrlV2"]
|
|
86
109
|
|
|
87
|
-
response = requests.post(
|
|
110
|
+
response = requests.post(
|
|
111
|
+
url=request_url,
|
|
112
|
+
params=params,
|
|
113
|
+
timeout=REQUEST_TIMEOUT,
|
|
114
|
+
)
|
|
88
115
|
|
|
89
116
|
if response.status_code != 200:
|
|
90
|
-
logger.error("Failed to translate text -> %s", response.content)
|
|
117
|
+
self.logger.error("Failed to translate text -> %s", response.content)
|
|
91
118
|
return None
|
|
92
119
|
|
|
93
120
|
translated_text = response.json()["data"]["translations"][0]["translatedText"]
|
|
@@ -96,16 +123,21 @@ class Translator:
|
|
|
96
123
|
|
|
97
124
|
# end method definition
|
|
98
125
|
|
|
99
|
-
def
|
|
100
|
-
"""Translate a string from one language to another using the Google Translate V3 API
|
|
126
|
+
def translate_v3(self, source_language: str, target_language: str, text: str) -> str:
|
|
127
|
+
"""Translate a string from one language to another using the Google Translate V3 API.
|
|
101
128
|
|
|
102
129
|
Args:
|
|
103
|
-
source_language (str):
|
|
104
|
-
|
|
105
|
-
|
|
130
|
+
source_language (str):
|
|
131
|
+
The source language.
|
|
132
|
+
target_language (str):
|
|
133
|
+
The destination language.
|
|
134
|
+
text (str):
|
|
135
|
+
The string to translate.
|
|
106
136
|
|
|
107
137
|
Returns:
|
|
108
|
-
str:
|
|
138
|
+
str:
|
|
139
|
+
The translated string.
|
|
140
|
+
|
|
109
141
|
"""
|
|
110
142
|
|
|
111
143
|
data = {
|
|
@@ -118,11 +150,14 @@ class Translator:
|
|
|
118
150
|
request_url = self.config()["translateUrlV3"]
|
|
119
151
|
|
|
120
152
|
response = requests.post(
|
|
121
|
-
url=request_url,
|
|
153
|
+
url=request_url,
|
|
154
|
+
headers=request_header,
|
|
155
|
+
json=data,
|
|
156
|
+
timeout=REQUEST_TIMEOUT,
|
|
122
157
|
)
|
|
123
158
|
|
|
124
159
|
if response.status_code != 200:
|
|
125
|
-
logger.error("Failed to translate text -> %s", response.content)
|
|
160
|
+
self.logger.error("Failed to translate text -> %s", response.content)
|
|
126
161
|
return None
|
|
127
162
|
|
|
128
163
|
translated_text = response.json()["data"]["translations"][0]["translatedText"]
|
pyxecm/helper/__init__.py
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
"""pyxecm helper classes, not for direct use"""
|
|
1
|
+
"""pyxecm helper classes, not for direct use."""
|
|
2
2
|
|
|
3
3
|
from .assoc import Assoc
|
|
4
|
+
from .data import Data
|
|
5
|
+
from .logadapter import PrefixLogAdapter
|
|
4
6
|
from .web import HTTP
|
|
5
7
|
from .xml import XML
|
|
6
|
-
|
|
8
|
+
|
|
9
|
+
__all__ = ["HTTP", "XML", "Assoc", "Data", "PrefixLogAdapter"]
|
pyxecm/helper/assoc.py
CHANGED
|
@@ -1,28 +1,21 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Extended ECM Assoc Module to implement functions to read / write from
|
|
3
|
-
so called "Assoc" data structures in Extended ECM. Right now this module
|
|
4
|
-
is used to tweak settings in XML-based transport packages that include
|
|
5
|
-
Assoc structures inside some of the XML elements.
|
|
1
|
+
"""Assoc Module to implement functions to read / write from so called "Assoc" data structures in Content Server.
|
|
6
2
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
stringToDict: convert an Assoc string to an Python dict representing the assoc values
|
|
11
|
-
dictToString: converting an Assoc dict to an Assoc string
|
|
3
|
+
Right now this module is used to tweak settings in XML-based transport packages that include
|
|
4
|
+
Assoc structures inside some of the XML elements.
|
|
12
5
|
"""
|
|
13
6
|
|
|
14
7
|
__author__ = "Dr. Marc Diefenbruch"
|
|
15
|
-
__copyright__ = "Copyright 2024, OpenText"
|
|
8
|
+
__copyright__ = "Copyright (C) 2024-2025, OpenText"
|
|
16
9
|
__credits__ = ["Kai-Philip Gatzweiler"]
|
|
17
10
|
__maintainer__ = "Dr. Marc Diefenbruch"
|
|
18
11
|
__email__ = "mdiefenb@opentext.com"
|
|
19
12
|
|
|
20
|
-
import re
|
|
21
13
|
import html
|
|
14
|
+
import re
|
|
22
15
|
|
|
23
16
|
|
|
24
17
|
class Assoc:
|
|
25
|
-
"""Class to handle Extended ECM Assoc data structures."""
|
|
18
|
+
"""Class Assoc is used to handle Extended ECM Assoc data structures."""
|
|
26
19
|
|
|
27
20
|
@classmethod
|
|
28
21
|
def is_unicode_escaped(cls, assoc_string: str) -> bool:
|
|
@@ -33,6 +26,7 @@ class Assoc:
|
|
|
33
26
|
|
|
34
27
|
Returns:
|
|
35
28
|
bool: True if string is in Unicode, False otherwise
|
|
29
|
+
|
|
36
30
|
"""
|
|
37
31
|
|
|
38
32
|
pattern = r"\\u[0-9a-fA-F]{4}"
|
|
@@ -40,78 +34,100 @@ class Assoc:
|
|
|
40
34
|
|
|
41
35
|
return len(matches) > 0
|
|
42
36
|
|
|
37
|
+
# end method definition
|
|
38
|
+
|
|
43
39
|
@classmethod
|
|
44
40
|
def escape_unicode(cls, assoc_string: str) -> str:
|
|
45
|
-
"""Escape / Encode a given string in Unicode
|
|
41
|
+
"""Escape / Encode a given string in Unicode.
|
|
46
42
|
|
|
47
43
|
Args:
|
|
48
|
-
assoc_string (str):
|
|
44
|
+
assoc_string (str):
|
|
45
|
+
The source string to escape.
|
|
49
46
|
|
|
50
47
|
Returns:
|
|
51
|
-
str:
|
|
48
|
+
str:
|
|
49
|
+
The escaped string.
|
|
50
|
+
|
|
52
51
|
"""
|
|
53
52
|
|
|
54
53
|
encoded_string = assoc_string.encode("unicode_escape") # .decode()
|
|
55
54
|
|
|
56
55
|
return encoded_string
|
|
57
56
|
|
|
57
|
+
# end method definition
|
|
58
|
+
|
|
58
59
|
@classmethod
|
|
59
60
|
def unescape_unicode(cls, assoc_string: str) -> str:
|
|
60
|
-
"""Unescape / Decode a given string
|
|
61
|
+
"""Unescape / Decode a given string.
|
|
61
62
|
|
|
62
63
|
Args:
|
|
63
|
-
assoc_string (str):
|
|
64
|
+
assoc_string (str):
|
|
65
|
+
The source string to unescape.
|
|
64
66
|
|
|
65
67
|
Returns:
|
|
66
|
-
str:
|
|
68
|
+
str:
|
|
69
|
+
The unescaped string.
|
|
70
|
+
|
|
67
71
|
"""
|
|
68
72
|
try:
|
|
69
73
|
decoded_string = bytes(assoc_string, "utf-8").decode("unicode_escape")
|
|
70
|
-
return decoded_string
|
|
71
74
|
except UnicodeDecodeError:
|
|
72
75
|
return assoc_string
|
|
73
76
|
|
|
77
|
+
return decoded_string
|
|
78
|
+
|
|
79
|
+
# end method definition
|
|
80
|
+
|
|
74
81
|
@classmethod
|
|
75
82
|
def is_html_escaped(cls, assoc_string: str) -> bool:
|
|
76
|
-
"""
|
|
77
|
-
is HTML escaped.
|
|
83
|
+
"""Check if an Assoc String is HTML escaped.
|
|
78
84
|
|
|
79
85
|
Args:
|
|
80
|
-
assoc_string (str):
|
|
86
|
+
assoc_string (str):
|
|
87
|
+
The string to test for HTML escaping.
|
|
81
88
|
|
|
82
89
|
Returns:
|
|
83
|
-
bool:
|
|
90
|
+
bool:
|
|
91
|
+
True = string is HTML escaped, False if now
|
|
92
|
+
|
|
84
93
|
"""
|
|
85
94
|
|
|
86
95
|
decoded_string = html.unescape(assoc_string)
|
|
87
96
|
|
|
88
97
|
return assoc_string != decoded_string
|
|
89
98
|
|
|
99
|
+
# end method definition
|
|
100
|
+
|
|
90
101
|
@classmethod
|
|
91
102
|
def unescape_html(cls, assoc_string: str) -> str:
|
|
92
|
-
"""HTML unescape a a string
|
|
103
|
+
"""HTML unescape a a string.
|
|
93
104
|
|
|
94
105
|
Args:
|
|
95
106
|
assoc_string (str): the string to unescape.
|
|
96
107
|
|
|
97
108
|
Returns:
|
|
98
109
|
str: unescaped string
|
|
110
|
+
|
|
99
111
|
"""
|
|
100
112
|
|
|
101
113
|
decoded_string = html.unescape(assoc_string)
|
|
102
114
|
return decoded_string
|
|
103
115
|
|
|
116
|
+
# end method definition
|
|
117
|
+
|
|
104
118
|
@classmethod
|
|
105
119
|
def string_to_dict(cls, assoc_string: str) -> dict:
|
|
106
120
|
"""Convert an Assoc string to a Python dict.
|
|
107
|
-
|
|
108
|
-
|
|
121
|
+
|
|
122
|
+
Each comma-separated element of the Assoc will become a dict element.
|
|
109
123
|
|
|
110
124
|
Args:
|
|
111
|
-
assoc_string (str):
|
|
125
|
+
assoc_string (str):
|
|
126
|
+
The source Assoc string to convert.
|
|
112
127
|
|
|
113
128
|
Returns:
|
|
114
129
|
dict: Python dict with the Assoc elements
|
|
130
|
+
|
|
115
131
|
"""
|
|
116
132
|
|
|
117
133
|
if cls.is_html_escaped(assoc_string):
|
|
@@ -152,15 +168,20 @@ class Assoc:
|
|
|
152
168
|
|
|
153
169
|
return assoc_dict
|
|
154
170
|
|
|
171
|
+
# end method definition
|
|
172
|
+
|
|
155
173
|
@classmethod
|
|
156
174
|
def dict_to_string(cls, assoc_dict: dict) -> str:
|
|
157
|
-
"""Convert a Python dict to an Assoc string
|
|
175
|
+
"""Convert a Python dict to an Assoc string.
|
|
158
176
|
|
|
159
177
|
Args:
|
|
160
|
-
assoc_dict (dict):
|
|
178
|
+
assoc_dict (dict):
|
|
179
|
+
The source dictionary to convert.
|
|
161
180
|
|
|
162
181
|
Returns:
|
|
163
|
-
str:
|
|
182
|
+
str:
|
|
183
|
+
The resulting Assoc string.
|
|
184
|
+
|
|
164
185
|
"""
|
|
165
186
|
|
|
166
187
|
assoc_string: str = "A<1,?,"
|
|
@@ -182,20 +203,29 @@ class Assoc:
|
|
|
182
203
|
assoc_string += ">"
|
|
183
204
|
return assoc_string
|
|
184
205
|
|
|
206
|
+
# end method definition
|
|
207
|
+
|
|
185
208
|
@classmethod
|
|
186
209
|
def extract_substring(
|
|
187
|
-
cls,
|
|
210
|
+
cls,
|
|
211
|
+
input_string: str,
|
|
212
|
+
start_sequence: str,
|
|
213
|
+
stop_sequence: str,
|
|
188
214
|
) -> str | None:
|
|
189
|
-
"""
|
|
190
|
-
by a strart and stop sequence.
|
|
215
|
+
"""Extract a substring that is delimited by a start and stop sequence.
|
|
191
216
|
|
|
192
217
|
Args:
|
|
193
|
-
input_string (str):
|
|
194
|
-
|
|
195
|
-
|
|
218
|
+
input_string (str):
|
|
219
|
+
Input string to search the delimited substring in.
|
|
220
|
+
start_sequence (str):
|
|
221
|
+
Start esequence of characters.
|
|
222
|
+
stop_sequence (str):
|
|
223
|
+
Stop sequence of characters
|
|
196
224
|
|
|
197
225
|
Returns:
|
|
198
|
-
str | None:
|
|
226
|
+
str | None:
|
|
227
|
+
The deliminated substring or None if not found.
|
|
228
|
+
|
|
199
229
|
"""
|
|
200
230
|
|
|
201
231
|
start_index = input_string.find(start_sequence)
|
|
@@ -209,17 +239,25 @@ class Assoc:
|
|
|
209
239
|
end_index += len(stop_sequence)
|
|
210
240
|
return input_string[start_index:end_index]
|
|
211
241
|
|
|
242
|
+
# end method definition
|
|
243
|
+
|
|
212
244
|
@classmethod
|
|
213
245
|
def extract_assoc_string(cls, input_string: str, is_escaped: bool = False) -> str:
|
|
214
|
-
"""Extract an Assoc from a string.
|
|
246
|
+
"""Extract an Assoc from a string.
|
|
247
|
+
|
|
248
|
+
The assoc is deliminated by A< ... >.
|
|
215
249
|
|
|
216
250
|
Args:
|
|
217
|
-
input_string (str):
|
|
218
|
-
|
|
219
|
-
|
|
251
|
+
input_string (str):
|
|
252
|
+
Input string that includes the Assoc as a substring.
|
|
253
|
+
is_escaped (bool, optional):
|
|
254
|
+
Whether or not the input string includes the
|
|
255
|
+
assoc escaped or not.
|
|
220
256
|
|
|
221
257
|
Returns:
|
|
222
|
-
str:
|
|
258
|
+
str:
|
|
259
|
+
The assoc string.
|
|
260
|
+
|
|
223
261
|
"""
|
|
224
262
|
|
|
225
263
|
if is_escaped:
|
|
@@ -227,3 +265,5 @@ class Assoc:
|
|
|
227
265
|
else:
|
|
228
266
|
assoc_string = cls.extract_substring(input_string, "A<", ">")
|
|
229
267
|
return assoc_string
|
|
268
|
+
|
|
269
|
+
# end method definition
|