mirror of
https://github.com/martinrotter/rssguard.git
synced 2025-01-30 09:04:52 +01:00
Migrate to new gmail api batch endpoint.
This commit is contained in:
parent
7e06964b82
commit
252cc59b8d
@ -83,6 +83,8 @@
|
||||
#define HTTP_HEADERS_AUTHORIZATION "Authorization"
|
||||
#define HTTP_HEADERS_USER_AGENT "User-Agent"
|
||||
|
||||
#define LOGSEC_NETWORK "network: "
|
||||
#define LOGSEC_ADBLOCK "adblock: "
|
||||
#define LOGSEC_FEEDMODEL "feed-model: "
|
||||
#define LOGSEC_FEEDDOWNLOADER "feed-downloader: "
|
||||
#define LOGSEC_MESSAGEMODEL "message-model: "
|
||||
|
@ -1874,6 +1874,27 @@ bool DatabaseQueries::deleteGmailAccount(const QSqlDatabase& db, int account_id)
|
||||
return q.exec();
|
||||
}
|
||||
|
||||
bool DatabaseQueries::storeNewGmailTokens(const QSqlDatabase& db, const QString& refresh_token, int account_id) {
|
||||
QSqlQuery query(db);
|
||||
|
||||
query.prepare("UPDATE GmailAccounts "
|
||||
"SET refresh_token = :refresh_token "
|
||||
"WHERE id = :id;");
|
||||
query.bindValue(QSL(":refresh_token"), refresh_token);
|
||||
query.bindValue(QSL(":id"), account_id);
|
||||
|
||||
if (query.exec()) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
qWarningNN << LOGSEC_GMAIL
|
||||
<< "Updating tokens in DB failed: '"
|
||||
<< query.lastError().text()
|
||||
<< "'.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool DatabaseQueries::deleteInoreaderAccount(const QSqlDatabase& db, int account_id) {
|
||||
QSqlQuery q(db);
|
||||
|
||||
|
@ -147,6 +147,7 @@ class DatabaseQueries {
|
||||
// Gmail account.
|
||||
static QStringList getAllRecipients(const QSqlDatabase& db, int account_id);
|
||||
static bool deleteGmailAccount(const QSqlDatabase& db, int account_id);
|
||||
static bool storeNewGmailTokens(const QSqlDatabase& db, const QString& refresh_token, int account_id);
|
||||
static QList<ServiceRoot*> getGmailAccounts(const QSqlDatabase& db, bool* ok = nullptr);
|
||||
static bool overwriteGmailAccount(const QSqlDatabase& db, const QString& username, const QString& app_id,
|
||||
const QString& app_key, const QString& redirect_url, const QString& refresh_token,
|
||||
|
@ -398,7 +398,7 @@ QString Settings::pathName() const {
|
||||
}
|
||||
|
||||
QSettings::Status Settings::checkSettings() {
|
||||
qDebug("Syncing settings.");
|
||||
qDebugNN << LOGSEC_CORE << "Syncing settings.";
|
||||
sync();
|
||||
return status();
|
||||
}
|
||||
@ -414,14 +414,17 @@ void Settings::finishRestoration(const QString& desired_settings_file_path) {
|
||||
BACKUP_NAME_SETTINGS + BACKUP_SUFFIX_SETTINGS;
|
||||
|
||||
if (QFile::exists(backup_settings_file)) {
|
||||
qWarning("Backup settings file '%s' was detected. Restoring it.", qPrintable(QDir::toNativeSeparators(backup_settings_file)));
|
||||
qWarningNN << LOGSEC_CORE
|
||||
<< "Backup settings file"
|
||||
<< QUOTE_W_SPACE(QDir::toNativeSeparators(backup_settings_file))
|
||||
<< "was detected. Restoring it.";
|
||||
|
||||
if (IOFactory::copyFile(backup_settings_file, desired_settings_file_path)) {
|
||||
QFile::remove(backup_settings_file);
|
||||
qDebug("Settings file was restored successully.");
|
||||
qDebugNN << LOGSEC_CORE << "Settings file was restored successully.";
|
||||
}
|
||||
else {
|
||||
qCritical("Settings file was NOT restored due to error when copying the file.");
|
||||
qCriticalNN << LOGSEC_CORE << "Settings file was NOT restored due to error when copying the file.";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -441,11 +444,16 @@ Settings* Settings::setupSettings(QObject* parent) {
|
||||
|
||||
// Check if portable settings are available.
|
||||
if (properties.m_type == SettingsProperties::SettingsType::Portable) {
|
||||
qDebug("Initializing settings in '%s' (portable way).", qPrintable(QDir::toNativeSeparators(properties.m_absoluteSettingsFileName)));
|
||||
qDebugNN << LOGSEC_CORE
|
||||
<< "Initializing settings in"
|
||||
<< QUOTE_W_SPACE(QDir::toNativeSeparators(properties.m_absoluteSettingsFileName))
|
||||
<< "(portable way).";
|
||||
}
|
||||
else {
|
||||
qDebug("Initializing settings in '%s' (non-portable way).",
|
||||
qPrintable(QDir::toNativeSeparators(properties.m_absoluteSettingsFileName)));
|
||||
qDebugNN << LOGSEC_CORE
|
||||
<< "Initializing settings in"
|
||||
<< QUOTE_W_SPACE(QDir::toNativeSeparators(properties.m_absoluteSettingsFileName))
|
||||
<< "(non-portable way).";
|
||||
}
|
||||
|
||||
return new_settings;
|
||||
|
@ -13,6 +13,7 @@ SkinFactory::SkinFactory(QObject* parent) : QObject(parent) {}
|
||||
|
||||
void SkinFactory::loadCurrentSkin() {
|
||||
QList<QString> skin_names_to_try;
|
||||
|
||||
skin_names_to_try.append(selectedSkinName());
|
||||
skin_names_to_try.append(APP_SKIN_DEFAULT);
|
||||
bool skin_parsed;
|
||||
@ -28,15 +29,15 @@ void SkinFactory::loadCurrentSkin() {
|
||||
|
||||
// Set this 'Skin' object as active one.
|
||||
m_currentSkin = skin_data;
|
||||
qDebug("Skin '%s' loaded.", qPrintable(skin_name));
|
||||
qDebugNN << LOGSEC_GUI << "Skin" << QUOTE_W_SPACE(skin_name) << "loaded.";
|
||||
return;
|
||||
}
|
||||
else {
|
||||
qWarning("Failed to load skin '%s'.", qPrintable(skin_name));
|
||||
qWarningNN << LOGSEC_GUI << "Failed to load skin" << QUOTE_W_SPACE_DOT(skin_name);
|
||||
}
|
||||
}
|
||||
|
||||
qCritical("Failed to load selected or default skin. Quitting!");
|
||||
qCriticalNN << LOGSEC_GUI << "Failed to load selected or default skin. Quitting!";
|
||||
}
|
||||
|
||||
void SkinFactory::loadSkinFromData(const Skin& skin) {
|
||||
|
@ -65,7 +65,7 @@ SystemFactory::AutoStartStatus SystemFactory::autoStartStatus() const {
|
||||
|
||||
// No correct path was found.
|
||||
if (desktop_file_location.isEmpty()) {
|
||||
qWarning("Searching for auto-start function status failed. HOME variable not found.");
|
||||
qWarningNN << LOGSEC_GUI << "Searching for auto-start function status failed. HOME variable not found.";
|
||||
return AutoStartStatus::Unavailable;
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ QString TextFactory::decrypt(const QString& text) {
|
||||
QString TextFactory::newline() {
|
||||
#if defined(Q_OS_WIN)
|
||||
return QSL("\r\n");
|
||||
#elif defined(Q_OS_MACOSOS)
|
||||
#elif defined(Q_OS_MACOS)
|
||||
return QSL("\r");
|
||||
#else
|
||||
return QSL("\n");
|
||||
@ -152,8 +152,10 @@ quint64 TextFactory::initializeSecretEncryptionKey() {
|
||||
IOFactory::writeFile(encryption_file_path, QString::number(s_encryptionKey).toLocal8Bit());
|
||||
}
|
||||
catch (ApplicationException& ex) {
|
||||
qCritical("Failed to write newly generated encryption key to file, error '%s'. Now, your passwords won't be "
|
||||
"readable after you start this application again.", qPrintable(ex.message()));
|
||||
qCriticalNN << LOGSEC_CORE
|
||||
<< "Failed to write newly generated encryption key to file, error"
|
||||
<< QUOTE_W_SPACE_DOT(ex.message())
|
||||
<< " Now, your passwords won't be readable after you start this application again.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,7 +174,9 @@ AdBlockSubscription* AdBlockManager::addSubscription(const QString& title, const
|
||||
QSaveFile file(filePath);
|
||||
|
||||
if (!file.open(QFile::WriteOnly)) {
|
||||
qWarning("Cannot save AdBlock subscription to file '%s'.", qPrintable(filePath));
|
||||
qWarningNN << LOGSEC_ADBLOCK
|
||||
<< "Cannot save AdBlock subscription to file"
|
||||
<< QUOTE_W_SPACE_DOT(filePath);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -262,7 +264,9 @@ void AdBlockManager::load() {
|
||||
QUrl url = QUrl(textStream.readLine(1024).remove(QLatin1String("Url: ")));
|
||||
|
||||
if (title.isEmpty() || !url.isValid()) {
|
||||
qWarning("Invalid AdBlock subscription file '%s'.", qPrintable(absolutePath));
|
||||
qWarningNN << LOGSEC_ADBLOCK
|
||||
<< "Invalid AdBlock subscription file"
|
||||
<< QUOTE_W_SPACE_DOT(absolutePath);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include "network-web/adblock/adblockrule.h"
|
||||
#include "network-web/adblock/adblocksearchtree.h"
|
||||
|
||||
#include "definitions/definitions.h"
|
||||
|
||||
#include <QWebEngineUrlRequestInfo>
|
||||
|
||||
AdBlockSearchTree::AdBlockSearchTree() : m_root(new Node) {}
|
||||
@ -42,7 +44,7 @@ bool AdBlockSearchTree::add(const AdBlockRule* rule) {
|
||||
int len = filter.size();
|
||||
|
||||
if (len <= 0) {
|
||||
qDebug("AdBlockSearchTree: Inserting rule with filter len <= 0!");
|
||||
qWarningNN << LOGSEC_ADBLOCK << "Inserting rule with filter len <= 0!";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,10 @@ void AdBlockSubscription::loadSubscription(const QStringList& disabledRules) {
|
||||
}
|
||||
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
qWarning("Unable to open adblock file '%s' for reading.", qPrintable(m_filePath));
|
||||
qWarningNN << LOGSEC_ADBLOCK
|
||||
<< "Unable to open adblock file"
|
||||
<< QUOTE_W_SPACE(m_filePath)
|
||||
<< "for reading.";
|
||||
QTimer::singleShot(0, this, SLOT(updateSubscription()));
|
||||
return;
|
||||
}
|
||||
@ -109,7 +112,9 @@ void AdBlockSubscription::loadSubscription(const QStringList& disabledRules) {
|
||||
QString header = textStream.readLine(1024);
|
||||
|
||||
if (!header.startsWith(QL1S("[Adblock")) || m_title.isEmpty()) {
|
||||
qWarning("Invalid format of AdBlock file '%s'.", qPrintable(m_filePath));
|
||||
qWarningNN << LOGSEC_ADBLOCK
|
||||
<< "Invalid format of AdBlock file"
|
||||
<< QUOTE_W_SPACE_DOT(m_filePath);
|
||||
QTimer::singleShot(0, this, SLOT(updateSubscription()));
|
||||
return;
|
||||
}
|
||||
@ -176,7 +181,10 @@ bool AdBlockSubscription::saveDownloadedData(const QByteArray& data) {
|
||||
QSaveFile file(m_filePath);
|
||||
|
||||
if (!file.open(QFile::WriteOnly)) {
|
||||
qWarning("Unable to open AdBlock file '%s' for writing.", qPrintable(m_filePath));
|
||||
qWarningNN << LOGSEC_ADBLOCK
|
||||
<< "Unable to open AdBlock file"
|
||||
<< QUOTE_W_SPACE(m_filePath)
|
||||
<< "for writing.";
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
@ -306,7 +314,10 @@ void AdBlockCustomList::saveSubscription() {
|
||||
QFile file(filePath());
|
||||
|
||||
if (!file.open(QFile::ReadWrite | QFile::Truncate)) {
|
||||
qWarning("Unable to open AdBlock file '%s' for writing.", qPrintable(filePath()));
|
||||
qWarningNN << LOGSEC_ADBLOCK
|
||||
<< "Unable to open AdBlock file"
|
||||
<< QUOTE_W_SPACE(filePath())
|
||||
<< "for writing.";
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -29,12 +29,18 @@ void BaseNetworkAccessManager::loadSettings() {
|
||||
setProxy(QNetworkProxy::applicationProxy());
|
||||
}
|
||||
|
||||
qDebug("Settings of BaseNetworkAccessManager loaded.");
|
||||
qDebugNN << LOGSEC_NETWORK << "Settings of BaseNetworkAccessManager loaded.";
|
||||
}
|
||||
|
||||
void BaseNetworkAccessManager::onSslErrors(QNetworkReply* reply, const QList<QSslError>& error) {
|
||||
qWarning("Ignoring SSL errors for '%s': '%s' (code %d).", qPrintable(reply->url().toString()), qPrintable(reply->errorString()),
|
||||
int(reply->error()));
|
||||
qWarningNN << LOGSEC_NETWORK
|
||||
<< "Ignoring SSL errors for '"
|
||||
<< reply->url().toString()
|
||||
<< "':"
|
||||
<< QUOTE_W_SPACE(reply->errorString())
|
||||
<< "(code "
|
||||
<< reply->error()
|
||||
<< ").";
|
||||
reply->ignoreSslErrors(error);
|
||||
}
|
||||
|
||||
@ -45,7 +51,7 @@ QNetworkReply* BaseNetworkAccessManager::createRequest(QNetworkAccessManager::Op
|
||||
|
||||
// This rapidly speeds up loading of web sites.
|
||||
// NOTE: https://en.wikipedia.org/wiki/HTTP_pipelining
|
||||
new_request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
|
||||
new_request.setAttribute(QNetworkRequest::Attribute::HttpPipeliningAllowedAttribute, true);
|
||||
|
||||
// Setup custom user-agent.
|
||||
new_request.setRawHeader(HTTP_HEADERS_USER_AGENT, QString(APP_USERAGENT).toLocal8Bit());
|
||||
|
@ -19,7 +19,9 @@ Downloader::Downloader(QObject* parent)
|
||||
connect(m_timer, &QTimer::timeout, this, &Downloader::cancel);
|
||||
}
|
||||
|
||||
Downloader::~Downloader() = default;
|
||||
Downloader::~Downloader() {
|
||||
qDebugNN << LOGSEC_NETWORK << "Destroying Downloader instance.";
|
||||
}
|
||||
|
||||
void Downloader::downloadFile(const QString& url, int timeout, bool protected_contents, const QString& username,
|
||||
const QString& password) {
|
||||
@ -67,7 +69,9 @@ void Downloader::manipulateData(const QString& url,
|
||||
m_timer->setInterval(timeout);
|
||||
|
||||
if (non_const_url.startsWith(URI_SCHEME_FEED)) {
|
||||
qDebug("Replacing URI schemes for '%s'.", qPrintable(non_const_url));
|
||||
qDebugNN << LOGSEC_NETWORK
|
||||
<< "Replacing URI schemes for"
|
||||
<< QUOTE_W_SPACE_DOT(non_const_url);
|
||||
request.setUrl(non_const_url.replace(QRegularExpression(QString('^') + URI_SCHEME_FEED), QString(URI_SCHEME_HTTP)));
|
||||
}
|
||||
else {
|
||||
|
@ -19,8 +19,6 @@ class Downloader : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
// Constructors and destructors.
|
||||
explicit Downloader(QObject* parent = nullptr);
|
||||
virtual ~Downloader();
|
||||
|
||||
@ -81,10 +79,8 @@ class Downloader : public QObject {
|
||||
|
||||
private:
|
||||
QNetworkReply* m_activeReply;
|
||||
|
||||
QScopedPointer<SilentNetworkAccessManager> m_downloadManager;
|
||||
QTimer* m_timer;
|
||||
|
||||
QHash<QByteArray, QByteArray> m_customHeaders;
|
||||
QByteArray m_inputData;
|
||||
QHttpMultiPart* m_inputMultipartData;
|
||||
@ -94,7 +90,6 @@ class Downloader : public QObject {
|
||||
|
||||
// Response data.
|
||||
QByteArray m_lastOutputData;
|
||||
|
||||
QList<HttpResponse> m_lastOutputMultipartData;
|
||||
|
||||
QNetworkReply::NetworkError m_lastOutputError;
|
||||
|
@ -12,7 +12,7 @@
|
||||
#define GMAIL_API_GET_ATTACHMENT "https://www.googleapis.com/gmail/v1/users/me/messages/%1/attachments/%2"
|
||||
#define GMAIL_API_LABELS_LIST "https://www.googleapis.com/gmail/v1/users/me/labels"
|
||||
#define GMAIL_API_MSGS_LIST "https://www.googleapis.com/gmail/v1/users/me/messages"
|
||||
#define GMAIL_API_BATCH "https://www.googleapis.com/batch"
|
||||
#define GMAIL_API_BATCH "https://www.googleapis.com/batch/gmail/v1"
|
||||
|
||||
#define GMAIL_ATTACHMENT_SEP "####"
|
||||
|
||||
|
@ -118,10 +118,11 @@ void GmailNetworkFactory::initializeOauth() {
|
||||
connect(m_oauth2, &OAuth2Service::authFailed, this, &GmailNetworkFactory::onAuthFailed);
|
||||
connect(m_oauth2, &OAuth2Service::tokensReceived, this, [this](QString access_token, QString refresh_token, int expires_in) {
|
||||
Q_UNUSED(expires_in)
|
||||
Q_UNUSED(access_token)
|
||||
|
||||
if (m_service != nullptr && !access_token.isEmpty() && !refresh_token.isEmpty()) {
|
||||
if (m_service != nullptr && !refresh_token.isEmpty()) {
|
||||
QSqlDatabase database = qApp->database()->connection(metaObject()->className());
|
||||
DatabaseQueries::storeNewInoreaderTokens(database, refresh_token, m_service->accountId());
|
||||
DatabaseQueries::storeNewGmailTokens(database, refresh_token, m_service->accountId());
|
||||
|
||||
qApp->showGuiMessage(tr("Logged in successfully"),
|
||||
tr("Your login to Gmail was authorized."),
|
||||
|
@ -54,8 +54,9 @@ void InoreaderNetworkFactory::initializeOauth() {
|
||||
connect(m_oauth2, &OAuth2Service::authFailed, this, &InoreaderNetworkFactory::onAuthFailed);
|
||||
connect(m_oauth2, &OAuth2Service::tokensReceived, this, [this](QString access_token, QString refresh_token, int expires_in) {
|
||||
Q_UNUSED(expires_in)
|
||||
Q_UNUSED(access_token)
|
||||
|
||||
if (m_service != nullptr && !access_token.isEmpty() && !refresh_token.isEmpty()) {
|
||||
if (m_service != nullptr && !refresh_token.isEmpty()) {
|
||||
QSqlDatabase database = qApp->database()->connection(metaObject()->className());
|
||||
DatabaseQueries::storeNewInoreaderTokens(database, refresh_token, m_service->accountId());
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user