Ejemplo n.º 1
0
    def run(self):
        for mo_id, guid, p_item in self.p_movies:
            # Increment one step
            self.current.progress.group(Movies, 'matched:movies').step()

            # Parse guid
            match = GuidParser.parse(guid)

            if not match.supported:
                mark_unsupported(self.p_unsupported, mo_id, guid)
                continue

            if not match.found:
                log.info('Unable to find identifier for: %s/%s (rating_key: %r)', guid.service, guid.id, mo_id)
                continue

            # Retrieve primary key for item
            pk = self.trakt.table('movies').get((match.guid.service, match.guid.id))

            # Process movie (execute handlers)
            self.execute_movie(mo_id, pk, match.guid, p_item)

            # Remove movie from pending items collection
            self.current.pending['movies'].remove(pk)

            # Task checkpoint
            self.checkpoint()

        # Stop progress group
        self.current.progress.group(Movies, 'matched:movies').stop()

        # Report unsupported movies (unsupported guid)
        log_unsupported(log, 'Found %d unsupported movie(s)', self.p_unsupported)
Ejemplo n.º 2
0
    def run(self):
        for mo_id, guid, p_item in self.p_movies:
            # Increment one step
            self.current.progress.group(Movies, 'matched:movies').step()

            # Parse guid
            match = GuidParser.parse(guid)

            if not match.supported:
                mark_unsupported(self.p_unsupported, mo_id, guid)
                continue

            if not match.found:
                log.info('Unable to find identifier for: %s/%s (rating_key: %r)', guid.service, guid.id, mo_id)
                continue

            # Retrieve primary key for item
            pk = self.trakt.table('movies').get((match.guid.service, match.guid.id))

            # Process movie (execute handlers)
            self.execute_movie(mo_id, pk, match.guid, p_item)

            # Remove movie from pending items collection
            self.current.pending['movies'].remove(pk)

            # Task checkpoint
            self.checkpoint()

        # Stop progress group
        self.current.progress.group(Movies, 'matched:movies').stop()

        # Report unsupported movies (unsupported guid)
        log_unsupported(log, 'Found %d unsupported movie(s)', self.p_unsupported)
Ejemplo n.º 3
0
    def run(self):
        # TODO process seasons
        self.run_shows()
        self.run_episodes()

        # Log details
        log_unsupported(log, 'Found %d unsupported show(s)', self.p_shows_unsupported)
Ejemplo n.º 4
0
    def finish(self):
        log_unsupported(log, 'Found %d unsupported show(s)',
                        self.p_shows_unsupported)

        # Process missing items
        self.finish_shows()
        self.finish_episodes()
Ejemplo n.º 5
0
    def run(self):
        self.run_shows()
        self.run_episodes()

        # Log details
        log_unsupported(log, 'Found %d unsupported show(s)', self.p_shows_unsupported)
        log.debug('Pending: %r', self.p_pending)
Ejemplo n.º 6
0
    def run(self):
        # TODO process seasons
        self.run_shows()
        self.run_episodes()

        # Log details
        log_unsupported(log, 'Found %d unsupported show(s)',
                        self.p_shows_unsupported)
Ejemplo n.º 7
0
    def run(self):
        self.run_shows()
        self.run_episodes()

        # Log details
        log_unsupported(log, 'Found %d unsupported show(s)',
                        self.p_shows_unsupported)
        log.debug('Pending: %r', self.p_pending)
Ejemplo n.º 8
0
    def run(self):
        # Process matched items
        self.process_matched_shows()
        self.process_matched_episodes()

        # Report unsupported shows
        log_unsupported(log, 'Found %d unsupported show(s)\n%s', self.p_shows_unsupported)

        # Process missing items
        self.process_missing_shows()
        self.process_missing_episodes()
