mirror of
https://github.com/martinrotter/rssguard.git
synced 2025-02-04 19:27:33 +01:00
fix #848 - added a way to specify common post-process filter when importing feeds
This commit is contained in:
parent
c0a737e93e
commit
4f45ce40ea
@ -27,6 +27,12 @@ FormStandardImportExport::FormStandardImportExport(StandardServiceRoot* service_
|
|||||||
|
|
||||||
GuiUtilities::applyDialogProperties(*this, qApp->icons()->fromTheme(QSL("document-export")));
|
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,
|
m_ui->m_lblSelectFile->setStatus(WidgetWithStatus::StatusType::Error,
|
||||||
tr("No file is selected."),
|
tr("No file is selected."),
|
||||||
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_btnSelectFile, &QPushButton::clicked, this, &FormStandardImportExport::selectFile);
|
||||||
connect(m_ui->m_btnCheckAllItems, &QPushButton::clicked, m_model, &FeedsImportExportModel::checkAllItems);
|
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_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;
|
FormStandardImportExport::~FormStandardImportExport() = default;
|
||||||
@ -58,6 +69,7 @@ void FormStandardImportExport::setMode(FeedsImportExportModel::Mode mode) {
|
|||||||
m_ui->m_treeFeeds->expandAll();
|
m_ui->m_treeFeeds->expandAll();
|
||||||
m_ui->m_cmbRootNode->setVisible(false);
|
m_ui->m_cmbRootNode->setVisible(false);
|
||||||
m_ui->m_lblRootNode->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_groupFile->setTitle(tr("Destination file"));
|
||||||
m_ui->m_groupFeeds->setTitle(tr("Source feeds && categories"));
|
m_ui->m_groupFeeds->setTitle(tr("Source feeds && categories"));
|
||||||
m_ui->m_buttonBox->button(QDialogButtonBox::StandardButton::Ok)->setText(tr("&Export to file"));
|
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);
|
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) {
|
void FormStandardImportExport::selectExportFile(bool without_dialog) {
|
||||||
const QString the_file = qApp->homeFolder() + QDir::separator() +
|
const QString the_file = qApp->homeFolder() + QDir::separator() +
|
||||||
QSL("rssguard_feeds_%1.opml").arg(QDate::currentDate().toString(Qt::DateFormat::ISODate));
|
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,
|
m_ui->m_lblSelectFile->setStatus(WidgetWithStatus::StatusType::Ok,
|
||||||
QDir::toNativeSeparators(selected_file),
|
QDir::toNativeSeparators(selected_file),
|
||||||
tr("File is selected."));
|
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) {
|
switch (m_conversionType) {
|
||||||
case ConversionType::OPML20:
|
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;
|
break;
|
||||||
|
|
||||||
case ConversionType::TxtUrlPerLine:
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -16,13 +16,10 @@ class Category;
|
|||||||
class StandardServiceRoot;
|
class StandardServiceRoot;
|
||||||
|
|
||||||
class FormStandardImportExport : public QDialog {
|
class FormStandardImportExport : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class ConversionType {
|
enum class ConversionType { OPML20 = 0, TxtUrlPerLine = 1 };
|
||||||
OPML20 = 0,
|
|
||||||
TxtUrlPerLine = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit FormStandardImportExport(StandardServiceRoot* service_root, QWidget* parent = nullptr);
|
explicit FormStandardImportExport(StandardServiceRoot* service_root, QWidget* parent = nullptr);
|
||||||
virtual ~FormStandardImportExport();
|
virtual ~FormStandardImportExport();
|
||||||
@ -37,6 +34,8 @@ class FormStandardImportExport : public QDialog {
|
|||||||
void onParsingFinished(int count_failed, int count_succeeded, bool parsing_error);
|
void onParsingFinished(int count_failed, int count_succeeded, bool parsing_error);
|
||||||
void onParsingProgress(int completed, int total);
|
void onParsingProgress(int completed, int total);
|
||||||
|
|
||||||
|
void onPostProcessScriptChanged(const QString& new_pp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void selectExportFile(bool without_dialog);
|
void selectExportFile(bool without_dialog);
|
||||||
void selectImportFile();
|
void selectImportFile();
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>478</width>
|
<width>500</width>
|
||||||
<height>434</height>
|
<height>550</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -49,6 +49,44 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="m_gbFetchMetadata">
|
||||||
|
<property name="title">
|
||||||
|
<string>Fetch online metadata</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Optional post-processing script</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>m_txtPostProcessScript</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="TextEditWithStatus" name="m_txtPostProcessScript" native="true">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>50</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>100</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QFormLayout" name="formLayout_3">
|
<layout class="QFormLayout" name="formLayout_3">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
@ -229,9 +267,16 @@
|
|||||||
<header>labelwithstatus.h</header>
|
<header>labelwithstatus.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>TextEditWithStatus</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>lineeditwithstatus.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>m_btnSelectFile</tabstop>
|
<tabstop>m_btnSelectFile</tabstop>
|
||||||
|
<tabstop>m_gbFetchMetadata</tabstop>
|
||||||
<tabstop>m_cmbRootNode</tabstop>
|
<tabstop>m_cmbRootNode</tabstop>
|
||||||
<tabstop>m_cbExportIcons</tabstop>
|
<tabstop>m_cbExportIcons</tabstop>
|
||||||
<tabstop>m_btnCheckAllItems</tabstop>
|
<tabstop>m_btnCheckAllItems</tabstop>
|
||||||
|
@ -40,8 +40,6 @@ StandardFeedDetails::StandardFeedDetails(QWidget* parent) : QWidget(parent) {
|
|||||||
QVariant::fromValue(StandardFeed::SourceType::Url));
|
QVariant::fromValue(StandardFeed::SourceType::Url));
|
||||||
m_ui.m_cmbSourceType->addItem(StandardFeed::sourceTypeToString(StandardFeed::SourceType::Script),
|
m_ui.m_cmbSourceType->addItem(StandardFeed::sourceTypeToString(StandardFeed::SourceType::Script),
|
||||||
QVariant::fromValue(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.
|
// Add standard feed types.
|
||||||
m_ui.m_cmbType->addItem(StandardFeed::typeToString(StandardFeed::Type::Atom10),
|
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) {
|
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."));
|
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 {
|
else {
|
||||||
m_ui.m_txtPostProcessScript->setStatus(LineEditWithStatus::StatusType::Ok, tr("Command is empty."));
|
m_ui.m_txtPostProcessScript->setStatus(LineEditWithStatus::StatusType::Ok, tr("Command is empty."));
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,9 @@ class Category;
|
|||||||
class RootItem;
|
class RootItem;
|
||||||
|
|
||||||
class StandardFeedDetails : public QWidget {
|
class StandardFeedDetails : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
friend class FormStandardFeedDetails;
|
friend class FormStandardFeedDetails;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit StandardFeedDetails(QWidget* parent = nullptr);
|
explicit StandardFeedDetails(QWidget* parent = nullptr);
|
||||||
|
@ -145,7 +145,9 @@ bool FeedsImportExportModel::exportToOMPL20(QByteArray& result, bool export_icon
|
|||||||
return true;
|
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 parsingStarted();
|
||||||
emit layoutAboutToBeChanged();
|
emit layoutAboutToBeChanged();
|
||||||
|
|
||||||
@ -200,10 +202,16 @@ void FeedsImportExportModel::importAsOPML20(const QByteArray& data, bool fetch_m
|
|||||||
if (!feed_url.isEmpty()) {
|
if (!feed_url.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
if (fetch_metadata_online) {
|
if (fetch_metadata_online) {
|
||||||
StandardFeed* guessed =
|
StandardFeed* guessed = StandardFeed::guessFeed(StandardFeed::SourceType::Url,
|
||||||
StandardFeed::guessFeed(StandardFeed::SourceType::Url, feed_url, {}, {}, {}, custom_proxy);
|
feed_url,
|
||||||
|
post_process_script,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
custom_proxy);
|
||||||
|
|
||||||
guessed->setSource(feed_url);
|
guessed->setSource(feed_url);
|
||||||
|
guessed->setPostProcessScript(post_process_script);
|
||||||
|
|
||||||
active_model_item->appendChild(guessed);
|
active_model_item->appendChild(guessed);
|
||||||
succeded++;
|
succeded++;
|
||||||
add_offline_anyway = false;
|
add_offline_anyway = false;
|
||||||
@ -319,7 +327,9 @@ bool FeedsImportExportModel::exportToTxtURLPerLine(QByteArray& result) {
|
|||||||
return true;
|
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 parsingStarted();
|
||||||
emit layoutAboutToBeChanged();
|
emit layoutAboutToBeChanged();
|
||||||
setRootItem(nullptr);
|
setRootItem(nullptr);
|
||||||
@ -341,9 +351,12 @@ void FeedsImportExportModel::importAsTxtURLPerLine(const QByteArray& data, bool
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (fetch_metadata_online) {
|
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->setSource(url);
|
||||||
|
guessed->setPostProcessScript(post_process_script);
|
||||||
|
|
||||||
root_item->appendChild(guessed);
|
root_item->appendChild(guessed);
|
||||||
succeded++;
|
succeded++;
|
||||||
add_offline_anyway = false;
|
add_offline_anyway = false;
|
||||||
|
@ -17,12 +17,14 @@ class FeedsImportExportModel : public AccountCheckSortedModel {
|
|||||||
// Exports to OPML 2.0
|
// Exports to OPML 2.0
|
||||||
// NOTE: http://dev.opml.org/spec2.html
|
// NOTE: http://dev.opml.org/spec2.html
|
||||||
bool exportToOMPL20(QByteArray& result, bool export_icons);
|
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
|
// Exports to plain text format
|
||||||
// where there is one feed URL per line.
|
// where there is one feed URL per line.
|
||||||
bool exportToTxtURLPerLine(QByteArray& result);
|
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;
|
Mode mode() const;
|
||||||
void setMode(Mode mode);
|
void setMode(Mode mode);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user