diff options
| author | Physick <96335032+DegustatorPonos@users.noreply.github.com> | 2026-05-10 18:06:16 +0500 |
|---|---|---|
| committer | Physick <96335032+DegustatorPonos@users.noreply.github.com> | 2026-05-10 18:06:16 +0500 |
| commit | 838eaa77fa389203a4c41751b36993575bbbfe04 (patch) | |
| tree | 706fb459923e590978bbacdde5fe2fb3bacf4b74 /src/RSS.cpp | |
Initial evening
Diffstat (limited to 'src/RSS.cpp')
| -rw-r--r-- | src/RSS.cpp | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/RSS.cpp b/src/RSS.cpp new file mode 100644 index 0000000..a1c0dde --- /dev/null +++ b/src/RSS.cpp @@ -0,0 +1,81 @@ +#include "RSS.hpp" +#include <iomanip> +#include <iostream> +#include <ctime> +#include <memory> +#include <stdexcept> +#include <curl/curl.h> + +RSS::RSS(std::string url) { + URL = url; + channelInfo = ChannelInfo(url); + parse(request()); +} + +size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* userp) { + size_t totalSize = size * nmemb; + userp->append((char*)contents, totalSize); + return totalSize; +} + +std::string RSS::request() { + std::unique_ptr<CURL, decltype(&curl_easy_cleanup)> curl ( + curl_easy_init(), &curl_easy_cleanup); + + if (!curl) { + throw std::runtime_error("Failed to initialize CURL"); + } + + std::string data; + + curl_easy_setopt(curl.get(), CURLOPT_URL, URL.c_str()); + curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &data); + curl_easy_setopt(curl.get(), CURLOPT_FOLLOWLOCATION, 1L); + + auto res = curl_easy_perform(curl.get()); + if (res != CURLE_OK) { + throw std::runtime_error(std::string("CURL request failed: ") + curl_easy_strerror(res)); + } + + curl_easy_cleanup(curl.get()); + return data; +} + +void RSS::parse(std::string contents) { + // std::cout << "starting tokenization..." << std::endl; + try { + auto leaf = XML_leaf(contents).GetChild("channel"); + if (leaf.Raw == "<>") + throw new std::runtime_error("The feed does not contain <channel> element"); + + this->channelInfo.Title = leaf.GetChild("title").Value; + + auto items = leaf.GetChildren("item"); + for (auto item : items) + Entries.push_back(RSS_Entry(item)); + } catch (const char *err) { + std::cout << "Failed to parse feed '" << URL << "' :" << err << std::endl; + return; + } +} + +RSS_Entry::RSS_Entry(XML_leaf node) { + Title = node.GetChild("title").GetValue(); + URL = node.GetChild("link").GetValue(); + Contents = node.GetChild("description").GetValue(); + + // auto pubDateField = node.GetChild("pubDate"); + // if (pubDateField.Value.length() == 0) return; + // std::cout << "pub date" << pubDateField.Value << std::endl; + // strptime(pubDateField.Value.c_str(), "%Y-%m-%dT%H:%M:%SZ", &pubDate); +} + +void RSS_Entry::print() { + std::cout + << "==============================\n" + << Title << '\n' + // << std::put_time(&pubDate, "%Y-%m-%d %H:%M:%S") << '\n' + << Contents << '\n' + << URL<< '\n'; +} |