Ejemplo n.º 9
0
    def run(self):
        # Process matched items
        self.process_matched_shows()
        self.process_matched_episodes()

        # Report unsupported shows
        log_unsupported(log, 'Found %d unsupported show(s)\n%s',
                        self.p_shows_unsupported)

        # Process missing items
        self.process_missing_shows()
        self.process_missing_episodes()
Ejemplo n.º 10
0
    def run(self):
        for mo_id, guid, p_movie in self.p_movies:
            # Parse guid
            match = GuidParser.parse(guid)

            if not match.supported:
                mark_unsupported(self.p_unsupported, mo_id, guid)
                continue

            if not match.found:
                log.info(
                    'Unable to find identifier for: %s/%s (rating_key: %r)',
                    guid.service, guid.id, mo_id)
                continue

            key = (match.guid.service, match.guid.id)

            # Try retrieve `pk` for `key`
            pk = self.trakt.table('movies').get(key)

            # Store in item map
            self.current.map.add(p_movie.get('library_section'), mo_id,
                                 [key, pk])

            if pk is None:
                # No `pk` found
                continue

            # Execute data handlers
            for data in self.get_data(SyncMedia.Movies):
                t_movie = self.trakt[(SyncMedia.Movies, data)].get(pk)

                self.execute_handlers(self.mode,
                                      SyncMedia.Movies,
                                      data,
                                      key=mo_id,
                                      p_item=p_movie,
                                      t_item=t_movie)

                # Increment one step
                self.step(self.p_pending, data, pk)

            # Task checkpoint
            self.checkpoint()

        # Log details
        log_unsupported(log, 'Found %d unsupported movie(s)',
                        self.p_unsupported)
        log.debug('Pending: %r', self.p_pending)
Ejemplo n.º 11
0
    def run(self):
        for mo_id, guid, p_movie in self.p_movies:
            # Parse guid
            match = GuidParser.parse(guid)

            if not match.supported:
                mark_unsupported(self.p_unsupported, mo_id, guid)
                continue

            if not match.found:
                log.info('Unable to find identifier for: %s/%s (rating_key: %r)', guid.service, guid.id, mo_id)
                continue

            key = (match.guid.service, match.guid.id)

            # Try retrieve `pk` for `key`
            pk = self.trakt.table('movies').get(key)

            # Store in item map
            self.current.map.add(p_movie.get('library_section'), mo_id, [key, pk])

            if pk is None:
                # No `pk` found
                continue

            # Execute data handlers
            for data in self.get_data(SyncMedia.Movies):
                t_movie = self.trakt[(SyncMedia.Movies, data)].get(pk)

                self.execute_handlers(
                    self.mode, SyncMedia.Movies, data,
                    key=mo_id,

                    p_item=p_movie,
                    t_item=t_movie
                )

                # Increment one step
                self.step(self.p_pending, data, pk)

            # Task checkpoint
            self.checkpoint()

        # Log details
        log_unsupported(log, 'Found %d unsupported movie(s)', self.p_unsupported)
        log.debug('Pending: %r', self.p_pending)
Ejemplo n.º 12
0
    def process_matched_movies(self):
        """Trigger actions for movies that have been matched in plex"""

        # Iterate over movies
        for rating_key, guid, p_item in self.p_movies:
            # Increment one step
            self.current.progress.group(Movies, 'matched:movies').step()

            # Ensure `guid` is available
            if not guid or guid.service not in GUID_SERVICES:
                mark_unsupported(self.p_unsupported, rating_key, guid)
                continue

            key = (guid.service, guid.id)

            # Try retrieve `pk` for `key`
            pk = self.trakt.table('movies').get(key)

            for data in self.get_data(SyncMedia.Movies):
                t_movie = self.trakt[(SyncMedia.Movies, data)].get(pk)

                self.execute_handlers(
                    SyncMedia.Movies, data,

                    key=rating_key,

                    guid=guid,
                    p_item=p_item,

                    t_item=t_movie
                )

            # Remove movie from `pending` set
            if pk and pk in self.p_pending:
                self.p_pending.remove(pk)

            # Task checkpoint
            self.checkpoint()

        # Stop progress group
        self.current.progress.group(Movies, 'matched:movies').stop()

        # Report unsupported movies (unsupported guid)
        log_unsupported(log, 'Found %d unsupported movie(s)\n%s', self.p_unsupported)
Ejemplo n.º 13
0
    def process_matched_movies(self):
        """Trigger actions for movies that have been matched in plex"""

        # Iterate over movies
        for rating_key, guid, p_item in self.p_movies:
            # Increment one step
            self.current.progress.group(Movies, 'matched:movies').step()

            # Ensure `guid` is available
            if not guid or guid.service not in GUID_SERVICES:
                mark_unsupported(self.p_unsupported, rating_key, guid, p_item)
                continue

            key = (guid.service, guid.id)

            # Try retrieve `pk` for `key`
            pk = self.trakt.table('movies').get(key)

            for data in self.get_data(SyncMedia.Movies):
                t_movie = self.trakt[(SyncMedia.Movies, data)].get(pk)

                self.execute_handlers(
                    SyncMedia.Movies, data,

                    key=rating_key,

                    guid=guid,
                    p_item=p_item,

                    t_item=t_movie
                )

            # Remove movie from `pending` set
            if pk and pk in self.p_pending:
                self.p_pending.remove(pk)

            # Task checkpoint
            self.checkpoint()

        # Stop progress group
        self.current.progress.group(Movies, 'matched:movies').stop()

        # Report unsupported movies (unsupported guid)
        log_unsupported(log, 'Found %d unsupported movie(s)\n%s', self.p_unsupported)
Ejemplo n.º 14
0
    def run(self):
        # Retrieve show sections
        p_sections, p_sections_map = self.sections('show')

        # Fetch episodes with account settings
        p_shows, p_seasons, p_episodes = self.plex.library.episodes.mapped(
            p_sections, ([
                MetadataItem.library_section
            ], [], []),
            account=self.current.account.plex.key,
            parse_guid=True
        )

        # TODO process seasons

        # Calculate total number of episodes
        pending = {}

        for data in self.get_data(SyncMedia.Episodes):
            t_episodes = [
                (key, se, ep)
                for key, t_show in self.trakt[(SyncMedia.Episodes, data)].items()
                for se, t_season in t_show.seasons.items()
                for ep in t_season.episodes.iterkeys()
            ]

            if data not in pending:
                pending[data] = {}

            for key in t_episodes:
                pending[data][key] = False

        # Task started
        unsupported_shows = {}

        # Process shows
        for sh_id, guid, p_show in p_shows:
            if not guid or guid.service not in GUID_SERVICES:
                mark_unsupported(unsupported_shows, sh_id, guid)
                continue

            key = (guid.service, guid.id)

            # Try retrieve `pk` for `key`
            pk = self.trakt.table('shows').get(key)

            # Store in item map
            self.current.map.add(p_show.get('library_section'), sh_id, [key, pk])

            if pk is None:
                # No `pk` found
                continue

            # Execute data handlers
            for data in self.get_data(SyncMedia.Shows):
                t_show = self.trakt[(SyncMedia.Shows, data)].get(pk)

                # Execute show handlers
                self.execute_handlers(
                    SyncMedia.Shows, data,
                    key=sh_id,

                    p_item=p_show,
                    t_item=t_show
                )

        # Process episodes
        for ids, guid, (season_num, episode_num), p_show, p_season, p_episode in p_episodes:
            if not guid or guid.service not in GUID_SERVICES:
                mark_unsupported(unsupported_shows, ids['show'], guid)
                continue

            key = (guid.service, guid.id)

            # Try retrieve `pk` for `key`
            pk = self.trakt.table('shows').get(key)

            if pk is None:
                # No `pk` found
                continue

            if not ids.get('episode'):
                # Missing `episode` rating key
                continue

            for data in self.get_data(SyncMedia.Episodes):
                t_show = self.trakt[(SyncMedia.Episodes, data)].get(pk)

                if t_show is None:
                    # Unable to find matching show in trakt data
                    continue

                t_season = t_show.seasons.get(season_num)

                if t_season is None:
                    # Unable to find matching season in `t_show`
                    continue

                t_episode = t_season.episodes.get(episode_num)

                if t_episode is None:
                    # Unable to find matching episode in `t_season`
                    continue

                self.execute_handlers(
                    SyncMedia.Episodes, data,
                    key=ids['episode'],

                    p_item=p_episode,
                    t_item=t_episode
                )

                # Increment one step
                self.step(pending, data, (pk, season_num, episode_num))

            # Task checkpoint
            self.checkpoint()

        # Log details
        log_unsupported(log, 'Found %d unsupported show(s)\n%s', unsupported_shows)
        log.debug('Pending: %r', pending)
