Skip to content

Commit 117d8cb

Browse files
authored
Merge pull request #365 from blacktwin/patch-5
Adding Managed User support
2 parents f95f792 + 05c2198 commit 117d8cb

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed

plexapi/myplex.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,12 @@ class MyPlexAccount(PlexObject):
6262
_session (obj): Requests session object used to access this client.
6363
"""
6464
FRIENDINVITE = 'https://plex.tv/api/servers/{machineId}/shared_servers' # post with data
65+
HOMEUSERCREATE = 'https://plex.tv/api/home/users?title={title}' # post with data
66+
EXISTINGUSER = 'https://plex.tv/api/home/users?invitedEmail={username}' # post with data
6567
FRIENDSERVERS = 'https://plex.tv/api/servers/{machineId}/shared_servers/{serverId}' # put with data
6668
PLEXSERVERS = 'https://plex.tv/api/servers/{machineId}' # get
6769
FRIENDUPDATE = 'https://plex.tv/api/friends/{userId}' # put with args, delete
70+
REMOVEHOMEUSER = 'https://plex.tv/api/home/users/{userId}' # delete
6871
REMOVEINVITE = 'https://plex.tv/api/invites/requested/{userId}?friend=0&server=1&home=0' # delete
6972
REQUESTED = 'https://plex.tv/api/invites/requested' # get
7073
REQUESTS = 'https://plex.tv/api/invites/requests' # get
@@ -230,6 +233,102 @@ def inviteFriend(self, user, server, sections=None, allowSync=False, allowCamera
230233
url = self.FRIENDINVITE.format(machineId=machineId)
231234
return self.query(url, self._session.post, json=params, headers=headers)
232235

236+
def createHomeUser(self, user, server, sections=None, allowSync=False, allowCameraUpload=False,
237+
allowChannels=False, filterMovies=None, filterTelevision=None, filterMusic=None):
238+
""" Share library content with the specified user.
239+
240+
Parameters:
241+
user (str): MyPlexUser, username, email of the user to be added.
242+
server (PlexServer): PlexServer object or machineIdentifier containing the library sections to share.
243+
sections ([Section]): Library sections, names or ids to be shared (default None shares all sections).
244+
allowSync (Bool): Set True to allow user to sync content.
245+
allowCameraUpload (Bool): Set True to allow user to upload photos.
246+
allowChannels (Bool): Set True to allow user to utilize installed channels.
247+
filterMovies (Dict): Dict containing key 'contentRating' and/or 'label' each set to a list of
248+
values to be filtered. ex: {'contentRating':['G'], 'label':['foo']}
249+
filterTelevision (Dict): Dict containing key 'contentRating' and/or 'label' each set to a list of
250+
values to be filtered. ex: {'contentRating':['G'], 'label':['foo']}
251+
filterMusic (Dict): Dict containing key 'label' set to a list of values to be filtered.
252+
ex: {'label':['foo']}
253+
"""
254+
machineId = server.machineIdentifier if isinstance(server, PlexServer) else server
255+
sectionIds = self._getSectionIds(server, sections)
256+
257+
headers = {'Content-Type': 'application/json'}
258+
url = self.HOMEUSERCREATE.format(title=user)
259+
# UserID needs to be created and referenced when adding sections
260+
user_creation = self.query(url, self._session.post, headers=headers)
261+
userIds = {}
262+
for elem in user_creation.findall("."):
263+
# Find userID
264+
userIds['id'] = elem.attrib.get('id')
265+
log.debug(userIds)
266+
params = {
267+
'server_id': machineId,
268+
'shared_server': {'library_section_ids': sectionIds, 'invited_id': userIds['id']},
269+
'sharing_settings': {
270+
'allowSync': ('1' if allowSync else '0'),
271+
'allowCameraUpload': ('1' if allowCameraUpload else '0'),
272+
'allowChannels': ('1' if allowChannels else '0'),
273+
'filterMovies': self._filterDictToStr(filterMovies or {}),
274+
'filterTelevision': self._filterDictToStr(filterTelevision or {}),
275+
'filterMusic': self._filterDictToStr(filterMusic or {}),
276+
},
277+
}
278+
url = self.FRIENDINVITE.format(machineId=machineId)
279+
library_assignment = self.query(url, self._session.post, json=params, headers=headers)
280+
return user_creation, library_assignment
281+
282+
def createExistingUser(self, user, server, sections=None, allowSync=False, allowCameraUpload=False,
283+
allowChannels=False, filterMovies=None, filterTelevision=None, filterMusic=None):
284+
""" Share library content with the specified user.
285+
286+
Parameters:
287+
user (str): MyPlexUser, username, email of the user to be added.
288+
server (PlexServer): PlexServer object or machineIdentifier containing the library sections to share.
289+
sections ([Section]): Library sections, names or ids to be shared (default None shares all sections).
290+
allowSync (Bool): Set True to allow user to sync content.
291+
allowCameraUpload (Bool): Set True to allow user to upload photos.
292+
allowChannels (Bool): Set True to allow user to utilize installed channels.
293+
filterMovies (Dict): Dict containing key 'contentRating' and/or 'label' each set to a list of
294+
values to be filtered. ex: {'contentRating':['G'], 'label':['foo']}
295+
filterTelevision (Dict): Dict containing key 'contentRating' and/or 'label' each set to a list of
296+
values to be filtered. ex: {'contentRating':['G'], 'label':['foo']}
297+
filterMusic (Dict): Dict containing key 'label' set to a list of values to be filtered.
298+
ex: {'label':['foo']}
299+
"""
300+
headers = {'Content-Type': 'application/json'}
301+
# If user already exists, carry over sections and settings.
302+
if isinstance(user, MyPlexUser):
303+
username = user.username
304+
elif user in [_user.username for _user in self.users()]:
305+
username = self.user(user).username
306+
else:
307+
# If user does not already exists, treat request as new request and include sections and settings.
308+
newUser = user
309+
url = self.EXISTINGUSER.format(username=newUser)
310+
user_creation = self.query(url, self._session.post, headers=headers)
311+
machineId = server.machineIdentifier if isinstance(server, PlexServer) else server
312+
sectionIds = self._getSectionIds(server, sections)
313+
params = {
314+
'server_id': machineId,
315+
'shared_server': {'library_section_ids': sectionIds, 'invited_email': newUser},
316+
'sharing_settings': {
317+
'allowSync': ('1' if allowSync else '0'),
318+
'allowCameraUpload': ('1' if allowCameraUpload else '0'),
319+
'allowChannels': ('1' if allowChannels else '0'),
320+
'filterMovies': self._filterDictToStr(filterMovies or {}),
321+
'filterTelevision': self._filterDictToStr(filterTelevision or {}),
322+
'filterMusic': self._filterDictToStr(filterMusic or {}),
323+
},
324+
}
325+
url = self.FRIENDINVITE.format(machineId=machineId)
326+
library_assignment = self.query(url, self._session.post, json=params, headers=headers)
327+
return user_creation, library_assignment
328+
329+
url = self.EXISTINGUSER.format(username=username)
330+
return self.query(url, self._session.post, headers=headers)
331+
233332
def removeFriend(self, user):
234333
""" Remove the specified user from all sharing.
235334
@@ -241,6 +340,16 @@ def removeFriend(self, user):
241340
url = url.format(userId=user.id)
242341
return self.query(url, self._session.delete)
243342

