Пример #1
0
def series_modal(request):
    content_discovery = ContentDiscovery()
    content_manager = ContentManager()
    report_modal = request.GET.get("report_modal", False)

    # Get the ID from the URL
    tmdb_id = request.GET.get("tmdb_id", None)
    tvdb_id = request.GET.get("tvdb_id", None)

    # Determine the TVDB ID
    if tvdb_id:
        pass

    elif tmdb_id:
        tvdb_id = content_discovery.get_external_ids(tmdb_id, "tv")["tvdb_id"]

    # Check if the show is already within Sonarr's collection
    requested_show = content_manager.get(tvdb_id=tvdb_id)

    # If it doesn't already exists, add then add it
    if requested_show is None:

        sonarr_params = obtain_sonarr_parameters(content_discovery,
                                                 content_manager, tmdb_id,
                                                 tvdb_id)

        requested_show = content_manager.add(
            tvdb_id=tvdb_id,
            quality_profile_id=sonarr_params["sonarr_profile_id"],
            root_dir=sonarr_params["sonarr_root"],
            series_type=sonarr_params["series_type"],
            season_folders=sonarr_params["season_folders"],
        )

    # Keep refreshing until we get the series from Sonarr
    series = content_manager.get(tvdb_id=tvdb_id,
                                 obtain_season_info=True,
                                 force_update_cache=True)
    if series is None:
        series_fetch_retries = 0
        while series is None:
            if series_fetch_retries > MAX_SERIES_FETCH_RETRIES:
                break
            series_fetch_retries = series_fetch_retries + 1
            series = content_manager.get(tvdb_id=tvdb_id,
                                         obtain_season_info=True,
                                         force_update_cache=True)
            log.handler(
                "Sonarr did not have the series information! Conreq is waiting...",
                log.INFO,
                __logger,
            )

    context = generate_context({
        "seasons": series["seasons"],
        "tvdb_id": tvdb_id,
        "report_modal": report_modal
    })
    template = loader.get_template("modal/series_selection.html")
    return HttpResponse(template.render(context, request))
Пример #2
0
def set_many_availability(results):
    """Sets the availabily on list of cards."""
    # Fetch Sonarr and Radarr libraries
    radarr_library = cache.handler(
        "radarr library",
    )
    sonarr_library = cache.handler(
        "sonarr library",
    )

    # Generate the availability if possible, or get the external ID if a TVDB ID is needed
    thread_list = []
    if isinstance(results, list):
        for card in results:
            thread = Thread(
                target=__set_many_availability,
                args=[card, radarr_library, sonarr_library],
            )
            thread.start()
            thread_list.append(thread)
        for thread in thread_list:
            thread.join()
    else:
        log.handler(
            "set_many_availability did not recieve a List!",
            log.WARNING,
            _logger,
        )

    return results
Пример #3
0
def manage_issue(request):
    if request.method == "POST":
        request_parameters = json.loads(request.body.decode("utf-8"))
        log.handler(
            "Manage issue command received: " + str(request_parameters),
            log.INFO,
            _logger,
        )

        # Delete a request
        if request_parameters.get("action", None) == "delete":
            issue = ReportedIssue.objects.select_related("reported_by").get(
                id=request_parameters["request_id"])

            # Check if report belongs to the user, or if the user is admin
            if issue and request.user.is_staff or issue.reported_by == request.user:
                issue.delete()
                return JsonResponse({"success": True})

        # Change the resolved status of a request
        elif (request_parameters.get("action", None) == "resolve"
              and request.user.is_staff):
            issue = ReportedIssue.objects.filter(
                id=request_parameters["request_id"])
            if issue:
                issue.update(resolved=request_parameters["resolved"])
                return JsonResponse({"success": True})

    return HttpResponseForbidden()
