Beispiel #1
0
    def add_movie(self,
                  movie_tmdbid,
                  movie_title,
                  movie_year,
                  movie_title_slug,
                  profile_id,
                  root_folder,
                  search_missing=False):
        payload = self._prepare_add_object_payload(movie_title,
                                                   movie_title_slug,
                                                   profile_id, root_folder)

        payload = dict_merge(
            payload, {
                'tmdbId': movie_tmdbid,
                'year': movie_year,
                'minimumAvailability': 'released',
                'addOptions': {
                    'searchForMovie': search_missing
                }
            })

        return self._add_object('api/movie',
                                payload,
                                identifier_field='tmdbId',
                                identifier=movie_tmdbid)
Beispiel #2
0
    def add_series(self,
                   series_tvdbid,
                   series_title,
                   series_title_slug,
                   profile_id,
                   root_folder,
                   tag_ids=None,
                   search_missing=False):
        payload = self._prepare_add_object_payload(series_title,
                                                   series_title_slug,
                                                   profile_id, root_folder)

        payload = dict_merge(
            payload, {
                'tvdbId': series_tvdbid,
                'tags': []
                if not tag_ids or not isinstance(tag_ids, list) else tag_ids,
                'seasons': [],
                'seasonFolder': True,
                'addOptions': {
                    'searchForMissingEpisodes': search_missing
                }
            })

        return self._add_object('api/series',
                                payload,
                                identifier_field='tvdbId',
                                identifier=series_tvdbid)
Beispiel #3
0
    def _make_item_request(self, url, object_name, payload=None):

        if payload is None:
            payload = {}

        payload = dict_merge(payload, {'extended': 'full'})

        try:
            req, resp_data = self._make_request(url, payload)

            if req.status_code == 200 and len(resp_data):
                resp_json = json.loads(resp_data)
                return resp_json
            elif req.status_code == 401:
                log.error(
                    "The authentication to Trakt is revoked. Please re-authenticate."
                )
                exit()
            else:
                log.error("Failed to retrieve %s, request response: %d",
                          object_name, req.status_code)
                return None
        except Exception:
            log.exception("Exception retrieving %s: ", object_name)
        return None
Beispiel #4
0
    def add_series(self, series_tvdb_id, series_title, series_title_slug, quality_profile_id, language_profile_id,
                   root_folder, tag_ids=None, search_missing=False, series_type='standard'):
        payload = self._prepare_add_object_payload(series_title, series_title_slug, quality_profile_id, root_folder)

        payload = dict_merge(payload, {
            'tvdbId': series_tvdb_id,
            'tags': [] if not tag_ids or not isinstance(tag_ids, list) else tag_ids,
            'seasons': [],
            'seasonFolder': True,
            'seriesType': series_type,
            'addOptions': {
                'searchForMissingEpisodes': search_missing
            }
        })

        if language_profile_id:
            payload['languageProfileId'] = language_profile_id
            endpoint = 'api/v3/series'
        else:
            endpoint = 'api/series'

        return self._add_object(endpoint, payload, identifier_field='tvdbId', identifier=series_tvdb_id)
Beispiel #5
0
    def add_movie(self,
                  movie_tmdb_id,
                  movie_title,
                  movie_year,
                  movie_title_slug,
                  quality_profile_id,
                  root_folder,
                  min_availability_temp,
                  search_missing=False):
        payload = self._prepare_add_object_payload(movie_title,
                                                   movie_title_slug,
                                                   quality_profile_id,
                                                   root_folder)

        # replace radarr minimum_availability if supplied
        if min_availability_temp == 'announced':
            minimum_availability = 'announced'
        elif min_availability_temp == 'in_cinemas':
            minimum_availability = 'inCinemas'
        elif min_availability_temp == 'predb':
            minimum_availability = 'preDB'
        else:
            minimum_availability = 'released'

        payload = dict_merge(
            payload, {
                'tmdbId': movie_tmdb_id,
                'year': int(movie_year),
                'minimumAvailability': minimum_availability,
                'addOptions': {
                    'searchForMovie': search_missing
                }
            })

        return self._add_object('api/v3/movie',
                                payload,
                                identifier_field='tmdbId',
                                identifier=movie_tmdb_id)
