New: Detect audio vs text from newznab categories

pull/1063/head
ta264 3 years ago
parent 065f03a01a
commit 3abda061ba

@ -11,6 +11,7 @@ using NzbDrone.Core.DecisionEngine.Specifications;
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
_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 @@ namespace NzbDrone.Core.Test.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.Download.Aggregation;
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 @@ namespace NzbDrone.Core.DecisionEngine
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 @@ namespace NzbDrone.Core.DecisionEngine
{
parsedBookInfo = new ParsedBookInfo
{
Quality = QualityParser.ParseQuality(report.Title)
Quality = QualityParser.ParseQuality(report.Title, null, report.Categories)
};
}
@ -160,7 +167,7 @@ namespace NzbDrone.Core.DecisionEngine
{
parsedBookInfo = new ParsedBookInfo
{
Quality = QualityParser.ParseQuality(report.Title, null)
Quality = QualityParser.ParseQuality(report.Title, null, report.Categories)
};
}

@ -121,6 +121,25 @@ namespace NzbDrone.Core.Indexers.Newznab
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 @@ namespace NzbDrone.Core.Indexers
releaseInfo.BasicAuthString = GetBasicAuth();
releaseInfo.InfoUrl = GetInfoUrl(item);
releaseInfo.CommentUrl = GetCommentUrl(item);
releaseInfo.Categories = GetCategories(item);
try
{
@ -230,6 +231,11 @@ namespace NzbDrone.Core.Indexers
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 @@ namespace NzbDrone.Core.Indexers.Torznab
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 @@ namespace NzbDrone.Core.Parser.Model
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 @@ namespace NzbDrone.Core.Parser
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 @@ namespace NzbDrone.Core.Parser
}
}
//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…
Cancel
Save