Skip to content

Commit 597cc03

Browse files
author
Eric Mugnier
committed
Merge branch 'master' of https://github.com/yeyeric/python-o365
2 parents c0cf76b + 7929cae commit 597cc03

File tree

9 files changed

+154
-9
lines changed

9 files changed

+154
-9
lines changed

CHANGES.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
Almost every release features a lot of bugfixes but those are not listed here.
44

55

6+
## Version 2.0.26 (2023-02-02)
7+
8+
###Features:
9+
- Connection now allows setting default headers (Thanks @yeyeric)
10+
- Now it's possible to request inmutable Ids to the MS Graph protocol (Thanks @yeyeric and @NielsDebrier)
11+
- Added more Well Known Folder Names (Thanks @ponquersohn)
12+
13+
614
## Version 2.0.25 (2023-01-13)
715

816
###Features:

O365/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '2.0.25'
1+
__version__ = '2.0.26'

O365/calendar.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,6 +1613,10 @@ def __init__(self, *, parent=None, con=None, **kwargs):
16131613
self.can_share = cloud_data.get(self._cc('canShare'), False)
16141614
self.can_view_private_items = cloud_data.get(
16151615
self._cc('canViewPrivateItems'), False)
1616+
1617+
# Hex color only returns a value when a custom calandar is set
1618+
# Hex color is read-only, cannot be used to set calendar's color
1619+
self.hex_color = cloud_data.get(self._cc('hexColor'), None)
16161620

16171621
def __str__(self):
16181622
return self.__repr__()

O365/excel.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,9 +1393,9 @@ def update(self, *, name=None, show_headers=None, show_totals=None, style=None):
13931393
data = {}
13941394
if name:
13951395
data['name'] = name
1396-
if show_headers:
1396+
if show_headers is not None:
13971397
data['showHeaders'] = show_headers
1398-
if show_totals:
1398+
if show_totals is not None:
13991399
data['showTotals'] = show_totals
14001400
if style:
14011401
data['style'] = style

O365/mailbox.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,116 @@ def archive_folder(self):
914914
folder_id=OutlookWellKnowFolderNames.ARCHIVE.value,
915915
)
916916

