some refactorings, fixed #390
This commit is contained in:
parent
86b1d6d10e
commit
40d32f3088
@ -30,7 +30,7 @@
|
||||
<url type="donation">https://martinrotter.github.io/donate/</url>
|
||||
<content_rating type="oars-1.1" />
|
||||
<releases>
|
||||
<release version="3.9.0" date="2021-03-29"/>
|
||||
<release version="3.9.0" date="2021-03-30"/>
|
||||
</releases>
|
||||
<content_rating type="oars-1.0">
|
||||
<content_attribute id="violence-cartoon">none</content_attribute>
|
||||
|
@ -304,7 +304,7 @@ Here you can find some useful advanced insights into RSS Guard's modus operandi.
|
||||
RSS Guard offers CLI (command line interface). For overview of its features, run `rssguard --help` in your terminal. You will see the overview of the interface.
|
||||
|
||||
```
|
||||
RSS Guard
|
||||
rssguard.exe [options] [url-1 ... url-n]
|
||||
|
||||
Options:
|
||||
-l, --log <log-file> Write application debug log to file. Note that
|
||||
@ -313,11 +313,26 @@ Options:
|
||||
single instance application mode.
|
||||
-s, --no-single-instance Allow running of multiple application
|
||||
instances.
|
||||
-n, --no-debug-output Completely disable stdout/stderr outputs.
|
||||
-?, -h, --help Displays help on commandline options.
|
||||
--help-all Displays help including Qt specific options.
|
||||
-v, --version Displays version information.
|
||||
|
||||
Arguments:
|
||||
urls List of URL addresses pointing to individual
|
||||
online feeds which should be added.
|
||||
```
|
||||
|
||||
RSS Guard can add feeds passed as URLs via command line arguments. Feed URI [scheme](https://en.wikipedia.org/wiki/Feed_URI_scheme) is supported, so that you can call RSS Guard like this:
|
||||
|
||||
```
|
||||
rssguard.exe "feed://archlinux.org/feeds/news"
|
||||
rssguard.exe "feed:https//archlinux.org/feeds/news"
|
||||
rssguard.exe "https://archlinux.org/feeds/news"
|
||||
```
|
||||
|
||||
So in order to comfortably add feed directly to RSS Guard from you browser without copying its URL manually, you have to "open" RSS Guard "with" feed URL passed as parameter. There are [extensions](https://addons.mozilla.org/en-GB/firefox/addon/open-with/) which can do it.
|
||||
|
||||
## How to build
|
||||
RSS Guard is C++ application and all common build instructions can be found in top of [project file](https://github.com/martinrotter/rssguard/blob/master/build.pro).
|
||||
|
||||
|
@ -46,6 +46,9 @@ class RSSGUARD_DLLSPEC Message {
|
||||
QString m_author;
|
||||
QString m_contents;
|
||||
QString m_rawContents;
|
||||
|
||||
// This should be preferably in UTC and should be converted
|
||||
// to localtime when needed.
|
||||
QDateTime m_created;
|
||||
QString m_feedId;
|
||||
int m_accountId;
|
||||
|
@ -231,7 +231,7 @@ Assignment DatabaseQueries::getCategories(const QSqlDatabase& db, int account_id
|
||||
|
||||
cat->setTitle(query_categories.value(CAT_DB_TITLE_INDEX).toString());
|
||||
cat->setDescription(query_categories.value(CAT_DB_DESCRIPTION_INDEX).toString());
|
||||
cat->setCreationDate(TextFactory::parseDateTime(query_categories.value(CAT_DB_DCREATED_INDEX).value<qint64>()).toLocalTime());
|
||||
cat->setCreationDate(TextFactory::parseDateTime(query_categories.value(CAT_DB_DCREATED_INDEX).value<qint64>()));
|
||||
cat->setIcon(qApp->icons()->fromByteArray(query_categories.value(CAT_DB_ICON_INDEX).toByteArray()));
|
||||
|
||||
categories << pair;
|
||||
@ -286,7 +286,7 @@ Assignment DatabaseQueries::getFeeds(const QSqlDatabase& db,
|
||||
}
|
||||
|
||||
feed->setDescription(QString::fromUtf8(query.value(FDS_DB_DESCRIPTION_INDEX).toByteArray()));
|
||||
feed->setCreationDate(TextFactory::parseDateTime(query.value(FDS_DB_DCREATED_INDEX).value<qint64>()).toLocalTime());
|
||||
feed->setCreationDate(TextFactory::parseDateTime(query.value(FDS_DB_DCREATED_INDEX).value<qint64>()));
|
||||
feed->setIcon(qApp->icons()->fromByteArray(query.value(FDS_DB_ICON_INDEX).toByteArray()));
|
||||
feed->setAutoUpdateType(static_cast<Feed::AutoUpdateType>(query.value(FDS_DB_UPDATE_TYPE_INDEX).toInt()));
|
||||
feed->setAutoUpdateInitialInterval(query.value(FDS_DB_UPDATE_INTERVAL_INDEX).toInt());
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
Application::Application(const QString& id, int& argc, char** argv)
|
||||
: QtSingleApplication(id, argc, argv), m_updateFeedsLock(new Mutex()) {
|
||||
parseCmdArguments();
|
||||
parseCmdArgumentsFromMyInstance();
|
||||
qInstallMessageHandler(performLogging);
|
||||
|
||||
m_feedReader = nullptr;
|
||||
@ -118,7 +118,7 @@ void Application::performLogging(QtMsgType type, const QMessageLogContext& conte
|
||||
}
|
||||
|
||||
void Application::reactOnForeignNotifications() {
|
||||
connect(this, &Application::messageReceived, this, &Application::processExecutionMessage);
|
||||
connect(this, &Application::messageReceived, this, &Application::parseCmdArgumentsFromOtherInstance);
|
||||
}
|
||||
|
||||
void Application::hideOrShowMainForm() {
|
||||
@ -347,39 +347,51 @@ void Application::restoreDatabaseSettings(bool restore_database, bool restore_se
|
||||
}
|
||||
}
|
||||
|
||||
void Application::processExecutionMessage(const QString& message) {
|
||||
void Application::parseCmdArgumentsFromOtherInstance(const QString& message) {
|
||||
qDebugNN << LOGSEC_CORE
|
||||
<< "Received"
|
||||
<< QUOTE_W_SPACE(message)
|
||||
<< "execution message from another application instance.";
|
||||
|
||||
const QStringList messages = message.split(ARGUMENTS_LIST_SEPARATOR);
|
||||
QStringList messages = message.split(ARGUMENTS_LIST_SEPARATOR);
|
||||
QCommandLineParser cmd_parser;
|
||||
|
||||
if (messages.contains(APP_QUIT_INSTANCE)) {
|
||||
messages.prepend(qApp->applicationFilePath());
|
||||
|
||||
cmd_parser.addOption(QCommandLineOption(QStringList() << APP_QUIT_INSTANCE));
|
||||
cmd_parser.addOption(QCommandLineOption(QStringList() << APP_IS_RUNNING));
|
||||
cmd_parser.addPositionalArgument("urls",
|
||||
"List of URL addresses pointing to individual online feeds which should be added.",
|
||||
"[url-1 ... url-n]");
|
||||
|
||||
cmd_parser.process(messages);
|
||||
|
||||
if (cmd_parser.isSet(APP_QUIT_INSTANCE)) {
|
||||
quit();
|
||||
return;
|
||||
}
|
||||
else if (cmd_parser.isSet(APP_IS_RUNNING)) {
|
||||
showGuiMessage(APP_NAME, tr("Application is already running."), QSystemTrayIcon::MessageIcon::Information);
|
||||
mainForm()->display();
|
||||
}
|
||||
else {
|
||||
for (const QString& msg : messages) {
|
||||
if (msg == APP_IS_RUNNING) {
|
||||
showGuiMessage(APP_NAME, tr("Application is already running."), QSystemTrayIcon::MessageIcon::Information);
|
||||
mainForm()->display();
|
||||
}
|
||||
else if (msg.startsWith(QL1S(URI_SCHEME_FEED_SHORT))) {
|
||||
// Application was running, and someone wants to add new feed.
|
||||
ServiceRoot* rt = boolinq::from(feedReader()->feedsModel()->serviceRoots()).firstOrDefault([](ServiceRoot* root) {
|
||||
return root->supportsFeedAdding();
|
||||
});
|
||||
|
||||
if (rt != nullptr) {
|
||||
rt->addNewFeed(nullptr, msg);
|
||||
}
|
||||
else {
|
||||
showGuiMessage(tr("Cannot add feed"),
|
||||
tr("Feed cannot be added because standard RSS/ATOM account is not enabled."),
|
||||
QSystemTrayIcon::MessageIcon::Warning, qApp->mainForm(),
|
||||
true);
|
||||
}
|
||||
}
|
||||
messages = cmd_parser.positionalArguments();
|
||||
|
||||
for (const QString& msg : qAsConst(messages)) {
|
||||
// Application was running, and someone wants to add new feed.
|
||||
ServiceRoot* rt = boolinq::from(feedReader()->feedsModel()->serviceRoots()).firstOrDefault([](ServiceRoot* root) {
|
||||
return root->supportsFeedAdding();
|
||||
});
|
||||
|
||||
if (rt != nullptr) {
|
||||
rt->addNewFeed(nullptr, msg);
|
||||
}
|
||||
else {
|
||||
showGuiMessage(tr("Cannot add feed"),
|
||||
tr("Feed cannot be added because there is no active account which can add feeds."),
|
||||
QSystemTrayIcon::MessageIcon::Warning,
|
||||
qApp->mainForm(),
|
||||
true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -576,7 +588,7 @@ void Application::determineFirstRuns() {
|
||||
eliminateFirstRuns();
|
||||
}
|
||||
|
||||
void Application::parseCmdArguments() {
|
||||
void Application::parseCmdArgumentsFromMyInstance() {
|
||||
QCommandLineOption log_file(QStringList() << CLI_LOG_SHORT << CLI_LOG_LONG,
|
||||
"Write application debug log to file. Note that logging to file may slow application down.",
|
||||
"log-file");
|
||||
@ -591,9 +603,11 @@ void Application::parseCmdArguments() {
|
||||
m_cmdParser.addOptions({ log_file, custom_data_folder, disable_singleinstance, disable_debug });
|
||||
m_cmdParser.addHelpOption();
|
||||
m_cmdParser.addVersionOption();
|
||||
m_cmdParser.addPositionalArgument("urls",
|
||||
"List of URL addresses pointing to individual online feeds which should be added.",
|
||||
"[url-1 ... url-n]");
|
||||
m_cmdParser.setApplicationDescription(APP_NAME);
|
||||
|
||||
m_cmdParser.process(*this);
|
||||
m_cmdParser.process(QCoreApplication::arguments());
|
||||
|
||||
s_customLogFile = m_cmdParser.value(CLI_LOG_SHORT);
|
||||
|
||||
|
@ -125,7 +125,8 @@ class RSSGUARD_DLLSPEC Application : public QtSingleApplication {
|
||||
void restart();
|
||||
|
||||
// Processes incoming message from another RSS Guard instance.
|
||||
void processExecutionMessage(const QString& message);
|
||||
void parseCmdArgumentsFromOtherInstance(const QString& message);
|
||||
void parseCmdArgumentsFromMyInstance();
|
||||
|
||||
private slots:
|
||||
void onCommitData(QSessionManager& manager);
|
||||
@ -142,7 +143,6 @@ class RSSGUARD_DLLSPEC Application : public QtSingleApplication {
|
||||
void setupCustomDataFolder(const QString& data_folder);
|
||||
void determineFirstRuns();
|
||||
void eliminateFirstRuns();
|
||||
void parseCmdArguments();
|
||||
|
||||
private:
|
||||
QCommandLineParser m_cmdParser;
|
||||
|
@ -202,6 +202,18 @@ QString WebFactory::unescapeHtml(const QString& html) {
|
||||
return output;
|
||||
}
|
||||
|
||||
QString WebFactory::processFeedUriScheme(const QString& url) {
|
||||
if (url.startsWith(URI_SCHEME_FEED)) {
|
||||
return QSL(URI_SCHEME_HTTPS) + url.mid(QSL(URI_SCHEME_FEED).size());
|
||||
}
|
||||
else if (url.startsWith(URI_SCHEME_FEED_SHORT)) {
|
||||
return url.mid(QSL(URI_SCHEME_FEED_SHORT).size());
|
||||
}
|
||||
else {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
void WebFactory::updateProxy() {
|
||||
const QNetworkProxy::ProxyType selected_proxy_type = static_cast<QNetworkProxy::ProxyType>(qApp->settings()->value(GROUP(Proxy),
|
||||
SETTING(Proxy::Type)).
|
||||
|
@ -37,6 +37,8 @@ class WebFactory : public QObject {
|
||||
// ∀ = ∀ (entity name), ∀ (base-10 entity), ∀ (base-16 entity)
|
||||
QString unescapeHtml(const QString& html);
|
||||
|
||||
QString processFeedUriScheme(const QString& url);
|
||||
|
||||
#if defined(USE_WEBENGINE)
|
||||
QAction* engineSettingsAction();
|
||||
AdBlockManager* adBlock() const;
|
||||
|
@ -88,7 +88,6 @@ void FormCategoryDetails::apply() {
|
||||
RootItem* parent = static_cast<RootItem*>(m_ui->m_cmbParentCategory->itemData(m_ui->m_cmbParentCategory->currentIndex()).value<void*>());
|
||||
|
||||
m_category->setTitle(m_ui->m_txtTitle->lineEdit()->text());
|
||||
m_category->setCreationDate(QDateTime::currentDateTime());
|
||||
m_category->setDescription(m_ui->m_txtDescription->lineEdit()->text());
|
||||
m_category->setIcon(m_ui->m_btnIcon->icon());
|
||||
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
#include "services/abstract/importantnode.h"
|
||||
|
||||
#include "miscellaneous/application.h"
|
||||
#include "database/databasequeries.h"
|
||||
#include "miscellaneous/application.h"
|
||||
#include "miscellaneous/iconfactory.h"
|
||||
#include "services/abstract/cacheforserviceroot.h"
|
||||
#include "services/abstract/serviceroot.h"
|
||||
@ -16,7 +16,6 @@ ImportantNode::ImportantNode(RootItem* parent_item) : RootItem(parent_item) {
|
||||
setIcon(qApp->icons()->fromTheme(QSL("mail-mark-important")));
|
||||
setTitle(tr("Important messages"));
|
||||
setDescription(tr("You can find all important messages here."));
|
||||
setCreationDate(QDateTime::currentDateTime());
|
||||
}
|
||||
|
||||
QList<Message> ImportantNode::undeletedMessages() const {
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
#include "services/abstract/labelsnode.h"
|
||||
|
||||
#include "gui/dialogs/formaddeditlabel.h"
|
||||
#include "miscellaneous/application.h"
|
||||
#include "database/databasefactory.h"
|
||||
#include "database/databasequeries.h"
|
||||
#include "gui/dialogs/formaddeditlabel.h"
|
||||
#include "miscellaneous/application.h"
|
||||
#include "miscellaneous/iconfactory.h"
|
||||
#include "services/abstract/serviceroot.h"
|
||||
|
||||
@ -17,7 +17,6 @@ LabelsNode::LabelsNode(RootItem* parent_item) : RootItem(parent_item), m_actLabe
|
||||
setIcon(qApp->icons()->fromTheme(QSL("tag-folder")));
|
||||
setTitle(tr("Labels"));
|
||||
setDescription(tr("You can see all your labels (tags) here."));
|
||||
setCreationDate(QDateTime::currentDateTime());
|
||||
}
|
||||
|
||||
void LabelsNode::loadLabels(const QList<Label*>& labels) {
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
#include "services/abstract/recyclebin.h"
|
||||
|
||||
#include "miscellaneous/application.h"
|
||||
#include "database/databasequeries.h"
|
||||
#include "miscellaneous/application.h"
|
||||
#include "miscellaneous/iconfactory.h"
|
||||
#include "miscellaneous/textfactory.h"
|
||||
#include "services/abstract/cacheforserviceroot.h"
|
||||
@ -18,7 +18,6 @@ RecycleBin::RecycleBin(RootItem* parent_item) : RootItem(parent_item), m_totalCo
|
||||
setIcon(qApp->icons()->fromTheme(QSL("user-trash")));
|
||||
setTitle(tr("Recycle bin"));
|
||||
setDescription(tr("Recycle bin contains all deleted messages from all feeds."));
|
||||
setCreationDate(QDateTime::currentDateTime());
|
||||
}
|
||||
|
||||
QString RecycleBin::additionalTooltip() const {
|
||||
|
@ -15,7 +15,8 @@
|
||||
|
||||
RootItem::RootItem(RootItem* parent_item)
|
||||
: QObject(nullptr), m_kind(RootItem::Kind::Root), m_id(NO_PARENT_CATEGORY), m_customId(QL1S("")),
|
||||
m_title(QString()), m_description(QString()), m_keepOnTop(false), m_childItems(QList<RootItem*>()), m_parentItem(parent_item) {}
|
||||
m_title(QString()), m_description(QString()), m_creationDate(QDateTime::currentDateTimeUtc()),
|
||||
m_keepOnTop(false), m_childItems(QList<RootItem*>()), m_parentItem(parent_item) {}
|
||||
|
||||
RootItem::RootItem(const RootItem& other) : RootItem(nullptr) {
|
||||
setTitle(other.title());
|
||||
|
@ -170,6 +170,7 @@ class RSSGUARD_DLLSPEC RootItem : public QObject {
|
||||
QString title() const;
|
||||
void setTitle(const QString& title);
|
||||
|
||||
// This should be in UTC and should be converted to localtime when needed.
|
||||
QDateTime creationDate() const;
|
||||
void setCreationDate(const QDateTime& creation_date);
|
||||
|
||||
|
@ -21,8 +21,6 @@ ServiceRoot::ServiceRoot(RootItem* parent)
|
||||
: RootItem(parent), m_recycleBin(new RecycleBin(this)), m_importantNode(new ImportantNode(this)),
|
||||
m_labelsNode(new LabelsNode(this)), m_accountId(NO_PARENT_CATEGORY), m_networkProxy(QNetworkProxy()) {
|
||||
setKind(RootItem::Kind::ServiceRoot);
|
||||
setCreationDate(QDateTime::currentDateTime());
|
||||
|
||||
appendCommonNodes();
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ void FormStandardFeedDetails::loadFeedData() {
|
||||
m_authDetails->m_txtPassword->lineEdit()->setText(std_feed->password());
|
||||
|
||||
if (m_creatingNew) {
|
||||
auto processed_url = qobject_cast<StandardServiceRoot*>(m_serviceRoot)->processFeedUrl(m_urlToProcess);
|
||||
auto processed_url = qApp->web()->processFeedUriScheme(m_urlToProcess);
|
||||
|
||||
m_standardFeedDetails->prepareForNewFeed(m_parentToSelect, processed_url);
|
||||
}
|
||||
|
@ -233,7 +233,6 @@ void FeedsImportExportModel::importAsOPML20(const QByteArray& data, bool fetch_m
|
||||
new_feed->setDescription(feed_description);
|
||||
new_feed->setEncoding(feed_encoding);
|
||||
new_feed->setSource(feed_url);
|
||||
new_feed->setCreationDate(QDateTime::currentDateTime());
|
||||
new_feed->setSourceType(source_type);
|
||||
new_feed->setPostProcessScript(post_process);
|
||||
|
||||
@ -290,7 +289,6 @@ void FeedsImportExportModel::importAsOPML20(const QByteArray& data, bool fetch_m
|
||||
new_category->setIcon(category_icon);
|
||||
}
|
||||
|
||||
new_category->setCreationDate(QDateTime::currentDateTime());
|
||||
new_category->setDescription(category_description);
|
||||
active_model_item->appendChild(new_category);
|
||||
|
||||
@ -369,7 +367,6 @@ void FeedsImportExportModel::importAsTxtURLPerLine(const QByteArray& data, bool
|
||||
|
||||
feed->setSource(url);
|
||||
feed->setTitle(url);
|
||||
feed->setCreationDate(QDateTime::currentDateTime());
|
||||
feed->setIcon(qApp->icons()->fromTheme(QSL("application-rss+xml")));
|
||||
feed->setEncoding(DEFAULT_FEED_ENCODING);
|
||||
root_item->appendChild(feed);
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "miscellaneous/mutex.h"
|
||||
#include "miscellaneous/settings.h"
|
||||
#include "network-web/networkfactory.h"
|
||||
#include "network-web/webfactory.h"
|
||||
#include "services/abstract/gui/formcategorydetails.h"
|
||||
#include "services/abstract/importantnode.h"
|
||||
#include "services/abstract/labelsnode.h"
|
||||
@ -86,8 +87,6 @@ void StandardServiceRoot::start(bool freshly_activated) {
|
||||
requestItemExpand({ this }, true);
|
||||
}
|
||||
}
|
||||
|
||||
checkArgumentsForFeedAdding();
|
||||
}
|
||||
|
||||
void StandardServiceRoot::stop() {
|
||||
@ -271,37 +270,6 @@ QList<Message> StandardServiceRoot::obtainNewMessages(const QList<Feed*>& feeds,
|
||||
return msgs;
|
||||
}
|
||||
|
||||
void StandardServiceRoot::checkArgumentsForFeedAdding() {
|
||||
auto args = qApp->arguments().mid(1);
|
||||
|
||||
for (const QString& arg : qAsConst(args)) {
|
||||
checkArgumentForFeedAdding(arg);
|
||||
}
|
||||
}
|
||||
|
||||
QString StandardServiceRoot::processFeedUrl(const QString& feed_url) {
|
||||
if (feed_url.startsWith(QL1S(URI_SCHEME_FEED_SHORT))) {
|
||||
QString without_feed_prefix = feed_url.mid(QSL(URI_SCHEME_FEED_SHORT).size());
|
||||
|
||||
if (without_feed_prefix.startsWith(QL1S(URI_SCHEME_HTTPS_SHORT)) ||
|
||||
without_feed_prefix.startsWith(QL1S(URI_SCHEME_HTTP_SHORT))) {
|
||||
return without_feed_prefix;
|
||||
}
|
||||
else {
|
||||
return feed_url;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return feed_url;
|
||||
}
|
||||
}
|
||||
|
||||
void StandardServiceRoot::checkArgumentForFeedAdding(const QString& argument) {
|
||||
if (argument.startsWith(QL1S(URI_SCHEME_FEED_SHORT))) {
|
||||
addNewFeed(nullptr, processFeedUrl(argument));
|
||||
}
|
||||
}
|
||||
|
||||
QList<QAction*> StandardServiceRoot::getContextMenuForFeed(StandardFeed* feed) {
|
||||
if (m_feedContextMenu.isEmpty()) {
|
||||
// Initialize.
|
||||
|
@ -46,9 +46,6 @@ class StandardServiceRoot : public ServiceRoot {
|
||||
void exportFeeds();
|
||||
|
||||
private:
|
||||
QString processFeedUrl(const QString& feed_url);
|
||||
void checkArgumentForFeedAdding(const QString& argument);
|
||||
void checkArgumentsForFeedAdding();
|
||||
|
||||
// Takes structure residing under given root item and adds feeds/categories from
|
||||
// it to active structure.
|
||||
|
@ -87,6 +87,7 @@ int main(int argc, char* argv[]) {
|
||||
qApp->offerChanges();
|
||||
qApp->showPolls();
|
||||
qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->loadAllExpandStates();
|
||||
qApp->parseCmdArgumentsFromOtherInstance(qApp->cmdParser()->positionalArguments().join(ARGUMENTS_LIST_SEPARATOR));
|
||||
|
||||
return Application::exec();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user