qBittorrent
RSS::Session Class Reference

#include <rss_session.h>

Inheritance diagram for RSS::Session:
Collaboration diagram for RSS::Session:

Public Slots

void refresh ()
 

Signals

void processingStateChanged (bool enabled)
 
void maxArticlesPerFeedChanged (int n)
 
void itemAdded (Item *item)
 
void itemPathChanged (Item *item)
 
void itemAboutToBeRemoved (Item *item)
 
void feedIconLoaded (Feed *feed)
 
void feedStateChanged (Feed *feed)
 

Public Member Functions

bool isProcessingEnabled () const
 
void setProcessingEnabled (bool enabled)
 
QThread * workingThread () const
 
AsyncFileStorageconfFileStorage () const
 
AsyncFileStoragedataFileStorage () const
 
int maxArticlesPerFeed () const
 
void setMaxArticlesPerFeed (int n)
 
int refreshInterval () const
 
void setRefreshInterval (int refreshInterval)
 
nonstd::expected< void, QString > addFolder (const QString &path)
 
nonstd::expected< void, QString > addFeed (const QString &url, const QString &path)
 
nonstd::expected< void, QString > moveItem (const QString &itemPath, const QString &destPath)
 
nonstd::expected< void, QString > moveItem (Item *item, const QString &destPath)
 
nonstd::expected< void, QString > removeItem (const QString &itemPath)
 
QList< Item * > items () const
 
ItemitemByPath (const QString &path) const
 
QList< Feed * > feeds () const
 
FeedfeedByURL (const QString &url) const
 
FolderrootFolder () const
 

Static Public Member Functions

static Sessioninstance ()
 

Private Slots

void handleItemAboutToBeDestroyed (Item *item)
 
void handleFeedTitleChanged (Feed *feed)
 

Private Member Functions

 Session ()
 
 ~Session () override
 
QUuid generateUID () const
 
void load ()
 
void loadFolder (const QJsonObject &jsonObj, Folder *folder)
 
void loadLegacy ()
 
void store ()
 
nonstd::expected< Folder *, QString > prepareItemDest (const QString &path)
 
FolderaddSubfolder (const QString &name, Folder *parentFolder)
 
FeedaddFeedToFolder (const QUuid &uid, const QString &url, const QString &name, Folder *parentFolder)
 
void addItem (Item *item, Folder *destFolder)
 

Private Attributes

CachedSettingValue< bool > m_storeProcessingEnabled
 
CachedSettingValue< int > m_storeRefreshInterval
 
CachedSettingValue< int > m_storeMaxArticlesPerFeed
 
QThread * m_workingThread
 
AsyncFileStoragem_confFileStorage
 
AsyncFileStoragem_dataFileStorage
 
QTimer m_refreshTimer
 
QHash< QString, Item * > m_itemsByPath
 
QHash< QUuid, Feed * > m_feedsByUID
 
QHash< QString, Feed * > m_feedsByURL
 

Static Private Attributes

static QPointer< Sessionm_instance = nullptr
 

Friends

class ::Application
 

Detailed Description

Definition at line 90 of file rss_session.h.

Constructor & Destructor Documentation

◆ Session()

Session::Session ( )
private

Definition at line 60 of file rss_session.cpp.

