Esempio n. 1
0
    def finish(self):
        if self.current.kwargs.get('section'):
            # Collection cleaning disabled for individual syncs
            return

        # Increment progress steps
        self.current.progress.group(Movies, 'missing:movies').add(len(self.current.pending['movies'].keys))

        # Iterate over movies
        for pk in list(self.current.pending['movies'].keys):
            # Increment one step
            self.current.progress.group(Movies, 'missing:movies').step()

            # Iterate over data handlers
            triggered = False

            for data in self.get_data(SyncMedia.Movies):
                if data not in [SyncData.Collection]:
                    continue

                # Retrieve movie
                t_movie = self.trakt[(SyncMedia.Movies, data)].get(pk)

                if not t_movie:
                    continue

                log.debug('Found movie missing from plex: %r [data: %r]', pk, SyncData.title(data))

                # Trigger handler
                self.execute_handlers(
                    self.mode, SyncMedia.Movies, data,

                    key=None,

                    guid=Guid.construct(*pk, matched=True),
                    p_item=None,

                    t_item=t_movie
                )

                # Mark triggered
                triggered = True

            # Check if action was triggered
            if not triggered:
                continue

            # Remove movie from `pending` set
            self.current.pending['movies'].keys.remove(pk)

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

        # Report pending movies (no actions triggered)
        self.log_pending(
            log, 'Unable to find %d movie(s) in Plex, list has been saved to: %s',
            self.current.account, 'movies', self.current.pending['movies'].keys
        )
Esempio n. 2
0
    def finish(self):
        if self.current.kwargs.get('section'):
            # Collection cleaning disabled for individual syncs
            return

        # Increment progress steps
        self.current.progress.group(Movies, 'missing:movies').add(len(self.current.pending['movies'].keys))

        # Iterate over movies
        for pk in list(self.current.pending['movies'].keys):
            # Increment one step
            self.current.progress.group(Movies, 'missing:movies').step()

            # Iterate over data handlers
            triggered = False

            for data in self.get_data(SyncMedia.Movies):
                if data not in [SyncData.Collection]:
                    continue

                # Retrieve movie
                t_movie = self.trakt[(SyncMedia.Movies, data)].get(pk)

                if not t_movie:
                    continue

                log.debug('Found movie missing from plex: %r [data: %r]', pk, SyncData.title(data))

                # Trigger handler
                self.execute_handlers(
                    self.mode, SyncMedia.Movies, data,

                    key=None,

                    guid=Guid.construct(*pk, matched=True),
                    p_item=None,

                    t_item=t_movie
                )

                # Mark triggered
                triggered = True

            # Check if action was triggered
            if not triggered:
                continue

            # Remove movie from `pending` set
            self.current.pending['movies'].keys.remove(pk)

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

        # Report pending movies (no actions triggered)
        self.log_pending(
            log, 'Unable to find %d movie(s) in Plex, list has been saved to: %s',
            self.current.account, 'movies', self.current.pending['movies'].keys
        )
Esempio n. 3
0
    def process_missing_shows(self):
        if self.current.kwargs.get('section'):
            # Collection cleaning disabled for individual syncs
            return

        # Increment progress steps
        self.current.progress.group(Shows, 'missing:shows').add(len(self.p_shows_pending))

        # Iterate over trakt shows (that aren't in plex)
        for pk in list(self.p_shows_pending):
            # Increment one step
            self.current.progress.group(Shows, 'missing:shows').step()

            # Iterate over data handlers
            triggered = False

            for data in self.get_data(SyncMedia.Shows):
                if data not in [SyncData.Collection]:
                    continue

                # Retrieve show
                t_show = self.trakt[(SyncMedia.Shows, data)].get(pk)

                if not t_show:
                    continue

                log.debug('Found show missing from plex: %r [data: %r]', pk, SyncData.title(data))

                # Trigger handler
                self.execute_handlers(
                    SyncMedia.Shows, data,

                    key=None,

                    guid=Guid.construct(*pk),
                    p_item=None,

                    t_item=t_show
                )

                # Mark triggered
                triggered = True

            # Check if action was triggered
            if not triggered:
                continue

            # Remove movie from `pending` set
            self.p_shows_pending.remove(pk)

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

        self.log_pending('Unable to find %d show(s) in Plex\n%s', self.p_shows_pending)