Beispiel #6
0
    def _make_items_request(
        self,
        url,
        limit,
        type_name,
        object_name,
        authenticate_user=None,
        payload=None,
        sleep_between=5,
        years=None,
        countries=None,
        languages=None,
        genres=None,
        runtimes=None,
        include_non_acting_roles=False,
    ):

        # default payload
        if payload is None:
            payload = {}

        payload = dict_merge(payload, {
            'extended': 'full',
            'limit': limit,
            'page': 1,
        })

        # languages list
        if languages:
            payload['languages'] = ','.join(languages).lower()

        # years range
        if years:
            payload['years'] = years

        # countries list
        if countries:
            payload['countries'] = ','.join(countries).lower()

        # genres list
        if genres:
            payload['genres'] = ','.join(genres).lower()

        # runtimes range
        if runtimes:
            payload['runtimes'] = runtimes

        processed = []

        if authenticate_user:
            type_name = type_name.replace(
                '{authenticate_user}',
                self._user_used_for_authentication(authenticate_user))

        try:
            resp_data = ''
            while True:
                attempts = 0
                max_attempts = 6
                retrieve_error = False
                while attempts <= max_attempts:
                    try:
                        req, resp_data = self._make_request(
                            url, payload, authenticate_user)
                        if resp_data is not None:
                            retrieve_error = False
                            break
                        else:
                            log.warning(
                                "Failed to retrieve valid response for Trakt %s %s from _make_item_request",
                                type_name, object_name)

                    except Exception:
                        log.exception(
                            "Exception retrieving %s %s in _make_item_request: ",
                            type_name, object_name)
                        retrieve_error = True

                    attempts += 1
                    log.info(
                        "Sleeping for %d seconds before making attempt %d/%d",
                        3 * attempts, attempts + 1, max_attempts)
                    time.sleep(3 * attempts)

                if retrieve_error or not resp_data or not len(resp_data):
                    log.error(
                        "Failed retrieving %s %s from _make_item_request %d times, aborting...",
                        type_name, object_name, attempts)
                    return None

                current_page = payload['page']
                total_pages = 0 if 'X-Pagination-Page-Count' not in req.headers else int(
                    req.headers['X-Pagination-Page-Count'])

                log.debug("Response Page: %d of %d", current_page, total_pages)

                if req.status_code == 200 and len(resp_data):
                    if (resp_data.startswith("[{") and resp_data.endswith("}]")) or \
                            (resp_data.startswith("{") and resp_data.endswith("}")):

                        resp_json = json.loads(resp_data)

                        if type_name == 'person' and 'cast' in resp_json:
                            for item in resp_json['cast']:
                                # filter out non-acting roles
                                if not include_non_acting_roles and \
                                        ((item['character'].strip() == '') or
                                         'narrat' in item['character'].lower() or
                                         'himself' in item['character'].lower()):
                                    continue
                                if item not in processed:
                                    if object_name.rstrip(
                                            's'
                                    ) not in item and 'title' in item:
                                        processed.append(
                                            {object_name.rstrip('s'): item})
                                    else:
                                        processed.append(item)
                        else:
                            for item in resp_json:
                                if item not in processed:
                                    if object_name.rstrip(
                                            's'
                                    ) not in item and 'title' in item:
                                        processed.append(
                                            {object_name.rstrip('s'): item})
                                    else:
                                        processed.append(item)

                    elif resp_data == '[]':
                        log.warning(
                            "Received empty JSON response for page: %d of %d",
                            current_page, total_pages)
                    else:
                        log.warning(
                            "Received malformed JSON response for page: %d of %d",
                            current_page, total_pages)

                    # check if we have fetched the last page, break if so
                    if total_pages == 0:
                        log.debug("There were no more pages left to retrieve.")
                        break
                    elif current_page >= total_pages:
                        log.debug(
                            "There are no more pages left to retrieve results from."
                        )
                        break
                    else:
                        log.info(
                            "There are %d page(s) left to retrieve results from.",
                            total_pages - current_page)
                        payload['page'] += 1
                        time.sleep(sleep_between)

                elif req.status_code == 401:
                    log.error(
                        "The authentication to Trakt is revoked. Please re-authenticate."
                    )
                    exit()
                else:
                    log.error("Failed to retrieve %s %s, request response: %d",
                              type_name, object_name, req.status_code)
                    break

            if len(processed):
                log.debug("Found %d %s %s", len(processed), type_name,
                          object_name)
                return processed

            return None
        except Exception:
            log.exception("Exception retrieving %s %s: ", type_name,
                          object_name)
        return None