61  : m_storeProcessingEnabled("RSS/Session/EnableProcessing")
62  , m_storeRefreshInterval("RSS/Session/RefreshInterval", 30)
63  , m_storeMaxArticlesPerFeed("RSS/Session/MaxArticlesPerFeed", 50)
64  , m_workingThread(new QThread(this))
65 {
66  Q_ASSERT(!m_instance); // only one instance is allowed
67  m_instance = this;
68 
71  m_confFileStorage->moveToThread(m_workingThread);
72  connect(m_workingThread, &QThread::finished, m_confFileStorage, &AsyncFileStorage::deleteLater);
73  connect(m_confFileStorage, &AsyncFileStorage::failed, [](const QString &fileName, const QString &errorString)
74  {
75  Logger::instance()->addMessage(QString("Couldn't save RSS Session configuration in %1. Error: %2")
76  .arg(fileName, errorString), Log::WARNING);
77  });
78 
81  m_dataFileStorage->moveToThread(m_workingThread);
82  connect(m_workingThread, &QThread::finished, m_dataFileStorage, &AsyncFileStorage::deleteLater);
83  connect(m_dataFileStorage, &AsyncFileStorage::failed, [](const QString &fileName, const QString &errorString)
84  {
85  Logger::instance()->addMessage(QString("Couldn't save RSS Session data in %1. Error: %2")
86  .arg(fileName, errorString), Log::WARNING);
87  });
88 
89  m_itemsByPath.insert("", new Folder); // root folder
90 
91  m_workingThread->start();
92  load();
93 
94  connect(&m_refreshTimer, &QTimer::timeout, this, &Session::refresh);
95  if (isProcessingEnabled())
96  {
98  refresh();
99  }
100 
101  // Remove legacy/corrupted settings
102  // (at least on Windows, QSettings is case-insensitive and it can get
103  // confused when asked about settings that differ only in their case)
104  auto settingsStorage = SettingsStorage::instance();
105  settingsStorage->removeValue("Rss/streamList");
106  settingsStorage->removeValue("Rss/streamAlias");
107  settingsStorage->removeValue("Rss/open_folders");
108  settingsStorage->removeValue("Rss/qt5/splitter_h");
109  settingsStorage->removeValue("Rss/qt5/splitterMain");
110  settingsStorage->removeValue("Rss/hosts_cookies");
111  settingsStorage->removeValue("RSS/streamList");
112  settingsStorage->removeValue("RSS/streamAlias");
113  settingsStorage->removeValue("RSS/open_folders");
114  settingsStorage->removeValue("RSS/qt5/splitter_h");
115  settingsStorage->removeValue("RSS/qt5/splitterMain");
116  settingsStorage->removeValue("RSS/hosts_cookies");
117  settingsStorage->removeValue("Rss/Session/EnableProcessing");
118  settingsStorage->removeValue("Rss/Session/RefreshInterval");
119  settingsStorage->removeValue("Rss/Session/MaxArticlesPerFeed");
120  settingsStorage->removeValue("Rss/AutoDownloader/EnableProcessing");
121 }
void failed(const QString &fileName, const QString &errorString)
void addMessage(const QString &message, const Log::MsgType &type=Log::NORMAL)
Definition: logger.cpp:73
static Logger * instance()
Definition: logger.cpp:56
int refreshInterval() const
bool isProcessingEnabled() const
CachedSettingValue< int > m_storeRefreshInterval
Definition: rss_session.h:159
QTimer m_refreshTimer
Definition: rss_session.h:164
QHash< QString, Item * > m_itemsByPath
Definition: rss_session.h:165
AsyncFileStorage * m_dataFileStorage
Definition: rss_session.h:163
CachedSettingValue< bool > m_storeProcessingEnabled
Definition: rss_session.h:158
CachedSettingValue< int > m_storeMaxArticlesPerFeed
Definition: rss_session.h:160
QThread * m_workingThread
Definition: rss_session.h:161
AsyncFileStorage * m_confFileStorage
Definition: rss_session.h:162
static QPointer< Session > m_instance
Definition: rss_session.h:156
static SettingsStorage * instance()
@ WARNING
Definition: logger.h:47
QString fileName(const QString &filePath)
Definition: fs.cpp:87
QString expandPathAbs(const QString &path)
Definition: fs.cpp:309
QString specialFolderLocation(const SpecialFolder folder)
Definition: profile.cpp:131
const int MsecsPerMin
Definition: rss_session.cpp:51
const QString DataFolderName(QStringLiteral("rss/articles"))
const QString ConfFolderName(QStringLiteral("rss"))

References Logger::addMessage(), ConfFolderName(), Config, Data, DataFolderName(), Utils::Fs::expandPathAbs(), AsyncFileStorage::failed(), Utils::Fs::fileName(), Logger::instance(), SettingsStorage::instance(), isProcessingEnabled(), load(), m_confFileStorage, m_dataFileStorage, m_instance, m_itemsByPath, m_refreshTimer, m_workingThread, MsecsPerMin, refresh(), refreshInterval(), specialFolderLocation(), and Log::WARNING.

Here is the call graph for this function:

◆ ~Session()

Session::~Session ( )
overrideprivate

Definition at line 123 of file rss_session.cpp.

124 {
125  qDebug() << "Deleting RSS Session...";
126 
127  m_workingThread->quit();
128  m_workingThread->wait();
129 
130  //store();
131  delete m_itemsByPath[""]; // deleting root folder
132 
133  qDebug() << "RSS Session deleted.";
134 }

References m_itemsByPath, and m_workingThread.

Member Function Documentation

◆ addFeed()

nonstd::expected< void, QString > Session::addFeed ( const QString &  url,
const QString &  path 
)

Definition at line 153 of file rss_session.cpp.

