// read and create items from a rss document void RssParser::parseFeed(const ParsingJob& job) { qDebug() << Q_FUNC_INFO << job.feedUrl << job.filePath; QFile fileRss(job.filePath); if (!fileRss.open(QIODevice::ReadOnly | QIODevice::Text)) { reportFailure(job, tr("Failed to open downloaded RSS file.")); return; } QXmlStreamReader xml(&fileRss); bool found_channel = false; while (xml.readNextStartElement()) { if (xml.name() == "rss") { // Find channels while (xml.readNextStartElement()) { if (xml.name() == "channel") { parseRSSChannel(xml, job.feedUrl); found_channel = true; break; } else { qDebug() << "Skip rss item: " << xml.name(); xml.skipCurrentElement(); } } break; } else if (xml.name() == "feed") { // Atom feed parseAtomChannel(xml, job.feedUrl); found_channel = true; break; } else { qDebug() << "Skip root item: " << xml.name(); xml.skipCurrentElement(); } } if (xml.hasError()) { reportFailure(job, xml.errorString()); return; } if (!found_channel) { reportFailure(job, tr("Invalid RSS feed at %1.").arg(job.feedUrl)); return; } // Clean up fileRss.close(); emit feedParsingFinished(job.feedUrl, QString()); fsutils::forceRemove(job.filePath); }
/* * Retrieves the distro RSS news feed from its respective site * If it fails to connect to the internet, uses the available "./.config/octopi/distro_rss.xml" * The result is a QString containing the RSS News Feed XML code */ QString MainWindow::retrieveDistroNews(bool searchForLatestNews) { const QString ctn_ARCH_LINUX_RSS = "https://www.archlinux.org/feeds/news/"; const QString ctn_CHAKRA_RSS = "http://chakra-project.org/news/index.php?/feeds/index.rss2"; const QString ctn_MANJARO_LINUX_RSS = "http://manjaro.org/feed/"; LinuxDistro distro = UnixCommand::getLinuxDistro(); QString res; QString tmpRssPath = QDir::homePath() + QDir::separator() + ".config/octopi/.tmp_distro_rss.xml"; QString rssPath = QDir::homePath() + QDir::separator() + ".config/octopi/distro_rss.xml"; QString contentsRss; QFile fileRss(rssPath); if (fileRss.exists()) { if (!fileRss.open(QIODevice::ReadOnly | QIODevice::Text)) res = ""; QTextStream in2(&fileRss); contentsRss = in2.readAll(); fileRss.close(); } if(searchForLatestNews && UnixCommand::hasInternetConnection() && distro != ectn_UNKNOWN) { QString curlCommand = "curl %1 -o %2"; if (distro == ectn_ARCHLINUX || distro == ectn_ARCHBANGLINUX) { curlCommand = curlCommand.arg(ctn_ARCH_LINUX_RSS).arg(tmpRssPath); } else if (distro == ectn_CHAKRA) { curlCommand = curlCommand.arg(ctn_CHAKRA_RSS).arg(tmpRssPath); } else if (distro == ectn_MANJAROLINUX) { curlCommand = curlCommand.arg(ctn_MANJARO_LINUX_RSS).arg(tmpRssPath); } if (UnixCommand::runCurlCommand(curlCommand).isEmpty()) { QFile fileTmpRss(tmpRssPath); QFile fileRss(rssPath); if (!fileRss.exists()) { fileTmpRss.rename(tmpRssPath, rssPath); if (!fileRss.open(QIODevice::ReadOnly | QIODevice::Text)) res = ""; QTextStream in2(&fileRss); contentsRss = in2.readAll(); fileRss.close(); res = contentsRss; } else { //A rss file already exists. We have to make a SHA1 hash to compare the contents QString tmpRssSHA1; QString rssSHA1; QString contentsTmpRss; QFile fileTmpRss(tmpRssPath); if (!fileTmpRss.open(QIODevice::ReadOnly | QIODevice::Text)) res = ""; QTextStream in(&fileTmpRss); contentsTmpRss = in.readAll(); fileTmpRss.close(); tmpRssSHA1 = QCryptographicHash::hash(contentsTmpRss.toAscii(), QCryptographicHash::Sha1); rssSHA1 = QCryptographicHash::hash(contentsRss.toAscii(), QCryptographicHash::Sha1); if (tmpRssSHA1 != rssSHA1){ fileRss.remove(); fileTmpRss.rename(tmpRssPath, rssPath); res = "*" + contentsTmpRss; //The asterisk indicates there is a MORE updated rss! } else { fileTmpRss.remove(); res = contentsRss; } } } } //Either we don't have internet or we weren't asked to retrieve the latest news else { QFile fileRss(rssPath); //Maybe we have a file in "./.config/octopi/distro_rss.xml" if (fileRss.exists()) { res = contentsRss; } else if (searchForLatestNews) { res = "<h3><font color=\"#E55451\">" + StrConstants::getInternetUnavailableError() + "</font></h3>"; } else if (distro != ectn_UNKNOWN) { res = "<h3><font color=\"#E55451\">" + StrConstants::getNewsErrorMessage() + "</font></h3>"; } else { res = "<h3><font color=\"#E55451\">" + StrConstants::getIncompatibleLinuxDistroError() + "</font></h3>"; } } return res; }