Esempio n. 4
0
    def process_missing_shows(self):
        if self.current.kwargs.get('section'):
            # Collection cleaning disabled for individual syncs
            return

        # Increment progress steps
        self.current.progress.group(Shows, 'missing:shows').add(
            len(self.p_shows_pending))

        # Iterate over trakt shows (that aren't in plex)
        for pk in list(self.p_shows_pending):
            # Increment one step
            self.current.progress.group(Shows, 'missing:shows').step()

            # Iterate over data handlers
            triggered = False

            for data in self.get_data(SyncMedia.Shows):
                if data not in [SyncData.Collection]:
                    continue

                # Retrieve show
                t_show = self.trakt[(SyncMedia.Shows, data)].get(pk)

                if not t_show:
                    continue

                log.debug('Found show missing from plex: %r [data: %r]', pk,
                          SyncData.title(data))

                # Trigger handler
                self.execute_handlers(SyncMedia.Shows,
                                      data,
                                      key=None,
                                      guid=Guid.construct(*pk),
                                      p_item=None,
                                      t_item=t_show)

                # Mark triggered
                triggered = True

            # Check if action was triggered
            if not triggered:
                continue

            # Remove movie from `pending` set
            self.p_shows_pending.remove(pk)

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

        self.log_pending('Unable to find %d show(s) in Plex\n%s',
                         self.p_shows_pending)
Esempio n. 5
0
    def parse(cls, guid, episode=None):
        media = (
            GuidMatch.Media.Episode
            if episode else GuidMatch.Media.Movie
        )

        # Ensure guid is valid
        if not guid or not guid.valid:
            return GuidMatch(
                media, guid,
                invalid=True
            )

        # Process guid episode identifier overrides
        if episode and len(episode) == 2:
            season_num, episode_num = episode

            if guid.season is not None:
                episode = guid.season, episode_num

        # Process natively supported guid services
        if guid.service in GUID_SERVICES:
            episodes = None

            if episode and len(episode) == 2:
                episodes = [episode]

            return GuidMatch(
                media, guid,
                episodes=episodes,
                supported=True,
                found=True
            )

        # Process episode
        if episode:
            return cls.parse_episode(guid, episode)

        # Process shows + movies
        supported, (service, key) = ModuleManager['mapper'].id(
            guid.service, guid.id,
            resolve_mappings=False
        )

        # Validate match
        if not supported:
            return GuidMatch(media, guid)

        if not service or not key:
            return GuidMatch(media, guid, supported=True)

        # Validate identifier
        if type(key) is list:
            log.info('[%s/%s] - List keys are not supported', guid.service, guid.id)
            return GuidMatch(media, guid, supported=True)

        if type(key) not in [int, str]:
            log.info('[%s/%s] - Unsupported key: %r', guid.service, guid.id, key)
            return GuidMatch(media, guid, supported=True)

        log.debug('[%s/%s] - Mapped to: %s/%s', guid.service, guid.id, service, key)

        # Return movie/show match
        return GuidMatch(
            media, Guid.construct(service, key, matched=True),
            supported=True,
            found=True
        )
Esempio n. 6
0
    def finish_episodes(self):
        if self.current.kwargs.get('section'):
            # Collection cleaning disabled for individual syncs
            return

        # Increment progress steps
        self.current.progress.group(Shows, 'missing:episodes').add(
            len(self.current.pending['episodes'].keys))

        # Iterate over trakt episodes (that aren't in plex)
        for pk, episodes in [
            (p, list(e))
                for (p, e) in self.current.pending['episodes'].keys.items()
        ]:
            # Increment one step
            self.current.progress.group(Shows, 'missing:episodes').step()

            # Iterate over trakt episodes (that aren't in plex)
            for identifier in episodes:
                # Iterate over data handlers
                season_num, episode_num = identifier
                triggered = False

                for data in self.get_data(SyncMedia.Episodes):
                    if data not in [SyncData.Collection]:
                        continue

                    # Retrieve episode
                    t_show, t_season, t_episode = self.t_objects(
                        self.trakt[(SyncMedia.Episodes, data)], pk, season_num,
                        episode_num)

                    if not t_episode:
                        continue

                    log.debug(
                        'Found episode missing from plex: %r - %r [data: %r]',
                        pk, identifier, SyncData.title(data))

                    # Trigger handler
                    self.execute_handlers(self.mode,
                                          SyncMedia.Episodes,
                                          data,
                                          key=None,
                                          identifier=identifier,
                                          guid=Guid.construct(*pk,
                                                              matched=True),
                                          p_show=None,
                                          p_item=None,
                                          t_show=t_show,
                                          t_item=t_episode)

                    # Mark triggered
                    triggered = True

                # Check if action was triggered
                if not triggered:
                    continue

                # Remove movie from `pending` set
                self.current.pending['episodes'].keys[pk].remove(identifier)

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

        self.log_pending(
            log,
            'Unable to find %d episode(s) in Plex, list has been saved to: %s',
            self.current.account, 'episodes',
            self.current.pending['episodes'].keys)