154 {
155  if (m_feedsByURL.contains(url))
156  return nonstd::make_unexpected(tr("RSS feed with given URL already exists: %1.").arg(url));
157 
158  const nonstd::expected<Folder *, QString> result = prepareItemDest(path);
159  if (!result)
160  return result.get_unexpected();
161 
162  const auto destFolder = result.value();
163  addItem(new Feed(generateUID(), url, path, this), destFolder);
164  store();
165  if (isProcessingEnabled())
166  feedByURL(url)->refresh();
167 
168  return {};
169 }
void refresh() override
Definition: rss_feed.cpp:132
nonstd::expected< Folder *, QString > prepareItemDest(const QString &path)
Feed * feedByURL(const QString &url) const
QUuid generateUID() const
void addItem(Item *item, Folder *destFolder)
QHash< QString, Feed * > m_feedsByURL
Definition: rss_session.h:167

References addItem(), feedByURL(), generateUID(), isProcessingEnabled(), m_feedsByURL, prepareItemDest(), RSS::Feed::refresh(), and store().

Referenced by RSSController::addFeedAction(), loadLegacy(), and RSSWidget::on_newFeedButton_clicked().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ addFeedToFolder()

Feed * Session::addFeedToFolder ( const QUuid &  uid,
const QString &  url,
const QString &  name,
Folder parentFolder 
)
private

Definition at line 401 of file rss_session.cpp.

402 {
403  auto feed = new Feed(uid, url, Item::joinPath(parentFolder->path(), name), this);
404  addItem(feed, parentFolder);
405  return feed;
406 }
static QString joinPath(const QString &path1, const QString &path2)
Definition: rss_item.cpp:82
QString path() const
Definition: rss_item.cpp:57

References addItem(), RSS::Item::joinPath(), and RSS::Item::path().

Referenced by loadFolder().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ addFolder()

nonstd::expected< void, QString > Session::addFolder ( const QString &  path)

Definition at line 141 of file rss_session.cpp.

142 {
143  const nonstd::expected<Folder *, QString> result = prepareItemDest(path);
144  if (!result)
145  return result.get_unexpected();
146 
147  const auto destFolder = result.value();
148  addItem(new Folder(path), destFolder);
149  store();
150  return {};
151 }

References addItem(), prepareItemDest(), and store().

Referenced by RSSController::addFolderAction(), RSSWidget::askNewFolder(), and loadLegacy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ addItem()

void Session::addItem ( Item item,
Folder destFolder 
)
private

Definition at line 408 of file rss_session.cpp.

409 {
410  if (auto feed = qobject_cast<Feed *>(item))
411  {
412  connect(feed, &Feed::titleChanged, this, &Session::handleFeedTitleChanged);
413  connect(feed, &Feed::iconLoaded, this, &Session::feedIconLoaded);
414  connect(feed, &Feed::stateChanged, this, &Session::feedStateChanged);
415  m_feedsByUID[feed->uid()] = feed;
416  m_feedsByURL[feed->url()] = feed;
417  }
418 
419  connect(item, &Item::pathChanged, this, &Session::itemPathChanged);
421  m_itemsByPath[item->path()] = item;
422  destFolder->addItem(item);
423  emit itemAdded(item);
424 }
void iconLoaded(Feed *feed=nullptr)
void titleChanged(Feed *feed=nullptr)
void stateChanged(Feed *feed=nullptr)
void addItem(Item *item)
Definition: rss_folder.cpp:119
void pathChanged(Item *item=nullptr)
void aboutToBeDestroyed(Item *item=nullptr)
void handleFeedTitleChanged(Feed *feed)
void itemPathChanged(Item *item)
void handleItemAboutToBeDestroyed(Item *item)
void feedStateChanged(Feed *feed)
void itemAdded(Item *item)
QHash< QUuid, Feed * > m_feedsByUID
Definition: rss_session.h:166
void feedIconLoaded(Feed *feed)

References RSS::Item::aboutToBeDestroyed(), RSS::Folder::addItem(), feedIconLoaded(), feedStateChanged(), handleFeedTitleChanged(), handleItemAboutToBeDestroyed(), RSS::Feed::iconLoaded(), itemAdded(), itemPathChanged(), m_feedsByUID, m_feedsByURL, m_itemsByPath, RSS::Item::path(), RSS::Item::pathChanged(), RSS::Feed::stateChanged(), and RSS::Feed::titleChanged().

Referenced by addFeed(), addFeedToFolder(), addFolder(), and addSubfolder().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ addSubfolder()

Folder * Session::addSubfolder ( const QString &  name,
Folder parentFolder 
)
private

Definition at line 394 of file rss_session.cpp.

395 {
396  auto folder = new Folder(Item::joinPath(parentFolder->path(), name));
397  addItem(folder, parentFolder);
398  return folder;
399 }

References addItem(), RSS::Item::joinPath(), and RSS::Item::path().

Referenced by loadFolder().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ confFileStorage()