Ejemplo n.º 15
0
    def finish(self):
        log_unsupported(log, 'Found %d unsupported show(s)', self.p_shows_unsupported)

        # Process missing items
        self.finish_shows()
        self.finish_episodes()
Ejemplo n.º 16
0
    def run(self):
        # TODO process seasons

        with elapsed.clock(Shows, 'run:shows'):
            # Process shows
            for sh_id, guid, p_show in self.p_shows:
                # Increment one step
                self.current.progress.group(Shows, 'shows').step()

                # Ensure `guid` is available
                if not guid or guid.service not in GUID_SERVICES:
                    mark_unsupported(self.p_shows_unsupported, sh_id, guid)
                    continue

                key = (guid.service, guid.id)

                # Try retrieve `pk` for `key`
                pk = self.trakt.table('shows').get(key)

                # Store in item map
                self.current.map.add(p_show.get('library_section'), sh_id, [key, pk])

                if pk is None:
                    # No `pk` found
                    continue

                # Iterate over changed data
                for key, result in self.trakt.changes:
                    media, data = key[0:2]

                    if media != SyncMedia.Shows:
                        # Ignore changes that aren't for episodes
                        continue

                    if data == SyncData.Watchlist:
                        # Ignore watchlist data
                        continue

                    if not self.is_data_enabled(data):
                        # Data type has been disabled
                        continue

                    data_name = Cache.Data.get(data)

                    if data_name not in result.changes:
                        # No changes for collection
                        continue

                    for action, shows in result.changes[data_name].items():
                        t_show = shows.get(pk)

                        if t_show is None:
                            # Unable to find matching show in trakt data
                            continue

                        # Execute show handlers
                        self.execute_handlers(
                            SyncMedia.Shows, data,
                            action=action,

                            key=sh_id,

                            p_item=p_show,
                            t_item=t_show
                        )

        # Stop progress group
        self.current.progress.group(Shows, 'shows').stop()

        with elapsed.clock(Shows, 'run:episodes'):
            # Process episodes
            for ids, guid, (season_num, episode_num), p_show, p_season, p_episode in self.p_episodes:
                # Increment one step
                self.current.progress.group(Shows, 'episodes').step()

                # Ensure `guid` is available
                if not guid or guid.service not in GUID_SERVICES:
                    mark_unsupported(self.p_shows_unsupported, ids['show'], guid)
                    continue

                key = (guid.service, guid.id)

                # Try retrieve `pk` for `key`
                pk = self.trakt.table('shows').get(key)

                if pk is None:
                    # No `pk` found
                    continue

                if not ids.get('episode'):
                    # Missing `episode` rating key
                    continue

                for key, result in self.trakt.changes:
                    media, data = key[0:2]

                    if media != SyncMedia.Episodes:
                        # Ignore changes that aren't for episodes
                        continue

                    if not self.is_data_enabled(data):
                        # Data type has been disabled
                        continue

                    data_name = Cache.Data.get(data)

                    if data_name not in result.changes:
                        # No changes for collection
                        continue

                    for action, shows in result.changes[data_name].items():
                        t_show = shows.get(pk)

                        if t_show is None:
                            # Unable to find matching show in trakt data
                            continue

                        t_season = t_show.get('seasons', {}).get(season_num)

                        if t_season is None:
                            # Unable to find matching season in `t_show`
                            continue

                        t_episode = t_season.get('episodes', {}).get(episode_num)

                        if t_episode is None:
                            # Unable to find matching episode in `t_season`
                            continue

                        self.execute_handlers(
                            SyncMedia.Episodes, data,
                            action=action,
                            key=ids['episode'],

                            p_item=p_episode,
                            t_item=t_episode
                        )

                # Task checkpoint
                self.checkpoint()

        # Stop progress group
        self.current.progress.group(Shows, 'episodes').stop()

        # Log details
        log_unsupported(log, 'Found %d unsupported show(s)\n%s', self.p_shows_unsupported)
