mirror of
https://github.com/Readarr/Readarr
synced 2025-12-14 20:36:18 +01:00
New: Detect audio vs text from newznab categories
This commit is contained in:
parent
065f03a01a
commit
3abda061ba
9 changed files with 72 additions and 10 deletions
|
|
@ -11,6 +11,7 @@
|
|||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
|
|
@ -60,7 +61,8 @@ public void Setup()
|
|||
_remoteBook = new RemoteBook
|
||||
{
|
||||
Author = new Author(),
|
||||
Books = new List<Book> { new Book() }
|
||||
Books = new List<Book> { new Book() },
|
||||
ParsedBookInfo = Builder<ParsedBookInfo>.CreateNew().With(x => x.Quality = new QualityModel(Quality.FLAC)).Build()
|
||||
};
|
||||
|
||||
Mocker.GetMock<IParsingService>()
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ public void init_should_add_default_profiles()
|
|||
Subject.Handle(new ApplicationStartedEvent());
|
||||
|
||||
Mocker.GetMock<IProfileRepository>()
|
||||
.Verify(v => v.Insert(It.IsAny<QualityProfile>()), Times.Exactly(4));
|
||||
.Verify(v => v.Insert(It.IsAny<QualityProfile>()), Times.Exactly(3));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
|
|
@ -105,6 +106,12 @@ private IEnumerable<DownloadDecision> GetBookDecisions(List<ReleaseInfo> reports
|
|||
|
||||
remoteBook.Release = report;
|
||||
|
||||
// parse quality again with title and category if unknown
|
||||
if (remoteBook.ParsedBookInfo.Quality.Quality == Quality.Unknown)
|
||||
{
|
||||
remoteBook.ParsedBookInfo.Quality = QualityParser.ParseQuality(report.Title, null, report.Categories);
|
||||
}
|
||||
|
||||
if (remoteBook.Author == null)
|
||||
{
|
||||
decision = new DownloadDecision(remoteBook, new Rejection("Unknown Author"));
|
||||
|
|
@ -138,7 +145,7 @@ private IEnumerable<DownloadDecision> GetBookDecisions(List<ReleaseInfo> reports
|
|||
{
|
||||
parsedBookInfo = new ParsedBookInfo
|
||||
{
|
||||
Quality = QualityParser.ParseQuality(report.Title)
|
||||
Quality = QualityParser.ParseQuality(report.Title, null, report.Categories)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -160,7 +167,7 @@ private IEnumerable<DownloadDecision> GetBookDecisions(List<ReleaseInfo> reports
|
|||
{
|
||||
parsedBookInfo = new ParsedBookInfo
|
||||
{
|
||||
Quality = QualityParser.ParseQuality(report.Title, null)
|
||||
Quality = QualityParser.ParseQuality(report.Title, null, report.Categories)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,6 +121,25 @@ protected override DateTime GetPublishDate(XElement item)
|
|||
return base.GetPublishDate(item);
|
||||
}
|
||||
|
||||
protected override List<int> GetCategories(XElement item)
|
||||
{
|
||||
var values = item.Elements(ns + "attr")
|
||||
.Where(e => e.Attribute("name").Value.Equals("category", StringComparison.OrdinalIgnoreCase) &&
|
||||
e.Attribute("value")?.Value != null)
|
||||
.Select(e => e.Attribute("value").Value);
|
||||
|
||||
var cats = new List<int>();
|
||||
foreach (var value in values)
|
||||
{
|
||||
if (int.TryParse(value, out var cat))
|
||||
{
|
||||
cats.Add(cat);
|
||||
}
|
||||
}
|
||||
|
||||
return cats;
|
||||
}
|
||||
|
||||
protected virtual string GetAuthor(XElement item)
|
||||
{
|
||||
var authorString = TryGetNewznabAttribute(item, "author");
|
||||
|
|
|
|||
|
|
@ -159,6 +159,7 @@ protected virtual ReleaseInfo ProcessItem(XElement item, ReleaseInfo releaseInfo
|
|||
releaseInfo.BasicAuthString = GetBasicAuth();
|
||||
releaseInfo.InfoUrl = GetInfoUrl(item);
|
||||
releaseInfo.CommentUrl = GetCommentUrl(item);
|
||||
releaseInfo.Categories = GetCategories(item);
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -230,6 +231,11 @@ protected virtual string GetCommentUrl(XElement item)
|
|||
return ParseUrl((string)item.Element("comments"));
|
||||
}
|
||||
|
||||
protected virtual List<int> GetCategories(XElement item)
|
||||
{
|
||||
return new List<int>();
|
||||
}
|
||||
|
||||
protected virtual long GetSize(XElement item)
|
||||
{
|
||||
if (UseEnclosureLength)
|
||||
|
|
|
|||
|
|
@ -91,9 +91,23 @@ protected override long GetSize(XElement item)
|
|||
return size;
|
||||
}
|
||||
|
||||
protected override DateTime GetPublishDate(XElement item)
|
||||
protected override List<int> GetCategories(XElement item)
|
||||
{
|
||||
return base.GetPublishDate(item);
|
||||
var values = item.Elements(ns + "attr")
|
||||
.Where(e => e.Attribute("name").Value.Equals("category", StringComparison.OrdinalIgnoreCase) &&
|
||||
e.Attribute("value")?.Value != null)
|
||||
.Select(e => e.Attribute("value").Value);
|
||||
|
||||
var cats = new List<int>();
|
||||
foreach (var value in values)
|
||||
{
|
||||
if (int.TryParse(value, out var cat))
|
||||
{
|
||||
cats.Add(cat);
|
||||
}
|
||||
}
|
||||
|
||||
return cats;
|
||||
}
|
||||
|
||||
protected override string GetDownloadUrl(XElement item)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NzbDrone.Core.Indexers;
|
||||
|
||||
|
|
@ -25,7 +26,7 @@ public class ReleaseInfo
|
|||
public string Source { get; set; }
|
||||
public string Container { get; set; }
|
||||
public string Codec { get; set; }
|
||||
public string Resolution { get; set; }
|
||||
public List<int> Categories { get; set; }
|
||||
|
||||
public int Age
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
|
|
@ -29,7 +31,7 @@ public class QualityParser
|
|||
private static readonly Regex CodecRegex = new Regex(@"\b(?:(?<PDF>PDF)|(?<MOBI>MOBI)|(?<EPUB>EPUB)|(?<AZW3>AZW3?)|(?<MP1>MPEG Version \d(.5)? Audio, Layer 1|MP1)|(?<MP2>MPEG Version \d(.5)? Audio, Layer 2|MP2)|(?<MP3VBR>MP3.*VBR|MPEG Version \d(.5)? Audio, Layer 3 vbr)|(?<MP3CBR>MP3|MPEG Version \d(.5)? Audio, Layer 3)|(?<FLAC>flac)|(?<WAVPACK>wavpack|wv)|(?<ALAC>alac)|(?<WMA>WMA\d?)|(?<WAV>WAV|PCM)|(?<AAC>M4A|M4P|M4B|AAC|mp4a|MPEG-4 Audio(?!.*alac))|(?<OGG>OGG|OGA|Vorbis))\b|(?<APE>monkey's audio|[\[|\(].*\bape\b.*[\]|\)])|(?<OPUS>Opus Version \d(.5)? Audio|[\[|\(].*\bopus\b.*[\]|\)])",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
public static QualityModel ParseQuality(string name, string desc = null)
|
||||
public static QualityModel ParseQuality(string name, string desc = null, List<int> categories = null)
|
||||
{
|
||||
Logger.Debug("Trying to parse quality for {0}", name);
|
||||
|
||||
|
|
@ -107,6 +109,16 @@ public static QualityModel ParseQuality(string name, string desc = null)
|
|||
}
|
||||
}
|
||||
|
||||
//Based on category
|
||||
if (result.Quality == Quality.Unknown && categories != null)
|
||||
{
|
||||
if (categories.Any(x => x >= 3000 && x < 4000))
|
||||
{
|
||||
result.Quality = Quality.UnknownAudio;
|
||||
result.QualityDetectionSource = QualityDetectionSource.Category;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
namespace NzbDrone.Core.Qualities
|
||||
namespace NzbDrone.Core.Qualities
|
||||
{
|
||||
public enum QualityDetectionSource
|
||||
{
|
||||
Name,
|
||||
Extension,
|
||||
TagLib
|
||||
TagLib,
|
||||
Category
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue