Skip to content

Commit 48eebbf

Browse files
directory,calendar, onedrive namespaces improvements (new types & methods)
1 parent e5ca51b commit 48eebbf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+354
-112
lines changed

examples/directory/delete_groups.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
print("Group deleted.")
1414
index += 1
1515

16-
deleted_groups = client.directory.deleted_groups.get().execute_query()
16+
deleted_groups = client.directory.deletedGroups.get().execute_query()
1717
groups_count = len(deleted_groups)
1818
index = 0
1919
while len(deleted_groups) > 0:

examples/teams/send_message.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
from tests.graph_case import acquire_token_by_username_password
33

44
client = GraphClient(acquire_token_by_username_password)
5-
teams_result = client.me.joinedTeams.get().execute_query()
5+
teams_result = client.me.joined_teams.get().execute_query()
66
if len(teams_result) > 0:
77
target_team = teams_result[1]
88

9-
messages = target_team.primaryChannel.messages.get().execute_query()
9+
messages = target_team.primary_channel.messages.get().execute_query()
1010
print(messages)
1111

1212
# item_body = ItemBody("Hello world!")

office365/calendar/calendar.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,17 @@ def get_schedule(self, schedules, startTime=None, endTime=None, availabilityView
3737
self.context.add_query(qry)
3838
return result
3939

40+
@property
41+
def can_edit(self):
42+
"""
43+
true if the user can write to the calendar, false otherwise.
44+
This property is true for the user who created the calendar.
45+
This property is also true for a user who has been shared a calendar and granted write access.
46+
47+
:rtype: bool or None
48+
"""
49+
return self.properties.get('canEdit', None)
50+
4051
@property
4152
def name(self):
4253
"""
@@ -59,7 +70,7 @@ def events(self):
5970
EventCollection(self.context, ResourcePath("events", self.resource_path)))
6071

6172
@property
62-
def calendarView(self):
73+
def calendar_view(self):
6374
"""The calendar view for the calendar. Navigation property. Read-only."""
6475
return self.properties.get('calendarView',
6576
EventCollection(self.context, ResourcePath("calendarView", self.resource_path)))

office365/calendar/event.py

+14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from office365.calendar.attendee import Attendee
2+
from office365.directory.extension import ExtensionCollection
23
from office365.mail.attachment_collection import AttachmentCollection
34
from office365.mail.item import Item
45
from office365.mail.location import Location
@@ -64,3 +65,16 @@ def attachments(self):
6465
"""The collection of fileAttachment and itemAttachment attachments for the event. """
6566
return self.properties.get('attachments',
6667
AttachmentCollection(self.context, ResourcePath("attachments", self.resource_path)))
68+
69+
@property
70+
def extensions(self):
71+
"""The collection of open extensions defined for the event. Nullable."""
72+
return self.properties.get('extensions',
73+
ExtensionCollection(self.context, ResourcePath("extensions", self.resource_path)))
74+
75+
@property
76+
def instances(self):
77+
"""The collection of open extensions defined for the event. Nullable."""
78+
from office365.calendar.event_collection import EventCollection
79+
return self.properties.get('instances',
80+
EventCollection(self.context, ResourcePath("instances", self.resource_path)))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class OnlineMeetingProviderType:
2+
"""Specifies the type of a principal."""
3+
4+
def __init__(self):
5+
pass
6+
7+
unknown = 0
8+
skypeForBusiness = 1
9+
skypeForConsumer = 2
10+
teamsForBusiness = 3

office365/directory/application.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def delete_object(self, permanent_delete=False):
3737
"""
3838
super(Application, self).delete_object()
3939
if permanent_delete:
40-
deleted_item = self.context.directory.deleted_applications[self.id]
40+
deleted_item = self.context.directory.deletedApplications[self.id]
4141
deleted_item.delete_object()
4242
return self
4343

office365/directory/assignedLicense.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,8 @@
22

33

44
class AssignedLicense(ClientValue):
5-
pass
5+
6+
def __init__(self, skuId=None, disabledPlans=None):
7+
super().__init__()
8+
self.skuId = skuId
9+
self.disabledPlans = disabledPlans

office365/directory/directory.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class Directory(Entity):
88
"container". Deleted items will remain available to restore for up to 30 days. After 30 days, the items are
99
permanently deleted. """
1010

11-
def deleted_items(self, entity_type=None):
11+
def deletedItems(self, entity_type=None):
1212
"""Recently deleted items. Read-only. Nullable."""
1313
if entity_type:
1414
return DirectoryObjectCollection(self.context, ResourcePath(entity_type,
@@ -20,16 +20,16 @@ def deleted_items(self, entity_type=None):
2020
ResourcePath("deletedItems", self.resource_path)))
2121

2222
@property
23-
def deleted_groups(self):
23+
def deletedGroups(self):
2424
"""Recently deleted groups"""
25-
return self.deleted_items("microsoft.graph.group")
25+
return self.deletedItems("microsoft.graph.group")
2626

2727
@property
28-
def deleted_users(self):
28+
def deletedUsers(self):
2929
"""Recently deleted users"""
30-
return self.deleted_items("microsoft.graph.user")
30+
return self.deletedItems("microsoft.graph.user")
3131

3232
@property
33-
def deleted_applications(self):
33+
def deletedApplications(self):
3434
"""Recently deleted applications"""
35-
return self.deleted_items("microsoft.graph.application")
35+
return self.deletedItems("microsoft.graph.application")

office365/directory/directoryObjectCollection.py

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from office365.runtime.client_result import ClientResult
44
from office365.runtime.http.http_method import HttpMethod
55
from office365.runtime.queries.service_operation_query import ServiceOperationQuery
6-
from office365.runtime.resource_path import ResourcePath
76

87

98
class DirectoryObjectCollection(EntityCollection):

office365/directory/group.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
from office365.calendar.event_collection import EventCollection
44
from office365.directory.appRoleAssignment import AppRoleAssignmentCollection
5+
from office365.directory.assignedLicense import AssignedLicense
56
from office365.directory.directoryObject import DirectoryObject
67
from office365.directory.directoryObjectCollection import DirectoryObjectCollection
78
from office365.onedrive.driveCollection import DriveCollection
89
from office365.onedrive.siteCollection import SiteCollection
910
from office365.runtime.client_result import ClientResult
11+
from office365.runtime.client_value_collection import ClientValueCollection
1012
from office365.runtime.http.http_method import HttpMethod
1113
from office365.runtime.queries.service_operation_query import ServiceOperationQuery
1214
from office365.runtime.resource_path import ResourcePath
@@ -70,7 +72,7 @@ def delete_object(self, permanent_delete=False):
7072
"""
7173
super(Group, self).delete_object()
7274
if permanent_delete:
73-
deleted_item = self.context.directory.deleted_groups[self.id]
75+
deleted_item = self.context.directory.deletedGroups[self.id]
7476
deleted_item.delete_object()
7577
return self
7678

@@ -109,3 +111,8 @@ def appRoleAssignments(self):
109111
return self.properties.get('appRoleAssignments',
110112
AppRoleAssignmentCollection(self.context,
111113
ResourcePath("appRoleAssignments", self.resource_path)))
114+
115+
@property
116+
def assigned_licenses(self):
117+
return self.properties.get('assignedLicenses',
118+
ClientValueCollection(AssignedLicense))

office365/directory/organization.py

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from office365.directory.directoryObject import DirectoryObject
2+
3+
4+
class Organization(DirectoryObject):
5+
pass
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from office365.runtime.client_value import ClientValue
2+
3+
4+
class ServicePlanInfo(ClientValue):
5+
"""Contains information about a service plan associated with a subscribed SKU. The servicePlans property of
6+
the subscribedSku entity is a collection of servicePlanInfo."""
7+
8+
def __init__(self, servicePlanId=None, servicePlanName=None, provisioningStatus=None, appliesTo=None):
9+
"""
10+
11+
:param str appliesTo: The object the service plan can be assigned to. Possible values:
12+
"User" - service plan can be assigned to individual users.
13+
"Company" - service plan can be assigned to the entire tenant.
14+
:param str provisioningStatus: The provisioning status of the service plan. Possible values:
15+
"Success" - Service is fully provisioned.
16+
"Disabled" - Service has been disabled.
17+
"PendingInput" - Service is not yet provisioned; awaiting service confirmation.
18+
"PendingActivation" - Service is provisioned but requires explicit activation by administrator
19+
(for example, Intune_O365 service plan)
20+
"PendingProvisioning" - Microsoft has added a new service to the product SKU and it has not been
21+
activated in the tenant, yet.
22+
:param str servicePlanName: The name of the service plan.
23+
:param str servicePlanId: The unique identifier of the service plan.
24+
"""
25+
super().__init__()
26+
self.servicePlanId = servicePlanId
27+
self.servicePlanName = servicePlanName
28+
self.provisioningStatus = provisioningStatus
29+
self.appliesTo = appliesTo

office365/directory/subscribedSku.py

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from office365.directory.servicePlanInfo import ServicePlanInfo
2+
from office365.entity import Entity
3+
from office365.entity_collection import EntityCollection
4+
from office365.runtime.client_value_collection import ClientValueCollection
5+
6+
7+
class SubscribedSku(Entity):
8+
"""Contains information about a service SKU that a company is subscribed to."""
9+
10+
@property
11+
def servicePlans(self):
12+
"""Information about the service plans that are available with the SKU. Not nullable"""
13+
return self.properties.get('servicePlans',
14+
ClientValueCollection(ServicePlanInfo))
15+
16+
17+
class SubscribedSkuCollection(EntityCollection):
18+
19+
def __init__(self, context, resource_path=None):
20+
super(SubscribedSkuCollection, self).__init__(context, SubscribedSku, resource_path)

office365/directory/user.py

+52-8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from office365.mail.contact_collection import ContactCollection
1414
from office365.calendar.event_collection import EventCollection
1515
from office365.mail.message_collection import MessageCollection
16+
from office365.onedrive.siteCollection import SiteCollection
1617
from office365.runtime.client_value_collection import ClientValueCollection
1718
from office365.runtime.http.http_method import HttpMethod
1819
from office365.runtime.queries.service_operation_query import ServiceOperationQuery
@@ -23,6 +24,32 @@
2324
class User(DirectoryObject):
2425
"""Represents an Azure AD user account. Inherits from directoryObject."""
2526

27+
def assign_license(self, addLicenses, removeLicenses):
28+
"""
29+
Add or remove licenses on the user.
30+
:param list[str] removeLicenses: A collection of skuIds that identify the licenses to remove.
31+
:param ClientValueCollection addLicenses: A collection of assignedLicense objects that specify
32+
the licenses to add.
33+
"""
34+
params = {
35+
"addLicenses": addLicenses,
36+
"removeLicenses": removeLicenses
37+
}
38+
qry = ServiceOperationQuery(self, "assignLicense", None, params, None, self)
39+
self.context.add_query(qry)
40+
return self
41+
42+
def change_password(self, currentPassword, newPassword):
43+
"""
44+
45+
:param str currentPassword:
46+
:param str newPassword:
47+
"""
48+
qry = ServiceOperationQuery(self, "changePassword", None,
49+
{"currentPassword": currentPassword, "newPassword": newPassword})
50+
self.context.add_query(qry)
51+
return self
52+
2653
def send_mail(self, message):
2754
"""Send a new message on the fly"""
2855
qry = ServiceOperationQuery(self, "sendmail", None, message)
@@ -80,6 +107,7 @@ def get_calendar_view(self, start_dt, end_dt):
80107
def _construct_request(request):
81108
request.method = HttpMethod.Get
82109
request.url += "?startDateTime={0}&endDateTime={1}".format(start_dt.isoformat(), end_dt.isoformat())
110+
83111
self.context.before_execute(_construct_request)
84112
return result
85113

@@ -102,6 +130,7 @@ def get_reminder_view(self, start_dt, end_dt):
102130

103131
def _construct_request(request):
104132
request.method = HttpMethod.Get
133+
105134
self.context.before_execute(_construct_request)
106135
return result
107136

@@ -113,7 +142,7 @@ def delete_object(self, permanent_delete=False):
113142
"""
114143
super(User, self).delete_object()
115144
if permanent_delete:
116-
deleted_user = self.context.directory.deleted_users[self.id]
145+
deleted_user = self.context.directory.deletedUsers[self.id]
117146
deleted_user.delete_object()
118147
return self
119148

@@ -122,7 +151,7 @@ def account_enabled(self):
122151
return self.properties.get('accountEnabled', None)
123152

124153
@property
125-
def creationType(self):
154+
def creation_type(self):
126155
"""Indicates whether the user account was created as a regular school or work account (null),
127156
an external account (Invitation), a local account for an Azure Active Directory B2C tenant (LocalAccount)
128157
or self-service sign-up using email verification (EmailVerified). Read-only.
@@ -137,7 +166,7 @@ def mail(self):
137166
return self.properties.get('mail', None)
138167

139168
@property
140-
def otherMails(self):
169+
def other_mails(self):
141170
"""A list of additional email addresses for the user;
142171
for example: ["[email protected]", "[email protected]"]. Supports $filter.
143172
"""
@@ -159,6 +188,11 @@ def assigned_licenses(self):
159188
return self.properties.get('assignedLicenses',
160189
ClientValueCollection(AssignedLicense))
161190

191+
@property
192+
def followed_sites(self):
193+
return self.properties.get('followedSites',
194+
SiteCollection(self.context, ResourcePath("followedSites", self.resource_path)))
195+
162196
@property
163197
def photo(self):
164198
"""
@@ -188,14 +222,14 @@ def calendars(self):
188222
CalendarCollection(self.context, ResourcePath("calendars", self.resource_path)))
189223

190224
@property
191-
def calendarGroups(self):
225+
def calendar_groups(self):
192226
"""The user's calendar groups. Read-only. Nullable."""
193227
return self.properties.get('calendarGroups',
194228
CalendarGroupCollection(self.context,
195229
ResourcePath("calendarGroups", self.resource_path)))
196230

197231
@property
198-
def licenseDetails(self):
232+
def license_details(self):
199233
"""Retrieve the properties and relationships of a Drive resource."""
200234
return self.properties.get('licenseDetails',
201235
LicenseDetailsCollection(self.context,
@@ -226,26 +260,36 @@ def messages(self):
226260
MessageCollection(self.context, ResourcePath("messages", self.resource_path)))
227261

228262
@property
229-
def joinedTeams(self):
263+
def joined_teams(self):
230264
"""Get the teams in Microsoft Teams that the user is a direct member of."""
231265
return self.properties.get('joinedTeams',
232266
TeamCollection(self.context, ResourcePath("joinedTeams", self.resource_path)))
233267

234268
@property
235-
def memberOf(self):
269+
def member_of(self):
236270
"""Get groups and directory roles that the user is a direct member of."""
237271
return self.properties.get('memberOf',
238272
DirectoryObjectCollection(self.context,
239273
ResourcePath("memberOf", self.resource_path)))
240274

241275
@property
242-
def transitiveMemberOf(self):
276+
def transitive_member_of(self):
243277
"""Get groups, directory roles that the user is a member of. This API request is transitive, and will also
244278
return all groups the user is a nested member of. """
245279
return self.properties.get('transitiveMemberOf',
246280
DirectoryObjectCollection(self.context,
247281
ResourcePath("transitiveMemberOf", self.resource_path)))
248282

283+
def get_property(self, name):
284+
if name == "transitiveMemberOf":
285+
return self.transitive_member_of
286+
elif name == "joinedTeams":
287+
return self.joined_teams
288+
elif name == "assignedLicenses":
289+
return self.assigned_licenses
290+
else:
291+
return super(User, self).get_property(name)
292+
249293
def set_property(self, name, value, persist_changes=True):
250294
super(User, self).set_property(name, value, persist_changes)
251295
# fallback: create a new resource path

office365/directory/userCollection.py

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ def __init__(self, context, resource_path=None):
1111

1212
def __getitem__(self, key):
1313
"""
14-
1514
:rtype: User
1615
"""
1716
return super(UserCollection, self).__getitem__(key)

0 commit comments

Comments
 (0)