Skip to content
22 changes: 15 additions & 7 deletions plexapi/myplex.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,13 +497,18 @@ def removeHomeUser(self, user):
url = self.HOMEUSER.format(userId=user.id)
return self.query(url, self._session.delete)

def switchHomeUser(self, user, pin=None):
""" Returns a new :class:`~plexapi.myplex.MyPlexAccount` object switched to the given home user.
def switchHomeUser(self, user, pin=None, session=None, timeout=None):
""" Returns a new :class:`~plexapi.myplex.MyPlexAccount` object switched to the given Plex Home user.

Parameters:
user (:class:`~plexapi.myplex.MyPlexUser` or str): :class:`~plexapi.myplex.MyPlexUser`,
username, or email of the home user to switch to.
pin (str): PIN for the home user (required if the home user has a PIN set).
username, or email of the Plex Home user to switch to.
pin (str): PIN for the Plex Home user (required if the Plex Home user has a PIN set).
session (requests.Session, optional): Use your own session object if you want to
cache the http responses from the server. This will default to the same
session as the current account if no new session is provided.
timeout (int, optional): Timeout in seconds on initial connection to the server.
This will default to the same timeout as the current account if no new timeout is provided.

Example:

Expand All @@ -521,9 +526,13 @@ def switchHomeUser(self, user, pin=None):
params = {}
if pin:
params['pin'] = pin
data = self.query(url, self._session.post, params=params)
if session is None:
session = self._session
if timeout is None:
timeout = self._timeout
data = self.query(url, session.post, params=params, timeout=timeout)
userToken = data.attrib.get('authenticationToken')
return MyPlexAccount(token=userToken, session=self._session)
return MyPlexAccount(token=userToken, session=session, timeout=timeout)

def setPin(self, newPin, currentPin=None):
""" Set a new Plex Home PIN for the account.
Expand Down Expand Up @@ -680,7 +689,6 @@ def user(self, username):
"""
username = str(username)
for user in self.users():
# Home users don't have email, username etc.
if username.lower() == user.title.lower():
return user

Expand Down
9 changes: 5 additions & 4 deletions plexapi/playlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,14 +442,15 @@ def create(cls, server, title, section=None, items=None, smart=False, limit=None
else:
return cls._create(server, title, items)

def copyToUser(self, user):
""" Copy playlist to another user account.
def copyToUser(self, user, pin=None):
""" Copy playlist to another Plex Home user account.

Parameters:
user (:class:`~plexapi.myplex.MyPlexUser` or str): `MyPlexUser` object, username,
email, or user id of the user to copy the playlist to.
or email of the Plex Home user to copy the playlist to.
pin (str): PIN for the Plex Home user (required if the Plex Home user has a PIN set).
"""
userServer = self._server.switchUser(user)
userServer = self._server.switchHomeUser(user, pin=pin)
return self.create(server=userServer, title=self.title, items=self.items())

def sync(self, videoQuality=None, photoResolution=None, audioBitrate=None, client=None, clientId=None, limit=None,
Expand Down
27 changes: 23 additions & 4 deletions plexapi/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,10 @@ def createToken(self, type='delegation', scope='all'):
q = self.query(f'/security/token?type={type}&scope={scope}')
return q.attrib.get('token')

@utils.deprecated('switchUser is deprecated, use switchHomeUser instead')
def switchUser(self, user, session=None, timeout=None):
""" Returns a new :class:`~plexapi.server.PlexServer` object logged in as the given username.
""" Deprecated. Use :meth:`~plexapi.server.PlexServer.switchHomeUser` instead.
Returns a new :class:`~plexapi.server.PlexServer` object logged in as the given username.
Note: Only the admin account can switch to other users.

Parameters:
Expand All @@ -247,6 +249,22 @@ def switchUser(self, user, session=None, timeout=None):
timeout (int, optional): Timeout in seconds on initial connection to the server.
This will default to the same timeout as the admin account if no new timeout
is provided.
"""
return self.switchHomeUser(user, session=session, timeout=timeout)

def switchHomeUser(self, user, pin=None, session=None, timeout=None):
""" Returns a new :class:`~plexapi.server.PlexServer` object logged in as the given Plex Home user.
Note: Only the admin account can switch to other users.

Parameters:
user (:class:`~plexapi.myplex.MyPlexUser` or str): :class:`~plexapi.myplex.MyPlexUser`,
username, or email of the Plex Home user to switch to.
pin (str): PIN for the Plex Home user (required if the Plex Home user has a PIN set).
session (requests.Session, optional): Use your own session object if you want to
cache the http responses from the server. This will default to the same
session as the current account if no new session is provided.
timeout (int, optional): Timeout in seconds on initial connection to the server.
This will default to the same timeout as the current account if no new timeout is provided.

Example:

Expand All @@ -255,17 +273,18 @@ def switchUser(self, user, session=None, timeout=None):
from plexapi.server import PlexServer
# Login to the Plex server using the admin token
plex = PlexServer('http://plexserver:32400', token='2ffLuB84dqLswk9skLos')
# Login to the same Plex server using a different account
userPlex = plex.switchUser("Username")
# Login to the same Plex server using a different Plex Home user account
userPlex = plex.switchHomeUser("Username")

"""
from plexapi.myplex import MyPlexUser
user = user if isinstance(user, MyPlexUser) else self.myPlexAccount().user(user)
userToken = user.get_token(self.machineIdentifier)
if session is None:
session = self._session
if timeout is None:
timeout = self._timeout
userAccount = self.myPlexAccount().switchHomeUser(user, pin=pin, session=session, timeout=timeout)
userToken = userAccount.resource(self.machineIdentifier).accessToken
return PlexServer(self._baseurl, token=userToken, session=session, timeout=timeout)

@cached_data_property
Expand Down
5 changes: 3 additions & 2 deletions tests/test_playlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,14 @@ def test_Play_photos(plex, client, photoalbum):
time.sleep(2)


def test_Playlist_copyToUser(plex, show, fresh_plex, shared_username):
def test_Playlist_copyToUser(plex, show, shared_username):
episodes = show.episodes()
playlist = plex.createPlaylist('shared_from_test_plexapi', items=episodes)
try:
playlist.copyToUser(shared_username)
user = plex.myPlexAccount().user(shared_username)
user_plex = fresh_plex(plex._baseurl, user.get_token(plex.machineIdentifier))
assert user.home is True
user_plex = plex.switchHomeUser(user)
assert playlist.title in [p.title for p in user_plex.playlists()]
finally:
playlist.delete()
Expand Down
Loading