AsyncFileStorage * Session::confFileStorage ( ) const

Definition at line 450 of file rss_session.cpp.

451 {
452  return m_confFileStorage;
453 }

References m_confFileStorage.

◆ dataFileStorage()

AsyncFileStorage * Session::dataFileStorage ( ) const

Definition at line 455 of file rss_session.cpp.

456 {
457  return m_dataFileStorage;
458 }

References m_dataFileStorage.

Referenced by RSS::Feed::cleanup(), RSS::Feed::Feed(), RSS::Feed::load(), and RSS::Feed::store().

Here is the caller graph for this function:

◆ feedByURL()

Feed * Session::feedByURL ( const QString &  url) const

Definition at line 470 of file rss_session.cpp.

471 {
472  return m_feedsByURL.value(url);
473 }

References m_feedsByURL.

Referenced by addFeed(), RSSController::matchingArticlesAction(), and AutomatedRssDownloader::updateMatchingArticles().

Here is the caller graph for this function:

◆ feedIconLoaded

void RSS::Session::feedIconLoaded ( Feed feed)
signal

Referenced by addItem(), and FeedListWidget::FeedListWidget().

Here is the caller graph for this function:

◆ feeds()

QList< Feed * > Session::feeds ( ) const

Definition at line 465 of file rss_session.cpp.

466 {
467  return m_feedsByURL.values();
468 }

References m_feedsByURL.

◆ feedStateChanged

void RSS::Session::feedStateChanged ( Feed feed)
signal

Referenced by addItem(), and FeedListWidget::FeedListWidget().

Here is the caller graph for this function:

◆ generateUID()

QUuid Session::generateUID ( ) const
private

Definition at line 513 of file rss_session.cpp.

514 {
515  QUuid uid = QUuid::createUuid();
516  while (m_feedsByUID.contains(uid))
517  uid = QUuid::createUuid();
518 
519  return uid;
520 }

References m_feedsByUID.

Referenced by addFeed(), and loadFolder().

Here is the caller graph for this function:

◆ handleFeedTitleChanged

void Session::handleFeedTitleChanged ( Feed feed)
privateslot

Definition at line 505 of file rss_session.cpp.

506 {
507  if (feed->name() == feed->url())
508  // Now we have something better than a URL.
509  // Trying to rename feed...
510  moveItem(feed, Item::joinPath(Item::parentPath(feed->path()), feed->title()));
511 }
QString title() const
Definition: rss_feed.cpp:159
QString url() const
Definition: rss_feed.cpp:154
static QString parentPath(const QString &path)
Definition: rss_item.cpp:108
QString name() const
Definition: rss_item.cpp:62
nonstd::expected< void, QString > moveItem(const QString &itemPath, const QString &destPath)

References RSS::Item::joinPath(), moveItem(), RSS::Item::name(), RSS::Item::parentPath(), RSS::Item::path(), RSS::Feed::title(), and RSS::Feed::url().

Referenced by addItem().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleItemAboutToBeDestroyed

void Session::handleItemAboutToBeDestroyed ( Item item)
privateslot

Definition at line 494 of file rss_session.cpp.

495 {
496  m_itemsByPath.remove(item->path());
497  auto feed = qobject_cast<Feed *>(item);
498  if (feed)
499  {
500  m_feedsByUID.remove(feed->uid());
501  m_feedsByURL.remove(feed->url());
502  }
503 }

References m_feedsByUID, m_feedsByURL, m_itemsByPath, and RSS::Item::path().

Referenced by addItem().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ instance()

◆ isProcessingEnabled()

bool Session::isProcessingEnabled ( ) const

Definition at line 426 of file rss_session.cpp.

427 {
429 }

References m_storeProcessingEnabled.

Referenced by addFeed(), RSS::Feed::Feed(), OptionsDialog::loadOptions(), AppController::preferencesAction(), and Session().

Here is the caller graph for this function:

◆ itemAboutToBeRemoved

void RSS::Session::itemAboutToBeRemoved ( Item item)
signal

Referenced by FeedListWidget::FeedListWidget(), and removeItem().

Here is the caller graph for this function:

◆ itemAdded

void RSS::Session::itemAdded ( Item item)
signal

Referenced by addItem(), and FeedListWidget::FeedListWidget().

Here is the caller graph for this function:

◆ itemByPath()

Item * Session::itemByPath ( const QString &  path) const

Definition at line 229 of file rss_session.cpp.

230 {
231  return m_itemsByPath.value(path);
232 }

References m_itemsByPath.

Referenced by RSSWidget::askNewFolder(), FeedListWidget::handleItemPathChanged(), RSSController::markAsReadAction(), RSSWidget::on_newFeedButton_clicked(), and RSSController::refreshItemAction().

