34 #include <QJsonDocument>
35 #include <QJsonObject>
40 #include "../asyncfilestorage.h"
41 #include "../global.h"
42 #include "../logger.h"
43 #include "../profile.h"
44 #include "../settingsstorage.h"
45 #include "../utils/fs.h"
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))
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");
125 qDebug() <<
"Deleting RSS Session...";
133 qDebug() <<
"RSS Session deleted.";
143 const nonstd::expected<Folder *, QString> result =
prepareItemDest(path);
145 return result.get_unexpected();
147 const auto destFolder = result.value();
156 return nonstd::make_unexpected(tr(
"RSS feed with given URL already exists: %1.").arg(url));
158 const nonstd::expected<Folder *, QString> result =
prepareItemDest(path);
160 return result.get_unexpected();
162 const auto destFolder = result.value();
171 nonstd::expected<void, QString>
Session::moveItem(
const QString &itemPath,
const QString &destPath)
173 if (itemPath.isEmpty())
174 return nonstd::make_unexpected(tr(
"Cannot move root folder."));
178 return nonstd::make_unexpected(tr(
"Item doesn't exist: %1.").arg(itemPath));
188 const nonstd::expected<Folder *, QString> result =
prepareItemDest(destPath);
190 return result.get_unexpected();
193 const auto destFolder = result.value();
194 if (srcFolder != destFolder)
197 destFolder->addItem(item);
207 if (itemPath.isEmpty())
208 return nonstd::make_unexpected(tr(
"Cannot delete root folder."));
212 return nonstd::make_unexpected(tr(
"Item doesn't exist: %1.").arg(itemPath));
237 if (!itemsFile.exists())
243 if (!itemsFile.open(QFile::ReadOnly))
246 QString(
"Couldn't read RSS Session data from %1. Error: %2")
247 .arg(itemsFile.fileName(), itemsFile.errorString()),
Log::WARNING);
251 QJsonParseError jsonError;
252 const QJsonDocument jsonDoc = QJsonDocument::fromJson(itemsFile.readAll(), &jsonError);
253 if (jsonError.error != QJsonParseError::NoError)
256 QString(
"Couldn't parse RSS Session data from %1. Error: %2")
257 .arg(itemsFile.fileName(), jsonError.errorString()),
Log::WARNING);
261 if (!jsonDoc.isObject())
264 QString(
"Couldn't load RSS Session data from %1. Invalid data format.")
274 bool updated =
false;
275 for (
const QString &key :
asConst(jsonObj.keys()))
277 const QJsonValue val {jsonObj[key]};
281 QString url = val.toString();
287 else if (val.isObject())
289 const QJsonObject valObj {val.toObject()};
290 if (valObj.contains(
"url"))
292 if (!valObj[
"url"].isString())
294 LogMsg(tr(
"Couldn't load RSS Feed '%1'. URL is required.")
300 if (valObj.contains(
"uid"))
302 uid = QUuid {valObj[
"uid"].toString()};
305 LogMsg(tr(
"Couldn't load RSS Feed '%1'. UID is invalid.")
312 LogMsg(tr(
"Duplicate RSS Feed UID: %1. Configuration seems to be corrupted.")
333 LogMsg(tr(
"Couldn't load RSS Item '%1'. Invalid data format.")
334 .arg(QString::fromLatin1(
"%1\\%2").arg(folder->
path(), key)),
Log::WARNING);
346 if (legacyFeedPaths.size() != feedAliases.size())
353 for (QString legacyPath : legacyFeedPaths)
356 legacyPath.remove(0, 1);
363 const QString feedPath = feedAliases[i].isEmpty()
381 return nonstd::make_unexpected(tr(
"Incorrect RSS Item path: %1.").arg(path));
384 return nonstd::make_unexpected(tr(
"RSS item with given path already exists: %1.").arg(path));
387 const auto destFolder = qobject_cast<Folder *>(
m_itemsByPath.value(destFolderPath));
389 return nonstd::make_unexpected(tr(
"Parent folder doesn't exist: %1.").arg(destFolderPath));
410 if (
auto feed = qobject_cast<Feed *>(item))
497 auto feed = qobject_cast<Feed *>(item);
507 if (feed->
name() == feed->
url())
515 QUuid uid = QUuid::createUuid();
517 uid = QUuid::createUuid();
void failed(const QString &fileName, const QString &errorString)
void store(const QString &fileName, const QByteArray &data)
void addMessage(const QString &message, const Log::MsgType &type=Log::NORMAL)
static Logger * instance()
void iconLoaded(Feed *feed=nullptr)
void titleChanged(Feed *feed=nullptr)
void stateChanged(Feed *feed=nullptr)
void removeItem(Item *item)
static QString joinPath(const QString &path1, const QString &path2)
void pathChanged(Item *item=nullptr)
void aboutToBeDestroyed(Item *item=nullptr)
static const QChar PathSeparator
static QStringList expandPath(const QString &path)
static QString parentPath(const QString &path)
static QString relativeName(const QString &path)
void setPath(const QString &path)
static bool isValidPath(const QString &path)
int refreshInterval() const
nonstd::expected< Folder *, QString > prepareItemDest(const QString &path)
void loadFolder(const QJsonObject &jsonObj, Folder *folder)
void handleFeedTitleChanged(Feed *feed)
bool isProcessingEnabled() const
static Session * instance()
CachedSettingValue< int > m_storeRefreshInterval
QThread * workingThread() const
QHash< QString, Item * > m_itemsByPath
Feed * addFeedToFolder(const QUuid &uid, const QString &url, const QString &name, Folder *parentFolder)
AsyncFileStorage * m_dataFileStorage
void itemPathChanged(Item *item)
QList< Feed * > feeds() const
AsyncFileStorage * dataFileStorage() const
void handleItemAboutToBeDestroyed(Item *item)
nonstd::expected< void, QString > addFolder(const QString &path)
void maxArticlesPerFeedChanged(int n)
Feed * feedByURL(const QString &url) const
CachedSettingValue< bool > m_storeProcessingEnabled
CachedSettingValue< int > m_storeMaxArticlesPerFeed
int maxArticlesPerFeed() const
Folder * rootFolder() const
nonstd::expected< void, QString > addFeed(const QString &url, const QString &path)
Folder * addSubfolder(const QString &name, Folder *parentFolder)
void feedStateChanged(Feed *feed)
QUuid generateUID() const
AsyncFileStorage * confFileStorage() const
void setRefreshInterval(int refreshInterval)
Item * itemByPath(const QString &path) const
QThread * m_workingThread
void setMaxArticlesPerFeed(int n)
nonstd::expected< void, QString > moveItem(const QString &itemPath, const QString &destPath)
void processingStateChanged(bool enabled)
AsyncFileStorage * m_confFileStorage
QList< Item * > items() const
void itemAdded(Item *item)
nonstd::expected< void, QString > removeItem(const QString &itemPath)
static QPointer< Session > m_instance
QHash< QUuid, Feed * > m_feedsByUID
void feedIconLoaded(Feed *feed)
void addItem(Item *item, Folder *destFolder)
QHash< QString, Feed * > m_feedsByURL
void itemAboutToBeRemoved(Item *item)
void setProcessingEnabled(bool enabled)
T loadValue(const QString &key, const T &defaultValue={}) const
static SettingsStorage * instance()
constexpr std::add_const_t< T > & asConst(T &t) noexcept
void LogMsg(const QString &message, const Log::MsgType &type)
QString fileName(const QString &filePath)
QString expandPathAbs(const QString &path)
QString toString(const lt::socket_type_t socketType)
QString specialFolderLocation(const SpecialFolder folder)