Пример #4
0
    def get_sonarr_library(self):
        """Fetches everything within Sonarr's library"""
        try:
            if self.conreq_config.sonarr_enabled:
                if self.conreq_config.sonarr_url and self.conreq_config.sonarr_api_key:
                    # Get the latest list of Sonarr's collection
                    results = self.__sonarr.getSeries()

                    # Set up a dictionary of results with IDs as keys
                    results_with_ids = {}
                    for series in results:
                        if series.__contains__("tvdbId"):
                            self.__check_availability(series)
                            self.__set_content_attributes("tv", "sonarr", series)
                            results_with_ids[str(series["tvdbId"])] = series

                    # Return all movies
                    return results_with_ids

                log.handler(
                    "Sonarr URL or API key is unset!",
                    log.WARNING,
                    _logger,
                )

        except:
            log.handler(
                "Could not get series!",
                log.ERROR,
                _logger,
            )
Пример #5
0
    async def receive_json(self, content, **kwargs):
        """When the browser attempts to send a message to the server."""
        log.handler(
            content,
            log.INFO,
            self.__logger,
        )
        # Reject users that aren't logged in
        if (isinstance(self.scope["user"], AnonymousUser)
                or not self.scope["user"].is_authenticated):
            await self.__forbidden()
        else:
            # Verify login status.
            await login(self.scope, self.scope["user"])

            # Process the command
            if content["command_name"] == "request":
                await self.__request_content(content)

            elif content["command_name"] == "generate modal":
                await self.__generate_modal(content)

            elif content["command_name"] == "server settings":
                await self.__server_settings(content)

            else:
                log.handler(
                    "Invalid websocket command.",
                    log.ERROR,
                    self.__logger,
                )
Пример #6
0
    def get_all_sonarr_content(self):
        try:
            if self.conreq_config.sonarr_enabled:
                if self.conreq_config.sonarr_url and self.conreq_config.sonarr_api_key:
                    # Get the latest list of Sonarr's collection
                    results = self.__sonarr.getSeries()

                    # Set up a dictionary of results with IDs as keys
                    results_with_ids = {}
                    for series in results:
                        if series.__contains__("tvdbId"):
                            self.__check_status(series)

                            results_with_ids[str(series["tvdbId"])] = series

                    # Return all movies
                    return results_with_ids

                log.handler(
                    "Sonarr URL or API key is unset!",
                    log.WARNING,
                    self.__logger,
                )

        except:
            log.handler(
                "Could not get series!",
                log.ERROR,
                self.__logger,
            )
Пример #7
0
    def all(self, query, page_number):
        """Search for a query. Sort the
        results based on their similiarity to the query.

        Args:
            query: A string containing a search term.
        """
        try:
            results = self._remove_bad_content_types(
                self._set_content_attributes(
                    None,
                    cache.handler(
                        "search all",
                        page_key=page_number,
                        function=tmdb.Search().multi,
                        cache_duration=SEARCH_CACHE_TIMEOUT,
                        kwargs={
                            "page": page_number,
                            "query": query,
                            "language": LANGUAGE,
                        },
                    ),
                ))
            return results

        except:
            log.handler(
                "Searching for all failed!",
                log.ERROR,
                _logger,
            )
            return []
Пример #8
0
    def movie(self, query, page_number):
        """Search Radarr for a query.

        Args:
            query: A string containing a search term.
        """
        try:
            results = self._set_content_attributes(
                "movie",
                cache.handler(
                    "search movie",
                    page_key=page_number,
                    function=tmdb.Search().movie,
                    cache_duration=SEARCH_CACHE_TIMEOUT,
                    kwargs={
                        "page": page_number,
                        "query": query,
                        "language": LANGUAGE,
                    },
                ),
            )
            return results

        except:
            log.handler(
                "Searching for movies failed!",
                log.ERROR,
                _logger,
            )
            return []
Пример #9
0
    def refresh_content(self):
        """Refreshes Sonarr and Radarr's content"""
        try:
            if self.conreq_config.radarr_enabled:
                cache.handler(
                    "radarr library cache",
                    function=self.get_all_radarr_content,
                    cache_duration=GET_CONTENT_CACHE_TIMEOUT,
                    force_update_cache=True,
                )
        except:
            log.handler(
                "Failed to refresh radarr!",
                log.WARNING,
                self.__logger,
            )

        try:
            if self.conreq_config.sonarr_enabled:
                cache.handler(
                    "sonarr library cache",
                    function=self.get_all_sonarr_content,
                    cache_duration=GET_CONTENT_CACHE_TIMEOUT,
                    force_update_cache=True,
                )
        except:
            log.handler(
                "Failed to refresh sonarr!",
                log.WARNING,
                self.__logger,
            )
