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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
|
#ifndef NEWSBOAT_RSSFEED_H_
#define NEWSBOAT_RSSFEED_H_
#include <memory>
#include <mutex>
#include <string>
#include <unordered_map>
#include <vector>
#include "matchable.h"
#include "rssitem.h"
#include "utils.h"
namespace newsboat {
enum class DlStatus { SUCCESS, TO_BE_DOWNLOADED, DURING_DOWNLOAD, DL_ERROR };
class Cache;
class RssFeed : public Matchable {
public:
explicit RssFeed(Cache* c, const std::string& rssurl);
~RssFeed() override;
std::string title_raw() const
{
return title_;
}
std::string title() const;
void set_title(const std::string& t)
{
title_ = t;
utils::trim(title_);
}
std::string description() const
{
return description_;
}
void set_description(const std::string& d)
{
description_ = d;
}
/// \brief Feed's canonical URL. Empty if feed was never fetched.
const std::string& link() const
{
return link_;
}
void set_link(const std::string& l)
{
link_ = l;
}
std::string pubDate() const
{
return utils::mt_strf_localtime(_("%a, %d %b %Y %T %z"), pubDate_);
}
void set_pubDate(time_t t)
{
pubDate_ = t;
}
bool hidden() const;
std::vector<std::shared_ptr<RssItem>>& items()
{
return items_;
}
void add_item(std::shared_ptr<RssItem> item)
{
items_.push_back(item);
items_guid_map[item->guid()] = item;
}
void add_items(const std::vector<std::shared_ptr<RssItem>>& items)
{
for (const auto& item : items) {
items_.push_back(item);
items_guid_map[item->guid()] = item;
}
}
void set_items(std::vector<std::shared_ptr<RssItem>>& items)
{
erase_items(items_.begin(), items_.end());
add_items(items);
}
void erase_items(std::vector<std::shared_ptr<RssItem>>::iterator begin,
std::vector<std::shared_ptr<RssItem>>::iterator end)
{
for (auto it = begin; it != end; ++it) {
items_guid_map.erase((*it)->guid());
}
items_.erase(begin, end);
}
void erase_item(std::vector<std::shared_ptr<RssItem>>::iterator pos)
{
items_guid_map.erase((*pos)->guid());
items_.erase(pos);
}
std::shared_ptr<RssItem> get_item_by_guid(const std::string& guid);
std::shared_ptr<RssItem> get_item_by_guid_unlocked(
const std::string& guid);
/// \brief User-specified feed URL.
const std::string& rssurl() const
{
return rssurl_;
}
unsigned int unread_item_count() const;
unsigned int total_item_count() const
{
return items_.size();
}
void set_tags(const std::vector<std::string>& tags);
bool matches_tag(const std::string& tag);
std::vector<std::string> get_tags() const;
std::string get_firsttag();
nonstd::optional<std::string> attribute_value(const std::string& attr) const
override;
void update_items(std::vector<std::shared_ptr<RssFeed>> feeds);
bool is_query_feed() const
{
return rssurl_.substr(0, 6) == "query:";
}
bool is_search_feed() const
{
return search_feed;
}
void set_search_feed(bool b)
{
search_feed = b;
}
void sort(const ArticleSortStrategy& sort_strategy);
void sort_unlocked(const ArticleSortStrategy& sort_strategy);
void purge_deleted_items();
void set_rtl(bool b)
{
is_rtl_ = b;
}
bool is_rtl()
{
return is_rtl_;
}
void set_index(unsigned int i)
{
idx = i;
}
void set_order(unsigned int x)
{
order = x;
}
unsigned int get_order()
{
return order;
}
void set_feedptrs(std::shared_ptr<RssFeed> self);
std::string get_status();
void reset_status()
{
std::lock_guard<std::mutex> guard(status_mutex_);
status_ = DlStatus::TO_BE_DOWNLOADED;
}
void set_status(DlStatus st)
{
std::lock_guard<std::mutex> guard(status_mutex_);
status_ = st;
}
void unload();
void load();
void mark_all_items_read();
// this is ugly, but makes it possible to lock items use e.g. from the Cache class
mutable std::mutex item_mutex;
private:
std::string title_;
std::string description_;
std::string link_;
time_t pubDate_;
const std::string rssurl_;
std::vector<std::shared_ptr<RssItem>> items_;
std::unordered_map<std::string, std::shared_ptr<RssItem>>
items_guid_map;
std::vector<std::string> tags_;
std::string query;
Cache* ch;
bool search_feed;
bool is_rtl_;
unsigned int idx;
unsigned int order;
std::mutex items_guid_map_mutex;
DlStatus status_;
std::mutex status_mutex_;
};
} // namespace newsboat
#endif /* NEWSBOAT_RSSFEED_H_ */
|