Ejemplo n.º 1
0
def test_utils_searchType():
    st = utils.searchType("movie")
    assert st == 1
    movie = utils.searchType(1)
    assert movie == "1"
    with pytest.raises(NotFound):
        utils.searchType("kekekekeke")
Ejemplo n.º 2
0
def test_utils_searchType():
    st = utils.searchType('movie')
    assert st == 1
    movie = utils.searchType(1)
    assert movie == '1'
    with pytest.raises(NotFound):
        utils.searchType('kekekekeke')
Ejemplo n.º 3
0
    def _createSmart(cls, server, title, section, limit=None, **kwargs):
        """ Create a Smart playlist. """

        if not isinstance(section, LibrarySection):
            section = server.library.section(section)

        sectionType = utils.searchType(section.type)
        sectionId = section.key
        uuid = section.uuid
        uri = 'library://%s/directory//library/sections/%s/all?type=%s' % (uuid,
                                                                           sectionId,
                                                                           sectionType)
        if limit:
            uri = uri + '&limit=%s' % str(limit)

        for category, value in kwargs.items():
            sectionChoices = section.listChoices(category)
            for choice in sectionChoices:
                if str(choice.title).lower() == str(value).lower():
                    uri = uri + '&%s=%s' % (category.lower(), str(choice.key))

        uri = uri + '&sourceType=%s' % sectionType
        key = '/playlists%s' % utils.joinArgs({
            'uri': uri,
            'type': section.CONTENT_TYPE,
            'title': title,
            'smart': 1,
        })
        data = server.query(key, method=server._session.post)[0]
        return cls(server, data, initpath=key)
Ejemplo n.º 4
0
    def listChoices(self, category, libtype=None, **kwargs):
        """ Returns a list of :class:`~plexapi.library.FilterChoice` objects for the
            specified category and libtype. kwargs can be any of the same kwargs in
            :func:`plexapi.library.LibraySection.search()` to help narrow down the choices
            to only those that matter in your current context.

            Parameters:
                category (str): Category to list choices for (genre, contentRating, etc).
                libtype (int): Library type of item filter.
                **kwargs (dict): Additional kwargs to narrow down the choices.

            Raises:
                :class:`~plexapi.exceptions.BadRequest`: Cannot include kwarg equal to specified category.
        """
        # TODO: Should this be moved to base?
        if category in kwargs:
            raise BadRequest(
                'Cannot include kwarg equal to specified category: %s' %
                category)
        args = {}
        for subcategory, value in kwargs.items():
            args[category] = self._cleanSearchFilter(subcategory, value)
        if libtype is not None:
            args['type'] = utils.searchType(libtype)
        key = '/library/sections/%s/%s%s' % (self.key, category,
                                             utils.joinArgs(args))
        return self.fetchItems(key, cls=FilterChoice)
Ejemplo n.º 5
0
    def _create(cls, server, title, section, items):
        """ Create a regular collection. """
        if not items:
            raise BadRequest('Must include items to add when creating new collection.')

        if not isinstance(section, LibrarySection):
            section = server.library.section(section)

        if items and not isinstance(items, (list, tuple)):
            items = [items]

        itemType = items[0].type
        ratingKeys = []
        for item in items:
            if item.type != itemType:  # pragma: no cover
                raise BadRequest('Can not mix media types when building a collection.')
            ratingKeys.append(str(item.ratingKey))

        ratingKeys = ','.join(ratingKeys)
        uri = '%s/library/metadata/%s' % (server._uriRoot(), ratingKeys)

        key = '/library/collections%s' % utils.joinArgs({
            'uri': uri,
            'type': utils.searchType(itemType),
            'title': title,
            'smart': 0,
            'sectionId': section.key
        })
        data = server.query(key, method=server._session.post)[0]
        return cls(server, data, initpath=key)
Ejemplo n.º 6
0
    def _createSmart(cls,
                     server,
                     title,
                     section,
                     limit=None,
                     libtype=None,
                     sort=None,
                     filters=None,
                     **kwargs):
        """ Create a smart collection. """
        if not isinstance(section, LibrarySection):
            section = server.library.section(section)

        libtype = libtype or section.TYPE

        searchKey = section._buildSearchKey(sort=sort,
                                            libtype=libtype,
                                            limit=limit,
                                            filters=filters,
                                            **kwargs)
        uri = '%s%s' % (server._uriRoot(), searchKey)

        key = '/library/collections%s' % utils.joinArgs(
            {
                'uri': uri,
                'type': utils.searchType(libtype),
                'title': title,
                'smart': 1,
                'sectionId': section.key
            })
        data = server.query(key, method=server._session.post)[0]
        return cls(server, data, initpath=key)
