Skip to content

Commit b59e027

Browse files
committed
planner & todo new types and methods
1 parent fc2705d commit b59e027

File tree

25 files changed

+314
-20
lines changed

25 files changed

+314
-20
lines changed

examples/onedrive/files/get_permissions.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@
1414
file_item = client.me.drive.root.get_by_path(file_path)
1515
permissions = file_item.permissions.get().execute_query()
1616
for perm in permissions:
17-
print(perm.granted_to_v2)
17+
print(perm.granted_to_v2)

examples/planner/create_task.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@
1515
plans = group.planner.plans.get().execute_query()
1616
if len(plans) == 0:
1717
sys.exit("No plans were found")
18-
task = plans[0].tasks.add(title="New task").execute_query()
18+
task = client.planner.tasks.add("Update client list", plans[0]).execute_query()
1919
print("Task {0} has been created".format(task.title))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from office365.runtime.client_value import ClientValue
2+
3+
4+
class FileSecurityState(ClientValue):
5+
"""Contains information about the file (not process) related to the alert."""

office365/onedrive/workbooks/charts/title.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class WorkbookChartTitle(Entity):
88

99
@property
1010
def format(self):
11-
""" The formatting of a chart title, which includes fill and font formatting."""
11+
"""The formatting of a chart title, which includes fill and font formatting."""
1212
return self.properties.get(
1313
"format",
1414
WorkbookChartTitleFormat(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from office365.runtime.client_value import ClientValue
2+
3+
4+
class PlannerCategoryDescriptions(ClientValue):
5+
"""Represents the descriptive labels for the categories that have been defined for a plan.
6+
It belongs to the plan details object. There can be up to 25 categories defined."""
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from office365.runtime.client_value import ClientValue
2+
3+
4+
class PlannerExternalReferences(ClientValue):
5+
"""The plannerExternalReferences resource represents the collection of references on a task. This is an Open Type.
6+
It's part of the task details object. The value in the property-value pair is the externalReference object.
7+
"""

office365/planner/planner.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from office365.entity_collection import EntityCollection
33
from office365.planner.buckets.bucket import PlannerBucket
44
from office365.planner.plans.collection import PlannerPlanCollection
5-
from office365.planner.tasks.task import PlannerTask
5+
from office365.planner.tasks.collection import PlannerTaskCollection
66
from office365.runtime.paths.resource_path import ResourcePath
77

88

@@ -25,12 +25,12 @@ def buckets(self):
2525

2626
@property
2727
def tasks(self):
28-
# type: () -> EntityCollection[PlannerTask]
28+
# type: () -> PlannerTaskCollection
2929
"""Returns the plannerTasks assigned to the user."""
3030
return self.properties.get(
3131
"tasks",
32-
EntityCollection(
33-
self.context, PlannerTask, ResourcePath("tasks", self.resource_path)
32+
PlannerTaskCollection(
33+
self.context, ResourcePath("tasks", self.resource_path)
3434
),
3535
)
3636

office365/planner/plans/container.py

+12
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,15 @@ class PlannerPlanContainer(ClientValue):
99
the contained plans are also deleted. The properties of the plannerPlanContainer cannot be changed after the plan
1010
is created.
1111
"""
12+
13+
def __init__(self, container_id=None, type_=None, url=None):
14+
"""
15+
:param str container_id: The identifier of the resource that contains the plan
16+
:param str type_: The type of the resource that contains the plan. For supported types, see the previous
17+
table. Possible values are: group, unknownFutureValue, roster. Use the Prefer: include-unknown-enum-members
18+
request header to get the following value in this evolvable enum: roster.
19+
:param str url: The full canonical URL of the container.
20+
"""
21+
self.containerId = container_id
22+
self.type = type_
23+
self.url = url

office365/planner/plans/details.py

+31
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,39 @@
11
from office365.entity import Entity
2+
from office365.planner.category_descriptions import PlannerCategoryDescriptions
3+
from office365.planner.user_ids import PlannerUserIds
24

35

46
class PlannerPlanDetails(Entity):
57
"""
68
The plannerPlanDetails resource represents the additional information about a plan.
79
Each plan object has a details object.
810
"""
11+
12+
@property
13+
def category_descriptions(self):
14+
# type: () -> PlannerCategoryDescriptions
15+
"""
16+
An object that specifies the descriptions of the 25 categories that can be associated with tasks in the plan.
17+
"""
18+
return self.properties.get(
19+
"categoryDescriptions", PlannerCategoryDescriptions()
20+
)
21+
22+
@property
23+
def shared_with(self):
24+
# type: () -> PlannerUserIds
25+
"""
26+
Set of user IDs that this plan is shared with. If you're using Microsoft 365 groups, use the Groups
27+
API to manage group membership to share the group's plan. You can also add existing members of the group to
28+
this collection, although it isn't required for them to access the plan owned by the group.
29+
"""
30+
return self.properties.get("sharedWith", PlannerUserIds())
31+
32+
def get_property(self, name, default_value=None):
33+
if default_value is None:
34+
property_mapping = {
35+
"categoryDescriptions": self.category_descriptions,
36+
"sharedWith": self.shared_with,
37+
}
38+
default_value = property_mapping.get(name, None)
39+
return super(PlannerPlanDetails, self).get_property(name, default_value)

office365/planner/tasks/collection.py

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from office365.entity_collection import EntityCollection
2+
from office365.planner.plans.plan import PlannerPlan
3+
from office365.planner.tasks.task import PlannerTask
4+
from office365.runtime.queries.create_entity import CreateEntityQuery
5+
6+
7+
class PlannerTaskCollection(EntityCollection[PlannerTask]):
8+
def __init__(self, context, resource_path=None):
9+
super(PlannerTaskCollection, self).__init__(context, PlannerTask, resource_path)
10+
11+
def add(self, title, plan, bucket=None):
12+
"""
13+
Create a new plannerTask.
14+
15+
:param str title: Task title
16+
:param str|PlannerPlan plan: Plan identifier or Plan object
17+
:param str|PlannerBucket bucket: Bucket identifier or Plan object
18+
"""
19+
return_type = PlannerTask(self.context)
20+
self.add_child(return_type)
21+
22+
def _add(plan_id):
23+
# type: (str) -> None
24+
payload = {"title": title, "planId": plan_id, "bucketId": bucket}
25+
qry = CreateEntityQuery(self, payload, return_type)
26+
self.context.add_query(qry)
27+
28+
if isinstance(plan, PlannerPlan):
29+
30+
def _parent_loaded():
31+
_add(plan.id)
32+
33+
plan.ensure_property("id", _parent_loaded)
34+
else:
35+
_add(plan)
36+
37+
return return_type

office365/planner/tasks/task.py

+24
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
from datetime import datetime
2+
3+
from office365.directory.permissions.identity_set import IdentitySet
14
from office365.entity import Entity
25
from office365.planner.tasks.task_details import PlannerTaskDetails
36
from office365.runtime.paths.resource_path import ResourcePath
@@ -11,6 +14,18 @@ class PlannerTask(Entity):
1114
See overview for more information regarding relationships between group, plan and task.
1215
"""
1316

17+
@property
18+
def created_by(self):
19+
"""Identity of the user that created the task."""
20+
return self.properties.get("createdBy", IdentitySet())
21+
22+
@property
23+
def created_datetime(self):
24+
"""
25+
Date and time at which the task is created.
26+
"""
27+
return self.properties.get("createdDateTime", datetime.min)
28+
1429
@property
1530
def title(self):
1631
"""Required. Title of the task."""
@@ -25,3 +40,12 @@ def details(self):
2540
self.context, ResourcePath("details", self.resource_path)
2641
),
2742
)
43+
44+
def get_property(self, name, default_value=None):
45+
if default_value is None:
46+
property_mapping = {
47+
"createdBy": self.created_by,
48+
"createdDateTime": self.created_datetime,
49+
}
50+
default_value = property_mapping.get(name, None)
51+
return super(PlannerTask, self).get_property(name, default_value)
+34-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
from typing import Optional
2+
13
from office365.entity import Entity
4+
from office365.planner.external_references import PlannerExternalReferences
5+
from office365.planner.tasks.check_list_items import PlannerChecklistItems
26

37

48
class PlannerTaskDetails(Entity):
@@ -7,4 +11,33 @@ class PlannerTaskDetails(Entity):
711
Each task object has a details object.
812
"""
913

10-
pass
14+
@property
15+
def checklist(self):
16+
# type: () -> PlannerChecklistItems
17+
"""
18+
The collection of checklist items on the task.
19+
"""
20+
return self.properties.get("checklist", PlannerChecklistItems())
21+
22+
@property
23+
def description(self):
24+
# type: () -> Optional[str]
25+
"""Description of the task."""
26+
return self.properties.get("description", None)
27+
28+
@property
29+
def preview_type(self):
30+
# type: () -> Optional[str]
31+
"""This sets the type of preview that shows up on the task.
32+
The possible values are: automatic, noPreview, checklist, description, reference.
33+
When set to automatic the displayed preview is chosen by the app viewing the task.
34+
"""
35+
return self.properties.get("previewType", None)
36+
37+
@property
38+
def references(self):
39+
# type: () -> PlannerExternalReferences
40+
"""
41+
The collection of references on the task.
42+
"""
43+
return self.properties.get("references", PlannerExternalReferences())

office365/planner/user_ids.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from office365.runtime.client_value import ClientValue
2+
3+
4+
class PlannerUserIds(ClientValue):
5+
"""The plannerUserIds resource represents the list of users IDs that a plan is shared with, and is an Open Type.
6+
If you're using Microsoft 365 groups, use the Groups API to manage group membership to share the group's plan.
7+
You can also add existing members of the group to this collection though it isn't required for them to access
8+
the plan owned by the group."""

office365/runtime/odata/request.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def _next_property(self, json, json_format):
9999
elif isinstance(json, dict):
100100
for name, value in json.items():
101101
if isinstance(json_format, JsonLightFormat):
102-
is_valid = name != "__metadata" and not (
102+
is_valid = name != json_format.metadata_type and not (
103103
isinstance(value, dict) and "__deferred" in value
104104
)
105105
else:

office365/runtime/odata/v3/json_light_format.py

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ def collection_delta(self):
3434
def metadata_type(self):
3535
return "__metadata"
3636

37+
@property
38+
def deferred_type(self):
39+
return "__deferred"
40+
3741
@property
3842
def value_tag(self):
3943
return "__value"

office365/sharepoint/files/file.py

+13
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,19 @@ def activity_capabilities(self):
717717
""""""
718718
return self.properties.get("ActivityCapabilities", ActivityCapabilities())
719719

720+
@property
721+
def checkin_comment(self):
722+
# type: () -> Optional[str]
723+
"""Specifies the comment used when a document is checked into a document library.
724+
Its length MUST be equal to or less than 1023."""
725+
return self.properties.get("CheckInComment", None)
726+
727+
@property
728+
def content_tag(self):
729+
# type: () -> Optional[str]
730+
"""Returns internal version of content, used to validate document equality for read purposes."""
731+
return self.properties.get("ContentTag", None)
732+
720733
@property
721734
def author(self):
722735
"""Specifies the user who added the file."""

office365/sharepoint/storagemetrics/storage_metrics.py

+18
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
class StorageMetrics(Entity):
88
"""Specifies the storage-related metrics for list folders in the site"""
99

10+
@property
11+
def additional_file_stream_size(self):
12+
# type: () -> Optional[int]
13+
""" """
14+
return self.properties.get("AdditionalFileStreamSize", None)
15+
1016
@property
1117
def last_modified(self):
1218
# type: () -> Optional[datetime.datetime]
@@ -41,3 +47,15 @@ def total_size(self):
4147
Total size for a file/folder includes stream, version, and metadata sizes.
4248
"""
4349
return self.properties.get("TotalSize", None)
50+
51+
@property
52+
def version_count(self):
53+
# type: () -> Optional[int]
54+
""" """
55+
return self.properties.get("VersionCount", None)
56+
57+
@property
58+
def version_size(self):
59+
# type: () -> Optional[int]
60+
""" """
61+
return self.properties.get("VersionSize", None)

office365/sharepoint/webs/regional_settings.py

+27
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,33 @@ def first_week_of_year(self):
9696
Specifies which week of a year is considered the first week."""
9797
return self.properties.get("FirstWeekOfYear", None)
9898

99+
@property
100+
def is_east_asia(self):
101+
# type: () -> Optional[bool]
102+
"""Returns "true" if the web locale is an East Asia locale; "false" otherwise."""
103+
return self.properties.get("IsEastAsia", None)
104+
105+
@property
106+
def is_right_to_left(self):
107+
# type: () -> Optional[bool]
108+
"""Specifies whether the site uses a right-to-left language. If it uses a right-to-left language,
109+
this value MUST be "true". Otherwise, this value MUST be "false"."""
110+
return self.properties.get("IsRightToLeft", None)
111+
112+
@property
113+
def is_ui_right_to_left(self):
114+
# type: () -> Optional[bool]
115+
"""Specifies whether the UI of the site (2) uses a right-to-left language. If it uses a right-to-left language,
116+
this value MUST be "true". Otherwise, this value MUST be "false"."""
117+
return self.properties.get("IsUIRightToLeft", None)
118+
119+
@property
120+
def list_separator(self):
121+
# type: () -> Optional[str]
122+
"""Specifies the separator that is used for lists on the server. For example, if the separator is ",",
123+
items in a list will appear as "1,2,3,4"."""
124+
return self.properties.get("ListSeparator", None)
125+
99126
@property
100127
def locale_id(self):
101128
# type: () -> Optional[int]

office365/todo/attachments/task_file.py

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from typing import AnyStr, Optional
2+
13
from office365.todo.attachments.base import AttachmentBase
24

35

@@ -10,5 +12,6 @@ class TaskFileAttachment(AttachmentBase):
1012

1113
@property
1214
def content_bytes(self):
15+
# type: () -> Optional[AnyStr]
1316
"""The base64-encoded contents of the file."""
1417
return self.properties.get("contentBytes", None)

office365/todo/checklist_item.py

+11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
1+
from typing import Optional
2+
13
from office365.entity import Entity
24

35

46
class ChecklistItem(Entity):
57
"""Represents a subtask in a bigger todoTask. ChecklistItem allows breaking down a complex task into more
68
actionable, smaller tasks."""
9+
10+
def __str__(self):
11+
return self.display_name or self.entity_type_name
12+
13+
@property
14+
def display_name(self):
15+
# type: () -> Optional[str]
16+
"""Indicates the title of the checklistItem."""
17+
return self.properties.get("displayName", None)

0 commit comments

Comments
 (0)