Ejemplo n.º 17
0
    def run(self):
        # Retrieve movie sections
        p_sections, p_sections_map = self.sections('movie')

        # Fetch movies with account settings
        p_items = self.plex.library.movies.mapped(
            p_sections, [
                MetadataItem.library_section
            ],
            account=self.current.account.plex.key,
            parse_guid=True
        )

        # Calculate total number of movies
        pending = {}

        for data in self.get_data(SyncMedia.Movies):
            if data not in pending:
                pending[data] = {}

            for pk in self.trakt[(SyncMedia.Movies, data)]:
                pending[data][pk] = False

        # Task started
        unsupported_movies = {}

        for rating_key, guid, p_item in p_items:
            if not guid or guid.service not in GUID_SERVICES:
                mark_unsupported(unsupported_movies, rating_key, guid)
                continue

            key = (guid.service, guid.id)

            # Try retrieve `pk` for `key`
            pk = self.trakt.table('movies').get(key)

            # Store in item map
            self.current.map.add(p_item.get('library_section'), rating_key, [key, pk])

            if pk is None:
                # No `pk` found
                continue

            # Execute data handlers
            for data in self.get_data(SyncMedia.Movies):
                t_movie = self.trakt[(SyncMedia.Movies, data)].get(pk)

                self.execute_handlers(
                    SyncMedia.Movies, data,
                    key=rating_key,

                    p_item=p_item,
                    t_item=t_movie
                )

                # Increment one step
                self.step(pending, data, pk)

            # Task checkpoint
            self.checkpoint()

        # Log details
        log_unsupported(log, 'Found %d unsupported movie(s)\n%s', unsupported_movies)
        log.debug('Pending: %r', pending)
Ejemplo n.º 18
0
    def run(self):
        # Process movies
        for mo_id, guid, p_item in self.p_movies:
            # Increment one step
            self.current.progress.group(Movies).step()

            # Ensure `guid` is available
            if not guid or guid.service not in GUID_SERVICES:
                mark_unsupported(self.p_unsupported, mo_id, guid)
                continue

            key = (guid.service, guid.id)

            # Try retrieve `pk` for `key`
            pk = self.trakt.table('movies').get(key)

            # Store in item map
            self.current.map.add(p_item.get('library_section'), mo_id, [key, pk])

            if pk is None:
                # No `pk` found
                continue

            # Iterate over changed data
            for key, result in self.trakt.changes:
                media, data = key[0:2]

                if media != SyncMedia.Movies:
                    # Ignore changes that aren't for movies
                    continue

                if data == SyncData.Watchlist:
                    # Ignore watchlist data
                    continue

                if not self.is_data_enabled(data):
                    # Data type has been disabled
                    continue

                data_name = Cache.Data.get(data)

                if data_name not in result.changes:
                    # No changes for collection
                    continue

                for action, items in result.changes[data_name].items():
                    t_item = items.get(pk)

                    if t_item is None:
                        # No item found in changes
                        continue

                    self.execute_handlers(
                        SyncMedia.Movies, data,
                        action=action,
                        key=mo_id,

                        p_item=p_item,
                        t_item=t_item
                    )

            # Task checkpoint
            self.checkpoint()

        # Stop progress group
        self.current.progress.group(Movies).stop()

        # Log details
        log_unsupported(log, 'Found %d unsupported movie(s)\n%s', self.p_unsupported)