Here is the caller graph for this function:

◆ itemPathChanged

void RSS::Session::itemPathChanged ( Item item)
signal

Referenced by addItem(), and FeedListWidget::FeedListWidget().

Here is the caller graph for this function:

◆ items()

QList< Item * > Session::items ( ) const

Definition at line 224 of file rss_session.cpp.

225 {
226  return m_itemsByPath.values();
227 }

References m_itemsByPath.

◆ load()

void Session::load ( )
private

Definition at line 234 of file rss_session.cpp.

235 {
236  QFile itemsFile(m_confFileStorage->storageDir().absoluteFilePath(FeedsFileName));
237  if (!itemsFile.exists())
238  {
239  loadLegacy();
240  return;
241  }
242 
243  if (!itemsFile.open(QFile::ReadOnly))
244  {
246  QString("Couldn't read RSS Session data from %1. Error: %2")
247  .arg(itemsFile.fileName(), itemsFile.errorString()), Log::WARNING);
248  return;
249  }
250 
251  QJsonParseError jsonError;
252  const QJsonDocument jsonDoc = QJsonDocument::fromJson(itemsFile.readAll(), &jsonError);
253  if (jsonError.error != QJsonParseError::NoError)
254  {
256  QString("Couldn't parse RSS Session data from %1. Error: %2")
257  .arg(itemsFile.fileName(), jsonError.errorString()), Log::WARNING);
258  return;
259  }
260 
261  if (!jsonDoc.isObject())
262  {
264  QString("Couldn't load RSS Session data from %1. Invalid data format.")
265  .arg(itemsFile.fileName()), Log::WARNING);
266  return;
267  }
268 
269  loadFolder(jsonDoc.object(), rootFolder());
270 }
QDir storageDir() const
void loadFolder(const QJsonObject &jsonObj, Folder *folder)
void loadLegacy()
Folder * rootFolder() const
const QString FeedsFileName(QStringLiteral("feeds.json"))

References Logger::addMessage(), FeedsFileName(), Logger::instance(), loadFolder(), loadLegacy(), m_confFileStorage, rootFolder(), AsyncFileStorage::storageDir(), and Log::WARNING.

Referenced by Session().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ loadFolder()

void Session::loadFolder ( const QJsonObject &  jsonObj,
Folder folder 
)
private

Definition at line 272 of file rss_session.cpp.

273 {
274  bool updated = false;
275  for (const QString &key : asConst(jsonObj.keys()))
276  {
277  const QJsonValue val {jsonObj[key]};
278  if (val.isString())
279  {
280  // previous format (reduced form) doesn't contain UID
281  QString url = val.toString();
282  if (url.isEmpty())
283  url = key;
284  addFeedToFolder(generateUID(), url, key, folder);
285  updated = true;
286  }
287  else if (val.isObject())
288  {
289  const QJsonObject valObj {val.toObject()};
290  if (valObj.contains("url"))
291  {
292  if (!valObj["url"].isString())
293  {
294  LogMsg(tr("Couldn't load RSS Feed '%1'. URL is required.")
295  .arg(QString("%1\\%2").arg(folder->path(), key)), Log::WARNING);
296  continue;
297  }
298 
299  QUuid uid;
300  if (valObj.contains("uid"))
301  {
302  uid = QUuid {valObj["uid"].toString()};
303  if (uid.isNull())
304  {
305  LogMsg(tr("Couldn't load RSS Feed '%1'. UID is invalid.")
306  .arg(QString("%1\\%2").arg(folder->path(), key)), Log::WARNING);
307  continue;
308  }
309 
310  if (m_feedsByUID.contains(uid))
311  {
312  LogMsg(tr("Duplicate RSS Feed UID: %1. Configuration seems to be corrupted.")
313  .arg(uid.toString()), Log::WARNING);
314  continue;
315  }
316  }
317  else
318  {
319  // previous format doesn't contain UID
320  uid = generateUID();
321  updated = true;
322  }
323 
324  addFeedToFolder(uid, valObj["url"].toString(), key, folder);
325  }
326  else
327  {
328  loadFolder(valObj, addSubfolder(key, folder));
329  }
330  }
331  else
332  {
333  LogMsg(tr("Couldn't load RSS Item '%1'. Invalid data format.")
334  .arg(QString::fromLatin1("%1\\%2").arg(folder->path(), key)), Log::WARNING);
335  }
336  }
337 
338  if (updated)
339  store(); // convert to updated format
340 }
Feed * addFeedToFolder(const QUuid &uid, const QString &url, const QString &name, Folder *parentFolder)
Folder * addSubfolder(const QString &name, Folder *parentFolder)
constexpr std::add_const_t< T > & asConst(T &t) noexcept
Definition: global.h:42
void LogMsg(const QString &message, const Log::MsgType &type)
Definition: logger.cpp:125
QString toString(const lt::socket_type_t socketType)
Definition: session.cpp:183

