Skip to content

Commit 3244d19

Browse files
vvgrem@gmail.comvvgrem@gmail.com
vvgrem@gmail.com
authored and
vvgrem@gmail.com
committed
Bug fixes (#306) and SharePoint API improvements (hubsite, utility namespaces)
1 parent 5dbbf60 commit 3244d19

21 files changed

+253
-37
lines changed

examples/sharepoint/connect_with_user_credential.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from settings import settings
22

3-
from office365.sharepoint.client_context import ClientContext
43

4+
from office365.sharepoint.client_context import ClientContext
55
ctx = ClientContext(settings["url"]).with_user_credentials(settings.get('user_credentials').get('username'),
66
settings.get('user_credentials').get('password'))
77

examples/sharepoint/folders/create_docset.py

-4
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@
77
settings.get('client_credentials').get('client_secret'))
88

99

10-
def create_folder():
11-
pass
12-
13-
1410
# ctx = ListDataService(site_url)
1511
# ctx = ClientContext(site_url).with_credentials(credentials)
1612
# ctx.execute_query()

examples/sharepoint/folders/create_folders.py

-23
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from settings import settings
2+
3+
from office365.runtime.auth.user_credential import UserCredential
4+
from office365.sharepoint.client_context import ClientContext
5+
6+
credentials = UserCredential(settings['user_credentials']['username'],
7+
settings['user_credentials']['password'])
8+
ctx = ClientContext(settings['url']).with_credentials(credentials)
9+
10+
target_folder = "/Shared Documents/Archive/2020/Sept"
11+
target_folder = ctx.web.ensure_folder_path(target_folder).execute_query()
12+
print(target_folder.serverRelativeUrl)
13+
14+
15+
16+
17+

generator/metadata/SharePoint.xml

+1-1
Large diffs are not rendered by default.

office365/runtime/auth/providers/saml_token_provider.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def xml_escape(s_val):
2929

3030

3131
def is_valid_auth_cookies(values):
32-
return any(values) and values.get('FedAuth', None) is not None
32+
return any(values) and (values.get('FedAuth', None) is not None or values.get('SPOIDCRL', None) is not None)
3333

3434

3535
class SamlTokenProvider(AuthenticationProvider, office365.logger.LoggerContext):

office365/sharepoint/folders/folder_collection.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ def get_by_path(self, decoded_url):
4141

4242
def ensure_folder_path(self, path):
4343
"""
44-
Function to create a folder
45-
:type path: string
46-
:param path: relative server URL (path) to a folder
44+
Creates a nested folder structure
45+
46+
:param str path: relative server URL (path) to a folder
4747
"""
4848

4949
url_component = os.path.normpath(path).split(os.path.sep)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from office365.runtime.client_value import ClientValue
2+
3+
4+
class WikiPageCreationInformation(ClientValue):
5+
6+
def __init__(self, server_relative_url, content):
7+
super().__init__()
8+
self.ServerRelativeUrl = server_relative_url
9+
self.WikiHtmlContent = content
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from office365.runtime.queries.service_operation_query import ServiceOperationQuery
2+
from office365.runtime.resource_path import ResourcePath
3+
from office365.sharepoint.base_entity import BaseEntity
4+
from office365.sharepoint.tenant.administration.hub_site_collection import HubSiteCollection
5+
6+
7+
class SPHubSitesUtility(BaseEntity):
8+
9+
def __init__(self, context):
10+
super().__init__(context, ResourcePath("Microsoft.SharePoint.Portal.SPHubSitesUtility"))
11+
12+
def get_hub_sites(self):
13+
hub_sites = HubSiteCollection(self.context)
14+
qry = ServiceOperationQuery(self, "GetHubSites", None, None, None, hub_sites)
15+
self.context.add_query(qry)
16+
return hub_sites

office365/sharepoint/sites/site.py

+21
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,20 @@ def get_catalog(self, type_catalog):
135135
:type type_catalog: int"""
136136
return List(self.context, ResourcePathServiceOperation("getCatalog", [type_catalog], self.resource_path))
137137

138+
def register_hub_site(self, creationInformation):
139+
"""Registers an existing site as a hub site.
140+
141+
:type creationInformation: HubSiteCreationInformation
142+
"""
143+
qry = ServiceOperationQuery(self, "RegisterHubSite", None, creationInformation, "creationInformation", None)
144+
self.context.add_query(qry)
145+
return self
146+
147+
def unregister_hub_site(self):
148+
qry = ServiceOperationQuery(self, "UnRegisterHubSite", None, None, None, None)
149+
self.context.add_query(qry)
150+
return self
151+
138152
@property
139153
def root_web(self):
140154
"""Get root web"""
@@ -162,6 +176,13 @@ def id(self):
162176
"""
163177
return self.properties.get("Id", None)
164178

