diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/microsoft_calendar/utils/microsoft_calendar.py | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/microsoft_calendar/utils/microsoft_calendar.py')
| -rw-r--r-- | addons/microsoft_calendar/utils/microsoft_calendar.py | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/addons/microsoft_calendar/utils/microsoft_calendar.py b/addons/microsoft_calendar/utils/microsoft_calendar.py new file mode 100644 index 00000000..04029468 --- /dev/null +++ b/addons/microsoft_calendar/utils/microsoft_calendar.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import requests +import json +import logging + +from werkzeug import urls + +from odoo import api, _ +from odoo.addons.microsoft_calendar.utils.microsoft_event import MicrosoftEvent +from odoo.addons.microsoft_account.models.microsoft_service import TIMEOUT + + +_logger = logging.getLogger(__name__) + +def requires_auth_token(func): + def wrapped(self, *args, **kwargs): + if not kwargs.get('token'): + raise AttributeError("An authentication token is required") + return func(self, *args, **kwargs) + return wrapped + +class InvalidSyncToken(Exception): + pass + +class MicrosoftCalendarService(): + + def __init__(self, microsoft_service): + self.microsoft_service = microsoft_service + + @requires_auth_token + def get_events(self, sync_token=None, token=None, timeout=TIMEOUT): + url = "/v1.0/me/calendarView/delta" + headers = {'Content-type': 'application/json', 'Authorization': 'Bearer %s' % token} + params = {} + if sync_token: + params['$deltatoken'] = sync_token + else: + params['startDateTime'] = '2016-12-01T00:00:00Z' + params['endDateTime'] = '2030-1-01T00:00:00Z' + try: + status, data, time = self.microsoft_service._do_request(url, params, headers, method='GET', timeout=timeout) + except requests.HTTPError as e: + if e.response.status_code == 410 and 'fullSyncRequired' in str(e.response.content): + raise InvalidSyncToken("Invalid sync token. Full sync required") + raise e + + events = data.get('value', []) + next_page_token = data.get('@odata.nextLink') + while next_page_token: + status, data, time = self.microsoft_service._do_request(next_page_token, {}, headers, preuri='', method='GET', timeout=timeout) + next_page_token = data.get('@odata.nextLink') + events += data.get('value', []) + + next_sync_token_url = data.get('@odata.deltaLink') + next_sync_token = urls.url_parse(next_sync_token_url).decode_query().get('$deltatoken', False) + + default_reminders = data.get('defaultReminders') + + return MicrosoftEvent(events), next_sync_token, default_reminders + + @requires_auth_token + def insert(self, values, token=None, timeout=TIMEOUT): + url = "/v1.0/me/calendar/events" + headers = {'Content-type': 'application/json', 'Authorization': 'Bearer %s' % token} + if not values.get('id'): + values.pop('id', None) + status, data, time = self.microsoft_service._do_request(url, json.dumps(values), headers, method='POST', timeout=timeout) + return data['id'] + + @requires_auth_token + def patch(self, event_id, values, token=None, timeout=TIMEOUT): + url = "/v1.0/me/calendar/events/%s" % event_id + headers = {'Content-type': 'application/json', 'Authorization': 'Bearer %s' % token} + self.microsoft_service._do_request(url, json.dumps(values), headers, method='PATCH', timeout=timeout) + + @requires_auth_token + def delete(self, event_id, token=None, timeout=TIMEOUT): + url = "/v1.0/me/calendar/events/%s" % event_id + headers = {'Authorization': 'Bearer %s' % token} + params = {} + try: + self.microsoft_service._do_request(url, params, headers=headers, method='DELETE', timeout=timeout) + except requests.HTTPError as e: + # For some unknown reason Microsoft can also return a 403 response when the event is already cancelled. + if e.response.status_code not in (410, 403): + raise e + _logger.info("Microsoft event %s was already deleted" % event_id) + + ##################################### + ## MANAGE CONNEXION TO MICROSOFT ## + ##################################### + + def is_authorized(self, user): + return bool(user.sudo().microsoft_calendar_rtoken) + + def _get_calendar_scope(self): + return 'offline_access openid Calendars.ReadWrite' + + def _microsoft_authentication_url(self, from_url='http://www.odoo.com'): + return self.microsoft_service._get_authorize_uri(from_url, service='calendar', scope=self._get_calendar_scope()) + + def _can_authorize_microsoft(self, user): + return user.has_group('base.group_erp_manager') |