Esempio n. 7
0
    def process_missing_episodes(self):
        if self.current.kwargs.get('section'):
            # Collection cleaning disabled for individual syncs
            return

        # Increment progress steps
        self.current.progress.group(Shows, 'missing:episodes').add(len(self.p_episodes_pending))

        # Iterate over trakt episodes (that aren't in plex)
        for pk, episodes in [(p, list(e)) for (p, e) in self.p_episodes_pending.items()]:
            # Increment one step
            self.current.progress.group(Shows, 'missing:episodes').step()

            # Iterate over trakt episodes (that aren't in plex)
            for identifier in episodes:
                # Iterate over data handlers
                season_num, episode_num = identifier
                triggered = False

                for data in self.get_data(SyncMedia.Episodes):
                    if data not in [SyncData.Collection]:
                        continue

                    # Retrieve episode
                    t_show, t_season, t_episode = self.t_objects(
                        self.trakt[(SyncMedia.Episodes, data)], pk,
                        season_num, episode_num
                    )

                    if not t_episode:
                        continue

                    log.debug('Found episode missing from plex: %r - %r [data: %r]', pk, identifier, SyncData.title(data))

                    # Trigger handler
                    self.execute_handlers(
                        SyncMedia.Episodes, data,
                        key=None,
                        identifier=identifier,
                        guid=Guid.construct(*pk),

                        p_show=None,
                        p_item=None,

                        t_show=t_show,
                        t_item=t_episode
                    )

                    # Mark triggered
                    triggered = True

                # Check if action was triggered
                if not triggered:
                    continue

                # Remove movie from `pending` set
                self.p_episodes_pending[pk].remove(identifier)

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

        self.log_pending('Unable to find %d episode(s) in Plex\n%s', self.p_episodes_pending)
Esempio n. 8
0
    def parse(cls, guid, episode=None):
        media = (GuidMatch.Media.Episode if episode else GuidMatch.Media.Movie)

        # Ensure guid is valid
        if not guid or not guid.valid:
            return GuidMatch(media, guid, invalid=True)

        # Process guid episode identifier overrides
        if episode and len(episode) == 2:
            season_num, episode_num = episode

            if guid.season is not None:
                episode = guid.season, episode_num

        # Process natively supported guid services
        if guid.service in GUID_SERVICES:
            episodes = None

            if episode and len(episode) == 2:
                episodes = [episode]

            return GuidMatch(media,
                             guid,
                             episodes=episodes,
                             supported=True,
                             found=True)

        # Process episode
        if episode:
            return cls.parse_episode(guid, episode)

        # Process shows + movies
        supported, (service,
                    key) = ModuleManager['mapper'].id(guid.service,
                                                      guid.id,
                                                      resolve_mappings=False)

        # Validate match
        if not supported:
            return GuidMatch(media, guid)

        if not service or not key:
            return GuidMatch(media, guid, supported=True)

        # Validate identifier
        if type(key) is list:
            log.info('[%s/%s] - List keys are not supported', guid.service,
                     guid.id)
            return GuidMatch(media, guid, supported=True)

        if type(key) not in [int, str]:
            log.info('[%s/%s] - Unsupported key: %r', guid.service, guid.id,
                     key)
            return GuidMatch(media, guid, supported=True)

        log.debug('[%s/%s] - Mapped to: %s/%s', guid.service, guid.id, service,
                  key)

        # Return movie/show match
        return GuidMatch(media,
                         Guid.construct(service, key, matched=True),
                         supported=True,
                         found=True)
