Use Perl-compatible regexes for RSS rules. Closes #6367.

--HG--
branch : magao-dev
This commit is contained in:
Tim Delaney
2017-02-11 16:33:18 +11:00
committed by sledgehammer999
parent 02c96fa5e2
commit 8d11af94f2
6 changed files with 86 additions and 46 deletions

View File

@@ -28,14 +28,15 @@
* Contact : chris@qbittorrent.org
*/
#include <QMessageBox>
#include <QFileDialog>
#include <QDebug>
#include <QMenu>
#include <QCursor>
#include <QDebug>
#include <QFileDialog>
#include <QMessageBox>
#include <QMenu>
#include <QRegularExpression>
#include "base/preferences.h"
#include "base/bittorrent/session.h"
#include "base/preferences.h"
#include "base/rss/rssdownloadrulelist.h"
#include "base/rss/rssmanager.h"
#include "base/rss/rssfolder.h"
@@ -72,8 +73,8 @@ AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer<Rss::Manager>
Q_ASSERT(ok);
m_ruleList = manager.toStrongRef()->downloadRules();
m_editableRuleList = new Rss::DownloadRuleList; // Read rule list from disk
m_episodeRegex = new QRegExp("^(^\\d{1,4}x(\\d{1,4}(-(\\d{1,4})?)?;){1,}){1,1}",
Qt::CaseInsensitive);
m_episodeRegex = new QRegularExpression("^(^\\d{1,4}x(\\d{1,4}(-(\\d{1,4})?)?;){1,}){1,1}",
QRegularExpression::CaseInsensitiveOption);
QString tip = "<p>" + tr("Matches articles based on episode filter.") + "</p><p><b>" + tr("Example: ")
+ "1x2;8-15;5;30-;</b>" + tr(" will match 2, 5, 8 through 15, 30 and onward episodes of season one", "example X will match") + "</p>";
tip += "<p>" + tr("Episode filter rules: ") + "</p><ul><li>" + tr("Season number is a mandatory non-zero value") + "</li>"
@@ -671,7 +672,7 @@ void AutomatedRssDownloader::updateFieldsToolTips(bool regex)
{
QString tip;
if (regex) {
tip = "<p>" + tr("Regex mode: use Perl-like regular expressions") + "</p>";
tip = "<p>" + tr("Regex mode: use Perl-compatible regular expressions") + "</p>";
}
else {
tip = "<p>" + tr("Wildcard mode: you can use") + "<ul>"
@@ -697,17 +698,23 @@ void AutomatedRssDownloader::updateFieldsToolTips(bool regex)
void AutomatedRssDownloader::updateMustLineValidity()
{
const QString text = ui->lineContains->text();
bool isRegex = ui->checkRegex->isChecked();
bool valid = true;
QString error;
if (!text.isEmpty()) {
QStringList tokens;
if (ui->checkRegex->isChecked())
if (isRegex)
tokens << text;
else
tokens << text.split("|");
foreach (const QString &token, text.split("|"))
tokens << Utils::String::wildcardToRegex(token);
foreach (const QString &token, tokens) {
QRegExp reg(token, Qt::CaseInsensitive, ui->checkRegex->isChecked() ? QRegExp::RegExp : QRegExp::Wildcard);
QRegularExpression reg(token, QRegularExpression::CaseInsensitiveOption);
if (!reg.isValid()) {
if (isRegex)
error = tr("Position %1: %2").arg(reg.patternErrorOffset()).arg(reg.errorString());
valid = false;
break;
}
@@ -717,27 +724,35 @@ void AutomatedRssDownloader::updateMustLineValidity()
if (valid) {
ui->lineContains->setStyleSheet("");
ui->lbl_must_stat->setPixmap(QPixmap());
ui->lbl_must_stat->setToolTip(QLatin1String(""));
}
else {
ui->lineContains->setStyleSheet("QLineEdit { color: #ff0000; }");
ui->lbl_must_stat->setPixmap(GuiIconProvider::instance()->getIcon("task-attention").pixmap(16, 16));
ui->lbl_must_stat->setToolTip(error);
}
}
void AutomatedRssDownloader::updateMustNotLineValidity()
{
const QString text = ui->lineNotContains->text();
bool isRegex = ui->checkRegex->isChecked();
bool valid = true;
QString error;
if (!text.isEmpty()) {
QStringList tokens;
if (ui->checkRegex->isChecked())
if (isRegex)
tokens << text;
else
tokens << text.split("|");
foreach (const QString &token, text.split("|"))
tokens << Utils::String::wildcardToRegex(token);
foreach (const QString &token, tokens) {
QRegExp reg(token, Qt::CaseInsensitive, ui->checkRegex->isChecked() ? QRegExp::RegExp : QRegExp::Wildcard);
QRegularExpression reg(token, QRegularExpression::CaseInsensitiveOption);
if (!reg.isValid()) {
if (isRegex)
error = tr("Position %1: %2").arg(reg.patternErrorOffset()).arg(reg.errorString());
valid = false;
break;
}
@@ -747,17 +762,19 @@ void AutomatedRssDownloader::updateMustNotLineValidity()
if (valid) {
ui->lineNotContains->setStyleSheet("");
ui->lbl_mustnot_stat->setPixmap(QPixmap());
ui->lbl_mustnot_stat->setToolTip(QLatin1String(""));
}
else {
ui->lineNotContains->setStyleSheet("QLineEdit { color: #ff0000; }");
ui->lbl_mustnot_stat->setPixmap(GuiIconProvider::instance()->getIcon("task-attention").pixmap(16, 16));
ui->lbl_mustnot_stat->setToolTip(error);
}
}
void AutomatedRssDownloader::updateEpisodeFilterValidity()
{
const QString text = ui->lineEFilter->text();
bool valid = text.isEmpty() || m_episodeRegex->indexIn(text) != -1;
bool valid = text.isEmpty() || m_episodeRegex->match(text).hasMatch();
if (valid) {
ui->lineEFilter->setStyleSheet("");

View File

@@ -57,6 +57,7 @@ namespace Rss
QT_BEGIN_NAMESPACE
class QListWidgetItem;
class QRegularExpression;
QT_END_NAMESPACE
class AutomatedRssDownloader: public QDialog
@@ -112,7 +113,7 @@ private:
QListWidgetItem *m_editedRule;
Rss::DownloadRuleList *m_ruleList;
Rss::DownloadRuleList *m_editableRuleList;
QRegExp *m_episodeRegex;
QRegularExpression *m_episodeRegex;
QShortcut *editHotkey;
QShortcut *deleteHotkey;
QSet<QPair<QString, QString >> m_treeListEntries;