From 64f9cbbf540df4bca4b5b55830dcfbebbf438bc9 Mon Sep 17 00:00:00 2001 From: Tim Delaney Date: Sun, 6 Nov 2016 22:51:33 +1100 Subject: [PATCH 1/3] Allow episode zero (special) and leading zeroes in RSS episode filter. --HG-- branch : magao-dev --- src/base/rss/rssdownloadrule.cpp | 14 +++++++++++--- src/gui/rss/automatedrssdownloader.cpp | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/base/rss/rssdownloadrule.cpp b/src/base/rss/rssdownloadrule.cpp index 288a7f1fc..819ead7b4 100644 --- a/src/base/rss/rssdownloadrule.cpp +++ b/src/base/rss/rssdownloadrule.cpp @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include "base/preferences.h" #include "base/utils/fs.h" @@ -97,10 +99,16 @@ bool DownloadRule::matches(const QString &articleTitle) const QString expStr; expStr += "s0?" + s + "[ -_\\.]?" + "e0?"; - foreach (const QString &ep, eps) { - if (ep.isEmpty()) + foreach (const QString &epStr, eps) { + if (epStr.isEmpty()) continue; + QStringRef ep( &epStr); + + // We need to trim leading zeroes, but if it's all zeros then we want episode zero. + while (ep.size() > 1 && ep.startsWith("0")) + ep = ep.right(ep.size() - 1); + if (ep.indexOf('-') != -1) { // Range detected QString partialPattern = "s0?" + s + "[ -_\\.]?" + "e(0?\\d{1,4})"; QRegExp reg(partialPattern, Qt::CaseInsensitive); @@ -120,7 +128,7 @@ bool DownloadRule::matches(const QString &articleTitle) const } } else { // Normal range - QStringList range = ep.split('-'); + QVector range = ep.split('-'); Q_ASSERT(range.size() == 2); if (range.first().toInt() > range.last().toInt()) continue; // Ignore this subrule completely diff --git a/src/gui/rss/automatedrssdownloader.cpp b/src/gui/rss/automatedrssdownloader.cpp index cd253f849..91d234654 100644 --- a/src/gui/rss/automatedrssdownloader.cpp +++ b/src/gui/rss/automatedrssdownloader.cpp @@ -78,7 +78,7 @@ AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer QString tip = "

" + tr("Matches articles based on episode filter.") + "

" + tr("Example: ") + "1x2;8-15;5;30-;" + tr(" will match 2, 5, 8 through 15, 30 and onward episodes of season one", "example X will match") + "

"; tip += "

