Beispiel #1
0
void GeneralPage::GetLangList()
{
	if (m_languagesList.empty())
	{
		m_languagesList.insert(make_pair(L"English", "en-US.xml"));
		const StringList& l_files = File::findFiles(Util::getLocalisationPath(), "*-*.xml");
		for (auto i = l_files.cbegin(); i != l_files.cend(); ++i)
		{
			string l_langFileName = Util::getFileName(*i);
			if (!GetLangByFile(l_langFileName, m_languagesList))
			{
				XMLParser::XMLResults xRes;
				const XMLParser::XMLNode xRootNode = XMLParser::XMLNode::parseFile(Text::toT(*i).c_str(), 0, &xRes);
				if (xRes.error == XMLParser::eXMLErrorNone)
				{
					const XMLParser::XMLNode ResNode = xRootNode.getChildNode("Language");
					if (!ResNode.isEmpty())
					{
						m_languagesList.insert(make_pair(Text::toT(ResNode.getAttributeOrDefault("Name")), l_langFileName));
					}
				}
			}
		}
	}
}
bool
RSSFeed::UpdateFeedNewXML()
{
	time_t maxLastDate = 0;
	clearNewsList();
	string data;
	try
	{
		GetRSSData(feedURL, data);
		XMLParser::XMLResults xRes;
		XMLParser::XMLNode xRootNode = XMLParser::XMLNode::parseString(Text::toUtf8(data).c_str(), 0, &xRes);
		if (xRes.error == XMLParser::eXMLErrorNone)
		{
			string codeingType = codeing;
			if (codeingType.empty() && xRootNode.isAttributeSet("encoding"))
			{
				// "windows-1251" or "utf-8"
				codeingType = xRootNode.getAttributeOrDefault("encoding");
			}
			std::transform(codeingType.begin(), codeingType.end(), codeingType.begin(), ::tolower);
			bool isUtf8 = false;
			if (codeingType == "utf-8")
				isUtf8 = true;
				
			const RssFormat rssFormat = DetectRSSFormat(&xRootNode, XML_PARSER);
			
			switch (rssFormat)
			{
				case RSS_2_0:
					return ProcessRSS(&xRootNode, XML_PARSER, isUtf8);
				case RSS_ATOM:
					return ProcessAtom(&xRootNode, XML_PARSER, isUtf8);
			}
		}
		else
		{
			return UpdateFeedOldParser(data);
		}
		return false;
	}
	catch (const Exception& e)
	{
		LogManager::message(e.getError());
		return false;
	}
}
RSSFeed::RssFormat RSSFeed::DetectRSSFormat(void* data, RSSParser parser)
{
	if (parser == XML_PARSER)
	{
		XMLParser::XMLNode* rootNode = reinterpret_cast<XMLParser::XMLNode*>(data);
		if (rootNode != nullptr)
		{
			// Start Detection
			XMLParser::XMLNode rssNode = rootNode->getChildNode("rss");
			if (!rssNode.isEmpty())
			{
				return RSS_2_0;
			}
			XMLParser::XMLNode atomNode = rootNode->getChildNode("feed");
			if (!atomNode.isEmpty())
			{
				return RSS_ATOM;
			}
		}
	}
	else if (parser == XML_SIMPLE)
	{
		SimpleXML* xml = reinterpret_cast<SimpleXML*>(data);
		if (xml != nullptr)
		{
			if (xml->findChild("rss")) return RSS_2_0;
			if (xml->findChild("feed")) return RSS_ATOM;
		}
	}
	return RSS_2_0;
}
bool
RSSFeed::ProcessAtom(void* data, RSSParser parser, bool isUtf8)
{
	time_t maxLastDate = 0;
	if (parser == XML_PARSER)
	{
		XMLParser::XMLNode* rootNode = reinterpret_cast<XMLParser::XMLNode*>(data);
		if (rootNode != nullptr)
		{
			XMLParser::XMLNode feedNode = rootNode->getChildNode("feed");
			if (!feedNode.isEmpty())
			{
				// Search items
				int i = 0;
				XMLParser::XMLNode itemNode = feedNode.getChildNode("entry", &i);
				while (!itemNode.isEmpty())
				{
					string title;
					string url;
					string desc;
					time_t pubDate = 0;
					string author;
					string category;
					XMLParser::XMLNode titleNode = itemNode.getChildNode("title");
					if (!titleNode.isEmpty())
					{
						if (titleNode.nText())
							title = titleNode.getText();
						else if (titleNode.nClear())
							title = titleNode.getClear().lpszValue;
						if (isUtf8) title = Text::fromUtf8(title);
					}
					int j = 0;
					XMLParser::XMLNode linkNode = itemNode.getChildNode("link", &j);
					while (!linkNode.isEmpty())
					{
						if (linkNode.nAttribute() && linkNode.isAttributeSet("rel") && linkNode.isAttributeSet("href"))
						{
							string relation = linkNode.getAttribute("rel");
							if (relation == "alternate")
							{
								url = linkNode.getAttribute("href");
								// [!] SSA Can be problems
								if (isUtf8) url = Text::utf8ToAcp(Text::fromUtf8(url));
								break;
							}
						}
						linkNode = itemNode.getChildNode("link", &j);
					}
					XMLParser::XMLNode descNode = itemNode.getChildNode("content");
					if (!descNode.isEmpty())
					{
						if (descNode.nText())
							desc = descNode.getText();
						else if (descNode.nClear())
							desc = descNode.getClear().lpszValue;
						if (isUtf8) desc = Text::fromUtf8(desc);
					}
					XMLParser::XMLNode pubDateNode = itemNode.getChildNode("published");
					if (!pubDateNode.isEmpty())
					{
						string pDate;
						if (pubDateNode.nText())
							pDate = pubDateNode.getText();
						else if (pubDateNode.nClear())
							pDate = pubDateNode.getClear().lpszValue;
							
						if (pDate.length() > 0)
						{
							/*
							SYSTEMTIME pTime = {0};
							InternetTimeToSystemTimeA(pDate.c_str(), &pTime, 0);
							*/
							// Using format in atom 2012-08-20T11:57:53.000Z
							
							std::string date_string, tod_string;
							boost::date_time::split(pDate, 'T', date_string, tod_string);
							tod_string = tod_string.substr(0, 8) + ".000";
							
							boost::posix_time::time_duration td = boost::date_time::parse_delimited_time_duration<boost::posix_time::time_duration>(tod_string);
							
							tm l_tm = {0};
							///
							l_tm.tm_year = atoi(date_string.substr(0, 4).c_str()) - 1900;
							l_tm.tm_mon = atoi(date_string.substr(5, 2).c_str())  - 1;
							l_tm.tm_mday = atoi(date_string.substr(8, 2).c_str());
							
							l_tm.tm_hour = td.hours();
							l_tm.tm_min = td.minutes();
							l_tm.tm_sec = td.seconds();
							
							pubDate = mktime(&l_tm);
							
						}
					}
					XMLParser::XMLNode authorNode =  itemNode.getChildNode("author");
					if (!authorNode.isEmpty())
					{
						XMLParser::XMLNode authorName = authorNode.getChildNode("name");
						if (!authorName.isEmpty())
						{
							if (authorName.nText())
								author =  authorName.getText();
							else if (authorName.nClear())
								author = authorName.getClear().lpszValue;
							if (isUtf8) author = Text::fromUtf8(author);
						}
					}
					int k = 0;
					XMLParser::XMLNode categoryNode =  itemNode.getChildNode("category", &k);
					while (!categoryNode.isEmpty())
					{
						if (categoryNode.nAttribute())
						{
							if (categoryNode.isAttributeSet("term"))
							{
								if (!category.empty())
									category += ",";
								category += categoryNode.getAttribute("term");
							}
						}
						categoryNode =  itemNode.getChildNode("category", &k);
					}
					if (isUtf8) category = Text::fromUtf8(category);
					
					if (pubDate == 0 || lastNewsDate < pubDate)
					{
						if (pubDate > maxLastDate)
							maxLastDate = pubDate;
							
						RSSItem* item = new RSSItem(Util::ConvertFromHTML(title), url, Util::ConvertFromHTML(desc), pubDate, author, category, source);
						CFlyFastLock(csNews);
						m_newsList.push_back(item);
					}
					
					itemNode = feedNode.getChildNode("entry", &i);
				}
				if (maxLastDate > lastNewsDate)
					lastNewsDate = maxLastDate;
					
				CFlyFastLock(csNews);
				return !m_newsList.empty();
			}
		}
	}
	else if (parser == XML_SIMPLE)
	{
		// [!] SSA - todo if needed?
		SimpleXML* xml = reinterpret_cast<SimpleXML*>(data);
		if (xml != nullptr)
		{
		}
	}
	return false;
}
bool
RSSFeed::ProcessRSS(void* data, RSSParser parser, bool isUtf8)
{
	time_t maxLastDate = 0;
	if (parser == XML_PARSER)
	{
		XMLParser::XMLNode* rootNode = reinterpret_cast<XMLParser::XMLNode*>(data);
		if (rootNode != nullptr)
		{
			XMLParser::XMLNode rssNode = rootNode->getChildNode("rss");
			if (!rssNode.isEmpty())
			{
				XMLParser::XMLNode channelNode = rssNode.getChildNode("channel");
				if (!channelNode.isEmpty())
				{
					// Search items
					int i = 0;
					XMLParser::XMLNode itemNode = channelNode.getChildNode("item", &i);
					while (!itemNode.isEmpty())
					{
						string title;
						string url;
						string desc;
						time_t pubDate = 0;
						string author;
						string category;
						XMLParser::XMLNode titleNode = itemNode.getChildNode("title");
						if (!titleNode.isEmpty())
						{
							if (titleNode.nText())
								title = titleNode.getText();
							else if (titleNode.nClear())
								title = titleNode.getClear().lpszValue;
							if (isUtf8) title = Text::fromUtf8(title);
						}
						XMLParser::XMLNode linkNode = itemNode.getChildNode("link");
						if (!linkNode.isEmpty())
						{
							if (linkNode.nText())
								url = linkNode.getText();
							else if (linkNode.nClear())
								url = linkNode.getClear().lpszValue;
							// [!] SSA Can be problems
							if (isUtf8) url = Text::utf8ToAcp(Text::fromUtf8(url));
						}
						XMLParser::XMLNode descNode = itemNode.getChildNode("description");
						if (!descNode.isEmpty())
						{
							if (descNode.nText())
								desc = descNode.getText();
							else if (descNode.nClear())
								desc = descNode.getClear().lpszValue;
							if (isUtf8) desc = Text::fromUtf8(desc);
						}
						XMLParser::XMLNode pubDateNode = itemNode.getChildNode("pubDate");
						if (!pubDateNode.isEmpty())
						{
							string pDate;
							if (pubDateNode.nText())
								pDate = pubDateNode.getText();
							else if (pubDateNode.nClear())
								pDate = pubDateNode.getClear().lpszValue;
								
							pubDate = convertPubDate(pDate);
						}
						XMLParser::XMLNode authorNode =  itemNode.getChildNode("author");
						if (!authorNode.isEmpty())
						{
							if (authorNode.nText())
								author =  authorNode.getText();
							else if (authorNode.nClear())
								author = authorNode.getClear().lpszValue;
							if (isUtf8) author = Text::fromUtf8(author);
						}
						XMLParser::XMLNode categoryNode =  itemNode.getChildNode("category");
						if (!categoryNode.isEmpty())
						{
							if (categoryNode.nText())
								category = categoryNode.getText();
							else if (categoryNode.nClear())
								category = categoryNode.getClear().lpszValue;
							if (isUtf8) category = Text::fromUtf8(category);
						}
						
						if (pubDate == 0 || lastNewsDate < pubDate)
						{
							if (pubDate > maxLastDate)
								maxLastDate = pubDate;
								
							RSSItem* item = new RSSItem(Util::ConvertFromHTML(title), url, Util::ConvertFromHTML(desc), pubDate, author, category, source);
							CFlyFastLock(csNews);
							m_newsList.push_back(item);
						}
						
						itemNode = channelNode.getChildNode("item", &i);
					}
					if (maxLastDate > lastNewsDate)
						lastNewsDate = maxLastDate;
						
					CFlyFastLock(csNews);
					return !m_newsList.empty();
				}
			}
		}
	}
	else if (parser == XML_SIMPLE)
	{
		SimpleXML* xml = reinterpret_cast<SimpleXML*>(data);
		if (xml != nullptr)
		{
			xml->resetCurrentChild();
			
			if (xml->findChild("rss"))
			{
				xml->stepIn();
				if (xml->findChild("channel"))
				{
					xml->stepIn();
					while (xml->findChild("item"))
					{
						xml->stepIn();
						string title;
						string url;
						string desc;
						time_t pubDate = 0;
						string author;
						string category;
						if (xml->findChild("title"))
							removeCDATA(xml->getChildData(), title);
						xml->resetCurrentChild();
						if (xml->findChild("link"))
							removeCDATA(xml->getChildData(), url);
						xml->resetCurrentChild();
						if (xml->findChild("description"))
							removeCDATA(xml->getChildData(), desc);
						xml->resetCurrentChild();
						if (xml->findChild("pubDate"))
						{
							string pDate;
							removeCDATA(xml->getChildData(), pDate);
							pubDate = convertPubDate(pDate);
						}
						xml->resetCurrentChild();
						
						if (xml->findChild("author"))
							removeCDATA(xml->getChildData(), author);
						xml->resetCurrentChild();
						if (xml->findChild("category"))
							removeCDATA(xml->getChildData(), category);
						xml->resetCurrentChild();
						
						if (pubDate == 0 || lastNewsDate < pubDate)
						{
							if (pubDate > maxLastDate)
								maxLastDate = pubDate;
								
							RSSItem* item = new RSSItem(Util::ConvertFromHTML(title), url, desc, pubDate, author, category, source);
							CFlyFastLock(csNews);
							m_newsList.push_back(item);
						}
						xml->stepOut();
					}
				}
			}
			if (maxLastDate > lastNewsDate)
				lastNewsDate = maxLastDate;
				
			CFlyFastLock(csNews);
			return !m_newsList.empty();
		}
	}
	return false;
}