Пример #10
0
    def __generate_conreq_rank(self, result, clean_query):
        """Determines string similarity and combined with a weight of the original rank"""
        try:
            clean_title = clean_string(result["title"])

            # Multiplier if whole substring was found within the search result
            if clean_title.find(clean_query) != -1:
                query_substring_multiplier = 0.1
            else:
                query_substring_multiplier = 1

            # Generate similarity rank
            result["conreqSimilarityRank"] = (
                # Round the values to look pretty
                self.__round(
                    # String similarity between the query and result
                    (
                        self.__damerau.distance(clean_query, clean_title)
                        # Use sonarr/radarr's original rank as a weight/bias
                        * (result["arrOriginalRank"] / 10))
                    # Bias towards full substring matches
                    * query_substring_multiplier) + 1)

        except:
            log.handler("Failed to generate conreq rank!", log.ERROR, _logger)
            try:
                result["conreqSimilarityRank"] = result["arrOriginalRank"]
            except:
                result["conreqSimilarityRank"] = 1
Пример #11
0
    def television(self, query, page_number):
        """Search Sonarr for a query.

        Args:
            query: A string containing a search term.
            conreq_rank: Calculate conreq similarity ranking and sort the results (True/False)
        """
        try:
            results = self._set_content_attributes(
                "tv",
                cache.handler(
                    "search tv",
                    page_key=page_number,
                    function=tmdb.Search().tv,
                    cache_duration=SEARCH_CACHE_TIMEOUT,
                    kwargs={
                        "page": page_number,
                        "query": query,
                        "language": LANGUAGE,
                    },
                ),
            )
            return results

        except:
            log.handler(
                "Searching for TV failed!",
                log.ERROR,
                _logger,
            )
            return []
Пример #12
0
    def get_all_radarr_content(self):
        try:
            if self.conreq_config.radarr_enabled:
                if self.conreq_config.radarr_url and self.conreq_config.radarr_api_key:
                    # Get the latest list of Radarr's collection
                    results = self.__radarr.getMovie()

                    # Set up a dictionary of results with IDs as keys
                    results_with_ids = {}
                    for movie in results:
                        if movie.__contains__("tmdbId"):
                            self.__check_status(movie)
                            results_with_ids[str(movie["tmdbId"])] = movie

                    # Return all movies
                    return results_with_ids

                log.handler(
                    "Radarr URL or API key is unset!",
                    log.WARNING,
                    self.__logger,
                )

        except:
            log.handler(
                "Could not get movies!",
                log.ERROR,
                self.__logger,
            )
Пример #13
0
    async def __generate_modal(self, content):
        response = {
            "command_name": "render page element",
            "selector": "#modal-content",
            "html": None,
        }

        # Check if an ID is present
        if (content["parameters"]["tvdb_id"] is not None
                or content["parameters"]["tmdb_id"] is not None):
            # Episode modal
            if content["parameters"]["modal_type"] == "episode selector":
                response["html"] = await database_sync_to_async(series_modal)(
                    tmdb_id=content["parameters"]["tmdb_id"],
                    tvdb_id=content["parameters"]["tvdb_id"],
                    user=self.scope["user"],
                )
                await self.send_json(response)

            # Content info modal
            elif content["parameters"]["modal_type"] == "content info":
                pass

            else:
                log.handler(
                    "Invalid modal type!",
                    log.ERROR,
                    self.__logger,
                )
        else:
            log.handler(
                "Generate modal command was missing an ID!",
                log.ERROR,
                self.__logger,
            )