179+
@property
180+
def is_hub_site(self):
181+
"""
182+
:rtype: bool
183+
"""
184+
return self.properties.get("IsHubSite", None)
185+
165186
@property
166187
def recycle_bin(self):
167188
"""Get recycle bin"""
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from office365.sharepoint.base_entity import BaseEntity
2+
3+
4+
class HubSite(BaseEntity):
5+
pass
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from office365.runtime.client_object_collection import ClientObjectCollection
2+
from office365.sharepoint.tenant.administration.hub_site import HubSite
3+
4+
5+
class HubSiteCollection(ClientObjectCollection):
6+
"""Represents a collection of HubSite resources."""
7+
8+
def __init__(self, context, resource_path=None):
9+
super(HubSiteCollection, self).__init__(context, HubSite, resource_path)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from office365.runtime.client_value import ClientValue
2+
3+
4+
class HubSitePermission(ClientValue):
5+
pass

office365/sharepoint/tenant/administration/tenant.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from office365.runtime.resource_path import ResourcePath
55
from office365.sharepoint.base_entity import BaseEntity
66
from office365.sharepoint.publishing.portal_health_status import PortalHealthStatus
7-
from office365.sharepoint.tenant.administration.hubSiteProperties import HubSiteProperties
7+
from office365.sharepoint.tenant.administration.hubsite_properties import HubSiteProperties
88
from office365.sharepoint.tenant.administration.secondary_administrators_fields_data import \
99
SecondaryAdministratorsFieldsData
1010
from office365.sharepoint.tenant.administration.secondary_administrators_info import SecondaryAdministratorsInfo
@@ -20,6 +20,12 @@ def __init__(self, context):
2020
super().__init__(context, ResourcePath("Microsoft.Online.SharePoint.TenantAdministration.Tenant"),
2121
"Microsoft.Online.SharePoint.TenantAdministration")
2222

