void CVideoInfoTag::ParseNative(const TiXmlElement* movie, bool prioritise) { std::string value; float fValue; if (XMLUtils::GetString(movie, "title", value)) SetTitle(value); if (XMLUtils::GetString(movie, "originaltitle", value)) SetOriginalTitle(value); if (XMLUtils::GetString(movie, "showtitle", value)) SetShowTitle(value); if (XMLUtils::GetString(movie, "sorttitle", value)) SetSortTitle(value); const TiXmlElement* node = movie->FirstChildElement("ratings"); if (node) { for (const TiXmlElement* child = node->FirstChildElement("rating"); child != nullptr; child = child->NextSiblingElement("rating")) { CRating r; std::string name; if (child->QueryStringAttribute("name", &name) != TIXML_SUCCESS) name = "default"; XMLUtils::GetFloat(child, "value", r.rating); XMLUtils::GetInt(child, "votes", r.votes); int max_value = 10; if ((child->QueryIntAttribute("max", &max_value) == TIXML_SUCCESS) && max_value >= 1) r.rating = r.rating / max_value * 10; // Normalise the Movie Rating to between 1 and 10 SetRating(r, name); bool isDefault = false; if ((child->QueryBoolAttribute("default", &isDefault) == TIXML_SUCCESS) && isDefault) m_strDefaultRating = name; } } else if (XMLUtils::GetFloat(movie, "rating", fValue)) { CRating r(fValue, 0); if (XMLUtils::GetString(movie, "votes", value)) r.votes = StringUtils::ReturnDigits(value); int max_value = 10; const TiXmlElement* rElement = movie->FirstChildElement("rating"); if (rElement && (rElement->QueryIntAttribute("max", &max_value) == TIXML_SUCCESS) && max_value >= 1) r.rating = r.rating / max_value * 10; // Normalise the Movie Rating to between 1 and 10 SetRating(r, "default"); m_strDefaultRating = "default"; } XMLUtils::GetInt(movie, "userrating", m_iUserRating); const TiXmlElement *epbookmark = movie->FirstChildElement("episodebookmark"); if (epbookmark) { XMLUtils::GetDouble(epbookmark, "position", m_EpBookmark.timeInSeconds); const TiXmlElement *playerstate = epbookmark->FirstChildElement("playerstate"); if (playerstate) { const TiXmlElement *value = playerstate->FirstChildElement(); if (value) m_EpBookmark.playerState << *value; } } else XMLUtils::GetDouble(movie, "epbookmark", m_EpBookmark.timeInSeconds); int max_value = 10; const TiXmlElement* urElement = movie->FirstChildElement("userrating"); if (urElement && (urElement->QueryIntAttribute("max", &max_value) == TIXML_SUCCESS) && max_value >= 1) m_iUserRating = m_iUserRating / max_value * 10; // Normalise the user Movie Rating to between 1 and 10 XMLUtils::GetInt(movie, "top250", m_iTop250); XMLUtils::GetInt(movie, "season", m_iSeason); XMLUtils::GetInt(movie, "episode", m_iEpisode); XMLUtils::GetInt(movie, "track", m_iTrack); XMLUtils::GetInt(movie, "displayseason", m_iSpecialSortSeason); XMLUtils::GetInt(movie, "displayepisode", m_iSpecialSortEpisode); int after=0; XMLUtils::GetInt(movie, "displayafterseason",after); if (after > 0) { m_iSpecialSortSeason = after; m_iSpecialSortEpisode = 0x1000; // should be more than any realistic episode number } if (XMLUtils::GetString(movie, "outline", value)) SetPlotOutline(value); if (XMLUtils::GetString(movie, "plot", value)) SetPlot(value); if (XMLUtils::GetString(movie, "tagline", value)) SetTagLine(value); if (XMLUtils::GetString(movie, "runtime", value) && !value.empty()) m_duration = GetDurationFromMinuteString(StringUtils::Trim(value)); if (XMLUtils::GetString(movie, "mpaa", value)) SetMPAARating(value); XMLUtils::GetInt(movie, "playcount", m_playCount); XMLUtils::GetDate(movie, "lastplayed", m_lastPlayed); if (XMLUtils::GetString(movie, "file", value)) SetFile(value); if (XMLUtils::GetString(movie, "path", value)) SetPath(value); const TiXmlElement* uniqueid = movie->FirstChildElement("uniqueid"); if (uniqueid == nullptr) { if (XMLUtils::GetString(movie, "id", value)) SetUniqueID(value); } else { for (; uniqueid != nullptr; uniqueid = uniqueid->NextSiblingElement("uniqueid")) { if (uniqueid->FirstChild()) { if (uniqueid->QueryStringAttribute("type", &value) == TIXML_SUCCESS) SetUniqueID(uniqueid->FirstChild()->ValueStr(), value); else SetUniqueID(uniqueid->FirstChild()->ValueStr()); bool isDefault; if ((uniqueid->QueryBoolAttribute("default", &isDefault) == TIXML_SUCCESS) && isDefault) m_strDefaultUniqueID = value; } } } if (XMLUtils::GetString(movie, "filenameandpath", value)) SetFileNameAndPath(value); if (XMLUtils::GetDate(movie, "premiered", m_premiered)) { m_bHasPremiered = true; } else { int year; if (XMLUtils::GetInt(movie, "year", year)) SetYear(year); } if (XMLUtils::GetString(movie, "status", value)) SetStatus(value); if (XMLUtils::GetString(movie, "code", value)) SetProductionCode(value); XMLUtils::GetDate(movie, "aired", m_firstAired); if (XMLUtils::GetString(movie, "album", value)) SetAlbum(value); if (XMLUtils::GetString(movie, "trailer", value)) SetTrailer(value); if (XMLUtils::GetString(movie, "basepath", value)) SetBasePath(value); size_t iThumbCount = m_strPictureURL.m_url.size(); std::string xmlAdd = m_strPictureURL.m_xml; const TiXmlElement* thumb = movie->FirstChildElement("thumb"); while (thumb) { m_strPictureURL.ParseElement(thumb); if (prioritise) { std::string temp; temp << *thumb; xmlAdd = temp+xmlAdd; } thumb = thumb->NextSiblingElement("thumb"); } // prioritise thumbs from nfos if (prioritise && iThumbCount && iThumbCount != m_strPictureURL.m_url.size()) { rotate(m_strPictureURL.m_url.begin(), m_strPictureURL.m_url.begin()+iThumbCount, m_strPictureURL.m_url.end()); m_strPictureURL.m_xml = xmlAdd; } std::vector<std::string> genres(m_genre); if (XMLUtils::GetStringArray(movie, "genre", genres, prioritise, g_advancedSettings.m_videoItemSeparator)) SetGenre(genres); std::vector<std::string> country(m_country); if (XMLUtils::GetStringArray(movie, "country", country, prioritise, g_advancedSettings.m_videoItemSeparator)) SetCountry(country); std::vector<std::string> credits(m_writingCredits); if (XMLUtils::GetStringArray(movie, "credits", credits, prioritise, g_advancedSettings.m_videoItemSeparator)) SetWritingCredits(credits); std::vector<std::string> director(m_director); if (XMLUtils::GetStringArray(movie, "director", director, prioritise, g_advancedSettings.m_videoItemSeparator)) SetDirector(director); std::vector<std::string> showLink(m_showLink); if (XMLUtils::GetStringArray(movie, "showlink", showLink, prioritise, g_advancedSettings.m_videoItemSeparator)) SetShowLink(showLink); const TiXmlElement* namedSeason = movie->FirstChildElement("namedseason"); while (namedSeason != nullptr) { if (namedSeason->FirstChild() != nullptr) { int seasonNumber; std::string seasonName = namedSeason->FirstChild()->ValueStr(); if (!seasonName.empty() && namedSeason->Attribute("number", &seasonNumber) != nullptr) m_namedSeasons.insert(std::make_pair(seasonNumber, seasonName)); } namedSeason = namedSeason->NextSiblingElement("namedseason"); } // cast node = movie->FirstChildElement("actor"); if (node && node->FirstChild() && prioritise) m_cast.clear(); while (node) { const TiXmlNode *actor = node->FirstChild("name"); if (actor && actor->FirstChild()) { SActorInfo info; info.strName = actor->FirstChild()->Value(); if (XMLUtils::GetString(node, "role", value)) info.strRole = StringUtils::Trim(value); XMLUtils::GetInt(node, "order", info.order); const TiXmlElement* thumb = node->FirstChildElement("thumb"); while (thumb) { info.thumbUrl.ParseElement(thumb); thumb = thumb->NextSiblingElement("thumb"); } const char* clear=node->Attribute("clear"); if (clear && stricmp(clear,"true")) m_cast.clear(); m_cast.push_back(info); } node = node->NextSiblingElement("actor"); } // Pre-Jarvis NFO file: // <set>A set</set> if (XMLUtils::GetString(movie, "set", value)) SetSet(value); // Jarvis+: // <set><name>A set</name><overview>A set with a number of movies...</overview></set> node = movie->FirstChildElement("set"); if (node) { // No name, no set if (XMLUtils::GetString(node, "name", value)) { SetSet(value); if (XMLUtils::GetString(node, "overview", value)) SetSetOverview(value); } } std::vector<std::string> tags(m_tags); if (XMLUtils::GetStringArray(movie, "tag", tags, prioritise, g_advancedSettings.m_videoItemSeparator)) SetTags(tags); std::vector<std::string> studio(m_studio); if (XMLUtils::GetStringArray(movie, "studio", studio, prioritise, g_advancedSettings.m_videoItemSeparator)) SetStudio(studio); // artists std::vector<std::string> artist(m_artist); node = movie->FirstChildElement("artist"); if (node && node->FirstChild() && prioritise) artist.clear(); while (node) { const TiXmlNode* pNode = node->FirstChild("name"); const char* pValue=NULL; if (pNode && pNode->FirstChild()) pValue = pNode->FirstChild()->Value(); else if (node->FirstChild()) pValue = node->FirstChild()->Value(); if (pValue) { const char* clear=node->Attribute("clear"); if (clear && stricmp(clear,"true")==0) artist.clear(); std::vector<std::string> newArtists = StringUtils::Split(pValue, g_advancedSettings.m_videoItemSeparator); artist.insert(artist.end(), newArtists.begin(), newArtists.end()); } node = node->NextSiblingElement("artist"); } SetArtist(artist); node = movie->FirstChildElement("fileinfo"); if (node) { // Try to pull from fileinfo/streamdetails/[video|audio|subtitle] const TiXmlNode *nodeStreamDetails = node->FirstChild("streamdetails"); if (nodeStreamDetails) { const TiXmlNode *nodeDetail = NULL; while ((nodeDetail = nodeStreamDetails->IterateChildren("audio", nodeDetail))) { CStreamDetailAudio *p = new CStreamDetailAudio(); if (XMLUtils::GetString(nodeDetail, "codec", value)) p->m_strCodec = StringUtils::Trim(value); if (XMLUtils::GetString(nodeDetail, "language", value)) p->m_strLanguage = StringUtils::Trim(value); XMLUtils::GetInt(nodeDetail, "channels", p->m_iChannels); StringUtils::ToLower(p->m_strCodec); StringUtils::ToLower(p->m_strLanguage); m_streamDetails.AddStream(p); } nodeDetail = NULL; while ((nodeDetail = nodeStreamDetails->IterateChildren("video", nodeDetail))) { CStreamDetailVideo *p = new CStreamDetailVideo(); if (XMLUtils::GetString(nodeDetail, "codec", value)) p->m_strCodec = StringUtils::Trim(value); XMLUtils::GetFloat(nodeDetail, "aspect", p->m_fAspect); XMLUtils::GetInt(nodeDetail, "width", p->m_iWidth); XMLUtils::GetInt(nodeDetail, "height", p->m_iHeight); XMLUtils::GetInt(nodeDetail, "durationinseconds", p->m_iDuration); if (XMLUtils::GetString(nodeDetail, "stereomode", value)) p->m_strStereoMode = StringUtils::Trim(value); if (XMLUtils::GetString(nodeDetail, "language", value)) p->m_strLanguage = StringUtils::Trim(value); StringUtils::ToLower(p->m_strCodec); StringUtils::ToLower(p->m_strStereoMode); StringUtils::ToLower(p->m_strLanguage); m_streamDetails.AddStream(p); } nodeDetail = NULL; while ((nodeDetail = nodeStreamDetails->IterateChildren("subtitle", nodeDetail))) { CStreamDetailSubtitle *p = new CStreamDetailSubtitle(); if (XMLUtils::GetString(nodeDetail, "language", value)) p->m_strLanguage = StringUtils::Trim(value); StringUtils::ToLower(p->m_strLanguage); m_streamDetails.AddStream(p); } } m_streamDetails.DetermineBestStreams(); } /* if fileinfo */ const TiXmlElement *epguide = movie->FirstChildElement("episodeguide"); if (epguide) { // DEPRECIATE ME - support for old XML-encoded <episodeguide> blocks. if (epguide->FirstChild() && strnicmp("<episodeguide", epguide->FirstChild()->Value(), 13) == 0) m_strEpisodeGuide = epguide->FirstChild()->Value(); else { std::stringstream stream; stream << *epguide; m_strEpisodeGuide = stream.str(); } } // fanart const TiXmlElement *fanart = movie->FirstChildElement("fanart"); if (fanart) { // we prioritise mixed-mode nfo's with fanart set if (prioritise) { std::string temp; temp << *fanart; m_fanart.m_xml = temp+m_fanart.m_xml; } else m_fanart.m_xml << *fanart; m_fanart.Unpack(); } // resumePoint const TiXmlNode *resume = movie->FirstChild("resume"); if (resume) { XMLUtils::GetDouble(resume, "position", m_resumePoint.timeInSeconds); XMLUtils::GetDouble(resume, "total", m_resumePoint.totalTimeInSeconds); } XMLUtils::GetDateTime(movie, "dateadded", m_dateAdded); }
void CVideoInfoTag::ParseNative(const TiXmlElement* movie, bool prioritise) { std::string value; if (XMLUtils::GetString(movie, "title", value)) SetTitle(value); if (XMLUtils::GetString(movie, "originaltitle", value)) SetOriginalTitle(value); if (XMLUtils::GetString(movie, "showtitle", value)) SetShowTitle(value); if (XMLUtils::GetString(movie, "sorttitle", value)) SetSortTitle(value); XMLUtils::GetFloat(movie, "rating", m_fRating); XMLUtils::GetInt(movie, "userrating", m_iUserRating); XMLUtils::GetFloat(movie, "epbookmark", m_fEpBookmark); int max_value = 10; const TiXmlElement* rElement = movie->FirstChildElement("rating"); if (rElement && (rElement->QueryIntAttribute("max", &max_value) == TIXML_SUCCESS) && max_value>=1) { m_fRating = m_fRating / max_value * 10; // Normalise the Movie Rating to between 1 and 10 } const TiXmlElement* urElement = movie->FirstChildElement("userrating"); if (urElement && (urElement->QueryIntAttribute("max", &max_value) == TIXML_SUCCESS) && max_value >= 1) m_iUserRating = m_iUserRating / max_value * 10; // Normalise the user Movie Rating to between 1 and 10 XMLUtils::GetInt(movie, "year", m_iYear); XMLUtils::GetInt(movie, "top250", m_iTop250); XMLUtils::GetInt(movie, "season", m_iSeason); XMLUtils::GetInt(movie, "episode", m_iEpisode); XMLUtils::GetInt(movie, "track", m_iTrack); if (XMLUtils::GetString(movie, "uniqueid", value)) SetUniqueId(value); XMLUtils::GetInt(movie, "displayseason", m_iSpecialSortSeason); XMLUtils::GetInt(movie, "displayepisode", m_iSpecialSortEpisode); std::string strFlag; XMLUtils::GetString(movie,"specialflag", strFlag); if (strFlag == "seasonfinale") m_iSpecialFlag = EPISODE_FLAG_SEASON_FINALE; else if (strFlag == "seriesfinale") m_iSpecialFlag = EPISODE_FLAG_SERIES_FINALE; else m_iSpecialFlag = EPISODE_FLAG_NONE; int after=0; XMLUtils::GetInt(movie, "displayafterseason",after); if (after > 0) { m_iSpecialSortSeason = after; m_iSpecialSortEpisode = 0x1000; // should be more than any realistic episode number } if (XMLUtils::GetString(movie, "votes", value)) SetVotes(value); if (XMLUtils::GetString(movie, "outline", value)) SetPlotOutline(value); if (XMLUtils::GetString(movie, "plot", value)) SetPlot(value); if (XMLUtils::GetString(movie, "tagline", value)) SetTagLine(value); if (XMLUtils::GetString(movie, "runtime", value) && !value.empty()) m_duration = GetDurationFromMinuteString(StringUtils::Trim(value)); if (XMLUtils::GetString(movie, "mpaa", value)) SetMPAARating(value); XMLUtils::GetInt(movie, "playcount", m_playCount); XMLUtils::GetDate(movie, "lastplayed", m_lastPlayed); if (XMLUtils::GetString(movie, "file", value)) SetFile(value); if (XMLUtils::GetString(movie, "path", value)) SetPath(value); if (XMLUtils::GetString(movie, "id", value)) SetIMDBNumber(value); if (XMLUtils::GetString(movie, "filenameandpath", value)) SetFileNameAndPath(value); XMLUtils::GetDate(movie, "premiered", m_premiered); if (XMLUtils::GetString(movie, "status", value)) SetStatus(value); if (XMLUtils::GetString(movie, "code", value)) SetProductionCode(value); XMLUtils::GetDate(movie, "aired", m_firstAired); if (XMLUtils::GetString(movie, "album", value)) SetAlbum(value); if (XMLUtils::GetString(movie, "trailer", value)) SetTrailer(value); if (XMLUtils::GetString(movie, "basepath", value)) SetBasePath(value); size_t iThumbCount = m_strPictureURL.m_url.size(); std::string xmlAdd = m_strPictureURL.m_xml; const TiXmlElement* thumb = movie->FirstChildElement("thumb"); while (thumb) { m_strPictureURL.ParseElement(thumb); if (prioritise) { std::string temp; temp << *thumb; xmlAdd = temp+xmlAdd; } thumb = thumb->NextSiblingElement("thumb"); } // prioritise thumbs from nfos if (prioritise && iThumbCount && iThumbCount != m_strPictureURL.m_url.size()) { rotate(m_strPictureURL.m_url.begin(), m_strPictureURL.m_url.begin()+iThumbCount, m_strPictureURL.m_url.end()); m_strPictureURL.m_xml = xmlAdd; } std::vector<std::string> genres(m_genre); if (XMLUtils::GetStringArray(movie, "genre", genres, prioritise, g_advancedSettings.m_videoItemSeparator)) SetGenre(genres); std::vector<std::string> country(m_country); if (XMLUtils::GetStringArray(movie, "country", country, prioritise, g_advancedSettings.m_videoItemSeparator)) SetCountry(country); std::vector<std::string> credits(m_writingCredits); if (XMLUtils::GetStringArray(movie, "credits", credits, prioritise, g_advancedSettings.m_videoItemSeparator)) SetWritingCredits(credits); std::vector<std::string> director(m_director); if (XMLUtils::GetStringArray(movie, "director", director, prioritise, g_advancedSettings.m_videoItemSeparator)) SetDirector(director); std::vector<std::string> showLink(m_showLink); if (XMLUtils::GetStringArray(movie, "showlink", showLink, prioritise, g_advancedSettings.m_videoItemSeparator)) SetShowLink(showLink); // cast const TiXmlElement* node = movie->FirstChildElement("actor"); if (node && node->FirstChild() && prioritise) m_cast.clear(); while (node) { const TiXmlNode *actor = node->FirstChild("name"); if (actor && actor->FirstChild()) { SActorInfo info; info.strName = actor->FirstChild()->Value(); if (XMLUtils::GetString(node, "role", value)) info.strRole = StringUtils::Trim(value); XMLUtils::GetInt(node, "order", info.order); const TiXmlElement* thumb = node->FirstChildElement("thumb"); while (thumb) { info.thumbUrl.ParseElement(thumb); thumb = thumb->NextSiblingElement("thumb"); } const char* clear=node->Attribute("clear"); if (clear && stricmp(clear,"true")) m_cast.clear(); m_cast.push_back(info); } node = node->NextSiblingElement("actor"); } if (XMLUtils::GetString(movie, "set", value)) SetSet(value); std::vector<std::string> tags(m_tags); if (XMLUtils::GetStringArray(movie, "tag", tags, prioritise, g_advancedSettings.m_videoItemSeparator)) SetTags(tags); std::vector<std::string> studio(m_studio); if (XMLUtils::GetStringArray(movie, "studio", studio, prioritise, g_advancedSettings.m_videoItemSeparator)) SetStudio(studio); // artists std::vector<std::string> artist(m_artist); node = movie->FirstChildElement("artist"); if (node && node->FirstChild() && prioritise) artist.clear(); while (node) { const TiXmlNode* pNode = node->FirstChild("name"); const char* pValue=NULL; if (pNode && pNode->FirstChild()) pValue = pNode->FirstChild()->Value(); else if (node->FirstChild()) pValue = node->FirstChild()->Value(); if (pValue) { const char* clear=node->Attribute("clear"); if (clear && stricmp(clear,"true")==0) artist.clear(); std::vector<std::string> newArtists = StringUtils::Split(pValue, g_advancedSettings.m_videoItemSeparator); artist.insert(artist.end(), newArtists.begin(), newArtists.end()); } node = node->NextSiblingElement("artist"); } SetArtist(artist); node = movie->FirstChildElement("fileinfo"); if (node) { // Try to pull from fileinfo/streamdetails/[video|audio|subtitle] const TiXmlNode *nodeStreamDetails = node->FirstChild("streamdetails"); if (nodeStreamDetails) { const TiXmlNode *nodeDetail = NULL; while ((nodeDetail = nodeStreamDetails->IterateChildren("audio", nodeDetail))) { CStreamDetailAudio *p = new CStreamDetailAudio(); if (XMLUtils::GetString(nodeDetail, "codec", value)) p->m_strCodec = StringUtils::Trim(value); if (XMLUtils::GetString(nodeDetail, "language", value)) p->m_strLanguage = StringUtils::Trim(value); XMLUtils::GetInt(nodeDetail, "channels", p->m_iChannels); StringUtils::ToLower(p->m_strCodec); StringUtils::ToLower(p->m_strLanguage); m_streamDetails.AddStream(p); } nodeDetail = NULL; while ((nodeDetail = nodeStreamDetails->IterateChildren("video", nodeDetail))) { CStreamDetailVideo *p = new CStreamDetailVideo(); if (XMLUtils::GetString(nodeDetail, "codec", value)) p->m_strCodec = StringUtils::Trim(value); XMLUtils::GetFloat(nodeDetail, "aspect", p->m_fAspect); XMLUtils::GetInt(nodeDetail, "width", p->m_iWidth); XMLUtils::GetInt(nodeDetail, "height", p->m_iHeight); XMLUtils::GetInt(nodeDetail, "durationinseconds", p->m_iDuration); if (XMLUtils::GetString(nodeDetail, "stereomode", value)) p->m_strStereoMode = StringUtils::Trim(value); StringUtils::ToLower(p->m_strCodec); StringUtils::ToLower(p->m_strStereoMode); m_streamDetails.AddStream(p); } nodeDetail = NULL; while ((nodeDetail = nodeStreamDetails->IterateChildren("subtitle", nodeDetail))) { CStreamDetailSubtitle *p = new CStreamDetailSubtitle(); if (XMLUtils::GetString(nodeDetail, "language", value)) p->m_strLanguage = StringUtils::Trim(value); StringUtils::ToLower(p->m_strLanguage); m_streamDetails.AddStream(p); } } m_streamDetails.DetermineBestStreams(); } /* if fileinfo */ const TiXmlElement *epguide = movie->FirstChildElement("episodeguide"); if (epguide) { // DEPRECIATE ME - support for old XML-encoded <episodeguide> blocks. if (epguide->FirstChild() && strnicmp("<episodeguide", epguide->FirstChild()->Value(), 13) == 0) m_strEpisodeGuide = epguide->FirstChild()->Value(); else { std::stringstream stream; stream << *epguide; m_strEpisodeGuide = stream.str(); } } // fanart const TiXmlElement *fanart = movie->FirstChildElement("fanart"); if (fanart) { // we prioritise mixed-mode nfo's with fanart set if (prioritise) { std::string temp; temp << *fanart; m_fanart.m_xml = temp+m_fanart.m_xml; } else m_fanart.m_xml << *fanart; m_fanart.Unpack(); } // resumePoint const TiXmlNode *resume = movie->FirstChild("resume"); if (resume) { XMLUtils::GetDouble(resume, "position", m_resumePoint.timeInSeconds); XMLUtils::GetDouble(resume, "total", m_resumePoint.totalTimeInSeconds); } XMLUtils::GetDateTime(movie, "dateadded", m_dateAdded); }