References addFeedToFolder(), addSubfolder(), asConst(), generateUID(), LogMsg(), m_feedsByUID, RSS::Item::path(), store(), anonymous_namespace{session.cpp}::toString(), and Log::WARNING.

Referenced by load().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ loadLegacy()

void Session::loadLegacy ( )
private

Definition at line 342 of file rss_session.cpp.

343 {
344  const auto legacyFeedPaths = SettingsStorage::instance()->loadValue<QStringList>("Rss/streamList");
345  const auto feedAliases = SettingsStorage::instance()->loadValue<QStringList>("Rss/streamAlias");
346  if (legacyFeedPaths.size() != feedAliases.size())
347  {
348  Logger::instance()->addMessage("Corrupted RSS list, not loading it.", Log::WARNING);
349  return;
350  }
351 
352  uint i = 0;
353  for (QString legacyPath : legacyFeedPaths)
354  {
355  if (Item::PathSeparator == QString(legacyPath[0]))
356  legacyPath.remove(0, 1);
357  const QString parentFolderPath = Item::parentPath(legacyPath);
358  const QString feedUrl = Item::relativeName(legacyPath);
359 
360  for (const QString &folderPath : asConst(Item::expandPath(parentFolderPath)))
361  addFolder(folderPath);
362 
363  const QString feedPath = feedAliases[i].isEmpty()
364  ? legacyPath
365  : Item::joinPath(parentFolderPath, feedAliases[i]);
366  addFeed(feedUrl, feedPath);
367  ++i;
368  }
369 
370  store(); // convert to new format
371 }
static const QChar PathSeparator
Definition: rss_item.h:61
static QStringList expandPath(const QString &path)
Definition: rss_item.cpp:90
static QString relativeName(const QString &path)
Definition: rss_item.cpp:114
nonstd::expected< void, QString > addFolder(const QString &path)
nonstd::expected< void, QString > addFeed(const QString &url, const QString &path)
T loadValue(const QString &key, const T &defaultValue={}) const

References addFeed(), addFolder(), Logger::addMessage(), asConst(), RSS::Item::expandPath(), Logger::instance(), SettingsStorage::instance(), RSS::Item::joinPath(), SettingsStorage::loadValue(), RSS::Item::parentPath(), RSS::Item::PathSeparator, RSS::Item::relativeName(), store(), and Log::WARNING.

Referenced by load().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ maxArticlesPerFeed()

int Session::maxArticlesPerFeed ( ) const

Definition at line 522 of file rss_session.cpp.

523 {
525 }

References m_storeMaxArticlesPerFeed.

Referenced by RSS::Feed::addArticle(), OptionsDialog::loadOptions(), AppController::preferencesAction(), and RSS::Feed::updateArticles().

Here is the caller graph for this function:

◆ maxArticlesPerFeedChanged

void RSS::Session::maxArticlesPerFeedChanged ( int  n)
signal

Referenced by RSS::Feed::Feed(), and setMaxArticlesPerFeed().

Here is the caller graph for this function:

◆ moveItem() [1/2]

nonstd::expected< void, QString > Session::moveItem ( const QString &  itemPath,
const QString &  destPath 
)

Definition at line 171 of file rss_session.cpp.

172 {
173  if (itemPath.isEmpty())
174  return nonstd::make_unexpected(tr("Cannot move root folder."));
175 
176  auto item = m_itemsByPath.value(itemPath);
177  if (!item)
178  return nonstd::make_unexpected(tr("Item doesn't exist: %1.").arg(itemPath));
179 
180  return moveItem(item, destPath);
181 }

References m_itemsByPath.

Referenced by FeedListWidget::dropEvent(), handleFeedTitleChanged(), RSSController::moveItemAction(), and RSSWidget::renameSelectedRSSItem().

Here is the caller graph for this function:

◆ moveItem() [2/2]

nonstd::expected< void, QString > Session::moveItem ( Item item,
const QString &  destPath 
)

Definition at line 183 of file rss_session.cpp.

