fetch feedly username in official support too, fetch inoreader for account

This commit is contained in:
Martin Rotter 2021-04-16 09:07:26 +02:00
parent 0a1e1d1ad7
commit 991ded863a
14 changed files with 132 additions and 15 deletions

View file

@ -17,7 +17,7 @@
#include <QVariantHash> #include <QVariantHash>
FeedlyAccountDetails::FeedlyAccountDetails(QWidget* parent) : QWidget(parent) { FeedlyAccountDetails::FeedlyAccountDetails(QWidget* parent) : QWidget(parent), m_lastProxy({}) {
#if defined(FEEDLY_OFFICIAL_SUPPORT) #if defined(FEEDLY_OFFICIAL_SUPPORT)
m_oauth = nullptr; m_oauth = nullptr;
#endif #endif
@ -94,14 +94,30 @@ void FeedlyAccountDetails::onAuthError(const QString& error, const QString& deta
} }
void FeedlyAccountDetails::onAuthGranted() { void FeedlyAccountDetails::onAuthGranted() {
m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Ok, FeedlyNetwork factory;
tr("Tested successfully. You may be prompted to login once more."),
tr("Your access was approved.")); factory.setOauth(m_oauth);
try {
auto prof = factory.profile(m_lastProxy);
m_ui.m_txtUsername->lineEdit()->setText(prof["email"].toString());
m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Ok,
tr("Tested successfully. You may be prompted to login once more."),
tr("Your access was approved."));
}
catch (const ApplicationException& ex) {
qCriticalNN << LOGSEC_FEEDLY
<< "Failed to obtain profile with error:"
<< QUOTE_W_SPACE_DOT(ex.message());
}
} }
#endif #endif
void FeedlyAccountDetails::performTest(const QNetworkProxy& custom_proxy) { void FeedlyAccountDetails::performTest(const QNetworkProxy& custom_proxy) {
m_lastProxy = custom_proxy;
#if defined(FEEDLY_OFFICIAL_SUPPORT) #if defined(FEEDLY_OFFICIAL_SUPPORT)
m_oauth->logout(false); m_oauth->logout(false);
@ -113,7 +129,6 @@ void FeedlyAccountDetails::performTest(const QNetworkProxy& custom_proxy) {
FeedlyNetwork factory; FeedlyNetwork factory;
factory.setUsername(m_ui.m_txtUsername->lineEdit()->text());
factory.setDeveloperAccessToken(m_ui.m_txtDeveloperAccessToken->lineEdit()->text()); factory.setDeveloperAccessToken(m_ui.m_txtDeveloperAccessToken->lineEdit()->text());
try { try {

View file

@ -45,6 +45,8 @@ class FeedlyAccountDetails : public QWidget {
#if defined(FEEDLY_OFFICIAL_SUPPORT) #if defined(FEEDLY_OFFICIAL_SUPPORT)
OAuth2Service* m_oauth; OAuth2Service* m_oauth;
#endif #endif
QNetworkProxy m_lastProxy;
}; };
#endif // FEEDLYACCOUNTDETAILS_H #endif // FEEDLYACCOUNTDETAILS_H

View file

@ -90,11 +90,11 @@ void GmailAccountDetails::onAuthGranted() {
tr("Tested successfully. You may be prompted to login once more."), tr("Tested successfully. You may be prompted to login once more."),
tr("Your access was approved.")); tr("Your access was approved."));
GmailNetworkFactory fac;
fac.setOauth(m_oauth);
try { try {
GmailNetworkFactory fac;
fac.setOauth(m_oauth);
auto resp = fac.getProfile(m_lastProxy); auto resp = fac.getProfile(m_lastProxy);
m_ui.m_txtUsername->lineEdit()->setText(resp["emailAddress"].toString()); m_ui.m_txtUsername->lineEdit()->setText(resp["emailAddress"].toString());

View file

@ -29,6 +29,7 @@
#define GREADER_API_STREAM_CONTENTS "reader/api/0/stream/contents/%1?output=json&n=%2" #define GREADER_API_STREAM_CONTENTS "reader/api/0/stream/contents/%1?output=json&n=%2"
#define GREADER_API_EDIT_TAG "reader/api/0/edit-tag" #define GREADER_API_EDIT_TAG "reader/api/0/edit-tag"
#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"
// Misc. // Misc.
#define GREADER_API_EDIT_TAG_BATCH 200 #define GREADER_API_EDIT_TAG_BATCH 200

View file

@ -3,6 +3,8 @@
#include "services/greader/greadernetwork.h" #include "services/greader/greadernetwork.h"
#include "3rd-party/boolinq/boolinq.h" #include "3rd-party/boolinq/boolinq.h"
#include "exceptions/applicationexception.h"
#include "exceptions/networkexception.h"
#include "miscellaneous/application.h" #include "miscellaneous/application.h"
#include "network-web/networkfactory.h" #include "network-web/networkfactory.h"
#include "network-web/webfactory.h" #include "network-web/webfactory.h"
@ -90,6 +92,34 @@ QNetworkReply::NetworkError GreaderNetwork::editLabels(const QString& state,
return QNetworkReply::NetworkError::NoError; return QNetworkReply::NetworkError::NoError;
} }
QVariantHash GreaderNetwork::userInfo(const QNetworkProxy& proxy) {
QString full_url = generateFullUrl(Operations::UserInfo);
int timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
QNetworkReply::NetworkError network_err;
if (!ensureLogin(proxy, &network_err)) {
throw NetworkException(network_err);
}
QByteArray output;
auto res = NetworkFactory::performNetworkOperation(full_url,
timeout,
{},
output,
QNetworkAccessManager::Operation::GetOperation,
{ authHeader() },
false,
{},
{},
proxy);
if (res.first != QNetworkReply::NetworkError::NoError) {
throw NetworkException(res.first);
}
return QJsonDocument::fromJson(output).object().toVariantHash();
}
QNetworkReply::NetworkError GreaderNetwork::markMessagesRead(RootItem::ReadStatus status, QNetworkReply::NetworkError GreaderNetwork::markMessagesRead(RootItem::ReadStatus status,
const QStringList& msg_custom_ids, const QStringList& msg_custom_ids,
const QNetworkProxy& proxy) { const QNetworkProxy& proxy) {
@ -617,6 +647,9 @@ QString GreaderNetwork::generateFullUrl(GreaderNetwork::Operations operation) co
case Operations::StreamContents: case Operations::StreamContents:
return sanitizedBaseUrl() + GREADER_API_STREAM_CONTENTS; return sanitizedBaseUrl() + GREADER_API_STREAM_CONTENTS;
case Operations::UserInfo:
return sanitizedBaseUrl() + GREADER_API_USER_INFO;
case Operations::EditTag: case Operations::EditTag:
return sanitizedBaseUrl() + GREADER_API_EDIT_TAG; return sanitizedBaseUrl() + GREADER_API_EDIT_TAG;

View file

@ -19,7 +19,8 @@ class GreaderNetwork : public QObject {
SubscriptionList, SubscriptionList,
StreamContents, StreamContents,
EditTag, EditTag,
Token Token,
UserInfo
}; };
explicit GreaderNetwork(QObject* parent = nullptr); explicit GreaderNetwork(QObject* parent = nullptr);
@ -35,6 +36,8 @@ class GreaderNetwork : public QObject {
QNetworkReply::NetworkError editLabels(const QString& state, bool assign, QNetworkReply::NetworkError editLabels(const QString& state, bool assign,
const QStringList& msg_custom_ids, const QNetworkProxy& proxy); const QStringList& msg_custom_ids, const QNetworkProxy& proxy);
QVariantHash userInfo(const QNetworkProxy& proxy);
// Stream contents for a feed/label/etc. // Stream contents for a feed/label/etc.
QList<Message> streamContents(ServiceRoot* root, const QString& stream_id, QList<Message> streamContents(ServiceRoot* root, const QString& stream_id,
Feed::Status& error, const QNetworkProxy& proxy); Feed::Status& error, const QNetworkProxy& proxy);

View file

@ -3,11 +3,14 @@
#include "services/greader/gui/greaderaccountdetails.h" #include "services/greader/gui/greaderaccountdetails.h"
#include "definitions/definitions.h" #include "definitions/definitions.h"
#include "exceptions/applicationexception.h"
#include "gui/guiutilities.h" #include "gui/guiutilities.h"
#include "miscellaneous/systemfactory.h" #include "miscellaneous/systemfactory.h"
#include "services/greader/definitions.h" #include "services/greader/definitions.h"
#include "services/greader/greadernetwork.h" #include "services/greader/greadernetwork.h"
#include <QVariantHash>
GreaderAccountDetails::GreaderAccountDetails(QWidget* parent) : QWidget(parent) { GreaderAccountDetails::GreaderAccountDetails(QWidget* parent) : QWidget(parent) {
m_ui.setupUi(this); m_ui.setupUi(this);

View file

@ -29,5 +29,6 @@
#define INOREADER_API_LIST_LABELS "https://www.inoreader.com/reader/api/0/tag/list?types=1" #define INOREADER_API_LIST_LABELS "https://www.inoreader.com/reader/api/0/tag/list?types=1"
#define INOREADER_API_LIST_FEEDS "https://www.inoreader.com/reader/api/0/subscription/list" #define INOREADER_API_LIST_FEEDS "https://www.inoreader.com/reader/api/0/subscription/list"
#define INOREADER_API_EDIT_TAG "https://www.inoreader.com/reader/api/0/edit-tag" #define INOREADER_API_EDIT_TAG "https://www.inoreader.com/reader/api/0/edit-tag"
#define INOREADER_API_USER_INFO "https://www.inoreader.com/reader/api/0/user-info"
#endif // INOREADER_DEFINITIONS_H #endif // INOREADER_DEFINITIONS_H

View file

@ -19,6 +19,8 @@ FormEditInoreaderAccount::FormEditInoreaderAccount(QWidget* parent)
insertCustomTab(m_details, tr("Server setup"), 0); insertCustomTab(m_details, tr("Server setup"), 0);
activateTab(0); activateTab(0);
connect(m_details->m_ui.m_btnTestSetup, &QPushButton::clicked, this, &FormEditInoreaderAccount::testSetup);
m_details->m_ui.m_txtUsername->setFocus(); m_details->m_ui.m_txtUsername->setFocus();
} }
@ -58,3 +60,7 @@ void FormEditInoreaderAccount::loadAccountData() {
m_details->m_ui.m_spinLimitMessages->setValue(account<InoreaderServiceRoot>()->network()->batchSize()); m_details->m_ui.m_spinLimitMessages->setValue(account<InoreaderServiceRoot>()->network()->batchSize());
m_details->m_ui.m_cbDownloadOnlyUnreadMessages->setChecked(account<InoreaderServiceRoot>()->network()->downloadOnlyUnreadMessages()); m_details->m_ui.m_cbDownloadOnlyUnreadMessages->setChecked(account<InoreaderServiceRoot>()->network()->downloadOnlyUnreadMessages());
} }
void FormEditInoreaderAccount::testSetup() {
m_details->testSetup(m_proxyDetails->proxy());
}

View file

@ -20,6 +20,9 @@ class FormEditInoreaderAccount : public FormAccountDetails {
protected: protected:
virtual void loadAccountData(); virtual void loadAccountData();
private slots:
void testSetup();
private: private:
InoreaderAccountDetails* m_details; InoreaderAccountDetails* m_details;
}; };

View file

@ -2,6 +2,7 @@
#include "services/inoreader/gui/inoreaderaccountdetails.h" #include "services/inoreader/gui/inoreaderaccountdetails.h"
#include "exceptions/applicationexception.h"
#include "gui/guiutilities.h" #include "gui/guiutilities.h"
#include "miscellaneous/application.h" #include "miscellaneous/application.h"
#include "network-web/oauth2service.h" #include "network-web/oauth2service.h"
@ -10,7 +11,7 @@
#include "services/inoreader/inoreadernetworkfactory.h" #include "services/inoreader/inoreadernetworkfactory.h"
InoreaderAccountDetails::InoreaderAccountDetails(QWidget* parent) InoreaderAccountDetails::InoreaderAccountDetails(QWidget* parent)
: QWidget(parent), m_oauth(nullptr) { : QWidget(parent), m_oauth(nullptr), m_lastProxy({}) {
m_ui.setupUi(this); m_ui.setupUi(this);
GuiUtilities::setLabelAsNotice(*m_ui.m_lblInfo, true); GuiUtilities::setLabelAsNotice(*m_ui.m_lblInfo, true);
@ -43,7 +44,6 @@ InoreaderAccountDetails::InoreaderAccountDetails(QWidget* parent)
connect(m_ui.m_txtAppKey->lineEdit(), &BaseLineEdit::textChanged, this, &InoreaderAccountDetails::checkOAuthValue); connect(m_ui.m_txtAppKey->lineEdit(), &BaseLineEdit::textChanged, this, &InoreaderAccountDetails::checkOAuthValue);
connect(m_ui.m_txtRedirectUrl->lineEdit(), &BaseLineEdit::textChanged, this, &InoreaderAccountDetails::checkOAuthValue); connect(m_ui.m_txtRedirectUrl->lineEdit(), &BaseLineEdit::textChanged, this, &InoreaderAccountDetails::checkOAuthValue);
connect(m_ui.m_txtUsername->lineEdit(), &BaseLineEdit::textChanged, this, &InoreaderAccountDetails::checkUsername); connect(m_ui.m_txtUsername->lineEdit(), &BaseLineEdit::textChanged, this, &InoreaderAccountDetails::checkUsername);
connect(m_ui.m_btnTestSetup, &QPushButton::clicked, this, &InoreaderAccountDetails::testSetup);
connect(m_ui.m_btnRegisterApi, &QPushButton::clicked, this, &InoreaderAccountDetails::registerApi); connect(m_ui.m_btnRegisterApi, &QPushButton::clicked, this, &InoreaderAccountDetails::registerApi);
emit m_ui.m_txtUsername->lineEdit()->textChanged(m_ui.m_txtUsername->lineEdit()->text()); emit m_ui.m_txtUsername->lineEdit()->textChanged(m_ui.m_txtUsername->lineEdit()->text());
@ -54,12 +54,13 @@ InoreaderAccountDetails::InoreaderAccountDetails(QWidget* parent)
hookNetwork(); hookNetwork();
} }
void InoreaderAccountDetails::testSetup() { void InoreaderAccountDetails::testSetup(const QNetworkProxy& custom_proxy) {
m_lastProxy = custom_proxy;
m_oauth->logout(); m_oauth->logout();
m_oauth->setClientId(m_ui.m_txtAppId->lineEdit()->text()); m_oauth->setClientId(m_ui.m_txtAppId->lineEdit()->text());
m_oauth->setClientSecret(m_ui.m_txtAppKey->lineEdit()->text()); m_oauth->setClientSecret(m_ui.m_txtAppKey->lineEdit()->text());
m_oauth->setRedirectUrl(m_ui.m_txtRedirectUrl->lineEdit()->text()); m_oauth->setRedirectUrl(m_ui.m_txtRedirectUrl->lineEdit()->text());
m_oauth->login(); m_oauth->login();
} }
@ -90,6 +91,21 @@ void InoreaderAccountDetails::onAuthGranted() {
m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Ok, m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Ok,
tr("Tested successfully. You may be prompted to login once more."), tr("Tested successfully. You may be prompted to login once more."),
tr("Your access was approved.")); tr("Your access was approved."));
try {
InoreaderNetworkFactory fac;
fac.setOauth(m_oauth);
auto resp = fac.userInfo(m_lastProxy);
m_ui.m_txtUsername->lineEdit()->setText(resp["userEmail"].toString());
}
catch (const ApplicationException& ex) {
qCriticalNN << LOGSEC_INOREADER
<< "Failed to obtain profile with error:"
<< QUOTE_W_SPACE_DOT(ex.message());
}
} }
void InoreaderAccountDetails::hookNetwork() { void InoreaderAccountDetails::hookNetwork() {

View file

@ -7,6 +7,8 @@
#include "ui_inoreaderaccountdetails.h" #include "ui_inoreaderaccountdetails.h"
#include <QNetworkProxy>
class OAuth2Service; class OAuth2Service;
class InoreaderAccountDetails : public QWidget { class InoreaderAccountDetails : public QWidget {
@ -19,7 +21,7 @@ class InoreaderAccountDetails : public QWidget {
private slots: private slots:
void registerApi(); void registerApi();
void testSetup();; void testSetup(const QNetworkProxy& custom_proxy);;
void checkOAuthValue(const QString& value); void checkOAuthValue(const QString& value);
void checkUsername(const QString& username); void checkUsername(const QString& username);
void onAuthFailed(); void onAuthFailed();
@ -38,6 +40,7 @@ class InoreaderAccountDetails : public QWidget {
// If editing existing account, then the pointer points // If editing existing account, then the pointer points
// directly to existing OAuth from the account. // directly to existing OAuth from the account.
OAuth2Service* m_oauth; OAuth2Service* m_oauth;
QNetworkProxy m_lastProxy;
}; };
#endif // INOREADERACCOUNTDETAILS_H #endif // INOREADERACCOUNTDETAILS_H

View file

@ -5,6 +5,8 @@
#include "3rd-party/boolinq/boolinq.h" #include "3rd-party/boolinq/boolinq.h"
#include "database/databasequeries.h" #include "database/databasequeries.h"
#include "definitions/definitions.h" #include "definitions/definitions.h"
#include "exceptions/applicationexception.h"
#include "exceptions/networkexception.h"
#include "gui/dialogs/formmain.h" #include "gui/dialogs/formmain.h"
#include "gui/tabwidget.h" #include "gui/tabwidget.h"
#include "miscellaneous/application.h" #include "miscellaneous/application.h"
@ -131,6 +133,34 @@ RootItem* InoreaderNetworkFactory::feedsCategories(bool obtain_icons) {
return decodeFeedCategoriesData(output_labels, output_feeds, obtain_icons); return decodeFeedCategoriesData(output_labels, output_feeds, obtain_icons);
} }
QVariantHash InoreaderNetworkFactory::userInfo(const QNetworkProxy& custom_proxy) {
QString bearer = m_oauth2->bearer().toLocal8Bit();
if (bearer.isEmpty()) {
throw ApplicationException(tr("not logged in"));
}
int timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
QByteArray output;
auto res = NetworkFactory::performNetworkOperation(INOREADER_API_USER_INFO,
timeout,
{},
output,
QNetworkAccessManager::Operation::GetOperation,
{ { QString(HTTP_HEADERS_AUTHORIZATION).toLocal8Bit(),
bearer.toLocal8Bit() } },
false,
{},
{},
custom_proxy);
if (res.first != QNetworkReply::NetworkError::NoError) {
throw NetworkException(res.first);
}
return QJsonDocument::fromJson(output).object().toVariantHash();
}
QList<RootItem*> InoreaderNetworkFactory::getLabels() { QList<RootItem*> InoreaderNetworkFactory::getLabels() {
QList<RootItem*> lbls; QList<RootItem*> lbls;
QString bearer = m_oauth2->bearer().toLocal8Bit(); QString bearer = m_oauth2->bearer().toLocal8Bit();

View file

@ -39,6 +39,7 @@ class InoreaderNetworkFactory : public QObject {
// Returned items do not have primary IDs assigned. // Returned items do not have primary IDs assigned.
RootItem* feedsCategories(bool obtain_icons); RootItem* feedsCategories(bool obtain_icons);
QVariantHash userInfo(const QNetworkProxy& custom_proxy);
QList<RootItem*> getLabels(); QList<RootItem*> getLabels();
QList<Message> messages(ServiceRoot* root, const QString& stream_id, Feed::Status& error); QList<Message> messages(ServiceRoot* root, const QString& stream_id, Feed::Status& error);
QNetworkReply::NetworkError editLabels(const QString& state, bool assign, const QStringList& msg_custom_ids); QNetworkReply::NetworkError editLabels(const QString& state, bool assign, const QStringList& msg_custom_ids);