diff --git a/resources/desktop/appdata.xml b/resources/desktop/appdata.xml new file mode 100755 index 000000000..98ddd00e1 --- /dev/null +++ b/resources/desktop/appdata.xml @@ -0,0 +1,37 @@ + + + + com.github.rssguard + GPL-3.0 + GPL-3.0 + RSS Guard + Simple (yet powerful) feed reader + + + RSS Guard is simple (yet powerful) feed reader. It is able to fetch the most known feed formats, including RSS/RDF and ATOM. RSS Guard is developed on top of the Qt library + + + rssguard.desktop + + + Linux version + http://www.hughsie.com/en_US/main.png + + + Windows version + http://www.hughsie.com/en_US/main.png + + + http://www.gnome.org/projects/en_US/gnome-power-manager + GNOME + + gnome-power-statistics + + + + + Fixes issues X, Y and Z + + + + \ No newline at end of file diff --git a/resources/screenshots/screenshot-linux.png b/resources/screenshots/screenshot-linux.png new file mode 100755 index 000000000..94cf6c422 Binary files /dev/null and b/resources/screenshots/screenshot-linux.png differ diff --git a/resources/screenshots/screenshot-windows.png b/resources/screenshots/screenshot-windows.png new file mode 100755 index 000000000..16cb896e1 Binary files /dev/null and b/resources/screenshots/screenshot-windows.png differ diff --git a/rssguard.pro b/rssguard.pro index bf98289d2..ac3480ceb 100755 --- a/rssguard.pro +++ b/rssguard.pro @@ -209,14 +209,16 @@ win32 { } CONFIG *= resources_big -RESOURCES += resources/sql.qrc \ - resources/rssguard.qrc +RESOURCES += resources/sql.qrc \ + resources/rssguard.qrc HEADERS += src/core/feeddownloader.h \ src/core/feedsmodel.h \ src/core/feedsproxymodel.h \ src/core/message.h \ src/core/messagesmodel.h \ + src/core/messagesmodelcache.h \ + src/core/messagesmodelsqllayer.h \ src/core/messagesproxymodel.h \ src/definitions/definitions.h \ src/dynamic-shortcuts/dynamicshortcuts.h \ @@ -241,6 +243,7 @@ HEADERS += src/core/feeddownloader.h \ src/gui/feedmessageviewer.h \ src/gui/feedstoolbar.h \ src/gui/feedsview.h \ + src/gui/guiutilities.h \ src/gui/labelwithstatus.h \ src/gui/lineeditwithstatus.h \ src/gui/messagebox.h \ @@ -248,6 +251,15 @@ HEADERS += src/core/feeddownloader.h \ src/gui/messagestoolbar.h \ src/gui/messagesview.h \ src/gui/plaintoolbutton.h \ + src/gui/settings/settingsbrowsermail.h \ + src/gui/settings/settingsdatabase.h \ + src/gui/settings/settingsdownloads.h \ + src/gui/settings/settingsfeedsmessages.h \ + src/gui/settings/settingsgeneral.h \ + src/gui/settings/settingsgui.h \ + src/gui/settings/settingslocalization.h \ + src/gui/settings/settingspanel.h \ + src/gui/settings/settingsshortcuts.h \ src/gui/squeezelabel.h \ src/gui/statusbar.h \ src/gui/styleditemdelegatewithoutfocus.h \ @@ -257,6 +269,7 @@ HEADERS += src/core/feeddownloader.h \ src/gui/tabwidget.h \ src/gui/timespinbox.h \ src/gui/toolbareditor.h \ + src/gui/treeviewcolumnsmenu.h \ src/gui/widgetwithstatus.h \ src/miscellaneous/application.h \ src/miscellaneous/autosaver.h \ @@ -264,6 +277,8 @@ HEADERS += src/core/feeddownloader.h \ src/miscellaneous/databasefactory.h \ src/miscellaneous/databasequeries.h \ src/miscellaneous/debugging.h \ + src/miscellaneous/externaltool.h \ + src/miscellaneous/feedreader.h \ src/miscellaneous/iconfactory.h \ src/miscellaneous/iofactory.h \ src/miscellaneous/localization.h \ @@ -278,6 +293,7 @@ HEADERS += src/core/feeddownloader.h \ src/network-web/downloader.h \ src/network-web/downloadmanager.h \ src/network-web/networkfactory.h \ + src/network-web/oauth2service.h \ src/network-web/silentnetworkaccessmanager.h \ src/network-web/webfactory.h \ src/qtsingleapplication/qtlocalpeer.h \ @@ -285,6 +301,7 @@ HEADERS += src/core/feeddownloader.h \ src/qtsingleapplication/qtsingleapplication.h \ src/qtsingleapplication/qtsinglecoreapplication.h \ src/services/abstract/accountcheckmodel.h \ + src/services/abstract/cacheforserviceroot.h \ src/services/abstract/category.h \ src/services/abstract/feed.h \ src/services/abstract/gui/formfeeddetails.h \ @@ -292,6 +309,18 @@ HEADERS += src/core/feeddownloader.h \ src/services/abstract/rootitem.h \ src/services/abstract/serviceentrypoint.h \ src/services/abstract/serviceroot.h \ + src/services/gmail/definitions.h \ + src/services/gmail/gmailentrypoint.h \ + src/services/gmail/gmailfeed.h \ + src/services/gmail/gmailserviceroot.h \ + src/services/gmail/gui/formeditgmailaccount.h \ + src/services/gmail/network/gmailnetworkfactory.h \ + src/services/inoreader/definitions.h \ + src/services/inoreader/gui/formeditinoreaderaccount.h \ + src/services/inoreader/inoreaderentrypoint.h \ + src/services/inoreader/inoreaderfeed.h \ + src/services/inoreader/inoreaderserviceroot.h \ + src/services/inoreader/network/inoreadernetworkfactory.h \ src/services/owncloud/definitions.h \ src/services/owncloud/gui/formeditowncloudaccount.h \ src/services/owncloud/gui/formowncloudfeeddetails.h \ @@ -299,47 +328,33 @@ HEADERS += src/core/feeddownloader.h \ src/services/owncloud/owncloudfeed.h \ src/services/owncloud/owncloudserviceentrypoint.h \ src/services/owncloud/owncloudserviceroot.h \ + src/services/standard/atomparser.h \ + src/services/standard/feedparser.h \ src/services/standard/gui/formstandardcategorydetails.h \ src/services/standard/gui/formstandardfeeddetails.h \ src/services/standard/gui/formstandardimportexport.h \ + src/services/standard/rdfparser.h \ + src/services/standard/rssparser.h \ src/services/standard/standardcategory.h \ src/services/standard/standardfeed.h \ src/services/standard/standardfeedsimportexportmodel.h \ src/services/standard/standardserviceentrypoint.h \ src/services/standard/standardserviceroot.h \ src/services/tt-rss/definitions.h \ + src/services/tt-rss/gui/formeditttrssaccount.h \ src/services/tt-rss/gui/formttrssfeeddetails.h \ src/services/tt-rss/network/ttrssnetworkfactory.h \ src/services/tt-rss/ttrssfeed.h \ src/services/tt-rss/ttrssserviceentrypoint.h \ - src/services/tt-rss/ttrssserviceroot.h \ - src/gui/settings/settingspanel.h \ - src/gui/settings/settingsgeneral.h \ - src/gui/settings/settingsdatabase.h \ - src/gui/settings/settingsshortcuts.h \ - src/gui/settings/settingsgui.h \ - src/gui/settings/settingslocalization.h \ - src/gui/settings/settingsbrowsermail.h \ - src/gui/settings/settingsfeedsmessages.h \ - src/gui/settings/settingsdownloads.h \ - src/miscellaneous/feedreader.h \ - src/services/standard/atomparser.h \ - src/services/standard/feedparser.h \ - src/services/standard/rdfparser.h \ - src/services/standard/rssparser.h \ - src/services/abstract/cacheforserviceroot.h \ - src/services/tt-rss/gui/formeditttrssaccount.h \ - src/gui/guiutilities.h \ - src/core/messagesmodelcache.h \ - src/core/messagesmodelsqllayer.h \ - src/gui/treeviewcolumnsmenu.h \ - src/miscellaneous/externaltool.h + src/services/tt-rss/ttrssserviceroot.h SOURCES += src/core/feeddownloader.cpp \ src/core/feedsmodel.cpp \ src/core/feedsproxymodel.cpp \ src/core/message.cpp \ src/core/messagesmodel.cpp \ + src/core/messagesmodelcache.cpp \ + src/core/messagesmodelsqllayer.cpp \ src/core/messagesproxymodel.cpp \ src/dynamic-shortcuts/dynamicshortcuts.cpp \ src/dynamic-shortcuts/dynamicshortcutswidget.cpp \ @@ -363,6 +378,7 @@ SOURCES += src/core/feeddownloader.cpp \ src/gui/feedmessageviewer.cpp \ src/gui/feedstoolbar.cpp \ src/gui/feedsview.cpp \ + src/gui/guiutilities.cpp \ src/gui/labelwithstatus.cpp \ src/gui/lineeditwithstatus.cpp \ src/gui/messagebox.cpp \ @@ -370,6 +386,15 @@ SOURCES += src/core/feeddownloader.cpp \ src/gui/messagestoolbar.cpp \ src/gui/messagesview.cpp \ src/gui/plaintoolbutton.cpp \ + src/gui/settings/settingsbrowsermail.cpp \ + src/gui/settings/settingsdatabase.cpp \ + src/gui/settings/settingsdownloads.cpp \ + src/gui/settings/settingsfeedsmessages.cpp \ + src/gui/settings/settingsgeneral.cpp \ + src/gui/settings/settingsgui.cpp \ + src/gui/settings/settingslocalization.cpp \ + src/gui/settings/settingspanel.cpp \ + src/gui/settings/settingsshortcuts.cpp \ src/gui/squeezelabel.cpp \ src/gui/statusbar.cpp \ src/gui/styleditemdelegatewithoutfocus.cpp \ @@ -379,6 +404,7 @@ SOURCES += src/core/feeddownloader.cpp \ src/gui/tabwidget.cpp \ src/gui/timespinbox.cpp \ src/gui/toolbareditor.cpp \ + src/gui/treeviewcolumnsmenu.cpp \ src/gui/widgetwithstatus.cpp \ src/main.cpp \ src/miscellaneous/application.cpp \ @@ -387,6 +413,8 @@ SOURCES += src/core/feeddownloader.cpp \ src/miscellaneous/databasefactory.cpp \ src/miscellaneous/databasequeries.cpp \ src/miscellaneous/debugging.cpp \ + src/miscellaneous/externaltool.cpp \ + src/miscellaneous/feedreader.cpp \ src/miscellaneous/iconfactory.cpp \ src/miscellaneous/iofactory.cpp \ src/miscellaneous/localization.cpp \ @@ -400,6 +428,7 @@ SOURCES += src/core/feeddownloader.cpp \ src/network-web/downloader.cpp \ src/network-web/downloadmanager.cpp \ src/network-web/networkfactory.cpp \ + src/network-web/oauth2service.cpp \ src/network-web/silentnetworkaccessmanager.cpp \ src/network-web/webfactory.cpp \ src/qtsingleapplication/qtlocalpeer.cpp \ @@ -407,6 +436,7 @@ SOURCES += src/core/feeddownloader.cpp \ src/qtsingleapplication/qtsingleapplication.cpp \ src/qtsingleapplication/qtsinglecoreapplication.cpp \ src/services/abstract/accountcheckmodel.cpp \ + src/services/abstract/cacheforserviceroot.cpp \ src/services/abstract/category.cpp \ src/services/abstract/feed.cpp \ src/services/abstract/gui/formfeeddetails.cpp \ @@ -414,55 +444,46 @@ SOURCES += src/core/feeddownloader.cpp \ src/services/abstract/rootitem.cpp \ src/services/abstract/serviceentrypoint.cpp \ src/services/abstract/serviceroot.cpp \ + src/services/gmail/gmailentrypoint.cpp \ + src/services/gmail/gmailfeed.cpp \ + src/services/gmail/gmailserviceroot.cpp \ + src/services/gmail/gui/formeditgmailaccount.cpp \ + src/services/gmail/network/gmailnetworkfactory.cpp \ + src/services/inoreader/gui/formeditinoreaderaccount.cpp \ + src/services/inoreader/inoreaderentrypoint.cpp \ + src/services/inoreader/inoreaderfeed.cpp \ + src/services/inoreader/inoreaderserviceroot.cpp \ + src/services/inoreader/network/inoreadernetworkfactory.cpp \ src/services/owncloud/gui/formeditowncloudaccount.cpp \ src/services/owncloud/gui/formowncloudfeeddetails.cpp \ src/services/owncloud/network/owncloudnetworkfactory.cpp \ src/services/owncloud/owncloudfeed.cpp \ src/services/owncloud/owncloudserviceentrypoint.cpp \ src/services/owncloud/owncloudserviceroot.cpp \ + src/services/standard/atomparser.cpp \ + src/services/standard/feedparser.cpp \ src/services/standard/gui/formstandardcategorydetails.cpp \ src/services/standard/gui/formstandardfeeddetails.cpp \ src/services/standard/gui/formstandardimportexport.cpp \ + src/services/standard/rdfparser.cpp \ + src/services/standard/rssparser.cpp \ src/services/standard/standardcategory.cpp \ src/services/standard/standardfeed.cpp \ src/services/standard/standardfeedsimportexportmodel.cpp \ src/services/standard/standardserviceentrypoint.cpp \ src/services/standard/standardserviceroot.cpp \ + src/services/tt-rss/gui/formeditttrssaccount.cpp \ src/services/tt-rss/gui/formttrssfeeddetails.cpp \ src/services/tt-rss/network/ttrssnetworkfactory.cpp \ src/services/tt-rss/ttrssfeed.cpp \ src/services/tt-rss/ttrssserviceentrypoint.cpp \ - src/services/tt-rss/ttrssserviceroot.cpp \ - src/gui/settings/settingspanel.cpp \ - src/gui/settings/settingsgeneral.cpp \ - src/gui/settings/settingsdatabase.cpp \ - src/gui/settings/settingsshortcuts.cpp \ - src/gui/settings/settingsgui.cpp \ - src/gui/settings/settingslocalization.cpp \ - src/gui/settings/settingsbrowsermail.cpp \ - src/gui/settings/settingsfeedsmessages.cpp \ - src/gui/settings/settingsdownloads.cpp \ - src/miscellaneous/feedreader.cpp \ - src/services/standard/atomparser.cpp \ - src/services/standard/feedparser.cpp \ - src/services/standard/rdfparser.cpp \ - src/services/standard/rssparser.cpp \ - src/services/abstract/cacheforserviceroot.cpp \ - src/services/tt-rss/gui/formeditttrssaccount.cpp \ - src/gui/guiutilities.cpp \ - src/core/messagesmodelcache.cpp \ - src/core/messagesmodelsqllayer.cpp \ - src/gui/treeviewcolumnsmenu.cpp \ - src/miscellaneous/externaltool.cpp + src/services/tt-rss/ttrssserviceroot.cpp mac { OBJECTIVE_SOURCES += src/miscellaneous/disablewindowtabbing.mm } -FORMS += src/gui/toolbareditor.ui \ - src/network-web/downloaditem.ui \ - src/network-web/downloadmanager.ui \ - src/gui/dialogs/formabout.ui \ +FORMS += src/gui/dialogs/formabout.ui \ src/gui/dialogs/formaddaccount.ui \ src/gui/dialogs/formbackupdatabasesettings.ui \ src/gui/dialogs/formdatabasecleanup.ui \ @@ -470,18 +491,23 @@ FORMS += src/gui/toolbareditor.ui \ src/gui/dialogs/formrestoredatabasesettings.ui \ src/gui/dialogs/formsettings.ui \ src/gui/dialogs/formupdate.ui \ + src/gui/settings/settingsbrowsermail.ui \ + src/gui/settings/settingsdatabase.ui \ + src/gui/settings/settingsdownloads.ui \ + src/gui/settings/settingsfeedsmessages.ui \ + src/gui/settings/settingsgeneral.ui \ + src/gui/settings/settingsgui.ui \ + src/gui/settings/settingslocalization.ui \ + src/gui/settings/settingsshortcuts.ui \ + src/gui/toolbareditor.ui \ + src/network-web/downloaditem.ui \ + src/network-web/downloadmanager.ui \ src/services/abstract/gui/formfeeddetails.ui \ + src/services/gmail/gui/formeditgmailaccount.ui \ + src/services/inoreader/gui/formeditinoreaderaccount.ui \ src/services/owncloud/gui/formeditowncloudaccount.ui \ src/services/standard/gui/formstandardcategorydetails.ui \ src/services/standard/gui/formstandardimportexport.ui \ - src/gui/settings/settingsgeneral.ui \ - src/gui/settings/settingsdatabase.ui \ - src/gui/settings/settingsshortcuts.ui \ - src/gui/settings/settingsgui.ui \ - src/gui/settings/settingslocalization.ui \ - src/gui/settings/settingsbrowsermail.ui \ - src/gui/settings/settingsfeedsmessages.ui \ - src/gui/settings/settingsdownloads.ui \ src/services/tt-rss/gui/formeditttrssaccount.ui equals(USE_WEBENGINE, true) { @@ -492,20 +518,7 @@ equals(USE_WEBENGINE, true) { src/network-web/googlesuggest.h \ src/network-web/webpage.h \ src/network-web/rssguardschemehandler.h \ - src/services/inoreader/definitions.h \ - src/services/inoreader/inoreaderentrypoint.h \ - src/services/inoreader/network/inoreadernetworkfactory.h \ - src/services/inoreader/inoreaderserviceroot.h \ - src/services/inoreader/gui/formeditinoreaderaccount.h \ - src/services/inoreader/inoreaderfeed.h \ - src/network-web/oauth2service.h \ - src/gui/dialogs/oauthlogin.h \ - src/services/gmail/definitions.h \ - src/services/gmail/gmailentrypoint.h \ - src/services/gmail/gmailserviceroot.h \ - src/services/gmail/gmailfeed.h \ - src/services/gmail/network/gmailnetworkfactory.h \ - src/services/gmail/gui/formeditgmailaccount.h + src/gui/dialogs/oauthlogin.h SOURCES += src/gui/locationlineedit.cpp \ src/gui/webviewer.cpp \ @@ -514,18 +527,7 @@ equals(USE_WEBENGINE, true) { src/network-web/googlesuggest.cpp \ src/network-web/webpage.cpp \ src/network-web/rssguardschemehandler.cpp \ - src/services/inoreader/inoreaderentrypoint.cpp \ - src/services/inoreader/network/inoreadernetworkfactory.cpp \ - src/services/inoreader/inoreaderserviceroot.cpp \ - src/services/inoreader/gui/formeditinoreaderaccount.cpp \ - src/services/inoreader/inoreaderfeed.cpp \ - src/network-web/oauth2service.cpp \ - src/gui/dialogs/oauthlogin.cpp \ - src/services/gmail/gmailentrypoint.cpp \ - src/services/gmail/gmailserviceroot.cpp \ - src/services/gmail/gmailfeed.cpp \ - src/services/gmail/network/gmailnetworkfactory.cpp \ - src/services/gmail/gui/formeditgmailaccount.cpp + src/gui/dialogs/oauthlogin.cpp # Add AdBlock sources. HEADERS += src/network-web/adblock/adblockaddsubscriptiondialog.h \ @@ -559,9 +561,7 @@ equals(USE_WEBENGINE, true) { FORMS += src/network-web/adblock/adblockaddsubscriptiondialog.ui \ src/network-web/adblock/adblockdialog.ui \ - src/services/inoreader/gui/formeditinoreaderaccount.ui \ - src/gui/dialogs/oauthlogin.ui \ - src/services/gmail/gui/formeditgmailaccount.ui + src/gui/dialogs/oauthlogin.ui } else { HEADERS += src/gui/messagepreviewer.h \ diff --git a/src/main.cpp b/src/main.cpp index 8d4c334b2..20bc9189c 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -175,21 +175,22 @@ int main(int argc, char* argv[]) { qApp->showPolls(); qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->loadAllExpandStates(); - OAuth2Service* srv = new OAuth2Service( +/* + OAuth2Service* srv = new OAuth2Service( "https://accounts.google.com/o/oauth2/auth", "https://accounts.google.com/o/oauth2/token", "369069180494-j66bgeciouinec1eem7fhvj6qm0as7q3.apps.googleusercontent.com", "vppQtxrEeBkImiXcjGYl9NxZ", "https://mail.google.com/"); - srv->setRefreshToken("1/RKE3oohSoTHE54L0IPflvndK-DcI7l0of3lVdLa1Q9Q"); - QObject::connect(srv, &OAuth2Service::authCodeObtained, [](QString auth_code) { + //srv->setRefreshToken("1/RKE3oohSoTHE54L0IPflvndK-DcI7l0of3lVdLa1Q9Q"); + QObject::connect(srv, &OAuth2Service::authCodeObtained, [](QString auth_code) { int a = 5; - }); - QObject::connect(srv, &OAuth2Service::authFailed, []() { + }); + QObject::connect(srv, &OAuth2Service::authFailed, []() { int a = 5; - }); - QObject::connect(srv, &OAuth2Service::tokensReceived, [srv](QString acc, QString ref, int exp) { + }); + QObject::connect(srv, &OAuth2Service::tokensReceived, [srv](QString acc, QString ref, int exp) { QHttpMultiPart* multi = new QHttpMultiPart(srv); QHttpPart p1; @@ -221,11 +222,11 @@ int main(int argc, char* argv[]) { }); int a = 5; - }); - QObject::connect(srv, &OAuth2Service::tokensRetrieveError, [](QString err, QString desc) { + }); + QObject::connect(srv, &OAuth2Service::tokensRetrieveError, [](QString err, QString desc) { int a = 5; - }); - srv->login(); + }); + srv->login();*/ // Enter global event loop. return Application::exec(); diff --git a/src/miscellaneous/databasequeries.cpp b/src/miscellaneous/databasequeries.cpp index a4606bbf6..f510cda95 100755 --- a/src/miscellaneous/databasequeries.cpp +++ b/src/miscellaneous/databasequeries.cpp @@ -21,7 +21,15 @@ #include "miscellaneous/application.h" #include "miscellaneous/iconfactory.h" #include "miscellaneous/textfactory.h" +#include "network-web/oauth2service.h" #include "services/abstract/category.h" +#include "services/gmail/definitions.h" +#include "services/gmail/gmailserviceroot.h" +#include "services/gmail/network/gmailnetworkfactory.h" +#include "services/inoreader/definitions.h" +#include "services/inoreader/inoreaderfeed.h" +#include "services/inoreader/inoreaderserviceroot.h" +#include "services/inoreader/network/inoreadernetworkfactory.h" #include "services/owncloud/definitions.h" #include "services/owncloud/network/owncloudnetworkfactory.h" #include "services/owncloud/owncloudfeed.h" @@ -33,16 +41,6 @@ #include "services/tt-rss/ttrssfeed.h" #include "services/tt-rss/ttrssserviceroot.h" -#if defined(USE_WEBENGINE) -#include "network-web/oauth2service.h" -#include "services/gmail/gmailserviceroot.h" -#include "services/gmail/network/gmailnetworkfactory.h" -#include "services/inoreader/definitions.h" -#include "services/inoreader/inoreaderfeed.h" -#include "services/inoreader/inoreaderserviceroot.h" -#include "services/inoreader/network/inoreadernetworkfactory.h" -#endif - #include #include #include @@ -1493,7 +1491,6 @@ Assignment DatabaseQueries::getCategories(QSqlDatabase db, int account_id, bool* return categories; } -#if defined(USE_WEBENGINE) QList DatabaseQueries::getGmailAccounts(QSqlDatabase db, bool* ok) { QSqlQuery query(db); @@ -1530,6 +1527,15 @@ QList DatabaseQueries::getGmailAccounts(QSqlDatabase db, bool* ok) return roots; } +bool DatabaseQueries::deleteGmailAccount(QSqlDatabase db, int account_id) { + QSqlQuery q(db); + + q.setForwardOnly(true); + q.prepare(QSL("DELETE FROM GmailAccounts WHERE id = :id;")); + q.bindValue(QSL(":id"), account_id); + return q.exec(); +} + bool DatabaseQueries::deleteInoreaderAccount(QSqlDatabase db, int account_id) { QSqlQuery q(db); @@ -1624,6 +1630,56 @@ QList DatabaseQueries::getInoreaderAccounts(QSqlDatabase db, bool* return roots; } +bool DatabaseQueries::overwriteGmailAccount(QSqlDatabase db, const QString& username, const QString& app_id, + const QString& app_key, const QString& redirect_url, + const QString& refresh_token, int batch_size, int account_id) { + QSqlQuery query(db); + + query.prepare("UPDATE GmailAccounts " + "SET username = :username, app_id = :app_id, app_key = :app_key, " + "redirect_url = :redirect_url, refresh_token = :refresh_token , msg_limit = :msg_limit " + "WHERE id = :id;"); + query.bindValue(QSL(":username"), username); + query.bindValue(QSL(":app_id"), app_id); + query.bindValue(QSL(":app_key"), app_key); + query.bindValue(QSL(":redirect_url"), redirect_url); + query.bindValue(QSL(":refresh_token"), refresh_token); + query.bindValue(QSL(":id"), account_id); + query.bindValue(QSL(":msg_limit"), batch_size <= 0 ? GMAIL_DEFAULT_BATCH_SIZE : batch_size); + + if (query.exec()) { + return true; + } + else { + qWarning("Gmail: Updating account failed: '%s'.", qPrintable(query.lastError().text())); + return false; + } +} + +bool DatabaseQueries::createGmailAccount(QSqlDatabase db, int id_to_assign, const QString& username, + const QString& app_id, const QString& app_key, const QString& redirect_url, + const QString& refresh_token, int batch_size) { + QSqlQuery q(db); + + q.prepare("INSERT INTO GmailAccounts (id, username, app_id, app_key, redirect_url, refresh_token, msg_limit) " + "VALUES (:id, :username, :app_id, :app_key, :redirect_url, :refresh_token, :msg_limit);"); + q.bindValue(QSL(":id"), id_to_assign); + q.bindValue(QSL(":username"), username); + q.bindValue(QSL(":app_id"), app_id); + q.bindValue(QSL(":app_key"), app_key); + q.bindValue(QSL(":redirect_url"), redirect_url); + q.bindValue(QSL(":refresh_token"), refresh_token); + q.bindValue(QSL(":msg_limit"), batch_size <= 0 ? GMAIL_DEFAULT_BATCH_SIZE : batch_size); + + if (q.exec()) { + return true; + } + else { + qWarning("Gmail: Inserting of new account failed: '%s'.", qPrintable(q.lastError().text())); + return false; + } +} + bool DatabaseQueries::overwriteInoreaderAccount(QSqlDatabase db, const QString& username, const QString& app_id, const QString& app_key, const QString& redirect_url, const QString& refresh_token, int batch_size, int account_id) { @@ -1674,8 +1730,6 @@ bool DatabaseQueries::createInoreaderAccount(QSqlDatabase db, int id_to_assign, } } -#endif - Assignment DatabaseQueries::getTtRssFeeds(QSqlDatabase db, int account_id, bool* ok) { Assignment feeds; diff --git a/src/miscellaneous/databasequeries.h b/src/miscellaneous/databasequeries.h index d53bb25cf..1a16a548c 100755 --- a/src/miscellaneous/databasequeries.h +++ b/src/miscellaneous/databasequeries.h @@ -78,10 +78,15 @@ class DatabaseQueries { int auto_update_interval); static Assignment getCategories(QSqlDatabase db, int account_id, bool* ok = nullptr); -#if defined(USE_WEBENGINE) - // Gmail account. + static bool deleteGmailAccount(QSqlDatabase db, int account_id); static QList getGmailAccounts(QSqlDatabase db, bool* ok = nullptr); + static bool overwriteGmailAccount(QSqlDatabase db, const QString& username, const QString& app_id, + const QString& app_key, const QString& redirect_url, const QString& refresh_token, + int batch_size, int account_id); + static bool createGmailAccount(QSqlDatabase db, int id_to_assign, const QString& username, + const QString& app_id, const QString& app_key, const QString& redirect_url, + const QString& refresh_token, int batch_size); // Inoreader account. static bool deleteInoreaderAccount(QSqlDatabase db, int account_id); @@ -94,7 +99,6 @@ class DatabaseQueries { static bool createInoreaderAccount(QSqlDatabase db, int id_to_assign, const QString& username, const QString& app_id, const QString& app_key, const QString& redirect_url, const QString& refresh_token, int batch_size); -#endif // ownCloud account. static QList getOwnCloudAccounts(QSqlDatabase db, bool* ok = nullptr); diff --git a/src/miscellaneous/feedreader.cpp b/src/miscellaneous/feedreader.cpp index 9e65476bc..fcc2693b4 100755 --- a/src/miscellaneous/feedreader.cpp +++ b/src/miscellaneous/feedreader.cpp @@ -18,13 +18,6 @@ #include "miscellaneous/feedreader.h" -#include "services/abstract/serviceroot.h" - -#if defined(USE_WEBENGINE) -#include "services/gmail/gmailentrypoint.h" -#include "services/inoreader/inoreaderentrypoint.h" -#endif - #include "core/feeddownloader.h" #include "core/feedsmodel.h" #include "core/feedsproxymodel.h" @@ -34,6 +27,9 @@ #include "miscellaneous/databasecleaner.h" #include "miscellaneous/mutex.h" #include "services/abstract/cacheforserviceroot.h" +#include "services/abstract/serviceroot.h" +#include "services/gmail/gmailentrypoint.h" +#include "services/inoreader/inoreaderentrypoint.h" #include "services/owncloud/owncloudserviceentrypoint.h" #include "services/standard/standardserviceentrypoint.h" #include "services/tt-rss/ttrssserviceentrypoint.h" @@ -70,10 +66,8 @@ FeedReader::~FeedReader() { QList FeedReader::feedServices() { if (m_feedServices.isEmpty()) { // NOTE: All installed services create their entry points here. -#if defined(USE_WEBENGINE) m_feedServices.append(new GmailEntryPoint()); m_feedServices.append(new InoreaderEntryPoint()); -#endif m_feedServices.append(new OwnCloudServiceEntryPoint()); m_feedServices.append(new StandardServiceEntryPoint()); m_feedServices.append(new TtRssServiceEntryPoint()); diff --git a/src/network-web/oauth2service.cpp b/src/network-web/oauth2service.cpp index e25389110..5ad2c74ff 100755 --- a/src/network-web/oauth2service.cpp +++ b/src/network-web/oauth2service.cpp @@ -41,10 +41,13 @@ #include "network-web/oauth2service.h" #include "definitions/definitions.h" -#include "gui/dialogs/oauthlogin.h" #include "miscellaneous/application.h" #include "services/inoreader/definitions.h" +#if defined(USE_WEBENGINE) +#include "gui/dialogs/oauthlogin.h" +#endif + #include #include #include @@ -70,7 +73,7 @@ OAuth2Service::OAuth2Service(QString authUrl, QString tokenUrl, QString clientId QString OAuth2Service::bearer() { if (!isFullyLoggedIn()) { - qApp->showGuiMessage(tr("Inoreader: you have to login first"), + qApp->showGuiMessage(tr("You have to login first"), tr("Click here to login."), QSystemTrayIcon::Critical, nullptr, false, @@ -165,13 +168,13 @@ void OAuth2Service::refreshAccessToken(QString refresh_token) { } void OAuth2Service::tokenRequestFinished(QNetworkReply* network_reply) { - QJsonDocument json_document = QJsonDocument::fromJson(network_reply->readAll()); + QByteArray repl = network_reply->readAll(); + QJsonDocument json_document = QJsonDocument::fromJson(repl); QJsonObject root_obj = json_document.object(); + auto cod = network_reply->error(); qDebug() << "Token response:" << json_document.toJson(); - IOFactory::writeTextFile("c.json", json_document.toJson()); - if (root_obj.keys().contains("error")) { QString error = root_obj.value("error").toString(); QString error_description = root_obj.value("error_description").toString(); @@ -293,6 +296,8 @@ void OAuth2Service::retrieveAuthCode() { "prompt=consent&access_type=offline").arg(m_clientId, m_scope, m_redirectUrl); + +#if defined(USE_WEBENGINE) OAuthLogin login_page(qApp->mainFormWidget()); connect(&login_page, &OAuthLogin::authGranted, this, &OAuth2Service::authCodeObtained); @@ -306,4 +311,7 @@ void OAuth2Service::retrieveAuthCode() { QSystemTrayIcon::MessageIcon::Information); login_page.login(auth_url, m_redirectUrl); +#endif + + // TODO: For non-webengine version, user http-server and login via external browser. } diff --git a/src/services/gmail/definitions.h b/src/services/gmail/definitions.h index e048f9f08..4090abad6 100755 --- a/src/services/gmail/definitions.h +++ b/src/services/gmail/definitions.h @@ -23,6 +23,8 @@ #define GMAIL_OAUTH_TOKEN_URL "https://accounts.google.com/o/oauth2/token" #define GMAIL_OAUTH_SCOPE "https://mail.google.com/" +#define GMAIL_API_LABELS_LIST "https://www.googleapis.com/gmail/v1/users/me/labels" + #define GMAIL_DEFAULT_BATCH_SIZE 100 #define GMAIL_MAX_BATCH_SIZE 999 #define GMAIL_MIN_BATCH_SIZE 20 diff --git a/src/services/gmail/gmailentrypoint.cpp b/src/services/gmail/gmailentrypoint.cpp index 1220a30bd..fe6a89e79 100755 --- a/src/services/gmail/gmailentrypoint.cpp +++ b/src/services/gmail/gmailentrypoint.cpp @@ -26,10 +26,19 @@ #include "services/gmail/gmailserviceroot.h" #include "services/gmail/gui/formeditgmailaccount.h" +#include + ServiceRoot* GmailEntryPoint::createNewRoot() const { +#if defined(USE_WEBENGINE) FormEditGmailAccount form_acc(qApp->mainFormWidget()); return form_acc.execForCreate(); +#else + QMessageBox::warning(qApp->mainFormWidget(), + QObject::tr("Not supported"), + QObject::tr("This plugin is not supported in NonWebEngine variant of this program.")); + return nullptr; +#endif } QList GmailEntryPoint::initializeSubtree() const { @@ -43,7 +52,7 @@ bool GmailEntryPoint::isSingleInstanceService() const { } QString GmailEntryPoint::name() const { - return QSL("Gmail (not yet implemented)"); + return QSL("Gmail"); } QString GmailEntryPoint::code() const { diff --git a/src/services/gmail/gmailserviceroot.cpp b/src/services/gmail/gmailserviceroot.cpp index 68a2e8d22..a5b20f87e 100755 --- a/src/services/gmail/gmailserviceroot.cpp +++ b/src/services/gmail/gmailserviceroot.cpp @@ -64,37 +64,33 @@ void GmailServiceRoot::saveAccountDataToDatabase() { QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); if (accountId() != NO_PARENT_CATEGORY) { - // TODO: dodělat - - /*if (DatabaseQueries::overwriteInoreaderAccount(database, m_network->userName(), - m_network->oauth()->clientId(), - m_network->oauth()->clientSecret(), - m_network->oauth()->redirectUrl(), - m_network->oauth()->refreshToken(), - m_network->batchSize(), - accountId())) { - updateTitle(); - itemChanged(QList() << this); - }*/ + if (DatabaseQueries::overwriteGmailAccount(database, m_network->userName(), + m_network->oauth()->clientId(), + m_network->oauth()->clientSecret(), + m_network->oauth()->redirectUrl(), + m_network->oauth()->refreshToken(), + m_network->batchSize(), + accountId())) { + updateTitle(); + itemChanged(QList() << this); + } } else { bool saved; int id_to_assign = DatabaseQueries::createAccount(database, code(), &saved); if (saved) { - // TODO: dodělat - - /*if (DatabaseQueries::createInoreaderAccount(database, id_to_assign, - m_network->userName(), - m_network->oauth()->clientId(), - m_network->oauth()->clientSecret(), - m_network->oauth()->redirectUrl(), - m_network->oauth()->refreshToken(), - m_network->batchSize())) { - setId(id_to_assign); - setAccountId(id_to_assign); - updateTitle(); - }*/ + if (DatabaseQueries::createGmailAccount(database, id_to_assign, + m_network->userName(), + m_network->oauth()->clientId(), + m_network->oauth()->clientSecret(), + m_network->oauth()->redirectUrl(), + m_network->oauth()->refreshToken(), + m_network->batchSize())) { + setId(id_to_assign); + setAccountId(id_to_assign); + updateTitle(); + } } } } @@ -158,10 +154,7 @@ QString GmailServiceRoot::additionalTooltip() const { } RootItem* GmailServiceRoot::obtainNewTreeForSyncIn() const { - // TODO: dodělat - return nullptr; - - //return m_network->feedsCategories(true); + return m_network->feedsCategories(); } void GmailServiceRoot::addNewFeed(const QString& url) { @@ -215,7 +208,7 @@ bool GmailServiceRoot::canBeDeleted() const { bool GmailServiceRoot::deleteViaGui() { QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); - if (DatabaseQueries::deleteInoreaderAccount(database, accountId())) { + if (DatabaseQueries::deleteGmailAccount(database, accountId())) { return ServiceRoot::deleteViaGui(); } else { diff --git a/src/services/gmail/gui/formeditgmailaccount.cpp b/src/services/gmail/gui/formeditgmailaccount.cpp index 64470a586..c0ee06bd1 100755 --- a/src/services/gmail/gui/formeditgmailaccount.cpp +++ b/src/services/gmail/gui/formeditgmailaccount.cpp @@ -79,8 +79,7 @@ void FormEditGmailAccount::testSetup() { if (m_oauth->login()) { m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Ok, tr("You are already logged in."), - tr("Access granted. \ - ")); + tr("Access granted.")); } } diff --git a/src/services/gmail/network/gmailnetworkfactory.cpp b/src/services/gmail/network/gmailnetworkfactory.cpp index 646f5631a..f52e3d561 100755 --- a/src/services/gmail/network/gmailnetworkfactory.cpp +++ b/src/services/gmail/network/gmailnetworkfactory.cpp @@ -76,7 +76,7 @@ void GmailNetworkFactory::initializeOauth() { DatabaseQueries::storeNewInoreaderTokens(database, refresh_token, m_service->accountId()); qApp->showGuiMessage(tr("Logged in successfully"), - tr("Your login to Inoreader was authorized."), + tr("Your login to Gmail was authorized."), QSystemTrayIcon::MessageIcon::Information); } }); @@ -86,7 +86,7 @@ void GmailNetworkFactory::setUsername(const QString& username) { m_username = username; } -RootItem* GmailNetworkFactory::feedsCategories(bool obtain_icons) { +RootItem* GmailNetworkFactory::feedsCategories() { Downloader downloader; QEventLoop loop; QString bearer = m_oauth2->bearer().toLocal8Bit(); @@ -95,13 +95,13 @@ RootItem* GmailNetworkFactory::feedsCategories(bool obtain_icons) { return nullptr; } - downloader.appendRawHeader(QString("Authorization").toLocal8Bit(), bearer.toLocal8Bit()); + downloader.appendRawHeader(QString(HTTP_HEADERS_AUTHORIZATION).toLocal8Bit(), bearer.toLocal8Bit()); // We need to quit event loop when the download finishes. connect(&downloader, &Downloader::completed, &loop, &QEventLoop::quit); // TODO: dodělat - //downloader.manipulateData(INOREADER_API_LIST_LABELS, QNetworkAccessManager::Operation::GetOperation); + downloader.manipulateData(GMAIL_API_LABELS_LIST, QNetworkAccessManager::Operation::GetOperation); loop.exec(); if (downloader.lastOutputError() != QNetworkReply::NetworkError::NoError) { @@ -110,17 +110,7 @@ RootItem* GmailNetworkFactory::feedsCategories(bool obtain_icons) { QString category_data = downloader.lastOutputData(); - // TODO: dodělat - //downloader.manipulateData(INOREADER_API_LIST_FEEDS, QNetworkAccessManager::Operation::GetOperation); - loop.exec(); - - if (downloader.lastOutputError() != QNetworkReply::NetworkError::NoError) { - return nullptr; - } - - QString feed_data = downloader.lastOutputData(); - - return decodeFeedCategoriesData(category_data, feed_data, obtain_icons); + return decodeFeedCategoriesData(category_data); } QList GmailNetworkFactory::messages(const QString& stream_id, Feed::Status& error) { @@ -382,9 +372,9 @@ QList GmailNetworkFactory::decodeMessages(const QString& messages_json_ return messages; } -RootItem* GmailNetworkFactory::decodeFeedCategoriesData(const QString& categories, const QString& feeds, bool obtain_icons) { +RootItem* GmailNetworkFactory::decodeFeedCategoriesData(const QString& categories) { RootItem* parent = new RootItem(); - QJsonArray json = QJsonDocument::fromJson(categories.toUtf8()).object()["tags"].toArray(); + QJsonArray json = QJsonDocument::fromJson(categories.toUtf8()).object()["labels"].toArray(); QMap cats; cats.insert(QString(), parent); @@ -392,7 +382,22 @@ RootItem* GmailNetworkFactory::decodeFeedCategoriesData(const QString& categorie foreach (const QJsonValue& obj, json) { auto label = obj.toObject(); QString label_id = label["id"].toString(); + QString label_name = label["name"].toString(); + QString label_type = label["type"].toString(); + if (label_name.contains(QL1C('/'))) { + // We have nested labels. + } + else { + GmailFeed* feed = new GmailFeed(); + + feed->setTitle(label_name); + feed->setCustomId(label_id); + + parent->appendChild(feed); + } + +/* if (label_id.contains(QSL("/label/"))) { // We have label (not "state"). Category* category = new Category(); @@ -405,12 +410,13 @@ RootItem* GmailNetworkFactory::decodeFeedCategoriesData(const QString& categorie // All categories in ownCloud are top-level. parent->appendChild(category); - } + }*/ } - json = QJsonDocument::fromJson(feeds.toUtf8()).object()["subscriptions"].toArray(); +/* + json = QJsonDocument::fromJson(feeds.toUtf8()).object()["subscriptions"].toArray(); - foreach (const QJsonValue& obj, json) { + foreach (const QJsonValue& obj, json) { auto subscription = obj.toObject(); QString id = subscription["id"].toString(); QString title = subscription["title"].toString(); @@ -435,28 +441,10 @@ RootItem* GmailNetworkFactory::decodeFeedCategoriesData(const QString& categorie feed->setTitle(title); feed->setCustomId(id); - if (obtain_icons) { - QString icon_url = subscription["iconUrl"].toString(); - - if (!icon_url.isEmpty()) { - QByteArray icon_data; - - if (NetworkFactory::performNetworkOperation(icon_url, DOWNLOAD_TIMEOUT, - QByteArray(), icon_data, - QNetworkAccessManager::GetOperation).first == QNetworkReply::NoError) { - // Icon downloaded, set it up. - QPixmap icon_pixmap; - - icon_pixmap.loadFromData(icon_data); - feed->setIcon(QIcon(icon_pixmap)); - } - } - } - if (cats.contains(parent_label)) { cats[parent_label]->appendChild(feed); } - } + }*/ return parent; } diff --git a/src/services/gmail/network/gmailnetworkfactory.h b/src/services/gmail/network/gmailnetworkfactory.h index d720a2623..8ea8a4d5b 100755 --- a/src/services/gmail/network/gmailnetworkfactory.h +++ b/src/services/gmail/network/gmailnetworkfactory.h @@ -52,7 +52,7 @@ class GmailNetworkFactory : public QObject { // Returns tree of feeds/categories. // Top-level root of the tree is not needed here. // Returned items do not have primary IDs assigned. - RootItem* feedsCategories(bool obtain_icons); + RootItem* feedsCategories(); QList messages(const QString& stream_id, Feed::Status& error); void markMessagesRead(RootItem::ReadStatus status, const QStringList& custom_ids, bool async = true); @@ -64,7 +64,7 @@ class GmailNetworkFactory : public QObject { private: QList decodeMessages(const QString& messages_json_data, const QString& stream_id); - RootItem* decodeFeedCategoriesData(const QString& categories, const QString& feeds, bool obtain_icons); + RootItem* decodeFeedCategoriesData(const QString& categories); void initializeOauth(); diff --git a/src/services/inoreader/inoreaderentrypoint.cpp b/src/services/inoreader/inoreaderentrypoint.cpp index 3cf65b58b..2c636a06e 100755 --- a/src/services/inoreader/inoreaderentrypoint.cpp +++ b/src/services/inoreader/inoreaderentrypoint.cpp @@ -27,10 +27,19 @@ #include "services/inoreader/inoreaderserviceroot.h" #include "services/inoreader/network/inoreadernetworkfactory.h" +#include + ServiceRoot* InoreaderEntryPoint::createNewRoot() const { +#if defined(USE_WEBENGINE) FormEditInoreaderAccount form_acc(qApp->mainFormWidget()); return form_acc.execForCreate(); +#else + QMessageBox::warning(qApp->mainFormWidget(), + QObject::tr("Not supported"), + QObject::tr("This plugin is not supported in NonWebEngine variant of this program.")); + return nullptr; +#endif } QList InoreaderEntryPoint::initializeSubtree() const {
+ RSS Guard is simple (yet powerful) feed reader. It is able to fetch the most known feed formats, including RSS/RDF and ATOM. RSS Guard is developed on top of the Qt library +
Fixes issues X, Y and Z