def update_show_indexer_metadata(self, show_obj): # type: (sickbeard.tv.TVShow) -> bool if self.show_metadata and show_obj and self._has_show_metadata(show_obj): logger.log(u'Metadata provider %s updating show indexer metadata file for %s' % (self.name, show_obj.name), logger.DEBUG) nfo_file_path = self.get_show_file_path(show_obj) with ek.ek(io.open, nfo_file_path, 'r', encoding='utf8') as xmlFileObj: show_xml = etree.ElementTree(file=xmlFileObj) tvid = show_xml.find('indexer') prodid = show_xml.find('id') root = show_xml.getroot() show_tvid = str(show_obj.tvid) if None is not tvid: tvid.text = '%s' % show_tvid else: etree.SubElement(root, 'indexer').text = '%s' % show_tvid show_prodid = str(show_obj.prodid) if None is not prodid: prodid.text = '%s' % show_prodid else: etree.SubElement(root, 'id').text = '%s' % show_prodid # Make it purdy sg_helpers.indent_xml(root) sg_helpers.write_file(nfo_file_path, show_xml, xmltree=True, utf8=True) return True
def _show_data(self, show_obj): # type: (sickbeard.tv.TVShow) -> Optional[Union[bool, etree.Element]] """ Creates an elementTree XML structure for an XBMC-style tvshow.nfo and returns the resulting data object. show_obj: a TVShow instance to create the NFO for """ show_id = show_obj.prodid show_lang = show_obj.lang tvinfo_config = sickbeard.TVInfoAPI(show_obj.tvid).api_params.copy() tvinfo_config['actors'] = True if show_lang and not 'en' == show_lang: tvinfo_config['language'] = show_lang if 0 != show_obj.dvdorder: tvinfo_config['dvdorder'] = True t = sickbeard.TVInfoAPI(show_obj.tvid).setup(**tvinfo_config) tv_node = etree.Element('tvshow') try: show_info = t[int(show_id)] except BaseTVinfoShownotfound as e: logger.log( 'Unable to find show with id %s on %s, skipping it' % (show_id, sickbeard.TVInfoAPI(show_obj.tvid).name), logger.ERROR) raise e except BaseTVinfoError as e: logger.log( '%s is down, can\'t use its data to add this show' % sickbeard.TVInfoAPI(show_obj.tvid).name, logger.ERROR) raise e if not self._valid_show(show_info, show_obj): return # check for title and id if None is getattr(show_info, 'seriesname', None) or None is getattr( show_info, 'id', None): logger.log( 'Incomplete info for show with id %s on %s, skipping it' % (show_id, sickbeard.TVInfoAPI(show_obj.tvid).name), logger.ERROR) return False title = etree.SubElement(tv_node, 'title') if None is not getattr(show_info, 'seriesname', None): title.text = '%s' % show_info['seriesname'] rating = etree.SubElement(tv_node, 'rating') if None is not getattr(show_info, 'rating', None): rating.text = '%s' % show_info['rating'] year = etree.SubElement(tv_node, 'year') year_text = self.get_show_year(show_obj, show_info) if year_text: year.text = '%s' % year_text plot = etree.SubElement(tv_node, 'plot') if None is not getattr(show_info, 'overview', None): plot.text = '%s' % show_info['overview'] episodeguide = etree.SubElement(tv_node, 'episodeguide') episodeguideurl = etree.SubElement(episodeguide, 'url') episodeguideurl2 = etree.SubElement(tv_node, 'episodeguideurl') if None is not getattr(show_info, 'id', None): showurl = sickbeard.TVInfoAPI( show_obj.tvid).config['base_url'] + str( show_info['id']) + '/all/en.zip' episodeguideurl.text = '%s' % showurl episodeguideurl2.text = '%s' % showurl mpaa = etree.SubElement(tv_node, 'mpaa') if None is not getattr(show_info, 'contentrating', None): mpaa.text = '%s' % show_info['contentrating'] prodid = etree.SubElement(tv_node, 'id') if None is not getattr(show_info, 'id', None): prodid.text = str(show_info['id']) tvid = etree.SubElement(tv_node, 'indexer') if None is not show_obj.tvid: tvid.text = str(show_obj.tvid) genre = etree.SubElement(tv_node, 'genre') if None is not getattr(show_info, 'genre', None): if isinstance(show_info['genre'], string_types): genre.text = ' / '.join(x.strip() for x in show_info['genre'].split('|') if x.strip()) premiered = etree.SubElement(tv_node, 'premiered') if None is not getattr(show_info, 'firstaired', None): premiered.text = '%s' % show_info['firstaired'] studio = etree.SubElement(tv_node, 'studio') if None is not getattr(show_info, 'network', None): studio.text = '%s' % show_info['network'] self.add_actor_element(show_info, etree, tv_node) # Make it purdy sg_helpers.indent_xml(tv_node) data = etree.ElementTree(tv_node) return data
def _ep_data(self, ep_obj): # type: (sickbeard.tv.TVEpisode) -> Optional[Union[bool, etree.Element]] """ Creates an elementTree XML structure for an XBMC-style episode.nfo and returns the resulting data object. show_obj: a TVEpisode instance to create the NFO for """ ep_obj_list_to_write = [ep_obj] + ep_obj.related_ep_obj show_lang = ep_obj.show_obj.lang tvinfo_config = sickbeard.TVInfoAPI( ep_obj.show_obj.tvid).api_params.copy() tvinfo_config['actors'] = True if show_lang and not 'en' == show_lang: tvinfo_config['language'] = show_lang if 0 != ep_obj.show_obj.dvdorder: tvinfo_config['dvdorder'] = True try: t = sickbeard.TVInfoAPI( ep_obj.show_obj.tvid).setup(**tvinfo_config) show_info = t[ep_obj.show_obj.prodid] except BaseTVinfoShownotfound as e: raise exceptions_helper.ShowNotFoundException(ex(e)) except BaseTVinfoError as e: logger.log( 'Unable to connect to %s while creating meta files - skipping - %s' % (sickbeard.TVInfoAPI(ep_obj.show_obj.tvid).name, ex(e)), logger.ERROR) return if not self._valid_show(show_info, ep_obj.show_obj): return if 1 < len(ep_obj_list_to_write): rootNode = etree.Element('xbmcmultiepisode') else: rootNode = etree.Element('episodedetails') # write an NFO containing info for all matching episodes for cur_ep_obj in ep_obj_list_to_write: try: ep_info = show_info[cur_ep_obj.season][cur_ep_obj.episode] except (BaseTVinfoEpisodenotfound, BaseTVinfoSeasonnotfound) as e: logger.log( 'Unable to find episode %sx%s on %s.. has it been removed? Should I delete from db?' % (cur_ep_obj.season, cur_ep_obj.episode, sickbeard.TVInfoAPI(ep_obj.show_obj.tvid).name)) return None except (BaseException, Exception): logger.log( u'Not generating nfo because failed to fetched tv info data at this time', logger.DEBUG) return None if None is getattr(ep_info, 'firstaired', None): ep_info['firstaired'] = str(datetime.date.fromordinal(1)) if None is getattr(ep_info, 'episodename', None): logger.log(u'Not generating nfo because the ep has no title', logger.DEBUG) return None logger.log( u'Creating metadata for episode ' + str(ep_obj.season) + 'x' + str(ep_obj.episode), logger.DEBUG) if 1 < len(ep_obj_list_to_write): episode = etree.SubElement(rootNode, 'episodedetails') else: episode = rootNode title = etree.SubElement(episode, 'title') if None is not cur_ep_obj.name: title.text = '%s' % cur_ep_obj.name showtitle = etree.SubElement(episode, 'showtitle') if None is not cur_ep_obj.show_obj.name: showtitle.text = '%s' % cur_ep_obj.show_obj.name season = etree.SubElement(episode, 'season') season.text = str(cur_ep_obj.season) episodenum = etree.SubElement(episode, 'episode') episodenum.text = str(cur_ep_obj.episode) uniqueid = etree.SubElement(episode, 'uniqueid') uniqueid.text = str(cur_ep_obj.epid) aired = etree.SubElement(episode, 'aired') if cur_ep_obj.airdate != datetime.date.fromordinal(1): aired.text = str(cur_ep_obj.airdate) else: aired.text = '' plot = etree.SubElement(episode, 'plot') if None is not cur_ep_obj.description: plot.text = '%s' % cur_ep_obj.description runtime = etree.SubElement(episode, 'runtime') if 0 != cur_ep_obj.season: if None is not getattr(show_info, 'runtime', None): runtime.text = '%s' % show_info['runtime'] displayseason = etree.SubElement(episode, 'displayseason') if None is not getattr(ep_info, 'airsbefore_season', None): displayseason_text = ep_info['airsbefore_season'] if None is not displayseason_text: displayseason.text = '%s' % displayseason_text displayepisode = etree.SubElement(episode, 'displayepisode') if None is not getattr(ep_info, 'airsbefore_episode', None): displayepisode_text = ep_info['airsbefore_episode'] if None is not displayepisode_text: displayepisode.text = '%s' % displayepisode_text thumb = etree.SubElement(episode, 'thumb') thumb_text = getattr(ep_info, 'filename', None) if None is not thumb_text: thumb.text = '%s' % thumb_text watched = etree.SubElement(episode, 'watched') watched.text = 'false' credits = etree.SubElement(episode, 'credits') credits_text = getattr(ep_info, 'writer', None) if None is not credits_text: credits.text = '%s' % credits_text director = etree.SubElement(episode, 'director') director_text = getattr(ep_info, 'director', None) if None is not director_text: director.text = '%s' % director_text rating = etree.SubElement(episode, 'rating') rating_text = getattr(ep_info, 'rating', None) if None is not rating_text: rating.text = '%s' % rating_text gueststar_text = getattr(ep_info, 'gueststars', None) if isinstance(gueststar_text, string_types): for actor in (x.strip() for x in gueststar_text.split('|') if x.strip()): cur_actor = etree.SubElement(episode, 'actor') cur_actor_name = etree.SubElement(cur_actor, 'name') cur_actor_name.text = '%s' % actor self.add_actor_element(show_info, etree, episode) # Make it purdy sg_helpers.indent_xml(rootNode) data = etree.ElementTree(rootNode) return data
def _show_data(self, show_obj): # type: (sickbeard.tv.TVShow) -> Optional[Union[bool, etree.Element]] """ Creates an elementTree XML structure for a Kodi-style tvshow.nfo and returns the resulting data object. show_obj: a TVShow instance to create the NFO for """ show_ID = show_obj.prodid show_lang = show_obj.lang tvinfo_config = sickbeard.TVInfoAPI(show_obj.tvid).api_params.copy() tvinfo_config['actors'] = True if show_lang and not 'en' == show_lang: tvinfo_config['language'] = show_lang if 0 != show_obj.dvdorder: tvinfo_config['dvdorder'] = True t = sickbeard.TVInfoAPI(show_obj.tvid).setup(**tvinfo_config) tv_node = etree.Element('tvshow') try: show_info = t[int(show_ID)] except BaseTVinfoShownotfound as e: logger.log( 'Unable to find show with id %s on %s, skipping it' % (show_ID, sickbeard.TVInfoAPI(show_obj.tvid).name), logger.ERROR) raise e except BaseTVinfoError as e: logger.log( '%s is down, can\'t use its data to add this show' % sickbeard.TVInfoAPI(show_obj.tvid).name, logger.ERROR) raise e if not self._valid_show(show_info, show_obj): return # check for title and id if None is getattr(show_info, 'seriesname', None) or None is getattr( show_info, 'id', None): logger.log( 'Incomplete info for show with id %s on %s, skipping it' % (show_ID, sickbeard.TVInfoAPI(show_obj.tvid).name), logger.ERROR) return False title = etree.SubElement(tv_node, 'title') if None is not getattr(show_info, 'seriesname', None): title.text = '%s' % show_info['seriesname'] # year = etree.SubElement(tv_node, 'year') premiered = etree.SubElement(tv_node, 'premiered') premiered_text = self.get_show_year(show_obj, show_info, year_only=False) if premiered_text: premiered.text = '%s' % premiered_text has_id = False tvdb_id = None for tvid, slug in map_iter( lambda _tvid: (_tvid, sickbeard.TVInfoAPI(_tvid).config.get('kodi_slug')), list(sickbeard.TVInfoAPI().all_sources)): mid = slug and show_obj.ids[tvid].get('id') if mid: has_id = True kwargs = dict(type=slug) if TVINFO_TVDB == tvid: kwargs.update(dict(default='true')) tvdb_id = str(mid) uniqueid = etree.SubElement(tv_node, 'uniqueid', **kwargs) uniqueid.text = '%s%s' % (('', 'tt')[TVINFO_IMDB == tvid], mid) if not has_id: logger.log( 'Incomplete info for show with id %s on %s, skipping it' % (show_ID, sickbeard.TVInfoAPI(show_obj.tvid).name), logger.ERROR) return False ratings = etree.SubElement(tv_node, 'ratings') if None is not getattr(show_info, 'rating', None): # todo: name dynamic depending on source rating = etree.SubElement(ratings, 'rating', name='thetvdb', max='10') rating_value = etree.SubElement(rating, 'value') rating_value.text = '%s' % show_info['rating'] if None is not getattr(show_info, 'siteratingcount', None): ratings_votes = etree.SubElement(rating, 'votes') ratings_votes.text = '%s' % show_info['siteratingcount'] plot = etree.SubElement(tv_node, 'plot') if None is not getattr(show_info, 'overview', None): plot.text = '%s' % show_info['overview'] episodeguide = etree.SubElement(tv_node, 'episodeguide') episodeguideurl = etree.SubElement(episodeguide, 'url', post='yes', cache='auth.json') if tvdb_id: episodeguideurl.text = sickbeard.TVInfoAPI( TVINFO_TVDB).config['epg_url'].replace('{MID}', tvdb_id) mpaa = etree.SubElement(tv_node, 'mpaa') if None is not getattr(show_info, 'contentrating', None): mpaa.text = '%s' % show_info['contentrating'] genre = etree.SubElement(tv_node, 'genre') if None is not getattr(show_info, 'genre', None): if isinstance(show_info['genre'], string_types): genre.text = ' / '.join([ x.strip() for x in show_info['genre'].split('|') if x.strip() ]) studio = etree.SubElement(tv_node, 'studio') if None is not getattr(show_info, 'network', None): studio.text = '%s' % show_info['network'] self.add_actor_element(show_info, etree, tv_node) # Make it purdy sg_helpers.indent_xml(tv_node) # output valid xml # data = etree.ElementTree(tv_node) # output non valid xml that Kodi accepts data = decode_str(etree.tostring(tv_node)) parts = data.split('episodeguide') if 3 == len(parts): data = 'episodeguide'.join( [parts[0], parts[1].replace('&quot;', '"'), parts[2]]) return data
def remove_default_attr(*args, **kwargs): try: from .. import db msg = 'Changing Kodi Nfo' sickbeard.classes.loading_msg.set_msg_progress(msg, '0%') kodi = metadata_class() num_shows = len(sickbeard.showList) for n, cur_show_obj in enumerate(sickbeard.showList): try: changed = False with cur_show_obj.lock: # call for progress with value sickbeard.classes.loading_msg.set_msg_progress( msg, '{:6.2f}%'.format(float(n) / num_shows * 100)) try: nfo_path = kodi.get_show_file_path(cur_show_obj) except (BaseException, Exception): nfo_path = None if nfo_path: # show try: if ek.ek(os.path.isfile, nfo_path): with ek.ek(io.open, nfo_path, 'r', encoding='utf8') as xml_file_obj: xmltree = etree.ElementTree( file=xml_file_obj) # remove default="" attributes default = False ratings = xmltree.find('ratings') r = None is not ratings and ratings.findall( 'rating') or [] for element in r: if not element.attrib.get('default'): changed |= None is not element.attrib.pop( 'default', None) else: default = True if len(r) and not default: ratings.find( 'rating').attrib['default'] = 'true' changed = True # remove default="" attributes default = False uniques = xmltree.findall('uniqueid') for element in uniques: if not element.attrib.get('default'): changed |= None is not element.attrib.pop( 'default', None) else: default = True if len(uniques) and not default: xmltree.find( 'uniqueid').attrib['default'] = 'true' changed = True # remove redundant duplicate tags root = xmltree.getroot() for element in xmltree.findall( 'premiered')[1:]: root.remove(element) changed = True if changed: sg_helpers.indent_xml(root) sg_helpers.write_file(nfo_path, xmltree, xmltree=True, utf8=True) except (BaseException, Exception): pass # episodes episodes = cur_show_obj.get_all_episodes( has_location=True) for cur_ep_obj in episodes: try: changed = False nfo_path = kodi.get_episode_file_path( cur_ep_obj) if nfo_path and ek.ek(os.path.isfile, nfo_path): with ek.ek( io.open, nfo_path, 'r', encoding='utf8') as xml_file_obj: xmltree = etree.ElementTree( file=xml_file_obj) # remove default="" attributes default = False ratings = xmltree.find('ratings') r = None is not ratings and ratings.findall( 'rating') or [] for element in r: if not element.attrib.get('default'): changed |= None is not element.attrib.pop( 'default', None) else: default = True if len(r) and not default: ratings.find('rating').attrib[ 'default'] = 'true' changed = True if changed: sg_helpers.indent_xml(xmltree.getroot()) sg_helpers.write_file(nfo_path, xmltree, xmltree=True, utf8=True) except (BaseException, Exception): pass except (BaseException, Exception): pass db.DBConnection().set_flag('kodi_nfo_default_removed') sickbeard.classes.loading_msg.set_msg_progress(msg, '100%') except (BaseException, Exception): pass
def _ep_data(self, ep_obj): # type: (sickbeard.tv.TVEpisode) -> Optional[Union[bool, etree.Element]] """ Creates an elementTree XML structure for a WDTV style episode.xml and returns the resulting data object. ep_obj: a TVShow instance to create the NFO for """ ep_obj_list_to_write = [ep_obj] + ep_obj.related_ep_obj show_lang = ep_obj.show_obj.lang try: tvinfo_config = sickbeard.TVInfoAPI( ep_obj.show_obj.tvid).api_params.copy() tvinfo_config['actors'] = True if show_lang and not 'en' == show_lang: tvinfo_config['language'] = show_lang if 0 != ep_obj.show_obj.dvdorder: tvinfo_config['dvdorder'] = True t = sickbeard.TVInfoAPI( ep_obj.show_obj.tvid).setup(**tvinfo_config) show_info = t[ep_obj.show_obj.prodid] except BaseTVinfoShownotfound as e: raise exceptions_helper.ShowNotFoundException(ex(e)) except BaseTVinfoError as e: logger.log( "Unable to connect to %s while creating meta files - skipping - %s" % (sickbeard.TVInfoAPI(ep_obj.show_obj.tvid).name, ex(e)), logger.ERROR) return False if not self._valid_show(show_info, ep_obj.show_obj): return rootNode = etree.Element("details") data = None # write an WDTV XML containing info for all matching episodes for cur_ep_obj in ep_obj_list_to_write: try: ep_info = show_info[cur_ep_obj.season][cur_ep_obj.episode] except (BaseException, Exception): logger.log( "Unable to find episode %sx%s on %s... has it been removed? Should I delete from db?" % (cur_ep_obj.season, cur_ep_obj.episode, sickbeard.TVInfoAPI(ep_obj.show_obj.tvid).name)) return None if None is getattr(ep_info, 'firstaired', None) and 0 == ep_obj.season: ep_info["firstaired"] = str(datetime.date.fromordinal(1)) if None is getattr(ep_info, 'episodename', None) or None is getattr( ep_info, 'firstaired', None): return None if 1 < len(ep_obj_list_to_write): episode = etree.SubElement(rootNode, "details") else: episode = rootNode episodeID = etree.SubElement(episode, "id") episodeID.text = str(cur_ep_obj.epid) title = etree.SubElement(episode, "title") title.text = '%s' % ep_obj.pretty_name() seriesName = etree.SubElement(episode, "series_name") if None is not getattr(show_info, 'seriesname', None): seriesName.text = '%s' % show_info["seriesname"] episodeName = etree.SubElement(episode, "episode_name") if None is not cur_ep_obj.name: episodeName.text = '%s' % cur_ep_obj.name seasonNumber = etree.SubElement(episode, "season_number") seasonNumber.text = str(cur_ep_obj.season) episodeNum = etree.SubElement(episode, "episode_number") episodeNum.text = str(cur_ep_obj.episode) firstAired = etree.SubElement(episode, "firstaired") if cur_ep_obj.airdate != datetime.date.fromordinal(1): firstAired.text = str(cur_ep_obj.airdate) year = etree.SubElement(episode, "year") year_text = self.get_show_year(ep_obj.show_obj, show_info) if year_text: year.text = '%s' % year_text runtime = etree.SubElement(episode, "runtime") if 0 != cur_ep_obj.season: if None is not getattr(show_info, 'runtime', None): runtime.text = '%s' % show_info["runtime"] genre = etree.SubElement(episode, "genre") if None is not getattr(show_info, 'genre', None): genre.text = " / ".join( [x for x in show_info["genre"].split('|') if x]) director = etree.SubElement(episode, "director") director_text = getattr(ep_info, 'director', None) if None is not director_text: director.text = '%s' % director_text for actor in getattr(show_info, 'actors', []): cur_actor = etree.SubElement(episode, 'actor') cur_actor_name = etree.SubElement(cur_actor, 'name') cur_actor_name.text = '%s' % actor['person']['name'] cur_actor_role = etree.SubElement(cur_actor, 'role') cur_actor_role_text = '%s' % actor['character']['name'] if cur_actor_role_text: cur_actor_role.text = '%s' % cur_actor_role_text overview = etree.SubElement(episode, "overview") if None is not cur_ep_obj.description: overview.text = '%s' % cur_ep_obj.description # Make it purdy sg_helpers.indent_xml(rootNode) data = etree.ElementTree(rootNode) return data
def _show_data(self, show_obj): # type: (sickbeard.tv.TVShow) -> Optional[Union[bool, etree.Element]] """ Creates an elementTree XML structure for a MediaBrowser-style series.xml returns the resulting data object. show_obj: a TVShow instance to create the NFO for """ show_lang = show_obj.lang tvinfo_config = sickbeard.TVInfoAPI(show_obj.tvid).api_params.copy() tvinfo_config['actors'] = True if show_lang and not 'en' == show_lang: tvinfo_config['language'] = show_lang if 0 != show_obj.dvdorder: tvinfo_config['dvdorder'] = True t = sickbeard.TVInfoAPI(show_obj.tvid).setup(**tvinfo_config) rootNode = etree.Element('details') tv_node = etree.SubElement(rootNode, 'movie') tv_node.attrib['isExtra'] = 'false' tv_node.attrib['isSet'] = 'false' tv_node.attrib['isTV'] = 'true' try: show_info = t[int(show_obj.prodid)] except BaseTVinfoShownotfound as e: logger.log( u'Unable to find show with id ' + str(show_obj.prodid) + ' on tvdb, skipping it', logger.ERROR) raise e except BaseTVinfoError as e: logger.log(u'TVDB is down, can\'t use its data to make the NFO', logger.ERROR) raise e if not self._valid_show(show_info, show_obj): return # check for title and id try: if None is show_info['seriesname'] \ or '' == show_info['seriesname'] \ or None is show_info['id'] \ or '' == show_info['id']: logger.log( 'Incomplete info for show with id %s on %s, skipping it' % (show_obj.prodid, sickbeard.TVInfoAPI(show_obj.tvid).name), logger.ERROR) return False except BaseTVinfoAttributenotfound: logger.log( 'Incomplete info for show with id %s on %s, skipping it' % (show_obj.prodid, sickbeard.TVInfoAPI(show_obj.tvid).name), logger.ERROR) return False SeriesName = etree.SubElement(tv_node, 'title') if None is not show_info['seriesname']: SeriesName.text = '%s' % show_info['seriesname'] else: SeriesName.text = '' Genres = etree.SubElement(tv_node, 'genres') if None is not show_info['genre']: for genre in show_info['genre'].split('|'): if genre and genre.strip(): cur_genre = etree.SubElement(Genres, 'Genre') cur_genre.text = '%s' % genre.strip() FirstAired = etree.SubElement(tv_node, 'premiered') if None is not show_info['firstaired']: FirstAired.text = '%s' % show_info['firstaired'] year = etree.SubElement(tv_node, 'year') year_text = self.get_show_year(show_obj, show_info) if year_text: year.text = '%s' % year_text if None is not show_info['rating']: try: rating = int((float(show_info['rating']) * 10)) except ValueError: rating = 0 Rating = etree.SubElement(tv_node, 'rating') rating_text = str(rating) if None is not rating_text: Rating.text = '%s' % rating_text Status = etree.SubElement(tv_node, 'status') if None is not show_info['status']: Status.text = '%s' % show_info['status'] mpaa = etree.SubElement(tv_node, 'mpaa') if None is not show_info['contentrating']: mpaa.text = '%s' % show_info['contentrating'] IMDB_ID = etree.SubElement(tv_node, 'id') if None is not show_info['imdb_id']: IMDB_ID.attrib['moviedb'] = 'imdb' IMDB_ID.text = '%s' % show_info['imdb_id'] prodid = etree.SubElement(tv_node, 'indexerid') if None is not show_info['id']: prodid.text = '%s' % show_info['id'] Runtime = etree.SubElement(tv_node, 'runtime') if None is not show_info['runtime']: Runtime.text = '%s' % show_info['runtime'] cast = etree.SubElement(tv_node, 'cast') self.add_actor_element(show_info, etree, cast) sg_helpers.indent_xml(rootNode) data = etree.ElementTree(rootNode) return data
def _ep_data(self, ep_obj): # type: (sickbeard.tv.TVEpisode) -> Optional[Union[bool, etree.Element]] """ Creates an elementTree XML structure for a MediaBrowser style episode.xml and returns the resulting data object. show_obj: a TVShow instance to create the NFO for """ ep_obj_list_to_write = [ep_obj] + ep_obj.related_ep_obj show_lang = ep_obj.show_obj.lang try: # There's gotta be a better way of doing this but we don't wanna # change the language value elsewhere tvinfo_config = sickbeard.TVInfoAPI( ep_obj.show_obj.tvid).api_params.copy() if show_lang and not 'en' == show_lang: tvinfo_config['language'] = show_lang if 0 != ep_obj.show_obj.dvdorder: tvinfo_config['dvdorder'] = True t = sickbeard.TVInfoAPI( ep_obj.show_obj.tvid).setup(**tvinfo_config) show_info = t[ep_obj.show_obj.prodid] except BaseTVinfoShownotfound as e: raise exceptions_helper.ShowNotFoundException(ex(e)) except BaseTVinfoError as e: logger.log( 'Unable to connect to %s while creating meta files - skipping - %s' % (sickbeard.TVInfoAPI(ep_obj.show_obj.tvid).name, ex(e)), logger.ERROR) return False if not self._valid_show(show_info, ep_obj.show_obj): return rootNode = etree.Element('details') movie = etree.SubElement(rootNode, 'movie') movie.attrib['isExtra'] = 'false' movie.attrib['isSet'] = 'false' movie.attrib['isTV'] = 'true' # write an MediaBrowser XML containing info for all matching episodes for cur_ep_obj in ep_obj_list_to_write: try: ep_info = show_info[cur_ep_obj.season][cur_ep_obj.episode] except (BaseException, Exception): logger.log( u'Unable to find episode %sx%s on tvdb... has it been removed? Should I delete from db?' % (cur_ep_obj.season, cur_ep_obj.episode)) return None if cur_ep_obj == ep_obj: # root (or single) episode # default to today's date for specials if firstaired is not set if None is ep_info['firstaired'] and 0 == ep_obj.season: ep_info['firstaired'] = str(datetime.date.fromordinal(1)) if None is ep_info['episodename'] or None is ep_info[ 'firstaired']: return None episode = movie EpisodeName = etree.SubElement(episode, 'title') if None is not cur_ep_obj.name: EpisodeName.text = '%s' % cur_ep_obj.name else: EpisodeName.text = '' SeasonNumber = etree.SubElement(episode, 'season') SeasonNumber.text = str(cur_ep_obj.season) EpisodeNumber = etree.SubElement(episode, 'episode') EpisodeNumber.text = str(ep_obj.episode) year = etree.SubElement(episode, 'year') year_text = self.get_show_year(ep_obj.show_obj, show_info) if year_text: year.text = '%s' % year_text plot = etree.SubElement(episode, 'plot') if None is not show_info['overview']: plot.text = '%s' % show_info['overview'] Overview = etree.SubElement(episode, 'episodeplot') if None is not cur_ep_obj.description: Overview.text = '%s' % cur_ep_obj.description else: Overview.text = '' mpaa = etree.SubElement(episode, 'mpaa') if None is not show_info['contentrating']: mpaa.text = '%s' % show_info['contentrating'] if not ep_obj.related_ep_obj: if None is not ep_info['rating']: try: rating = int((float(ep_info['rating']) * 10)) except ValueError: rating = 0 Rating = etree.SubElement(episode, 'rating') rating_text = str(rating) if None is not rating_text: Rating.text = '%s' % rating_text director = etree.SubElement(episode, 'director') director_text = ep_info['director'] if None is not director_text: director.text = '%s' % director_text credits = etree.SubElement(episode, 'credits') credits_text = ep_info['writer'] if None is not credits_text: credits.text = '%s' % credits_text cast = etree.SubElement(episode, 'cast') self.add_actor_element(show_info, etree, cast) else: # append data from (if any) related episodes if cur_ep_obj.name: if not EpisodeName.text: EpisodeName.text = '%s' % cur_ep_obj.name else: EpisodeName.text = '%s, %s' % (EpisodeName.text, cur_ep_obj.name) if cur_ep_obj.description: if not Overview.text: Overview.text = '%s' % cur_ep_obj.description else: Overview.text = '%s\r%s' % (Overview.text, cur_ep_obj.description) sg_helpers.indent_xml(rootNode) data = etree.ElementTree(rootNode) return data
def _ep_data(self, ep_obj): # type: (sickbeard.tv.TVEpisode) -> Optional[Union[bool, etree.Element]] """ Creates an elementTree XML structure for a MediaBrowser style episode.xml and returns the resulting data object. show_obj: a TVShow instance to create the NFO for """ ep_obj_list_to_write = [ep_obj] + ep_obj.related_ep_obj persons_dict = {'Director': [], 'GuestStar': [], 'Writer': []} show_lang = ep_obj.show_obj.lang try: tvinfo_config = sickbeard.TVInfoAPI(ep_obj.show_obj.tvid).api_params.copy() tvinfo_config['actors'] = True if show_lang and not 'en' == show_lang: tvinfo_config['language'] = show_lang if 0 != ep_obj.show_obj.dvdorder: tvinfo_config['dvdorder'] = True t = sickbeard.TVInfoAPI(ep_obj.show_obj.tvid).setup(**tvinfo_config) show_info = t[ep_obj.show_obj.prodid] except BaseTVinfoShownotfound as e: raise exceptions_helper.ShowNotFoundException(ex(e)) except BaseTVinfoError as e: logger.log("Unable to connect to %s while creating meta files - skipping - %s" % (sickbeard.TVInfoAPI(ep_obj.show_obj.tvid).name, ex(e)), logger.ERROR) return False if not self._valid_show(show_info, ep_obj.show_obj): return rootNode = etree.Element("Item") # write an MediaBrowser XML containing info for all matching episodes for cur_ep_obj in ep_obj_list_to_write: try: ep_info = show_info[cur_ep_obj.season][cur_ep_obj.episode] except (BaseException, Exception): logger.log("Unable to find episode %sx%s on %s.. has it been removed? Should I delete from db?" % (cur_ep_obj.season, cur_ep_obj.episode, sickbeard.TVInfoAPI(ep_obj.show_obj.tvid).name)) return None if cur_ep_obj == ep_obj: # root (or single) episode # default to today's date for specials if firstaired is not set if None is getattr(ep_info, 'firstaired', None) and 0 == ep_obj.season: ep_info['firstaired'] = str(datetime.date.fromordinal(1)) if None is getattr(ep_info, 'episodename', None) or None is getattr(ep_info, 'firstaired', None): return None episode = rootNode EpisodeName = etree.SubElement(episode, "EpisodeName") if None is not cur_ep_obj.name: EpisodeName.text = '%s' % cur_ep_obj.name else: EpisodeName.text = "" EpisodeNumber = etree.SubElement(episode, "EpisodeNumber") EpisodeNumber.text = str(ep_obj.episode) if ep_obj.related_ep_obj: EpisodeNumberEnd = etree.SubElement(episode, "EpisodeNumberEnd") EpisodeNumberEnd.text = str(cur_ep_obj.episode) SeasonNumber = etree.SubElement(episode, "SeasonNumber") SeasonNumber.text = str(cur_ep_obj.season) if not ep_obj.related_ep_obj: absolute_number = etree.SubElement(episode, "absolute_number") if None is not getattr(ep_info, 'absolute_number', None): absolute_number.text = '%s' % ep_info['absolute_number'] FirstAired = etree.SubElement(episode, "FirstAired") if cur_ep_obj.airdate != datetime.date.fromordinal(1): FirstAired.text = str(cur_ep_obj.airdate) else: FirstAired.text = "" MetadataType = etree.SubElement(episode, "Type") MetadataType.text = "Episode" Overview = etree.SubElement(episode, "Overview") if None is not cur_ep_obj.description: Overview.text = '%s' % cur_ep_obj.description else: Overview.text = "" if not ep_obj.related_ep_obj: Rating = etree.SubElement(episode, "Rating") if None is not getattr(ep_info, 'rating', None): Rating.text = '%s' % ep_info['rating'] IMDB_ID = etree.SubElement(episode, "IMDB_ID") IMDB = etree.SubElement(episode, "IMDB") IMDbId = etree.SubElement(episode, "IMDbId") if None is not getattr(show_info, 'imdb_id', None): IMDB_ID.text = '%s' % show_info['imdb_id'] IMDB.text = '%s' % show_info['imdb_id'] IMDbId.text = '%s' % show_info['imdb_id'] prodid = etree.SubElement(episode, "id") prodid.text = str(cur_ep_obj.show_obj.prodid) tvid = etree.SubElement(episode, "indexer") tvid.text = str(cur_ep_obj.show_obj.tvid) Persons = etree.SubElement(episode, "Persons") Language = etree.SubElement(episode, "Language") try: Language.text = '%s' % cur_ep_obj.show_obj.lang except (BaseException, Exception): Language.text = 'en' # tvrage api doesn't provide language so we must assume a value here thumb = etree.SubElement(episode, "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 = '%s' % thumb_text else: # append data from (if any) related episodes EpisodeNumberEnd.text = str(cur_ep_obj.episode) if cur_ep_obj.name: if not EpisodeName.text: EpisodeName.text = '%s' % cur_ep_obj.name else: EpisodeName.text = '%s, %s' % (EpisodeName.text, cur_ep_obj.name) if cur_ep_obj.description: if not Overview.text: Overview.text = '%s' % cur_ep_obj.description else: Overview.text = '%s\r%s' % (Overview.text, cur_ep_obj.description) # collect all directors, guest stars and writers if None is not getattr(ep_info, 'director', None): persons_dict['Director'] += [x.strip() for x in ep_info['director'].split('|') if x] if None is not getattr(ep_info, 'gueststars', None): persons_dict['GuestStar'] += [x.strip() for x in ep_info['gueststars'].split('|') if x] if None is not getattr(ep_info, 'writer', None): persons_dict['Writer'] += [x.strip() for x in ep_info['writer'].split('|') if x] # 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, "Person") cur_person_name = etree.SubElement(Person, "Name") cur_person_name.text = '%s' % cur_name cur_person_type = etree.SubElement(Person, "Type") cur_person_type.text = '%s' % person_type sg_helpers.indent_xml(rootNode) data = etree.ElementTree(rootNode) return data
def _show_data(self, show_obj): # type: (sickbeard.tv.TVShow) -> Optional[Union[bool, etree.Element]] """ Creates an elementTree XML structure for a MediaBrowser-style series.xml returns the resulting data object. show_obj: a TVShow instance to create the NFO for """ show_lang = show_obj.lang # There's gotta be a better way of doing this but we don't wanna # change the language value elsewhere tvinfo_config = sickbeard.TVInfoAPI(show_obj.tvid).api_params.copy() tvinfo_config['actors'] = True if show_lang and not 'en' == show_lang: tvinfo_config['language'] = show_lang if 0 != show_obj.dvdorder: tvinfo_config['dvdorder'] = True t = sickbeard.TVInfoAPI(show_obj.tvid).setup(**tvinfo_config) tv_node = etree.Element("Series") try: show_info = t[int(show_obj.prodid)] except BaseTVinfoShownotfound as e: logger.log("Unable to find show with id %s on %s, skipping it" % (show_obj.prodid, sickbeard.TVInfoAPI(show_obj.tvid).name), logger.ERROR) raise e except BaseTVinfoError as e: logger.log("%s is down, can't use its data to make the NFO" % sickbeard.TVInfoAPI(show_obj.tvid).name, logger.ERROR) raise e if not self._valid_show(show_info, show_obj): return # check for title and id if None is getattr(show_info, 'seriesname', None) or None is getattr(show_info, 'id', None): logger.log("Incomplete info for show with id %s on %s, skipping it" % (show_obj.prodid, sickbeard.TVInfoAPI(show_obj.tvid).name), logger.ERROR) return False prodid = etree.SubElement(tv_node, "id") if None is not getattr(show_info, 'id', None): prodid.text = str(show_info['id']) tvid = etree.SubElement(tv_node, "indexer") if None is not show_obj.tvid: tvid.text = str(show_obj.tvid) SeriesName = etree.SubElement(tv_node, "SeriesName") if None is not getattr(show_info, 'seriesname', None): SeriesName.text = '%s' % show_info['seriesname'] Status = etree.SubElement(tv_node, "Status") if None is not getattr(show_info, 'status', None): Status.text = '%s' % show_info['status'] Network = etree.SubElement(tv_node, "Network") if None is not getattr(show_info, 'network', None): Network.text = '%s' % show_info['network'] Airs_Time = etree.SubElement(tv_node, "Airs_Time") if None is not getattr(show_info, 'airs_time', None): Airs_Time.text = '%s' % show_info['airs_time'] Airs_DayOfWeek = etree.SubElement(tv_node, "Airs_DayOfWeek") if None is not getattr(show_info, 'airs_dayofweek', None): Airs_DayOfWeek.text = '%s' % show_info['airs_dayofweek'] FirstAired = etree.SubElement(tv_node, "FirstAired") if None is not getattr(show_info, 'firstaired', None): FirstAired.text = '%s' % show_info['firstaired'] ContentRating = etree.SubElement(tv_node, "ContentRating") MPAARating = etree.SubElement(tv_node, "MPAARating") certification = etree.SubElement(tv_node, "certification") if None is not getattr(show_info, 'contentrating', None): ContentRating.text = '%s' % show_info['contentrating'] MPAARating.text = '%s' % show_info['contentrating'] certification.text = '%s' % show_info['contentrating'] MetadataType = etree.SubElement(tv_node, "Type") MetadataType.text = "Series" Overview = etree.SubElement(tv_node, "Overview") if None is not getattr(show_info, 'overview', None): Overview.text = '%s' % show_info['overview'] PremiereDate = etree.SubElement(tv_node, "PremiereDate") if None is not getattr(show_info, 'firstaired', None): PremiereDate.text = '%s' % show_info['firstaired'] Rating = etree.SubElement(tv_node, "Rating") if None is not getattr(show_info, 'rating', None): Rating.text = '%s' % show_info['rating'] ProductionYear = etree.SubElement(tv_node, "ProductionYear") year_text = self.get_show_year(show_obj, show_info) if year_text: ProductionYear.text = '%s' % year_text RunningTime = etree.SubElement(tv_node, "RunningTime") Runtime = etree.SubElement(tv_node, "Runtime") if None is not getattr(show_info, 'runtime', None): RunningTime.text = '%s' % show_info['runtime'] Runtime.text = '%s' % show_info['runtime'] IMDB_ID = etree.SubElement(tv_node, "IMDB_ID") IMDB = etree.SubElement(tv_node, "IMDB") IMDbId = etree.SubElement(tv_node, "IMDbId") if None is not getattr(show_info, 'imdb_id', None): IMDB_ID.text = '%s' % show_info['imdb_id'] IMDB.text = '%s' % show_info['imdb_id'] IMDbId.text = '%s' % show_info['imdb_id'] Zap2ItId = etree.SubElement(tv_node, "Zap2ItId") if None is not getattr(show_info, 'zap2it_id', None): Zap2ItId.text = '%s' % show_info['zap2it_id'] Genres = etree.SubElement(tv_node, "Genres") for genre in show_info['genre'].split('|'): if genre: cur_genre = etree.SubElement(Genres, "Genre") cur_genre.text = '%s' % genre Genre = etree.SubElement(tv_node, "Genre") if None is not getattr(show_info, 'genre', None): Genre.text = "|".join([x for x in show_info["genre"].split('|') if x]) Studios = etree.SubElement(tv_node, "Studios") Studio = etree.SubElement(Studios, "Studio") if None is not getattr(show_info, 'network', None): Studio.text = '%s' % show_info['network'] Persons = etree.SubElement(tv_node, 'Persons') for actor in getattr(show_info, 'actors', []): cur_actor = etree.SubElement(Persons, 'Person') cur_actor_name = etree.SubElement(cur_actor, 'Name') cur_actor_name.text = '%s' % actor['person']['name'] cur_actor_type = etree.SubElement(cur_actor, 'Type') cur_actor_type.text = 'Actor' cur_actor_role = etree.SubElement(cur_actor, 'Role') cur_actor_role_text = '%s' % actor['character']['name'] if cur_actor_role_text: cur_actor_role.text = '%s' % cur_actor_role_text sg_helpers.indent_xml(tv_node) data = etree.ElementTree(tv_node) return data