wbintegrator_office365 1.55.9__py2.py3-none-any.whl → 1.56.0__py2.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.
- wbintegrator_office365/importer/api.py +5 -5
- wbintegrator_office365/models/event.py +5 -3
- wbintegrator_office365/models/subscription.py +1 -1
- wbintegrator_office365/tasks.py +77 -0
- wbintegrator_office365/tests/test_admin.py +1 -0
- wbintegrator_office365/tests/test_models.py +1 -0
- wbintegrator_office365/tests/test_tasks.py +1 -0
- wbintegrator_office365/tests/test_views.py +2 -1
- wbintegrator_office365/viewsets/viewsets.py +2 -2
- {wbintegrator_office365-1.55.9.dist-info → wbintegrator_office365-1.56.0.dist-info}/METADATA +2 -1
- {wbintegrator_office365-1.55.9.dist-info → wbintegrator_office365-1.56.0.dist-info}/RECORD +12 -12
- {wbintegrator_office365-1.55.9.dist-info → wbintegrator_office365-1.56.0.dist-info}/WHEEL +0 -0
@@ -22,7 +22,7 @@ class MicrosoftGraphAPI:
|
|
22
22
|
self.graph_url = getattr(settings, "WBINTEGRATOR_OFFICE365_GRAPH_URL", "")
|
23
23
|
|
24
24
|
global_preferences = global_preferences_registry.manager()
|
25
|
-
if global_preferences["wbintegrator_office365__access_token"] == "0":
|
25
|
+
if global_preferences["wbintegrator_office365__access_token"] == "0": # noqa
|
26
26
|
global_preferences["wbintegrator_office365__access_token"] = self._get_access_token()
|
27
27
|
|
28
28
|
def _get_administrator_consent(self):
|
@@ -385,13 +385,13 @@ class MicrosoftGraphAPI:
|
|
385
385
|
global_preferences = global_preferences_registry.manager()
|
386
386
|
headers["Authorization"] = f'Bearer {global_preferences["wbintegrator_office365__access_token"]}'
|
387
387
|
if method == "POST":
|
388
|
-
response = requests.post(url, data=data, headers=headers)
|
388
|
+
response = requests.post(url, data=data, headers=headers, timeout=10)
|
389
389
|
elif method == "DELETE":
|
390
|
-
response = requests.delete(url, headers=headers)
|
390
|
+
response = requests.delete(url, headers=headers, timeout=10)
|
391
391
|
elif method == "PATCH":
|
392
|
-
response = requests.patch(url, data=data, headers=headers)
|
392
|
+
response = requests.patch(url, data=data, headers=headers, timeout=10)
|
393
393
|
else:
|
394
|
-
response = requests.get(url, headers=headers, params=params)
|
394
|
+
response = requests.get(url, headers=headers, params=params, timeout=10)
|
395
395
|
if response.status_code == status.HTTP_401_UNAUTHORIZED:
|
396
396
|
new_token = self._get_access_token()
|
397
397
|
if new_token != global_preferences["wbintegrator_office365__access_token"]:
|
@@ -94,7 +94,7 @@ class Event(WBModel):
|
|
94
94
|
)
|
95
95
|
|
96
96
|
@classmethod
|
97
|
-
def get_endpoint_basename(
|
97
|
+
def get_endpoint_basename(cls):
|
98
98
|
return "wbintegrator_office365:event"
|
99
99
|
|
100
100
|
@classmethod
|
@@ -254,7 +254,7 @@ class EventLog(WBModel):
|
|
254
254
|
data = models.JSONField(default=dict, null=True, blank=True)
|
255
255
|
|
256
256
|
@classmethod
|
257
|
-
def get_endpoint_basename(
|
257
|
+
def get_endpoint_basename(cls):
|
258
258
|
return "wbintegrator_office365:eventlog"
|
259
259
|
|
260
260
|
@classmethod
|
@@ -301,8 +301,10 @@ class CallUser(WBModel):
|
|
301
301
|
contacts = TelephoneContact.objects.filter(number=self.tenant_user.tenant_id, entry__isnull=False)
|
302
302
|
if contacts.exists():
|
303
303
|
return str(contacts.first().entry)
|
304
|
-
elif self.tenant_user.tenant_id[0] == "+":
|
304
|
+
elif self.tenant_user.tenant_id and self.tenant_user.tenant_id[0] == "+":
|
305
305
|
return self.tenant_user.tenant_id
|
306
|
+
else:
|
307
|
+
return self.tenant_user.display_name
|
306
308
|
|
307
309
|
def __str__(self):
|
308
310
|
if repr := self.get_humanized_repr():
|
wbintegrator_office365/tasks.py
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
import os
|
2
|
+
from collections import defaultdict
|
1
3
|
from datetime import date, timedelta
|
2
4
|
|
5
|
+
import boto3
|
3
6
|
import humanize
|
4
7
|
from celery import shared_task
|
5
8
|
from django.contrib.auth import get_user_model
|
@@ -23,6 +26,65 @@ def format_td(td: timedelta) -> str:
|
|
23
26
|
return humanize.precisedelta(td, suppress=["hours"], minimum_unit="seconds", format="%0.0f")
|
24
27
|
|
25
28
|
|
29
|
+
#################################################
|
30
|
+
################# TEMPORARY #####################
|
31
|
+
#################################################
|
32
|
+
|
33
|
+
|
34
|
+
def convert_user(user):
|
35
|
+
email = user["Attributes"][0]["Value"]
|
36
|
+
first = user["Attributes"][3]["Value"]
|
37
|
+
last = user["Attributes"][2]["Value"]
|
38
|
+
|
39
|
+
return f"{email} ({first} {last})"
|
40
|
+
|
41
|
+
|
42
|
+
def get_fundy_users():
|
43
|
+
access_key = os.environ["FUNDY_BOTO_ACCESS_KEY"]
|
44
|
+
secret_access_key = os.environ["FUNDY_BOTO_SECRET_ACCESS_KEY"]
|
45
|
+
|
46
|
+
client = boto3.client(
|
47
|
+
"cognito-idp", region_name="eu-north-1", aws_access_key_id=access_key, aws_secret_access_key=secret_access_key
|
48
|
+
)
|
49
|
+
|
50
|
+
pagination_token = None
|
51
|
+
users = []
|
52
|
+
while True:
|
53
|
+
if not pagination_token:
|
54
|
+
response = client.list_users(
|
55
|
+
UserPoolId="eu-north-1_IFRQriJAf",
|
56
|
+
)
|
57
|
+
else:
|
58
|
+
response = client.list_users(
|
59
|
+
UserPoolId="eu-north-1_IFRQriJAf",
|
60
|
+
PaginationToken=pagination_token,
|
61
|
+
)
|
62
|
+
|
63
|
+
users.extend(response["Users"])
|
64
|
+
if response.get("PaginationToken", None) is None:
|
65
|
+
break
|
66
|
+
else:
|
67
|
+
pagination_token = response["PaginationToken"]
|
68
|
+
|
69
|
+
users_date = defaultdict(list)
|
70
|
+
for user in sorted(users, key=lambda x: x["UserCreateDate"]):
|
71
|
+
users_date[user["UserCreateDate"].date()].append(convert_user(user))
|
72
|
+
return users_date, len(users)
|
73
|
+
|
74
|
+
|
75
|
+
def get_fundy_user_statistics():
|
76
|
+
today = date.today()
|
77
|
+
users, total_users = get_fundy_users()
|
78
|
+
|
79
|
+
yesterday_users = users.get(today - timedelta(days=1), [])
|
80
|
+
return yesterday_users, len(yesterday_users), total_users
|
81
|
+
|
82
|
+
|
83
|
+
#################################################
|
84
|
+
################ TEMPORARY END ##################
|
85
|
+
#################################################
|
86
|
+
|
87
|
+
|
26
88
|
@shared_task
|
27
89
|
def send_call_summary(
|
28
90
|
to_emails: list,
|
@@ -109,6 +171,21 @@ def send_call_summary(
|
|
109
171
|
message += "</table><br/>"
|
110
172
|
|
111
173
|
message += "</div>"
|
174
|
+
|
175
|
+
######## TEMPORARY START ########
|
176
|
+
yesterday_users, yesterday_users_count, total_users_count = get_fundy_user_statistics()
|
177
|
+
message += f"""
|
178
|
+
<div>
|
179
|
+
<h3>FUNDY USER STATISTICS</h3>
|
180
|
+
<strong>Yesterday Users:</strong> {yesterday_users_count}
|
181
|
+
<strong>Total Users:</strong> {total_users_count}
|
182
|
+
<ul>
|
183
|
+
"""
|
184
|
+
for user in yesterday_users:
|
185
|
+
message += f"<li>{user}</li>"
|
186
|
+
message += "</ul></div>"
|
187
|
+
######## TEMPORARY END ########
|
188
|
+
|
112
189
|
title = f"Call summary - {date_repr}"
|
113
190
|
if include_detail:
|
114
191
|
title = "Detailed " + title
|
@@ -6,6 +6,7 @@ from django.contrib.messages import get_messages, storage
|
|
6
6
|
from rest_framework import status
|
7
7
|
from rest_framework.test import APIRequestFactory
|
8
8
|
from wbcore.test.utils import get_or_create_superuser
|
9
|
+
|
9
10
|
from wbintegrator_office365.admin import SubscriptionAdmin, TenantUserAdmin
|
10
11
|
from wbintegrator_office365.factories import TenantUserFactory
|
11
12
|
from wbintegrator_office365.models import Subscription, TenantUser
|
@@ -6,6 +6,7 @@ import phonenumbers
|
|
6
6
|
import pytest
|
7
7
|
from rest_framework import status
|
8
8
|
from wbcore.contrib.directory.factories import TelephoneContactFactory
|
9
|
+
|
9
10
|
from wbintegrator_office365.factories import SubscriptionFactory, TenantUserFactory
|
10
11
|
from wbintegrator_office365.importer import parse
|
11
12
|
from wbintegrator_office365.models import CallEvent, Subscription
|
@@ -7,6 +7,7 @@ from rest_framework.test import APIRequestFactory
|
|
7
7
|
from wbcore.contrib.authentication.factories import InternalUserFactory
|
8
8
|
from wbcore.test.utils import get_or_create_superuser
|
9
9
|
from wbhuman_resources.factories import EmployeeHumanResourceFactory
|
10
|
+
|
10
11
|
from wbintegrator_office365.factories import CallEventFactory, CallUserFactory
|
11
12
|
from wbintegrator_office365.viewsets.viewsets import (
|
12
13
|
CallEventReceptionTime,
|
@@ -63,7 +64,7 @@ class TestView:
|
|
63
64
|
)
|
64
65
|
@patch("wbintegrator_office365.importer.MicrosoftGraphAPI._get_access_token")
|
65
66
|
@patch("wbintegrator_office365.importer.MicrosoftGraphAPI.users")
|
66
|
-
def
|
67
|
+
def test_get_plotly_calleventsummarygraph(self, mock_users, mock_acess, mvs, factory, empty_compare_employee):
|
67
68
|
request = APIRequestFactory().get("")
|
68
69
|
request.user = get_or_create_superuser()
|
69
70
|
|
@@ -445,7 +445,7 @@ class CallEventSummaryGraph(viewsets.ChartViewSet):
|
|
445
445
|
df = df.sort_values(by=["day"]).reset_index()
|
446
446
|
return df
|
447
447
|
|
448
|
-
def get_plotly(self, queryset):
|
448
|
+
def get_plotly(self, queryset): # noqa: C901
|
449
449
|
fig = go.Figure()
|
450
450
|
if queryset.exists():
|
451
451
|
df = pd.DataFrame(queryset.annotate(day=F("created__date")).values("start", "end", "day"))
|
@@ -740,5 +740,5 @@ def listen(request):
|
|
740
740
|
for notification in notifications:
|
741
741
|
# print(colored(f"{timezone.now():%Y-%m-%d %H:%M:%S.%f} {notification}", 'blue'))
|
742
742
|
if (resource_data := notification.get("resource_data")) and (id_event := resource_data.get("id")):
|
743
|
-
transaction.on_commit(lambda: handle_event_from_webhook.delay(id_event,
|
743
|
+
transaction.on_commit(lambda obj=notification: handle_event_from_webhook.delay(id_event, obj))
|
744
744
|
return HttpResponse(notifications, content_type="text/plain")
|
{wbintegrator_office365-1.55.9.dist-info → wbintegrator_office365-1.56.0.dist-info}/METADATA
RENAMED
@@ -1,7 +1,8 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: wbintegrator_office365
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.56.0
|
4
4
|
Author-email: Christopher Wittlinger <c.wittlinger@stainly.com>
|
5
|
+
Requires-Dist: boto3>=1.35.99
|
5
6
|
Requires-Dist: bs4==0.0.*
|
6
7
|
Requires-Dist: oauthlib==3.1.*
|
7
8
|
Requires-Dist: requests-oauthlib==1.3.*
|
@@ -5,12 +5,12 @@ wbintegrator_office365/dynamic_preferences_registry.py,sha256=RIptl8WGibV_XMynXl
|
|
5
5
|
wbintegrator_office365/factories.py,sha256=pG8moGurbSElIugs_Gz3nd7-UJt3vC6mGy-EZQIeldI,3872
|
6
6
|
wbintegrator_office365/filters.py,sha256=bSX1jrP1SrqiGkysoX__AqPRUPSU-uQq_-tOHinqijU,7447
|
7
7
|
wbintegrator_office365/serializers.py,sha256=tR_HdsyxwCZo2_sOdhj2NErOEjTRyoIXA6DRR-BjVKs,8097
|
8
|
-
wbintegrator_office365/tasks.py,sha256
|
8
|
+
wbintegrator_office365/tasks.py,sha256=-kji2Bipo95nP4UWWfRi4JrW2-Hn8AXv4KiM-oQYsyU,10176
|
9
9
|
wbintegrator_office365/urls.py,sha256=qfIIb3CNJw40xhGJnE7ztEMt2l-kgnRXA_P8Y3sDlPg,1922
|
10
10
|
wbintegrator_office365/configurations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
11
|
wbintegrator_office365/configurations/configurations/__init__.py,sha256=tIBWiG0KWrDJ1xtKe5m1W9aKX5PMNLwsYuoy7xrQ4uI,1145
|
12
12
|
wbintegrator_office365/importer/__init__.py,sha256=gNaDqAZV8afLM7yOHtGa8uQGvSMhajEQcLJyd5PejyY,105
|
13
|
-
wbintegrator_office365/importer/api.py,sha256=
|
13
|
+
wbintegrator_office365/importer/api.py,sha256=W6URWPYPkEuU8ZEnNdeYBssWQi54wfuiniePloB_Mik,20067
|
14
14
|
wbintegrator_office365/importer/disable_signals.py,sha256=d7vsELREUeUkrmGFMYICbvcKKrKTWhm_BEOZuPuXbAc,1090
|
15
15
|
wbintegrator_office365/importer/parser.py,sha256=6tkr9Z30SkBzm4989JONXcL8dnONf0PJIgnYlKrispU,5905
|
16
16
|
wbintegrator_office365/kpi_handlers/__init__.py,sha256=C93QmjQfQHw9L5ohR877l7zRFkYZ21PnjbCF2eVntxU,35
|
@@ -20,23 +20,23 @@ wbintegrator_office365/migrations/0002_remove_calendar_owner_remove_calendareven
|
|
20
20
|
wbintegrator_office365/migrations/0003_alter_event_options.py,sha256=rUYPQdwEuJowo10veLOZPtV3WMqxJu8_uan600EcpN4,585
|
21
21
|
wbintegrator_office365/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
22
|
wbintegrator_office365/models/__init__.py,sha256=sZKutR9oNMm2IaON35doaMVPgeMfxmWDqoAdALHRLIA,126
|
23
|
-
wbintegrator_office365/models/event.py,sha256=
|
24
|
-
wbintegrator_office365/models/subscription.py,sha256=
|
23
|
+
wbintegrator_office365/models/event.py,sha256=tw9GaCrNieQ9KRDFcMVoobwjYBZObTkTmgldVtwcLCY,27110
|
24
|
+
wbintegrator_office365/models/subscription.py,sha256=ynp74wjd8OFRrnkomGl7pc8OyXRRvdHyl36TzHiCVSM,6423
|
25
25
|
wbintegrator_office365/models/tenant.py,sha256=-FS6jg9nt8IgUv_729D92QFvrrbKleBUGnXhwaLv5Sc,2357
|
26
26
|
wbintegrator_office365/templates/admin/tenant_change_list.html,sha256=mI4C1ZmTkl5MdN4CgoIWgCziSReqlHiK71aI7zJpVEM,358
|
27
27
|
wbintegrator_office365/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
28
28
|
wbintegrator_office365/tests/conftest.py,sha256=5R2mRq3sdVEDEaQx2n6CrCwQtUm5WdYC_rKJ9Gs_iOQ,971
|
29
|
-
wbintegrator_office365/tests/test_admin.py,sha256=
|
30
|
-
wbintegrator_office365/tests/test_models.py,sha256=
|
31
|
-
wbintegrator_office365/tests/test_tasks.py,sha256=
|
32
|
-
wbintegrator_office365/tests/test_views.py,sha256=
|
29
|
+
wbintegrator_office365/tests/test_admin.py,sha256=wAC1JEWrWrlgFsG1xKbkm-OpRHo4ojDvNKeQ9ydiCeM,3485
|
30
|
+
wbintegrator_office365/tests/test_models.py,sha256=AvdEESUBpCFdUfphkR8fIjX-NBlZ8iCQbOtn-eLL-HY,2396
|
31
|
+
wbintegrator_office365/tests/test_tasks.py,sha256=eEv4GWUMmN9wXGXukmVfShDCCckt_Eg0uQ1F38p8Avw,12566
|
32
|
+
wbintegrator_office365/tests/test_views.py,sha256=FG7N2FbYVUtIS1Crk6JEOzNi0dzKT0yOVctBuFz5tJI,5327
|
33
33
|
wbintegrator_office365/tests/tests.py,sha256=HS3gXIgob9Rpx8Tn7p58nuan4LAvEJwGs9fhq9pDKu8,296
|
34
34
|
wbintegrator_office365/viewsets/__init__.py,sha256=8P6rwxciuMFbxHwlb6nbNODQIP_OeTLxX2UnJAzYNi4,889
|
35
35
|
wbintegrator_office365/viewsets/display.py,sha256=TS1fZCHFUb9XUNlXT1EO_7HE_lUsB1EgB6bQdsSX5sQ,12306
|
36
36
|
wbintegrator_office365/viewsets/endpoints.py,sha256=NxEdH-tKk87mJdSNxpOZdN2z0AhYY_1ob_zcHgPOAXQ,1969
|
37
37
|
wbintegrator_office365/viewsets/menu.py,sha256=hafwoiHZmN3ltf30dTfwHreDwhyfdHlGOQk8bB7jB_o,2406
|
38
38
|
wbintegrator_office365/viewsets/titles.py,sha256=9GZ_fqN9-sJzYHFvibOhNrRQQMNTh_m4eAv66VaGzDM,1214
|
39
|
-
wbintegrator_office365/viewsets/viewsets.py,sha256=
|
40
|
-
wbintegrator_office365-1.
|
41
|
-
wbintegrator_office365-1.
|
42
|
-
wbintegrator_office365-1.
|
39
|
+
wbintegrator_office365/viewsets/viewsets.py,sha256=Mu6loE9ICDYEhWZNURsbdFj8ofdz4qZUSVStydQ7pW4,26353
|
40
|
+
wbintegrator_office365-1.56.0.dist-info/METADATA,sha256=jolMzMRl6DokyPGO0Ll2D2QIEN8SPFcUxhpBwysku-M,334
|
41
|
+
wbintegrator_office365-1.56.0.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
|
42
|
+
wbintegrator_office365-1.56.0.dist-info/RECORD,,
|
File without changes
|