Ejemplo n.º 19
0
    def run(self):
        # Process movies
        for mo_id, guid, p_item in self.p_movies:
            # Increment one step
            self.current.progress.group(Movies).step()

            # Ensure `guid` is available
            if not guid or guid.service not in GUID_SERVICES:
                mark_unsupported(self.p_unsupported, mo_id, guid)
                continue

            key = (guid.service, guid.id)

            # Try retrieve `pk` for `key`
            pk = self.trakt.table('movies').get(key)

            # Store in item map
            self.current.map.add(p_item.get('library_section'), mo_id,
                                 [key, pk])

            if pk is None:
                # No `pk` found
                continue

            # Iterate over changed data
            for key, result in self.trakt.changes:
                media, data = key[0:2]

                if media != SyncMedia.Movies:
                    # Ignore changes that aren't for movies
                    continue

                if data == SyncData.Watchlist:
                    # Ignore watchlist data
                    continue

                if not self.is_data_enabled(data):
                    # Data type has been disabled
                    continue

                data_name = Cache.Data.get(data)

                if data_name not in result.changes:
                    # No changes for collection
                    continue

                for action, items in result.changes[data_name].items():
                    t_item = items.get(pk)

                    if t_item is None:
                        # No item found in changes
                        continue

                    self.execute_handlers(SyncMedia.Movies,
                                          data,
                                          action=action,
                                          key=mo_id,
                                          p_item=p_item,
                                          t_item=t_item)

            # Task checkpoint
            self.checkpoint()

        # Stop progress group
        self.current.progress.group(Movies).stop()

        # Log details
        log_unsupported(log, 'Found %d unsupported movie(s)\n%s',
                        self.p_unsupported)
Ejemplo n.º 20
0
    def run(self):
        # Process movies
        for mo_id, guid, p_movie in self.p_movies:
            # Increment one step
            self.current.progress.group(Movies).step()

            # Parse guid
            match = GuidParser.parse(guid)

            if not match.supported:
                mark_unsupported(self.p_unsupported, mo_id, guid)
                continue

            if not match.found:
                log.info(
                    'Unable to find identifier for: %s/%s (rating_key: %r)',
                    guid.service, guid.id, mo_id)
                continue

            key = (match.guid.service, match.guid.id)

            # Try retrieve `pk` for `key`
            pk = self.trakt.table('movies').get(key)

            # Store in item map
            self.current.map.add(p_movie.get('library_section'), mo_id,
                                 [key, pk])

            if pk is None:
                # No `pk` found
                continue

            # Run pull handlers if the item has been added recently
            if self.should_pull(mo_id, p_movie.get('added_at')):
                log.info(
                    'Movie %r has been added recently, running pull sync instead',
                    mo_id)

                # Execute handlers
                for data in self.get_data(SyncMedia.Movies):
                    t_movie = self.trakt[(SyncMedia.Movies, data)].get(pk)

                    self.execute_handlers(SyncMode.Pull,
                                          SyncMedia.Movies,
                                          data,
                                          key=mo_id,
                                          p_item=p_movie,
                                          t_item=t_movie)
            else:
                # Execute handlers for changed data
                for data, action, t_movie in self.iter_changes(
                        SyncMedia.Movies, pk):
                    self.execute_handlers(self.mode,
                                          SyncMedia.Movies,
                                          data,
                                          action=action,
                                          key=mo_id,
                                          p_item=p_movie,
                                          t_item=t_movie)

            # Task checkpoint
            self.checkpoint()

        # Stop progress group
        self.current.progress.group(Movies).stop()

        # Log details
        log_unsupported(log, 'Found %d unsupported movie(s)',
                        self.p_unsupported)
