Skip to content

Commit

Permalink
SharePoint namespace new types & methods (StorageMetrics, CustomActio…
Browse files Browse the repository at this point in the history
…nElement), bug fixes: #307 - address file by server relative url
  • Loading branch information
vvgrem@gmail.com authored and vvgrem@gmail.com committed Jan 7, 2021
1 parent 4999e19 commit 16d115f
Show file tree
Hide file tree
Showing 20 changed files with 209 additions and 16 deletions.
40 changes: 40 additions & 0 deletions 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}")
2 changes: 1 addition & 1 deletion generator/metadata/SharePoint.xml

Large diffs are not rendered by default.

Empty file.
5 changes: 5 additions & 0 deletions office365/sharepoint/customactions/custom_action_element.py
@@ -0,0 +1,5 @@
from office365.runtime.client_value import ClientValue


class CustomActionElement(ClientValue):
pass
5 changes: 5 additions & 0 deletions office365/sharepoint/customactions/user_custom_action.py
@@ -0,0 +1,5 @@
from office365.sharepoint.base_entity import BaseEntity


class UserCustomAction(BaseEntity):
pass
6 changes: 6 additions & 0 deletions office365/sharepoint/folders/folder.py
Expand Up @@ -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):
Expand Down Expand Up @@ -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."""
Expand Down
5 changes: 5 additions & 0 deletions office365/sharepoint/listitems/list_Item_form_update_value.py
@@ -0,0 +1,5 @@
from office365.runtime.client_value import ClientValue


class ListItemFormUpdateValue(ClientValue):
pass
71 changes: 60 additions & 11 deletions 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
Expand All @@ -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):
Expand All @@ -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 = {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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):
"""
Expand Down
9 changes: 9 additions & 0 deletions office365/sharepoint/pages/wiki_page_creation_information.py
Expand Up @@ -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"
Empty file.
5 changes: 5 additions & 0 deletions office365/sharepoint/storagemetrics/storage_metrics.py
@@ -0,0 +1,5 @@
from office365.sharepoint.base_entity import BaseEntity


class StorageMetrics(BaseEntity):
pass
5 changes: 5 additions & 0 deletions office365/sharepoint/utilities/principal_info.py
@@ -0,0 +1,5 @@
from office365.runtime.client_value import ClientValue


class PrincipalInfo(ClientValue):
pass
5 changes: 5 additions & 0 deletions office365/sharepoint/utilities/upload_status.py
@@ -0,0 +1,5 @@
from office365.runtime.client_value import ClientValue


class UploadStatus(ClientValue):
pass
14 changes: 14 additions & 0 deletions office365/sharepoint/utilities/utility.py
Expand Up @@ -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):
Expand Down Expand Up @@ -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):
"""
Expand Down
5 changes: 5 additions & 0 deletions office365/sharepoint/utilities/wopi_properties.py
@@ -0,0 +1,5 @@
from office365.runtime.client_value import ClientValue


class WopiProperties(ClientValue):
pass
5 changes: 5 additions & 0 deletions office365/sharepoint/utilities/wopi_web_app_properties.py
@@ -0,0 +1,5 @@
from office365.runtime.client_value import ClientValue


class WopiWebAppProperties(ClientValue):
pass
7 changes: 7 additions & 0 deletions 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
Expand All @@ -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)
Expand Down
5 changes: 1 addition & 4 deletions office365/sharepoint/webs/web.py
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions tests/sharepoint/test_list.py
Expand Up @@ -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)
27 changes: 27 additions & 0 deletions 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()

0 comments on commit 16d115f

Please sign in to comment.