Ejemplo n.º 7
0
    def search(self,
               title=None,
               sort=None,
               maxresults=999999,
               libtype=None,
               **kwargs):
        """ Search the library. If there are many results, they will be fetched from the server
            in batches of X_PLEX_CONTAINER_SIZE amounts. If you're only looking for the first <num>
            results, it would be wise to set the maxresults option to that amount so this functions
            doesn't iterate over all results on the server.

            Args:
                title (string, optional): General string query to search for.
                sort (string): column:dir; column can be any of {addedAt, originallyAvailableAt, lastViewedAt,
                      titleSort, rating, mediaHeight, duration}. dir can be asc or desc.
                maxresults (int): Only return the specified number of results
                libtype (string): Filter results to a spcifiec libtype {movie, show, episode, artist, album, track}
                kwargs: Any of the available filters for the current library section. Partial string
                        matches allowed. Multiple matches OR together. All inputs will be compared with the
                        available options and a warning logged if the option does not appear valid.

                        'unwatched': Display or hide unwatched content (True, False). [all]
                        'duplicate': Display or hide duplicate items (True, False). [movie]
                        'actor': List of actors to search ([actor_or_id, ...]). [movie]
                        'collection': List of collections to search within ([collection_or_id, ...]). [all]
                        'contentRating': List of content ratings to search within ([rating_or_key, ...]). [movie,tv]
                        'country': List of countries to search within ([country_or_key, ...]). [movie,music]
                        'decade': List of decades to search within ([yyy0, ...]). [movie]
                        'director': List of directors to search ([director_or_id, ...]). [movie]
                        'genre': List Genres to search within ([genere_or_id, ...]). [all]
                        'network': List of TV networks to search within ([resolution_or_key, ...]). [tv]
                        'resolution': List of video resolutions to search within ([resolution_or_key, ...]). [movie]
                        'studio': List of studios to search within ([studio_or_key, ...]). [music]
                        'year': List of years to search within ([yyyy, ...]). [all]
        """
        # Cleanup the core arguments
        args = {}
        for category, value in kwargs.items():
            args[category] = self._cleanSearchFilter(category, value, libtype)
        if title is not None:
            args['title'] = title
        if sort is not None:
            args['sort'] = self._cleanSearchSort(sort)
        if libtype is not None:
            args['type'] = utils.searchType(libtype)

        # Iterate over the results
        results, subresults = [], '_init'
        args['X-Plex-Container-Start'] = 0
        args['X-Plex-Container-Size'] = min(X_PLEX_CONTAINER_SIZE, maxresults)

        while subresults and maxresults > len(results):
            query = '/library/sections/%s/all%s' % (self.key,
                                                    utils.joinArgs(args))
            subresults = utils.listItems(self.server, query)
            results += subresults[:maxresults - len(results)]
            args['X-Plex-Container-Start'] += args['X-Plex-Container-Size']
        return results
Ejemplo n.º 8
0
    def _edit(self, **kwargs):
        """ Actually edit an object. """
        if 'id' not in kwargs:
            kwargs['id'] = self.ratingKey
        if 'type' not in kwargs:
            kwargs['type'] = utils.searchType(self.type)

        part = '/library/sections/%s/all?%s' % (self.librarySectionID,
                                                urlencode(kwargs))
        self._server.query(part, method=self._server._session.put)
Ejemplo n.º 9
0
 def listChoices(self, category, libtype=None, **kwargs):
     """ List choices for the specified filter category. kwargs can be any of the same
         kwargs in self.search() to help narrow down the choices to only those that
         matter in your current context.
     """
     if category in kwargs:
         raise BadRequest('Cannot include kwarg equal to specified category: %s' % category)
     args = {}
     for subcategory, value in kwargs.items():
         args[category] = self._cleanSearchFilter(subcategory, value)
     if libtype is not None: args['type'] = utils.searchType(libtype)
     query = '/library/sections/%s/%s%s' % (self.key, category, utils.joinArgs(args))
     return utils.listItems(self.server, query, bytag=True)
