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; }