" + tr("Episode filter rules: ") + "

  • " + tr("Season number is a mandatory non-zero value") + "
  • " - + "
  • " + tr("Episode number is a mandatory non-zero value") + "
  • " + + "
  • " + tr("Episode number is a mandatory positive value") + "
  • " + "
  • " + tr("Filter must end with semicolon") + "
  • " + "
  • " + tr("Three range types for episodes are supported: ") + "
  • " + "
    • " "
    • " + tr("Single number: 1x25; matches episode 25 of season one") + "
    • " From 96c1187f4717251d62bfc59a0fd3c23140ddc8e9 Mon Sep 17 00:00:00 2001 From: Tim Delaney Date: Sun, 6 Nov 2016 15:26:48 +1100 Subject: [PATCH 2/3] RSS parse torrent episodes like 1x01 as well as S01E01. Closes #2749. --HG-- branch : magao-dev --- src/base/rss/rssdownloadrule.cpp | 22 +++++++++++++++++----- src/gui/rss/automatedrssdownloader.cpp | 2 +- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/base/rss/rssdownloadrule.cpp b/src/base/rss/rssdownloadrule.cpp index 819ead7b4..f0d8d7584 100644 --- a/src/base/rss/rssdownloadrule.cpp +++ b/src/base/rss/rssdownloadrule.cpp @@ -96,8 +96,6 @@ bool DownloadRule::matches(const QString &articleTitle) const QString s = f.cap(1); QStringList eps = f.cap(2).split(";"); - QString expStr; - expStr += "s0?" + s + "[ -_\\.]?" + "e0?"; foreach (const QString &epStr, eps) { if (epStr.isEmpty()) @@ -110,14 +108,21 @@ bool DownloadRule::matches(const QString &articleTitle) const ep = ep.right(ep.size() - 1); if (ep.indexOf('-') != -1) { // Range detected - QString partialPattern = "s0?" + s + "[ -_\\.]?" + "e(0?\\d{1,4})"; - QRegExp reg(partialPattern, Qt::CaseInsensitive); + QString partialPattern1 = "\\bs0?" + s + "[ -_\\.]?" + "e(0?\\d{1,4})(?:\\D|\\b)"; + QString partialPattern2 = "\\b" + s + "x" + "(0?\\d{1,4})(?:\\D|\\b)"; + QRegExp reg(partialPattern1, Qt::CaseInsensitive); if (ep.endsWith('-')) { // Infinite range int epOurs = ep.left(ep.size() - 1).toInt(); // Extract partial match from article and compare as digits pos = reg.indexIn(articleTitle); + + if (pos == -1) { + reg = QRegExp(partialPattern2, Qt::CaseInsensitive); + pos = reg.indexIn(articleTitle); + } + if (pos != -1) { int epTheirs = reg.cap(1).toInt(); if (epTheirs >= epOurs) { @@ -138,6 +143,12 @@ bool DownloadRule::matches(const QString &articleTitle) const // Extract partial match from article and compare as digits pos = reg.indexIn(articleTitle); + + if (pos == -1) { + reg = QRegExp(partialPattern2, Qt::CaseInsensitive); + pos = reg.indexIn(articleTitle); + } + if (pos != -1) { int epTheirs = reg.cap(1).toInt(); if ((epOursFirst <= epTheirs) && (epOursLast >= epTheirs)) { @@ -149,7 +160,8 @@ bool DownloadRule::matches(const QString &articleTitle) const } } else { // Single number - QRegExp reg(expStr + ep + "\\D", Qt::CaseInsensitive); + QString expStr("\\b(?:s0?" + s + "[ -_\\.]?" + "e0?" + ep + "|" + s + "x" + "0?" + ep + ")(?:\\D|\\b)"); + QRegExp reg(expStr, Qt::CaseInsensitive); if (reg.indexIn(articleTitle) != -1) { qDebug() << "Matched episode:" << ep; qDebug() << "Matched article:" << articleTitle; diff --git a/src/gui/rss/automatedrssdownloader.cpp b/src/gui/rss/automatedrssdownloader.cpp index 91d234654..9931457c7 100644 --- a/src/gui/rss/automatedrssdownloader.cpp +++ b/src/gui/rss/automatedrssdownloader.cpp @@ -71,7 +71,7 @@ AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer Q_ASSERT(ok); m_ruleList = manager.toStrongRef()->downloadRules(); m_editableRuleList = new Rss::DownloadRuleList; // Read rule list from disk - m_episodeRegex = new QRegExp("^(^[1-9]{1,1}\\d{0,3}x([1-9]{1,1}\\d{0,3}(-([1-9]{1,1}\\d{0,3})?)?;){1,}){1,1}", + m_episodeRegex = new QRegExp("^(^\\d{1,4}x(\\d{1,4}(-(\\d{1,4})?)?;){1,}){1,1}", Qt::CaseInsensitive); m_episodeValidator = new QRegExpValidator(*m_episodeRegex, ui->lineEFilter); ui->lineEFilter->setValidator(m_episodeValidator); From 32bdb73f707f0d7cdfd7a6b1890d69187e95c8eb Mon Sep 17 00:00:00 2001 From: Tim Delaney Date: Mon, 7 Nov 2016 07:18:06 +1100 Subject: [PATCH 3/3] RSS allow infinite range to extend beyond current season. Closes #800, #3876, #6170. --HG-- branch : magao-dev --- src/base/rss/rssdownloadrule.cpp | 15 +++++++++------ src/gui/rss/automatedrssdownloader.cpp | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/base/rss/rssdownloadrule.cpp b/src/base/rss/rssdownloadrule.cpp index f0d8d7584..1f5e67fc8 100644 --- a/src/base/rss/rssdownloadrule.cpp +++ b/src/base/rss/rssdownloadrule.cpp @@ -96,6 +96,7 @@ bool DownloadRule::matches(const QString &articleTitle) const QString s = f.cap(1); QStringList eps = f.cap(2).split(";"); + int sOurs = s.toInt(); foreach (const QString &epStr, eps) { if (epStr.isEmpty()) @@ -108,8 +109,8 @@ bool DownloadRule::matches(const QString &articleTitle) const ep = ep.right(ep.size() - 1); if (ep.indexOf('-') != -1) { // Range detected - QString partialPattern1 = "\\bs0?" + s + "[ -_\\.]?" + "e(0?\\d{1,4})(?:\\D|\\b)"; - QString partialPattern2 = "\\b" + s + "x" + "(0?\\d{1,4})(?:\\D|\\b)"; + QString partialPattern1 = "\\bs0?(\\d{1,4})[ -_\\.]?e(0?\\d{1,4})(?:\\D|\\b)"; + QString partialPattern2 = "\\b(\\d{1,4})x(0?\\d{1,4})(?:\\D|\\b)"; QRegExp reg(partialPattern1, Qt::CaseInsensitive); if (ep.endsWith('-')) { // Infinite range @@ -124,8 +125,9 @@ bool DownloadRule::matches(const QString &articleTitle) const } if (pos != -1) { - int epTheirs = reg.cap(1).toInt(); - if (epTheirs >= epOurs) { + int sTheirs = reg.cap(1).toInt(); + int epTheirs = reg.cap(2).toInt(); + if (((sTheirs == sOurs) && (epTheirs >= epOurs)) || (sTheirs > sOurs)) { qDebug() << "Matched episode:" << ep; qDebug() << "Matched article:" << articleTitle; return true; @@ -150,8 +152,9 @@ bool DownloadRule::matches(const QString &articleTitle) const } if (pos != -1) { - int epTheirs = reg.cap(1).toInt(); - if ((epOursFirst <= epTheirs) && (epOursLast >= epTheirs)) { + int sTheirs = reg.cap(1).toInt(); + int epTheirs = reg.cap(2).toInt(); + if ((sTheirs == sOurs) && ((epOursFirst <= epTheirs) && (epOursLast >= epTheirs))) { qDebug() << "Matched episode:" << ep; qDebug() << "Matched article:" << articleTitle; return true; diff --git a/src/gui/rss/automatedrssdownloader.cpp b/src/gui/rss/automatedrssdownloader.cpp index 9931457c7..790953f73 100644 --- a/src/gui/rss/automatedrssdownloader.cpp +++ b/src/gui/rss/automatedrssdownloader.cpp @@ -83,7 +83,7 @@ AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer + "
    • " + tr("Three range types for episodes are supported: ") + "
    • " + "
      • " "
      • " + tr("Single number: 1x25; matches episode 25 of season one") + "
      • " + "
      • " + tr("Normal range: 1x25-40; matches episodes 25 through 40 of season one") + "
      • " - + "
      • " + tr("Infinite range: 1x25-; matches episodes 25 and upward of season one") + "
      • " + "
    "; + + "
  • " + tr("Infinite range: 1x25-; matches episodes 25 and upward of season one, and all episodes of later seasons") + "
  • " + "
"; ui->lineEFilter->setToolTip(tip); initCategoryCombobox(); loadFeedList();