Files
bazarr/libs/plexapi/mixins/resources.py
2026-03-17 21:30:35 -04:00

329 lines
12 KiB
Python

from urllib.parse import quote_plus
from plexapi import media
from plexapi.utils import openOrRead
class ArtUrlMixin:
""" Mixin for Plex objects that can have a background artwork url. """
@property
def artUrl(self):
""" Return the art url for the Plex object. """
art = self.firstAttr('art', 'grandparentArt')
return self._server.url(art, includeToken=True) if art else None
class ArtLockMixin:
""" Mixin for Plex objects that can have a locked background artwork. """
def lockArt(self):
""" Lock the background artwork for a Plex object. """
return self._edit(**{'art.locked': 1})
def unlockArt(self):
""" Unlock the background artwork for a Plex object. """
return self._edit(**{'art.locked': 0})
class ArtMixin(ArtUrlMixin, ArtLockMixin):
""" Mixin for Plex objects that can have background artwork. """
def arts(self):
""" Returns list of available :class:`~plexapi.media.Art` objects. """
return self.fetchItems(f'/library/metadata/{self.ratingKey}/arts', cls=media.Art)
def uploadArt(self, url=None, filepath=None):
""" Upload a background artwork from a url or filepath.
Parameters:
url (str): The full URL to the image to upload.
filepath (str): The full file path to the image to upload or file-like object.
"""
if url:
key = f'/library/metadata/{self.ratingKey}/arts?url={quote_plus(url)}'
self._server.query(key, method=self._server._session.post)
elif filepath:
key = f'/library/metadata/{self.ratingKey}/arts'
data = openOrRead(filepath)
self._server.query(key, method=self._server._session.post, data=data)
return self
def setArt(self, art):
""" Set the background artwork for a Plex object.
Parameters:
art (:class:`~plexapi.media.Art`): The art object to select.
"""
art.select()
return self
def deleteArt(self):
""" Delete the art from a Plex object. """
key = f'/library/metadata/{self.ratingKey}/art'
self._server.query(key, method=self._server._session.delete)
return self
class LogoUrlMixin:
""" Mixin for Plex objects that can have a logo url. """
@property
def logo(self):
""" Return the API path to the logo image. """
return next((i.url for i in self.images if i.type == 'clearLogo'), None)
@property
def logoUrl(self):
""" Return the logo url for the Plex object. """
return self._server.url(self.logo, includeToken=True) if self.logo else None
class LogoLockMixin:
""" Mixin for Plex objects that can have a locked logo. """
def lockLogo(self):
""" Lock the logo for a Plex object. """
return self._edit(**{'clearLogo.locked': 1})
def unlockLogo(self):
""" Unlock the logo for a Plex object. """
return self._edit(**{'clearLogo.locked': 0})
class LogoMixin(LogoUrlMixin, LogoLockMixin):
""" Mixin for Plex objects that can have logos. """
def logos(self):
""" Returns list of available :class:`~plexapi.media.Logo` objects. """
return self.fetchItems(f'/library/metadata/{self.ratingKey}/clearLogos', cls=media.Logo)
def uploadLogo(self, url=None, filepath=None):
""" Upload a logo from a url or filepath.
Parameters:
url (str): The full URL to the image to upload.
filepath (str): The full file path to the image to upload or file-like object.
"""
if url:
key = f'/library/metadata/{self.ratingKey}/clearLogos?url={quote_plus(url)}'
self._server.query(key, method=self._server._session.post)
elif filepath:
key = f'/library/metadata/{self.ratingKey}/clearLogos'
data = openOrRead(filepath)
self._server.query(key, method=self._server._session.post, data=data)
return self
def setLogo(self, logo):
""" Set the logo for a Plex object.
Parameters:
logo (:class:`~plexapi.media.Logo`): The logo object to select.
"""
logo.select()
return self
def deleteLogo(self):
""" Delete the logo from a Plex object. """
key = f'/library/metadata/{self.ratingKey}/clearLogo'
self._server.query(key, method=self._server._session.delete)
return self
class PosterUrlMixin:
""" Mixin for Plex objects that can have a poster url. """
@property
def thumbUrl(self):
""" Return the thumb url for the Plex object. """
thumb = self.firstAttr('thumb', 'parentThumb', 'grandparentThumb')
return self._server.url(thumb, includeToken=True) if thumb else None
@property
def posterUrl(self):
""" Alias to self.thumbUrl. """
return self.thumbUrl
class PosterLockMixin:
""" Mixin for Plex objects that can have a locked poster. """
def lockPoster(self):
""" Lock the poster for a Plex object. """
return self._edit(**{'thumb.locked': 1})
def unlockPoster(self):
""" Unlock the poster for a Plex object. """
return self._edit(**{'thumb.locked': 0})
class PosterMixin(PosterUrlMixin, PosterLockMixin):
""" Mixin for Plex objects that can have posters. """
def posters(self):
""" Returns list of available :class:`~plexapi.media.Poster` objects. """
return self.fetchItems(f'/library/metadata/{self.ratingKey}/posters', cls=media.Poster)
def uploadPoster(self, url=None, filepath=None):
""" Upload a poster from a url or filepath.
Parameters:
url (str): The full URL to the image to upload.
filepath (str): The full file path to the image to upload or file-like object.
"""
if url:
key = f'/library/metadata/{self.ratingKey}/posters?url={quote_plus(url)}'
self._server.query(key, method=self._server._session.post)
elif filepath:
key = f'/library/metadata/{self.ratingKey}/posters'
data = openOrRead(filepath)
self._server.query(key, method=self._server._session.post, data=data)
return self
def setPoster(self, poster):
""" Set the poster for a Plex object.
Parameters:
poster (:class:`~plexapi.media.Poster`): The poster object to select.
"""
poster.select()
return self
def deletePoster(self):
""" Delete the poster from a Plex object. """
key = f'/library/metadata/{self.ratingKey}/thumb'
self._server.query(key, method=self._server._session.delete)
return self
class SquareArtUrlMixin:
""" Mixin for Plex objects that can have a square art url. """
@property
def squareArt(self):
""" Return the API path to the square art image. """
return next((i.url for i in self.images if i.type == 'backgroundSquare'), None)
@property
def squareArtUrl(self):
""" Return the square art url for the Plex object. """
return self._server.url(self.squareArt, includeToken=True) if self.squareArt else None
class SquareArtLockMixin:
""" Mixin for Plex objects that can have a locked square art. """
def lockSquareArt(self):
""" Lock the square art for a Plex object. """
return self._edit(**{'squareArt.locked': 1})
def unlockSquareArt(self):
""" Unlock the square art for a Plex object. """
return self._edit(**{'squareArt.locked': 0})
class SquareArtMixin(SquareArtUrlMixin, SquareArtLockMixin):
""" Mixin for Plex objects that can have square art. """
def squareArts(self):
""" Returns list of available :class:`~plexapi.media.SquareArt` objects. """
return self.fetchItems(f'/library/metadata/{self.ratingKey}/squareArts', cls=media.SquareArt)
def uploadSquareArt(self, url=None, filepath=None):
""" Upload a square art from a url or filepath.
Parameters:
url (str): The full URL to the image to upload.
filepath (str): The full file path to the image to upload or file-like object.
"""
if url:
key = f'/library/metadata/{self.ratingKey}/squareArts?url={quote_plus(url)}'
self._server.query(key, method=self._server._session.post)
elif filepath:
key = f'/library/metadata/{self.ratingKey}/squareArts'
data = openOrRead(filepath)
self._server.query(key, method=self._server._session.post, data=data)
return self
def setSquareArt(self, squareArt):
""" Set the square art for a Plex object.
Parameters:
squareArt (:class:`~plexapi.media.SquareArt`): The square art object to select.
"""
squareArt.select()
return self
def deleteSquareArt(self):
""" Delete the square art from a Plex object. """
key = f'/library/metadata/{self.ratingKey}/squareArt'
self._server.query(key, method=self._server._session.delete)
return self
class ThemeUrlMixin:
""" Mixin for Plex objects that can have a theme url. """
@property
def themeUrl(self):
""" Return the theme url for the Plex object. """
theme = self.firstAttr('theme', 'parentTheme', 'grandparentTheme')
return self._server.url(theme, includeToken=True) if theme else None
class ThemeLockMixin:
""" Mixin for Plex objects that can have a locked theme. """
def lockTheme(self):
""" Lock the theme for a Plex object. """
return self._edit(**{'theme.locked': 1})
def unlockTheme(self):
""" Unlock the theme for a Plex object. """
return self._edit(**{'theme.locked': 0})
class ThemeMixin(ThemeUrlMixin, ThemeLockMixin):
""" Mixin for Plex objects that can have themes. """
def themes(self):
""" Returns list of available :class:`~plexapi.media.Theme` objects. """
return self.fetchItems(f'/library/metadata/{self.ratingKey}/themes', cls=media.Theme)
def uploadTheme(self, url=None, filepath=None, timeout=None):
""" Upload a theme from url or filepath.
Warning: Themes cannot be deleted using PlexAPI!
Parameters:
url (str): The full URL to the theme to upload.
filepath (str): The full file path to the theme to upload or file-like object.
timeout (int, optional): Timeout, in seconds, to use when uploading themes to the server.
(default config.TIMEOUT).
"""
if url:
key = f'/library/metadata/{self.ratingKey}/themes?url={quote_plus(url)}'
self._server.query(key, method=self._server._session.post, timeout=timeout)
elif filepath:
key = f'/library/metadata/{self.ratingKey}/themes'
data = openOrRead(filepath)
self._server.query(key, method=self._server._session.post, data=data, timeout=timeout)
return self
def setTheme(self, theme):
""" Set the theme for a Plex object.
Raises:
:exc:`~plexapi.exceptions.NotImplementedError`: Themes cannot be set through the API.
"""
raise NotImplementedError(
'Themes cannot be set through the API. '
'Re-upload the theme using "uploadTheme" to set it.'
)
def deleteTheme(self):
""" Delete the theme from a Plex object. """
key = f'/library/metadata/{self.ratingKey}/theme'
self._server.query(key, method=self._server._session.delete)
return self