Exemple #1
0
    def _retry_request(retry_count, prompt=True, message='Request failed', reason=None):
        # Ask if a retry should be attempted
        if prompt:
            print('%s (%s)' % (
                message,
                reason
            ))

            if boolean_input('Request has failed %d times, retry request?' % retry_count, default=True):
                # Retry request again
                return

            # User cancelled the request
            if reason:
                raise Exception('%s (attempted %d times), %s' % (
                    message,
                    retry_count,
                    reason
                ))

            raise Exception('%s (attempted %d times)' % (
                message,
                retry_count
            ))

        # Retry request
        print('%s, retrying in 5 seconds... (%s)' % (
            message,
            reason
        ))
        time.sleep(5)
Exemple #2
0
    def process_movies(self, profile, movies):
        log.debug('Executing actions on %d movies...', len(movies))

        timezone = profile.timezone

        for _, movie in movies.items():
            title, ids = Formatter.movie(movie, timezone=timezone)
            print()

            # Review actions
            if self.review and not boolean_input(
                    'Remove %d duplicate history record(s) for %s?' %
                (len(ids), title),
                    default=True):
                print('Skipped')
                continue

            # Remove history records
            for x in six.moves.xrange(0, len(ids), self.batch_size):
                self._remove_records(ids[x:x + self.batch_size])

            print()
            print('-' * 70)
            print()

        return True
Exemple #3
0
    def execute(self, profile, review=None):
        if review is None:
            review = boolean_input('Review every action?', default=True)
            print()

        executor = Executor(review)

        if not executor.process_shows(profile, self.scanner.shows):
            return False

        if not executor.process_movies(profile, self.scanner.movies):
            return False

        print('Done')
        return True
Exemple #4
0
    def _remove_records(ids):
        while True:
            # Attempt removal of records
            try:
                response = Trakt['sync/history'].remove(items={'ids': ids},
                                                        exceptions=True)
            except (ClientError, ServerError, RequestException) as ex:
                # Retrieve error message
                message = ex.message

                if isinstance(ex, (ClientError, ServerError)):
                    _, message = ex.error

                # Prompt for request retry
                print('Unable to remove %d history record(s): %s' %
                      (len(ids), message))

                if not boolean_input('Would you like to retry the request?',
                                     default=True):
                    # Cancel request
                    return False

                # Retry request
                print()
                continue

            # Display results
            deleted_episodes = response.get('deleted', {}).get('episodes', 0)
            deleted_movies = response.get('deleted', {}).get('movies', 0)

            if deleted_episodes and deleted_movies:
                print(
                    'Removed %d episode record(s) and %d movie record(s) from history'
                    % (deleted_episodes, deleted_movies))
            elif deleted_episodes:
                print('Removed %d episode record(s) from history' %
                      (deleted_episodes))
            elif deleted_movies:
                print('Removed %d movie record(s) from history' %
                      (deleted_movies))

            for record_id in response.get('not_found', {}).get('ids', []):
                print('Unable to find record with id: %r' % record_id)

            return True
Exemple #5
0
    def _add_movies(self, movies):
        response = Trakt['sync/history'].add({'movies': movies})

        print(' - Added {} Movies'.format(response.get("added").get("movies")))

        failed_movies = response.get('not_found').get('movies')
        if len(failed_movies) > 0:
            print()
            print('Unable to apply Movies:')
            for movie in failed_movies:
                print(' - ', movie)

            print()
            if not boolean_input('Would you like to continue anyway?',
                                 default=False):
                return False

        return True
Exemple #6
0
    def process(self, profile=None):
        log.debug('process()')

        if not profile:
            print('Requesting profile...')
            profile = Profile.fetch(self.per_page, self.rate_limit)

        if not profile:
            print('Unable to fetch profile')
            exit(1)

        print('Logged in as %r' % profile.username)
        print()

        if not boolean_input('Would you like to continue?', default=True):
            exit(0)

        print()

        if not self.scan(profile):
            exit(1)

        print()

        if not self.shows and not self.movies:
            print('Unable to find any duplicates')
            exit(0)

        timezone = profile.timezone

        # Display duplicate shows
        for _, show in self.shows.items():
            if not show.children:
                continue

            Formatter.show(show, timezone=timezone)
            print()

        # Display duplicate movies
        for _, movie in self.movies.items():
            Formatter.movie(movie, timezone=timezone)
            print()

        return True
Exemple #7
0
    def process(self, profile=None):
        log.debug('process()')

        if not profile:
            print('Requesting profile...')
            profile = Profile.fetch(self.per_page, self.rate_limit)

        if not profile:
            raise Exception('Unable to fetch profile')

        print('Logged in as %r' % profile.username)
        print()

        if not boolean_input('Would you like to continue?', default=True):
            exit(0)

        print()

        # Create backup
        return self.create_backup(profile)
Exemple #8
0
    def process(self, profile=None, backup=None, review=None):
        log.debug('process()')

        if not profile:
            print('Requesting profile...')
            profile = Profile.fetch(
                self.per_page,
                self.rate_limit
            )

        if not profile:
            print('Unable to fetch profile')
            exit(1)

        print('Logged in as %r' % profile.username)
        print()

        if not boolean_input('Would you like to continue?', default=True):
            exit(0)

        print()

        # Create backup
        if backup is None:
            backup = boolean_input('Create profile backup?', default=True)
            print()

        if backup and not self._create_backup(profile):
            print('Unable to create backup')
            exit(1)

        print()

        # Construct new duplicate scanner
        self.scanner = ScanHistoryDuplicatesTask(
            delta_max=self.delta_max,

            debug=self.debug,
            rate_limit=self.rate_limit
        )

        # Scan history for duplicates
        if not self.scanner.scan(profile):
            exit(1)

        print()

        if len(self.scanner.shows) or len(self.scanner.movies):
            print('Found %d show(s) and %d movie(s) with duplicates' % (
                len(self.scanner.shows),
                len(self.scanner.movies)
            ))
        else:
            print('Unable to find any duplicates')
            exit(0)

        print()

        # Execute actions
        if not self.execute(profile, review):
            print('Unable to execute actions')
            exit(1)

        return True