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()
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
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
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