Пример #14
0
def sonarr_request_background_task(
    tvdb_id, request_parameters, content_manager, sonarr_params, username
):
    """Function that can be run in the background to request something on Sonarr"""
    # Check if the show is already within Sonarr's collection
    show = content_manager.get(tvdb_id=tvdb_id)

    # If it doesn't already exists, add then request it
    if show is None:
        show = content_manager.add(
            tvdb_id=tvdb_id,
            quality_profile_id=sonarr_params["sonarr_profile_id"],
            root_dir=sonarr_params["sonarr_root"],
            series_type=sonarr_params["series_type"],
            season_folders=sonarr_params["season_folders"],
        )

    # Request
    content_manager.request(
        sonarr_id=show["id"],
        seasons=request_parameters["seasons"],
        episode_ids=request_parameters["episode_ids"],
    )

    log.handler(
        username + " requested TV series " + show["title"],
        log.INFO,
        _logger,
    )
Пример #15
0
    def get_radarr_library(self):
        """Fetches everything within Radarr's library"""
        try:
            if self.conreq_config.radarr_enabled:
                if self.conreq_config.radarr_url and self.conreq_config.radarr_api_key:
                    # Get the latest list of Radarr's collection
                    results = self.__radarr.getMovie()

                    # Set up a dictionary of results with IDs as keys
                    results_with_ids = {}
                    for movie in results:
                        if movie.__contains__("tmdbId"):
                            self.__check_availability(movie)
                            self.__set_content_attributes("movie", "radarr", movie)
                            results_with_ids[str(movie["tmdbId"])] = movie

                    # Return all movies
                    return results_with_ids

                log.handler(
                    "Radarr URL or API key is unset!",
                    log.WARNING,
                    _logger,
                )

        except:
            log.handler(
                "Could not get movies!",
                log.ERROR,
                _logger,
            )
Пример #16
0
    def similar_and_recommended(self, tmdb_id, content_type):
        """Merges the results of similar and recommended.

        Args:
            id: An Integer or String containing the TMDB ID.
            content_type: String containing "movie" or "tv".
        """
        try:
            thread_list = []

            # Get recommended page one
            recommend_page_one = self.__recommended(tmdb_id, content_type, 1)

            # Gather additional recommended pages
            if recommend_page_one["total_pages"] > 1:
                for page_number in range(2, recommend_page_one["total_pages"]):
                    if page_number <= MAX_RECOMMENDED_PAGES:
                        thread = ReturnThread(
                            target=self.__recommended,
                            args=[tmdb_id, content_type, page_number],
                        )
                        thread.start()
                        thread_list.append(thread)

            # Get similar page one
            similar_page_one = self.__similar(tmdb_id, content_type, 1)

            # Gather up additional similar pages
            if similar_page_one["total_pages"] > 1:
                for page_number in range(2, similar_page_one["total_pages"]):
                    if page_number <= MAX_SIMILAR_PAGES:
                        thread = ReturnThread(
                            target=self.__similar,
                            args=[tmdb_id, content_type, page_number],
                        )
                        thread.start()
                        thread_list.append(thread)

            # Merge results of the first page of similar and recommended
            merged_results = self.__merge_results(recommend_page_one,
                                                  similar_page_one)

            # Wait for all the threads to complete and merge them in
            for thread in thread_list:
                merged_results = self.__merge_results(merged_results,
                                                      thread.join())

            self.determine_id_validity(merged_results)

            # Shuffle and return
            return self.__shuffle_results(merged_results)

        except:
            log.handler(
                "Failed to obtain merged Similar and Recommended!",
                log.ERROR,
                self.__logger,
            )
            return {}