Ejemplo n.º 10
0
    def search(self, title=None, sort=None, maxresults=999999, libtype=None, **kwargs):
        """ Search the library. If there are many results, they will be fetched from the server
            in batches of X_PLEX_CONTAINER_SIZE amounts. If you're only looking for the first <num>
            results, it would be wise to set the maxresults option to that amount so this functions
            doesn't iterate over all results on the server.

            Parameters:
                title (str): General string query to search for (optional).
                sort (str): column:dir; column can be any of {addedAt, originallyAvailableAt, lastViewedAt,
                      titleSort, rating, mediaHeight, duration}. dir can be asc or desc (optional).
                maxresults (int): Only return the specified number of results (optional).
                libtype (str): Filter results to a spcifiec libtype (movie, show, episode, artist,
                    album, track; optional).
                **kwargs (dict): Any of the available filters for the current library section. Partial string
                        matches allowed. Multiple matches OR together. All inputs will be compared with the
                        available options and a warning logged if the option does not appear valid.

                        * unwatched: Display or hide unwatched content (True, False). [all]
                        * duplicate: Display or hide duplicate items (True, False). [movie]
                        * actor: List of actors to search ([actor_or_id, ...]). [movie]
                        * collection: List of collections to search within ([collection_or_id, ...]). [all]
                        * contentRating: List of content ratings to search within ([rating_or_key, ...]). [movie,tv]
                        * country: List of countries to search within ([country_or_key, ...]). [movie,music]
                        * decade: List of decades to search within ([yyy0, ...]). [movie]
                        * director: List of directors to search ([director_or_id, ...]). [movie]
                        * genre: List Genres to search within ([genere_or_id, ...]). [all]
                        * network: List of TV networks to search within ([resolution_or_key, ...]). [tv]
                        * resolution: List of video resolutions to search within ([resolution_or_key, ...]). [movie]
                        * studio: List of studios to search within ([studio_or_key, ...]). [music]
                        * year: List of years to search within ([yyyy, ...]). [all]
        """
        # cleanup the core arguments
        args = {}
        for category, value in kwargs.items():
            args[category] = self._cleanSearchFilter(category, value, libtype)
        if title is not None:
            args['title'] = title
        if sort is not None:
            args['sort'] = self._cleanSearchSort(sort)
        if libtype is not None:
            args['type'] = utils.searchType(libtype)
        # iterate over the results
        results, subresults = [], '_init'
        args['X-Plex-Container-Start'] = 0
        args['X-Plex-Container-Size'] = min(X_PLEX_CONTAINER_SIZE, maxresults)
        while subresults and maxresults > len(results):
            key = '/library/sections/%s/all%s' % (self.key, utils.joinArgs(args))
            subresults = self.fetchItems(key)
            results += subresults[:maxresults - len(results)]
            args['X-Plex-Container-Start'] += args['X-Plex-Container-Size']
        return results
Ejemplo n.º 11
0
 def search(self, title=None, libtype=None, **kwargs):
     """ Searching within a library section is much more powerful. It seems certain attributes on the media
         objects can be targeted to filter this search down a bit, but I havent found the documentation for
         it. For example: "studio=Comedy%20Central" or "year=1999" "title=Kung Fu" all work. Other items
         such as actor=<id> seem to work, but require you already know the id of the actor.
         TLDR: This is untested but seems to work. Use library section search when you can.
     """
     args = {}
     if title: args['title'] = title
     if libtype: args['type'] = utils.searchType(libtype)
     for attr, value in kwargs.items():
         args[attr] = value
     query = '/library/all%s' % utils.joinArgs(args)
     return utils.listItems(self.server, query)
Ejemplo n.º 12
0
 def search(self, title=None, libtype=None, **kwargs):
     """ Searching within a library section is much more powerful. It seems certain attributes on the media
         objects can be targeted to filter this search down a bit, but I havent found the documentation for
         it. For example: "studio=Comedy%20Central" or "year=1999" "title=Kung Fu" all work. Other items
         such as actor=<id> seem to work, but require you already know the id of the actor.
         TLDR: This is untested but seems to work. Use library section search when you can.
     """
     args = {}
     if title: args['title'] = title
     if libtype: args['type'] = utils.searchType(libtype)
     for attr, value in kwargs.items():
         args[attr] = value
     query = '/library/all%s' % utils.joinArgs(args)
     return utils.listItems(self.server, query)
