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.
@@ -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(self):
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(self):
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():
@@ -59,7 +59,7 @@ class Subscription(WBModel):
59
59
  )
60
60
 
61
61
  @classmethod
62
- def get_endpoint_basename(self):
62
+ def get_endpoint_basename(cls):
63
63
  return "wbintegrator_office365:subscription"
64
64
 
65
65
  @classmethod
@@ -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
@@ -1,6 +1,7 @@
1
1
  from unittest.mock import patch
2
2
 
3
3
  import pytest
4
+
4
5
  from wbintegrator_office365.factories import EventFactory, SubscriptionFactory
5
6
  from wbintegrator_office365.importer import DisableSignals
6
7
  from wbintegrator_office365.models import (
@@ -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 test_get_plotly_CallEventSummaryGraph(self, mock_users, mock_acess, mvs, factory, empty_compare_employee):
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, notification))
743
+ transaction.on_commit(lambda obj=notification: handle_event_from_webhook.delay(id_event, obj))
744
744
  return HttpResponse(notifications, content_type="text/plain")
@@ -1,7 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wbintegrator_office365
3
- Version: 1.55.9
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=gley52lfXrOQUCz3L3NN3OGp5L7_sBVI2PtdxWDQBnE,7800
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=F0Ed8EZGq3-Y0gN95KQ-h6nFbg4U0HC-ObJ-S267hm8,20011
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=5mKpTheP8UpUlLF_eFujfNDlsYjjbdwwdH5fB3Tg8Rg,27002
24
- wbintegrator_office365/models/subscription.py,sha256=EnesSa2OnuygsyfXXY8ABYOjgOaUv9Jj3c6OVQOPWyU,6424
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=MP_RRfHdVi9_D3-jUC05HvS-jabZHSIofr4MX41ADYY,3484
30
- wbintegrator_office365/tests/test_models.py,sha256=mM_ti0XeOoyNz25Fb_R9LjIVscnUZTYJVWTmw6MGbM4,2395
31
- wbintegrator_office365/tests/test_tasks.py,sha256=qrzXTjlH52gssyrsyNY1vMmfJMCUqgS6hQeZROsalE4,12565
32
- wbintegrator_office365/tests/test_views.py,sha256=istI7h751mEt_roslIiR5qqfqDI8Sj-L2Cgd_8gKMAQ,5326
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=T9u8vViyeHrK1xzPbQqIKXgpf4qM-5KkPzbZGdLLujA,26331
40
- wbintegrator_office365-1.55.9.dist-info/METADATA,sha256=r1S2oYzBT5I58UlYgqKT9DDOtbBKnaGZplJHdAUMotc,304
41
- wbintegrator_office365-1.55.9.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
42
- wbintegrator_office365-1.55.9.dist-info/RECORD,,
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,,