Пример #17
0
def sonarr_settings(request):
    template = loader.get_template("viewport/components/server_settings_sonarr.html")

    # Database values
    conreq_config = ConreqConfig.get_solo()

    # Obtain sonarr and radarr information
    content_manger = ArrManager()
    sonarr_quality_profiles = []
    current_sonarr_anime_quality_profile = ""
    current_sonarr_tv_quality_profile = ""
    sonarr_folders = []
    current_sonarr_anime_folder = ""
    current_sonarr_tv_folder = ""

    if conreq_config.sonarr_enabled:
        # Sonarr Quality Profiles
        try:
            for profile in content_manger.sonarr_quality_profiles():
                # Current anime profile
                if conreq_config.sonarr_anime_quality_profile == profile["id"]:
                    current_sonarr_anime_quality_profile = profile["name"]
                # Current TV profile
                if conreq_config.sonarr_tv_quality_profile == profile["id"]:
                    current_sonarr_tv_quality_profile = profile["name"]
                # List of all dropdown entries
                sonarr_quality_profiles.append(
                    {"id": profile["id"], "label": profile["name"]}
                )
        except:
            log.handler("Failed to obtain Sonarr Quality Profiles!", log.ERROR, _logger)

        # Sonarr Folder Paths
        try:
            for path in content_manger.sonarr_root_dirs():
                # Current anime dirs
                if conreq_config.sonarr_anime_folder == path["id"]:
                    current_sonarr_anime_folder = path["path"]
                # Current TV dirs
                if conreq_config.sonarr_tv_folder == path["id"]:
                    current_sonarr_tv_folder = path["path"]
                # List of all dropdown entries
                sonarr_folders.append({"id": path["id"], "label": path["path"]})
        except:
            log.handler("Failed to obtain Sonarr Folder Paths!", log.ERROR, _logger)

    context = {
        "sonarr_quality_profiles": sonarr_quality_profiles,
        "current_sonarr_anime_quality_profile": current_sonarr_anime_quality_profile,
        "current_sonarr_tv_quality_profile": current_sonarr_tv_quality_profile,
        "sonarr_folders": sonarr_folders,
        "current_sonarr_anime_folder": current_sonarr_anime_folder,
        "current_sonarr_tv_folder": current_sonarr_tv_folder,
    }

    return HttpResponse(template.render(context, request))
Пример #18
0
    def get_by_tmdb_id(self, tmdb_id, content_type, obtain_extras=True):
        """Obtains a movie or series given a TMDB ID.

        Args:
            id: An Integer or String containing the TMDB ID.
            content_type: String containing "movie" or "tv".
        """
        # Searches for content based on TMDB ID
        try:
            # Obtain extras if needed
            if obtain_extras:
                extras = "reviews,keywords,videos,credits,images"
            else:
                extras = None

            # Obtain a movie by ID
            if content_type == "movie":
                return self._set_content_attributes(
                    content_type,
                    cache.handler(
                        "get movie by tmdb id",
                        page_key=tmdb_id,
                        function=tmdb.Movies(tmdb_id).info,
                        cache_duration=GET_BY_TMDB_ID_CACHE_TIMEOUT,
                        kwargs={"append_to_response": extras},
                    ),
                )

            # Obtain a TV show by ID
            if content_type == "tv":
                return self._set_content_attributes(
                    content_type,
                    cache.handler(
                        "get tv by tmdb id",
                        page_key=tmdb_id,
                        function=tmdb.TV(tmdb_id).info,
                        cache_duration=GET_BY_TMDB_ID_CACHE_TIMEOUT,
                        kwargs={"append_to_response": extras},
                    ),
                )

            # Content Type was invalid
            log.handler(
                "Invalid content_type " + str(content_type) +
                " in get_by_id().",
                log.WARNING,
                _logger,
            )

        except:
            log.handler(
                "Failed to obtain content by ID!",
                log.ERROR,
                _logger,
            )
        return None
Пример #19
0
    def sonarr_quality_profiles(self):
        """Returns the quality profiles available within Sonarr"""
        try:
            return self.__sonarr.get_quality_profiles()

        except:
            log.handler(
                "Failed to get sonarr quality profiles!",
                log.ERROR,
                _logger,
            )
Пример #20
0
    def radarr_quality_profiles(self):
        """Returns the quality profiles available within Radarr"""
        try:
            return self.__radarr.getQualityProfiles()

        except:
            log.handler(
                "Failed to get radarr quality profiles!",
                log.ERROR,
                _logger,
            )
Пример #21
0
    def radarr_root_dirs(self):
        """Returns the root dirs available within Radarr"""
        try:
            return self.__radarr.getRoot()

        except:
            log.handler(
                "Failed to get radarr root dirs!",
                log.ERROR,
                _logger,
            )
