Office365-REST-Python-Client 2.5.6__py3-none-any.whl → 2.5.7__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.
- {Office365_REST_Python_Client-2.5.6.dist-info → Office365_REST_Python_Client-2.5.7.dist-info}/METADATA +5 -5
- {Office365_REST_Python_Client-2.5.6.dist-info → Office365_REST_Python_Client-2.5.7.dist-info}/RECORD +85 -58
- office365/directory/administrative_unit.py +9 -2
- office365/directory/applications/roles/collection.py +5 -1
- office365/directory/applications/roles/role.py +1 -1
- office365/directory/audit/provisioning/object_summary.py +30 -1
- office365/directory/authentication/methods/fido.py +8 -0
- office365/directory/authentication/methods/password.py +23 -0
- office365/directory/custom_security_attribute_definition.py +7 -0
- office365/directory/device_local_credential_info.py +6 -0
- office365/directory/directory.py +40 -12
- office365/directory/identitygovernance/appconsent/request_collection.py +1 -1
- office365/directory/identitygovernance/termsofuse/agreement_acceptance.py +8 -0
- office365/directory/identitygovernance/userconsent/request_collection.py +1 -1
- office365/directory/insights/resource_reference.py +1 -1
- office365/directory/policies/device_registration.py +6 -0
- office365/directory/policies/root.py +13 -0
- office365/directory/security/threatintelligence/article_indicator.py +7 -0
- office365/directory/serviceprincipals/service_principal.py +3 -8
- office365/directory/synchronization/schema.py +16 -0
- office365/directory/users/user.py +23 -0
- office365/onedrive/driveitems/driveItem.py +74 -6
- office365/onedrive/lists/list.py +1 -1
- office365/onedrive/sitepages/__init__.py +0 -0
- office365/onedrive/sitepages/base.py +29 -0
- office365/onedrive/sitepages/canvas_layout.py +43 -0
- office365/onedrive/sitepages/collection.py +32 -0
- office365/onedrive/sitepages/horizontal_section.py +23 -0
- office365/onedrive/sitepages/horizontal_section_column.py +27 -0
- office365/onedrive/sitepages/site_page.py +116 -0
- office365/onedrive/sitepages/title_area.py +13 -0
- office365/onedrive/sitepages/vertical_section.py +27 -0
- office365/onedrive/sitepages/web_part.py +5 -0
- office365/onedrive/sites/site.py +10 -0
- office365/onedrive/workbooks/charts/data_labels.py +13 -1
- office365/onedrive/workbooks/tables/sort.py +5 -0
- office365/onedrive/workbooks/tables/table.py +57 -0
- office365/onedrive/workbooks/worksheets/protection.py +20 -1
- office365/onedrive/workbooks/worksheets/protection_options.py +7 -0
- office365/outlook/calendar/calendar.py +1 -3
- office365/outlook/calendar/events/event.py +45 -0
- office365/outlook/calendar/response_status.py +11 -0
- office365/outlook/calendar/rooms/room.py +14 -0
- office365/outlook/mail/automatic_replies_mailtips.py +5 -0
- office365/outlook/mail/conversation.py +1 -3
- office365/outlook/mail/folders/folder.py +1 -3
- office365/outlook/mail/tips.py +17 -0
- office365/planner/plans/plan.py +11 -1
- office365/reports/root.py +33 -0
- office365/runtime/auth/authentication_context.py +12 -2
- office365/runtime/odata/json_format.py +3 -2
- office365/runtime/odata/request.py +12 -2
- office365/runtime/queries/upload_session.py +5 -0
- office365/sharepoint/alerts/collection.py +2 -1
- office365/sharepoint/attachments/attachment.py +3 -9
- office365/sharepoint/client_context.py +4 -2
- office365/sharepoint/contenttypes/content_type.py +13 -1
- office365/sharepoint/contenttypes/fieldlinks/collection.py +1 -1
- office365/sharepoint/directory/helper.py +2 -0
- office365/sharepoint/fields/collection.py +4 -3
- office365/sharepoint/folders/folder.py +1 -3
- office365/sharepoint/migrationcenter/deploy_status.py +5 -0
- office365/sharepoint/migrationcenter/service/performance/__init__.py +0 -0
- office365/sharepoint/migrationcenter/service/performance/dashboard_data.py +9 -0
- office365/sharepoint/migrationcenter/service/performance/data.py +7 -0
- office365/sharepoint/migrationcenter/service/performance/entity_data.py +5 -0
- office365/sharepoint/principal/principal.py +2 -4
- office365/sharepoint/recyclebin/item.py +107 -7
- office365/sharepoint/sharing/information.py +9 -0
- office365/sharepoint/sharing/link_info.py +6 -0
- office365/sharepoint/sharing/permission_collection.py +18 -0
- office365/sharepoint/sites/script_safe_domain.py +5 -0
- office365/sharepoint/sites/site.py +10 -4
- office365/sharepoint/taxonomy/field_value.py +1 -1
- office365/sharepoint/tenant/administration/powerapps/__init__.py +0 -0
- office365/sharepoint/tenant/administration/powerapps/environment_context.py +8 -0
- office365/sharepoint/webs/information_collection.py +1 -1
- office365/sharepoint/webs/regional_settings.py +71 -0
- office365/sharepoint/webs/web.py +10 -5
- office365/teams/apps/catalog.py +1 -0
- office365/teams/chats/chat.py +4 -0
- office365/teams/schedule/schedule.py +6 -2
- {Office365_REST_Python_Client-2.5.6.dist-info → Office365_REST_Python_Client-2.5.7.dist-info}/LICENSE +0 -0
- {Office365_REST_Python_Client-2.5.6.dist-info → Office365_REST_Python_Client-2.5.7.dist-info}/WHEEL +0 -0
- {Office365_REST_Python_Client-2.5.6.dist-info → Office365_REST_Python_Client-2.5.7.dist-info}/top_level.txt +0 -0
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
1
4
|
from office365.directory.audit.provisioning.service_principal import (
|
|
2
5
|
ProvisioningServicePrincipal,
|
|
3
6
|
)
|
|
@@ -7,6 +10,29 @@ from office365.entity import Entity
|
|
|
7
10
|
class ProvisioningObjectSummary(Entity):
|
|
8
11
|
"""Represents an action performed by the Azure AD Provisioning service and its associated properties."""
|
|
9
12
|
|
|
13
|
+
@property
|
|
14
|
+
def activity_datetime(self):
|
|
15
|
+
"""Represents date and time information using ISO 8601 format and is always in UTC time."""
|
|
16
|
+
return self.properties.get("activityDateTime", datetime.min)
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
def change_id(self):
|
|
20
|
+
# type: () -> Optional[str]
|
|
21
|
+
"""Unique ID of this change in this cycle. Supports $filter (eq, contains)."""
|
|
22
|
+
return self.properties.get("changeId", None)
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def cycle_id(self):
|
|
26
|
+
# type: () -> Optional[str]
|
|
27
|
+
"""Unique ID per job iteration. Supports $filter (eq, contains)."""
|
|
28
|
+
return self.properties.get("cycleId", None)
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def duration_in_milliseconds(self):
|
|
32
|
+
# type: () -> Optional[int]
|
|
33
|
+
"""Indicates how long this provisioning action took to finish. Measured in milliseconds."""
|
|
34
|
+
return self.properties.get("durationInMilliseconds", None)
|
|
35
|
+
|
|
10
36
|
@property
|
|
11
37
|
def service_principal(self):
|
|
12
38
|
"""Represents the service principal used for provisioning."""
|
|
@@ -14,6 +40,9 @@ class ProvisioningObjectSummary(Entity):
|
|
|
14
40
|
|
|
15
41
|
def get_property(self, name, default_value=None):
|
|
16
42
|
if default_value is None:
|
|
17
|
-
property_mapping = {
|
|
43
|
+
property_mapping = {
|
|
44
|
+
"activityDateTime": self.activity_datetime,
|
|
45
|
+
"servicePrincipal": self.service_principal,
|
|
46
|
+
}
|
|
18
47
|
default_value = property_mapping.get(name, None)
|
|
19
48
|
return super(ProvisioningObjectSummary, self).get_property(name, default_value)
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
1
3
|
from office365.directory.authentication.methods.method import AuthenticationMethod
|
|
2
4
|
|
|
3
5
|
|
|
4
6
|
class Fido2AuthenticationMethod(AuthenticationMethod):
|
|
5
7
|
"""Representation of a FIDO2 security key registered to a user. FIDO2 is a sign-in authentication method."""
|
|
8
|
+
|
|
9
|
+
@property
|
|
10
|
+
def model(self):
|
|
11
|
+
# type: () -> Optional[str]
|
|
12
|
+
"""The manufacturer-assigned model of the FIDO2 security key."""
|
|
13
|
+
return self.properties.get("model", None)
|
|
@@ -1,6 +1,29 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
1
4
|
from office365.directory.authentication.methods.method import AuthenticationMethod
|
|
2
5
|
|
|
3
6
|
|
|
4
7
|
class PasswordAuthenticationMethod(AuthenticationMethod):
|
|
5
8
|
"""A representation of a user's password. For security, the password itself will never be returned in the object,
|
|
6
9
|
but action can be taken to reset a password."""
|
|
10
|
+
|
|
11
|
+
@property
|
|
12
|
+
def created_datetime(self):
|
|
13
|
+
# type: () -> datetime
|
|
14
|
+
"""The date and time when this password was last updated. This property is currently not populated."""
|
|
15
|
+
return self.properties.get("createdDateTime", datetime.min)
|
|
16
|
+
|
|
17
|
+
@property
|
|
18
|
+
def password(self):
|
|
19
|
+
# type: () -> Optional[str]
|
|
20
|
+
"""For security, the password is always returned as null from a LIST or GET operation."""
|
|
21
|
+
return self.properties.get("password", None)
|
|
22
|
+
|
|
23
|
+
def get_property(self, name, default_value=None):
|
|
24
|
+
if default_value is None:
|
|
25
|
+
property_mapping = {"createdDateTime": self.created_datetime}
|
|
26
|
+
default_value = property_mapping.get(name, None)
|
|
27
|
+
return super(PasswordAuthenticationMethod, self).get_property(
|
|
28
|
+
name, default_value
|
|
29
|
+
)
|
office365/directory/directory.py
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
from office365.directory.administrative_unit import AdministrativeUnit
|
|
2
|
+
from office365.directory.custom_security_attribute_definition import (
|
|
3
|
+
CustomSecurityAttributeDefinition,
|
|
4
|
+
)
|
|
5
|
+
from office365.directory.device_local_credential_info import DeviceLocalCredentialInfo
|
|
2
6
|
from office365.directory.object_collection import DirectoryObjectCollection
|
|
3
7
|
from office365.entity import Entity
|
|
4
8
|
from office365.entity_collection import EntityCollection
|
|
@@ -10,6 +14,42 @@ class Directory(Entity):
|
|
|
10
14
|
"container". Deleted items will remain available to restore for up to 30 days. After 30 days, the items are
|
|
11
15
|
permanently deleted."""
|
|
12
16
|
|
|
17
|
+
@property
|
|
18
|
+
def device_local_credentials(self):
|
|
19
|
+
"""Conceptual container for user and group directory objects."""
|
|
20
|
+
return self.properties.get(
|
|
21
|
+
"deviceLocalCredentials",
|
|
22
|
+
EntityCollection(
|
|
23
|
+
self.context,
|
|
24
|
+
DeviceLocalCredentialInfo,
|
|
25
|
+
ResourcePath("deviceLocalCredentials", self.resource_path),
|
|
26
|
+
),
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def administrative_units(self):
|
|
31
|
+
"""Conceptual container for user and group directory objects."""
|
|
32
|
+
return self.properties.get(
|
|
33
|
+
"administrativeUnits",
|
|
34
|
+
EntityCollection(
|
|
35
|
+
self.context,
|
|
36
|
+
AdministrativeUnit,
|
|
37
|
+
ResourcePath("administrativeUnits", self.resource_path),
|
|
38
|
+
),
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def custom_security_attribute_definitions(self):
|
|
43
|
+
"""Conceptual container for customSecurityAttributeDefinition objects and their properties."""
|
|
44
|
+
return self.properties.get(
|
|
45
|
+
"customSecurityAttributeDefinitions",
|
|
46
|
+
EntityCollection(
|
|
47
|
+
self.context,
|
|
48
|
+
CustomSecurityAttributeDefinition,
|
|
49
|
+
ResourcePath("customSecurityAttributeDefinitions", self.resource_path),
|
|
50
|
+
),
|
|
51
|
+
)
|
|
52
|
+
|
|
13
53
|
def deleted_items(self, entity_type=None):
|
|
14
54
|
"""Recently deleted items. Read-only. Nullable."""
|
|
15
55
|
if entity_type:
|
|
@@ -27,18 +67,6 @@ class Directory(Entity):
|
|
|
27
67
|
),
|
|
28
68
|
)
|
|
29
69
|
|
|
30
|
-
@property
|
|
31
|
-
def administrative_units(self):
|
|
32
|
-
"""Conceptual container for user and group directory objects."""
|
|
33
|
-
return self.properties.get(
|
|
34
|
-
"administrativeUnits",
|
|
35
|
-
EntityCollection(
|
|
36
|
-
self.context,
|
|
37
|
-
AdministrativeUnit,
|
|
38
|
-
ResourcePath("administrativeUnits", self.resource_path),
|
|
39
|
-
),
|
|
40
|
-
)
|
|
41
|
-
|
|
42
70
|
@property
|
|
43
71
|
def deleted_groups(self):
|
|
44
72
|
"""Recently deleted groups"""
|
|
@@ -3,7 +3,7 @@ from office365.entity_collection import EntityCollection
|
|
|
3
3
|
from office365.runtime.queries.function import FunctionQuery
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
class AppConsentRequestCollection(EntityCollection):
|
|
6
|
+
class AppConsentRequestCollection(EntityCollection[AppConsentRequest]):
|
|
7
7
|
"""AppConsentRequest's collection"""
|
|
8
8
|
|
|
9
9
|
def __init__(self, context, resource_path=None):
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
1
3
|
from office365.entity import Entity
|
|
2
4
|
|
|
3
5
|
|
|
@@ -6,3 +8,9 @@ class AgreementAcceptance(Entity):
|
|
|
6
8
|
Represents the current status of a user's response to a company's customizable terms of use agreement powered by
|
|
7
9
|
Azure Active Directory (Azure AD).
|
|
8
10
|
"""
|
|
11
|
+
|
|
12
|
+
@property
|
|
13
|
+
def user_principal_name(self):
|
|
14
|
+
# type: () -> Optional[str]
|
|
15
|
+
"""UPN of the user when the acceptance was recorded."""
|
|
16
|
+
return self.properties.get("userPrincipalName", None)
|
|
@@ -4,7 +4,7 @@ from office365.directory.identitygovernance.userconsent.request import (
|
|
|
4
4
|
from office365.entity_collection import EntityCollection
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
class UserConsentRequestCollection(EntityCollection):
|
|
7
|
+
class UserConsentRequestCollection(EntityCollection[UserConsentRequest]):
|
|
8
8
|
"""AppConsentRequest's collection"""
|
|
9
9
|
|
|
10
10
|
def __init__(self, context, resource_path=None):
|
|
@@ -9,6 +9,7 @@ from office365.directory.policies.authentication_strength import (
|
|
|
9
9
|
from office365.directory.policies.authorization import AuthorizationPolicy
|
|
10
10
|
from office365.directory.policies.conditional_access import ConditionalAccessPolicy
|
|
11
11
|
from office365.directory.policies.cross_tenant_access import CrossTenantAccessPolicy
|
|
12
|
+
from office365.directory.policies.device_registration import DeviceRegistrationPolicy
|
|
12
13
|
from office365.directory.policies.permission_grant import PermissionGrantPolicy
|
|
13
14
|
from office365.directory.policies.tenant_app_management import TenantAppManagementPolicy
|
|
14
15
|
from office365.entity import Entity
|
|
@@ -33,6 +34,17 @@ class PolicyRoot(Entity):
|
|
|
33
34
|
),
|
|
34
35
|
)
|
|
35
36
|
|
|
37
|
+
@property
|
|
38
|
+
def device_registration_policy(self):
|
|
39
|
+
""" """
|
|
40
|
+
return self.properties.get(
|
|
41
|
+
"deviceRegistrationPolicy",
|
|
42
|
+
DeviceRegistrationPolicy(
|
|
43
|
+
self.context,
|
|
44
|
+
ResourcePath("deviceRegistrationPolicy", self.resource_path),
|
|
45
|
+
),
|
|
46
|
+
)
|
|
47
|
+
|
|
36
48
|
def authentication_strength_policies(self):
|
|
37
49
|
# type: () -> EntityCollection[AuthenticationStrengthPolicy]
|
|
38
50
|
"""
|
|
@@ -147,6 +159,7 @@ class PolicyRoot(Entity):
|
|
|
147
159
|
"conditional_access_policies": self.conditional_access_policies,
|
|
148
160
|
"crossTenantAccessPolicy": self.cross_tenant_access_policy,
|
|
149
161
|
"defaultAppManagementPolicy": self.default_app_management_policy,
|
|
162
|
+
"deviceRegistrationPolicy": self.device_registration_policy,
|
|
150
163
|
"permissionGrantPolicies": self.permission_grant_policies,
|
|
151
164
|
}
|
|
152
165
|
default_value = property_mapping.get(name, None)
|
|
@@ -111,10 +111,8 @@ class ServicePrincipal(DirectoryObject):
|
|
|
111
111
|
|
|
112
112
|
def _grant(principal):
|
|
113
113
|
# type: ("ServicePrincipal") -> None
|
|
114
|
-
app_role_id = repr(app_role)
|
|
115
|
-
principal_id = principal.id
|
|
116
114
|
self.app_role_assigned_to.add(
|
|
117
|
-
principalId=
|
|
115
|
+
principalId=principal.id, resourceId=self.id, appRoleId=app_role.id
|
|
118
116
|
)
|
|
119
117
|
|
|
120
118
|
def _ensure_principal():
|
|
@@ -128,20 +126,17 @@ class ServicePrincipal(DirectoryObject):
|
|
|
128
126
|
"""Revokes an app role assignment from a client service principal"""
|
|
129
127
|
|
|
130
128
|
def _revoke(principal):
|
|
131
|
-
# type ("ServicePrincipal") -> None
|
|
132
|
-
principal_id = principal.id
|
|
133
|
-
app_role_id = repr(app_role)
|
|
129
|
+
# type: ("ServicePrincipal") -> None
|
|
134
130
|
app_role_assigned_to_ids = [
|
|
135
131
|
item.id
|
|
136
132
|
for item in self.app_role_assigned_to
|
|
137
|
-
if item.principal_id ==
|
|
133
|
+
if item.principal_id == principal.id and item.app_role_id == app_role.id
|
|
138
134
|
]
|
|
139
135
|
if len(app_role_assigned_to_ids) > 0:
|
|
140
136
|
self.app_role_assigned_to[app_role_assigned_to_ids[0]].delete_object()
|
|
141
137
|
|
|
142
138
|
def _ensure_resource(principal):
|
|
143
139
|
self.ensure_properties(["id", "appRoleAssignedTo"], _revoke, principal)
|
|
144
|
-
# self.app_role_assigned_to.get_all(page_loaded=_revoke)
|
|
145
140
|
|
|
146
141
|
def _ensure_principal():
|
|
147
142
|
self.context.service_principals.get_by_app(app).get().after_execute(
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
from office365.directory.synchronization.directory_definition import DirectoryDefinition
|
|
1
2
|
from office365.entity import Entity
|
|
3
|
+
from office365.entity_collection import EntityCollection
|
|
4
|
+
from office365.runtime.paths.resource_path import ResourcePath
|
|
2
5
|
|
|
3
6
|
|
|
4
7
|
class SynchronizationSchema(Entity):
|
|
@@ -9,3 +12,16 @@ class SynchronizationSchema(Entity):
|
|
|
9
12
|
|
|
10
13
|
The following sections describe the high-level components of the synchronization schema.
|
|
11
14
|
"""
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def directories(self):
|
|
18
|
+
# type: () -> EntityCollection[DirectoryDefinition]
|
|
19
|
+
"""Contains the collection of directories and all of their objects."""
|
|
20
|
+
return self.properties.get(
|
|
21
|
+
"directories",
|
|
22
|
+
EntityCollection(
|
|
23
|
+
self.context,
|
|
24
|
+
DirectoryDefinition,
|
|
25
|
+
ResourcePath("directories", self.resource_path),
|
|
26
|
+
),
|
|
27
|
+
)
|
|
@@ -50,6 +50,7 @@ from office365.outlook.mail.mailbox_settings import MailboxSettings
|
|
|
50
50
|
from office365.outlook.mail.messages.collection import MessageCollection
|
|
51
51
|
from office365.outlook.mail.messages.message import Message
|
|
52
52
|
from office365.outlook.mail.recipient import Recipient
|
|
53
|
+
from office365.outlook.mail.tips import MailTips
|
|
53
54
|
from office365.outlook.user import OutlookUser
|
|
54
55
|
from office365.planner.user import PlannerUser
|
|
55
56
|
from office365.runtime.client_result import ClientResult
|
|
@@ -169,6 +170,28 @@ class User(DirectoryObject):
|
|
|
169
170
|
self.context.add_query(qry)
|
|
170
171
|
return self
|
|
171
172
|
|
|
173
|
+
def get_mail_tips(self, email_addresses, mail_tips_options=None):
|
|
174
|
+
"""Get the MailTips of one or more recipients as available to the signed-in user.
|
|
175
|
+
:param list[str] email_addresses: A collection of SMTP addresses of recipients to get MailTips for.
|
|
176
|
+
:param str mail_tips_options: A enumeration of flags that represents the requested mailtips.
|
|
177
|
+
Possible values are: automaticReplies, customMailTip, deliveryRestriction, externalMemberCount,
|
|
178
|
+
mailboxFullStatus, maxMessageSize, moderationStatus, recipientScope, recipientSuggestions,
|
|
179
|
+
and totalMemberCount.
|
|
180
|
+
"""
|
|
181
|
+
return_type = ClientResult(self.context, ClientValueCollection(MailTips))
|
|
182
|
+
payload = {
|
|
183
|
+
"EmailAddresses": StringCollection(email_addresses),
|
|
184
|
+
"MailTipsOptions": mail_tips_options,
|
|
185
|
+
}
|
|
186
|
+
qry = ServiceOperationQuery(
|
|
187
|
+
self,
|
|
188
|
+
"getMailTips",
|
|
189
|
+
None,
|
|
190
|
+
payload,
|
|
191
|
+
)
|
|
192
|
+
self.context.add_query(qry)
|
|
193
|
+
return return_type
|
|
194
|
+
|
|
172
195
|
def send_mail(
|
|
173
196
|
self,
|
|
174
197
|
subject,
|
|
@@ -2,6 +2,8 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
from datetime import datetime
|
|
5
|
+
from functools import partial
|
|
6
|
+
from os.path import isfile, join
|
|
5
7
|
from typing import IO, AnyStr, Callable, Optional, TypeVar
|
|
6
8
|
|
|
7
9
|
import requests
|
|
@@ -272,6 +274,30 @@ class DriveItem(BaseItem):
|
|
|
272
274
|
name = os.path.basename(path_or_file)
|
|
273
275
|
return self.upload(name, content)
|
|
274
276
|
|
|
277
|
+
def upload_folder(self, path, file_uploaded=None):
|
|
278
|
+
# type: (str, Callable[["DriveItem"], None]) -> "DriveItem"
|
|
279
|
+
|
|
280
|
+
def _after_file_upload(return_type):
|
|
281
|
+
# type: ("DriveItem") -> None
|
|
282
|
+
if callable(file_uploaded):
|
|
283
|
+
file_uploaded(return_type)
|
|
284
|
+
|
|
285
|
+
def _upload_folder(source_path, target_folder):
|
|
286
|
+
# type: (str, "DriveItem") -> None
|
|
287
|
+
for name in os.listdir(source_path):
|
|
288
|
+
cur_path = join(source_path, name)
|
|
289
|
+
if isfile(cur_path):
|
|
290
|
+
with open(cur_path, "rb") as f:
|
|
291
|
+
target_folder.upload_file(f).after_execute(_after_file_upload)
|
|
292
|
+
else:
|
|
293
|
+
target_folder.create_folder(name).after_execute(
|
|
294
|
+
partial(_upload_folder, cur_path)
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
"""Uploads a folder"""
|
|
298
|
+
_upload_folder(path, self)
|
|
299
|
+
return self
|
|
300
|
+
|
|
275
301
|
def get_content(self, format_name=None):
|
|
276
302
|
# type: (Optional[str]) -> ClientResult[AnyStr]
|
|
277
303
|
"""
|
|
@@ -302,6 +328,52 @@ class DriveItem(BaseItem):
|
|
|
302
328
|
self.get_content().after_execute(_save_content)
|
|
303
329
|
return self
|
|
304
330
|
|
|
331
|
+
def download_folder(
|
|
332
|
+
self, download_file, after_file_downloaded=None, recursive=True
|
|
333
|
+
):
|
|
334
|
+
# type: (IO, Callable[[File], None], bool) -> "DriveItem"
|
|
335
|
+
"""
|
|
336
|
+
Download the folder content
|
|
337
|
+
"""
|
|
338
|
+
import zipfile
|
|
339
|
+
|
|
340
|
+
def _after_file_downloaded(drive_item, base_path, result):
|
|
341
|
+
# type: ("DriveItem", str, ClientResult[AnyStr]) -> None
|
|
342
|
+
with zipfile.ZipFile(download_file.name, "a", zipfile.ZIP_DEFLATED) as zf:
|
|
343
|
+
zip_path = (
|
|
344
|
+
"/".join([base_path, drive_item.name])
|
|
345
|
+
if base_path is not None
|
|
346
|
+
else drive_item.name
|
|
347
|
+
)
|
|
348
|
+
zf.writestr(zip_path, result.value)
|
|
349
|
+
if callable(after_file_downloaded):
|
|
350
|
+
after_file_downloaded(drive_item)
|
|
351
|
+
|
|
352
|
+
def _after_folder_downloaded(parent_item, base_path=None):
|
|
353
|
+
# type: ("DriveItem", str) -> None
|
|
354
|
+
for drive_item in parent_item.children:
|
|
355
|
+
if drive_item.is_file:
|
|
356
|
+
drive_item.get_content().after_execute(
|
|
357
|
+
partial(_after_file_downloaded, drive_item, base_path)
|
|
358
|
+
)
|
|
359
|
+
else:
|
|
360
|
+
if recursive:
|
|
361
|
+
if base_path is None:
|
|
362
|
+
next_base_path = str(drive_item.name)
|
|
363
|
+
else:
|
|
364
|
+
next_base_path = "/".join([base_path, drive_item.name])
|
|
365
|
+
_download_folder(drive_item, next_base_path)
|
|
366
|
+
|
|
367
|
+
def _download_folder(drive_item, prev_result=None):
|
|
368
|
+
# type: ("DriveItem", str) -> None
|
|
369
|
+
drive_item.ensure_properties(
|
|
370
|
+
["children", "name"],
|
|
371
|
+
partial(_after_folder_downloaded, drive_item, prev_result),
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
_download_folder(self)
|
|
375
|
+
return self
|
|
376
|
+
|
|
305
377
|
def download_session(
|
|
306
378
|
self, file_object, chunk_downloaded=None, chunk_size=1024 * 1024
|
|
307
379
|
):
|
|
@@ -600,9 +672,7 @@ class DriveItem(BaseItem):
|
|
|
600
672
|
@property
|
|
601
673
|
def audio(self):
|
|
602
674
|
# type: () -> Audio
|
|
603
|
-
"""
|
|
604
|
-
Audio metadata, if the item is an audio file. Read-only.
|
|
605
|
-
"""
|
|
675
|
+
"""Audio metadata, if the item is an audio file. Read-only."""
|
|
606
676
|
return self.properties.get("audio", Audio())
|
|
607
677
|
|
|
608
678
|
@property
|
|
@@ -616,9 +686,7 @@ class DriveItem(BaseItem):
|
|
|
616
686
|
@property
|
|
617
687
|
def photo(self):
|
|
618
688
|
# type: () -> Photo
|
|
619
|
-
"""
|
|
620
|
-
Photo metadata, if the item is a photo. Read-only.
|
|
621
|
-
"""
|
|
689
|
+
"""Photo metadata, if the item is a photo. Read-only."""
|
|
622
690
|
return self.properties.get("photo", Photo())
|
|
623
691
|
|
|
624
692
|
@property
|
office365/onedrive/lists/list.py
CHANGED
|
File without changes
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from office365.base_item import BaseItem
|
|
4
|
+
from office365.onedrive.driveitems.publication_facet import PublicationFacet
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BaseSitePage(BaseItem):
|
|
8
|
+
"""An abstract type that represents a page in the site page library."""
|
|
9
|
+
|
|
10
|
+
@property
|
|
11
|
+
def publishing_state(self):
|
|
12
|
+
# type: () -> Optional[str]
|
|
13
|
+
"""The publishing status and the MM.mm version of the page."""
|
|
14
|
+
return self.properties.get("publishingState", PublicationFacet())
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def page_layout(self):
|
|
18
|
+
# type: () -> Optional[str]
|
|
19
|
+
"""
|
|
20
|
+
The name of the page layout of the page.
|
|
21
|
+
The possible values are: microsoftReserved, article, home, unknownFutureValue.
|
|
22
|
+
"""
|
|
23
|
+
return self.properties.get("pageLayout", None)
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def title(self):
|
|
27
|
+
# type: () -> Optional[str]
|
|
28
|
+
"""Title of the sitePage."""
|
|
29
|
+
return self.properties.get("title", None)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from office365.entity import Entity
|
|
2
|
+
from office365.entity_collection import EntityCollection
|
|
3
|
+
from office365.onedrive.sitepages.horizontal_section import HorizontalSection
|
|
4
|
+
from office365.onedrive.sitepages.vertical_section import VerticalSection
|
|
5
|
+
from office365.runtime.paths.resource_path import ResourcePath
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CanvasLayout(Entity):
|
|
9
|
+
"""Represents the layout of the content in a given SharePoint page."""
|
|
10
|
+
|
|
11
|
+
@property
|
|
12
|
+
def horizontal_sections(self):
|
|
13
|
+
# type: () -> EntityCollection[HorizontalSection]
|
|
14
|
+
"""Collection of horizontal sections on the SharePoint page.."""
|
|
15
|
+
return self.properties.get(
|
|
16
|
+
"horizontalSections",
|
|
17
|
+
EntityCollection(
|
|
18
|
+
self.context,
|
|
19
|
+
HorizontalSection,
|
|
20
|
+
ResourcePath("horizontalSections", self.resource_path),
|
|
21
|
+
),
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def vertical_section(self):
|
|
26
|
+
# type: () -> VerticalSection
|
|
27
|
+
"""Vertical section on the SharePoint page."""
|
|
28
|
+
return self.properties.get(
|
|
29
|
+
"verticalSection",
|
|
30
|
+
VerticalSection(
|
|
31
|
+
self.context,
|
|
32
|
+
ResourcePath("verticalSection", self.resource_path),
|
|
33
|
+
),
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
def get_property(self, name, default_value=None):
|
|
37
|
+
if default_value is None:
|
|
38
|
+
property_mapping = {
|
|
39
|
+
"horizontalSections": self.horizontal_sections,
|
|
40
|
+
"verticalSection": self.vertical_section,
|
|
41
|
+
}
|
|
42
|
+
default_value = property_mapping.get(name, None)
|
|
43
|
+
return super(CanvasLayout, self).get_property(name, default_value)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from office365.entity_collection import EntityCollection
|
|
2
|
+
from office365.onedrive.sitepages.site_page import SitePage
|
|
3
|
+
from office365.onedrive.sitepages.title_area import TitleArea
|
|
4
|
+
from office365.runtime.http.request_options import RequestOptions
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SitePageCollection(EntityCollection[SitePage]):
|
|
8
|
+
"""Sites container"""
|
|
9
|
+
|
|
10
|
+
def __init__(self, context, resource_path=None):
|
|
11
|
+
super(SitePageCollection, self).__init__(context, SitePage, resource_path)
|
|
12
|
+
|
|
13
|
+
def add(self, title):
|
|
14
|
+
"""
|
|
15
|
+
Create a new sitePage in the site pages list in a site.
|
|
16
|
+
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def _construct_request(request):
|
|
20
|
+
# type: (RequestOptions) -> None
|
|
21
|
+
request.set_header("Content-Type", "application/json")
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
super(SitePageCollection, self)
|
|
25
|
+
.add(
|
|
26
|
+
title=title,
|
|
27
|
+
name="{0}.aspx".format(title),
|
|
28
|
+
pageLayout="article",
|
|
29
|
+
titleArea=TitleArea(),
|
|
30
|
+
)
|
|
31
|
+
.before_execute(_construct_request)
|
|
32
|
+
)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from office365.entity import Entity
|
|
2
|
+
from office365.entity_collection import EntityCollection
|
|
3
|
+
from office365.onedrive.sitepages.horizontal_section_column import (
|
|
4
|
+
HorizontalSectionColumn,
|
|
5
|
+
)
|
|
6
|
+
from office365.runtime.paths.resource_path import ResourcePath
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class HorizontalSection(Entity):
|
|
10
|
+
"""Represents a horizontal section in a given SharePoint page."""
|
|
11
|
+
|
|
12
|
+
@property
|
|
13
|
+
def columns(self):
|
|
14
|
+
# type: () -> EntityCollection[HorizontalSectionColumn]
|
|
15
|
+
"""The set of vertical columns in this section."""
|
|
16
|
+
return self.properties.get(
|
|
17
|
+
"columns",
|
|
18
|
+
EntityCollection(
|
|
19
|
+
self.context,
|
|
20
|
+
HorizontalSectionColumn,
|
|
21
|
+
ResourcePath("columns", self.resource_path),
|
|
22
|
+
),
|
|
23
|
+
)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from office365.entity import Entity
|
|
2
|
+
from office365.entity_collection import EntityCollection
|
|
3
|
+
from office365.onedrive.sitepages.web_part import WebPart
|
|
4
|
+
from office365.runtime.paths.resource_path import ResourcePath
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class HorizontalSectionColumn(Entity):
|
|
8
|
+
"""Represents a vertical column in a given horizontal section."""
|
|
9
|
+
|
|
10
|
+
@property
|
|
11
|
+
def web_parts(self):
|
|
12
|
+
# type: () -> EntityCollection[WebPart]
|
|
13
|
+
"""The set of web parts in this section."""
|
|
14
|
+
return self.properties.get(
|
|
15
|
+
"webParts",
|
|
16
|
+
EntityCollection(
|
|
17
|
+
self.context, WebPart, ResourcePath("webParts", self.resource_path)
|
|
18
|
+
),
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
def get_property(self, name, default_value=None):
|
|
22
|
+
if default_value is None:
|
|
23
|
+
property_mapping = {
|
|
24
|
+
"webParts": self.web_parts,
|
|
25
|
+
}
|
|
26
|
+
default_value = property_mapping.get(name, None)
|
|
27
|
+
return super(HorizontalSectionColumn, self).get_property(name, default_value)
|