Esempio n. 9
0
class GuidParser(object):
    @classmethod
    def parse(cls, guid, episode=None):
        media = (GuidMatch.Media.Episode if episode else GuidMatch.Media.Movie)

        # Ensure guid is valid
        if not guid or not guid.valid:
            return GuidMatch(media, guid, invalid=True)

        # Process guid episode identifier overrides
        if episode and len(episode) == 2:
            season_num, episode_num = episode

            if guid.season is not None:
                episode = guid.season, episode_num

        # Process natively supported guid services
        if guid.service in GUID_SERVICES:
            episodes = None

            if episode and len(episode) == 2:
                episodes = [episode]

            return GuidMatch(media,
                             guid,
                             episodes=episodes,
                             supported=True,
                             found=True)

        # Process episode
        if episode:
            return cls.parse_episode(guid, episode)

        # Process shows + movies
        supported, (service,
                    key) = ModuleManager['mapper'].id(guid.service,
                                                      guid.id,
                                                      resolve_mappings=False)

        # Validate match
        if not supported:
            return GuidMatch(media, guid)

        if not service or not key:
            return GuidMatch(media, guid, supported=True)

        # Validate identifier
        if type(key) is list:
            log.info('[%s/%s] - List keys are not supported', guid.service,
                     guid.id)
            return GuidMatch(media, guid, supported=True)

        if type(key) not in [int, str]:
            log.info('[%s/%s] - Unsupported key: %r', guid.service, guid.id,
                     key)
            return GuidMatch(media, guid, supported=True)

        log.debug('[%s/%s] - Mapped to: %s/%s', guid.service, guid.id, service,
                  key)

        # Return movie/show match
        return GuidMatch(media,
                         Guid.construct(service, key, matched=True),
                         supported=True,
                         found=True)

    @classmethod
    def parse_episode(cls, guid, (season_num, episode_num)):
        episodes = [(season_num, episode_num)]

        # Map episode to a supported service (via OEM)
        supported, match = ModuleManager['mapper'].map_episode(
            guid, season_num, episode_num, resolve_mappings=False)

        # Validate match
        if not supported:
            return GuidMatch(GuidMatch.Media.Episode, guid, episodes=episodes)

        if not match or not match.identifiers:
            log.debug('Unable to find mapping for %r S%02dE%02d', guid,
                      season_num, episode_num)
            return GuidMatch(GuidMatch.Media.Episode,
                             guid,
                             episodes=episodes,
                             supported=True)

        # Retrieve identifier
        service = match.identifiers.keys()[0]
        key = match.identifiers[service]

        if type(key) is list:
            log.info('[%s/%s] - List keys are not supported', guid.service,
                     guid.id)
            return GuidMatch(GuidMatch.Media.Episode,
                             guid,
                             episodes=episodes,
                             supported=True)

        # Cast `key` numbers to integers
        key = try_convert(key, int, key)

        # Validate show identifier
        if type(key) not in [int, str]:
            log.info('[%s/%s] - Unsupported key: %r', guid.service, guid.id,
                     key)
            return GuidMatch(GuidMatch.Media.Episode,
                             guid,
                             episodes=episodes,
                             supported=True)

        # Process episode matches
        if isinstance(match, EpisodeMatch):
            # Ensure match doesn't include an absolute number
            if match.absolute_num is not None:
                log.info(
                    '[%s/%s] - Episode mappings with absolute numbers are not supported',
                    guid.service, guid.id)
                return GuidMatch(GuidMatch.Media.Episode,
                                 guid,
                                 episodes=episodes,
                                 supported=True)

            # Update `episodes` list
            if match.mappings:
                # Use match mappings
                episodes = []

                for mapping in match.mappings:
                    log.debug('[%s/%s] (S%02dE%02d) - Mapped to: %r',
                              guid.service, guid.id, season_num, episode_num,
                              mapping)
                    episodes.append((int(mapping.season), int(mapping.number)))
            else:
                # Use match identifier
                log.debug('[%s/%s] (S%02dE%02d) - Mapped to: %r', guid.service,
                          guid.id, season_num, episode_num, match)
                episodes = [(int(match.season_num), int(match.episode_num))]

            # Return episode match
            return GuidMatch(GuidMatch.Media.Episode,
                             Guid.construct(service, key, matched=True),
                             episodes=episodes,
                             supported=True,
                             found=True)

        # Process movie matches
        if isinstance(match, MovieMatch):
            log.debug('[%s/%s] (S%02dE%02d) - Mapped to: %r', guid.service,
                      guid.id, season_num, episode_num, match)

            # Return movie match
            return GuidMatch(GuidMatch.Media.Movie,
                             Guid.construct(service, key, matched=True),
                             supported=True,
                             found=True)

        # Unknown value for `match` returned
        log.warn('Unknown match returned: %r', match)
        return GuidMatch(GuidMatch.Media.Episode,
                         guid,
                         episodes=episodes,
                         supported=True)