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 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 getSeasonNZBs(name, url_data, season): """ :param name: name :type name: AnyStr :param url_data: url data :type url_data: Any :param season: season :type season: int :return: :rtype: Tuple[Dict, AnyStr] """ try: showXML = etree.ElementTree(etree.XML(url_data)) except SyntaxError: logger.log(u'Unable to parse the XML of %s, not splitting it' % name, logger.ERROR) return {}, '' filename = name.replace('.nzb', '') nzbElement = showXML.getroot() regex = r'([\w\._\ ]+)[\._ ]S%02d[\._ ]([\w\._\-\ ]+)' % season sceneNameMatch = re.search(regex, filename, re.I) if sceneNameMatch: showName, qualitySection = sceneNameMatch.groups() else: logger.log( '%s - Not a valid season pack scene name. If it\'s a valid one, log a bug.' % name, logger.ERROR) return {}, '' regex = r'(%s[\._]S%02d(?:[E0-9]+)\.[\w\._]+)' % (re.escape(showName), season) regex = regex.replace(' ', '.') ep_files = {} xmlns = None for cur_file in list(nzbElement): if not isinstance(cur_file.tag, string_types): continue xmlns_match = re.match(r'[{](https?://[A-Za-z0-9_./]+/nzb)[}]file', cur_file.tag) if not xmlns_match: continue else: xmlns = xmlns_match.group(1) match = re.search(regex, cur_file.get("subject"), re.I) if not match: # print curFile.get("subject"), "doesn't match", regex continue cur_ep = match.group(1) fn = name_extractor(cur_file.get('subject', '')) if cur_ep == re.sub(r'\+\d+\.par2$', '', fn, flags=re.I): bn, ext = ek.ek(os.path.splitext, fn) cur_ep = re.sub(r'\.(part\d+|vol\d+(\+\d+)?)$', '', bn, flags=re.I) bn, ext = ek.ek(os.path.splitext, cur_ep) if isinstance(ext, string_types) \ and re.search(r'^\.(nzb|r\d{2}|rar|7z|zip|par2|vol\d+|nfo|srt|txt|bat|sh|mkv|mp4|avi|wmv)$', ext, flags=re.I): logger.log('Unable to split %s into episode nzb\'s' % name, logger.WARNING) return {}, '' if cur_ep not in ep_files: ep_files[cur_ep] = [cur_file] else: ep_files[cur_ep].append(cur_file) return ep_files, xmlns
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 retrieveShowMetadata(self, folder): # type: (AnyStr) -> Union[Tuple[int, int, AnyStr], Tuple[None, None, None]] """ Used only when mass adding Existing Shows, using previously generated Show metadata to reduce the need to query TVDB. """ from sickbeard.indexers.indexer_config import TVINFO_TVDB empty_return = (None, None, None) metadata_path = ek.ek(os.path.join, folder, self._show_metadata_filename) if not ek.ek(os.path.isdir, folder) or not ek.ek(os.path.isfile, metadata_path): logger.log(u"Can't load the metadata file from " + repr(metadata_path) + ", it doesn't exist", logger.DEBUG) return empty_return logger.log(u"Loading show info from metadata file in " + folder, logger.DEBUG) try: with ek.ek(io.open, metadata_path, 'r', encoding='utf8') as xmlFileObj: showXML = etree.ElementTree(file=xmlFileObj) if None is showXML.findtext('title') \ or (None is showXML.find('//uniqueid[@type="tvdb"]') and (None is showXML.findtext('tvdbid') and None is showXML.findtext('id')) and None is showXML.findtext('indexer')): logger.log(u"Invalid info in tvshow.nfo (missing name or id):" + str(showXML.findtext('title')) + ' ' + str(showXML.findtext('indexer')) + ' ' + str(showXML.findtext('tvdbid')) + ' ' + str(showXML.findtext('id'))) return empty_return name = showXML.findtext('title') try: tvid = int(showXML.findtext('indexer')) except (BaseException, Exception): tvid = None prodid = showXML.find('//uniqueid[@type="tvdb"]') if None is not prodid: prodid = int(prodid.text) tvid = TVINFO_TVDB elif None is not showXML.findtext('tvdbid'): prodid = int(showXML.findtext('tvdbid')) tvid = TVINFO_TVDB elif None is not showXML.findtext('id'): prodid = int(showXML.findtext('id')) try: tvid = TVINFO_TVDB if [s for s in showXML.findall('.//*') if s.text and -1 != s.text.find('thetvdb.com')] else tvid except (BaseException, Exception): pass else: logger.log(u"Empty <id> or <tvdbid> field in NFO, unable to find a ID", logger.WARNING) return empty_return if None is prodid: logger.log(u"Invalid Show ID (%s), not using metadata file" % prodid, logger.WARNING) return empty_return except (BaseException, Exception) as e: logger.log( u"There was an error parsing your existing metadata file: '" + metadata_path + "' error: " + ex(e), logger.WARNING) return empty_return return tvid, prodid, name
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 Exception as e: if check_exception_type(e, ExceptionTuples.tvinfo_shownotfound): raise exceptions_helper.ShowNotFoundException(ex(e)) elif check_exception_type(e, ExceptionTuples.tvinfo_error): 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 else: raise e 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 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 Exception as e: if check_exception_type(e, ExceptionTuples.tvinfo_shownotfound): 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 elif check_exception_type(e, ExceptionTuples.tvinfo_error): logger.log( "%s is down, can't use its data to make the NFO" % sickbeard.TVInfoAPI(show_obj.tvid).name, logger.ERROR) raise else: 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 helpers.indent_xml(tv_node) data = etree.ElementTree(tv_node) 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