Skip to content

Commit

Permalink
Release 2.3.1: SharePoint namespaces (fields, tenant and etc) improve…
Browse files Browse the repository at this point in the history
…ments, bug fixes (#303, #265)
  • Loading branch information
vvgrem@gmail.com authored and vvgrem@gmail.com committed Dec 13, 2020
1 parent d85f717 commit 5dbbf60
Show file tree
Hide file tree
Showing 21 changed files with 237 additions and 75 deletions.
13 changes: 3 additions & 10 deletions examples/sharepoint/files/upload_large_file.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import functools
import os
from settings import settings

Expand All @@ -13,7 +12,7 @@
target_folder = ctx.web.get_folder_by_server_relative_url(target_url)
size_chunk = 1000000
local_path = "../../../tests/data/big_buck_bunny.mp4"

# local_path = "../../../tests/data/SharePoint User Guide.docx"

file_size = os.path.getsize(local_path)

Expand All @@ -22,12 +21,6 @@ def print_upload_progress(offset):
print("Uploaded '{}' bytes from '{}'...[{}%]".format(offset, file_size, round(offset / file_size * 100, 2)))


if file_size > size_chunk:
result_file = target_folder.files.create_upload_session(local_path, size_chunk, print_upload_progress)
else:
with open(local_path, 'rb') as content_file:
file_content = content_file.read()
name = os.path.basename(local_path)
result_file = target_folder.upload_file(name, file_content)
uploaded_file = target_folder.files.create_upload_session(local_path, size_chunk, print_upload_progress)
ctx.execute_query()
print('File {0} has been uploaded successfully'.format(result_file.serverRelativeUrl))
print('File {0} has been uploaded successfully'.format(uploaded_file.serverRelativeUrl))
21 changes: 21 additions & 0 deletions office365/sharepoint/fields/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ def create_field_from_type(context, field_parameters):
field.set_property(n, v)
return field

def enable_index(self):
pass

def disable_index(self):
pass

def set_show_in_display_form(self, flag):
"""Sets the value of the ShowInDisplayForm property for this fields.
Expand Down Expand Up @@ -96,6 +102,21 @@ def id(self):
"""
return self.properties.get('Id', None)

@property
def schema_xml(self):
"""Gets a value that specifies the XML schema that defines the field.
:rtype: str or None
"""
return self.properties.get('SchemaXml', None)

@schema_xml.setter
def schema_xml(self, val):
"""Sets a value that specifies the XML schema that defines the field.
"""
self.set_property('SchemaXml', val)

@property
def type_as_string(self):
"""Gets a value that specifies the type of the field..
Expand Down
55 changes: 55 additions & 0 deletions office365/sharepoint/fields/field_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from office365.runtime.resource_path_service_operation import ResourcePathServiceOperation
from office365.sharepoint.base_entity_collection import BaseEntityCollection
from office365.sharepoint.fields.field import Field
from office365.sharepoint.fields.field_creation_information import FieldCreationInformation
from office365.sharepoint.fields.field_type import FieldType
from office365.sharepoint.fields.xmlSchemaFieldCreationInformation import XmlSchemaFieldCreationInformation


Expand All @@ -18,6 +20,59 @@ def create_typed_object(self, properties):
field = super(FieldCollection, self).create_typed_object(properties)
return field

def add_url_field(self, title, description=None):
"""
Adds Url field
:param str title:
:param str or None description:
:return:
"""
create_field_info = FieldCreationInformation(title=title,
description=description,
field_type_kind=FieldType.URL)
return self.add(create_field_info)

def add_lookup_field(self, title, lookup_list_id, lookup_field_name, allow_multiple_values=False):
"""
Adds Lookup field
:param bool allow_multiple_values:
:param str lookup_field_name:
:param str lookup_list_id:
:param str title:
"""
if allow_multiple_values:
field_schema = f'''
<Field Type="LookupMulti" Mult="TRUE" DisplayName="{title}" Required="FALSE" Hidden="TRUE" \
ShowField="{lookup_field_name}" List="{{{lookup_list_id}}}" StaticName="{title}" Name="{title}">
</Field>
'''
target_field = self.create_field_as_xml(field_schema)
else:
create_field_info = FieldCreationInformation(title=title,
lookup_list_id=lookup_list_id,
lookup_field_name=lookup_field_name,
field_type_kind=FieldType.Lookup)
target_field = self.add_field(create_field_info)
return target_field

def add_choice_field(self, title, values, multiple_values=False):
"""
Adds Choice field
:param bool multiple_values:
:param list[str] values:
:param str title:
"""
fld_type = FieldType.MultiChoice if multiple_values else FieldType.Choice
create_field_info = FieldCreationInformation(title, fld_type)
[create_field_info.Choices.add(choice) for choice in values]
return self.add_field(create_field_info)

def add_user_field(self):
pass

def add(self, field_create_information):
"""Adds a fields to the fields collection.
Expand Down
3 changes: 2 additions & 1 deletion office365/sharepoint/fields/field_creation_information.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ def __init__(self, title, field_type_kind, description=None,
self.Title = title
self.FieldTypeKind = field_type_kind
self.Description = description
self.Choices = ClientValueCollection(str) if field_type_kind == FieldType.MultiChoice else None
self.Choices = ClientValueCollection(str) \
if field_type_kind == FieldType.MultiChoice or field_type_kind == FieldType.Choice else None
self.LookupListId = lookup_list_id
self.LookupFieldName = lookup_field_name
self.LookupWebId = lookup_web_id
Expand Down
13 changes: 13 additions & 0 deletions office365/sharepoint/fields/field_lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ def __init__(self, context):
"""Specifies a lookup field."""
super().__init__(context)

@property
def allow_multiple_values(self):
"""Gets a value that specifies whether the lookup field allows multiple values.
:rtype: bool or None
"""
return self.properties.get('AllowMultipleValues', None)

@allow_multiple_values.setter
def allow_multiple_values(self, value):
"""Sets a value that specifies whether the lookup field allows multiple values.
"""
self.set_property('AllowMultipleValues', value)

@property
def lookup_web_id(self):
"""Gets the ID of the Web site that contains the list that is the source of this field's value.
Expand Down
18 changes: 15 additions & 3 deletions office365/sharepoint/files/file_collection.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import os

from office365.runtime.client_object_collection import ClientObjectCollection
from office365.runtime.queries.service_operation_query import ServiceOperationQuery
from office365.runtime.resource_path_service_operation import ResourcePathServiceOperation
from office365.sharepoint.actions.create_file import CreateFileQuery
from office365.sharepoint.actions.upload_session import UploadSessionQuery
from office365.sharepoint.files.file import File
from office365.sharepoint.files.file_creation_information import FileCreationInformation


class FileCollection(ClientObjectCollection):
Expand All @@ -28,9 +31,18 @@ def create_upload_session(self, source_path, chunk_size, chunk_uploaded=None, *c
:param chunk_func_args: arguments to pass to chunk_uploaded function
:return: office365.sharepoint.files.file.File
"""
qry = UploadSessionQuery(self, source_path, chunk_size, chunk_uploaded, chunk_func_args)
self.context.add_query(qry)
return qry.file
file_size = os.path.getsize(source_path)
if file_size > chunk_size:
qry = UploadSessionQuery(self, source_path, chunk_size, chunk_uploaded, chunk_func_args)
self.context.add_query(qry)
return qry.file
else:
with open(source_path, 'rb') as content_file:
file_content = content_file.read()
info = FileCreationInformation(url=os.path.basename(source_path), overwrite=True, content=file_content)
qry = CreateFileQuery(self, info)
self.context.add_query(qry)
return qry.return_type

def add(self, file_creation_information):
"""Creates a File resource
Expand Down
4 changes: 2 additions & 2 deletions office365/sharepoint/listitems/listitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
from office365.sharepoint.fields.fieldMultiLookupValue import FieldMultiLookupValue
from office365.sharepoint.permissions.securable_object import SecurableObject
from office365.sharepoint.sharing.externalSharingSiteOption import ExternalSharingSiteOption
from office365.sharepoint.sharing.objectSharingInformation import ObjectSharingInformation
from office365.sharepoint.sharing.sharingResult import SharingResult
from office365.sharepoint.sharing.object_sharing_information import ObjectSharingInformation
from office365.sharepoint.sharing.sharing_result import SharingResult
from office365.sharepoint.ui.applicationpages.clientPeoplePickerQueryParameters import ClientPeoplePickerQueryParameters
from office365.sharepoint.ui.applicationpages.clientPeoplePickerWebServiceInterface import (
ClientPeoplePickerWebServiceInterface,
Expand Down
2 changes: 1 addition & 1 deletion office365/sharepoint/sharing/objectSharingSettings.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from office365.runtime.resource_path import ResourcePath
from office365.sharepoint.base_entity import BaseEntity
from office365.sharepoint.sharing.objectSharingInformation import ObjectSharingInformation
from office365.sharepoint.sharing.object_sharing_information import ObjectSharingInformation


class ObjectSharingSettings(BaseEntity):
Expand Down
File renamed without changes.
22 changes: 22 additions & 0 deletions office365/sharepoint/tenant/administration/tenant.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from office365.runtime.client_result import ClientResult
from office365.runtime.client_value_collection import ClientValueCollection
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.publishing.portal_health_status import PortalHealthStatus
from office365.sharepoint.tenant.administration.hubSiteProperties import HubSiteProperties
from office365.sharepoint.tenant.administration.secondary_administrators_fields_data import \
SecondaryAdministratorsFieldsData
Expand All @@ -18,6 +20,26 @@ def __init__(self, context):
super().__init__(context, ResourcePath("Microsoft.Online.SharePoint.TenantAdministration.Tenant"),
"Microsoft.Online.SharePoint.TenantAdministration")

def check_tenant_licenses(self, licenses):
"""
Checks whether a tenant has the specified licenses.
:param list[str] licenses: The list of licenses to check for.
:return:
"""
result = ClientResult(bool)
params = ClientValueCollection(str, licenses)
qry = ServiceOperationQuery(self, "CheckTenantLicenses", None, params, "licenses", result)
self.context.add_query(qry)
return result

def get_site_health_status(self, sourceUrl):
result = ClientResult(PortalHealthStatus)
params = {"sourceUrl": sourceUrl}
qry = ServiceOperationQuery(self, "GetSiteHealthStatus", None, params, None, result)
self.context.add_query(qry)
return result

def get_site_secondary_administrators(self, site_id):
"""
Gets site collection administrators
Expand Down
12 changes: 12 additions & 0 deletions office365/sharepoint/views/view.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from office365.runtime.client_result import ClientResult
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 Down Expand Up @@ -45,6 +46,12 @@ def delete_object(self):
self.remove_from_parent_collection()
return self

def render_as_html(self):
result = ClientResult(str)
qry = ServiceOperationQuery(self, "RenderAsHtml", None, None, None, result)
self.context.add_query(qry)
return result

@property
def content_type_id(self):
"""Gets the identifier of the content type with which the view is associated.
Expand Down Expand Up @@ -96,6 +103,11 @@ def view_query(self):
"""Gets or sets a value that specifies the query that is used by the list view."""
return self.properties.get('ViewQuery', None)

@property
def base_view_id(self):
"""Gets a value that specifies the base view identifier of the list view."""
return self.properties.get('BaseViewId', None)

def set_property(self, name, value, persist_changes=True):
super(View, self).set_property(name, value, persist_changes)
# fallback: create a new resource path
Expand Down
2 changes: 1 addition & 1 deletion office365/sharepoint/webs/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from office365.sharepoint.recyclebin.recycleBinItemCollection import RecycleBinItemCollection
from office365.sharepoint.sharing.externalSharingSiteOption import ExternalSharingSiteOption
from office365.sharepoint.sharing.objectSharingSettings import ObjectSharingSettings
from office365.sharepoint.sharing.sharingResult import SharingResult
from office365.sharepoint.sharing.sharing_result import SharingResult
from office365.sharepoint.ui.applicationpages.clientPeoplePickerQueryParameters import ClientPeoplePickerQueryParameters
from office365.sharepoint.ui.applicationpages.clientPeoplePickerWebServiceInterface import (
ClientPeoplePickerWebServiceInterface,
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

setup(
name="Office365-REST-Python-Client",
version="2.3.0.1",
version="2.3.1",
author="Vadim Gremyachev",
author_email="vvgrem@gmail.com",
maintainer="Konrad Gądek, Domenico Di Nicola",
Expand Down

0 comments on commit 5dbbf60

Please sign in to comment.