diff --git a/examples/sharepoint/lists_and_items/listitem_create.py b/examples/sharepoint/lists_and_items/listitem_create.py new file mode 100644 index 00000000..d3c10280 --- /dev/null +++ b/examples/sharepoint/lists_and_items/listitem_create.py @@ -0,0 +1,40 @@ +from office365.runtime.auth.client_credential import ClientCredential +from office365.sharepoint.client_context import ClientContext +from office365.sharepoint.fields.field_multi_user_value import FieldMultiUserValue +from office365.sharepoint.fields.field_user_value import FieldUserValue +from office365.sharepoint.lists.list_creation_information import ListCreationInformation +from office365.sharepoint.lists.list_template_type import ListTemplateType +from settings import settings +from tests import random_seed + +credentials = ClientCredential(settings['client_credentials']['client_id'], + settings['client_credentials']['client_secret']) +ctx = ClientContext(settings.get('url')).with_credentials(credentials) + +list_title = "Tasks N%s" % random_seed +list_create_info = ListCreationInformation(list_title, + None, + ListTemplateType.TasksWithTimelineAndHierarchy) + +tasks_list = ctx.web.lists.add(list_create_info).execute_query() +current_user = ctx.web.current_user.get().execute_query() + +multi_user_value = FieldMultiUserValue() +multi_user_value.add(FieldUserValue.from_user(current_user)) + +item_to_create = tasks_list.add_item({ + "Title": "New Task", + "AssignedTo": multi_user_value +}).execute_query() + + +multi_user_value_alt = FieldMultiUserValue() +multi_user_value_alt.add(FieldUserValue(current_user.id)) + +item_to_create_alt = tasks_list.add_item({ + "Title": "New Task 2", + "AssignedTo": multi_user_value_alt +}).execute_query() + + +print(f"List item added into list {list_title}") diff --git a/generator/metadata/SharePoint.xml b/generator/metadata/SharePoint.xml index d8ba4f40..39225191 100644 --- a/generator/metadata/SharePoint.xml +++ b/generator/metadata/SharePoint.xml @@ -1 +1 @@ - + diff --git a/office365/sharepoint/customactions/__init__.py b/office365/sharepoint/customactions/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/office365/sharepoint/customactions/custom_action_element.py b/office365/sharepoint/customactions/custom_action_element.py new file mode 100644 index 00000000..928dad32 --- /dev/null +++ b/office365/sharepoint/customactions/custom_action_element.py @@ -0,0 +1,5 @@ +from office365.runtime.client_value import ClientValue + + +class CustomActionElement(ClientValue): + pass diff --git a/office365/sharepoint/customactions/user_custom_action.py b/office365/sharepoint/customactions/user_custom_action.py new file mode 100644 index 00000000..f9c5dce9 --- /dev/null +++ b/office365/sharepoint/customactions/user_custom_action.py @@ -0,0 +1,5 @@ +from office365.sharepoint.base_entity import BaseEntity + + +class UserCustomAction(BaseEntity): + pass diff --git a/office365/sharepoint/folders/folder.py b/office365/sharepoint/folders/folder.py index 1dfc3532..fe4fc08c 100644 --- a/office365/sharepoint/folders/folder.py +++ b/office365/sharepoint/folders/folder.py @@ -12,6 +12,7 @@ from office365.sharepoint.contenttypes.content_type_id import ContentTypeId from office365.sharepoint.files.file_creation_information import FileCreationInformation from office365.sharepoint.listitems.listitem import ListItem +from office365.sharepoint.storagemetrics.storage_metrics import StorageMetrics class Folder(BaseEntity): @@ -138,6 +139,11 @@ def _move_folder_with_files(): self.ensure_property("Files", _move_folder_with_files) return self + @property + def storage_metrics(self): + return self.properties.get("StorageMetrics", + StorageMetrics(self.context, ResourcePath("StorageMetrics", self.resource_path))) + @property def list_item_all_fields(self): """Specifies the list item fields (2) values for the list item corresponding to the folder.""" diff --git a/office365/sharepoint/listitems/list_Item_form_update_value.py b/office365/sharepoint/listitems/list_Item_form_update_value.py new file mode 100644 index 00000000..c4408dcd --- /dev/null +++ b/office365/sharepoint/listitems/list_Item_form_update_value.py @@ -0,0 +1,5 @@ +from office365.runtime.client_value import ClientValue + + +class ListItemFormUpdateValue(ClientValue): + pass diff --git a/office365/sharepoint/lists/list.py b/office365/sharepoint/lists/list.py index ef54375a..a4906cb3 100644 --- a/office365/sharepoint/lists/list.py +++ b/office365/sharepoint/lists/list.py @@ -1,4 +1,5 @@ from office365.runtime.client_result import ClientResult +from office365.runtime.client_value_collection import ClientValueCollection from office365.runtime.queries.delete_entity_query import DeleteEntityQuery from office365.runtime.queries.service_operation_query import ServiceOperationQuery from office365.runtime.resource_path import ResourcePath @@ -9,17 +10,21 @@ from office365.sharepoint.fields.field_collection import FieldCollection from office365.sharepoint.fields.related_field_collection import RelatedFieldCollection from office365.sharepoint.files.checkedOutFileCollection import CheckedOutFileCollection +from office365.sharepoint.files.file import File from office365.sharepoint.folders.folder import Folder from office365.sharepoint.forms.form_collection import FormCollection from office365.sharepoint.listitems.caml.caml_query import CamlQuery from office365.sharepoint.listitems.creation_information_using_path import ListItemCreationInformationUsingPath +from office365.sharepoint.listitems.form_update_value import ListItemFormUpdateValue from office365.sharepoint.listitems.listitem import ListItem from office365.sharepoint.listitems.listItem_collection import ListItemCollection +from office365.sharepoint.pages.wiki_page_creation_information import WikiPageCreationInformation from office365.sharepoint.permissions.securable_object import SecurableObject from office365.sharepoint.usercustomactions.user_custom_action_collection import UserCustomActionCollection from office365.sharepoint.views.view import View from office365.sharepoint.views.view_collection import ViewCollection from office365.sharepoint.webhooks.subscription_collection import SubscriptionCollection +from office365.sharepoint.utilities.utility import Utility class List(SecurableObject): @@ -28,6 +33,46 @@ class List(SecurableObject): def __init__(self, context, resource_path=None): super(List, self).__init__(context, resource_path) + @staticmethod + def get_list_data_as_stream(context, list_full_url, parameters=None): + """ + + :param office365.sharepoint.client_context.ClientContext context: + :param str list_full_url: + :param RenderListDataParameters parameters: + """ + result = ClientResult(None) + payload = { + "listFullUrl": list_full_url, + "parameters": parameters, + } + target_list = context.web.get_list(list_full_url) + qry = ServiceOperationQuery(target_list, "GetListDataAsStream", None, payload, None, result) + context.add_query(qry) + return result + + def bulk_validate_update_list_items(self, item_ids, form_values, new_document_update=True, + checkin_comment=None, folder_path=None): + """ + + :param list[int] item_ids: + :param dict form_values: + :param bool new_document_update: + :param str checkin_comment: + :param str folder_path: + """ + result = ClientValueCollection(ListItemFormUpdateValue) + params = { + "itemIds": item_ids, + "formValues": ClientValueCollection(ListItemFormUpdateValue, form_values), + "bNewDocumentUpdate": new_document_update, + "checkInComment": checkin_comment, + "folderPath": folder_path + } + qry = ServiceOperationQuery(self, "BulkValidateUpdateListItems", None, params, None, result) + self.context.add_query(qry) + return result + def get_lookup_field_choices(self, targetFieldName, pagingInfo=None): result = ClientResult(str) params = { @@ -133,6 +178,21 @@ def _resolve_folder_url(): self.root_folder.ensure_property("ServerRelativeUrl", _resolve_folder_url) return item + def create_wiki_page(self, page_name, page_content): + """ + :param str page_name: + :param str page_content: + """ + result = ClientResult(File) + + def _list_loaded(): + page_url = self.root_folder.serverRelativeUrl + "/" + page_name + wiki_props = WikiPageCreationInformation(page_url, page_content) + result.value = Utility.create_wiki_page_in_context_web(self.context, wiki_props) + self.ensure_property("RootFolder", _list_loaded) + + return result + def add_item_using_path(self, leaf_name, object_type, folder_url): """ :type leaf_name: str @@ -201,17 +261,6 @@ def delete_object(self): self.remove_from_parent_collection() return self - @staticmethod - def get_list_data_as_stream(context, listFullUrl, parameters): - """ - - :type context: ClientContext - :type listFullUrl: str - :type parameters: RenderListDataParameters - :return: - """ - pass - @property def enable_folder_creation(self): """ diff --git a/office365/sharepoint/pages/wiki_page_creation_information.py b/office365/sharepoint/pages/wiki_page_creation_information.py index 0e62f3c5..68659054 100644 --- a/office365/sharepoint/pages/wiki_page_creation_information.py +++ b/office365/sharepoint/pages/wiki_page_creation_information.py @@ -4,6 +4,15 @@ class WikiPageCreationInformation(ClientValue): def __init__(self, server_relative_url, content): + """ + + :param str server_relative_url: + :param str content: + """ super().__init__() self.ServerRelativeUrl = server_relative_url self.WikiHtmlContent = content + + @property + def entity_type_name(self): + return "SP.Utilities.WikiPageCreationInformation" diff --git a/office365/sharepoint/storagemetrics/__init__.py b/office365/sharepoint/storagemetrics/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/office365/sharepoint/storagemetrics/storage_metrics.py b/office365/sharepoint/storagemetrics/storage_metrics.py new file mode 100644 index 00000000..18fb36c8 --- /dev/null +++ b/office365/sharepoint/storagemetrics/storage_metrics.py @@ -0,0 +1,5 @@ +from office365.sharepoint.base_entity import BaseEntity + + +class StorageMetrics(BaseEntity): + pass diff --git a/office365/sharepoint/utilities/principal_info.py b/office365/sharepoint/utilities/principal_info.py new file mode 100644 index 00000000..4807b125 --- /dev/null +++ b/office365/sharepoint/utilities/principal_info.py @@ -0,0 +1,5 @@ +from office365.runtime.client_value import ClientValue + + +class PrincipalInfo(ClientValue): + pass diff --git a/office365/sharepoint/utilities/upload_status.py b/office365/sharepoint/utilities/upload_status.py new file mode 100644 index 00000000..ef137934 --- /dev/null +++ b/office365/sharepoint/utilities/upload_status.py @@ -0,0 +1,5 @@ +from office365.runtime.client_value import ClientValue + + +class UploadStatus(ClientValue): + pass diff --git a/office365/sharepoint/utilities/utility.py b/office365/sharepoint/utilities/utility.py index 61347e89..16a0bc53 100644 --- a/office365/sharepoint/utilities/utility.py +++ b/office365/sharepoint/utilities/utility.py @@ -3,6 +3,7 @@ from office365.runtime.queries.service_operation_query import ServiceOperationQuery from office365.runtime.resource_path import ResourcePath from office365.sharepoint.base_entity import BaseEntity +from office365.sharepoint.files.file import File class Utility(BaseEntity): @@ -59,6 +60,19 @@ def search_principals_using_context_web(context, s_input, sources, scopes, maxCo context.add_query(qry) return result + @staticmethod + def create_wiki_page_in_context_web(context, parameters): + """ + :type context: office365.sharepoint.client_context.ClientContext + :type parameters: office365.sharepoint.pages.wiki_page_creation_information.WikiPageCreationInformation + """ + return_file = File(context) + utility = Utility(context) + qry = ServiceOperationQuery(utility, "CreateWikiPageInContextWeb", None, parameters, "parameters", return_file) + qry.static = True + context.add_query(qry) + return return_file + @staticmethod def send_email(context, properties): """ diff --git a/office365/sharepoint/utilities/wopi_properties.py b/office365/sharepoint/utilities/wopi_properties.py new file mode 100644 index 00000000..edb0288a --- /dev/null +++ b/office365/sharepoint/utilities/wopi_properties.py @@ -0,0 +1,5 @@ +from office365.runtime.client_value import ClientValue + + +class WopiProperties(ClientValue): + pass diff --git a/office365/sharepoint/utilities/wopi_web_app_properties.py b/office365/sharepoint/utilities/wopi_web_app_properties.py new file mode 100644 index 00000000..74ce8c8a --- /dev/null +++ b/office365/sharepoint/utilities/wopi_web_app_properties.py @@ -0,0 +1,5 @@ +from office365.runtime.client_value import ClientValue + + +class WopiWebAppProperties(ClientValue): + pass diff --git a/office365/sharepoint/webs/remote_web.py b/office365/sharepoint/webs/remote_web.py index 90d135d1..f16f00ff 100644 --- a/office365/sharepoint/webs/remote_web.py +++ b/office365/sharepoint/webs/remote_web.py @@ -1,3 +1,4 @@ +from office365.onedrive.list import List from office365.runtime.client_object import ClientObject from office365.runtime.queries.service_operation_query import ServiceOperationQuery from office365.runtime.resource_path import ResourcePath @@ -7,6 +8,12 @@ class RemoteWeb(ClientObject): """Specifies a remote web that might be on a different domain.""" + def get_list_by_server_relative_url(self, serverRelativeUrl): + target_list = List(self.context) + qry = ServiceOperationQuery(self, "GetListByServerRelativeUrl", [serverRelativeUrl], None, None, target_list) + self.context.add_query(qry) + return target_list + @staticmethod def create(context, requestUrl): remote_web = RemoteWeb(context) diff --git a/office365/sharepoint/webs/web.py b/office365/sharepoint/webs/web.py index e8006837..572a6d46 100644 --- a/office365/sharepoint/webs/web.py +++ b/office365/sharepoint/webs/web.py @@ -57,7 +57,7 @@ def __init__(self, context, resource_path=None): @staticmethod def get_web_url_from_page_url(context, page_full_url): - """Determine whether site exists + """Gets Web from page url :type context: office365.sharepoint.client_context.ClientContext :type page_full_url: str @@ -222,9 +222,6 @@ def get_folder_by_server_relative_url(self, url): """Returns the folder object located at the specified server-relative URL. :type url: str """ - if url.startswith("/"): - url = url[1:] - return Folder( self.context, ResourcePathServiceOperation("getFolderByServerRelativeUrl", [url], self.resource_path) diff --git a/tests/sharepoint/test_list.py b/tests/sharepoint/test_list.py index 083c643d..86e3ffb4 100644 --- a/tests/sharepoint/test_list.py +++ b/tests/sharepoint/test_list.py @@ -126,3 +126,7 @@ def test_16_get_list_using_path(self): def test_17_ensure_events_list(self): events_list = self.client.web.lists.ensure_events_list().execute_query() self.assertIsNotNone(events_list.resource_path) + + def test_18_get_list_by_server_relative_url(self): + pages_list = self.client.web.get_list("SitePages").get().execute_query() + self.assertIsNotNone(pages_list.resource_path) diff --git a/tests/sharepoint/test_pages.py b/tests/sharepoint/test_pages.py new file mode 100644 index 00000000..5ec94876 --- /dev/null +++ b/tests/sharepoint/test_pages.py @@ -0,0 +1,27 @@ +from office365.sharepoint.files.file import File +from office365.sharepoint.lists.list import List +from tests.sharepoint.sharepoint_case import SPTestCase + + +class TestPages(SPTestCase): + pages_list = None # type: List + target_file = None # type: File + + @classmethod + def setUpClass(cls): + super(TestPages, cls).setUpClass() + + def test1_ensure_site_pages_library(self): + pages_list = self.client.web.lists.ensure_site_pages_library().execute_query() + self.assertIsNotNone(pages_list.resource_path) + self.__class__.pages_list = pages_list + + def test2_create_wiki_page(self): + page_name = "WelcomeWikiPage.aspx" + result = self.__class__.pages_list.create_wiki_page(page_name, "Wiki content") + self.client.execute_query() + self.assertIsNotNone(result.value) + self.__class__.target_file = result.value + + def test3_delete_page(self): + self.__class__.target_file.delete_object().execute_query()