Пример #22
0
    def __recommended(self, tmdb_id, content_type, page_number):
        """Obtains recommendations given a TMDB ID.

        Args:
            id: An Integer or String containing the TMDB ID.
            content_type: String containing "movie" or "tv".
            page_number: An Integer that is the page number to return.
        """
        try:
            if content_type == "movie":
                return self._set_content_attributes(
                    content_type,
                    cache.handler(
                        "discover recommended movies",
                        page_key=str(tmdb_id) + "page" + str(page_number),
                        function=tmdb.Movies(tmdb_id).recommendations,
                        cache_duration=RECOMMENDED_CACHE_TIMEOUT,
                        kwargs={
                            "language": LANGUAGE,
                            "page": page_number,
                        },
                    ),
                )

            if content_type == "tv":
                return self._set_content_attributes(
                    content_type,
                    cache.handler(
                        "discover recommended tv",
                        page_key=str(tmdb_id) + "page" + str(page_number),
                        function=tmdb.TV(tmdb_id).recommendations,
                        cache_duration=RECOMMENDED_CACHE_TIMEOUT,
                        kwargs={
                            "language": LANGUAGE,
                            "page": page_number,
                        },
                    ),
                )

            # Content Type was invalid
            log.handler(
                "Invalid content_type " + str(content_type) +
                " in recommend().",
                log.WARNING,
                _logger,
            )

        except:
            log.handler(
                "Failed to obtain recommendations!",
                log.ERROR,
                _logger,
            )
        return None
Пример #23
0
 async def receive_json(self, content, **kwargs):
     """When the browser attempts to send a message to the server."""
     log.handler(
         content,
         log.INFO,
         _logger,
     )
     # Reject users that aren't logged in
     if (isinstance(self.scope["user"], AnonymousUser)
             or not self.scope["user"].is_authenticated):
         await self.__forbidden()
Пример #24
0
    def sonarr_root_dirs(self):
        """Returns the root dirs available within Sonarr"""
        try:
            return self.__sonarr.get_root_folder()

        except:
            log.handler(
                "Failed to get sonarr root dirs!",
                log.ERROR,
                _logger,
            )
Пример #25
0
    def __set_original_rank(self, results):
        """Sets the search ranking was provided by Sonarr/Radarr"""
        try:
            for index, result in enumerate(results, start=1):
                self.__generate_original_rank(result, index)

            # Sort them by the similarity metric
            return results

        except:
            log.handler("Failed to rank results", log.ERROR, _logger)
            return results
Пример #26
0
    def _shuffle_results(query):
        """Shuffle API results"""
        try:
            shuffle(query["results"])
            return query

        except:
            log.handler(
                "Failed to shuffle results!",
                log.ERROR,
                _logger,
            )
Пример #27
0
    def delete(self, **kwargs):
        """Deletes an existing movie, series, or episode(s) using Sonarr or Radarr.

        Kwargs:
            # Pick One ID
            radarr_id: An integer string containing the Radarr ID.
            sonarr_id: An integer containing the Sonarr ID.
            episode_file_ids: A list of integers containing the specific "episodeFileId" values.

        Returns:
            1) JSON response of removing the content.
            2) None
        """
        # TODO: Need to remove any currently downloading content for things that are removed.
        # TODO: Need to blacklist deleted content.
        try:
            # Remove a movie with a specific Radarr ID.
            if kwargs.__contains__("radarr_id"):
                return self.__radarr.delMovie(kwargs["radarr_id"],
                                              delFiles=True)

            # Remove a show with a specific Sonarr ID.
            if kwargs.__contains__("sonarr_id"):
                # Remove the whole show
                return self.__sonarr.delSeries(kwargs["sonarr_id"],
                                               delFiles=True)

            # Remove episodes with Sonarr episode IDs.
            if kwargs.__contains__("episode_file_ids"):
                response = []
                # Remove all episode files in the list
                for episode_id in kwargs["episode_file_ids"]:
                    response.append(
                        self.__sonarr.del_episode_file_by_episode_id(
                            episode_id))

                return response

            # Invalid parameter
            log.handler(
                "Invalid parameter for deleting content!",
                log.WARNING,
                self.__logger,
            )
            return None

        except:
            log.handler(
                "Failed to delete content!",
                log.ERROR,
                self.__logger,
            )
            return None
