Exemple #1
0
    def demote(self, service):
        # Update existing parts
        for part_num, part in self.parts.items():
            self.parts[part_num].update_attributes(
                identifiers=self.identifiers,
                names=self.names,
                supplemental=self.supplemental,
                parameters=self.parameters)

        # Retrieve part number
        part_num = self.parameters.get('episode_offset')

        if part_num is not None:
            part_num = str(try_convert(part_num, int, 0) + 1)
        else:
            part_num = '1'

        # Create part from current show
        part = ModelRegistry['Part'].from_movie(self, part_num, self)

        if part_num in self.parts:
            self.parts[part_num].add(part, service)
        else:
            self.parts[part_num] = part

        # Clear show
        return self.clear()
    def demote(self, service):
        # Update existing parts
        for part_num, part in self.parts.items():
            self.parts[part_num].update_attributes(
                identifiers=self.identifiers,
                names=self.names,

                supplemental=self.supplemental,
                parameters=self.parameters
            )

        # Retrieve part number
        part_num = self.parameters.get('episode_offset')

        if part_num is not None:
            part_num = str(try_convert(part_num, int, 0) + 1)
        else:
            part_num = '1'

        # Create part from current show
        part = ModelRegistry['Part'].from_movie(self, part_num, self)

        if part_num in self.parts:
            self.parts[part_num].add(part, service)
        else:
            self.parts[part_num] = part

        # Clear show
        return self.clear()
Exemple #3
0
    def _match_show(self, show, identifier):
        # Retrieve "default_season" parameter
        default_season = None

        if 'default_season' in show.parameters:
            default_season = show.parameters['default_season']

            if default_season != 'a':
                # Cast season number to an integer
                default_season = try_convert(default_season, int)

                if default_season is None:
                    log.warn(
                        'Invalid value provided for the "default_season" parameter: %r',
                        show.parameters['default_season']
                    )
                    return None

        # Retrieve season number
        season_num = identifier.season_num

        if season_num is None or default_season is None or default_season == 'a':
            season_num = default_season
        elif season_num > 0:
            season_num = default_season + (season_num - 1)

        # Retrieve episode number
        episode_num = identifier.episode_num

        if 'episode_offset' in show.parameters:
            episode_num += int(show.parameters['episode_offset'])

        # Build episode match
        if season_num != 'a':
            match = EpisodeMatch(
                self._get_identifiers(show),
                season_num=season_num,
                episode_num=episode_num,

                progress=identifier.progress
            )
        else:
            if identifier.absolute_num is None:
                raise AbsoluteNumberRequiredError('Unable to match %r, an absolute number is required' % identifier)

            match = EpisodeMatch(
                self._get_identifiers(show),
                absolute_num=identifier.absolute_num,

                progress=identifier.progress
            )

        if not match.valid:
            return None

        return match
    def parse(cls, collection, node, use_absolute_mapper=True):
        # Retrieve default season
        default_season = node.attrib.get('defaulttvdbseason')

        if default_season is None:
            return

        # Retrieve episode offset (and cast to integer)
        episode_offset = try_convert(node.attrib.get('episodeoffset'), int, 0)

        # Retrieve AniDB identifier
        anidb_id = cls.get_anidb_id(node)

        if anidb_id is None:
            log.warn('Item has an invalid AniDB identifier: %r ', anidb_id)
            return

        # Retrieve TMDb identifier
        media, tmdb_ids = cls._get_tmdb_identifier(node)

        if not media or media != cls.get_collection_media(collection):
            return

        if not cls._validate_identifier(tmdb_ids):
            return

        # Parse items
        for x, tmdb_id in enumerate(tmdb_ids):
            if tmdb_id == 'unknown':
                continue

            # Determine item episode offset
            i_episode_offset = episode_offset

            if len(tmdb_ids) > 1:
                i_episode_offset = (episode_offset or 0) + x

            if i_episode_offset is not None:
                if i_episode_offset != 0:
                    i_episode_offset = str(i_episode_offset)
                else:
                    i_episode_offset = None

            # Construct item
            item = cls.parse_one(
                collection, node, media,
                anidb_id, tmdb_id,
                default_season,
                i_episode_offset,
                use_absolute_mapper=use_absolute_mapper
            )

            if not item:
                continue

            yield item
    def add(self, item, service):
        # Ensure item is different
        if self == item:
            return True

        if self.matches_identifiers(item.identifiers):
            return self.update(item)

        # Demote current movie to a part
        if self.collection.target in self.identifiers and not self.demote(service):
            return False

        # Retrieve part number
        i_part_num = item.parameters.get('episode_offset')

        if i_part_num is not None:
            i_part_num = str(try_convert(i_part_num, int, 0) + 1)
        else:
            i_part_num = '1'

        # Add parts to current movie
        part_numbers = set([
            s.number for s in six.itervalues(item.parts)
        ] + [
            i_part_num
        ])

        error = False

        for part_num in part_numbers:
            # Construct part
            part = ModelRegistry['Part'].from_movie(self, part_num, item)

            if part_num in self.parts:
                # Update existing part
                if not self.parts[part_num].add(part, service):
                    error = True

                continue

            # Store new part
            self.parts[part_num] = part

        return not error