343+
def removeHomeUser(self, user):
344+
""" Remove the specified managed user from home.
345+
346+
Parameters:
347+
user (str): MyPlexUser, username, email of the user to be removed from home.
348+
"""
349+
user = self.user(user)
350+
url = self.REMOVEHOMEUSER.format(userId=user.id)
351+
return self.query(url, self._session.delete)
352+
244353
def updateFriend(self, user, server, sections=None, removeSections=False, allowSync=None, allowCameraUpload=None,
245354
allowChannels=None, filterMovies=None, filterTelevision=None, filterMusic=None):
246355
""" Update the specified user's share settings.

tests/test_myplex.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,27 @@ def test_myplex_updateFriend(account, plex, mocker, shared_username):
157157
filterTelevision=vid_filter, filterMusic={'label': ['foo']})
158158

159159

160+
def test_myplex_createExistingUser(account, plex, shared_username):
161+
user = account.user(shared_username)
162+
url = 'https://plex.tv/api/invites/requested/{}?friend=0&server=0&home=1'.format(user.id)
163+
164+
account.createExistingUser(user, plex)
165+
assert shared_username in [u.username for u in account.users() if u.home is True]
166+
# Remove Home invite
167+
account.query(url, account._session.delete)
168+
# Confirm user was removed from home and has returned to friend
169+
assert shared_username not in [u.username for u in plex.myPlexAccount().users() if u.home is True]
170+
assert shared_username in [u.username for u in plex.myPlexAccount().users() if u.home is False]
171+
172+
173+
def test_myplex_createHomeUser_remove(account, plex):
174+
homeuser = 'New Home User'
175+
account.createHomeUser(homeuser, plex)
176+
assert homeuser in [u.title for u in plex.myPlexAccount().users() if u.home is True]
177+
account.removeHomeUser(homeuser)
178+
assert homeuser not in [u.title for u in plex.myPlexAccount().users() if u.home is True]
179+
180+
160181
def test_myplex_plexpass_attributes(account_plexpass):
161182
assert account_plexpass.subscriptionActive
162183
assert account_plexpass.subscriptionStatus == 'Active'

0 commit comments

Comments
 (0)