Пример #28
0
def __generate_request_card(entry, content_discovery, content_manager):
    """Generates a single request card. This is intended for multi-threaded use."""
    card = None
    # Fetch TMDB entry
    if entry["source"] == "tmdb":
        card = content_discovery.get_by_tmdb_id(
            tmdb_id=entry["content_id"],
            content_type=entry["content_type"],
            obtain_extras=False,
        )

    # Fetch TVDB entry
    elif entry["source"] == "tvdb":
        # Attempt to convert card to TMDB
        conversion = content_discovery.get_by_tvdb_id(tvdb_id=entry["content_id"])
        # Conversion found
        if conversion.__contains__("tv_results") and conversion["tv_results"]:
            card = conversion["tv_results"][0]

            # Convert all requests to use this new ID
            old_requests = UserRequest.objects.filter(
                content_id=entry["content_id"], source="tvdb"
            )
            old_requests.update(content_id=card["id"], source="tmdb")

        # Fallback to checking sonarr's database
        else:
            card = content_manager.get(tvdb_id=entry["content_id"])

            # Determine if the card has a known poster image
            if isinstance(card, dict):
                card["content_type"] = entry["content_type"]
                if card.__contains__("images"):
                    remote_poster = is_key_value_in_list(
                        "coverType", "poster", card["images"], return_item=True
                    )
                    if remote_poster:
                        card["remotePoster"] = remote_poster["remoteUrl"]

    if card is None:
        log.handler(
            entry["content_type"]
            + " from "
            + entry["source"]
            + " with ID "
            + entry["content_id"]
            + " no longer exists!",
            log.WARNING,
            _logger,
        )

    return card
Пример #29
0
    def discover_by_filter(self, content_type, **kwargs):
        """Filter by keywords or any other TMDB filter capable arguements.
        (see tmdbsimple discover.movie and discover.tv)

        Args:
            content_type: String containing "movie" or "tv".
            # Additional kwargs #
            keyword: A single String or a List of strings.
            _______: Any other values supported by tmdbsimple discover.movie or discover.tv.
        """
        try:
            if kwargs.__contains__("keyword"):
                # Convert all keywords to IDs
                keyword_ids = self.__keywords_to_ids(kwargs["keyword"])
                if keyword_ids is not None:
                    kwargs["with_keywords"] = keyword_ids

                # Remove keyword strings (invalid parameters)
                kwargs.__delitem__("keyword")

            # Perform a discovery search for a movie
            if content_type.lower() == "movie":
                return cache.handler(
                    "discover movie cache",
                    function=tmdb.Discover().movie,
                    page_key=str(kwargs),
                    cache_duration=DISCOVER_BY_FILTER_CACHE_TIMEOUT,
                    **kwargs,
                )

            # Perform a discovery search for a TV show
            if content_type.lower() == "tv":
                return cache.handler(
                    "discover tv cache",
                    function=tmdb.Discover().tv,
                    page_key=str(kwargs),
                    cache_duration=DISCOVER_BY_FILTER_CACHE_TIMEOUT,
                    **kwargs,
                )

            # Content Type was invalid
            log.handler(
                "Invalid content_type " + str(content_type) +
                " in discover().",
                log.WARNING,
                self.__logger,
            )
            return {}

        except:
            log.handler("Failed to discover!", log.ERROR, self.__logger)
            return {}
Пример #30
0
    def __round(self, number, significant_figures=5):
        # Round a number using the concept of significant figures
        try:
            # Rounding would've returned an error if the number is 0
            if number == 0:
                return number

            # Round a non-zero number
            return round(
                number, -int(floor(log10(number))) + (significant_figures - 1))
        except:
            log.handler("Failed to round!", log.ERROR, self.__logger)
            return number