Line data Source code
1 : #include "BatchFeedFetcher.h"
2 : #include "FeedFetcher.h"
3 : #include "FeedDiscoveryLogging.h"
4 :
5 83 : BatchFeedFetcher::BatchFeedFetcher(QObject *parent)
6 83 : : QObject{parent}
7 83 : {}
8 :
9 13 : void BatchFeedFetcher::parse(const QList<QUrl> &urls)
10 : {
11 : // Clear any existing parsers and results, in case this object is being reused.
12 13 : parsers.clear();
13 13 : parserUrls.clear();
14 13 : results.clear();
15 :
16 : // Clear feed map as the pointers are no longer valid (they were owned by parsers.)
17 13 : feeds.clear();
18 :
19 : // Set up parsers.
20 33 : for (const QUrl& url : urls) {
21 : // Skip this URL if we've already seen it.
22 20 : if (parsers.contains(url)) {
23 2 : continue;
24 : }
25 :
26 18 : auto parser = createParser();
27 18 : connect(parser.get(), &FeedSource::done, this, &BatchFeedFetcher::onParserDone);
28 18 : parserUrls.insert(parser.get(), url);
29 18 : parser->parse(url);
30 18 : parsers.insert(url, parser);
31 18 : }
32 13 : }
33 :
34 0 : std::shared_ptr<FeedSource> BatchFeedFetcher::createParser()
35 : {
36 0 : return std::make_shared<FeedFetcher>();
37 : }
38 :
39 18 : void BatchFeedFetcher::onParserDone()
40 : {
41 18 : FeedSource* parser = qobject_cast<FeedSource*>(sender());
42 18 : if (!parser) {
43 0 : qCWarning(logFeedDiscovery) << "BatchFeedFetcher: onParserDone called but sender is not a FeedSource";
44 0 : return;
45 : }
46 :
47 : // Look up the original request URL via the reverse index, since
48 : // parser->getURL() may differ from the request URL after redirects.
49 18 : QUrl requestUrl = parserUrls.value(parser);
50 :
51 18 : if (requestUrl.isEmpty()) {
52 0 : qCWarning(logFeedDiscovery) << "BatchFeedFetcher: parser finished but not found in map:" << parser->getURL();
53 0 : return;
54 : }
55 :
56 : // Store result under the original request URL.
57 18 : results[requestUrl] = parser->getResult();
58 :
59 : // Store feed if parser succeeded.
60 18 : if (parser->getResult() == FeedFetchResult::OK) {
61 12 : auto feed = parser->getFeed();
62 12 : if (feed) {
63 12 : feeds[requestUrl] = feed;
64 : }
65 12 : }
66 :
67 : // Check if we're done.
68 56 : for (auto it = parsers.cbegin(); it != parsers.cend(); ++it) {
69 38 : if (it.value()->getResult() == FeedFetchResult::InProgress) {
70 : // Not done yet!
71 0 : return;
72 : }
73 : }
74 :
75 : // We're done!
76 18 : emit ready();
77 18 : }
78 :
79 15 : std::shared_ptr<RawFeed> BatchFeedFetcher::getFeed(const QUrl& url)
80 : {
81 15 : return feeds.value(url, nullptr);
82 : }
|