greader supports feed deleting
This commit is contained in:
parent
80392d4c05
commit
caecf5355a
|
@ -30,7 +30,7 @@ else {
|
||||||
$is_qt_6 = $qt_version.StartsWith("6")
|
$is_qt_6 = $qt_version.StartsWith("6")
|
||||||
|
|
||||||
$maria_version = "11.1.2"
|
$maria_version = "11.1.2"
|
||||||
$maria_link = "https://archive.mariadb.org/mariadb-$maria_version/winx64-packages/mariadb-$maria_version-winx64.zip"
|
$maria_link = "https://mirror.netcologne.de/mariadb/mariadb-$maria_version/winx64-packages/mariadb-$maria_version-winx64.zip"
|
||||||
$maria_output = "maria.zip"
|
$maria_output = "maria.zip"
|
||||||
|
|
||||||
$cmake_version = "3.27.7"
|
$cmake_version = "3.27.7"
|
||||||
|
|
|
@ -352,10 +352,16 @@ set(SOURCES
|
||||||
services/greader/greadernetwork.h
|
services/greader/greadernetwork.h
|
||||||
services/greader/greaderserviceroot.cpp
|
services/greader/greaderserviceroot.cpp
|
||||||
services/greader/greaderserviceroot.h
|
services/greader/greaderserviceroot.h
|
||||||
|
services/greader/greaderfeed.cpp
|
||||||
|
services/greader/greaderfeed.h
|
||||||
services/greader/gui/formeditgreaderaccount.cpp
|
services/greader/gui/formeditgreaderaccount.cpp
|
||||||
services/greader/gui/formeditgreaderaccount.h
|
services/greader/gui/formeditgreaderaccount.h
|
||||||
services/greader/gui/greaderaccountdetails.cpp
|
services/greader/gui/greaderaccountdetails.cpp
|
||||||
services/greader/gui/greaderaccountdetails.h
|
services/greader/gui/greaderaccountdetails.h
|
||||||
|
services/greader/gui/formgreaderfeeddetails.cpp
|
||||||
|
services/greader/gui/formgreaderfeeddetails.h
|
||||||
|
services/greader/gui/greaderfeeddetails.cpp
|
||||||
|
services/greader/gui/greaderfeeddetails.h
|
||||||
services/owncloud/definitions.h
|
services/owncloud/definitions.h
|
||||||
services/owncloud/gui/formeditowncloudaccount.cpp
|
services/owncloud/gui/formeditowncloudaccount.cpp
|
||||||
services/owncloud/gui/formeditowncloudaccount.h
|
services/owncloud/gui/formeditowncloudaccount.h
|
||||||
|
@ -487,6 +493,7 @@ set(UI_FILES
|
||||||
services/gmail/gui/formaddeditemail.ui
|
services/gmail/gui/formaddeditemail.ui
|
||||||
services/gmail/gui/gmailaccountdetails.ui
|
services/gmail/gui/gmailaccountdetails.ui
|
||||||
services/greader/gui/greaderaccountdetails.ui
|
services/greader/gui/greaderaccountdetails.ui
|
||||||
|
services/greader/gui/greaderfeeddetails.ui
|
||||||
services/owncloud/gui/owncloudaccountdetails.ui
|
services/owncloud/gui/owncloudaccountdetails.ui
|
||||||
services/reddit/gui/redditaccountdetails.ui
|
services/reddit/gui/redditaccountdetails.ui
|
||||||
services/standard/gui/formdiscoverfeeds.ui
|
services/standard/gui/formdiscoverfeeds.ui
|
||||||
|
|
|
@ -29,11 +29,17 @@
|
||||||
#define GREADER_API_EDIT_TAG "reader/api/0/edit-tag"
|
#define GREADER_API_EDIT_TAG "reader/api/0/edit-tag"
|
||||||
#define GREADER_API_SUBSCRIPTION_EXPORT "reader/api/0/subscription/export"
|
#define GREADER_API_SUBSCRIPTION_EXPORT "reader/api/0/subscription/export"
|
||||||
#define GREADER_API_SUBSCRIPTION_IMPORT "reader/api/0/subscription/import"
|
#define GREADER_API_SUBSCRIPTION_IMPORT "reader/api/0/subscription/import"
|
||||||
|
#define GREADER_API_SUBSCRIPTION_EDIT "reader/api/0/subscription/edit?ac=%1&s=%2"
|
||||||
#define GREADER_API_ITEM_IDS "reader/api/0/stream/items/ids?output=json&n=%2&s=%1"
|
#define GREADER_API_ITEM_IDS "reader/api/0/stream/items/ids?output=json&n=%2&s=%1"
|
||||||
#define GREADER_API_ITEM_CONTENTS "reader/api/0/stream/items/contents?output=json&n=200000"
|
#define GREADER_API_ITEM_CONTENTS "reader/api/0/stream/items/contents?output=json&n=200000"
|
||||||
#define GREADER_API_TOKEN "reader/api/0/token"
|
#define GREADER_API_TOKEN "reader/api/0/token"
|
||||||
#define GREADER_API_USER_INFO "reader/api/0/user-info?output=json"
|
#define GREADER_API_USER_INFO "reader/api/0/user-info?output=json"
|
||||||
|
|
||||||
|
// Edit subscription ops.
|
||||||
|
#define GREADER_API_EDIT_SUBSCRIPTION_ADD "subscribe"
|
||||||
|
#define GREADER_API_EDIT_SUBSCRIPTION_MODIFY "edit"
|
||||||
|
#define GREADER_API_EDIT_SUBSCRIPTION_DELETE "unsubscribe"
|
||||||
|
|
||||||
// Misc.
|
// Misc.
|
||||||
#define GREADER_API_ITEM_IDS_MAX 200000
|
#define GREADER_API_ITEM_IDS_MAX 200000
|
||||||
#define GREADER_API_EDIT_TAG_BATCH 200
|
#define GREADER_API_EDIT_TAG_BATCH 200
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "services/abstract/label.h"
|
#include "services/abstract/label.h"
|
||||||
#include "services/abstract/labelsnode.h"
|
#include "services/abstract/labelsnode.h"
|
||||||
#include "services/greader/definitions.h"
|
#include "services/greader/definitions.h"
|
||||||
|
#include "services/greader/greaderfeed.h"
|
||||||
|
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
@ -341,6 +342,57 @@ QNetworkReply::NetworkError GreaderNetwork::markMessagesStarred(RootItem::Import
|
||||||
proxy);
|
proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GreaderNetwork::subscriptionEdit(const QString& op,
|
||||||
|
const QString& stream_id,
|
||||||
|
const QString& new_title,
|
||||||
|
const QString& set_label,
|
||||||
|
const QString& unset_label,
|
||||||
|
const QNetworkProxy& proxy) {
|
||||||
|
if (!ensureLogin(proxy)) {
|
||||||
|
throw ApplicationException(tr("login failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString full_url = generateFullUrl(Operations::SubscriptionEdit).arg(op, stream_id);
|
||||||
|
|
||||||
|
if (op == QSL(GREADER_API_EDIT_SUBSCRIPTION_ADD)) {
|
||||||
|
full_url += QSL("&t=%1").arg(new_title);
|
||||||
|
|
||||||
|
if (!set_label.isEmpty()) {
|
||||||
|
full_url += QSL("&a=%1").arg(set_label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op == QSL(GREADER_API_EDIT_SUBSCRIPTION_MODIFY)) {
|
||||||
|
full_url += QSL("&t=%1").arg(new_title);
|
||||||
|
|
||||||
|
if (!set_label.isEmpty()) {
|
||||||
|
full_url += QSL("&a=%1").arg(set_label);
|
||||||
|
}
|
||||||
|
else if (!unset_label.isEmpty()) {
|
||||||
|
full_url += QSL("&r=%1").arg(unset_label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
|
||||||
|
|
||||||
|
QByteArray output;
|
||||||
|
auto result = NetworkFactory::performNetworkOperation(full_url,
|
||||||
|
timeout,
|
||||||
|
{},
|
||||||
|
output,
|
||||||
|
QNetworkAccessManager::Operation::PostOperation,
|
||||||
|
{authHeader()},
|
||||||
|
false,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
proxy);
|
||||||
|
|
||||||
|
if (result.m_networkError != QNetworkReply::NetworkError::NoError) {
|
||||||
|
qCriticalNN << LOGSEC_GREADER << "Cannot edit subscription:" << QUOTE_W_SPACE_DOT(result.m_networkError);
|
||||||
|
throw NetworkException(result.m_networkError, output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GreaderNetwork::subscriptionImport(const QByteArray& opml_data, const QNetworkProxy& proxy) {
|
void GreaderNetwork::subscriptionImport(const QByteArray& opml_data, const QNetworkProxy& proxy) {
|
||||||
if (!ensureLogin(proxy)) {
|
if (!ensureLogin(proxy)) {
|
||||||
throw ApplicationException(tr("login failed"));
|
throw ApplicationException(tr("login failed"));
|
||||||
|
@ -749,7 +801,7 @@ RootItem* GreaderNetwork::decodeTagsSubscriptions(const QString& categories,
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have label (not "state").
|
// We have label (not "state").
|
||||||
auto* feed = new Feed();
|
auto* feed = new GreaderFeed();
|
||||||
|
|
||||||
feed->setDescription(url);
|
feed->setDescription(url);
|
||||||
feed->setSource(url);
|
feed->setSource(url);
|
||||||
|
@ -1127,6 +1179,9 @@ QString GreaderNetwork::generateFullUrl(GreaderNetwork::Operations operation) co
|
||||||
case Operations::SubscriptionImport:
|
case Operations::SubscriptionImport:
|
||||||
return sanitizedBaseUrl() + QSL(GREADER_API_SUBSCRIPTION_IMPORT);
|
return sanitizedBaseUrl() + QSL(GREADER_API_SUBSCRIPTION_IMPORT);
|
||||||
|
|
||||||
|
case Operations::SubscriptionEdit:
|
||||||
|
return sanitizedBaseUrl() + QSL(GREADER_API_SUBSCRIPTION_EDIT);
|
||||||
|
|
||||||
case Operations::Token:
|
case Operations::Token:
|
||||||
return sanitizedBaseUrl() + QSL(GREADER_API_TOKEN);
|
return sanitizedBaseUrl() + QSL(GREADER_API_TOKEN);
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,8 @@ class GreaderNetwork : public QObject {
|
||||||
ItemIds,
|
ItemIds,
|
||||||
ItemContents,
|
ItemContents,
|
||||||
SubscriptionExport,
|
SubscriptionExport,
|
||||||
SubscriptionImport
|
SubscriptionImport,
|
||||||
|
SubscriptionEdit
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit GreaderNetwork(QObject* parent = nullptr);
|
explicit GreaderNetwork(QObject* parent = nullptr);
|
||||||
|
@ -84,6 +85,12 @@ class GreaderNetwork : public QObject {
|
||||||
void setOauth(OAuth2Service* oauth);
|
void setOauth(OAuth2Service* oauth);
|
||||||
|
|
||||||
// API methods.
|
// API methods.
|
||||||
|
void subscriptionEdit(const QString& op,
|
||||||
|
const QString& stream_id,
|
||||||
|
const QString& new_title,
|
||||||
|
const QString& set_label,
|
||||||
|
const QString& unset_label,
|
||||||
|
const QNetworkProxy& proxy);
|
||||||
void subscriptionImport(const QByteArray& opml_data, const QNetworkProxy& proxy);
|
void subscriptionImport(const QByteArray& opml_data, const QNetworkProxy& proxy);
|
||||||
QByteArray subscriptionExport(const QNetworkProxy& proxy);
|
QByteArray subscriptionExport(const QNetworkProxy& proxy);
|
||||||
QNetworkReply::NetworkError editLabels(const QString& state,
|
QNetworkReply::NetworkError editLabels(const QString& state,
|
||||||
|
|
|
@ -7,12 +7,15 @@
|
||||||
#include "gui/messagebox.h"
|
#include "gui/messagebox.h"
|
||||||
#include "miscellaneous/application.h"
|
#include "miscellaneous/application.h"
|
||||||
#include "miscellaneous/iconfactory.h"
|
#include "miscellaneous/iconfactory.h"
|
||||||
|
#include "miscellaneous/mutex.h"
|
||||||
#include "miscellaneous/textfactory.h"
|
#include "miscellaneous/textfactory.h"
|
||||||
#include "network-web/oauth2service.h"
|
#include "network-web/oauth2service.h"
|
||||||
#include "services/greader/definitions.h"
|
#include "services/greader/definitions.h"
|
||||||
#include "services/greader/greaderentrypoint.h"
|
#include "services/greader/greaderentrypoint.h"
|
||||||
|
#include "services/greader/greaderfeed.h"
|
||||||
#include "services/greader/greadernetwork.h"
|
#include "services/greader/greadernetwork.h"
|
||||||
#include "services/greader/gui/formeditgreaderaccount.h"
|
#include "services/greader/gui/formeditgreaderaccount.h"
|
||||||
|
#include "services/greader/gui/formgreaderfeeddetails.h"
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
|
||||||
|
@ -211,7 +214,7 @@ bool GreaderServiceRoot::wantsBaggedIdsOfExistingMessages() const {
|
||||||
|
|
||||||
void GreaderServiceRoot::start(bool freshly_activated) {
|
void GreaderServiceRoot::start(bool freshly_activated) {
|
||||||
if (!freshly_activated) {
|
if (!freshly_activated) {
|
||||||
DatabaseQueries::loadRootFromDatabase<Category, Feed>(this);
|
DatabaseQueries::loadRootFromDatabase<Category, GreaderFeed>(this);
|
||||||
loadCacheFromFile();
|
loadCacheFromFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,6 +334,32 @@ ServiceRoot::LabelOperation GreaderServiceRoot::supportedLabelOperations() const
|
||||||
return ServiceRoot::LabelOperation::Synchronised;
|
return ServiceRoot::LabelOperation::Synchronised;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GreaderServiceRoot::supportsFeedAdding() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GreaderServiceRoot::addNewFeed(RootItem* selected_item, const QString& url) {
|
||||||
|
if (!qApp->feedUpdateLock()->tryLock()) {
|
||||||
|
// Lock was not obtained because
|
||||||
|
// it is used probably by feed updater or application
|
||||||
|
// is quitting.
|
||||||
|
qApp->showGuiMessage(Notification::Event::GeneralEvent,
|
||||||
|
{tr("Cannot add item"),
|
||||||
|
tr("Cannot add feed because another critical operation is ongoing."),
|
||||||
|
QSystemTrayIcon::MessageIcon::Warning});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QScopedPointer<FormGreaderFeedDetails> form_pointer(new FormGreaderFeedDetails(this,
|
||||||
|
selected_item,
|
||||||
|
url,
|
||||||
|
qApp->mainFormWidget()));
|
||||||
|
|
||||||
|
form_pointer->addEditFeed<GreaderFeed>();
|
||||||
|
qApp->feedUpdateLock()->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
void GreaderServiceRoot::updateTitleIcon() {
|
void GreaderServiceRoot::updateTitleIcon() {
|
||||||
setTitle(QSL("%1 (%2)").arg(TextFactory::extractUsernameFromEmail(m_network->username()),
|
setTitle(QSL("%1 (%2)").arg(TextFactory::extractUsernameFromEmail(m_network->username()),
|
||||||
GreaderServiceRoot::serviceToString(m_network->service())));
|
GreaderServiceRoot::serviceToString(m_network->service())));
|
||||||
|
|
|
@ -35,6 +35,8 @@ class GreaderServiceRoot : public ServiceRoot, public CacheForServiceRoot {
|
||||||
virtual QList<QAction*> serviceMenu();
|
virtual QList<QAction*> serviceMenu();
|
||||||
virtual void saveAllCachedData(bool ignore_errors);
|
virtual void saveAllCachedData(bool ignore_errors);
|
||||||
virtual LabelOperation supportedLabelOperations() const;
|
virtual LabelOperation supportedLabelOperations() const;
|
||||||
|
virtual bool supportsFeedAdding() const;
|
||||||
|
virtual void addNewFeed(RootItem* selected_item, const QString& url = QString());
|
||||||
virtual QVariantHash customDatabaseData() const;
|
virtual QVariantHash customDatabaseData() const;
|
||||||
virtual void setCustomDatabaseData(const QVariantHash& data);
|
virtual void setCustomDatabaseData(const QVariantHash& data);
|
||||||
virtual void aboutToBeginFeedFetching(const QList<Feed*>& feeds,
|
virtual void aboutToBeginFeedFetching(const QList<Feed*>& feeds,
|
||||||
|
|
|
@ -29,7 +29,7 @@ void FormTtRssFeedDetails::apply() {
|
||||||
else {
|
else {
|
||||||
RootItem* parent = m_feedDetails->ui.m_cmbParentCategory->currentData().value<RootItem*>();
|
RootItem* parent = m_feedDetails->ui.m_cmbParentCategory->currentData().value<RootItem*>();
|
||||||
auto* root = qobject_cast<TtRssServiceRoot*>(parent->getParentServiceRoot());
|
auto* root = qobject_cast<TtRssServiceRoot*>(parent->getParentServiceRoot());
|
||||||
const int category_id = parent->kind() == RootItem::Kind::ServiceRoot ? 0 : parent->customId().toInt();
|
const int category_id = parent->kind() == RootItem::Kind::ServiceRoot ? 0 : parent->customNumericId();
|
||||||
const TtRssSubscribeToFeedResponse response =
|
const TtRssSubscribeToFeedResponse response =
|
||||||
root->network()->subscribeToFeed(m_feedDetails->ui.m_txtUrl->lineEdit()->text(),
|
root->network()->subscribeToFeed(m_feedDetails->ui.m_txtUrl->lineEdit()->text(),
|
||||||
category_id,
|
category_id,
|
||||||
|
@ -66,11 +66,6 @@ void FormTtRssFeedDetails::loadFeedData() {
|
||||||
if (!m_urlToProcess.isEmpty()) {
|
if (!m_urlToProcess.isEmpty()) {
|
||||||
m_feedDetails->ui.m_txtUrl->lineEdit()->setText(m_urlToProcess);
|
m_feedDetails->ui.m_txtUrl->lineEdit()->setText(m_urlToProcess);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
else if (Application::clipboard()->mimeData()->hasText()) {
|
|
||||||
m_feedDetails->ui.m_txtUrl->lineEdit()->setText(Application::clipboard()->text());
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
m_feedDetails->ui.m_txtUrl->lineEdit()->selectAll();
|
m_feedDetails->ui.m_txtUrl->lineEdit()->selectAll();
|
||||||
m_feedDetails->ui.m_txtUrl->setFocus();
|
m_feedDetails->ui.m_txtUrl->setFocus();
|
||||||
|
|
|
@ -11,8 +11,10 @@ class AuthenticationDetails;
|
||||||
|
|
||||||
class FormTtRssFeedDetails : public FormFeedDetails {
|
class FormTtRssFeedDetails : public FormFeedDetails {
|
||||||
public:
|
public:
|
||||||
explicit FormTtRssFeedDetails(ServiceRoot* service_root, RootItem* parent_to_select = nullptr,
|
explicit FormTtRssFeedDetails(ServiceRoot* service_root,
|
||||||
const QString& url = QString(), QWidget* parent = nullptr);
|
RootItem* parent_to_select = nullptr,
|
||||||
|
const QString& url = QString(),
|
||||||
|
QWidget* parent = nullptr);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
virtual void apply();
|
virtual void apply();
|
||||||
|
|
Loading…
Reference in New Issue