File indexing completed on 2024-04-21 05:10:35
0001 /* 0002 This file is part of Akregator. 0003 0004 SPDX-FileCopyrightText: 2004 Sashmit Bhaduri <smt@vfemail.net> 0005 SPDX-FileCopyrightText: 2005 Frank Osterfeld <osterfeld@kde.org> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0 0008 */ 0009 0010 #include "fetchqueue.h" 0011 #include "akregatorconfig.h" 0012 #include "feed.h" 0013 #include "treenode.h" 0014 0015 using namespace Akregator; 0016 0017 FetchQueue::FetchQueue(QObject *parent) 0018 : QObject(parent) 0019 { 0020 } 0021 0022 FetchQueue::~FetchQueue() 0023 { 0024 slotAbort(); 0025 } 0026 0027 void FetchQueue::slotAbort() 0028 { 0029 for (Feed *const i : std::as_const(m_fetchingFeeds)) { 0030 disconnectFromFeed(i); 0031 i->slotAbortFetch(); 0032 } 0033 m_fetchingFeeds.clear(); 0034 0035 for (Feed *const i : std::as_const(m_queuedFeeds)) { 0036 disconnectFromFeed(i); 0037 } 0038 m_queuedFeeds.clear(); 0039 0040 Q_EMIT signalStopped(); 0041 } 0042 0043 void FetchQueue::addFeed(Feed *f) 0044 { 0045 if (!m_queuedFeeds.contains(f) && !m_fetchingFeeds.contains(f)) { 0046 connectToFeed(f); 0047 m_queuedFeeds.append(f); 0048 fetchNextFeed(); 0049 } 0050 } 0051 0052 void FetchQueue::fetchNextFeed() 0053 { 0054 if (!m_queuedFeeds.isEmpty() && m_fetchingFeeds.count() < Settings::concurrentFetches()) { 0055 if (m_fetchingFeeds.isEmpty() && m_queuedFeeds.count() == 1) { 0056 Q_EMIT signalStarted(); 0057 } 0058 Feed *f = *(m_queuedFeeds.begin()); 0059 m_queuedFeeds.pop_front(); 0060 m_fetchingFeeds.append(f); 0061 f->fetch(false); 0062 } 0063 } 0064 0065 void FetchQueue::slotFeedFetched(Feed *f) 0066 { 0067 Q_EMIT fetched(f); 0068 feedDone(f); 0069 } 0070 0071 void FetchQueue::slotFetchError(Feed *f) 0072 { 0073 Q_EMIT fetchError(f); 0074 feedDone(f); 0075 } 0076 0077 void FetchQueue::slotFetchAborted(Feed *f) 0078 { 0079 Q_EMIT fetched(f); // FIXME: better use a signal like signalAborted(Feed*) 0080 feedDone(f); 0081 } 0082 0083 bool FetchQueue::isEmpty() const 0084 { 0085 return m_queuedFeeds.isEmpty() && m_fetchingFeeds.isEmpty(); 0086 } 0087 0088 void FetchQueue::feedDone(Feed *f) 0089 { 0090 disconnectFromFeed(f); 0091 m_fetchingFeeds.removeAll(f); 0092 if (isEmpty()) { 0093 Q_EMIT signalStopped(); 0094 } else { 0095 fetchNextFeed(); 0096 } 0097 } 0098 0099 void FetchQueue::connectToFeed(Feed *feed) 0100 { 0101 connect(feed, &Feed::fetched, this, &FetchQueue::slotFeedFetched); 0102 connect(feed, &Feed::fetchError, this, &FetchQueue::slotFetchError); 0103 connect(feed, &Feed::fetchAborted, this, &FetchQueue::slotFetchAborted); 0104 connect(feed, &TreeNode::signalDestroyed, this, &FetchQueue::slotNodeDestroyed); 0105 } 0106 0107 void FetchQueue::disconnectFromFeed(Feed *feed) 0108 { 0109 feed->disconnect(this); 0110 } 0111 0112 void FetchQueue::slotNodeDestroyed(TreeNode *node) 0113 { 0114 Feed *const feed = qobject_cast<Feed *>(node); 0115 Q_ASSERT(feed); 0116 0117 m_fetchingFeeds.removeAll(feed); 0118 m_queuedFeeds.removeAll(feed); 0119 } 0120 0121 #include "moc_fetchqueue.cpp"