917+
def clutter_folder(self):
918+
"""Shortcut to get Clutter Folder instance
919+
The clutter folder low-priority messages are moved to when using the Clutter feature.
920+
921+
:rtype: mailbox.Folder
922+
"""
923+
return self.folder_constructor(
924+
parent=self,
925+
name="Clutter",
926+
folder_id=OutlookWellKnowFolderNames.CLUTTER.value,
927+
)
928+
929+
def conflicts_folder(self):
930+
"""Shortcut to get Conflicts Folder instance
931+
The folder that contains conflicting items in the mailbox.
932+
933+
:rtype: mailbox.Folder
934+
"""
935+
return self.folder_constructor(
936+
parent=self,
937+
name="Conflicts",
938+
folder_id=OutlookWellKnowFolderNames.CONFLICTS.value,
939+
)
940+
941+
def conversationhistory_folder(self):
942+
"""Shortcut to get Conversation History Folder instance
943+
The folder where Skype saves IM conversations (if Skype is configured to do so).
944+
945+
:rtype: mailbox.Folder
946+
"""
947+
return self.folder_constructor(
948+
parent=self,
949+
name="Conflicts",
950+
folder_id=OutlookWellKnowFolderNames.CONVERSATIONHISTORY.value,
951+
)
952+
953+
def localfailures_folder(self):
954+
"""Shortcut to get Local Failure Folder instance
955+
The folder that contains items that exist on the local client but could not be uploaded to the server.
956+
957+
:rtype: mailbox.Folder
958+
"""
959+
return self.folder_constructor(
960+
parent=self,
961+
name="Local Failures",
962+
folder_id=OutlookWellKnowFolderNames.LOCALFAILURES.value,
963+
)
964+
965+
def recoverableitemsdeletions_folder(self):
966+
"""Shortcut to get Recoverable Items Deletions (Purges) Folder instance
967+
The folder that contains soft-deleted items: deleted either from the Deleted Items folder, or by pressing shift+delete in Outlook.
968+
This folder is not visible in any Outlook email client,
969+
but end users can interact with it through the Recover Deleted Items from Server feature in Outlook or Outlook on the web.
970+
971+
:rtype: mailbox.Folder
972+
"""
973+
return self.folder_constructor(
974+
parent=self,
975+
name="Recoverable Items Deletions (Purges)",
976+
folder_id=OutlookWellKnowFolderNames.RECOVERABLEITEMSDELETIONS.value,
977+
)
978+
979+
def scheduled_folder(self):
980+
"""Shortcut to get Scheduled Folder instance
981+
The folder that contains messages that are scheduled to reappear in the inbox using the Schedule feature in Outlook for iOS.
982+
983+
:rtype: mailbox.Folder
984+
"""
985+
return self.folder_constructor(
986+
parent=self,
987+
name="Scheduled",
988+
folder_id=OutlookWellKnowFolderNames.SCHEDULED.value,
989+
)
990+
991+
def searchfolders_folder(self):
992+
"""Shortcut to get Search Folders Folder instance
993+
The parent folder for all search folders defined in the user's mailbox.
994+
995+
:rtype: mailbox.Folder
996+
"""
997+
return self.folder_constructor(
998+
parent=self,
999+
name="Search Folders",
1000+
folder_id=OutlookWellKnowFolderNames.SEARCHFOLDERS.value,
1001+
)
1002+
1003+
def serverfailures_folder(self):
1004+
"""Shortcut to get Server Failures Folder instance
1005+
The folder that contains items that exist on the server but could not be synchronized to the local client.
1006+
1007+
:rtype: mailbox.Folder
1008+
"""
1009+
return self.folder_constructor(
1010+
parent=self,
1011+
name="Server Failures",
1012+
folder_id=OutlookWellKnowFolderNames.SERVERFAILURES.value,
1013+
)
1014+
1015+
def syncissues_folder(self):
1016+
"""Shortcut to get Sync Issues Folder instance
1017+
The folder that contains synchronization logs created by Outlook.
1018+
1019+
:rtype: mailbox.Folder
1020+
"""
1021+
return self.folder_constructor(
1022+
parent=self,
1023+
name="Sync Issues",
1024+
folder_id=OutlookWellKnowFolderNames.SYNCISSUES.value,
1025+
)
1026+
9171027
def get_settings(self):
9181028
"""Return the MailboxSettings.
9191029
@@ -934,3 +1044,4 @@ def get_settings(self):
9341044
return self.mailbox_settings_constructor(
9351045
parent=self, **{self._cloud_data_key: data}
9361046
)
1047+

O365/utils/utils.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@ class OutlookWellKnowFolderNames(Enum):
5555
SENT = 'SentItems'
5656
OUTBOX = 'Outbox'
5757
ARCHIVE = 'Archive'
58+
CLUTTER='clutter'
59+
CONFLICTS='conflicts'
60+
CONVERSATIONHISTORY='conversationhistory'
61+
LOCALFAILURES='localfailures'
62+
RECOVERABLEITEMSDELETIONS='recoverableitemsdeletions'
63+
SCHEDULED='scheduled'
64+
SEARCHFOLDERS='searchfolders'
65+
SERVERFAILURES='serverfailures'
66+
SYNCISSUES='syncissues'
67+
5868

5969

6070
class OneDriveWellKnowFolderNames(Enum):

O365/utils/windows_tz.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@
453453
"Europe/Istanbul": "Turkey Standard Time",
454454
"Europe/Jersey": "GMT Standard Time",
455455
"Europe/Kaliningrad": "Kaliningrad Standard Time",
456-
"Europe/Kiev": "FLE Standard Time",
456+
"Europe/Kyiv": "FLE Standard Time",
457457
"Europe/Kirov": "Russian Standard Time",
458458
"Europe/Lisbon": "GMT Standard Time",
459459
"Europe/Ljubljana": "Central European Standard Time",

README.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ When to use one or the other and requirements:
153153
**Authentication** | 2 step authentication with user consent | 2 step authentication with user consent | 1 step authentication
154154
**Auth Scopes** | Required | Required | None
155155
**Token Expiration** | 60 Minutes without refresh token or 90 days* | 60 Minutes without refresh token or 90 days* | 60 Minutes*
156-
**Login Expiration** | Unlimited if there is a refresh token and as long as a re| Unlimited if there is a refresh token and as long as a refresh is done within the 90 days | Unlimited
156+
**Login Expiration** | Unlimited if there is a refresh token and as long as a refresh is done within the 90 days | Unlimited if there is a refresh token and as long as a refresh is done within the 90 days | Unlimited
157157
**Resources** | Access the user resources, and any shared resources | Access the user resources, and any shared resources | All Azure AD users the app has access to
158158
**Microsoft Account Type** | Any | Any | Not Allowed for Personal Accounts
159159
**Tenant ID Required** | Defaults to "common" | Defaults to "common" | Required (can't be "common")
@@ -290,10 +290,15 @@ For the "with your own identity" authentication method, you can just use `accoun
290290

291291
The following example is done using Flask.
292292
```python
293+
from flask import request
294+
from O365 import Account
295+
296+
293297
@route('/stepone')
294298
def auth_step_one():
299+
# callback = absolute url to auth_step_two_callback() page, https://domain.tld/steptwo
300+
callback = url_for('auth_step_two_callback', _external=True) # Flask example
295301

296-
callback = 'my absolute url to auth_step_two_callback'
297302
account = Account(credentials)
298303
url, state = account.con.get_authorization_url(requested_scopes=my_scopes,
299304
redirect_uri=callback)
@@ -313,7 +318,11 @@ For the "with your own identity" authentication method, you can just use `accoun
313318
# rebuild the redirect_uri used in auth_step_one
314319
callback = 'my absolute url to auth_step_two_callback'
315320

316-
result = account.con.request_token(request.url,
321+
# get the request URL of the page which will include additional auth information
322+
# Example request: /steptwo?code=abc123&state=xyz456
323+
requested_url = request.url # uses Flask's request() method
324+
325+
result = account.con.request_token(requested_url,
317326
state=my_saved_state,
318327
redirect_uri=callback)
319328
# if result is True, then authentication was succesful
@@ -440,9 +449,12 @@ Methods that stores tokens:
440449

441450
To store the token you will have to provide a properly configured TokenBackend.
442451

443-
Actually there are only two implemented (but you can easely implement more like a CookieBackend, RedisBackend, etc.):
452+
There are a few `TokenBackend` classes implemented (and you can easily implement more like a CookieBackend, RedisBackend, etc.):
444453
- `FileSystemTokenBackend` (Default backend): Stores and retrieves tokens from the file system. Tokens are stored as files.
454+
- `EnvTokenBackend`: Stores and retrieves tokens from environment variables.
445455
- `FirestoreTokenBackend`: Stores and retrives tokens from a Google Firestore Datastore. Tokens are stored as documents within a collection.
456+
- `AWSS3Backend`: Stores and retrieves tokens from an AWS S3 bucket. Tokens are stored as a file within a S3 bucket.
457+
- `AWSSecretsBackend`: Stores and retrieves tokens from an AWS Secrets Management vault.
446458

447459
For example using the FileSystem Token Backend:
448460

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from setuptools import setup, find_packages
44

55

6-
VERSION = '2.0.25'
6+
VERSION = '2.0.26'
77

88
# Available classifiers: https://pypi.org/pypi?%3Aaction=list_classifiers
99
CLASSIFIERS = [

0 commit comments

Comments
 (0)