Ejemplo n.º 13
0
    def _edit(self, **kwargs):
        """ Actually edit an object. """
        if isinstance(self._edits, dict):
            self._edits.update(kwargs)
            return self

        if 'id' not in kwargs:
            kwargs['id'] = self.ratingKey
        if 'type' not in kwargs:
            kwargs['type'] = utils.searchType(self._searchType)

        part = '/library/sections/%s/all%s' % (self.librarySectionID,
                                               utils.joinArgs(kwargs))
        self._server.query(part, method=self._server._session.put)
        return self
Ejemplo n.º 14
0
 def listChoices(self, category, libtype=None, **kwargs):
     """ List choices for the specified filter category. kwargs can be any of the same
         kwargs in self.search() to help narrow down the choices to only those that
         matter in your current context.
     """
     if category in kwargs:
         raise BadRequest(
             'Cannot include kwarg equal to specified category: %s' %
             category)
     args = {}
     for subcategory, value in kwargs.items():
         args[category] = self._cleanSearchFilter(subcategory, value)
     if libtype is not None: args['type'] = utils.searchType(libtype)
     query = '/library/sections/%s/%s%s' % (self.key, category,
                                            utils.joinArgs(args))
     return utils.listItems(self.server, query, bytag=True)
Ejemplo n.º 15
0
    def edit(self, **kwargs):
        """ Edit an object.

            Parameters:
                kwargs (dict): Dict of settings to edit.

            Example:
                {'type': 1,
                 'id': movie.ratingKey,
                 'collection[0].tag.tag': 'Super',
                 'collection.locked': 0}
        """
        if 'id' not in kwargs:
            kwargs['id'] = self.ratingKey
        if 'type' not in kwargs:
            kwargs['type'] = utils.searchType(self.type)

        part = '/library/sections/%s/all?%s' % (self.librarySectionID, urlencode(kwargs))
        self._server.query(part, method=self._server._session.put)
Ejemplo n.º 16
0
    def _loadData(self, data):
        """ Load attribute values from Plex XML response. """
        self._data = data
        self.filter = data.attrib.get('filter')
        self.id = cast(int, data.attrib.get('id'))
        self.key = data.attrib.get('key')
        self.role = data.attrib.get('role')
        self.tag = data.attrib.get('tag')
        self.thumb = data.attrib.get('thumb')

        parent = self._parent()
        self._librarySectionID = utils.cast(int, parent._data.attrib.get('librarySectionID'))
        self._librarySectionKey = parent._data.attrib.get('librarySectionKey')
        self._librarySectionTitle = parent._data.attrib.get('librarySectionTitle')
        self._parentType = parent.TYPE

        if self._librarySectionKey and self.filter:
            self.key = '%s/all?%s&type=%s' % (
                self._librarySectionKey, self.filter, utils.searchType(self._parentType))
Ejemplo n.º 17
0
    def edit(self, **kwargs):
        """ Edit an object.

            Parameters:
                kwargs (dict): Dict of settings to edit.

            Example:
                {'type': 1,
                 'id': movie.ratingKey,
                 'collection[0].tag.tag': 'Super',
                 'collection.locked': 0}
        """
        if 'id' not in kwargs:
            kwargs['id'] = self.ratingKey
        if 'type' not in kwargs:
            kwargs['type'] = utils.searchType(self.type)

        part = '/library/sections/%s/all?%s' % (self.librarySectionID,
                                                urlencode(kwargs))
        self._server.query(part, method=self._server._session.put)
Ejemplo n.º 18
0
    def listChoices(self, category, libtype=None, **kwargs):
        """ Returns a list of :class:`~plexapi.library.FilterChoice` objects for the
            specified category and libtype. kwargs can be any of the same kwargs in
            :func:`plexapi.library.LibraySection.search()` to help narrow down the choices
            to only those that matter in your current context.

            Parameters:
                category (str): Category to list choices for (genre, contentRating, etc).
                libtype (int): Library type of item filter.
                **kwargs (dict): Additional kwargs to narrow down the choices.

            Raises:
                :class:`~plexapi.exceptions.BadRequest`: Cannot include kwarg equal to specified category.
        """
        # TODO: Should this be moved to base?
        if category in kwargs:
            raise BadRequest('Cannot include kwarg equal to specified category: %s' % category)
        args = {}
        for subcategory, value in kwargs.items():
            args[category] = self._cleanSearchFilter(subcategory, value)
        if libtype is not None:
            args['type'] = utils.searchType(libtype)
        key = '/library/sections/%s/%s%s' % (self.key, category, utils.joinArgs(args))
        return self.fetchItems(key, cls=FilterChoice)