Beispiel #7
0
    def _make_items_request(self, url, page, limit, languages, type_name, object_name, authenticate_user=None, payload={},
                            sleep_between=5, genres=None):
        if not languages:
            languages = ['en']

        #Limit pages and results per page if a results_limit was sent.
        if limit == 0:
            limit_results = False
            limit = 1000
        else:
            limit_results = True
            total_pages, limit = self.getPageAndResultsPerPage(limit)
            
        payload = dict_merge(payload, {'extended': 'full', 'limit': limit, 'page': 1, 'languages': ','.join(languages)})
        if genres:
            payload['genres'] = genres

        processed = []

        if authenticate_user:
            type_name = type_name.replace('{authenticate_user}', self._user_used_for_authentication(authenticate_user))

        try:
            resp_data = ''
            while True:
                attempts = 0
                max_attempts = 6
                retrieve_error = False
                while attempts <= max_attempts:
                    try:
                        req, resp_data = self._make_request(url, payload, authenticate_user)
                        if resp_data is not None:
                            retrieve_error = False
                            break
                        else:
                            log.warning("Failed to retrieve valid response for Trakt %s %s from _make_item_request",
                                        type_name, object_name)

                    except Exception:
                        log.exception("Exception retrieving %s %s in _make_item_request: ", type_name, object_name)
                        retrieve_error = True

                    attempts += 1
                    log.info("Sleeping for %d seconds before making attempt %d/%d", 3 * attempts, attempts + 1,
                             max_attempts)
                    time.sleep(3 * attempts)

                if retrieve_error or not resp_data or not len(resp_data):
                    log.error("Failed retrieving %s %s from _make_item_request %d times, aborting...", type_name,
                              object_name, attempts)
                    return None

                current_page = payload['page']
                
                #Limit pages if results are limited.    
                if limit_results == True and not type_name == 'boxoffice':
                    log.debug("Limiting Trakt list results to %d.",limit)
                else:
                    if type_name == 'boxoffice':
                        log.debug("Cannot limit Trakt's Box Office results. It always has 10 results.")
                        total_pages = 1
                    else:
                        log.debug("Not limiting Trakt list results.")
                        total_pages = 0 if 'X-Pagination-Page-Count' not in req.headers else int(req.headers['X-Pagination-Page-Count'])

                log.debug("Response Page: %d of %d", current_page, total_pages)

                if req.status_code == 200 and len(resp_data):
                    if resp_data.startswith("[{") and resp_data.endswith("}]"):
                        resp_json = json.loads(resp_data)

                        if type_name == 'person' and 'cast' in resp_json:
                            # handle person results
                            for item in resp_json['cast']:
                                if item not in processed:
                                    if object_name.rstrip('s') not in item and 'title' in item:
                                        processed.append({object_name.rstrip('s'): item})
                                    else:
                                        processed.append(item)
                        else:
                            for item in resp_json:
                                if item not in processed:
                                    if object_name.rstrip('s') not in item and 'title' in item:
                                        processed.append({object_name.rstrip('s'): item})
                                    else:
                                        processed.append(item)

                    else:
                        log.warning("Received malformed JSON response for page: %d of %d", current_page, total_pages)

                    # check if we have fetched the last page, break if so
                    if total_pages == 0:
                        log.debug("There were no more pages to retrieve")
                        break
                    elif current_page >= total_pages:
                        log.debug("There are no more pages to retrieve results from")
                        break
                    else:
                        log.info("There are %d pages left to retrieve results from", total_pages - current_page)
                        payload['page'] += 1
                        time.sleep(sleep_between)

                elif req.status_code == 401:
                    log.error("The authentication to Trakt is revoked. Please re-authenticate.")
                    exit()
                else:
                    log.error("Failed to retrieve %s %s, request response: %d", type_name, object_name, req.status_code)
                    break

            if len(processed):
                log.debug("Found %d %s %s", len(processed), type_name, object_name)
                return processed

            return None
        except Exception:
            log.exception("Exception retrieving %s %s: ", type_name, object_name)
        return None
    def _make_items_request(self,
                            url,
                            limit,
                            languages,
                            type_name,
                            object_name,
                            authenticate_user=None,
                            payload={},
                            sleep_between=5,
                            genres=None):
        if not languages:
            languages = ['en']

        payload = dict_merge(
            payload, {
                'extended': 'full',
                'limit': limit,
                'page': 1,
                'languages': ','.join(languages)
            })
        if genres:
            payload['genres'] = genres

        processed = []

        if authenticate_user:
            type_name = type_name.replace(
                '{authenticate_user}',
                self._user_used_for_authentication(authenticate_user))

        try:
            while True:
                req = self._make_request(url, payload, authenticate_user)

                current_page = payload['page']
                total_pages = 0 if 'X-Pagination-Page-Count' not in req.headers else int(
                    req.headers['X-Pagination-Page-Count'])

                log.debug("Response Page: %d of %d", current_page, total_pages)

                if req.status_code == 200:
                    resp_json = req.json()
                    if type_name == 'person' and 'cast' in resp_json:
                        # handle person results
                        for item in resp_json['cast']:
                            if item not in processed:
                                if object_name.rstrip(
                                        's') not in item and 'title' in item:
                                    processed.append(
                                        {object_name.rstrip('s'): item})
                                else:
                                    processed.append(item)
                    else:
                        for item in resp_json:
                            if item not in processed:
                                if object_name.rstrip(
                                        's') not in item and 'title' in item:
                                    processed.append(
                                        {object_name.rstrip('s'): item})
                                else:
                                    processed.append(item)

                    # check if we have fetched the last page, break if so
                    if total_pages == 0:
                        log.debug("There were no more pages to retrieve")
                        break
                    elif current_page >= total_pages:
                        log.debug(
                            "There are no more pages to retrieve results from")
                        break
                    else:
                        log.info(
                            "There are %d pages left to retrieve results from",
                            total_pages - current_page)
                        payload['page'] += 1
                        time.sleep(sleep_between)
                elif req.status_code == 401:
                    log.error(
                        "The authentication to Trakt is revoked. Please re-authenticate."
                    )
                    exit()
                else:
                    log.error("Failed to retrieve %s %s, request response: %d",
                              type_name, object_name, req.status_code)
                    break

            if len(processed):
                log.debug("Found %d %s %s", len(processed), type_name,
                          object_name)
                return processed
            return None
        except Exception:
            log.exception("Exception retrieving %s %s: ", type_name,
                          object_name)
        return None