finalized experimental mergin of inoreader into greader

This commit is contained in:
Martin Rotter 2021-08-06 12:58:39 +02:00
parent c7fc631f4c
commit b068fafe42
6 changed files with 242 additions and 240 deletions

View File

@ -42,6 +42,9 @@
#define TOR_SPONSORED_STREAM_ID "tor/sponsored"
#define TOR_ITEM_CONTENTS_BATCH 9999
// Inoreader.
#define INO_ITEM_CONTENTS_BATCH 250
#define INO_HEADER_APPID "AppId"
#define INO_HEADER_APPKEY "AppKey"

View File

@ -403,10 +403,12 @@ QList<Message> GreaderNetwork::itemContents(ServiceRoot* root, const QList<QStri
QList<QString> my_stream_ids(stream_ids);
while (!my_stream_ids.isEmpty()) {
int batch = m_service == GreaderServiceRoot::Service::TheOldReader ||
m_service == GreaderServiceRoot::Service::FreshRss
int batch = (m_service == GreaderServiceRoot::Service::TheOldReader ||
m_service == GreaderServiceRoot::Service::FreshRss)
? TOR_ITEM_CONTENTS_BATCH
: GREADER_API_ITEM_CONTENTS_BATCH;
: (m_service == GreaderServiceRoot::Service::Inoreader
? INO_ITEM_CONTENTS_BATCH
: GREADER_API_ITEM_CONTENTS_BATCH);
QList<QString> batch_ids = my_stream_ids.mid(0, batch);
my_stream_ids = my_stream_ids.mid(batch);
@ -567,7 +569,8 @@ RootItem* GreaderNetwork::decodeTagsSubscriptions(const QString& categories, con
QJsonArray json;
if (m_service == GreaderServiceRoot::Service::Bazqux ||
m_service == GreaderServiceRoot::Service::Reedah) {
m_service == GreaderServiceRoot::Service::Reedah ||
m_service == GreaderServiceRoot::Service::Inoreader) {
// We need to process subscription list first and extract categories.
json = QJsonDocument::fromJson(feeds.toUtf8()).object()["subscriptions"].toArray();
@ -621,7 +624,8 @@ RootItem* GreaderNetwork::decodeTagsSubscriptions(const QString& categories, con
lbls.append(new_lbl);
}
else if ((m_service == GreaderServiceRoot::Service::Bazqux ||
m_service == GreaderServiceRoot::Service::Reedah) &&
m_service == GreaderServiceRoot::Service::Reedah ||
m_service == GreaderServiceRoot::Service::Inoreader) &&
label_id.contains(QSL("/label/"))) {
if (!cats.contains(label_id)) {
// This stream is not a category, it is label, bitches!
@ -825,13 +829,21 @@ void GreaderNetwork::setBaseUrl(const QString& base_url) {
}
QPair<QByteArray, QByteArray> GreaderNetwork::authHeader() const {
QPair<QByteArray, QByteArray> header = { QSL(HTTP_HEADERS_AUTHORIZATION).toLocal8Bit(),
QSL("GoogleLogin auth=%1").arg(m_authAuth).toLocal8Bit() };
return header;
if (m_service == GreaderServiceRoot::Service::Inoreader) {
return { QString(HTTP_HEADERS_AUTHORIZATION).toLocal8Bit(),
m_oauth2->bearer().toLocal8Bit() };
}
else {
return { QSL(HTTP_HEADERS_AUTHORIZATION).toLocal8Bit(),
QSL("GoogleLogin auth=%1").arg(m_authAuth).toLocal8Bit() };
}
}
bool GreaderNetwork::ensureLogin(const QNetworkProxy& proxy, QNetworkReply::NetworkError* output) {
if (m_service == GreaderServiceRoot::Service::Inoreader) {
return !m_oauth2->bearer().isEmpty();
}
if (m_authSid.isEmpty() && m_authAuth.isEmpty()) {
auto login = clientLogin(proxy);
@ -990,7 +1002,9 @@ void GreaderNetwork::clearCredentials() {
}
QString GreaderNetwork::sanitizedBaseUrl() const {
auto base_url = m_baseUrl;
QString base_url = m_service == GreaderServiceRoot::Service::Inoreader
? GREADER_URL_INOREADER
: m_baseUrl;
if (!base_url.endsWith('/')) {
base_url = base_url + QL1C('/');

View File

@ -29,6 +29,7 @@ class GreaderNetwork : public QObject {
explicit GreaderNetwork(QObject* parent = nullptr);
// Convenience methods.
QNetworkReply::NetworkError markMessagesRead(RootItem::ReadStatus status,
const QStringList& msg_custom_ids,
const QNetworkProxy& proxy);
@ -36,13 +37,6 @@ class GreaderNetwork : public QObject {
const QStringList& msg_custom_ids,
const QNetworkProxy& proxy);
// Assign/deassign tags to/from message(s).
QNetworkReply::NetworkError editLabels(const QString& state, bool assign,
const QStringList& msg_custom_ids, const QNetworkProxy& proxy);
QVariantHash userInfo(const QNetworkProxy& proxy);
void clearPrefetchedMessages();
void prepareFeedFetching(GreaderServiceRoot* root,
const QList<Feed*>& feeds,
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
@ -56,22 +50,12 @@ class GreaderNetwork : public QObject {
Feed::Status& error,
const QNetworkProxy& proxy);
QStringList itemIds(const QString& stream_id, bool unread_only, const QNetworkProxy& proxy, int max_count = -1);
// Stream contents for a feed/label/etc.
QList<Message> itemContents(ServiceRoot* root, const QList<QString>& stream_ids,
Feed::Status& error, const QNetworkProxy& proxy);
QList<Message> streamContents(ServiceRoot* root, const QString& stream_id,
Feed::Status& error, const QNetworkProxy& proxy);
// Downloads and structures full tree for sync-in.
RootItem* categoriesFeedsLabelsTree(bool obtain_icons, const QNetworkProxy& proxy);
// Performs client login, if successful, then saves SID, LSID and Auth.
QNetworkReply::NetworkError clientLogin(const QNetworkProxy& proxy);
void clearCredentials();
void clearPrefetchedMessages();
// Getters/setters.
GreaderServiceRoot::Service service() const;
void setService(const GreaderServiceRoot::Service& service);
@ -87,8 +71,6 @@ class GreaderNetwork : public QObject {
int batchSize() const;
void setBatchSize(int batch_size);
void clearCredentials();
bool downloadOnlyUnreadMessages() const;
void setDownloadOnlyUnreadMessages(bool download_only_unread);
@ -100,6 +82,17 @@ class GreaderNetwork : public QObject {
OAuth2Service* oauth() const;
void setOauth(OAuth2Service* oauth);
// API methods.
QNetworkReply::NetworkError editLabels(const QString& state, bool assign,
const QStringList& msg_custom_ids, const QNetworkProxy& proxy);
QVariantHash userInfo(const QNetworkProxy& proxy);
QStringList itemIds(const QString& stream_id, bool unread_only, const QNetworkProxy& proxy, int max_count = -1);
QList<Message> itemContents(ServiceRoot* root, const QList<QString>& stream_ids,
Feed::Status& error, const QNetworkProxy& proxy);
QList<Message> streamContents(ServiceRoot* root, const QString& stream_id,
Feed::Status& error, const QNetworkProxy& proxy);
QNetworkReply::NetworkError clientLogin(const QNetworkProxy& proxy);
private slots:
void onTokensError(const QString& error, const QString& error_description);
void onAuthFailed();
@ -112,13 +105,15 @@ class GreaderNetwork : public QObject {
QString convertLongStreamIdToShortStreamId(const QString& stream_id) const;
QString convertShortStreamIdToLongStreamId(const QString& stream_id) const;
QString simplifyStreamId(const QString& stream_id) const;
QStringList decodeItemIds(const QString& stream_json_data, QString& continuation);
QList<Message> decodeStreamContents(ServiceRoot* root, const QString& stream_json_data, const QString& stream_id, QString& continuation);
RootItem* decodeTagsSubscriptions(const QString& categories, const QString& feeds, bool obtain_icons, const QNetworkProxy& proxy);
QString sanitizedBaseUrl() const;
QString generateFullUrl(Operations operation) const;
void initializeOauth();
private:

View File

@ -114,6 +114,7 @@ void GreaderAccountDetails::onAuthGranted() {
try {
GreaderNetwork fac;
fac.setService(service());
fac.setOauth(m_oauth);
auto resp = fac.userInfo(m_lastProxy);

View File

@ -43,10 +43,8 @@ class GreaderAccountDetails : public QWidget {
Ui::GreaderAccountDetails m_ui;
// Testing OAuth service. This object is not ever copied
// to new living account instance, instead only its properties
// like tokens are copied.
// If editing existing account, then the pointer points
// directly to existing OAuth from the account.
// to new living account instance but maybe be copied from it,
// instead only its properties like tokens are copied.
OAuth2Service* m_oauth;
QNetworkProxy m_lastProxy;
};

View File

@ -79,208 +79,7 @@
</property>
</widget>
</item>
<item row="10" column="0" colspan="2">
<widget class="ResizableStackedWidget" name="m_stackedAuth">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="m_authClassic">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="m_gbAuthentication">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Some feeds require authentication, including GMail feeds. BASIC, NTLM-2 and DIGEST-MD5 authentication schemes are supported.</string>
</property>
<property name="title">
<string>Authentication</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Username</string>
</property>
<property name="buddy">
<cstring>m_txtUsername</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="LineEditWithStatus" name="m_txtUsername" native="true"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Password</string>
</property>
<property name="buddy">
<cstring>m_txtPassword</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="LineEditWithStatus" name="m_txtPassword" native="true"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="m_authOauth">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>OAuth 2.0 settings</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="m_lblUsername_2">
<property name="text">
<string>App ID</string>
</property>
<property name="buddy">
<cstring>m_txtAppId</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="LineEditWithStatus" name="m_txtAppId" native="true"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="m_lblUsername_3">
<property name="text">
<string>App key</string>
</property>
<property name="buddy">
<cstring>m_txtAppKey</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="LineEditWithStatus" name="m_txtAppKey" native="true"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="m_lblUsername_4">
<property name="text">
<string>Redirect URL</string>
</property>
<property name="buddy">
<cstring>m_txtRedirectUrl</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="LineEditWithStatus" name="m_txtRedirectUrl" native="true"/>
</item>
<item row="4" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QPushButton" name="m_btnRegisterApi">
<property name="text">
<string>Get my own App ID</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="m_lblInfo">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item row="11" column="0" colspan="2">
<item row="13" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="m_btnTestSetup">
@ -304,7 +103,7 @@
</item>
</layout>
</item>
<item row="12" column="0" colspan="2">
<item row="14" column="0" colspan="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -317,6 +116,198 @@
</property>
</spacer>
</item>
<item row="10" column="0" colspan="2">
<widget class="QGroupBox" name="m_gbAuth">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Authentication</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Username</string>
</property>
<property name="buddy">
<cstring>m_txtUsername</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="LineEditWithStatus" name="m_txtUsername" native="true"/>
</item>
<item row="1" column="0" colspan="2">
<widget class="ResizableStackedWidget" name="m_stackedAuth">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="m_authClassic">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QFormLayout" name="formLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Password</string>
</property>
<property name="buddy">
<cstring>m_txtPassword</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="LineEditWithStatus" name="m_txtPassword" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="m_authOauth">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>OAuth 2.0 settings</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="m_lblUsername_2">
<property name="text">
<string>App ID</string>
</property>
<property name="buddy">
<cstring>m_txtAppId</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="LineEditWithStatus" name="m_txtAppId" native="true"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="m_lblUsername_3">
<property name="text">
<string>App key</string>
</property>
<property name="buddy">
<cstring>m_txtAppKey</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="LineEditWithStatus" name="m_txtAppKey" native="true"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="m_lblUsername_4">
<property name="text">
<string>Redirect URL</string>
</property>
<property name="buddy">
<cstring>m_txtRedirectUrl</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="LineEditWithStatus" name="m_txtRedirectUrl" native="true"/>
</item>
<item row="4" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QPushButton" name="m_btnRegisterApi">
<property name="text">
<string>Get my own App ID</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="m_lblInfo">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>