diff --git a/examples/data/report #123.csv b/examples/data/report #123.csv deleted file mode 100644 index d800886d9..000000000 --- a/examples/data/report #123.csv +++ /dev/null @@ -1 +0,0 @@ -123 \ No newline at end of file diff --git a/examples/data/report '123.csv b/examples/data/report '123.csv deleted file mode 100644 index d800886d9..000000000 --- a/examples/data/report '123.csv +++ /dev/null @@ -1 +0,0 @@ -123 \ No newline at end of file diff --git a/examples/data/report.csv b/examples/data/reports/report.csv similarity index 100% rename from examples/data/report.csv rename to examples/data/reports/report.csv diff --git a/examples/directory/applications/get_by_app_id.py b/examples/directory/applications/get_by_app_id.py index e6e61d5d1..573fa6361 100644 --- a/examples/directory/applications/get_by_app_id.py +++ b/examples/directory/applications/get_by_app_id.py @@ -7,11 +7,7 @@ as Object ID and appId is referred to as Application (client) ID on the Azure portal. """ from office365.graph_client import GraphClient -from tests import ( - test_client_id, - test_client_secret, - test_tenant, -) +from tests import test_client_id, test_client_secret, test_tenant client = GraphClient.with_client_secret(test_tenant, test_client_id, test_client_secret) app = client.applications.get_by_app_id(test_client_id).get().execute_query() diff --git a/examples/directory/applications/grant_perms.py b/examples/directory/applications/grant_perms.py index ee2da2991..ea18a61cd 100644 --- a/examples/directory/applications/grant_perms.py +++ b/examples/directory/applications/grant_perms.py @@ -15,11 +15,7 @@ """ from office365.graph_client import GraphClient -from tests import ( - test_admin_principal_name, - test_client_id, - test_tenant, -) +from tests import test_admin_principal_name, test_client_id, test_tenant client = GraphClient.with_token_interactive( test_tenant, test_client_id, test_admin_principal_name diff --git a/examples/directory/applications/revoke_perms.py b/examples/directory/applications/revoke_perms.py index 0d575c9dd..380ab83e4 100644 --- a/examples/directory/applications/revoke_perms.py +++ b/examples/directory/applications/revoke_perms.py @@ -5,11 +5,7 @@ """ from office365.graph_client import GraphClient -from tests import ( - test_admin_principal_name, - test_client_id, - test_tenant, -) +from tests import test_admin_principal_name, test_client_id, test_tenant client = GraphClient.with_token_interactive( test_tenant, test_client_id, test_admin_principal_name diff --git a/examples/directory/roles/for_user.py b/examples/directory/roles/for_user.py index f3b19c513..fba51e065 100644 --- a/examples/directory/roles/for_user.py +++ b/examples/directory/roles/for_user.py @@ -4,12 +4,7 @@ https://learn.microsoft.com/en-us/graph/api/directoryrole-list?view=graph-rest-1.0 """ from office365.graph_client import GraphClient -from tests import ( - test_client_id, - test_password, - test_tenant, - test_username, -) +from tests import test_client_id, test_password, test_tenant, test_username client = GraphClient.with_username_and_password( test_tenant, test_client_id, test_username, test_password diff --git a/examples/directory/users/get_licenses.py b/examples/directory/users/get_licenses.py index fdf8979f7..25a245caa 100644 --- a/examples/directory/users/get_licenses.py +++ b/examples/directory/users/get_licenses.py @@ -4,12 +4,7 @@ https://learn.microsoft.com/en-us/graph/api/user-list-licensedetails?view=graph-rest-1.0 """ from office365.graph_client import GraphClient -from tests import ( - test_client_id, - test_password, - test_tenant, - test_username, -) +from tests import test_client_id, test_password, test_tenant, test_username client = GraphClient.with_username_and_password( test_tenant, test_client_id, test_username, test_password diff --git a/examples/onedrive/files/upload.py b/examples/onedrive/files/upload.py index fb1fd4ad5..85fff8ea1 100644 --- a/examples/onedrive/files/upload.py +++ b/examples/onedrive/files/upload.py @@ -17,5 +17,7 @@ # local_path = "../../data/Financial Sample.xlsx" local_path = "../../data/countries.json" -file = folder.upload_file(local_path).execute_query() +# file = folder.upload_file(local_path).execute_query() +with open(local_path, "rb") as f: + file = folder.upload_file(f).execute_query() print("File {0} has been uploaded".format(file.web_url)) diff --git a/examples/onedrive/folders/upload.py b/examples/onedrive/folders/upload.py index 746333be5..ddfab343f 100644 --- a/examples/onedrive/folders/upload.py +++ b/examples/onedrive/folders/upload.py @@ -1,31 +1,20 @@ """ Demonstrates how to upload files from a local folder into OneDrive drive - """ -import os -from os.path import isfile, join - from office365.graph_client import GraphClient -from office365.runtime.client_request_exception import ClientRequestException -from tests.graph_case import acquire_token_by_username_password +from office365.onedrive.driveitems.driveItem import DriveItem +from tests import test_client_id, test_password, test_tenant, test_username -client = GraphClient(acquire_token_by_username_password) -remote_drive = client.me.drive -local_path = "../../data" -for name in os.listdir(local_path): - path = join(local_path, name) - if isfile(path): - try: - with open(path, "rb") as local_file: - uploaded_file = remote_drive.root.upload_file( - local_file - ).execute_query() - print("File '{0}' uploaded into '{1}'".format(path, uploaded_file.web_url)) - except ClientRequestException as e: - print( - "An error occured while uploading a file {0}: {1}".format( - path, e.message - ) - ) +def print_progress(uploaded_file): + # type: (DriveItem)-> None + print("File has been uploaded into '{0}'".format(uploaded_file.web_url)) + + +client = GraphClient.with_username_and_password( + test_tenant, test_client_id, test_username, test_password +) +local_path = "../../data" +target_folder = client.me.drive.root.get_by_path("Import") +target_folder.upload_folder(local_path, print_progress).execute_query() diff --git a/examples/onedrive/folders/upload_custom.py b/examples/onedrive/folders/upload_custom.py new file mode 100644 index 000000000..e90b66fef --- /dev/null +++ b/examples/onedrive/folders/upload_custom.py @@ -0,0 +1,32 @@ +""" +Demonstrates how to upload files from a local folder into OneDrive drive +""" + +import os +from os.path import isfile, join + +from office365.graph_client import GraphClient +from office365.runtime.client_request_exception import ClientRequestException +from tests import test_client_id, test_password, test_tenant, test_username + +client = GraphClient.with_username_and_password( + test_tenant, test_client_id, test_username, test_password +) +remote_drive = client.me.drive +local_path = "../../data" + +for name in os.listdir(local_path): + path = join(local_path, name) + if isfile(path): + try: + with open(path, "rb") as local_file: + uploaded_file = remote_drive.root.upload_file( + local_file + ).execute_query() + print("File '{0}' uploaded into '{1}'".format(path, uploaded_file.web_url)) + except ClientRequestException as e: + print( + "An error occured while uploading a file {0}: {1}".format( + path, e.message + ) + ) diff --git a/examples/sharepoint/connect_with_client_certificate_scopes.py b/examples/sharepoint/connect_with_client_certificate_scopes.py index ccecbc6ce..23be6357a 100644 --- a/examples/sharepoint/connect_with_client_certificate_scopes.py +++ b/examples/sharepoint/connect_with_client_certificate_scopes.py @@ -7,12 +7,7 @@ import os from office365.sharepoint.client_context import ClientContext -from tests import ( - test_cert_thumbprint, - test_client_id, - test_site_url, - test_tenant, -) +from tests import test_cert_thumbprint, test_client_id, test_site_url, test_tenant cert_credentials = { "tenant": test_tenant, diff --git a/examples/sharepoint/files/download_deprecated.py b/examples/sharepoint/files/download_deprecated.py index ede044c1b..6e5ae7ea5 100644 --- a/examples/sharepoint/files/download_deprecated.py +++ b/examples/sharepoint/files/download_deprecated.py @@ -12,7 +12,6 @@ ctx = ClientContext(test_team_site_url).with_credentials(test_client_credentials) file_url = "Shared Documents/Sample.pdf" -# file_url = "Shared Documents/report '123.csv" download_path = os.path.join(tempfile.mkdtemp(), os.path.basename(file_url)) with open(download_path, "wb") as local_file: file = ctx.web.get_file_by_server_relative_url(file_url).get().execute_query() diff --git a/examples/sharepoint/files/permissions/assign.py b/examples/sharepoint/files/permissions/assign.py index 964a8e3da..43d24248d 100644 --- a/examples/sharepoint/files/permissions/assign.py +++ b/examples/sharepoint/files/permissions/assign.py @@ -10,7 +10,7 @@ ) client = ClientContext(test_team_site_url).with_credentials(test_client_credentials) -file_url = "Shared Documents/report #123.csv" +file_url = "Shared Documents/Financial Sample.xlsx" role_def = client.web.role_definitions.get_by_type(RoleType.Contributor) diff --git a/examples/sharepoint/files/permissions/check.py b/examples/sharepoint/files/permissions/check.py index 5996a835a..7a5e2728b 100644 --- a/examples/sharepoint/files/permissions/check.py +++ b/examples/sharepoint/files/permissions/check.py @@ -10,7 +10,7 @@ ) client = ClientContext(test_team_site_url).with_credentials(test_user_credentials) -file_url = "Shared Documents/report #123.csv" +file_url = "Shared Documents/Financial Sample.xlsx" target_user = client.web.site_users.get_by_email(test_user_principal_name_alt) target_file = client.web.get_file_by_server_relative_path(file_url) diff --git a/examples/sharepoint/files/permissions/list.py b/examples/sharepoint/files/permissions/list.py index 69f0ec0e9..e58b51d41 100644 --- a/examples/sharepoint/files/permissions/list.py +++ b/examples/sharepoint/files/permissions/list.py @@ -8,7 +8,7 @@ ) client = ClientContext(test_team_site_url).with_credentials(test_user_credentials) -file_url = "Shared Documents/report #123.csv" +file_url = "Shared Documents/Financial Sample.xlsx" target_user = client.web.site_users.get_by_email(test_user_principal_name_alt) target_file = client.web.get_file_by_server_relative_path(file_url) diff --git a/examples/sharepoint/files/replace.py b/examples/sharepoint/files/replace.py index caf009796..1ff15450b 100644 --- a/examples/sharepoint/files/replace.py +++ b/examples/sharepoint/files/replace.py @@ -7,7 +7,7 @@ ctx = ClientContext(test_team_site_url).with_credentials(test_user_credentials) -path = "../../data/report #123.csv" +path = "../../data/report.csv" print("Uploading a new file...") with open(path, "rb") as f: diff --git a/examples/sharepoint/folders/share.py b/examples/sharepoint/folders/share.py index 4dc9fc95b..9ab7f7cca 100644 --- a/examples/sharepoint/folders/share.py +++ b/examples/sharepoint/folders/share.py @@ -3,11 +3,7 @@ """ from office365.sharepoint.client_context import ClientContext from office365.sharepoint.sharing.external_site_option import ExternalSharingSiteOption -from tests import ( - test_team_site_url, - test_user_credentials, - test_user_principal_name, -) +from tests import test_team_site_url, test_user_credentials, test_user_principal_name ctx = ClientContext(test_team_site_url).with_credentials(test_user_credentials) folder_url = "Shared Documents/Archive" diff --git a/examples/sharepoint/listitems/attachments/upload.py b/examples/sharepoint/listitems/attachments/upload.py index ccadcf8bd..911dab880 100644 --- a/examples/sharepoint/listitems/attachments/upload.py +++ b/examples/sharepoint/listitems/attachments/upload.py @@ -18,7 +18,7 @@ task_item = tasks_list.add_item({"Title": "New Task"}).execute_query() # 2. read & upload attachment for a list item -path = "../../../data/report #123.csv" +path = "../../../data/Financial Sample.xlsx" with open(path, "rb") as fh: file_content = fh.read() attachment_file_info = AttachmentCreationInformation( diff --git a/examples/sharepoint/listitems/create.py b/examples/sharepoint/listitems/create.py index 41df741fc..d779555b4 100644 --- a/examples/sharepoint/listitems/create.py +++ b/examples/sharepoint/listitems/create.py @@ -4,11 +4,7 @@ from office365.sharepoint.client_context import ClientContext from office365.sharepoint.fields.user_value import FieldUserValue -from tests import ( - test_client_credentials, - test_team_site_url, - test_user_principal_name, -) +from tests import test_client_credentials, test_team_site_url, test_user_principal_name ctx = ClientContext(test_team_site_url).with_credentials(test_client_credentials) tasks_list = ctx.web.lists.get_by_title("Company Tasks") diff --git a/examples/sharepoint/listitems/system_update.py b/examples/sharepoint/listitems/system_update.py index 4bcd291bd..9283f7eb7 100644 --- a/examples/sharepoint/listitems/system_update.py +++ b/examples/sharepoint/listitems/system_update.py @@ -7,11 +7,7 @@ from office365.sharepoint.client_context import ClientContext from office365.sharepoint.fields.user_value import FieldUserValue -from tests import ( - test_client_credentials, - test_site_url, - test_user_principal_name, -) +from tests import test_client_credentials, test_site_url, test_user_principal_name ctx = ClientContext(test_site_url).with_credentials(test_client_credentials) diff --git a/examples/sharepoint/pages/create.py b/examples/sharepoint/pages/create.py index d9416469f..ef0439041 100644 --- a/examples/sharepoint/pages/create.py +++ b/examples/sharepoint/pages/create.py @@ -5,11 +5,7 @@ """ from office365.sharepoint.client_context import ClientContext -from tests import ( - create_unique_name, - test_team_site_url, - test_user_credentials, -) +from tests import create_unique_name, test_team_site_url, test_user_credentials ctx = ClientContext(test_team_site_url).with_credentials(test_user_credentials) page_title = create_unique_name("Site Page ") diff --git a/examples/sharepoint/pages/create_and_publish.py b/examples/sharepoint/pages/create_and_publish.py index 4569bf0a0..b2106075b 100644 --- a/examples/sharepoint/pages/create_and_publish.py +++ b/examples/sharepoint/pages/create_and_publish.py @@ -5,11 +5,7 @@ """ from office365.sharepoint.client_context import ClientContext -from tests import ( - create_unique_name, - test_team_site_url, - test_user_credentials, -) +from tests import create_unique_name, test_team_site_url, test_user_credentials ctx = ClientContext(test_team_site_url).with_credentials(test_user_credentials) page_title = create_unique_name("Site Page ") diff --git a/examples/sharepoint/search/search_site_only.py b/examples/sharepoint/search/search_site_only.py index 10ab7093f..ea517ba77 100644 --- a/examples/sharepoint/search/search_site_only.py +++ b/examples/sharepoint/search/search_site_only.py @@ -6,11 +6,7 @@ """ from office365.sharepoint.client_context import ClientContext -from tests import ( - test_site_url, - test_team_site_url, - test_user_credentials, -) +from tests import test_site_url, test_team_site_url, test_user_credentials ctx = ClientContext(test_site_url).with_credentials(test_user_credentials) diff --git a/generator/metadata/MicrosoftGraph.xml b/generator/metadata/MicrosoftGraph.xml index 0a2399470..22c9954db 100644 --- a/generator/metadata/MicrosoftGraph.xml +++ b/generator/metadata/MicrosoftGraph.xml @@ -15960,6 +15960,9 @@ + + + @@ -16214,11 +16217,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -18653,6 +18770,12 @@ + + + + + + @@ -22763,10 +22886,31 @@ + + + + + + + + + + + + + + + + + + + + + @@ -22774,6 +22918,22 @@ + + + + + + + + + + + + + + + + @@ -22787,6 +22947,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -22904,6 +23105,10 @@ + + + + @@ -24875,6 +25080,7 @@ + @@ -24884,6 +25090,9 @@ + + + @@ -30084,6 +30293,21 @@ + + + + + + + + + + + + + + + @@ -33217,6 +33441,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -33226,6 +33483,10 @@ + + + + @@ -33424,19 +33685,6 @@ - - - - - - - - - - - - - @@ -39936,6 +40184,7 @@ + @@ -39948,6 +40197,7 @@ + @@ -39965,6 +40215,9 @@ + + + @@ -39972,6 +40225,14 @@ + + + + + + + + diff --git a/office365/onedrive/driveitems/driveItem.py b/office365/onedrive/driveitems/driveItem.py index 3d680a23f..c8c7ef0f7 100644 --- a/office365/onedrive/driveitems/driveItem.py +++ b/office365/onedrive/driveitems/driveItem.py @@ -2,6 +2,8 @@ import os from datetime import datetime +from functools import partial +from os.path import isfile, join from typing import IO, AnyStr, Callable, Optional, TypeVar import requests @@ -272,6 +274,30 @@ def upload_file(self, path_or_file): name = os.path.basename(path_or_file) return self.upload(name, content) + def upload_folder(self, path, file_uploaded=None): + # type: (str, Callable[["DriveItem"], None]) -> "DriveItem" + + def _after_file_upload(return_type): + # type: ("DriveItem") -> None + if callable(file_uploaded): + file_uploaded(return_type) + + def _upload_folder(source_path, target_folder): + # type: (str, "DriveItem") -> None + for name in os.listdir(source_path): + cur_path = join(source_path, name) + if isfile(cur_path): + with open(cur_path, "rb") as f: + target_folder.upload_file(f).after_execute(_after_file_upload) + else: + target_folder.create_folder(name).after_execute( + partial(_upload_folder, cur_path) + ) + + """Uploads a folder""" + _upload_folder(path, self) + return self + def get_content(self, format_name=None): # type: (Optional[str]) -> ClientResult[AnyStr] """ diff --git a/office365/onedrive/sitepages/__init__.py b/office365/onedrive/sitepages/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/office365/onedrive/sitepages/base.py b/office365/onedrive/sitepages/base.py new file mode 100644 index 000000000..6a6680a7c --- /dev/null +++ b/office365/onedrive/sitepages/base.py @@ -0,0 +1,29 @@ +from typing import Optional + +from office365.base_item import BaseItem +from office365.onedrive.driveitems.publication_facet import PublicationFacet + + +class BaseSitePage(BaseItem): + """An abstract type that represents a page in the site page library.""" + + @property + def publishing_state(self): + # type: () -> Optional[str] + """The publishing status and the MM.mm version of the page.""" + return self.properties.get("publishingState", PublicationFacet()) + + @property + def page_layout(self): + # type: () -> Optional[str] + """ + The name of the page layout of the page. + The possible values are: microsoftReserved, article, home, unknownFutureValue. + """ + return self.properties.get("pageLayout", None) + + @property + def title(self): + # type: () -> Optional[str] + """Title of the sitePage.""" + return self.properties.get("title", None) diff --git a/office365/onedrive/sitepages/site_page.py b/office365/onedrive/sitepages/site_page.py new file mode 100644 index 000000000..cb5a7c7d6 --- /dev/null +++ b/office365/onedrive/sitepages/site_page.py @@ -0,0 +1,6 @@ +from office365.onedrive.sitepages.base import BaseSitePage + + +class SitePage(BaseSitePage): + """This resource represents a page in the sitePages list. It contains the title, layout, and a collection of + webParts.""" diff --git a/office365/onedrive/sites/site.py b/office365/onedrive/sites/site.py index f83e95727..2785e2c75 100644 --- a/office365/onedrive/sites/site.py +++ b/office365/onedrive/sites/site.py @@ -13,6 +13,7 @@ from office365.onedrive.operations.rich_long_running import RichLongRunningOperation from office365.onedrive.permissions.collection import PermissionCollection from office365.onedrive.sharepoint_ids import SharePointIds +from office365.onedrive.sitepages.base import BaseSitePage from office365.onedrive.sites.site_collection import SiteCollection from office365.onedrive.termstore.store import Store from office365.onenote.onenote import Onenote @@ -224,6 +225,17 @@ def onenote(self): Onenote(self.context, ResourcePath("onenote", self.resource_path)), ) + @property + def pages(self): + # type: () -> EntityCollection[Store] + """The collection of site pages under this site.""" + return self.properties.get( + "pages", + EntityCollection( + self.context, BaseSitePage, ResourcePath("pages", self.resource_path) + ), + ) + @property def term_store(self): # type: () -> Store diff --git a/office365/runtime/queries/upload_session.py b/office365/runtime/queries/upload_session.py index 12ab4a024..2cfd7b227 100644 --- a/office365/runtime/queries/upload_session.py +++ b/office365/runtime/queries/upload_session.py @@ -4,6 +4,11 @@ class UploadSessionQuery(ServiceOperationQuery): + """ + The UploadSession query provides information about how to upload large files to OneDrive, OneDrive for + Business, or SharePoint document libraries + """ + def __init__(self, binding_type, parameters_type): super(UploadSessionQuery, self).__init__( binding_type, "createUploadSession", None, parameters_type diff --git a/tests/onedrive/test_sitepage.py b/tests/onedrive/test_sitepage.py new file mode 100644 index 000000000..bc6af86fa --- /dev/null +++ b/tests/onedrive/test_sitepage.py @@ -0,0 +1,18 @@ +from tests.graph_case import GraphTestCase + + +class TestSitePage(GraphTestCase): + """OneDrive specific test case base class""" + + @classmethod + def setUpClass(cls): + super(TestSitePage, cls).setUpClass() + cls.test_site = cls.client.sites.root + + @classmethod + def tearDownClass(cls): + pass + + def test1_list_site_pages(self): + result = self.test_site.pages.get().execute_query() + self.assertIsNotNone(result.resource_path)