|
|
@ -166,7 +166,7 @@ bool Session::addFeed(const QString &url, const QString &path, QString *error) |
|
|
|
if (!destFolder) |
|
|
|
if (!destFolder) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
addItem(new Feed(url, path, this), destFolder); |
|
|
|
addItem(new Feed(generateUID(), url, path, this), destFolder); |
|
|
|
store(); |
|
|
|
store(); |
|
|
|
if (m_processingEnabled) |
|
|
|
if (m_processingEnabled) |
|
|
|
feedByURL(url)->refresh(); |
|
|
|
feedByURL(url)->refresh(); |
|
|
@ -282,36 +282,61 @@ void Session::load() |
|
|
|
|
|
|
|
|
|
|
|
void Session::loadFolder(const QJsonObject &jsonObj, Folder *folder) |
|
|
|
void Session::loadFolder(const QJsonObject &jsonObj, Folder *folder) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
bool updated = false; |
|
|
|
foreach (const QString &key, jsonObj.keys()) { |
|
|
|
foreach (const QString &key, jsonObj.keys()) { |
|
|
|
QJsonValue val = jsonObj[key]; |
|
|
|
const QJsonValue val {jsonObj[key]}; |
|
|
|
if (val.isString()) { |
|
|
|
if (val.isString()) { |
|
|
|
|
|
|
|
// previous format (reduced form) doesn't contain UID
|
|
|
|
QString url = val.toString(); |
|
|
|
QString url = val.toString(); |
|
|
|
if (url.isEmpty()) |
|
|
|
if (url.isEmpty()) |
|
|
|
url = key; |
|
|
|
url = key; |
|
|
|
addFeedToFolder(url, key, folder); |
|
|
|
addFeedToFolder(generateUID(), url, key, folder); |
|
|
|
|
|
|
|
updated = true; |
|
|
|
} |
|
|
|
} |
|
|
|
else if (!val.isObject()) { |
|
|
|
else if (val.isObject()) { |
|
|
|
Logger::instance()->addMessage( |
|
|
|
const QJsonObject valObj {val.toObject()}; |
|
|
|
QString("Couldn't load RSS Item '%1'. Invalid data format.") |
|
|
|
|
|
|
|
.arg(QString("%1\\%2").arg(folder->path(), key)), Log::WARNING); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
QJsonObject valObj = val.toObject(); |
|
|
|
|
|
|
|
if (valObj.contains("url")) { |
|
|
|
if (valObj.contains("url")) { |
|
|
|
if (!valObj["url"].isString()) { |
|
|
|
if (!valObj["url"].isString()) { |
|
|
|
Logger::instance()->addMessage( |
|
|
|
LogMsg(QString("Couldn't load RSS Feed '%1'. URL is required.") |
|
|
|
QString("Couldn't load RSS Feed '%1'. URL is required.") |
|
|
|
.arg(QString("%1\\%2").arg(folder->path(), key)), Log::WARNING); |
|
|
|
.arg(QString("%1\\%2").arg(folder->path(), key)), Log::WARNING); |
|
|
|
|
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
addFeedToFolder(valObj["url"].toString(), key, folder); |
|
|
|
QUuid uid; |
|
|
|
|
|
|
|
if (valObj.contains("uid")) { |
|
|
|
|
|
|
|
uid = QUuid {valObj["uid"].toString()}; |
|
|
|
|
|
|
|
if (uid.isNull()) { |
|
|
|
|
|
|
|
LogMsg(QString("Couldn't load RSS Feed '%1'. UID is invalid.") |
|
|
|
|
|
|
|
.arg(QString("%1\\%2").arg(folder->path(), key)), Log::WARNING); |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (m_feedsByUID.contains(uid)) { |
|
|
|
|
|
|
|
LogMsg(QString("Duplicate RSS Feed UID: %1. Configuration seems to be corrupted.") |
|
|
|
|
|
|
|
.arg(uid.toString()), Log::WARNING); |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
// previous format doesn't contain UID
|
|
|
|
|
|
|
|
uid = generateUID(); |
|
|
|
|
|
|
|
updated = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
addFeedToFolder(uid, valObj["url"].toString(), key, folder); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
loadFolder(valObj, addSubfolder(key, folder)); |
|
|
|
loadFolder(valObj, addSubfolder(key, folder)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
LogMsg(QString("Couldn't load RSS Item '%1'. Invalid data format.") |
|
|
|
|
|
|
|
.arg(QString("%1\\%2").arg(folder->path(), key)), Log::WARNING); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (updated) |
|
|
|
|
|
|
|
store(); // convert to updated format
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Session::loadLegacy() |
|
|
|
void Session::loadLegacy() |
|
|
@ -324,7 +349,7 @@ void Session::loadLegacy() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint i = 0; |
|
|
|
uint i = 0; |
|
|
|
foreach (QString legacyPath, legacyFeedPaths) { |
|
|
|
for (QString legacyPath : legacyFeedPaths) { |
|
|
|
if (Item::PathSeparator == QString(legacyPath[0])) |
|
|
|
if (Item::PathSeparator == QString(legacyPath[0])) |
|
|
|
legacyPath.remove(0, 1); |
|
|
|
legacyPath.remove(0, 1); |
|
|
|
const QString parentFolderPath = Item::parentPath(legacyPath); |
|
|
|
const QString parentFolderPath = Item::parentPath(legacyPath); |
|
|
@ -380,9 +405,9 @@ Folder *Session::addSubfolder(const QString &name, Folder *parentFolder) |
|
|
|
return folder; |
|
|
|
return folder; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Feed *Session::addFeedToFolder(const QString &url, const QString &name, Folder *parentFolder) |
|
|
|
Feed *Session::addFeedToFolder(const QUuid &uid, const QString &url, const QString &name, Folder *parentFolder) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto feed = new Feed(url, Item::joinPath(parentFolder->path(), name), this); |
|
|
|
auto feed = new Feed(uid, url, Item::joinPath(parentFolder->path(), name), this); |
|
|
|
addItem(feed, parentFolder); |
|
|
|
addItem(feed, parentFolder); |
|
|
|
return feed; |
|
|
|
return feed; |
|
|
|
} |
|
|
|
} |
|
|
@ -393,6 +418,7 @@ void Session::addItem(Item *item, Folder *destFolder) |
|
|
|
connect(feed, &Feed::titleChanged, this, &Session::handleFeedTitleChanged); |
|
|
|
connect(feed, &Feed::titleChanged, this, &Session::handleFeedTitleChanged); |
|
|
|
connect(feed, &Feed::iconLoaded, this, &Session::feedIconLoaded); |
|
|
|
connect(feed, &Feed::iconLoaded, this, &Session::feedIconLoaded); |
|
|
|
connect(feed, &Feed::stateChanged, this, &Session::feedStateChanged); |
|
|
|
connect(feed, &Feed::stateChanged, this, &Session::feedStateChanged); |
|
|
|
|
|
|
|
m_feedsByUID[feed->uid()] = feed; |
|
|
|
m_feedsByURL[feed->url()] = feed; |
|
|
|
m_feedsByURL[feed->url()] = feed; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -473,8 +499,10 @@ void Session::handleItemAboutToBeDestroyed(Item *item) |
|
|
|
{ |
|
|
|
{ |
|
|
|
m_itemsByPath.remove(item->path()); |
|
|
|
m_itemsByPath.remove(item->path()); |
|
|
|
auto feed = qobject_cast<Feed *>(item); |
|
|
|
auto feed = qobject_cast<Feed *>(item); |
|
|
|
if (feed) |
|
|
|
if (feed) { |
|
|
|
|
|
|
|
m_feedsByUID.remove(feed->uid()); |
|
|
|
m_feedsByURL.remove(feed->url()); |
|
|
|
m_feedsByURL.remove(feed->url()); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Session::handleFeedTitleChanged(Feed *feed) |
|
|
|
void Session::handleFeedTitleChanged(Feed *feed) |
|
|
@ -485,6 +513,15 @@ void Session::handleFeedTitleChanged(Feed *feed) |
|
|
|
moveItem(feed, Item::joinPath(Item::parentPath(feed->path()), feed->title())); |
|
|
|
moveItem(feed, Item::joinPath(Item::parentPath(feed->path()), feed->title())); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QUuid Session::generateUID() const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
QUuid uid = QUuid::createUuid(); |
|
|
|
|
|
|
|
while (m_feedsByUID.contains(uid)) |
|
|
|
|
|
|
|
uid = QUuid::createUuid(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return uid; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int Session::maxArticlesPerFeed() const |
|
|
|
int Session::maxArticlesPerFeed() const |
|
|
|
{ |
|
|
|
{ |
|
|
|
return m_maxArticlesPerFeed; |
|
|
|
return m_maxArticlesPerFeed; |
|
|
|