Ejemplo n.º 21
0
    def run(self):
        # Retrieve movie sections
        p_sections, p_sections_map = self.sections('movie')

        # Fetch movies with account settings
        p_items = self.plex.library.movies.mapped(
            p_sections, [MetadataItem.library_section],
            account=self.current.account.plex.key,
            parse_guid=True)

        # Calculate total number of movies
        pending = {}

        for data in self.get_data(SyncMedia.Movies):
            if data not in pending:
                pending[data] = {}

            for pk in self.trakt[(SyncMedia.Movies, data)]:
                pending[data][pk] = False

        # Task started
        unsupported_movies = {}

        for rating_key, guid, p_item in p_items:
            if not guid or guid.service not in GUID_SERVICES:
                mark_unsupported(unsupported_movies, rating_key, guid)
                continue

            key = (guid.service, guid.id)

            # Try retrieve `pk` for `key`
            pk = self.trakt.table('movies').get(key)

            # Store in item map
            self.current.map.add(p_item.get('library_section'), rating_key,
                                 [key, pk])

            if pk is None:
                # No `pk` found
                continue

            # Execute data handlers
            for data in self.get_data(SyncMedia.Movies):
                t_movie = self.trakt[(SyncMedia.Movies, data)].get(pk)

                self.execute_handlers(SyncMedia.Movies,
                                      data,
                                      key=rating_key,
                                      p_item=p_item,
                                      t_item=t_movie)

                # Increment one step
                self.step(pending, data, pk)

            # Task checkpoint
            self.checkpoint()

        # Log details
        log_unsupported(log, 'Found %d unsupported movie(s)\n%s',
                        unsupported_movies)
        log.debug('Pending: %r', pending)
Ejemplo n.º 22
0
    def run(self):
        # Process movies
        for mo_id, guid, p_movie in self.p_movies:
            # Increment one step
            self.current.progress.group(Movies).step()

            # Parse guid
            match = GuidParser.parse(guid)

            if not match.supported:
                mark_unsupported(self.p_unsupported, mo_id, guid)
                continue

            if not match.found:
                log.info('Unable to find identifier for: %s/%s (rating_key: %r)', guid.service, guid.id, mo_id)
                continue

            key = (match.guid.service, match.guid.id)

            # Try retrieve `pk` for `key`
            pk = self.trakt.table('movies').get(key)

            # Store in item map
            self.current.map.add(p_movie.get('library_section'), mo_id, [key, pk])

            if pk is None:
                # No `pk` found
                continue

            # Run pull handlers if the item has been added recently
            if self.should_pull(mo_id, p_movie.get('added_at')):
                log.info('Movie %r has been added recently, running pull sync instead', mo_id)

                # Execute handlers
                for data in self.get_data(SyncMedia.Movies):
                    t_movie = self.trakt[(SyncMedia.Movies, data)].get(pk)

                    self.execute_handlers(
                        SyncMode.Pull, SyncMedia.Movies, data,
                        key=mo_id,

                        p_item=p_movie,
                        t_item=t_movie
                    )
            else:
                # Execute handlers for changed data
                for data, action, t_movie in self.iter_changes(SyncMedia.Movies, pk):
                    self.execute_handlers(
                        self.mode, SyncMedia.Movies, data,
                        action=action,
                        key=mo_id,

                        p_item=p_movie,
                        t_item=t_movie
                    )

            # Task checkpoint
            self.checkpoint()

        # Stop progress group
        self.current.progress.group(Movies).stop()

        # Log details
        log_unsupported(log, 'Found %d unsupported movie(s)', self.p_unsupported)