From 4f45ce40ea83aff2a270698836d65cd99d8be53c Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Thu, 8 Dec 2022 10:45:42 +0100 Subject: [PATCH] fix #848 - added a way to specify common post-process filter when importing feeds --- .../standard/gui/formstandardimportexport.cpp | 41 +++++++++++----- .../standard/gui/formstandardimportexport.h | 9 ++-- .../standard/gui/formstandardimportexport.ui | 49 ++++++++++++++++++- .../standard/gui/standardfeeddetails.cpp | 8 +-- .../standard/gui/standardfeeddetails.h | 4 +- .../standardfeedsimportexportmodel.cpp | 23 +++++++-- .../standard/standardfeedsimportexportmodel.h | 6 ++- 7 files changed, 104 insertions(+), 36 deletions(-) diff --git a/src/librssguard/services/standard/gui/formstandardimportexport.cpp b/src/librssguard/services/standard/gui/formstandardimportexport.cpp index 08bf687c0..80b217154 100644 --- a/src/librssguard/services/standard/gui/formstandardimportexport.cpp +++ b/src/librssguard/services/standard/gui/formstandardimportexport.cpp @@ -27,6 +27,12 @@ FormStandardImportExport::FormStandardImportExport(StandardServiceRoot* service_ GuiUtilities::applyDialogProperties(*this, qApp->icons()->fromTheme(QSL("document-export"))); + m_ui->m_txtPostProcessScript->textEdit()->setTabChangesFocus(true); + m_ui->m_txtPostProcessScript->textEdit()->setPlaceholderText(tr("Full command to execute")); + m_ui->m_txtPostProcessScript->textEdit()->setToolTip(tr("You can enter full command including interpreter here.")); + m_ui->m_txtPostProcessScript->setStatus(WidgetWithStatus::StatusType::Ok, + tr("Here you can enter script executaion line, including interpreter.")); + m_ui->m_lblSelectFile->setStatus(WidgetWithStatus::StatusType::Error, tr("No file is selected."), tr("No file is selected.")); @@ -42,6 +48,11 @@ FormStandardImportExport::FormStandardImportExport(StandardServiceRoot* service_ connect(m_ui->m_btnSelectFile, &QPushButton::clicked, this, &FormStandardImportExport::selectFile); connect(m_ui->m_btnCheckAllItems, &QPushButton::clicked, m_model, &FeedsImportExportModel::checkAllItems); connect(m_ui->m_btnUncheckAllItems, &QPushButton::clicked, m_model, &FeedsImportExportModel::uncheckAllItems); + connect(m_ui->m_txtPostProcessScript->textEdit(), &QPlainTextEdit::textChanged, this, [this]() { + onPostProcessScriptChanged(m_ui->m_txtPostProcessScript->textEdit()->toPlainText()); + }); + + onPostProcessScriptChanged({}); } FormStandardImportExport::~FormStandardImportExport() = default; @@ -58,6 +69,7 @@ void FormStandardImportExport::setMode(FeedsImportExportModel::Mode mode) { m_ui->m_treeFeeds->expandAll(); m_ui->m_cmbRootNode->setVisible(false); m_ui->m_lblRootNode->setVisible(false); + m_ui->m_gbFetchMetadata->setVisible(false); m_ui->m_groupFile->setTitle(tr("Destination file")); m_ui->m_groupFeeds->setTitle(tr("Source feeds && categories")); m_ui->m_buttonBox->button(QDialogButtonBox::StandardButton::Ok)->setText(tr("&Export to file")); @@ -142,6 +154,15 @@ void FormStandardImportExport::onParsingProgress(int completed, int total) { m_ui->m_progressBar->setValue(completed); } +void FormStandardImportExport::onPostProcessScriptChanged(const QString& new_pp) { + if (QRegularExpression(QSL(SCRIPT_SOURCE_TYPE_REGEXP)).match(new_pp).hasMatch() || !new_pp.simplified().isEmpty()) { + m_ui->m_txtPostProcessScript->setStatus(LineEditWithStatus::StatusType::Ok, tr("Command is ok.")); + } + else { + m_ui->m_txtPostProcessScript->setStatus(LineEditWithStatus::StatusType::Ok, tr("Command is empty.")); + } +} + void FormStandardImportExport::selectExportFile(bool without_dialog) { const QString the_file = qApp->homeFolder() + QDir::separator() + QSL("rssguard_feeds_%1.opml").arg(QDate::currentDate().toString(Qt::DateFormat::ISODate)); @@ -218,18 +239,8 @@ void FormStandardImportExport::selectImportFile() { m_ui->m_lblSelectFile->setStatus(WidgetWithStatus::StatusType::Ok, QDir::toNativeSeparators(selected_file), tr("File is selected.")); - QMessageBox::StandardButton answer = - MsgBox::show(this, - QMessageBox::Icon::Warning, - tr("Get online metadata"), - tr("Metadata for your feeds can be fetched online. Note that the action " - "could take several minutes, depending on number of feeds."), - tr("Do you want to fetch feed metadata online?"), - QString(), - QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, - QMessageBox::StandardButton::Yes); - parseImportFile(selected_file, answer == QMessageBox::StandardButton::Yes); + parseImportFile(selected_file, m_ui->m_gbFetchMetadata->isChecked()); } } @@ -250,11 +261,15 @@ void FormStandardImportExport::parseImportFile(const QString& file_name, bool fe switch (m_conversionType) { case ConversionType::OPML20: - m_model->importAsOPML20(input_data, fetch_metadata_online); + m_model->importAsOPML20(input_data, + fetch_metadata_online, + m_ui->m_txtPostProcessScript->textEdit()->toPlainText()); break; case ConversionType::TxtUrlPerLine: - m_model->importAsTxtURLPerLine(input_data, fetch_metadata_online); + m_model->importAsTxtURLPerLine(input_data, + fetch_metadata_online, + m_ui->m_txtPostProcessScript->textEdit()->toPlainText()); break; default: diff --git a/src/librssguard/services/standard/gui/formstandardimportexport.h b/src/librssguard/services/standard/gui/formstandardimportexport.h index 3e32cd461..1a3bf3af8 100644 --- a/src/librssguard/services/standard/gui/formstandardimportexport.h +++ b/src/librssguard/services/standard/gui/formstandardimportexport.h @@ -16,13 +16,10 @@ class Category; class StandardServiceRoot; class FormStandardImportExport : public QDialog { - Q_OBJECT + Q_OBJECT public: - enum class ConversionType { - OPML20 = 0, - TxtUrlPerLine = 1 - }; + enum class ConversionType { OPML20 = 0, TxtUrlPerLine = 1 }; explicit FormStandardImportExport(StandardServiceRoot* service_root, QWidget* parent = nullptr); virtual ~FormStandardImportExport(); @@ -37,6 +34,8 @@ class FormStandardImportExport : public QDialog { void onParsingFinished(int count_failed, int count_succeeded, bool parsing_error); void onParsingProgress(int completed, int total); + void onPostProcessScriptChanged(const QString& new_pp); + private: void selectExportFile(bool without_dialog); void selectImportFile(); diff --git a/src/librssguard/services/standard/gui/formstandardimportexport.ui b/src/librssguard/services/standard/gui/formstandardimportexport.ui index 72263f516..5ab892983 100644 --- a/src/librssguard/services/standard/gui/formstandardimportexport.ui +++ b/src/librssguard/services/standard/gui/formstandardimportexport.ui @@ -6,8 +6,8 @@ 0 0 - 478 - 434 + 500 + 550 @@ -49,6 +49,44 @@ + + + + Fetch online metadata + + + true + + + + + + Optional post-processing script + + + m_txtPostProcessScript + + + + + + + + 0 + 50 + + + + + 16777215 + 100 + + + + + + + @@ -229,9 +267,16 @@
labelwithstatus.h
1 + + TextEditWithStatus + QWidget +
lineeditwithstatus.h
+ 1 +
m_btnSelectFile + m_gbFetchMetadata m_cmbRootNode m_cbExportIcons m_btnCheckAllItems diff --git a/src/librssguard/services/standard/gui/standardfeeddetails.cpp b/src/librssguard/services/standard/gui/standardfeeddetails.cpp index 5af65c788..23adf1e9a 100644 --- a/src/librssguard/services/standard/gui/standardfeeddetails.cpp +++ b/src/librssguard/services/standard/gui/standardfeeddetails.cpp @@ -40,8 +40,6 @@ StandardFeedDetails::StandardFeedDetails(QWidget* parent) : QWidget(parent) { QVariant::fromValue(StandardFeed::SourceType::Url)); m_ui.m_cmbSourceType->addItem(StandardFeed::sourceTypeToString(StandardFeed::SourceType::Script), QVariant::fromValue(StandardFeed::SourceType::Script)); - m_ui.m_txtPostProcessScript->setStatus(WidgetWithStatus::StatusType::Ok, - tr("Here you can enter script executaion line, including interpreter.")); // Add standard feed types. m_ui.m_cmbType->addItem(StandardFeed::typeToString(StandardFeed::Type::Atom10), @@ -265,13 +263,9 @@ void StandardFeedDetails::onUrlChanged(const QString& new_url) { } void StandardFeedDetails::onPostProcessScriptChanged(const QString& new_pp) { - if (QRegularExpression(QSL(SCRIPT_SOURCE_TYPE_REGEXP)).match(new_pp).hasMatch()) { + if (QRegularExpression(QSL(SCRIPT_SOURCE_TYPE_REGEXP)).match(new_pp).hasMatch() || !new_pp.simplified().isEmpty()) { m_ui.m_txtPostProcessScript->setStatus(LineEditWithStatus::StatusType::Ok, tr("Command is ok.")); } - else if (!new_pp.simplified().isEmpty()) { - m_ui.m_txtPostProcessScript->setStatus(LineEditWithStatus::StatusType::Warning, - tr("Command not seem to use \"#\" separator for arguments.")); - } else { m_ui.m_txtPostProcessScript->setStatus(LineEditWithStatus::StatusType::Ok, tr("Command is empty.")); } diff --git a/src/librssguard/services/standard/gui/standardfeeddetails.h b/src/librssguard/services/standard/gui/standardfeeddetails.h index 4c6ce0dd6..3ceec3346 100644 --- a/src/librssguard/services/standard/gui/standardfeeddetails.h +++ b/src/librssguard/services/standard/gui/standardfeeddetails.h @@ -15,9 +15,9 @@ class Category; class RootItem; class StandardFeedDetails : public QWidget { - Q_OBJECT + Q_OBJECT - friend class FormStandardFeedDetails; + friend class FormStandardFeedDetails; public: explicit StandardFeedDetails(QWidget* parent = nullptr); diff --git a/src/librssguard/services/standard/standardfeedsimportexportmodel.cpp b/src/librssguard/services/standard/standardfeedsimportexportmodel.cpp index 8c810517a..9eb47ccd0 100644 --- a/src/librssguard/services/standard/standardfeedsimportexportmodel.cpp +++ b/src/librssguard/services/standard/standardfeedsimportexportmodel.cpp @@ -145,7 +145,9 @@ bool FeedsImportExportModel::exportToOMPL20(QByteArray& result, bool export_icon return true; } -void FeedsImportExportModel::importAsOPML20(const QByteArray& data, bool fetch_metadata_online) { +void FeedsImportExportModel::importAsOPML20(const QByteArray& data, + bool fetch_metadata_online, + const QString& post_process_script) { emit parsingStarted(); emit layoutAboutToBeChanged(); @@ -200,10 +202,16 @@ void FeedsImportExportModel::importAsOPML20(const QByteArray& data, bool fetch_m if (!feed_url.isEmpty()) { try { if (fetch_metadata_online) { - StandardFeed* guessed = - StandardFeed::guessFeed(StandardFeed::SourceType::Url, feed_url, {}, {}, {}, custom_proxy); + StandardFeed* guessed = StandardFeed::guessFeed(StandardFeed::SourceType::Url, + feed_url, + post_process_script, + {}, + {}, + custom_proxy); guessed->setSource(feed_url); + guessed->setPostProcessScript(post_process_script); + active_model_item->appendChild(guessed); succeded++; add_offline_anyway = false; @@ -319,7 +327,9 @@ bool FeedsImportExportModel::exportToTxtURLPerLine(QByteArray& result) { return true; } -void FeedsImportExportModel::importAsTxtURLPerLine(const QByteArray& data, bool fetch_metadata_online) { +void FeedsImportExportModel::importAsTxtURLPerLine(const QByteArray& data, + bool fetch_metadata_online, + const QString& post_process_script) { emit parsingStarted(); emit layoutAboutToBeChanged(); setRootItem(nullptr); @@ -341,9 +351,12 @@ void FeedsImportExportModel::importAsTxtURLPerLine(const QByteArray& data, bool try { if (fetch_metadata_online) { - StandardFeed* guessed = StandardFeed::guessFeed(StandardFeed::SourceType::Url, url, {}, {}, {}, custom_proxy); + StandardFeed* guessed = + StandardFeed::guessFeed(StandardFeed::SourceType::Url, url, post_process_script, {}, {}, custom_proxy); guessed->setSource(url); + guessed->setPostProcessScript(post_process_script); + root_item->appendChild(guessed); succeded++; add_offline_anyway = false; diff --git a/src/librssguard/services/standard/standardfeedsimportexportmodel.h b/src/librssguard/services/standard/standardfeedsimportexportmodel.h index da5f8901d..ff9a04a44 100644 --- a/src/librssguard/services/standard/standardfeedsimportexportmodel.h +++ b/src/librssguard/services/standard/standardfeedsimportexportmodel.h @@ -17,12 +17,14 @@ class FeedsImportExportModel : public AccountCheckSortedModel { // Exports to OPML 2.0 // NOTE: http://dev.opml.org/spec2.html bool exportToOMPL20(QByteArray& result, bool export_icons); - void importAsOPML20(const QByteArray& data, bool fetch_metadata_online); + void importAsOPML20(const QByteArray& data, bool fetch_metadata_online, const QString& post_process_script = {}); // Exports to plain text format // where there is one feed URL per line. bool exportToTxtURLPerLine(QByteArray& result); - void importAsTxtURLPerLine(const QByteArray& data, bool fetch_metadata_online); + void importAsTxtURLPerLine(const QByteArray& data, + bool fetch_metadata_online, + const QString& post_process_script = {}); Mode mode() const; void setMode(Mode mode);