23+
def hubsites(self, siteUrl):
24+
pass
25+
26+
def connect_site_to_hubsite_by_id(self, siteUrl, hubSiteId):
27+
pass
28+
2329
def check_tenant_licenses(self, licenses):
2430
"""
2531
Checks whether a tenant has the specified licenses.

office365/sharepoint/utilities/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from office365.runtime.client_value import ClientValue
2+
from office365.runtime.client_value_collection import ClientValueCollection
3+
4+
5+
class EmailProperties(ClientValue):
6+
7+
def __init__(self, body, subject, to, from_address=None, cc=None, bcc=None, additional_headers=None):
8+
"""
9+
10+
:param str body:
11+
:param str subject:
12+
:param list[str] to:
13+
:param str or None from_address:
14+
:param list[str] or None cc:
15+
:param list[str] or None bcc:
16+
:param dict or None additional_headers:
17+
"""
18+
super().__init__()
19+
self.Body = body
20+
self.Subject = subject
21+
self.From = from_address
22+
self.To = ClientValueCollection(str, to)
23+
self.CC = ClientValueCollection(str, cc)
24+
self.BCC = ClientValueCollection(str, bcc)
25+
self.AdditionalHeaders = additional_headers
26+
27+
@property
28+
def entity_type_name(self):
29+
return "SP.Utilities.EmailProperties"
+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
from office365.runtime.client_result import ClientResult
2+
from office365.runtime.client_value_collection import ClientValueCollection
3+
from office365.runtime.queries.service_operation_query import ServiceOperationQuery
4+
from office365.runtime.resource_path import ResourcePath
5+
from office365.sharepoint.base_entity import BaseEntity
6+
7+
8+
class Utility(BaseEntity):
9+
10+
def __init__(self, context):
11+
super().__init__(context, ResourcePath("SP.Utilities.Utility"))
12+
13+
@staticmethod
14+
def get_current_user_email_addresses(context):
15+
"""
16+
17+
:type context: office365.sharepoint.client_context.ClientContext
18+
"""
19+
result = ClientResult(str)
20+
utility = Utility(context)
21+
qry = ServiceOperationQuery(utility, "GetCurrentUserEmailAddresses", None, None, None, result)
22+
qry.static = True
23+
context.add_query(qry)
24+
return result
25+
26+
@staticmethod
27+
def get_user_permission_levels(context):
28+
"""
29+
:type context: office365.sharepoint.client_context.ClientContext
30+
"""
31+
result = ClientResult(ClientValueCollection(str))
32+
utility = Utility(context)
33+
qry = ServiceOperationQuery(utility, "GetUserPermissionLevels", None, None, None, result)
34+
qry.static = True
35+
context.add_query(qry)
36+
return result
37+
38+
@staticmethod
39+
def search_principals_using_context_web(context, s_input, sources, scopes, maxCount, groupName=None):
40+
"""
41+
:type s_input: str
42+
:type sources: int
43+
:type scopes: int
44+
:type maxCount: int
45+
:type groupName: str or None
46+
:type context: office365.sharepoint.client_context.ClientContext
47+
"""
48+
result = ClientResult(ClientValueCollection(str))
49+
utility = Utility(context)
50+
params = {
51+
"input": s_input,
52+
"sources": sources,
53+
"scopes": scopes,
54+
"maxCount": maxCount,
55+
"groupName": groupName
56+
}
57+
qry = ServiceOperationQuery(utility, "SearchPrincipalsUsingContextWeb", params, None, None, result)
58+
qry.static = True
59+
context.add_query(qry)
60+
return result
61+
62+
@staticmethod
63+
def send_email(context, properties):
64+
"""
65+
:type context: office365.sharepoint.client_context.ClientContext
66+
:type properties: office365.sharepoint.utilities.email_properties.EmailProperties
67+
"""
68+
utility = Utility(context)
69+
qry = ServiceOperationQuery(utility, "SendEmail", None, properties, "properties")
70+
qry.static = True
71+
context.add_query(qry)
72+
73+
@property
74+
def entity_type_name(self):
75+
return "SP.Utilities.Utility"

office365/sharepoint/webs/web.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,9 @@ def get_folder_by_server_relative_url(self, url):
232232

233233
def ensure_folder_path(self, path):
234234
"""
235-
Function to create folder tree
236-
:type path: string
237-
:param path: relative server URL (path) to a folder
235+
Creates a nested folder structure
236+
237+
:param str path: relative server URL (path) to a folder
238238
"""
239239
return self.root_folder.folders.ensure_folder_path(path)
240240

tests/sharepoint/test_hub_site.py

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from office365.sharepoint.portal.hub_sites_utility import SPHubSitesUtility
2+
from tests.sharepoint.sharepoint_case import SPTestCase
3+
4+
5+
class TestHubSite(SPTestCase):
6+
7+
@classmethod
8+
def setUpClass(cls):
9+
super(TestHubSite, cls).setUpClass()
10+
cls.target_site = cls.client.site.get().execute_query()
11+
12+
def test1_register_hub_site(self):
13+
if not self.target_site.is_hub_site:
14+
site = self.target_site.register_hub_site(None).get().execute_query()
15+
self.assertTrue(site.is_hub_site)
16+
17+
def test2_get_hub_sites(self):
18+
hub_sites = SPHubSitesUtility(self.client).get_hub_sites().execute_query()
19+
self.assertGreater(len(hub_sites), 0)
20+
21+
def test3_unregister_hub_site(self):
22+
site = self.target_site.unregister_hub_site().get().execute_query()
23+
self.assertFalse(site.is_hub_site)
24+

tests/sharepoint/test_utility.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from office365.sharepoint.utilities.email_properties import EmailProperties
2+
from office365.sharepoint.utilities.utility import Utility
3+
from settings import settings
4+
from tests.sharepoint.sharepoint_case import SPTestCase
5+
6+
7+
class TestUtility(SPTestCase):
8+
9+
@classmethod
10+
def setUpClass(cls):
11+
super(TestUtility, cls).setUpClass()
12+
13+
def test1_get_current_user_email_addresses(self):
14+
result = Utility.get_current_user_email_addresses(self.client)
15+
self.client.execute_query()
16+
self.assertIsNotNone(result.value)
17+
18+
def test2_get_user_permission_levels(self):
19+
result = Utility.get_user_permission_levels(self.client)
20+
self.client.execute_query()
21+
self.assertIsNotNone(result.value)
22+
23+
def test3_send_email(self):
24+
email_props = EmailProperties("The new cafeteria is open.", "Meet for lunch?",
25+
[settings.get('first_account_name')])
26+
Utility.send_email(self.client, email_props)
27+
self.client.execute_query()

0 commit comments

Comments
 (0)