pyxecm 2.0.4__py3-none-any.whl → 3.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/coreshare.py +5 -3
- pyxecm/helper/data.py +4 -4
- pyxecm/helper/otel_config.py +26 -0
- pyxecm/helper/web.py +1 -2
- pyxecm/otca.py +1356 -16
- pyxecm/otcs.py +2354 -593
- pyxecm/otds.py +1 -1
- pyxecm/otmm.py +4 -5
- pyxecm/py.typed +0 -0
- pyxecm-3.0.0.dist-info/METADATA +48 -0
- pyxecm-3.0.0.dist-info/RECORD +96 -0
- {pyxecm-2.0.4.dist-info → pyxecm-3.0.0.dist-info}/WHEEL +1 -2
- pyxecm-3.0.0.dist-info/entry_points.txt +4 -0
- {pyxecm/customizer/api → pyxecm_api}/__main__.py +1 -1
- pyxecm_api/agents/__init__.py +7 -0
- pyxecm_api/agents/app.py +13 -0
- pyxecm_api/agents/functions.py +119 -0
- pyxecm_api/agents/models.py +10 -0
- pyxecm_api/agents/otcm_knowledgegraph/functions.py +85 -0
- pyxecm_api/agents/otcm_knowledgegraph/models.py +61 -0
- pyxecm_api/agents/otcm_knowledgegraph/router.py +74 -0
- pyxecm_api/agents/otcm_user_agent/models.py +20 -0
- pyxecm_api/agents/otcm_user_agent/router.py +65 -0
- pyxecm_api/agents/otcm_workspace_agent/models.py +40 -0
- pyxecm_api/agents/otcm_workspace_agent/router.py +200 -0
- pyxecm_api/app.py +221 -0
- {pyxecm/customizer/api → pyxecm_api}/auth/functions.py +10 -2
- {pyxecm/customizer/api → pyxecm_api}/auth/router.py +4 -3
- {pyxecm/customizer/api → pyxecm_api}/common/functions.py +39 -9
- {pyxecm/customizer/api → pyxecm_api}/common/metrics.py +1 -2
- {pyxecm/customizer/api → pyxecm_api}/common/router.py +7 -8
- {pyxecm/customizer/api → pyxecm_api}/settings.py +21 -6
- {pyxecm/customizer/api → pyxecm_api}/terminal/router.py +1 -1
- {pyxecm/customizer/api → pyxecm_api}/v1_csai/router.py +39 -10
- pyxecm_api/v1_csai/statics/bindings/utils.js +189 -0
- pyxecm_api/v1_csai/statics/tom-select/tom-select.complete.min.js +356 -0
- pyxecm_api/v1_csai/statics/tom-select/tom-select.css +334 -0
- pyxecm_api/v1_csai/statics/vis-9.1.2/vis-network.css +1 -0
- pyxecm_api/v1_csai/statics/vis-9.1.2/vis-network.min.js +27 -0
- pyxecm_api/v1_maintenance/__init__.py +1 -0
- {pyxecm/customizer/api → pyxecm_api}/v1_maintenance/functions.py +3 -3
- {pyxecm/customizer/api → pyxecm_api}/v1_maintenance/router.py +8 -8
- pyxecm_api/v1_otcs/__init__.py +1 -0
- {pyxecm/customizer/api → pyxecm_api}/v1_otcs/functions.py +7 -5
- {pyxecm/customizer/api → pyxecm_api}/v1_otcs/router.py +8 -7
- pyxecm_api/v1_payload/__init__.py +1 -0
- {pyxecm/customizer/api → pyxecm_api}/v1_payload/functions.py +10 -7
- {pyxecm/customizer/api → pyxecm_api}/v1_payload/router.py +11 -10
- {pyxecm/customizer → pyxecm_customizer}/__init__.py +8 -0
- {pyxecm/customizer → pyxecm_customizer}/__main__.py +15 -21
- {pyxecm/customizer → pyxecm_customizer}/browser_automation.py +414 -103
- {pyxecm/customizer → pyxecm_customizer}/customizer.py +178 -116
- {pyxecm/customizer → pyxecm_customizer}/guidewire.py +60 -20
- {pyxecm/customizer → pyxecm_customizer}/k8s.py +4 -4
- pyxecm_customizer/knowledge_graph.py +719 -0
- pyxecm_customizer/log.py +35 -0
- {pyxecm/customizer → pyxecm_customizer}/m365.py +41 -33
- {pyxecm/customizer → pyxecm_customizer}/payload.py +2265 -1933
- {pyxecm/customizer/api/common → pyxecm_customizer}/payload_list.py +18 -55
- {pyxecm/customizer → pyxecm_customizer}/salesforce.py +1 -1
- {pyxecm/customizer → pyxecm_customizer}/sap.py +6 -2
- {pyxecm/customizer → pyxecm_customizer}/servicenow.py +2 -4
- {pyxecm/customizer → pyxecm_customizer}/settings.py +7 -6
- {pyxecm/customizer → pyxecm_customizer}/successfactors.py +40 -28
- {pyxecm/customizer → pyxecm_customizer}/translate.py +1 -1
- {pyxecm/maintenance_page → pyxecm_maintenance_page}/__main__.py +1 -1
- {pyxecm/maintenance_page → pyxecm_maintenance_page}/app.py +14 -8
- pyxecm/customizer/api/app.py +0 -157
- pyxecm/customizer/log.py +0 -107
- pyxecm/customizer/nhc.py +0 -1169
- pyxecm/customizer/openapi.py +0 -258
- pyxecm/customizer/pht.py +0 -1357
- pyxecm-2.0.4.dist-info/METADATA +0 -119
- pyxecm-2.0.4.dist-info/RECORD +0 -78
- pyxecm-2.0.4.dist-info/licenses/LICENSE +0 -202
- pyxecm-2.0.4.dist-info/top_level.txt +0 -1
- {pyxecm/customizer/api → pyxecm_api}/__init__.py +0 -0
- {pyxecm/customizer/api/auth → pyxecm_api/agents/otcm_knowledgegraph}/__init__.py +0 -0
- {pyxecm/customizer/api/common → pyxecm_api/agents/otcm_user_agent}/__init__.py +0 -0
- {pyxecm/customizer/api/v1_csai → pyxecm_api/agents/otcm_workspace_agent}/__init__.py +0 -0
- {pyxecm/customizer/api/v1_maintenance → pyxecm_api/auth}/__init__.py +0 -0
- {pyxecm/customizer/api → pyxecm_api}/auth/models.py +0 -0
- {pyxecm/customizer/api/v1_otcs → pyxecm_api/common}/__init__.py +0 -0
- {pyxecm/customizer/api → pyxecm_api}/common/models.py +0 -0
- {pyxecm/customizer/api → pyxecm_api}/terminal/__init__.py +0 -0
- {pyxecm/customizer/api/v1_payload → pyxecm_api/v1_csai}/__init__.py +0 -0
- {pyxecm/customizer/api → pyxecm_api}/v1_csai/models.py +0 -0
- {pyxecm/customizer/api → pyxecm_api}/v1_maintenance/models.py +0 -0
- {pyxecm/customizer/api → pyxecm_api}/v1_payload/models.py +0 -0
- {pyxecm/customizer → pyxecm_customizer}/exceptions.py +0 -0
- {pyxecm/maintenance_page → pyxecm_maintenance_page}/__init__.py +0 -0
- {pyxecm/maintenance_page → pyxecm_maintenance_page}/settings.py +0 -0
- {pyxecm/maintenance_page → pyxecm_maintenance_page}/static/favicon.avif +0 -0
- {pyxecm/maintenance_page → pyxecm_maintenance_page}/templates/maintenance.html +0 -0
pyxecm_customizer/log.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Common logging handler for VictoriaLogs and the LogCountFilter."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LogCountFilter(logging.Filter):
|
|
9
|
+
"""LogFilter to be assinged to thread_logger to count the number os messages by level."""
|
|
10
|
+
|
|
11
|
+
def __init__(self, payload_items: pd.DataFrame, index: int) -> None:
|
|
12
|
+
"""LogCountFilter initializer.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
payload_items (pd.DataFrame): _description_
|
|
16
|
+
index (int): _description_
|
|
17
|
+
|
|
18
|
+
"""
|
|
19
|
+
super().__init__()
|
|
20
|
+
self.index = index
|
|
21
|
+
self.payload_items = payload_items
|
|
22
|
+
|
|
23
|
+
def filter(self, record: logging.LogRecord) -> bool:
|
|
24
|
+
"""Filter method.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
record (_type_): _description_
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
bool: _description_
|
|
31
|
+
|
|
32
|
+
"""
|
|
33
|
+
level_name = (record.levelname).lower()
|
|
34
|
+
self.payload_items.loc[self.index, f"log_{level_name}"] += 1
|
|
35
|
+
return True
|
|
@@ -16,16 +16,16 @@ import re
|
|
|
16
16
|
import time
|
|
17
17
|
import urllib.parse
|
|
18
18
|
import zipfile
|
|
19
|
-
from datetime import
|
|
19
|
+
from datetime import UTC, datetime
|
|
20
20
|
from http import HTTPStatus
|
|
21
21
|
from urllib.parse import quote
|
|
22
22
|
|
|
23
23
|
import requests
|
|
24
|
-
|
|
25
|
-
from pyxecm.customizer.browser_automation import BrowserAutomation
|
|
26
24
|
from pyxecm.helper import HTTP
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
from .browser_automation import BrowserAutomation
|
|
27
|
+
|
|
28
|
+
default_logger = logging.getLogger("pyxecm_customizer.m365")
|
|
29
29
|
|
|
30
30
|
request_login_headers = {
|
|
31
31
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
@@ -1297,8 +1297,7 @@ class M365:
|
|
|
1297
1297
|
|
|
1298
1298
|
try:
|
|
1299
1299
|
with open(file_path, "wb") as file:
|
|
1300
|
-
|
|
1301
|
-
file.write(chunk)
|
|
1300
|
+
file.writelines(response.iter_content(chunk_size=8192))
|
|
1302
1301
|
except OSError:
|
|
1303
1302
|
self.logger.error(
|
|
1304
1303
|
"Error saving photo for user with ID -> %s!",
|
|
@@ -2267,13 +2266,14 @@ class M365:
|
|
|
2267
2266
|
counter += 1
|
|
2268
2267
|
|
|
2269
2268
|
self.logger.info(
|
|
2270
|
-
"%s M365
|
|
2269
|
+
"%s M365 Team%s with name -> '%s' have been deleted.",
|
|
2271
2270
|
str(counter),
|
|
2271
|
+
"s" if counter > 1 else "",
|
|
2272
2272
|
name,
|
|
2273
2273
|
)
|
|
2274
2274
|
return True
|
|
2275
2275
|
else:
|
|
2276
|
-
self.logger.info("No M365
|
|
2276
|
+
self.logger.info("No M365 Team with name -> '%s' found.", name)
|
|
2277
2277
|
return False
|
|
2278
2278
|
else:
|
|
2279
2279
|
self.logger.error("Failed to retrieve M365 Teams with name -> '%s'", name)
|
|
@@ -4221,7 +4221,7 @@ class M365:
|
|
|
4221
4221
|
# Extract just the date:
|
|
4222
4222
|
latest_email_date = latest_email["receivedDateTime"].split("T")[0]
|
|
4223
4223
|
# Get the current date (today):
|
|
4224
|
-
today_date = datetime.now(
|
|
4224
|
+
today_date = datetime.now(UTC).strftime("%Y-%m-%d")
|
|
4225
4225
|
# We do a sanity check here: the verification mail should be from today,
|
|
4226
4226
|
# otherwise we assume it is an old mail and we need to wait for the
|
|
4227
4227
|
# new verification mail to yet arrive:
|
|
@@ -4256,17 +4256,23 @@ class M365:
|
|
|
4256
4256
|
return False
|
|
4257
4257
|
# Simulate a "click" on this URL:
|
|
4258
4258
|
if use_browser_automation:
|
|
4259
|
+
self.logger.info("Using browser automation for email verification...")
|
|
4259
4260
|
# Core Share needs a full browser:
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4261
|
+
try:
|
|
4262
|
+
browser_automation_object = BrowserAutomation(
|
|
4263
|
+
take_screenshots=True,
|
|
4264
|
+
automation_name="email-verification",
|
|
4265
|
+
logger=self.logger,
|
|
4266
|
+
)
|
|
4267
|
+
except Exception:
|
|
4268
|
+
self.logger.error("Failed to create browser automation object. Bailing out...")
|
|
4269
|
+
return False
|
|
4270
|
+
|
|
4265
4271
|
self.logger.info(
|
|
4266
|
-
"Open URL -> %s to verify account or email change
|
|
4272
|
+
"Open URL -> %s to verify account or email change...",
|
|
4267
4273
|
url,
|
|
4268
4274
|
)
|
|
4269
|
-
success = browser_automation_object.get_page(url)
|
|
4275
|
+
success = browser_automation_object.get_page(url=url)
|
|
4270
4276
|
if success:
|
|
4271
4277
|
user_interaction_required = False
|
|
4272
4278
|
self.logger.info(
|
|
@@ -4275,7 +4281,7 @@ class M365:
|
|
|
4275
4281
|
)
|
|
4276
4282
|
if password_field_id:
|
|
4277
4283
|
password_field = browser_automation_object.find_elem(
|
|
4278
|
-
|
|
4284
|
+
selector=password_field_id,
|
|
4279
4285
|
show_error=False,
|
|
4280
4286
|
)
|
|
4281
4287
|
if password_field:
|
|
@@ -4286,8 +4292,8 @@ class M365:
|
|
|
4286
4292
|
"Found password field on returned page - it seems email verification requests password entry!",
|
|
4287
4293
|
)
|
|
4288
4294
|
result = browser_automation_object.find_elem_and_set(
|
|
4289
|
-
|
|
4290
|
-
|
|
4295
|
+
selector=password_field_id,
|
|
4296
|
+
value=password,
|
|
4291
4297
|
is_sensitive=True,
|
|
4292
4298
|
)
|
|
4293
4299
|
if not result:
|
|
@@ -4302,7 +4308,7 @@ class M365:
|
|
|
4302
4308
|
)
|
|
4303
4309
|
if user_interaction_required and password_confirmation_field_id:
|
|
4304
4310
|
password_confirm_field = browser_automation_object.find_elem(
|
|
4305
|
-
|
|
4311
|
+
selector=password_confirmation_field_id,
|
|
4306
4312
|
show_error=False,
|
|
4307
4313
|
)
|
|
4308
4314
|
if password_confirm_field:
|
|
@@ -4310,8 +4316,8 @@ class M365:
|
|
|
4310
4316
|
"Found password confirmation field on returned page - it seems email verification requests consecutive password!",
|
|
4311
4317
|
)
|
|
4312
4318
|
result = browser_automation_object.find_elem_and_set(
|
|
4313
|
-
|
|
4314
|
-
|
|
4319
|
+
selector=password_confirmation_field_id,
|
|
4320
|
+
value=password,
|
|
4315
4321
|
is_sensitive=True,
|
|
4316
4322
|
)
|
|
4317
4323
|
if not result:
|
|
@@ -4322,19 +4328,19 @@ class M365:
|
|
|
4322
4328
|
success = False
|
|
4323
4329
|
if user_interaction_required and password_submit_xpath:
|
|
4324
4330
|
password_submit_button = browser_automation_object.find_elem(
|
|
4325
|
-
|
|
4326
|
-
|
|
4331
|
+
selector=password_submit_xpath,
|
|
4332
|
+
selector_type="xpath",
|
|
4327
4333
|
show_error=False,
|
|
4328
4334
|
)
|
|
4329
4335
|
if password_submit_button:
|
|
4330
4336
|
self.logger.info(
|
|
4331
4337
|
"Submit password change dialog with button -> '%s' (found with XPath -> %s)",
|
|
4332
|
-
password_submit_button.
|
|
4338
|
+
password_submit_button.inner_text(),
|
|
4333
4339
|
password_submit_xpath,
|
|
4334
4340
|
)
|
|
4335
4341
|
result = browser_automation_object.find_elem_and_click(
|
|
4336
|
-
|
|
4337
|
-
|
|
4342
|
+
selector=password_submit_xpath,
|
|
4343
|
+
selector_type="xpath",
|
|
4338
4344
|
)
|
|
4339
4345
|
if not result:
|
|
4340
4346
|
self.logger.error(
|
|
@@ -4346,30 +4352,32 @@ class M365:
|
|
|
4346
4352
|
# which require a short wait time. It seems it is required!
|
|
4347
4353
|
time.sleep(1)
|
|
4348
4354
|
terms_accept_button = browser_automation_object.find_elem(
|
|
4349
|
-
|
|
4350
|
-
|
|
4355
|
+
selector=terms_of_service_xpath,
|
|
4356
|
+
selector_type="xpath",
|
|
4351
4357
|
show_error=False,
|
|
4352
4358
|
)
|
|
4353
4359
|
if terms_accept_button:
|
|
4354
4360
|
self.logger.info(
|
|
4355
4361
|
"Accept terms of service with button -> '%s' (found with XPath -> %s)",
|
|
4356
|
-
terms_accept_button.
|
|
4362
|
+
terms_accept_button.inner_text(),
|
|
4357
4363
|
terms_of_service_xpath,
|
|
4358
4364
|
)
|
|
4359
4365
|
result = browser_automation_object.find_elem_and_click(
|
|
4360
|
-
|
|
4361
|
-
|
|
4366
|
+
selector=terms_of_service_xpath,
|
|
4367
|
+
selector_type="xpath",
|
|
4362
4368
|
)
|
|
4363
4369
|
if not result:
|
|
4364
4370
|
self.logger.error(
|
|
4365
4371
|
"Failed to accept terms of service with button -> '%s'",
|
|
4366
|
-
terms_accept_button.
|
|
4372
|
+
terms_accept_button.inner_text(),
|
|
4367
4373
|
)
|
|
4368
4374
|
success = False
|
|
4369
4375
|
else:
|
|
4370
4376
|
self.logger.info(
|
|
4371
4377
|
"No Terms of Service acceptance required.",
|
|
4372
4378
|
)
|
|
4379
|
+
# end if user_interaction_required and password_submit_xpath:
|
|
4380
|
+
# end if success:
|
|
4373
4381
|
# end if use_browser_automation
|
|
4374
4382
|
else:
|
|
4375
4383
|
# Salesforce (other than Core Share) is OK with the simple HTTP GET request:
|