184 {
185  Q_ASSERT(item);
186  Q_ASSERT(item != rootFolder());
187 
188  const nonstd::expected<Folder *, QString> result = prepareItemDest(destPath);
189  if (!result)
190  return result.get_unexpected();
191 
192  auto srcFolder = static_cast<Folder *>(m_itemsByPath.value(Item::parentPath(item->path())));
193  const auto destFolder = result.value();
194  if (srcFolder != destFolder)
195  {
196  srcFolder->removeItem(item);
197  destFolder->addItem(item);
198  }
199  m_itemsByPath.insert(destPath, m_itemsByPath.take(item->path()));
200  item->setPath(destPath);
201  store();
202  return {};
203 }
void removeItem(Item *item)
Definition: rss_folder.cpp:137
void setPath(const QString &path)
Definition: rss_item.cpp:48

References m_itemsByPath, RSS::Item::parentPath(), RSS::Item::path(), prepareItemDest(), RSS::Folder::removeItem(), rootFolder(), RSS::Item::setPath(), and store().

Here is the call graph for this function:

◆ prepareItemDest()

nonstd::expected< Folder *, QString > Session::prepareItemDest ( const QString &  path)
private

Definition at line 378 of file rss_session.cpp.

379 {
380  if (!Item::isValidPath(path))
381  return nonstd::make_unexpected(tr("Incorrect RSS Item path: %1.").arg(path));
382 
383  if (m_itemsByPath.contains(path))
384  return nonstd::make_unexpected(tr("RSS item with given path already exists: %1.").arg(path));
385 
386  const QString destFolderPath = Item::parentPath(path);
387  const auto destFolder = qobject_cast<Folder *>(m_itemsByPath.value(destFolderPath));
388  if (!destFolder)
389  return nonstd::make_unexpected(tr("Parent folder doesn't exist: %1.").arg(destFolderPath));
390 
391  return destFolder;
392 }
static bool isValidPath(const QString &path)
Definition: rss_item.cpp:67

References RSS::Item::isValidPath(), m_itemsByPath, and RSS::Item::parentPath().

Referenced by addFeed(), addFolder(), and moveItem().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ processingStateChanged

void RSS::Session::processingStateChanged ( bool  enabled)
signal

◆ refresh

void Session::refresh ( )
slot

Definition at line 536 of file rss_session.cpp.

537 {
538  // NOTE: Should we allow manually refreshing for disabled session?
539  rootFolder()->refresh();
540 }
void refresh() override
Definition: rss_folder.cpp:88

References RSS::Folder::refresh(), and rootFolder().

Referenced by RSSWidget::refreshAllFeeds(), Session(), and setProcessingEnabled().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ refreshInterval()

int Session::refreshInterval ( ) const

Definition at line 475 of file rss_session.cpp.

476 {
477  return m_storeRefreshInterval;
478 }

References m_storeRefreshInterval.

Referenced by OptionsDialog::loadOptions(), AppController::preferencesAction(), Session(), setProcessingEnabled(), and setRefreshInterval().

Here is the caller graph for this function:

◆ removeItem()

nonstd::expected< void, QString > Session::removeItem ( const QString &  itemPath)

Definition at line 205 of file rss_session.cpp.

206 {
207  if (itemPath.isEmpty())
208  return nonstd::make_unexpected(tr("Cannot delete root folder."));
209 
210  auto *item = m_itemsByPath.value(itemPath);
211  if (!item)
212  return nonstd::make_unexpected(tr("Item doesn't exist: %1.").arg(itemPath));
213 
214  emit itemAboutToBeRemoved(item);
215  item->cleanup();
216 
217  auto folder = static_cast<Folder *>(m_itemsByPath.value(Item::parentPath(item->path())));
218  folder->removeItem(item);
219  delete item;
220  store();
221  return {};
222 }
void itemAboutToBeRemoved(Item *item)

References itemAboutToBeRemoved(), m_itemsByPath, RSS::Item::parentPath(), RSS::Folder::removeItem(), and store().

Referenced by RSSWidget::deleteSelectedItems(), and RSSController::removeItemAction().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rootFolder()

Folder * Session::rootFolder ( ) const

Definition at line 460 of file rss_session.cpp.

461 {
462  return static_cast<Folder *>(m_itemsByPath.value(""));
463 }

References m_itemsByPath.

Referenced by RSSWidget::askNewFolder(), FeedListWidget::dropEvent(), FeedListWidget::FeedListWidget(), RSSController::itemsAction(), load(), moveItem(), RSSWidget::on_newFeedButton_clicked(), refresh(), and store().

Here is the caller graph for this function:

◆ setMaxArticlesPerFeed()

void Session::setMaxArticlesPerFeed ( int  n)

Definition at line 527 of file rss_session.cpp.

528 {
529  if (m_storeMaxArticlesPerFeed != n)
530  {
533  }
534 }
void maxArticlesPerFeedChanged(int n)

References m_storeMaxArticlesPerFeed, and maxArticlesPerFeedChanged().