Exemple #6
0
    def add(self, item, service):
        # Ensure item is different
        if self == item:
            return True

        if self.matches_identifiers(item.identifiers):
            return self.update(item)

        # Demote current movie to a part
        if self.collection.target in self.identifiers and not self.demote(
                service):
            return False

        # Retrieve part number
        i_part_num = item.parameters.get('episode_offset')

        if i_part_num is not None:
            i_part_num = str(try_convert(i_part_num, int, 0) + 1)
        else:
            i_part_num = '1'

        # Add parts to current movie
        part_numbers = set([s.number for s in six.itervalues(item.parts)] +
                           [i_part_num])

        error = False

        for part_num in part_numbers:
            # Construct part
            part = ModelRegistry['Part'].from_movie(self, part_num, item)

            if part_num in self.parts:
                # Update existing part
                if not self.parts[part_num].add(part, service):
                    error = True

                continue

            # Store new part
            self.parts[part_num] = part

        return not error
    def _validate_identifier(tmdb_ids):
        if not tmdb_ids:
            log.warn('Item has an invalid TMDb identifier: %r', tmdb_ids)
            return False

        valid = False

        for tmdb_id in tmdb_ids:
            if tmdb_id == 'unknown':
                continue

            if not tmdb_id:
                log.warn('Item has an invalid TMDb identifier: %r', tmdb_id)
                continue

            if try_convert(tmdb_id, int) is None:
                log.warn('Item has an invalid TMDb identifier: %r', tmdb_id)
                return None

            valid = True

        return valid
    def _validate_identifier(imdb_ids):
        if not imdb_ids:
            log.warn('Item has an invalid IMDB identifier: %r', imdb_ids)
            return False

        valid = False

        for imdb_id in imdb_ids:
            if imdb_id == 'unknown':
                continue

            if not imdb_id:
                log.warn('Item has an invalid IMDB identifier: %r', imdb_id)
                continue

            if not imdb_id.startswith('tt') or try_convert(imdb_id[2:], int) is None:
                log.warn('Item has an invalid IMDB identifier: %r', imdb_id)
                continue

            valid = True

        return valid
Exemple #9
0
    def _match_season(self, show, identifier):
        # Try retrieve matching season
        season = show.seasons.get(str(identifier.season_num)) or show.seasons.get('a')

        if not season:
            return None, None

        if season.number == 'a':
            if identifier.absolute_num is None:
                raise AbsoluteNumberRequiredError('Unable to match %r, an absolute number is required' % identifier)

            return season, EpisodeMatch(
                self._get_identifiers(show, season),
                absolute_num=identifier.absolute_num,

                progress=identifier.progress
            )

        # Look for matching season mapping
        for season_mapping in season.mappings:
            if not (season_mapping.start <= identifier.episode_num <= season_mapping.end):
                continue

            return season, EpisodeMatch(
                self._get_identifiers(show, season),
                int(season_mapping.season),
                identifier.episode_num + season_mapping.offset,

                progress=identifier.progress
            )

        # Retrieve "default_season" parameter
        default_season = None

        if 'default_season' in season.parameters:
            default_season = season.parameters['default_season']

            if default_season != 'a':
                # Cast season number to an integer
                default_season = try_convert(default_season, int)

                if default_season is None:
                    log.warn(
                        'Invalid value provided for the "default_season" parameter: %r',
                        season.parameters['default_season']
                    )
                    return season, None

        # Retrieve season number
        season_num = identifier.season_num

        if season.identifiers:
            season_num = 1

        if default_season is not None:
            season_num = default_season

        # Retrieve episode number
        episode_num = identifier.episode_num

        # Apply episode offset
        episode_offset = self._get_parameter('episode_offset', show, season)

        if episode_offset is not None:
            episode_num += int(episode_offset)

        # Build season match
        match = EpisodeMatch(
            self._get_identifiers(show, season),
            season_num=season_num,
            episode_num=episode_num,

            progress=identifier.progress
        )

        if not match.valid:
            return season, None

        return season, match