def update_show_indexer_metadata(self, show_obj): if self.show_metadata and show_obj and self._has_show_metadata( show_obj): log.debug( u'Metadata provider {name} updating series indexer info metadata file for {series}', { u'name': self.name, u'series': show_obj.name }) nfo_file_path = self.get_show_file_path(show_obj) try: with io.open(nfo_file_path, u'rb') as xmlFileObj: showXML = etree.ElementTree(file=xmlFileObj) indexerid = showXML.find(u'id') root = showXML.getroot() if indexerid is not None: indexerid.text = str(show_obj.indexerid) else: etree.SubElement(root, u'id').text = str(show_obj.indexerid) # Make it purdy helpers.indent_xml(root) showXML.write(nfo_file_path, encoding=u'UTF-8') helpers.chmod_as_parent(nfo_file_path) return True except etree.ParseError as error: log.warning( u'Received an invalid XML for {series}, try again later. Error: {error}', { u'series': show_obj.name, u'error': error }) except IOError as error: if error.errno == errno.EACCES: log.warning( u'Unable to write metadata file to {location} - verify that the path is writeable', {u'location': nfo_file_path}) else: log.error( u'Unable to write metadata file to {location}. Error: {error!r}', { u'location': nfo_file_path, u'error': error })
def _ep_data(self, ep_obj): """ Creates an elementTree XML structure for a MediaBrowser style episode.xml and returns the resulting data object. show_obj: a Series instance to create the NFO for """ eps_to_write = [ep_obj] + ep_obj.related_episodes persons_dict = {u'Director': [], u'GuestStar': [], u'Writer': []} my_show = self._get_show_data(ep_obj.series) if not my_show: return None root_node = etree.Element(u'Item') # write an MediaBrowser XML containing info for all matching episodes for ep_to_write in eps_to_write: try: my_ep = my_show[ep_to_write.season][ep_to_write.episode] except (IndexerEpisodeNotFound, IndexerSeasonNotFound): log.info( u'Unable to find episode {number} on {indexer}... has it been removed? Should I delete from db?', { u'number': episode_num(ep_to_write.season, ep_to_write.episode), u'indexer': indexerApi(ep_obj.series.indexer).name }) return None if ep_to_write == ep_obj: # root (or single) episode # default to today's date for specials if firstaired is not set if ep_to_write.season == 0 and not getattr( my_ep, u'firstaired', None): my_ep[u'firstaired'] = str(datetime.date.fromordinal(1)) if not (getattr(my_ep, u'episodename', None) and getattr(my_ep, u'firstaired', None)): return None episode = root_node if ep_to_write.name: episode_name = etree.SubElement(episode, u'EpisodeName') episode_name.text = ep_to_write.name episode_number = etree.SubElement(episode, u'EpisodeNumber') episode_number.text = str(ep_obj.episode) if ep_obj.related_episodes: episode_number_end = etree.SubElement( episode, u'EpisodeNumberEnd') episode_number_end.text = str(ep_to_write.episode) season_number = etree.SubElement(episode, u'SeasonNumber') season_number.text = str(ep_to_write.season) if not ep_obj.related_episodes and getattr( my_ep, u'absolute_number', None): absolute_number = etree.SubElement(episode, u'absolute_number') absolute_number.text = str(my_ep[u'absolute_number']) if ep_to_write.airdate != datetime.date.fromordinal(1): first_aired = etree.SubElement(episode, u'FirstAired') first_aired.text = str(ep_to_write.airdate) metadata_type = etree.SubElement(episode, u'Type') metadata_type.text = u'Episode' if ep_to_write.description: overview = etree.SubElement(episode, u'Overview') overview.text = ep_to_write.description if not ep_obj.related_episodes: if getattr(my_ep, u'rating', None): rating = etree.SubElement(episode, u'Rating') rating.text = my_ep[u'rating'] if getattr(my_show, u'imdb_id', None): IMDB_ID = etree.SubElement(episode, u'IMDB_ID') IMDB_ID.text = my_show[u'imdb_id'] IMDB = etree.SubElement(episode, u'IMDB') IMDB.text = my_show[u'imdb_id'] IMDbId = etree.SubElement(episode, u'IMDbId') IMDbId.text = my_show[u'imdb_id'] indexer_id = etree.SubElement(episode, u'id') indexer_id.text = str(ep_to_write.indexerid) persons = etree.SubElement(episode, u'Persons') if getattr(my_show, u'_actors', None): for actor in my_show[u'_actors']: if not (u'name' in actor and actor[u'name'].strip()): continue cur_actor = etree.SubElement(persons, u'Person') cur_actor_name = etree.SubElement(cur_actor, u'Name') cur_actor_name.text = actor[u'name'].strip() cur_actor_type = etree.SubElement(cur_actor, u'Type') cur_actor_type.text = u'Actor' if u'role' in actor and actor[u'role'].strip(): cur_actor_role = etree.SubElement( cur_actor, u'Role') cur_actor_role.text = actor[u'role'].strip() language = etree.SubElement(episode, u'Language') try: language.text = my_ep[u'language'] except Exception: language.text = app.INDEXER_DEFAULT_LANGUAGE # tvrage api doesn't provide language so we must assume a value here thumb = etree.SubElement(episode, u'filename') # TODO: See what this is needed for.. if its still needed # just write this to the NFO regardless of whether it actually exists or not # note: renaming files after nfo generation will break this, tough luck thumb_text = self.get_episode_thumb_path(ep_obj) if thumb_text: thumb.text = thumb_text else: # append data from (if any) related episodes episode_number_end.text = str(ep_to_write.episode) if ep_to_write.name: if not episode_name.text: episode_name.text = ep_to_write.name else: episode_name.text = u', '.join( [episode_name.text, ep_to_write.name]) if ep_to_write.description: if not overview.text: overview.text = ep_to_write.description else: overview.text = u'\r'.join( [overview.text, ep_to_write.description]) # collect all directors, guest stars and writers if getattr(my_ep, u'director', None): persons_dict[u'Director'] += [ x.strip() for x in my_ep[u'director'].split(u'|') if x.strip() ] if getattr(my_ep, u'gueststars', None): persons_dict[u'GuestStar'] += [ x.strip() for x in my_ep[u'gueststars'].split(u'|') if x.strip() ] if getattr(my_ep, u'writer', None): persons_dict[u'Writer'] += [ x.strip() for x in my_ep[u'writer'].split(u'|') if x.strip() ] # fill in Persons section with collected directors, guest starts and writers for person_type, names in iteritems(persons_dict): # remove doubles names = list(set(names)) for cur_name in names: person = etree.SubElement(persons, u'Person') cur_person_name = etree.SubElement(person, u'Name') cur_person_name.text = cur_name cur_person_type = etree.SubElement(person, u'Type') cur_person_type.text = person_type # Make it purdy helpers.indent_xml(root_node) data = etree.ElementTree(root_node) return data
def _show_data(self, show_obj): """ Creates an elementTree XML structure for a MediaBrowser-style series.xml returns the resulting data object. show_obj: a Series instance to create the NFO for """ my_show = self._get_show_data(show_obj) # If by any reason it couldn't get the shows indexer data let's not go throught the rest of this method # as that pretty useless. if not my_show: return False tv_node = etree.Element(u'Series') if getattr(my_show, u'id', None): indexerid = etree.SubElement(tv_node, u'id') indexerid.text = str(my_show[u'id']) if getattr(my_show, u'seriesname', None): series_name = etree.SubElement(tv_node, u'SeriesName') series_name.text = my_show[u'seriesname'] if getattr(my_show, u'status', None): status = etree.SubElement(tv_node, u'Status') status.text = my_show[u'status'] if getattr(my_show, u'network', None): network = etree.SubElement(tv_node, u'Network') network.text = my_show[u'network'] if getattr(my_show, u'airs_time', None): airs_time = etree.SubElement(tv_node, u'Airs_Time') airs_time.text = my_show[u'airs_time'] if getattr(my_show, u'airs_dayofweek', None): airs_day_of_week = etree.SubElement(tv_node, u'Airs_DayOfWeek') airs_day_of_week.text = my_show[u'airs_dayofweek'] first_aired = etree.SubElement(tv_node, u'FirstAired') if getattr(my_show, u'firstaired', None): first_aired.text = my_show[u'firstaired'] if getattr(my_show, u'contentrating', None): content_rating = etree.SubElement(tv_node, u'ContentRating') content_rating.text = my_show[u'contentrating'] mpaa = etree.SubElement(tv_node, u'MPAARating') mpaa.text = my_show[u'contentrating'] certification = etree.SubElement(tv_node, u'certification') certification.text = my_show[u'contentrating'] metadata_type = etree.SubElement(tv_node, u'Type') metadata_type.text = u'Series' if getattr(my_show, u'overview', None): overview = etree.SubElement(tv_node, u'Overview') overview.text = my_show[u'overview'] if getattr(my_show, u'firstaired', None): premiere_date = etree.SubElement(tv_node, u'PremiereDate') premiere_date.text = my_show[u'firstaired'] if getattr(my_show, u'rating', None): rating = etree.SubElement(tv_node, u'Rating') rating.text = my_show[u'rating'] if getattr(my_show, u'firstaired', None): try: year_text = str( datetime.datetime.strptime(my_show[u'firstaired'], dateFormat).year) if year_text: production_year = etree.SubElement(tv_node, u'ProductionYear') production_year.text = year_text except Exception: pass if getattr(my_show, u'runtime', None): running_time = etree.SubElement(tv_node, u'RunningTime') running_time.text = my_show[u'runtime'] runtime = etree.SubElement(tv_node, u'Runtime') runtime.text = my_show[u'runtime'] if getattr(my_show, u'imdb_id', None): imdb_id = etree.SubElement(tv_node, u'IMDB_ID') imdb_id.text = my_show[u'imdb_id'] imdb_id = etree.SubElement(tv_node, u'IMDB') imdb_id.text = my_show[u'imdb_id'] imdb_id = etree.SubElement(tv_node, u'IMDbId') imdb_id.text = my_show[u'imdb_id'] if getattr(my_show, u'zap2it_id', None): zap2it_id = etree.SubElement(tv_node, u'Zap2ItId') zap2it_id.text = my_show[u'zap2it_id'] if getattr(my_show, u'genre', None) and isinstance( my_show[u'genre'], string_types): genres = etree.SubElement(tv_node, u'Genres') for genre in my_show[u'genre'].split(u'|'): if genre.strip(): cur_genre = etree.SubElement(genres, u'Genre') cur_genre.text = genre.strip() genre = etree.SubElement(tv_node, u'Genre') genre.text = u'|'.join([ x.strip() for x in my_show[u'genre'].split(u'|') if x.strip() ]) if getattr(my_show, u'network', None): studios = etree.SubElement(tv_node, u'Studios') studio = etree.SubElement(studios, u'Studio') studio.text = my_show[u'network'] if getattr(my_show, u'_actors', None): persons = etree.SubElement(tv_node, u'Persons') for actor in my_show[u'_actors']: if not (u'name' in actor and actor[u'name'].strip()): continue cur_actor = etree.SubElement(persons, u'Person') cur_actor_name = etree.SubElement(cur_actor, u'Name') cur_actor_name.text = actor[u'name'].strip() cur_actor_type = etree.SubElement(cur_actor, u'Type') cur_actor_type.text = u'Actor' if u'role' in actor and actor[u'role'].strip(): cur_actor_role = etree.SubElement(cur_actor, u'Role') cur_actor_role.text = actor[u'role'].strip() helpers.indent_xml(tv_node) data = etree.ElementTree(tv_node) return data
def _ep_data(self, ep_obj): """ Creates an elementTree XML structure for a WDTV style episode.xml and returns the resulting data object. ep_obj: a Series instance to create the NFO for """ eps_to_write = [ep_obj] + ep_obj.related_episodes my_show = self._get_show_data(ep_obj.series) if not my_show: return None root_node = etree.Element('details') # write an WDTV XML containing info for all matching episodes for ep_to_write in eps_to_write: try: my_ep = my_show[ep_to_write.season][ep_to_write.episode] except (IndexerEpisodeNotFound, IndexerSeasonNotFound): log.info( 'Unable to find episode {number} on {indexer}... has it been removed? Should I delete from db?', { 'number': ep_num(ep_to_write.season, ep_to_write.episode), 'indexer': indexerApi(ep_obj.series.indexer).name, }) return None if ep_obj.season == 0 and not getattr(my_ep, 'firstaired', None): my_ep['firstaired'] = str(datetime.date.fromordinal(1)) if not (getattr(my_ep, 'episodename', None) and getattr(my_ep, 'firstaired', None)): return None if len(eps_to_write) > 1: episode = etree.SubElement(root_node, 'details') else: episode = root_node # TODO: get right EpisodeID episode_id = etree.SubElement(episode, 'id') episode_id.text = str(ep_to_write.indexerid) title = etree.SubElement(episode, 'title') title.text = ep_obj.pretty_name() if getattr(my_show, 'seriesname', None): series_name = etree.SubElement(episode, 'series_name') series_name.text = my_show['seriesname'] if ep_to_write.name: episode_name = etree.SubElement(episode, 'episode_name') episode_name.text = ep_to_write.name season_number = etree.SubElement(episode, 'season_number') season_number.text = str(ep_to_write.season) episode_num = etree.SubElement(episode, 'episode_number') episode_num.text = str(ep_to_write.episode) first_aired = etree.SubElement(episode, 'firstaired') if ep_to_write.airdate != datetime.date.fromordinal(1): first_aired.text = str(ep_to_write.airdate) if getattr(my_show, 'firstaired', None): try: year_text = str( datetime.datetime.strptime(my_show['firstaired'], dateFormat).year) if year_text: year = etree.SubElement(episode, 'year') year.text = year_text except Exception: pass if ep_to_write.season != 0 and getattr(my_show, 'runtime', None): runtime = etree.SubElement(episode, 'runtime') runtime.text = str(my_show['runtime']) if getattr(my_show, 'genre', None): genre = etree.SubElement(episode, 'genre') genre.text = ' / '.join([ x.strip() for x in my_show['genre'].split('|') if x.strip() ]) if getattr(my_ep, 'director', None): director = etree.SubElement(episode, 'director') director.text = my_ep['director'] if getattr(my_show, '_actors', None): for actor in my_show['_actors']: if not ('name' in actor and actor['name'].strip()): continue cur_actor = etree.SubElement(episode, 'actor') cur_actor_name = etree.SubElement(cur_actor, 'name') cur_actor_name.text = actor['name'] if 'role' in actor and actor['role'].strip(): cur_actor_role = etree.SubElement(cur_actor, 'role') cur_actor_role.text = actor['role'].strip() if ep_to_write.description: overview = etree.SubElement(episode, 'overview') overview.text = ep_to_write.description # Make it purdy helpers.indent_xml(root_node) data = etree.ElementTree(root_node) return data
def _ep_data(self, ep_obj): """ Creates an elementTree XML structure for a MediaBrowser style episode.xml and returns the resulting data object. show_obj: a Series instance to create the NFO for """ eps_to_write = [ep_obj] + ep_obj.related_episodes persons_dict = { u'Director': [], u'GuestStar': [], u'Writer': [] } my_show = self._get_show_data(ep_obj.series) if not my_show: return None root_node = etree.Element(u'Item') # write an MediaBrowser XML containing info for all matching episodes for ep_to_write in eps_to_write: try: my_ep = my_show[ep_to_write.season][ep_to_write.episode] except (IndexerEpisodeNotFound, IndexerSeasonNotFound): log.info( u'Unable to find episode {number} on {indexer}... has it been removed? Should I delete from db?', { u'number': episode_num(ep_to_write.season, ep_to_write.episode), u'indexer': indexerApi(ep_obj.series.indexer).name } ) return None if ep_to_write == ep_obj: # root (or single) episode # default to today's date for specials if firstaired is not set if ep_to_write.season == 0 and not getattr(my_ep, u'firstaired', None): my_ep[u'firstaired'] = str(datetime.date.fromordinal(1)) if not (getattr(my_ep, u'episodename', None) and getattr(my_ep, u'firstaired', None)): return None episode = root_node if ep_to_write.name: episode_name = etree.SubElement(episode, u'EpisodeName') episode_name.text = ep_to_write.name episode_number = etree.SubElement(episode, u'EpisodeNumber') episode_number.text = str(ep_obj.episode) if ep_obj.related_episodes: episode_number_end = etree.SubElement(episode, u'EpisodeNumberEnd') episode_number_end.text = str(ep_to_write.episode) season_number = etree.SubElement(episode, u'SeasonNumber') season_number.text = str(ep_to_write.season) if not ep_obj.related_episodes and getattr(my_ep, u'absolute_number', None): absolute_number = etree.SubElement(episode, u'absolute_number') absolute_number.text = str(my_ep[u'absolute_number']) if ep_to_write.airdate != datetime.date.fromordinal(1): first_aired = etree.SubElement(episode, u'FirstAired') first_aired.text = str(ep_to_write.airdate) metadata_type = etree.SubElement(episode, u'Type') metadata_type.text = u'Episode' if ep_to_write.description: overview = etree.SubElement(episode, u'Overview') overview.text = ep_to_write.description if not ep_obj.related_episodes: if getattr(my_ep, u'rating', None): rating = etree.SubElement(episode, u'Rating') rating.text = str(my_ep[u'rating']) if getattr(my_show, u'imdb_id', None): IMDB_ID = etree.SubElement(episode, u'IMDB_ID') IMDB_ID.text = my_show[u'imdb_id'] IMDB = etree.SubElement(episode, u'IMDB') IMDB.text = my_show[u'imdb_id'] IMDbId = etree.SubElement(episode, u'IMDbId') IMDbId.text = my_show[u'imdb_id'] indexer_id = etree.SubElement(episode, u'id') indexer_id.text = str(ep_to_write.indexerid) persons = etree.SubElement(episode, u'Persons') if getattr(my_show, u'_actors', None): for actor in my_show[u'_actors']: if not (u'name' in actor and actor[u'name'].strip()): continue cur_actor = etree.SubElement(persons, u'Person') cur_actor_name = etree.SubElement(cur_actor, u'Name') cur_actor_name.text = actor[u'name'].strip() cur_actor_type = etree.SubElement(cur_actor, u'Type') cur_actor_type.text = u'Actor' if u'role' in actor and actor[u'role'].strip(): cur_actor_role = etree.SubElement(cur_actor, u'Role') cur_actor_role.text = actor[u'role'].strip() language = etree.SubElement(episode, u'Language') try: language.text = my_ep[u'language'] except Exception: language.text = app.INDEXER_DEFAULT_LANGUAGE # tvrage api doesn't provide language so we must assume a value here thumb = etree.SubElement(episode, u'filename') # TODO: See what this is needed for.. if its still needed # just write this to the NFO regardless of whether it actually exists or not # note: renaming files after nfo generation will break this, tough luck thumb_text = self.get_episode_thumb_path(ep_obj) if thumb_text: thumb.text = thumb_text else: # append data from (if any) related episodes episode_number_end.text = str(ep_to_write.episode) if ep_to_write.name: if not episode_name.text: episode_name.text = ep_to_write.name else: episode_name.text = u', '.join([episode_name.text, ep_to_write.name]) if ep_to_write.description: if not overview.text: overview.text = ep_to_write.description else: overview.text = u'\r'.join([overview.text, ep_to_write.description]) # collect all directors, guest stars and writers if getattr(my_ep, u'director', None): persons_dict[u'Director'] += [x.strip() for x in my_ep[u'director'].split(u'|') if x.strip()] if getattr(my_ep, u'gueststars', None): persons_dict[u'GuestStar'] += [x.strip() for x in my_ep[u'gueststars'].split(u'|') if x.strip()] if getattr(my_ep, u'writer', None): persons_dict[u'Writer'] += [x.strip() for x in my_ep[u'writer'].split(u'|') if x.strip()] # fill in Persons section with collected directors, guest starts and writers for person_type, names in iteritems(persons_dict): # remove doubles names = list(set(names)) for cur_name in names: person = etree.SubElement(persons, u'Person') cur_person_name = etree.SubElement(person, u'Name') cur_person_name.text = cur_name cur_person_type = etree.SubElement(person, u'Type') cur_person_type.text = person_type # Make it purdy helpers.indent_xml(root_node) data = etree.ElementTree(root_node) return data
def _show_data(self, show_obj): """ Creates an elementTree XML structure for an KODI-style tvshow.nfo and returns the resulting data object. show_obj: a Series instance to create the NFO for """ my_show = self._get_show_data(show_obj) # If by any reason it couldn't get the shows indexer data let's not go throught the rest of this method # as that pretty useless. if not my_show: return False tv_node = etree.Element('tvshow') title = etree.SubElement(tv_node, 'title') title.text = my_show['seriesname'] if getattr(my_show, 'rating', None): rating = etree.SubElement(tv_node, 'rating') rating.text = my_show['rating'] if getattr(my_show, 'firstaired', None): try: year_text = str( datetime.datetime.strptime(my_show['firstaired'], dateFormat).year) if year_text: year = etree.SubElement(tv_node, 'year') year.text = year_text except Exception: pass if getattr(my_show, 'overview', None): plot = etree.SubElement(tv_node, 'plot') plot.text = my_show['overview'] if getattr(my_show, 'id', None): episode_guide = etree.SubElement(tv_node, 'episodeguide') episode_guide_url = etree.SubElement(episode_guide, 'url', cache='auth.json', post='yes') episode_guide_url.text = '{url}/login?{{"apikey":"{apikey}","id":{id}}}' \ '|Content-Type=application/json'.format(url=API_BASE_TVDB, apikey=TVDB_API_KEY, id=my_show['id']) if getattr(my_show, 'contentrating', None): mpaa = etree.SubElement(tv_node, 'mpaa') mpaa.text = my_show['contentrating'] if getattr(my_show, 'id', None): indexer_id = etree.SubElement(tv_node, 'id') indexer_id.text = str(my_show['id']) if getattr(my_show, 'genre', None) and isinstance( my_show['genre'], string_types): for genre in self._split_info(my_show['genre']): cur_genre = etree.SubElement(tv_node, 'genre') cur_genre.text = genre if 'country_codes' in show_obj.imdb_info: for country in self._split_info( show_obj.imdb_info['country_codes']): try: cur_country_name = Country(country.upper()).name.title() except Exception: continue cur_country = etree.SubElement(tv_node, 'country') cur_country.text = cur_country_name if getattr(my_show, 'firstaired', None): premiered = etree.SubElement(tv_node, 'premiered') premiered.text = my_show['firstaired'] if getattr(my_show, 'network', None): studio = etree.SubElement(tv_node, 'studio') studio.text = my_show['network'].strip() if getattr(my_show, 'writer', None) and isinstance( my_show['writer'], string_types): for writer in self._split_info(my_show['writer']): cur_writer = etree.SubElement(tv_node, 'credits') cur_writer.text = writer if getattr(my_show, 'director', None) and isinstance( my_show['director'], string_types): for director in self._split_info(my_show['director']): cur_director = etree.SubElement(tv_node, 'director') cur_director.text = director if getattr(my_show, '_actors', None): for actor in my_show['_actors']: cur_actor = etree.SubElement(tv_node, 'actor') if 'name' in actor and actor['name'].strip(): cur_actor_name = etree.SubElement(cur_actor, 'name') cur_actor_name.text = actor['name'].strip() else: continue if 'role' in actor and actor['role'].strip(): cur_actor_role = etree.SubElement(cur_actor, 'role') cur_actor_role.text = actor['role'].strip() if 'image' in actor and actor['image'].strip(): cur_actor_thumb = etree.SubElement(cur_actor, 'thumb') cur_actor_thumb.text = actor['image'].strip() # Make it purdy helpers.indent_xml(tv_node) data = etree.ElementTree(tv_node) return data
def _show_data(self, show_obj): """ Creates an elementTree XML structure for a MediaBrowser-style series.xml returns the resulting data object. show_obj: a Series instance to create the NFO for """ my_show = self._get_show_data(show_obj) # If by any reason it couldn't get the shows indexer data let's not go throught the rest of this method # as that pretty useless. if not my_show: return False tv_node = etree.Element(u'Series') if getattr(my_show, u'id', None): indexerid = etree.SubElement(tv_node, u'id') indexerid.text = str(my_show[u'id']) if getattr(my_show, u'seriesname', None): series_name = etree.SubElement(tv_node, u'SeriesName') series_name.text = my_show[u'seriesname'] if getattr(my_show, u'status', None): status = etree.SubElement(tv_node, u'Status') status.text = my_show[u'status'] if getattr(my_show, u'network', None): network = etree.SubElement(tv_node, u'Network') network.text = my_show[u'network'] if getattr(my_show, u'airs_time', None): airs_time = etree.SubElement(tv_node, u'Airs_Time') airs_time.text = my_show[u'airs_time'] if getattr(my_show, u'airs_dayofweek', None): airs_day_of_week = etree.SubElement(tv_node, u'Airs_DayOfWeek') airs_day_of_week.text = my_show[u'airs_dayofweek'] first_aired = etree.SubElement(tv_node, u'FirstAired') if getattr(my_show, u'firstaired', None): first_aired.text = my_show[u'firstaired'] if getattr(my_show, u'contentrating', None): content_rating = etree.SubElement(tv_node, u'ContentRating') content_rating.text = my_show[u'contentrating'] mpaa = etree.SubElement(tv_node, u'MPAARating') mpaa.text = my_show[u'contentrating'] certification = etree.SubElement(tv_node, u'certification') certification.text = my_show[u'contentrating'] metadata_type = etree.SubElement(tv_node, u'Type') metadata_type.text = u'Series' if getattr(my_show, u'overview', None): overview = etree.SubElement(tv_node, u'Overview') overview.text = my_show[u'overview'] if getattr(my_show, u'firstaired', None): premiere_date = etree.SubElement(tv_node, u'PremiereDate') premiere_date.text = my_show[u'firstaired'] if getattr(my_show, u'rating', None): rating = etree.SubElement(tv_node, u'Rating') rating.text = str(my_show[u'rating']) if getattr(my_show, u'firstaired', None): try: year_text = str(datetime.datetime.strptime(my_show[u'firstaired'], dateFormat).year) if year_text: production_year = etree.SubElement(tv_node, u'ProductionYear') production_year.text = year_text except Exception: pass if getattr(my_show, u'runtime', None): running_time = etree.SubElement(tv_node, u'RunningTime') running_time.text = str(my_show[u'runtime']) runtime = etree.SubElement(tv_node, u'Runtime') runtime.text = str(my_show[u'runtime']) if getattr(my_show, u'imdb_id', None): imdb_id = etree.SubElement(tv_node, u'IMDB_ID') imdb_id.text = my_show[u'imdb_id'] imdb_id = etree.SubElement(tv_node, u'IMDB') imdb_id.text = my_show[u'imdb_id'] imdb_id = etree.SubElement(tv_node, u'IMDbId') imdb_id.text = my_show[u'imdb_id'] if getattr(my_show, u'zap2it_id', None): zap2it_id = etree.SubElement(tv_node, u'Zap2ItId') zap2it_id.text = my_show[u'zap2it_id'] if getattr(my_show, u'genre', None) and isinstance(my_show[u'genre'], string_types): genres = etree.SubElement(tv_node, u'Genres') for genre in my_show[u'genre'].split(u'|'): if genre.strip(): cur_genre = etree.SubElement(genres, u'Genre') cur_genre.text = genre.strip() genre = etree.SubElement(tv_node, u'Genre') genre.text = u'|'.join([x.strip() for x in my_show[u'genre'].split(u'|') if x.strip()]) if getattr(my_show, u'network', None): studios = etree.SubElement(tv_node, u'Studios') studio = etree.SubElement(studios, u'Studio') studio.text = my_show[u'network'] if getattr(my_show, u'_actors', None): persons = etree.SubElement(tv_node, u'Persons') for actor in my_show[u'_actors']: if not (u'name' in actor and actor[u'name'].strip()): continue cur_actor = etree.SubElement(persons, u'Person') cur_actor_name = etree.SubElement(cur_actor, u'Name') cur_actor_name.text = actor[u'name'].strip() cur_actor_type = etree.SubElement(cur_actor, u'Type') cur_actor_type.text = u'Actor' if u'role' in actor and actor[u'role'].strip(): cur_actor_role = etree.SubElement(cur_actor, u'Role') cur_actor_role.text = actor[u'role'].strip() helpers.indent_xml(tv_node) data = etree.ElementTree(tv_node) return data
def _ep_data(self, ep_obj): """ Creates an elementTree XML structure for a WDTV style episode.xml and returns the resulting data object. ep_obj: a Series instance to create the NFO for """ eps_to_write = [ep_obj] + ep_obj.related_episodes my_show = self._get_show_data(ep_obj.series) if not my_show: return None root_node = etree.Element('details') # write an WDTV XML containing info for all matching episodes for ep_to_write in eps_to_write: try: my_ep = my_show[ep_to_write.season][ep_to_write.episode] except (IndexerEpisodeNotFound, IndexerSeasonNotFound): log.info( 'Unable to find episode {number} on {indexer}... has it been removed? Should I delete from db?', { 'number': ep_num(ep_to_write.season, ep_to_write.episode), 'indexer': indexerApi(ep_obj.series.indexer).name, } ) return None if ep_obj.season == 0 and not getattr(my_ep, 'firstaired', None): my_ep['firstaired'] = str(datetime.date.fromordinal(1)) if not (getattr(my_ep, 'episodename', None) and getattr(my_ep, 'firstaired', None)): return None if len(eps_to_write) > 1: episode = etree.SubElement(root_node, 'details') else: episode = root_node # TODO: get right EpisodeID episode_id = etree.SubElement(episode, 'id') episode_id.text = str(ep_to_write.indexerid) title = etree.SubElement(episode, 'title') title.text = ep_obj.pretty_name() if getattr(my_show, 'seriesname', None): series_name = etree.SubElement(episode, 'series_name') series_name.text = my_show['seriesname'] if ep_to_write.name: episode_name = etree.SubElement(episode, 'episode_name') episode_name.text = ep_to_write.name season_number = etree.SubElement(episode, 'season_number') season_number.text = str(ep_to_write.season) episode_num = etree.SubElement(episode, 'episode_number') episode_num.text = str(ep_to_write.episode) first_aired = etree.SubElement(episode, 'firstaired') if ep_to_write.airdate != datetime.date.fromordinal(1): first_aired.text = str(ep_to_write.airdate) if getattr(my_show, 'firstaired', None): try: year_text = str(datetime.datetime.strptime(my_show['firstaired'], dateFormat).year) if year_text: year = etree.SubElement(episode, 'year') year.text = year_text except Exception: pass if ep_to_write.season != 0 and getattr(my_show, 'runtime', None): runtime = etree.SubElement(episode, 'runtime') runtime.text = str(my_show['runtime']) if getattr(my_show, 'genre', None): genre = etree.SubElement(episode, 'genre') genre.text = ' / '.join([x.strip() for x in my_show['genre'].split('|') if x.strip()]) if getattr(my_ep, 'director', None): director = etree.SubElement(episode, 'director') director.text = my_ep['director'] if getattr(my_show, '_actors', None): for actor in my_show['_actors']: if not ('name' in actor and actor['name'].strip()): continue cur_actor = etree.SubElement(episode, 'actor') cur_actor_name = etree.SubElement(cur_actor, 'name') cur_actor_name.text = actor['name'] if 'role' in actor and actor['role'].strip(): cur_actor_role = etree.SubElement(cur_actor, 'role') cur_actor_role.text = actor['role'].strip() if ep_to_write.description: overview = etree.SubElement(episode, 'overview') overview.text = ep_to_write.description # Make it purdy helpers.indent_xml(root_node) data = etree.ElementTree(root_node) return data
def _ep_data(self, ep_obj): """ Creates an elementTree XML structure for an KODI-style episode.nfo and returns the resulting data object. show_obj: a Episode instance to create the NFO for """ eps_to_write = [ep_obj] + ep_obj.related_episodes my_show = self._get_show_data(ep_obj.series) if not my_show: return None if len(eps_to_write) > 1: root_node = etree.Element('kodimultiepisode') else: root_node = etree.Element('episodedetails') # write an NFO containing info for all matching episodes for ep_to_write in eps_to_write: try: my_ep = my_show[ep_to_write.season][ep_to_write.episode] except (IndexerEpisodeNotFound, IndexerSeasonNotFound): log.info( u'Unable to find episode {ep_num} on {indexer}...' u' has it been removed? Should I delete from db?', { 'ep_num': episode_num(ep_to_write.season, ep_to_write.episode), 'indexer': indexerApi(ep_obj.series.indexer).name, }) return None if not getattr(my_ep, 'firstaired', None): my_ep['firstaired'] = str(datetime.date.fromordinal(1)) if not getattr(my_ep, 'episodename', None): log.debug(u'Not generating nfo because the ep has no title') return None log.debug(u'Creating metadata for episode {0}', episode_num(ep_obj.season, ep_obj.episode)) if len(eps_to_write) > 1: episode = etree.SubElement(root_node, 'episodedetails') else: episode = root_node if getattr(my_ep, 'episodename', None): title = etree.SubElement(episode, 'title') title.text = my_ep['episodename'] if getattr(my_show, 'seriesname', None): showtitle = etree.SubElement(episode, 'showtitle') showtitle.text = my_show['seriesname'] season = etree.SubElement(episode, 'season') season.text = str(ep_to_write.season) episodenum = etree.SubElement(episode, 'episode') episodenum.text = str(ep_to_write.episode) uniqueid = etree.SubElement(episode, 'uniqueid') uniqueid.text = str(ep_to_write.indexerid) if ep_to_write.airdate != datetime.date.fromordinal(1): aired = etree.SubElement(episode, 'aired') aired.text = str(ep_to_write.airdate) if getattr(my_ep, 'overview', None): plot = etree.SubElement(episode, 'plot') plot.text = my_ep['overview'] if ep_to_write.season and getattr(my_show, 'runtime', None): runtime = etree.SubElement(episode, 'runtime') runtime.text = my_show['runtime'] if getattr(my_ep, 'airsbefore_season', None): displayseason = etree.SubElement(episode, 'displayseason') displayseason.text = my_ep['airsbefore_season'] if getattr(my_ep, 'airsbefore_episode', None): displayepisode = etree.SubElement(episode, 'displayepisode') displayepisode.text = my_ep['airsbefore_episode'] if getattr(my_ep, 'filename', None): thumb = etree.SubElement(episode, 'thumb') thumb.text = my_ep['filename'].strip() # watched = etree.SubElement(episode, 'watched') # watched.text = 'false' if getattr(my_ep, 'rating', None): rating = etree.SubElement(episode, 'rating') rating.text = my_ep['rating'] if getattr(my_ep, 'writer', None) and isinstance( my_ep['writer'], string_types): for writer in self._split_info(my_ep['writer']): cur_writer = etree.SubElement(episode, 'credits') cur_writer.text = writer if getattr(my_ep, 'director', None) and isinstance( my_ep['director'], string_types): for director in self._split_info(my_ep['director']): cur_director = etree.SubElement(episode, 'director') cur_director.text = director if getattr(my_ep, 'gueststars', None) and isinstance( my_ep['gueststars'], string_types): for actor in self._split_info(my_ep['gueststars']): cur_actor = etree.SubElement(episode, 'actor') cur_actor_name = etree.SubElement(cur_actor, 'name') cur_actor_name.text = actor if getattr(my_show, '_actors', None): for actor in my_show['_actors']: cur_actor = etree.SubElement(episode, 'actor') if 'name' in actor and actor['name'].strip(): cur_actor_name = etree.SubElement(cur_actor, 'name') cur_actor_name.text = actor['name'].strip() else: continue if 'role' in actor and actor['role'].strip(): cur_actor_role = etree.SubElement(cur_actor, 'role') cur_actor_role.text = actor['role'].strip() if 'image' in actor and actor['image'].strip(): cur_actor_thumb = etree.SubElement(cur_actor, 'thumb') cur_actor_thumb.text = actor['image'].strip() # Make it purdy helpers.indent_xml(root_node) data = etree.ElementTree(root_node) return data
def _ep_data(self, ep_obj): """ Creates an elementTree XML structure for a MediaBrowser style episode.xml and returns the resulting data object. show_obj: a Series instance to create the NFO for """ eps_to_write = [ep_obj] + ep_obj.related_episodes my_show = self._get_show_data(ep_obj.series) if not my_show: return None root_node = etree.Element('details') movie = etree.SubElement(root_node, 'movie') movie.attrib['isExtra'] = 'false' movie.attrib['isSet'] = 'false' movie.attrib['isTV'] = 'true' # write an MediaBrowser XML containing info for all matching episodes for ep_to_write in eps_to_write: try: my_ep = my_show[ep_to_write.season][ep_to_write.episode] except (IndexerEpisodeNotFound, IndexerSeasonNotFound): log.info( 'Unable to find episode {ep_num} on {indexer}...' ' has it been removed? Should I delete from db?', { 'ep_num': episode_num(ep_to_write.season, ep_to_write.episode), 'indexer': indexerApi(ep_obj.series.indexer).name, }) return None if ep_to_write == ep_obj: # root (or single) episode # default to today's date for specials if firstaired is not set if ep_to_write.season == 0 and not getattr( my_ep, 'firstaired', None): my_ep['firstaired'] = str(datetime.date.fromordinal(1)) if not (getattr(my_ep, 'episodename', None) and getattr(my_ep, 'firstaired', None)): return None episode = movie if ep_to_write.name: episode_name = etree.SubElement(episode, 'title') episode_name.text = ep_to_write.name season_number = etree.SubElement(episode, 'season') season_number.text = str(ep_to_write.season) episode_number = etree.SubElement(episode, 'episode') episode_number.text = str(ep_to_write.episode) if getattr(my_show, 'firstaired', None): try: year_text = str( datetime.datetime.strptime(my_show['firstaired'], dateFormat).year) if year_text: year = etree.SubElement(episode, 'year') year.text = year_text except Exception: pass if getattr(my_show, 'overview', None): plot = etree.SubElement(episode, 'plot') plot.text = my_show['overview'] if ep_to_write.description: overview = etree.SubElement(episode, 'episodeplot') overview.text = ep_to_write.description if getattr(my_show, 'contentrating', None): mpaa = etree.SubElement(episode, 'mpaa') mpaa.text = my_show['contentrating'] if not ep_obj.related_episodes and getattr( my_ep, 'rating', None): try: rating = int((float(my_ep['rating']) * 10)) except ValueError: rating = 0 if rating: rating = etree.SubElement(episode, 'rating') rating.text = str(rating) if getattr(my_ep, 'director', None): director = etree.SubElement(episode, 'director') director.text = my_ep['director'] if getattr(my_ep, 'writer', None): writer = etree.SubElement(episode, 'credits') writer.text = my_ep['writer'] if getattr(my_show, '_actors', None) or getattr( my_ep, 'gueststars', None): cast = etree.SubElement(episode, 'cast') if getattr(my_ep, 'gueststars', None) and isinstance( my_ep['gueststars'], string_types): for actor in (x.strip() for x in my_ep['gueststars'].split('|') if x.strip()): cur_actor = etree.SubElement(cast, 'actor') cur_actor.text = actor if getattr(my_show, '_actors', None): for actor in my_show['_actors']: if 'name' in actor and actor['name'].strip(): cur_actor = etree.SubElement(cast, 'actor') cur_actor.text = actor['name'].strip() else: # append data from (if any) related episodes if ep_to_write.name: if not episode_name.text: episode_name.text = ep_to_write.name else: episode_name.text = ', '.join( [episode_name.text, ep_to_write.name]) if ep_to_write.description: if not overview.text: overview.text = ep_to_write.description else: overview.text = '\r'.join( [overview.text, ep_to_write.description]) # Make it purdy helpers.indent_xml(root_node) data = etree.ElementTree(root_node) return data
def _show_data(self, show_obj): """ Creates an elementTree XML structure for a MediaBrowser-style series.xml returns the resulting data object. show_obj: a Series instance to create the NFO for """ my_show = self._get_show_data(show_obj) # If by any reason it couldn't get the shows indexer data let's not go throught the rest of this method # as that pretty useless. if not my_show: return False root_node = etree.Element('details') tv_node = etree.SubElement(root_node, 'movie') tv_node.attrib['isExtra'] = 'false' tv_node.attrib['isSet'] = 'false' tv_node.attrib['isTV'] = 'true' title = etree.SubElement(tv_node, 'title') title.text = my_show['seriesname'] if getattr(my_show, 'genre', None): genres = etree.SubElement(tv_node, 'genres') for genre in my_show['genre'].split('|'): if genre and genre.strip(): cur_genre = etree.SubElement(genres, 'Genre') cur_genre.text = genre.strip() if getattr(my_show, 'firstaired', None): first_aired = etree.SubElement(tv_node, 'premiered') first_aired.text = my_show['firstaired'] try: year_text = str( datetime.datetime.strptime(my_show['firstaired'], dateFormat).year) if year_text: year = etree.SubElement(tv_node, 'year') year.text = year_text except Exception: pass if getattr(my_show, 'overview', None): plot = etree.SubElement(tv_node, 'plot') plot.text = my_show['overview'] if getattr(my_show, 'rating', None): try: rating = int(float(my_show['rating']) * 10) except ValueError: rating = 0 if rating: rating = etree.SubElement(tv_node, 'rating') rating.text = str(rating) if getattr(my_show, 'status', None): status = etree.SubElement(tv_node, 'status') status.text = my_show['status'] if getattr(my_show, 'contentrating', None): mpaa = etree.SubElement(tv_node, 'mpaa') mpaa.text = my_show['contentrating'] if getattr(my_show, 'imdb_id', None): imdb_id = etree.SubElement(tv_node, 'id') imdb_id.attrib['moviedb'] = 'imdb' imdb_id.text = my_show['imdb_id'] if getattr(my_show, 'id', None): indexer_id = etree.SubElement(tv_node, 'indexerid') indexer_id.text = str(my_show['id']) if getattr(my_show, 'runtime', None): runtime = etree.SubElement(tv_node, 'runtime') runtime.text = str(my_show['runtime']) if getattr(my_show, '_actors', None): cast = etree.SubElement(tv_node, 'cast') for actor in my_show['_actors']: if 'name' in actor and actor['name'].strip(): cur_actor = etree.SubElement(cast, 'actor') cur_actor.text = actor['name'].strip() helpers.indent_xml(root_node) data = etree.ElementTree(root_node) return data
def _show_data(self, series_obj): """ Creates an elementTree XML structure for an KODI-style tvshow.nfo and returns the resulting data object. show_obj: a Series instance to create the NFO for """ my_show = self._get_show_data(series_obj) # If by any reason it couldn't get the shows indexer data let's not go throught the rest of this method # as that pretty useless. if not my_show: return False tv_node = etree.Element('tvshow') title = etree.SubElement(tv_node, 'title') title.text = my_show['seriesname'] if getattr(my_show, 'rating', None): rating = etree.SubElement(tv_node, 'rating') rating.text = text_type(my_show['rating']) if getattr(my_show, 'firstaired', None): try: year_text = text_type(datetime.datetime.strptime(my_show['firstaired'], dateFormat).year) if year_text: year = etree.SubElement(tv_node, 'year') year.text = year_text except Exception: pass if getattr(my_show, 'overview', None): plot = etree.SubElement(tv_node, 'plot') plot.text = my_show['overview'] # For now we're only using this for tvdb indexed shows. We should come with a proper strategy as how to use the # metadata for TMDB/TVMAZE shows. We could try to map it a tvdb show. Or keep mixing it. if series_obj.indexer == INDEXER_TVDBV2 and getattr(my_show, 'id', None): episode_guide = etree.SubElement(tv_node, 'episodeguide') episode_guide_url = etree.SubElement(episode_guide, 'url', cache='auth.json', post='yes') episode_guide_url.text = '{url}/login?{{"apikey":"{apikey}","id":{id}}}' \ '|Content-Type=application/json'.format(url=API_BASE_TVDB, apikey=TVDB_API_KEY, id=my_show['id']) if getattr(my_show, 'contentrating', None): mpaa = etree.SubElement(tv_node, 'mpaa') mpaa.text = my_show['contentrating'] if getattr(my_show, 'id', None): indexer_id = etree.SubElement(tv_node, 'id') indexer_id.text = text_type(my_show['id']) if getattr(my_show, 'genre', None) and isinstance(my_show['genre'], string_types): for genre in self._split_info(my_show['genre']): cur_genre = etree.SubElement(tv_node, 'genre') cur_genre.text = genre if 'country_codes' in series_obj.imdb_info: for country in self._split_info(series_obj.imdb_info['country_codes']): try: cur_country_name = Country(country.upper()).name.title() except Exception: continue cur_country = etree.SubElement(tv_node, 'country') cur_country.text = cur_country_name if getattr(my_show, 'firstaired', None): premiered = etree.SubElement(tv_node, 'premiered') premiered.text = my_show['firstaired'] if getattr(my_show, 'network', None): studio = etree.SubElement(tv_node, 'studio') studio.text = my_show['network'].strip() if getattr(my_show, 'writer', None) and isinstance(my_show['writer'], string_types): for writer in self._split_info(my_show['writer']): cur_writer = etree.SubElement(tv_node, 'credits') cur_writer.text = writer if getattr(my_show, 'director', None) and isinstance(my_show['director'], string_types): for director in self._split_info(my_show['director']): cur_director = etree.SubElement(tv_node, 'director') cur_director.text = director if getattr(my_show, '_actors', None): for actor in my_show['_actors']: cur_actor = etree.SubElement(tv_node, 'actor') if 'name' in actor and actor['name'].strip(): cur_actor_name = etree.SubElement(cur_actor, 'name') cur_actor_name.text = actor['name'].strip() else: continue if 'role' in actor and actor['role'].strip(): cur_actor_role = etree.SubElement(cur_actor, 'role') cur_actor_role.text = actor['role'].strip() if 'image' in actor and actor['image'].strip(): cur_actor_thumb = etree.SubElement(cur_actor, 'thumb') cur_actor_thumb.text = actor['image'].strip() # Make it purdy helpers.indent_xml(tv_node) data = etree.ElementTree(tv_node) return data
def _ep_data(self, ep_obj): """ Creates an elementTree XML structure for an KODI-style episode.nfo and returns the resulting data object. show_obj: a Episode instance to create the NFO for """ eps_to_write = [ep_obj] + ep_obj.related_episodes series_obj = self._get_show_data(ep_obj.series) if not series_obj: return None if len(eps_to_write) > 1: root_node = etree.Element('kodimultiepisode') else: root_node = etree.Element('episodedetails') # write an NFO containing info for all matching episodes for ep_to_write in eps_to_write: try: my_ep = series_obj[ep_to_write.season][ep_to_write.episode] except (IndexerEpisodeNotFound, IndexerSeasonNotFound): log.info( u'Unable to find episode {ep_num} on {indexer}...' u' has it been removed? Should I delete from db?', { 'ep_num': episode_num(ep_to_write.season, ep_to_write.episode), 'indexer': indexerApi(ep_obj.series.indexer).name, } ) return None if not getattr(my_ep, 'firstaired', None): my_ep['firstaired'] = text_type(datetime.date.fromordinal(1)) if not getattr(my_ep, 'episodename', None): log.debug(u'Not generating nfo because the ep has no title') return None log.debug(u'Creating metadata for episode {0}', episode_num(ep_obj.season, ep_obj.episode)) if len(eps_to_write) > 1: episode = etree.SubElement(root_node, 'episodedetails') else: episode = root_node if getattr(my_ep, 'episodename', None): title = etree.SubElement(episode, 'title') title.text = my_ep['episodename'] if getattr(series_obj, 'seriesname', None): showtitle = etree.SubElement(episode, 'showtitle') showtitle.text = series_obj['seriesname'] season = etree.SubElement(episode, 'season') season.text = text_type(ep_to_write.season) episodenum = etree.SubElement(episode, 'episode') episodenum.text = text_type(ep_to_write.episode) uniqueid = etree.SubElement(episode, 'uniqueid') uniqueid.text = text_type(ep_to_write.indexerid) if ep_to_write.airdate != datetime.date.fromordinal(1): aired = etree.SubElement(episode, 'aired') aired.text = text_type(ep_to_write.airdate) if getattr(my_ep, 'overview', None): plot = etree.SubElement(episode, 'plot') plot.text = my_ep['overview'] if ep_to_write.season and getattr(series_obj, 'runtime', None): runtime = etree.SubElement(episode, 'runtime') runtime.text = text_type(series_obj['runtime']) if getattr(my_ep, 'airsbefore_season', None): displayseason = etree.SubElement(episode, 'displayseason') displayseason.text = my_ep['airsbefore_season'] if getattr(my_ep, 'airsbefore_episode', None): displayepisode = etree.SubElement(episode, 'displayepisode') displayepisode.text = my_ep['airsbefore_episode'] if getattr(my_ep, 'filename', None): thumb = etree.SubElement(episode, 'thumb') thumb.text = my_ep['filename'].strip() # watched = etree.SubElement(episode, 'watched') # watched.text = 'false' if getattr(my_ep, 'rating', None): rating = etree.SubElement(episode, 'rating') rating.text = text_type(my_ep['rating']) if getattr(my_ep, 'writer', None) and isinstance(my_ep['writer'], string_types): for writer in self._split_info(my_ep['writer']): cur_writer = etree.SubElement(episode, 'credits') cur_writer.text = writer if getattr(my_ep, 'director', None) and isinstance(my_ep['director'], string_types): for director in self._split_info(my_ep['director']): cur_director = etree.SubElement(episode, 'director') cur_director.text = director if getattr(my_ep, 'gueststars', None) and isinstance(my_ep['gueststars'], string_types): for actor in self._split_info(my_ep['gueststars']): cur_actor = etree.SubElement(episode, 'actor') cur_actor_name = etree.SubElement(cur_actor, 'name') cur_actor_name.text = actor if getattr(series_obj, '_actors', None): for actor in series_obj['_actors']: cur_actor = etree.SubElement(episode, 'actor') if 'name' in actor and actor['name'].strip(): cur_actor_name = etree.SubElement(cur_actor, 'name') cur_actor_name.text = actor['name'].strip() else: continue if 'role' in actor and actor['role'].strip(): cur_actor_role = etree.SubElement(cur_actor, 'role') cur_actor_role.text = actor['role'].strip() if 'image' in actor and actor['image'].strip(): cur_actor_thumb = etree.SubElement(cur_actor, 'thumb') cur_actor_thumb.text = actor['image'].strip() # Make it purdy helpers.indent_xml(root_node) data = etree.ElementTree(root_node) return data
def _show_data(self, series_obj): """ Creates an elementTree XML structure for an KODI-style tvshow.nfo and returns the resulting data object. show_obj: a Series instance to create the NFO for """ my_show = self._get_show_data(series_obj) # If by any reason it couldn't get the shows indexer data let's not go throught the rest of this method # as that pretty useless. if not my_show: return False tv_node = etree.Element('tvshow') title = etree.SubElement(tv_node, 'title') title.text = my_show['seriesname'] if getattr(my_show, 'rating', None): rating = etree.SubElement(tv_node, 'rating') rating.text = text_type(my_show['rating']) if getattr(my_show, 'firstaired', None): try: year_text = text_type( datetime.datetime.strptime(my_show['firstaired'], dateFormat).year) if year_text: year = etree.SubElement(tv_node, 'year') year.text = year_text except Exception: pass if getattr(my_show, 'overview', None): plot = etree.SubElement(tv_node, 'plot') plot.text = my_show['overview'] # For now we're only using this for tvdb indexed shows. We should come with a proper strategy as how to use the # metadata for TMDB/TVMAZE shows. We could try to map it a tvdb show. Or keep mixing it. if series_obj.indexer == INDEXER_TVDBV2 and getattr( my_show, 'id', None): episode_guide = etree.SubElement(tv_node, 'episodeguide') episode_guide_url = etree.SubElement(episode_guide, 'url', cache='auth.json', post='yes') episode_guide_url.text = '{url}/login?{{"apikey":"{apikey}","id":{id}}}' \ '|Content-Type=application/json'.format(url=API_BASE_TVDB, apikey=TVDB_API_KEY, id=my_show['id']) if getattr(my_show, 'contentrating', None): mpaa = etree.SubElement(tv_node, 'mpaa') mpaa.text = my_show['contentrating'] # Add main indexer uniqueid = etree.SubElement(tv_node, 'uniqueid') uniqueid.set('default', 'true') uniqueid.set('type', series_obj.identifier.indexer.slug) uniqueid.text = str(series_obj.identifier.id) for indexer_slug in ('tvdb', 'tmdb', 'imdb', 'tvmaze', 'anidb'): if indexer_slug == series_obj.identifier.indexer.slug: continue external_id = series_obj.externals.get(f'{indexer_slug}_id') if not external_id: continue uniqueid = etree.SubElement(tv_node, 'uniqueid') uniqueid.set('default', 'false') uniqueid.set('type', indexer_slug) uniqueid.text = str(external_id) if getattr(my_show, 'genre', None) and isinstance( my_show['genre'], string_types): for genre in self._split_info(my_show['genre']): cur_genre = etree.SubElement(tv_node, 'genre') cur_genre.text = genre if 'country_codes' in series_obj.imdb_info: for country in self._split_info( series_obj.imdb_info['country_codes']): try: cur_country_name = Country(country.upper()).name.title() except Exception: continue cur_country = etree.SubElement(tv_node, 'country') cur_country.text = cur_country_name if getattr(my_show, 'firstaired', None): premiered = etree.SubElement(tv_node, 'premiered') premiered.text = my_show['firstaired'] if getattr(my_show, 'network', None): studio = etree.SubElement(tv_node, 'studio') studio.text = my_show['network'].strip() if getattr(my_show, 'writer', None) and isinstance( my_show['writer'], string_types): for writer in self._split_info(my_show['writer']): cur_writer = etree.SubElement(tv_node, 'credits') cur_writer.text = writer if getattr(my_show, 'director', None) and isinstance( my_show['director'], string_types): for director in self._split_info(my_show['director']): cur_director = etree.SubElement(tv_node, 'director') cur_director.text = director if getattr(my_show, '_actors', None): for actor in my_show['_actors']: cur_actor = etree.SubElement(tv_node, 'actor') if 'name' in actor and actor['name'].strip(): cur_actor_name = etree.SubElement(cur_actor, 'name') cur_actor_name.text = actor['name'].strip() else: continue if 'role' in actor and actor['role'].strip(): cur_actor_role = etree.SubElement(cur_actor, 'role') cur_actor_role.text = actor['role'].strip() if 'image' in actor and actor['image'].strip(): cur_actor_thumb = etree.SubElement(cur_actor, 'thumb') cur_actor_thumb.text = actor['image'].strip() # Make it purdy helpers.indent_xml(tv_node) data = etree.ElementTree(tv_node) return data
def _show_data(self, show_obj): """ Creates an elementTree XML structure for a MediaBrowser-style series.xml returns the resulting data object. show_obj: a Series instance to create the NFO for """ my_show = self._get_show_data(show_obj) # If by any reason it couldn't get the shows indexer data let's not go throught the rest of this method # as that pretty useless. if not my_show: return False root_node = etree.Element('details') tv_node = etree.SubElement(root_node, 'movie') tv_node.attrib['isExtra'] = 'false' tv_node.attrib['isSet'] = 'false' tv_node.attrib['isTV'] = 'true' title = etree.SubElement(tv_node, 'title') title.text = my_show['seriesname'] if getattr(my_show, 'genre', None): genres = etree.SubElement(tv_node, 'genres') for genre in my_show['genre'].split('|'): if genre and genre.strip(): cur_genre = etree.SubElement(genres, 'Genre') cur_genre.text = genre.strip() if getattr(my_show, 'firstaired', None): first_aired = etree.SubElement(tv_node, 'premiered') first_aired.text = my_show['firstaired'] try: year_text = str(datetime.datetime.strptime(my_show['firstaired'], dateFormat).year) if year_text: year = etree.SubElement(tv_node, 'year') year.text = year_text except Exception: pass if getattr(my_show, 'overview', None): plot = etree.SubElement(tv_node, 'plot') plot.text = my_show['overview'] if getattr(my_show, 'rating', None): try: rating = int(float(my_show['rating']) * 10) except ValueError: rating = 0 if rating: rating = etree.SubElement(tv_node, 'rating') rating.text = str(rating) if getattr(my_show, 'status', None): status = etree.SubElement(tv_node, 'status') status.text = my_show['status'] if getattr(my_show, 'contentrating', None): mpaa = etree.SubElement(tv_node, 'mpaa') mpaa.text = my_show['contentrating'] if getattr(my_show, 'imdb_id', None): imdb_id = etree.SubElement(tv_node, 'id') imdb_id.attrib['moviedb'] = 'imdb' imdb_id.text = my_show['imdb_id'] if getattr(my_show, 'id', None): indexer_id = etree.SubElement(tv_node, 'indexerid') indexer_id.text = str(my_show['id']) if getattr(my_show, 'runtime', None): runtime = etree.SubElement(tv_node, 'runtime') runtime.text = str(my_show['runtime']) if getattr(my_show, '_actors', None): cast = etree.SubElement(tv_node, 'cast') for actor in my_show['_actors']: if 'name' in actor and actor['name'].strip(): cur_actor = etree.SubElement(cast, 'actor') cur_actor.text = actor['name'].strip() helpers.indent_xml(root_node) data = etree.ElementTree(root_node) return data
def _ep_data(self, ep_obj): """ Creates an elementTree XML structure for a MediaBrowser style episode.xml and returns the resulting data object. show_obj: a Series instance to create the NFO for """ eps_to_write = [ep_obj] + ep_obj.related_episodes my_show = self._get_show_data(ep_obj.series) if not my_show: return None root_node = etree.Element('details') movie = etree.SubElement(root_node, 'movie') movie.attrib['isExtra'] = 'false' movie.attrib['isSet'] = 'false' movie.attrib['isTV'] = 'true' # write an MediaBrowser XML containing info for all matching episodes for ep_to_write in eps_to_write: try: my_ep = my_show[ep_to_write.season][ep_to_write.episode] except (IndexerEpisodeNotFound, IndexerSeasonNotFound): log.info( 'Unable to find episode {ep_num} on {indexer}...' ' has it been removed? Should I delete from db?', { 'ep_num': episode_num(ep_to_write.season, ep_to_write.episode), 'indexer': indexerApi(ep_obj.series.indexer).name, } ) return None if ep_to_write == ep_obj: # root (or single) episode # default to today's date for specials if firstaired is not set if ep_to_write.season == 0 and not getattr(my_ep, 'firstaired', None): my_ep['firstaired'] = str(datetime.date.fromordinal(1)) if not (getattr(my_ep, 'episodename', None) and getattr(my_ep, 'firstaired', None)): return None episode = movie if ep_to_write.name: episode_name = etree.SubElement(episode, 'title') episode_name.text = ep_to_write.name season_number = etree.SubElement(episode, 'season') season_number.text = str(ep_to_write.season) episode_number = etree.SubElement(episode, 'episode') episode_number.text = str(ep_to_write.episode) if getattr(my_show, 'firstaired', None): try: year_text = str(datetime.datetime.strptime(my_show['firstaired'], dateFormat).year) if year_text: year = etree.SubElement(episode, 'year') year.text = year_text except Exception: pass if getattr(my_show, 'overview', None): plot = etree.SubElement(episode, 'plot') plot.text = my_show['overview'] if ep_to_write.description: overview = etree.SubElement(episode, 'episodeplot') overview.text = ep_to_write.description if getattr(my_show, 'contentrating', None): mpaa = etree.SubElement(episode, 'mpaa') mpaa.text = my_show['contentrating'] if not ep_obj.related_episodes and getattr(my_ep, 'rating', None): try: rating = int((float(my_ep['rating']) * 10)) except ValueError: rating = 0 if rating: rating = etree.SubElement(episode, 'rating') rating.text = str(rating) if getattr(my_ep, 'director', None): director = etree.SubElement(episode, 'director') director.text = my_ep['director'] if getattr(my_ep, 'writer', None): writer = etree.SubElement(episode, 'credits') writer.text = my_ep['writer'] if getattr(my_show, '_actors', None) or getattr(my_ep, 'gueststars', None): cast = etree.SubElement(episode, 'cast') if getattr(my_ep, 'gueststars', None) and isinstance(my_ep['gueststars'], string_types): for actor in (x.strip() for x in my_ep['gueststars'].split('|') if x.strip()): cur_actor = etree.SubElement(cast, 'actor') cur_actor.text = actor if getattr(my_show, '_actors', None): for actor in my_show['_actors']: if 'name' in actor and actor['name'].strip(): cur_actor = etree.SubElement(cast, 'actor') cur_actor.text = actor['name'].strip() else: # append data from (if any) related episodes if ep_to_write.name: if not episode_name.text: episode_name.text = ep_to_write.name else: episode_name.text = ', '.join([episode_name.text, ep_to_write.name]) if ep_to_write.description: if not overview.text: overview.text = ep_to_write.description else: overview.text = '\r'.join([overview.text, ep_to_write.description]) # Make it purdy helpers.indent_xml(root_node) data = etree.ElementTree(root_node) return data