Referenced by OptionsDialog::saveOptions(), and AppController::setPreferencesAction().

Here is the caller graph for this function:

◆ setProcessingEnabled()

void Session::setProcessingEnabled ( bool  enabled)

Definition at line 431 of file rss_session.cpp.

432 {
433  if (m_storeProcessingEnabled != enabled)
434  {
435  m_storeProcessingEnabled = enabled;
436  if (enabled)
437  {
439  refresh();
440  }
441  else
442  {
443  m_refreshTimer.stop();
444  }
445 
446  emit processingStateChanged(enabled);
447  }
448 }
void processingStateChanged(bool enabled)

References m_refreshTimer, m_storeProcessingEnabled, MsecsPerMin, processingStateChanged(), refresh(), and refreshInterval().

Referenced by OptionsDialog::saveOptions(), and AppController::setPreferencesAction().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setRefreshInterval()

void Session::setRefreshInterval ( int  refreshInterval)

Definition at line 480 of file rss_session.cpp.

References m_refreshTimer, m_storeRefreshInterval, MsecsPerMin, and refreshInterval().

Referenced by OptionsDialog::saveOptions(), AppController::setPreferencesAction(), and RSSWidget::updateRefreshInterval().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ store()

void Session::store ( )
private

Definition at line 373 of file rss_session.cpp.

374 {
375  m_confFileStorage->store(FeedsFileName, QJsonDocument(rootFolder()->toJsonValue().toObject()).toJson());
376 }
void store(const QString &fileName, const QByteArray &data)
QJsonValue toJsonValue(const std::optional< bool > boolValue)

References FeedsFileName(), m_confFileStorage, rootFolder(), AsyncFileStorage::store(), and anonymous_namespace{rss_autodownloadrule.cpp}::toJsonValue().

Referenced by addFeed(), addFolder(), loadFolder(), loadLegacy(), moveItem(), and removeItem().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ workingThread()

QThread * Session::workingThread ( ) const

Definition at line 489 of file rss_session.cpp.

490 {
491  return m_workingThread;
492 }

References m_workingThread.

Referenced by RSS::Feed::Feed().

Here is the caller graph for this function:

Friends And Related Function Documentation

◆ ::Application

friend class ::Application
friend

Definition at line 95 of file rss_session.h.

Member Data Documentation

◆ m_confFileStorage

AsyncFileStorage* RSS::Session::m_confFileStorage
private

Definition at line 162 of file rss_session.h.

Referenced by confFileStorage(), load(), Session(), and store().

◆ m_dataFileStorage

AsyncFileStorage* RSS::Session::m_dataFileStorage
private

Definition at line 163 of file rss_session.h.

Referenced by dataFileStorage(), and Session().

◆ m_feedsByUID

QHash<QUuid, Feed *> RSS::Session::m_feedsByUID
private

Definition at line 166 of file rss_session.h.

Referenced by addItem(), generateUID(), handleItemAboutToBeDestroyed(), and loadFolder().

◆ m_feedsByURL

QHash<QString, Feed *> RSS::Session::m_feedsByURL
private

Definition at line 167 of file rss_session.h.

Referenced by addFeed(), addItem(), feedByURL(), feeds(), and handleItemAboutToBeDestroyed().

◆ m_instance

QPointer< Session > Session::m_instance = nullptr
staticprivate

Definition at line 156 of file rss_session.h.

Referenced by instance(), and Session().

◆ m_itemsByPath

QHash<QString, Item *> RSS::Session::m_itemsByPath
private

◆ m_refreshTimer

QTimer RSS::Session::m_refreshTimer
private

Definition at line 164 of file rss_session.h.

Referenced by Session(), setProcessingEnabled(), and setRefreshInterval().

◆ m_storeMaxArticlesPerFeed

CachedSettingValue<int> RSS::Session::m_storeMaxArticlesPerFeed
private

Definition at line 160 of file rss_session.h.

Referenced by maxArticlesPerFeed(), and setMaxArticlesPerFeed().

◆ m_storeProcessingEnabled

CachedSettingValue<bool> RSS::Session::m_storeProcessingEnabled
private

Definition at line 158 of file rss_session.h.

Referenced by isProcessingEnabled(), and setProcessingEnabled().

◆ m_storeRefreshInterval

CachedSettingValue<int> RSS::Session::m_storeRefreshInterval
private

Definition at line 159 of file rss_session.h.

Referenced by refreshInterval(), and setRefreshInterval().

◆ m_workingThread

QThread* RSS::Session::m_workingThread
private

Definition at line 161 of file rss_session.h.

Referenced by Session(), workingThread(), and ~Session().


The documentation for this class was generated from the following files: