1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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';
}
|