mirror of https://github.com/lidarr/Lidarr
Extend Qualities and Setup Default Groups (#127)
* Extend Qualities and Setup Default Groups * fixup! Extend Qualities * fixup! Codacy * fixup! One more
This commit is contained in:
parent
ead0b7a2f4
commit
10b8174726
|
@ -16,8 +16,13 @@
|
|||
width: 50px;
|
||||
}
|
||||
|
||||
.audio {
|
||||
composes: cell from 'Components/Table/Cells/TableRowCell.css';
|
||||
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.language,
|
||||
.audio,
|
||||
.video,
|
||||
.status {
|
||||
composes: cell from 'Components/Table/Cells/TableRowCell.css';
|
||||
|
|
|
@ -167,7 +167,7 @@ class EditQualityProfileModalContent extends Component {
|
|||
name="cutoff"
|
||||
{...cutoff}
|
||||
values={qualities}
|
||||
helpText="Once this quality is reached Sonarr will no longer download episodes"
|
||||
helpText="Once this quality is reached Lidarr will no longer download albums"
|
||||
onChange={onCutoffChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
@ -200,7 +200,7 @@ class EditQualityProfileModalContent extends Component {
|
|||
id &&
|
||||
<div
|
||||
className={styles.deleteButtonContainer}
|
||||
title={isInUse && 'Can\'t delete a quality profile that is attached to a series'}
|
||||
title={isInUse && 'Can\'t delete a quality profile that is attached to a artist'}
|
||||
>
|
||||
<Button
|
||||
kind={kinds.DANGER}
|
||||
|
|
|
@ -7,6 +7,7 @@ function MediaInfo(props) {
|
|||
type,
|
||||
audioChannels,
|
||||
audioCodec,
|
||||
audioBitRate,
|
||||
videoCodec
|
||||
} = props;
|
||||
|
||||
|
@ -27,6 +28,16 @@ function MediaInfo(props) {
|
|||
!!audioChannels &&
|
||||
audioChannels.toFixed(1)
|
||||
}
|
||||
|
||||
{
|
||||
((!!audioCodec && !!audioBitRate) || (!!audioChannels && !!audioBitRate)) &&
|
||||
' - '
|
||||
}
|
||||
|
||||
{
|
||||
!!audioBitRate &&
|
||||
audioBitRate
|
||||
}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
@ -46,6 +57,7 @@ MediaInfo.propTypes = {
|
|||
type: PropTypes.string.isRequired,
|
||||
audioChannels: PropTypes.number,
|
||||
audioCodec: PropTypes.string,
|
||||
audioBitRate: PropTypes.string,
|
||||
videoCodec: PropTypes.string
|
||||
};
|
||||
|
||||
|
|
|
@ -23,11 +23,11 @@ namespace Lidarr.Api.V1.Profiles.Quality
|
|||
|
||||
protected override bool IsValid(PropertyValidatorContext context)
|
||||
{
|
||||
var cutoff = (int)context.PropertyValue;
|
||||
int cutoff = (int)context.PropertyValue;
|
||||
dynamic instance = context.ParentContext.InstanceToValidate;
|
||||
var items = instance.Items as IList<QualityProfileQualityItemResource>;
|
||||
|
||||
var cutoffItem = items.SingleOrDefault(i => i.Id == cutoff || (i.Quality != null && i.Quality.Id == cutoff));
|
||||
QualityProfileQualityItemResource cutoffItem = items.SingleOrDefault(i => (i.Quality == null && i.Id == cutoff) || i.Quality?.Id == cutoff);
|
||||
|
||||
if (cutoffItem == null)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NzbDrone.Core.Profiles.Qualities;
|
||||
using Lidarr.Http;
|
||||
|
||||
|
@ -7,44 +5,19 @@ namespace Lidarr.Api.V1.Profiles.Quality
|
|||
{
|
||||
public class QualityProfileSchemaModule : LidarrRestModule<QualityProfileResource>
|
||||
{
|
||||
public QualityProfileSchemaModule()
|
||||
private readonly IProfileService _profileService;
|
||||
|
||||
public QualityProfileSchemaModule(IProfileService profileService)
|
||||
: base("/qualityprofile/schema")
|
||||
{
|
||||
_profileService = profileService;
|
||||
GetResourceSingle = GetSchema;
|
||||
}
|
||||
|
||||
private QualityProfileResource GetSchema()
|
||||
{
|
||||
var groupedQualites = NzbDrone.Core.Qualities.Quality.DefaultQualityDefinitions.GroupBy(q => q.Weight);
|
||||
var items = new List<ProfileQualityItem>();
|
||||
var groupId = 1000;
|
||||
Profile qualityProfile = _profileService.GetDefaultProfile(string.Empty);
|
||||
|
||||
foreach (var group in groupedQualites)
|
||||
{
|
||||
if (group.Count() == 1)
|
||||
{
|
||||
items.Add(new ProfileQualityItem { Quality = group.First().Quality, Allowed = false });
|
||||
continue;
|
||||
}
|
||||
|
||||
items.Add(new ProfileQualityItem
|
||||
{
|
||||
Id = groupId,
|
||||
Name = group.First().GroupName,
|
||||
Items = group.Select(g => new ProfileQualityItem
|
||||
{
|
||||
Quality = g.Quality,
|
||||
Allowed = false
|
||||
}).ToList(),
|
||||
Allowed = false
|
||||
});
|
||||
|
||||
groupId++;
|
||||
}
|
||||
|
||||
var qualityProfile = new Profile();
|
||||
qualityProfile.Cutoff = NzbDrone.Core.Qualities.Quality.Unknown.Id;
|
||||
qualityProfile.Items = items;
|
||||
|
||||
return qualityProfile.ToResource();
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace Lidarr.Api.V1.TrackFiles
|
|||
public class MediaInfoResource : RestResource
|
||||
{
|
||||
public decimal AudioChannels { get; set; }
|
||||
public string AudioBitRate { get; set; }
|
||||
public string AudioCodec { get; set; }
|
||||
}
|
||||
|
||||
|
@ -21,7 +22,8 @@ namespace Lidarr.Api.V1.TrackFiles
|
|||
return new MediaInfoResource
|
||||
{
|
||||
AudioChannels = MediaInfoFormatter.FormatAudioChannels(model),
|
||||
AudioCodec = MediaInfoFormatter.FormatAudioCodec(model)
|
||||
AudioCodec = MediaInfoFormatter.FormatAudioCodec(model),
|
||||
AudioBitRate = MediaInfoFormatter.FormatAudioBitrate(model)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,15 +77,15 @@ namespace NzbDrone.Core.Test.Datastore
|
|||
.All().With(c => c.Id = 0)
|
||||
.Build().ToList();
|
||||
|
||||
history[0].Quality = new QualityModel(Quality.MP3_512, new Revision(version: 2));
|
||||
history[1].Quality = new QualityModel(Quality.MP3_320, new Revision(version: 2));
|
||||
history[0].Quality = new QualityModel(Quality.MP3_320, new Revision(version: 2));
|
||||
history[1].Quality = new QualityModel(Quality.MP3_256, new Revision(version: 2));
|
||||
|
||||
|
||||
Db.InsertMany(history);
|
||||
|
||||
var returnedHistory = Db.All<History.History>();
|
||||
|
||||
returnedHistory[0].Quality.Quality.Should().Be(Quality.MP3_512);
|
||||
returnedHistory[0].Quality.Quality.Should().Be(Quality.MP3_320);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore.Migration;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
[TestFixture]
|
||||
public class add_various_qualites_in_profileFixture : MigrationTest<add_various_qualites_in_profile>
|
||||
{
|
||||
private string GenerateQualityJson(int quality, bool allowed)
|
||||
{
|
||||
return $"{{ \"quality\": {quality}, \"allowed\": {allowed.ToString().ToLowerInvariant()} }}";
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_add_wav_quality()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Profiles").Row(new
|
||||
{
|
||||
Id = 0,
|
||||
Name = "Lossless",
|
||||
Cutoff = 1,
|
||||
Items = $"[{GenerateQualityJson(1, true)}, {GenerateQualityJson((int)Quality.MP3_320, false)}, {GenerateQualityJson((int)Quality.FLAC, true)}]"
|
||||
});
|
||||
});
|
||||
|
||||
var profiles = db.Query<Profile4>("SELECT Items FROM Profiles LIMIT 1");
|
||||
|
||||
var items = profiles.First().Items;
|
||||
items.Should().HaveCount(7);
|
||||
items.Select(v => v.Quality).Should().Contain(13);
|
||||
items.Select(v => v.Items.Count).Should().BeEquivalentTo(9, 5, 6, 3, 0, 5, 5);
|
||||
items.Select(v => v.Allowed).Should().BeEquivalentTo(false, true, false, true, false, false, false);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_add_trash_lossy_quality_group_and_qualities()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Profiles").Row(new
|
||||
{
|
||||
Id = 0,
|
||||
Name = "Lossless",
|
||||
Cutoff = 1,
|
||||
Items = $"[{GenerateQualityJson(1, true)}, {GenerateQualityJson((int)Quality.MP3_320, false)}, {GenerateQualityJson((int)Quality.FLAC, true)}]"
|
||||
});
|
||||
});
|
||||
|
||||
var profiles = db.Query<Profile4>("SELECT Items FROM Profiles LIMIT 1");
|
||||
|
||||
var items = profiles.First().Items;
|
||||
items.Should().HaveCount(7);
|
||||
items.Select(v => v.Name).Should().Contain("Trash Quality Lossy");
|
||||
items.Select(v => v.Items.Count).Should().BeEquivalentTo(9, 5, 6, 3, 0, 5, 5);
|
||||
items.Select(v => v.Allowed).Should().BeEquivalentTo(false, true, false, true, false, false, false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -47,7 +47,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
};
|
||||
|
||||
_fakeArtist = Builder<Artist>.CreateNew()
|
||||
.With(c => c.Profile = new Profile { Cutoff = Quality.MP3_512.Id, Items = Qualities.QualityFixture.GetDefaultQualities() })
|
||||
.With(c => c.Profile = new Profile { Cutoff = Quality.MP3_320.Id, Items = Qualities.QualityFixture.GetDefaultQualities() })
|
||||
.With(l => l.LanguageProfile = new LanguageProfile { Cutoff = Language.Spanish, Languages = LanguageFixture.GetDefaultLanguages() })
|
||||
.Build();
|
||||
|
||||
|
@ -66,7 +66,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
};
|
||||
|
||||
_upgradableQuality = new Tuple<QualityModel, Language>(new QualityModel(Quality.MP3_192, new Revision(version: 1)), Language.English);
|
||||
_notupgradableQuality = new Tuple<QualityModel, Language>(new QualityModel(Quality.MP3_512, new Revision(version: 2)), Language.English);
|
||||
_notupgradableQuality = new Tuple<QualityModel, Language>(new QualityModel(Quality.MP3_320, new Revision(version: 2)), Language.English);
|
||||
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.SetupGet(s => s.EnableCompletedDownloadHandling)
|
||||
|
@ -162,9 +162,9 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
[Test]
|
||||
public void should_not_be_upgradable_if_album_is_of_same_quality_as_existing()
|
||||
{
|
||||
_fakeArtist.Profile = new Profile { Cutoff = Quality.MP3_512.Id, Items = Qualities.QualityFixture.GetDefaultQualities() };
|
||||
_parseResultSingle.ParsedAlbumInfo.Quality = new QualityModel(Quality.MP3_512, new Revision(version: 1));
|
||||
_upgradableQuality = new Tuple<QualityModel, Language>(new QualityModel(Quality.MP3_512, new Revision(version: 1)), Language.English);
|
||||
_fakeArtist.Profile = new Profile { Cutoff = Quality.MP3_320.Id, Items = Qualities.QualityFixture.GetDefaultQualities() };
|
||||
_parseResultSingle.ParsedAlbumInfo.Quality = new QualityModel(Quality.MP3_320, new Revision(version: 1));
|
||||
_upgradableQuality = new Tuple<QualityModel, Language>(new QualityModel(Quality.MP3_320, new Revision(version: 1)), Language.English);
|
||||
|
||||
GivenMostRecentForAlbum(FIRST_ALBUM_ID, string.Empty, _upgradableQuality, DateTime.UtcNow, HistoryEventType.Grabbed);
|
||||
|
||||
|
@ -174,9 +174,9 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
[Test]
|
||||
public void should_not_be_upgradable_if_cutoff_already_met()
|
||||
{
|
||||
_fakeArtist.Profile = new Profile { Cutoff = Quality.MP3_512.Id, Items = Qualities.QualityFixture.GetDefaultQualities() };
|
||||
_parseResultSingle.ParsedAlbumInfo.Quality = new QualityModel(Quality.MP3_512, new Revision(version: 1));
|
||||
_upgradableQuality = new Tuple<QualityModel, Language>(new QualityModel(Quality.MP3_512, new Revision(version: 1)), Language.Spanish);
|
||||
_fakeArtist.Profile = new Profile { Cutoff = Quality.MP3_320.Id, Items = Qualities.QualityFixture.GetDefaultQualities() };
|
||||
_parseResultSingle.ParsedAlbumInfo.Quality = new QualityModel(Quality.MP3_320, new Revision(version: 1));
|
||||
_upgradableQuality = new Tuple<QualityModel, Language>(new QualityModel(Quality.MP3_320, new Revision(version: 1)), Language.Spanish);
|
||||
|
||||
GivenMostRecentForAlbum(FIRST_ALBUM_ID, string.Empty, _upgradableQuality, DateTime.UtcNow, HistoryEventType.Grabbed);
|
||||
|
||||
|
@ -202,9 +202,9 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
public void should_return_false_if_cutoff_already_met_and_cdh_is_disabled()
|
||||
{
|
||||
GivenCdhDisabled();
|
||||
_fakeArtist.Profile = new Profile { Cutoff = Quality.MP3_512.Id, Items = Qualities.QualityFixture.GetDefaultQualities() };
|
||||
_parseResultSingle.ParsedAlbumInfo.Quality = new QualityModel(Quality.MP3_512, new Revision(version: 1));
|
||||
_upgradableQuality = new Tuple<QualityModel, Language>(new QualityModel(Quality.MP3_512, new Revision(version: 1)), Language.Spanish);
|
||||
_fakeArtist.Profile = new Profile { Cutoff = Quality.MP3_320.Id, Items = Qualities.QualityFixture.GetDefaultQualities() };
|
||||
_parseResultSingle.ParsedAlbumInfo.Quality = new QualityModel(Quality.MP3_320, new Revision(version: 1));
|
||||
_upgradableQuality = new Tuple<QualityModel, Language>(new QualityModel(Quality.MP3_320, new Revision(version: 1)), Language.Spanish);
|
||||
|
||||
GivenMostRecentForAlbum(FIRST_ALBUM_ID, "test", _upgradableQuality, DateTime.UtcNow.AddDays(-100), HistoryEventType.Grabbed);
|
||||
|
||||
|
|
|
@ -332,7 +332,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
[Test]
|
||||
public void should_prefer_quality_over_the_number_of_peers()
|
||||
{
|
||||
var remoteAlbum1 = GivenRemoteAlbum(new List<Album> { GivenAlbum(1) }, new QualityModel(Quality.MP3_512), Language.English);
|
||||
var remoteAlbum1 = GivenRemoteAlbum(new List<Album> { GivenAlbum(1) }, new QualityModel(Quality.MP3_320), Language.English);
|
||||
var remoteAlbum2 = GivenRemoteAlbum(new List<Album> { GivenAlbum(1) }, new QualityModel(Quality.MP3_192), Language.English);
|
||||
|
||||
var torrentInfo1 = new TorrentInfo();
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
{
|
||||
new object[] { Quality.MP3_192 },
|
||||
new object[] { Quality.MP3_256 },
|
||||
new object[] { Quality.MP3_512 }
|
||||
new object[] { Quality.MP3_320 }
|
||||
};
|
||||
|
||||
public static object[] DeniedTestCases =
|
||||
|
@ -35,7 +35,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
public void Setup()
|
||||
{
|
||||
var fakeArtist = Builder<Artist>.CreateNew()
|
||||
.With(c => c.Profile = (LazyLoaded<Profile>)new Profile { Cutoff = Quality.MP3_512.Id })
|
||||
.With(c => c.Profile = (LazyLoaded<Profile>)new Profile { Cutoff = Quality.MP3_320.Id })
|
||||
.Build();
|
||||
|
||||
remoteAlbum = new RemoteAlbum
|
||||
|
@ -49,7 +49,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
public void should_allow_if_quality_is_defined_in_profile(Quality qualityType)
|
||||
{
|
||||
remoteAlbum.ParsedAlbumInfo.Quality.Quality = qualityType;
|
||||
remoteAlbum.Artist.Profile.Value.Items = Qualities.QualityFixture.GetDefaultQualities(Quality.MP3_192, Quality.MP3_256, Quality.MP3_512);
|
||||
remoteAlbum.Artist.Profile.Value.Items = Qualities.QualityFixture.GetDefaultQualities(Quality.MP3_192, Quality.MP3_256, Quality.MP3_320);
|
||||
|
||||
Subject.IsSatisfiedBy(remoteAlbum, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
public void should_not_allow_if_quality_is_not_defined_in_profile(Quality qualityType)
|
||||
{
|
||||
remoteAlbum.ParsedAlbumInfo.Quality.Quality = qualityType;
|
||||
remoteAlbum.Artist.Profile.Value.Items = Qualities.QualityFixture.GetDefaultQualities(Quality.MP3_192, Quality.MP3_256, Quality.MP3_512);
|
||||
remoteAlbum.Artist.Profile.Value.Items = Qualities.QualityFixture.GetDefaultQualities(Quality.MP3_192, Quality.MP3_256, Quality.MP3_320);
|
||||
|
||||
Subject.IsSatisfiedBy(remoteAlbum, null).Accepted.Should().BeFalse();
|
||||
}
|
||||
|
|
|
@ -22,8 +22,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
new object[] { Quality.MP3_192, 1, Quality.MP3_192, 1, Quality.MP3_192, false },
|
||||
new object[] { Quality.MP3_320, 1, Quality.MP3_256, 2, Quality.MP3_320, false },
|
||||
new object[] { Quality.MP3_320, 1, Quality.MP3_256, 2, Quality.MP3_320, false },
|
||||
new object[] { Quality.MP3_320, 1, Quality.MP3_320, 1, Quality.MP3_320, false },
|
||||
new object[] { Quality.MP3_512, 1, Quality.MP3_512, 1, Quality.MP3_512, false }
|
||||
new object[] { Quality.MP3_320, 1, Quality.MP3_320, 1, Quality.MP3_320, false }
|
||||
};
|
||||
|
||||
public static object[] IsUpgradeTestCasesLanguages =
|
||||
|
|
|
@ -103,7 +103,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
[Test]
|
||||
public void should_return_true_when_quality_in_queue_is_lower()
|
||||
{
|
||||
_artist.Profile.Value.Cutoff = Quality.MP3_512.Id;
|
||||
_artist.Profile.Value.Cutoff = Quality.MP3_320.Id;
|
||||
_artist.LanguageProfile.Value.Cutoff = Language.Spanish;
|
||||
|
||||
var remoteAlbum = Builder<RemoteAlbum>.CreateNew()
|
||||
|
@ -193,7 +193,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
[Test]
|
||||
public void should_return_false_when_quality_in_queue_is_better()
|
||||
{
|
||||
_artist.Profile.Value.Cutoff = Quality.MP3_512.Id;
|
||||
_artist.Profile.Value.Cutoff = Quality.MP3_320.Id;
|
||||
|
||||
var remoteAlbum = Builder<RemoteAlbum>.CreateNew()
|
||||
.With(r => r.Artist = _artist)
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
var languages = Languages.LanguageFixture.GetDefaultLanguages(Language.English, Language.Spanish);
|
||||
|
||||
var fakeArtist = Builder<Artist>.CreateNew()
|
||||
.With(c => c.Profile = new Profile { Cutoff = Quality.MP3_512.Id, Items = Qualities.QualityFixture.GetDefaultQualities()})
|
||||
.With(c => c.Profile = new Profile { Cutoff = Quality.MP3_320.Id, Items = Qualities.QualityFixture.GetDefaultQualities()})
|
||||
.With(l => l.LanguageProfile = new LanguageProfile { Cutoff = Language.Spanish, Languages = languages })
|
||||
.Build();
|
||||
|
||||
|
@ -102,8 +102,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
[Test]
|
||||
public void should_not_be_upgradable_if_qualities_are_the_same()
|
||||
{
|
||||
_firstFile.Quality = new QualityModel(Quality.MP3_512);
|
||||
_parseResultSingle.ParsedAlbumInfo.Quality = new QualityModel(Quality.MP3_512);
|
||||
_firstFile.Quality = new QualityModel(Quality.MP3_320);
|
||||
_parseResultSingle.ParsedAlbumInfo.Quality = new QualityModel(Quality.MP3_320);
|
||||
Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse();
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
|
|||
{
|
||||
new ProfileQualityItem { Allowed = true, Quality = Quality.MP3_256 },
|
||||
new ProfileQualityItem { Allowed = true, Quality = Quality.MP3_320 },
|
||||
new ProfileQualityItem { Allowed = true, Quality = Quality.MP3_512 }
|
||||
new ProfileQualityItem { Allowed = true, Quality = Quality.FLAC }
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -130,7 +130,7 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
|
|||
[Test]
|
||||
public void should_not_delete_if_the_grabbed_quality_is_the_lower()
|
||||
{
|
||||
GivenHeldRelease(new QualityModel(Quality.MP3_512));
|
||||
GivenHeldRelease(new QualityModel(Quality.FLAC));
|
||||
|
||||
Subject.Handle(new AlbumGrabbedEvent(_remoteAlbum));
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ namespace NzbDrone.Core.Test.MediaFiles.TrackImport
|
|||
public void should_use_file_quality_if_folder_quality_is_null()
|
||||
{
|
||||
GivenSpecifications(_pass1, _pass2, _pass3);
|
||||
var expectedQuality = QualityParser.ParseQuality(_audioFiles.Single());
|
||||
var expectedQuality = QualityParser.ParseQuality(_audioFiles.Single(), null, 0);
|
||||
|
||||
var result = Subject.GetImportDecisions(_audioFiles, _artist);
|
||||
|
||||
|
@ -197,7 +197,7 @@ namespace NzbDrone.Core.Test.MediaFiles.TrackImport
|
|||
public void should_use_file_quality_if_file_quality_was_determined_by_name()
|
||||
{
|
||||
GivenSpecifications(_pass1, _pass2, _pass3);
|
||||
var expectedQuality = QualityParser.ParseQuality(_audioFiles.Single());
|
||||
var expectedQuality = QualityParser.ParseQuality(_audioFiles.Single(), null, 0);
|
||||
|
||||
var result = Subject.GetImportDecisions(_audioFiles, _artist, new ParsedTrackInfo{Quality = new QualityModel(Quality.MP3_256) });
|
||||
|
||||
|
|
|
@ -111,6 +111,7 @@
|
|||
<Compile Include="Datastore\DatabaseRelationshipFixture.cs" />
|
||||
<Compile Include="Datastore\MappingExtentionFixture.cs" />
|
||||
<Compile Include="Datastore\MarrDataLazyLoadingFixture.cs" />
|
||||
<Compile Include="Datastore\Migration\004_add_various_qualities_in_profileFixture.cs" />
|
||||
<Compile Include="Datastore\ObjectDatabaseFixture.cs" />
|
||||
<Compile Include="Datastore\PagingSpecExtensionsTests\PagingOffsetFixture.cs" />
|
||||
<Compile Include="Datastore\PagingSpecExtensionsTests\ToSortDirectionFixture.cs" />
|
||||
|
@ -534,7 +535,6 @@
|
|||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Datastore\Migration\" />
|
||||
<Folder Include="InstrumentationTests\" />
|
||||
<Folder Include="Providers\" />
|
||||
<Folder Include="ProviderTests\UpdateProviderTests\" />
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using FluentAssertions;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
@ -24,7 +24,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
[TestCase("The Real Housewives of Some Place - S01E01 - Why are we doing this?", 0)]
|
||||
public void should_parse_reality_from_title(string title, int reality)
|
||||
{
|
||||
QualityParser.ParseQuality(title).Revision.Real.Should().Be(reality);
|
||||
QualityParser.ParseQuality(title, null, 0).Revision.Real.Should().Be(reality);
|
||||
}
|
||||
|
||||
[TestCase("Chuck.S04E05.HDTV.XviD-LOL", 1)]
|
||||
|
@ -45,7 +45,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
[TestCase("[Vivid-Asenshi] Akame ga Kill - 02v2 [1F67AB55]", 2)]
|
||||
public void should_parse_version_from_title(string title, int version)
|
||||
{
|
||||
QualityParser.ParseQuality(title).Revision.Version.Should().Be(version);
|
||||
QualityParser.ParseQuality(title, null, 0).Revision.Version.Should().Be(version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using FluentAssertions;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Qualities;
|
||||
|
@ -16,80 +16,199 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
new object[] {Quality.MP3_VBR},
|
||||
new object[] {Quality.MP3_256},
|
||||
new object[] {Quality.MP3_320},
|
||||
new object[] {Quality.MP3_512},
|
||||
new object[] {Quality.MP3_VBR_V2},
|
||||
new object[] {Quality.WAV},
|
||||
new object[] {Quality.WMA},
|
||||
new object[] {Quality.AAC_192},
|
||||
new object[] {Quality.AAC_256},
|
||||
new object[] {Quality.AAC_320},
|
||||
new object[] {Quality.AAC_VBR},
|
||||
new object[] {Quality.ALAC},
|
||||
new object[] {Quality.FLAC},
|
||||
};
|
||||
|
||||
[TestCase("VA - The Best 101 Love Ballads (2017) MP3 [192 kbps]")]
|
||||
[TestCase("ATCQ - The Love Movement 1998 2CD 192kbps RIP")]
|
||||
[TestCase("A Tribe Called Quest - The Love Movement 1998 2CD [192kbps] RIP")]
|
||||
[TestCase("Maula - Jism 2 [2012] Mp3 - 192Kbps [Extended]- TK")]
|
||||
[TestCase("VA - Complete Clubland - The Ultimate Ride Of Your Lfe [2014][MP3][192 kbps]")]
|
||||
[TestCase("Complete Clubland - The Ultimate Ride Of Your Lfe [2014][MP3](192kbps)")]
|
||||
[TestCase("The Ultimate Ride Of Your Lfe [192 KBPS][2014][MP3]")]
|
||||
[TestCase("Gary Clark Jr - Live North America 2016 (2017) MP3 192kbps")]
|
||||
[TestCase("Some Song [192][2014][MP3]")]
|
||||
[TestCase("Other Song (192)[2014][MP3]")]
|
||||
public void should_parse_mp3_192_quality(string title)
|
||||
[TestCase("", "MPEG Version 1 Audio, Layer 3", 96)]
|
||||
public void should_parse_mp3_96_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, Quality.MP3_192);
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.MP3_096);
|
||||
}
|
||||
|
||||
[TestCase("Beyoncé Lemonade [320] 2016 Beyonce Lemonade [320] 2016")]
|
||||
[TestCase("Childish Gambino - Awaken, My Love Album 2016 mp3 320 Kbps")]
|
||||
[TestCase("Maluma – Felices Los 4 MP3 320 Kbps 2017 Download")]
|
||||
[TestCase("Ricardo Arjona - APNEA (Single 2014) (320 kbps)")]
|
||||
[TestCase("Kehlani - SweetSexySavage (Deluxe Edition) (2017) 320")]
|
||||
[TestCase("Anderson Paak - Malibu (320)(2016)")]
|
||||
public void should_parse_mp3_320_quality(string title)
|
||||
[TestCase("", "MPEG Version 1 Audio, Layer 3", 128)]
|
||||
public void should_parse_mp3_128_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, Quality.MP3_320);
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.MP3_128);
|
||||
}
|
||||
|
||||
|
||||
[TestCase("Caetano Veloso Discografia Completa MP3 @256")]
|
||||
[TestCase("Little Mix - Salute [Deluxe Edition] [2013] [M4A-256]-V3nom [GLT")]
|
||||
[TestCase("Ricky Martin - A Quien Quiera Escuchar (2015) 256 kbps [GloDLS]")]
|
||||
[TestCase("Jake Bugg - Jake Bugg (Album) [2012] {MP3 256 kbps}")]
|
||||
[TestCase("Milky Chance - Sadnecessary [256 Kbps] [M4A]")]
|
||||
[TestCase("Clean Bandit - New Eyes [2014] [Mp3-256]-V3nom [GLT]")]
|
||||
[TestCase("Armin van Buuren - A State Of Trance 810 (20.04.2017) 256 kbps")]
|
||||
[TestCase("PJ Harvey - Let England Shake [mp3-256-2011][trfkad]")]
|
||||
[TestCase("X-Men Soundtracks (2006-2014) AAC, 256 kbps")]
|
||||
[TestCase("Walk the Line Soundtrack (2005) [AAC, 256 kbps]")]
|
||||
public void should_parse_mp3_256_quality(string title)
|
||||
[TestCase("", "MPEG Version 1 Audio, Layer 3", 160)]
|
||||
public void should_parse_mp3_160_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, Quality.MP3_256);
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.MP3_160);
|
||||
}
|
||||
|
||||
[TestCase("Caetano Veloso Discografia Completa MP3 @512")]
|
||||
[TestCase("Walk the Line Soundtrack (2005) [AAC, 512 kbps]")]
|
||||
[TestCase("Emeli Sande Next To Me (512 Kbps)")]
|
||||
public void should_parse_mp3_512_quality(string title)
|
||||
[TestCase("VA - The Best 101 Love Ballads (2017) MP3 [192 kbps]", null, 0)]
|
||||
[TestCase("ATCQ - The Love Movement 1998 2CD 192kbps RIP", null, 0)]
|
||||
[TestCase("A Tribe Called Quest - The Love Movement 1998 2CD [192kbps] RIP", null, 0)]
|
||||
[TestCase("Maula - Jism 2 [2012] Mp3 - 192Kbps [Extended]- TK", null, 0)]
|
||||
[TestCase("VA - Complete Clubland - The Ultimate Ride Of Your Lfe [2014][MP3][192 kbps]", null, 0)]
|
||||
[TestCase("Complete Clubland - The Ultimate Ride Of Your Lfe [2014][MP3](192kbps)", null, 0)]
|
||||
[TestCase("The Ultimate Ride Of Your Lfe [192 KBPS][2014][MP3]", null, 0)]
|
||||
[TestCase("Gary Clark Jr - Live North America 2016 (2017) MP3 192kbps", null, 0)]
|
||||
[TestCase("Some Song [192][2014][MP3]", null, 0)]
|
||||
[TestCase("Other Song (192)[2014][MP3]", null, 0)]
|
||||
[TestCase("", "MPEG Version 1 Audio, Layer 3", 192)]
|
||||
public void should_parse_mp3_192_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, Quality.MP3_512);
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.MP3_192);
|
||||
}
|
||||
|
||||
[TestCase("Kendrick Lamar - DAMN (2017) FLAC")]
|
||||
[TestCase("Alicia Keys - Vault Playlist Vol. 1 (2017) [FLAC CD]")]
|
||||
[TestCase("Gorillaz - Humanz (Deluxe) - lossless FLAC Tracks - 2017 - CDrip")]
|
||||
[TestCase("David Bowie - Blackstar (2016) [FLAC]")]
|
||||
[TestCase("The Cure - Greatest Hits (2001) FLAC Soup")]
|
||||
[TestCase("Slowdive- Souvlaki (FLAC)")]
|
||||
[TestCase("John Coltrane - Kulu Se Mama (1965) [EAC-FLAC]")]
|
||||
[TestCase("The Rolling Stones - The Very Best Of '75-'94 (1995) {FLAC}")]
|
||||
[TestCase("Migos-No_Label_II-CD-FLAC-2014-FORSAKEN")]
|
||||
[TestCase("ADELE 25 CD FLAC 2015 PERFECT")]
|
||||
public void should_parse_flac_quality(string title)
|
||||
[TestCase("Caetano Veloso Discografia Completa MP3 @256", null, 0)]
|
||||
[TestCase("Ricky Martin - A Quien Quiera Escuchar (2015) 256 kbps [GloDLS]", null, 0)]
|
||||
[TestCase("Jake Bugg - Jake Bugg (Album) [2012] {MP3 256 kbps}", null, 0)]
|
||||
[TestCase("Clean Bandit - New Eyes [2014] [Mp3-256]-V3nom [GLT]", null, 0)]
|
||||
[TestCase("Armin van Buuren - A State Of Trance 810 (20.04.2017) 256 kbps", null, 0)]
|
||||
[TestCase("PJ Harvey - Let England Shake [mp3-256-2011][trfkad]", null, 0)]
|
||||
[TestCase("", "MPEG Version 1 Audio, Layer 3", 256)]
|
||||
public void should_parse_mp3_256_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, Quality.FLAC);
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.MP3_256);
|
||||
}
|
||||
|
||||
[TestCase("Beyoncé Lemonade [320] 2016 Beyonce Lemonade [320] 2016", null, 0)]
|
||||
[TestCase("Childish Gambino - Awaken, My Love Album 2016 mp3 320 Kbps", null, 0)]
|
||||
[TestCase("Maluma – Felices Los 4 MP3 320 Kbps 2017 Download", null, 0)]
|
||||
[TestCase("Ricardo Arjona - APNEA (Single 2014) (320 kbps)", null, 0)]
|
||||
[TestCase("Kehlani - SweetSexySavage (Deluxe Edition) (2017) 320", null, 0)]
|
||||
[TestCase("Anderson Paak - Malibu (320)(2016)", null, 0)]
|
||||
[TestCase("", "MPEG Version 1 Audio, Layer 3", 320)]
|
||||
public void should_parse_mp3_320_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.MP3_320);
|
||||
}
|
||||
|
||||
[TestCase("Sia - This Is Acting (Standard Edition) [2016-Web-MP3-V0(VBR)]", null, 0)]
|
||||
public void should_parse_mp3_vbr_v0_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.MP3_VBR);
|
||||
}
|
||||
|
||||
[TestCase("", "MPEG Version 1 Audio, Layer 3 VBR", 298)]
|
||||
public void should_parse_mp3_vbr_v2_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.MP3_VBR_V2);
|
||||
}
|
||||
|
||||
[TestCase("Kendrick Lamar - DAMN (2017) FLAC", null, 0)]
|
||||
[TestCase("Alicia Keys - Vault Playlist Vol. 1 (2017) [FLAC CD]", null, 0)]
|
||||
[TestCase("Gorillaz - Humanz (Deluxe) - lossless FLAC Tracks - 2017 - CDrip", null, 0)]
|
||||
[TestCase("David Bowie - Blackstar (2016) [FLAC]", null, 0)]
|
||||
[TestCase("The Cure - Greatest Hits (2001) FLAC Soup", null, 0)]
|
||||
[TestCase("Slowdive- Souvlaki (FLAC)", null, 0)]
|
||||
[TestCase("John Coltrane - Kulu Se Mama (1965) [EAC-FLAC]", null, 0)]
|
||||
[TestCase("The Rolling Stones - The Very Best Of '75-'94 (1995) {FLAC}", null, 0)]
|
||||
[TestCase("Migos-No_Label_II-CD-FLAC-2014-FORSAKEN", null, 0)]
|
||||
[TestCase("ADELE 25 CD FLAC 2015 PERFECT", null, 0)]
|
||||
[TestCase("", "Flac Audio", 1057)]
|
||||
public void should_parse_flac_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.FLAC);
|
||||
}
|
||||
|
||||
[TestCase("Beck.-.Guero.2005.[2016.Remastered].24bit.96kHz.LOSSLESS.FLAC", null, 0, 0)]
|
||||
[TestCase("[R.E.M - Lifes Rich Pageant(1986) [24bit192kHz 2016 Remaster]LOSSLESS FLAC]", null, 0, 0)]
|
||||
[TestCase("", "Flac Audio", 5057, 24)]
|
||||
public void should_parse_flac_24bit_quality(string title, string desc, int bitrate, int sampleSize)
|
||||
{
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.FLAC_24, sampleSize);
|
||||
}
|
||||
|
||||
[TestCase("", "Microsoft WMA2 Audio", 218)]
|
||||
public void should_parse_wma_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.WMA);
|
||||
}
|
||||
|
||||
[TestCase("", "PCM Audio", 1411)]
|
||||
public void should_parse_wav_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.WAV);
|
||||
}
|
||||
|
||||
|
||||
[TestCase("Chuck Berry Discography ALAC", null, 0)]
|
||||
[TestCase("A$AP Rocky - LONG LIVE A$AP Deluxe asap[ALAC]", null, 0)]
|
||||
[TestCase("", "MPEG-4 Audio (alac)", 0)]
|
||||
public void should_parse_alac_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.ALAC);
|
||||
}
|
||||
|
||||
[TestCase("Milky Chance - Sadnecessary [256 Kbps] [M4A]", null, 0)]
|
||||
[TestCase("Little Mix - Salute [Deluxe Edition] [2013] [M4A-256]-V3nom [GLT", null, 0)]
|
||||
[TestCase("X-Men Soundtracks (2006-2014) AAC, 256 kbps", null, 0)]
|
||||
[TestCase("The Weeknd - The Hills - Single[iTunes Plus AAC M4A]", null, 0)]
|
||||
[TestCase("Walk the Line Soundtrack (2005) [AAC, 256 kbps]", null, 0)]
|
||||
[TestCase("Firefly Soundtrack(2007 (2002-2003)) [AAC, 256 kbps VBR]", null, 0)]
|
||||
public void should_parse_aac_256_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.AAC_256);
|
||||
}
|
||||
|
||||
[TestCase("", "MPEG-4 Audio (mp4a)", 320)]
|
||||
public void should_parse_aac_320_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.AAC_320);
|
||||
}
|
||||
|
||||
|
||||
public void should_parse_aac_vbr_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.AAC_VBR);
|
||||
}
|
||||
|
||||
[TestCase("Kirlian Camera - The Ice Curtain - Album 1998 - Ogg-Vorbis Q10", null, 0)]
|
||||
[TestCase("", "Vorbis Version 0 Audio", 500)]
|
||||
public void should_parse_vorbis_q10_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.VORBIS_Q10);
|
||||
}
|
||||
|
||||
[TestCase("", "Vorbis Version 0 Audio", 320)]
|
||||
public void should_parse_vorbis_q9_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.VORBIS_Q9);
|
||||
}
|
||||
|
||||
[TestCase("Various Artists - No New York [1978/Ogg/q8]", null, 0)]
|
||||
[TestCase("", "Vorbis Version 0 Audio", 256)]
|
||||
public void should_parse_vorbis_q8_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.VORBIS_Q8);
|
||||
}
|
||||
|
||||
[TestCase("Masters_At_Work-Nuyorican_Soul-.Talkin_Loud.-1997-OGG.Q7", null, 0)]
|
||||
[TestCase("", "Vorbis Version 0 Audio", 224)]
|
||||
public void should_parse_vorbis_q7_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.VORBIS_Q7);
|
||||
}
|
||||
|
||||
[TestCase("", "Vorbis Version 0 Audio", 192)]
|
||||
public void should_parse_vorbis_q6_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.VORBIS_Q6);
|
||||
}
|
||||
|
||||
[TestCase("", "Vorbis Version 0 Audio", 160)]
|
||||
public void should_parse_vorbis_q5_quality(string title, string desc, int bitrate)
|
||||
{
|
||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.VORBIS_Q5);
|
||||
}
|
||||
|
||||
// Flack doesn't get match for 'FLAC' quality
|
||||
[TestCase("Roberta Flack 2006 - The Very Best of")]
|
||||
public void should_not_parse_flac_quality(string title)
|
||||
{
|
||||
ParseAndVerifyQuality(title, Quality.Unknown);
|
||||
ParseAndVerifyQuality(title, null, 0, Quality.Unknown);
|
||||
}
|
||||
|
||||
[TestCase("The Chainsmokers & Coldplay - Something Just Like This")]
|
||||
|
@ -99,35 +218,38 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
[TestCase("Maroon 5 Ft Kendrick Lamar -Dont Wanna Know MP3 2016")]
|
||||
public void quality_parse(string title)
|
||||
{
|
||||
ParseAndVerifyQuality(title, Quality.Unknown);
|
||||
ParseAndVerifyQuality(title, null, 0, Quality.Unknown);
|
||||
}
|
||||
|
||||
[Test, TestCaseSource(nameof(SelfQualityParserCases))]
|
||||
public void parsing_our_own_quality_enum_name(Quality quality)
|
||||
{
|
||||
var fileName = string.Format("Some album [{0}]", quality.Name);
|
||||
var result = QualityParser.ParseQuality(fileName);
|
||||
var result = QualityParser.ParseQuality(fileName, null, 0);
|
||||
result.Quality.Should().Be(quality);
|
||||
}
|
||||
|
||||
[TestCase("Little Mix - Salute [Deluxe Edition] [2013] [M4A-256]-V3nom [GLT")]
|
||||
public void should_parse_quality_from_name(string title)
|
||||
{
|
||||
QualityParser.ParseQuality(title).QualitySource.Should().Be(QualitySource.Name);
|
||||
QualityParser.ParseQuality(title, null, 0).QualitySource.Should().Be(QualitySource.Name);
|
||||
}
|
||||
|
||||
[TestCase("01. Kanye West - Ultralight Beam.mp3")]
|
||||
[TestCase("01. Kanye West - Ultralight Beam.ogg")]
|
||||
[TestCase("01. Kanye West - Ultralight Beam.m4a")]
|
||||
[TestCase("01. Kanye West - Ultralight Beam.wma")]
|
||||
[TestCase("01. Kanye West - Ultralight Beam.wav")]
|
||||
public void should_parse_quality_from_extension(string title)
|
||||
{
|
||||
QualityParser.ParseQuality(title).QualitySource.Should().Be(QualitySource.Extension);
|
||||
QualityParser.ParseQuality(title, null, 0).QualitySource.Should().Be(QualitySource.Extension);
|
||||
}
|
||||
|
||||
private void ParseAndVerifyQuality(string title, Quality quality)
|
||||
private void ParseAndVerifyQuality(string name, string desc, int bitrate, Quality quality, int sampleSize = 0)
|
||||
{
|
||||
var result = QualityParser.ParseQuality(title);
|
||||
var result = QualityParser.ParseQuality(name, desc, bitrate, sampleSize);
|
||||
result.Quality.Should().Be(quality);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ namespace NzbDrone.Core.Test.Qualities
|
|||
new object[] {2, Quality.MP3_VBR},
|
||||
new object[] {3, Quality.MP3_256},
|
||||
new object[] {4, Quality.MP3_320},
|
||||
new object[] {5, Quality.MP3_512},
|
||||
new object[] {6, Quality.FLAC},
|
||||
};
|
||||
|
||||
|
@ -29,7 +28,6 @@ namespace NzbDrone.Core.Test.Qualities
|
|||
new object[] {Quality.MP3_VBR, 2},
|
||||
new object[] {Quality.MP3_256, 3},
|
||||
new object[] {Quality.MP3_320, 4},
|
||||
new object[] {Quality.MP3_512, 5},
|
||||
new object[] {Quality.FLAC, 6},
|
||||
};
|
||||
|
||||
|
@ -56,7 +54,6 @@ namespace NzbDrone.Core.Test.Qualities
|
|||
Quality.MP3_VBR,
|
||||
Quality.MP3_256,
|
||||
Quality.MP3_320,
|
||||
Quality.MP3_512,
|
||||
Quality.FLAC,
|
||||
};
|
||||
|
||||
|
|
|
@ -41,12 +41,12 @@ namespace NzbDrone.Core.Test.Qualities
|
|||
new ProfileQualityItem
|
||||
{
|
||||
Allowed = true,
|
||||
Quality = Quality.MP3_320
|
||||
Quality = Quality.MP3_256
|
||||
},
|
||||
new ProfileQualityItem
|
||||
{
|
||||
Allowed = true,
|
||||
Quality = Quality.MP3_512
|
||||
Quality = Quality.MP3_320
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -119,8 +119,8 @@ namespace NzbDrone.Core.Test.Qualities
|
|||
{
|
||||
GivenGroupedProfile();
|
||||
|
||||
var first = new QualityModel(Quality.MP3_320);
|
||||
var second = new QualityModel(Quality.MP3_512);
|
||||
var first = new QualityModel(Quality.MP3_256);
|
||||
var second = new QualityModel(Quality.MP3_320);
|
||||
|
||||
var compare = Subject.Compare(first, second);
|
||||
|
||||
|
@ -132,8 +132,8 @@ namespace NzbDrone.Core.Test.Qualities
|
|||
{
|
||||
GivenGroupedProfile();
|
||||
|
||||
var first = new QualityModel(Quality.MP3_320);
|
||||
var second = new QualityModel(Quality.MP3_512);
|
||||
var first = new QualityModel(Quality.MP3_256);
|
||||
var second = new QualityModel(Quality.MP3_320);
|
||||
|
||||
var compare = Subject.Compare(first, second, true);
|
||||
|
||||
|
|
|
@ -0,0 +1,335 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using FluentMigrator;
|
||||
using Newtonsoft.Json;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(4)]
|
||||
public class add_various_qualites_in_profile : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Execute.Sql("UPDATE QualityDefinitions SET Title = 'MP3-160' WHERE Quality = 5"); // Change MP3-512 to MP3-160
|
||||
Execute.WithConnection(ConvertProfile);
|
||||
}
|
||||
|
||||
private void ConvertProfile(IDbConnection conn, IDbTransaction tran)
|
||||
{
|
||||
var updater = new ProfileUpdater3(conn, tran);
|
||||
|
||||
updater.AddQuality(Qualities4.WAV);
|
||||
|
||||
updater.MoveQuality(Qualities4.MP3_160, Qualities4.Unknown);
|
||||
|
||||
updater.CreateNewGroup(Qualities4.Unknown, 1000, "Trash Quality Lossy", new[] { Qualities4.MP3_080,
|
||||
Qualities4.MP3_064,
|
||||
Qualities4.MP3_056,
|
||||
Qualities4.MP3_048,
|
||||
Qualities4.MP3_040,
|
||||
Qualities4.MP3_032,
|
||||
Qualities4.MP3_024,
|
||||
Qualities4.MP3_016,
|
||||
Qualities4.MP3_008 });
|
||||
|
||||
updater.CreateGroupAt(Qualities4.MP3_160, 1001, "Poor Quality Lossy", new[] { Qualities4.MP3_160,
|
||||
Qualities4.VORBIS_Q5,
|
||||
Qualities4.MP3_128,
|
||||
Qualities4.MP3_096,
|
||||
Qualities4.MP3_112 }); // Group Vorbis-Q5 with MP3-160
|
||||
|
||||
updater.CreateGroupAt(Qualities4.MP3_192, 1002, "Low Quality Lossy", new[] { Qualities4.MP3_192,
|
||||
Qualities4.AAC_192,
|
||||
Qualities4.VORBIS_Q6,
|
||||
Qualities4.WMA,
|
||||
Qualities4.MP3_224 }); // Group Vorbis-Q6, AAC 192, WMA with MP3-190
|
||||
|
||||
updater.CreateGroupAt(Qualities4.MP3_256, 1003, "Mid Quality Lossy", new[] { Qualities4.MP3_256,
|
||||
Qualities4.MP3_VBR_V2,
|
||||
Qualities4.VORBIS_Q8,
|
||||
Qualities4.VORBIS_Q7,
|
||||
Qualities4.AAC_256 }); // Group Mp3-VBR-V2, Vorbis-Q7, Q8, AAC-256 with MP3-256
|
||||
|
||||
updater.CreateGroupAt(Qualities4.MP3_320, 1004, "High Quality Lossy", new[] { Qualities4.MP3_VBR,
|
||||
Qualities4.MP3_320,
|
||||
Qualities4.AAC_320,
|
||||
Qualities4.AAC_VBR,
|
||||
Qualities4.VORBIS_Q10,
|
||||
Qualities4.VORBIS_Q9 }); // Group MP3-VBR-V0, AAC-VBR, Vorbis-Q10, Q9, AAC-320 with MP3-320
|
||||
|
||||
updater.CreateGroupAt(Qualities4.FLAC, 1005, "Lossless", new[] { Qualities4.FLAC,
|
||||
Qualities4.ALAC,
|
||||
Qualities4.FLAC_24 }); // Group ALAC with FLAC
|
||||
|
||||
|
||||
updater.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
public class Profile4
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int Cutoff { get; set; }
|
||||
public List<ProfileItem4> Items { get; set; }
|
||||
}
|
||||
|
||||
public class ProfileItem4
|
||||
{
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
public int? Quality { get; set; }
|
||||
public List<ProfileItem4> Items { get; set; }
|
||||
public bool Allowed { get; set; }
|
||||
|
||||
public ProfileItem4()
|
||||
{
|
||||
Items = new List<ProfileItem4>();
|
||||
}
|
||||
}
|
||||
|
||||
public enum Qualities4
|
||||
{
|
||||
Unknown,
|
||||
MP3_192,
|
||||
MP3_VBR,
|
||||
MP3_256,
|
||||
MP3_320,
|
||||
MP3_160,
|
||||
FLAC,
|
||||
ALAC,
|
||||
MP3_VBR_V2,
|
||||
AAC_192,
|
||||
AAC_256,
|
||||
AAC_320,
|
||||
AAC_VBR,
|
||||
WAV,
|
||||
VORBIS_Q10,
|
||||
VORBIS_Q9,
|
||||
VORBIS_Q8,
|
||||
VORBIS_Q7,
|
||||
VORBIS_Q6,
|
||||
VORBIS_Q5,
|
||||
WMA,
|
||||
FLAC_24,
|
||||
MP3_128,
|
||||
MP3_096,
|
||||
MP3_080,
|
||||
MP3_064,
|
||||
MP3_056,
|
||||
MP3_048,
|
||||
MP3_040,
|
||||
MP3_032,
|
||||
MP3_024,
|
||||
MP3_016,
|
||||
MP3_008,
|
||||
MP3_112,
|
||||
MP3_224
|
||||
}
|
||||
|
||||
public class ProfileUpdater3
|
||||
{
|
||||
private readonly IDbConnection _connection;
|
||||
private readonly IDbTransaction _transaction;
|
||||
|
||||
private List<Profile4> _profiles;
|
||||
private HashSet<Profile4> _changedProfiles = new HashSet<Profile4>();
|
||||
|
||||
public ProfileUpdater3(IDbConnection conn, IDbTransaction tran)
|
||||
{
|
||||
_connection = conn;
|
||||
_transaction = tran;
|
||||
|
||||
_profiles = GetProfiles();
|
||||
}
|
||||
|
||||
public void Commit()
|
||||
{
|
||||
foreach (var profile in _changedProfiles)
|
||||
{
|
||||
using (var updateProfileCmd = _connection.CreateCommand())
|
||||
{
|
||||
updateProfileCmd.Transaction = _transaction;
|
||||
updateProfileCmd.CommandText =
|
||||
"UPDATE Profiles SET Name = ?, Cutoff = ?, Items = ? WHERE Id = ?";
|
||||
updateProfileCmd.AddParameter(profile.Name);
|
||||
updateProfileCmd.AddParameter(profile.Cutoff);
|
||||
updateProfileCmd.AddParameter(profile.Items.ToJson());
|
||||
updateProfileCmd.AddParameter(profile.Id);
|
||||
|
||||
updateProfileCmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
_changedProfiles.Clear();
|
||||
}
|
||||
|
||||
public void AddQuality(Qualities4 quality)
|
||||
{
|
||||
foreach (var profile in _profiles)
|
||||
{
|
||||
profile.Items.Add(new ProfileItem4
|
||||
{
|
||||
Quality = (int)quality,
|
||||
Allowed = false
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void CreateGroupAt(Qualities4 find, int groupId, string name, Qualities4[] qualities)
|
||||
{
|
||||
foreach (var profile in _profiles)
|
||||
{
|
||||
var findIndex = profile.Items.FindIndex(v => v.Quality == (int)find);
|
||||
|
||||
if (findIndex > -1)
|
||||
{
|
||||
var findQuality = profile.Items[findIndex];
|
||||
|
||||
profile.Items.Insert(findIndex, new ProfileItem4
|
||||
{
|
||||
Id = groupId,
|
||||
Name = name,
|
||||
Quality = null,
|
||||
Items = qualities.Select(q => new ProfileItem4
|
||||
{
|
||||
Quality = (int)q,
|
||||
Allowed = findQuality.Allowed
|
||||
}).ToList(),
|
||||
Allowed = findQuality.Allowed
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the ID isn't found for some reason (mangled migration 71?)
|
||||
|
||||
profile.Items.Add(new ProfileItem4
|
||||
{
|
||||
Id = groupId,
|
||||
Name = name,
|
||||
Quality = null,
|
||||
Items = qualities.Select(q => new ProfileItem4
|
||||
{
|
||||
Quality = (int)q,
|
||||
Allowed = false
|
||||
}).ToList(),
|
||||
Allowed = false
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var quality in qualities)
|
||||
{
|
||||
var index = profile.Items.FindIndex(v => v.Quality == (int)quality);
|
||||
|
||||
if (index > -1)
|
||||
{
|
||||
profile.Items.RemoveAt(index);
|
||||
}
|
||||
|
||||
if (profile.Cutoff == (int)quality)
|
||||
{
|
||||
profile.Cutoff = groupId;
|
||||
}
|
||||
}
|
||||
|
||||
_changedProfiles.Add(profile);
|
||||
}
|
||||
}
|
||||
|
||||
public void CreateNewGroup(Qualities4 createafter, int groupId, string name, Qualities4[] qualities)
|
||||
{
|
||||
foreach (var profile in _profiles)
|
||||
{
|
||||
var findIndex = profile.Items.FindIndex(v => v.Quality == (int)createafter) + 1;
|
||||
|
||||
if (findIndex > -1)
|
||||
{
|
||||
|
||||
profile.Items.Insert(findIndex, new ProfileItem4
|
||||
{
|
||||
Id = groupId,
|
||||
Name = name,
|
||||
Quality = null,
|
||||
Items = qualities.Select(q => new ProfileItem4
|
||||
{
|
||||
Quality = (int)q,
|
||||
Allowed = false
|
||||
}).ToList(),
|
||||
Allowed = false
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
profile.Items.Add(new ProfileItem4
|
||||
{
|
||||
Id = groupId,
|
||||
Name = name,
|
||||
Quality = null,
|
||||
Items = qualities.Select(q => new ProfileItem4
|
||||
{
|
||||
Quality = (int)q,
|
||||
Allowed = false
|
||||
}).ToList(),
|
||||
Allowed = false
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveQuality(Qualities4 quality, Qualities4 moveafter)
|
||||
{
|
||||
foreach (var profile in _profiles)
|
||||
{
|
||||
var findIndex = profile.Items.FindIndex(v => v.Quality == (int)quality);
|
||||
|
||||
if (findIndex > -1)
|
||||
{
|
||||
var allowed = profile.Items[findIndex].Allowed;
|
||||
profile.Items.RemoveAt(findIndex);
|
||||
var findMoveIndex = profile.Items.FindIndex(v => v.Quality == (int)moveafter) + 1;
|
||||
profile.Items.Insert(findMoveIndex, new ProfileItem4
|
||||
{
|
||||
Quality = (int)quality,
|
||||
Allowed = allowed
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private List<Profile4> GetProfiles()
|
||||
{
|
||||
var profiles = new List<Profile4>();
|
||||
|
||||
using (var getProfilesCmd = _connection.CreateCommand())
|
||||
{
|
||||
getProfilesCmd.Transaction = _transaction;
|
||||
getProfilesCmd.CommandText = @"SELECT Id, Name, Cutoff, Items FROM Profiles";
|
||||
|
||||
using (var profileReader = getProfilesCmd.ExecuteReader())
|
||||
{
|
||||
while (profileReader.Read())
|
||||
{
|
||||
profiles.Add(new Profile4
|
||||
{
|
||||
Id = profileReader.GetInt32(0),
|
||||
Name = profileReader.GetString(1),
|
||||
Cutoff = profileReader.GetInt32(2),
|
||||
Items = Json.Deserialize<List<ProfileItem4>>(profileReader.GetString(3))
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return profiles;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -99,6 +99,7 @@ namespace NzbDrone.Core.Datastore
|
|||
|
||||
Mapper.Entity<QualityDefinition>().RegisterModel("QualityDefinitions")
|
||||
.Ignore(d => d.GroupName)
|
||||
.Ignore(d => d.GroupWeight)
|
||||
.Ignore(d => d.Weight);
|
||||
|
||||
Mapper.Entity<Profile>().RegisterModel("Profiles");
|
||||
|
|
|
@ -110,15 +110,6 @@ namespace NzbDrone.Core.MediaFiles
|
|||
_logger.Warn("Unable to parse file on import: [{0}]", audioFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
var size = _diskProvider.GetFileSize(audioFile);
|
||||
var quality = QualityParser.ParseQuality(audioFile);
|
||||
|
||||
//if (!_detectSample.IsSample(artist, quality, audioFile, size, albumParseResult.IsPossibleSpecialEpisode))
|
||||
//{
|
||||
// _logger.Warn("Non-sample file detected: [{0}]", audioFile);
|
||||
// return false;
|
||||
//}
|
||||
}
|
||||
|
||||
if (rarFiles.Any(f => _diskProvider.GetFileSize(f) > 10.Megabytes()))
|
||||
|
|
|
@ -16,7 +16,9 @@ namespace NzbDrone.Core.MediaFiles
|
|||
{ ".mp3", Quality.Unknown },
|
||||
{ ".m4a", Quality.Unknown },
|
||||
{ ".ogg", Quality.Unknown },
|
||||
{ ".flac", Quality.FLAC },
|
||||
{ ".wma", Quality.WMA },
|
||||
{ ".wav", Quality.WAV },
|
||||
{ ".flac", Quality.FLAC }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NLog;
|
||||
using NLog.Fluent;
|
||||
using NzbDrone.Common.Extensions;
|
||||
|
@ -14,6 +15,13 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
|
|||
{
|
||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(MediaInfoFormatter));
|
||||
|
||||
public static string FormatAudioBitrate(MediaInfoModel mediaInfo)
|
||||
{
|
||||
int audioBitrate = mediaInfo.AudioBitrate / 1000;
|
||||
|
||||
return audioBitrate + " kbps";
|
||||
}
|
||||
|
||||
public static decimal FormatAudioChannels(MediaInfoModel mediaInfo)
|
||||
{
|
||||
var audioChannelPositions = mediaInfo.AudioChannelPositions;
|
||||
|
|
|
@ -171,14 +171,6 @@ namespace NzbDrone.Core.MediaFiles.TrackImport
|
|||
|
||||
return musicFiles.Count(file =>
|
||||
{
|
||||
var size = _diskProvider.GetFileSize(file);
|
||||
var fileQuality = QualityParser.ParseQuality(file);
|
||||
//var sample = _detectSample.IsSample(artist, GetQuality(folderInfo, fileQuality, artist), file, size, folderInfo.IsPossibleSpecialEpisode);
|
||||
|
||||
//if (sample)
|
||||
//{
|
||||
// return false;
|
||||
//}
|
||||
|
||||
if (SceneChecker.IsSceneTitle(Path.GetFileName(file)))
|
||||
{
|
||||
|
|
|
@ -146,7 +146,7 @@ namespace NzbDrone.Core.MediaFiles.TrackImport.Manual
|
|||
{
|
||||
var localTrack = new LocalTrack();
|
||||
localTrack.Path = file;
|
||||
localTrack.Quality = QualityParser.ParseQuality(file);
|
||||
localTrack.Quality = QualityParser.ParseQuality(file, null, 0);
|
||||
localTrack.Language = LanguageParser.ParseLanguage(file);
|
||||
localTrack.Size = _diskProvider.GetFileSize(file);
|
||||
|
||||
|
|
|
@ -172,6 +172,7 @@
|
|||
<Compile Include="Datastore\LogDatabase.cs" />
|
||||
<Compile Include="Datastore\Migration\001_initial_setup.cs" />
|
||||
<Compile Include="Datastore\Migration\002_add_reason_to_pending_releases.cs" />
|
||||
<Compile Include="Datastore\Migration\004_add_various_qualities_in_profile.cs" />
|
||||
<Compile Include="Datastore\Migration\003_add_medium_support.cs" />
|
||||
<Compile Include="Datastore\Migration\Framework\MigrationContext.cs" />
|
||||
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
|
||||
|
|
|
@ -9,6 +9,7 @@ using NzbDrone.Common.Instrumentation;
|
|||
using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Languages;
|
||||
using TagLib;
|
||||
|
||||
namespace NzbDrone.Core.Parser
|
||||
{
|
||||
|
@ -264,7 +265,7 @@ namespace NzbDrone.Core.Parser
|
|||
//result.Language = LanguageParser.ParseLanguage(title);
|
||||
//Logger.Debug("Language parsed: {0}", result.Language);
|
||||
|
||||
result.Quality = QualityParser.ParseQuality(title);
|
||||
result.Quality = QualityParser.ParseQuality(title, null, 0);
|
||||
Logger.Debug("Quality parsed: {0}", result.Quality);
|
||||
|
||||
// Majora: We don't currently need Release Group for Music.
|
||||
|
@ -369,7 +370,7 @@ namespace NzbDrone.Core.Parser
|
|||
result.Language = LanguageParser.ParseLanguage(releaseTitle);
|
||||
Logger.Debug("Language parsed: {0}", result.Language);
|
||||
|
||||
result.Quality = QualityParser.ParseQuality(title);
|
||||
result.Quality = QualityParser.ParseQuality(title, null, 0);
|
||||
Logger.Debug("Quality parsed: {0}", result.Quality);
|
||||
|
||||
result.ReleaseGroup = ParseReleaseGroup(releaseTitle);
|
||||
|
@ -492,6 +493,8 @@ namespace NzbDrone.Core.Parser
|
|||
{
|
||||
var fileInfo = new FileInfo(path);
|
||||
var file = TagLib.File.Create(path);
|
||||
Logger.Debug("Starting Tag Parse for {0}", file.Name);
|
||||
|
||||
var trackNumber = file.Tag.Track;
|
||||
var trackTitle = file.Tag.Title;
|
||||
var discNumber = (file.Tag.Disc > 0) ? Convert.ToInt32(file.Tag.Disc) : 1 ;
|
||||
|
@ -532,12 +535,10 @@ namespace NzbDrone.Core.Parser
|
|||
|
||||
if (acodec != null && (acodec.MediaTypes & TagLib.MediaTypes.Audio) != TagLib.MediaTypes.None)
|
||||
{
|
||||
Logger.Debug("Audio Properties : " + acodec.Description);
|
||||
Logger.Debug("Bitrate: " + acodec.AudioBitrate);
|
||||
Logger.Debug("SampleRate: " + acodec.AudioSampleRate);
|
||||
Logger.Debug("Channels: " + acodec.AudioChannels + "\n");
|
||||
Logger.Debug("Audio Properties : " + acodec.Description + ", Bitrate: " + acodec.AudioBitrate + ", Sample Size: " +
|
||||
file.Properties.BitsPerSample + ", SampleRate: " + acodec.AudioSampleRate + ", Channels: " + acodec.AudioChannels);
|
||||
|
||||
result.Quality = QualityParser.ParseQuality(acodec.Description, acodec.AudioBitrate, acodec.AudioSampleRate);
|
||||
result.Quality = QualityParser.ParseQuality(file.Name, acodec.Description, acodec.AudioBitrate, file.Properties.BitsPerSample);
|
||||
Logger.Debug("Quality parsed: {0}", result.Quality);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -187,7 +187,7 @@ namespace NzbDrone.Core.Parser
|
|||
if (folderInfo != null)
|
||||
{
|
||||
parsedTrackInfo = folderInfo.JsonClone();
|
||||
parsedTrackInfo.Quality = QualityParser.ParseQuality(Path.GetFileName(filename));
|
||||
parsedTrackInfo.Quality = QualityParser.ParseQuality(Path.GetFileName(filename), null, 0);
|
||||
}
|
||||
|
||||
else
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.Text.RegularExpressions;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
|
@ -39,76 +40,98 @@ namespace NzbDrone.Core.Parser
|
|||
private static readonly Regex RealRegex = new Regex(@"\b(?<real>REAL)\b",
|
||||
RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex BitRateRegex = new Regex(@"\b(?:(?<B192>192[ ]?kbps|192|[\[\(].*192.*[\]\)])|
|
||||
(?<B256>256[ ]?kbps|256|[\[\(].*256.*[\]\)])|
|
||||
(?<B320>320[ ]?kbps|320|[\[\(].*320.*[\]\)])|
|
||||
(?<B512>512[ ]?kbps|512|[\[\(].*512.*[\]\)])|
|
||||
(?<VBR>VBR[ ]?kbps|VBR|[\[\(].*VBR.*[\]\)])|
|
||||
(?<FLAC>FLAC))\b",
|
||||
private static readonly Regex BitRateRegex = new Regex(@"\b(?:(?<B096>96[ ]?kbps|96|[\[\(].*96.*[\]\)])|
|
||||
(?<B128>128[ ]?kbps|128|[\[\(].*128.*[\]\)])|
|
||||
(?<B160>160[ ]?kbps|160|[\[\(].*160.*[\]\)]|q5)|
|
||||
(?<B192>192[ ]?kbps|192|[\[\(].*192.*[\]\)]|q6)|
|
||||
(?<B224>224[ ]?kbps|224|[\[\(].*224.*[\]\)]|q7)|
|
||||
(?<B256>256[ ]?kbps|256|itunes\splus|[\[\(].*256.*[\]\)]|q8)|
|
||||
(?<B320>320[ ]?kbps|320|[\[\(].*320.*[\]\)]|q9)|
|
||||
(?<B500>500[ ]?kbps|500|[\[\(].*500.*[\]\)]|q10)|
|
||||
(?<VBRV0>V0[ ]?kbps|V0|[\[\(].*V0.*[\]\)])|
|
||||
(?<VBRV2>V2[ ]?kbps|V2|[\[\(].*V2.*[\]\)]))\b",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
||||
|
||||
private static readonly Regex CodecRegex = new Regex(@"\b(?:
|
||||
(?<MP3>MPEG Version \d+ Audio, Layer 3)|
|
||||
(?<FLAC>flac)|
|
||||
(?<VBR>VBR|MPEG Version \d+ Audio, Layer 3 VBR$)
|
||||
)\b",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
||||
private static readonly Regex SampleSizeRegex = new Regex(@"\b(?:(?<S24>24[ ]bit|24bit|[\[\(].*24bit.*[\]\)]))");
|
||||
|
||||
private static readonly Regex CodecRegex = new Regex(@"\b(?:(?<MP3VBR>MP3\S*VBR|MPEG Version 1 Audio, Layer 3 vbr)|(?<MP3CBR>MP3|MPEG Version \d+ Audio, Layer 3)|(?<FLAC>flac)|(?<ALAC>alac)|(?<WMA>WMA\d?)|(?<WAV>WAV|PCM)|(?<AAC>M4A|AAC|mp4a)|(?<OGG>OGG|Vorbis))\b",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
public static QualityModel ParseQuality(string desc, int bitrate, int sampleRate)
|
||||
{
|
||||
var result = new QualityModel { Quality = Quality.Unknown };
|
||||
|
||||
switch (bitrate)
|
||||
{
|
||||
case 192:
|
||||
result.Quality = Quality.MP3_192;
|
||||
break;
|
||||
case 256:
|
||||
result.Quality = Quality.MP3_256;
|
||||
break;
|
||||
case 320:
|
||||
result.Quality = Quality.MP3_320;
|
||||
break;
|
||||
default:
|
||||
var match = CodecRegex.Match(desc); //TODO: BUG: Figure out why this always fails
|
||||
if (!match.Success) result.Quality = Quality.Unknown;
|
||||
if (match.Groups["VBR"].Success) result.Quality = Quality.MP3_VBR;
|
||||
if (match.Groups["FLAC"].Success) result.Quality = Quality.FLAC;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static QualityModel ParseQuality(string name)
|
||||
public static QualityModel ParseQuality(string name, string desc, int fileBitrate, int fileSampleSize = 0)
|
||||
{
|
||||
Logger.Debug("Trying to parse quality for {0}", name);
|
||||
|
||||
var normalizedName = name.Replace('_', ' ').Trim().ToLower();
|
||||
var result = ParseQualityModifiers(name, normalizedName);
|
||||
var bitrate = ParseBitRate(normalizedName);
|
||||
|
||||
switch(bitrate)
|
||||
if (desc.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
case BitRate.B192:
|
||||
result.Quality = Quality.MP3_192;
|
||||
var descCodec = ParseCodec(desc);
|
||||
|
||||
result.Quality = FindQuality(descCodec, fileBitrate, fileSampleSize);
|
||||
|
||||
if (result.Quality != Quality.Unknown) { return result; }
|
||||
}
|
||||
|
||||
var codec = ParseCodec(normalizedName);
|
||||
var bitrate = ParseBitRate(normalizedName);
|
||||
var sampleSize = ParseSampleSize(normalizedName);
|
||||
|
||||
switch(codec)
|
||||
{
|
||||
case Codec.MP3VBR:
|
||||
if (bitrate == BitRate.VBRV0) { result.Quality = Quality.MP3_VBR; }
|
||||
else if (bitrate == BitRate.VBRV2) { result.Quality = Quality.MP3_VBR_V2; }
|
||||
else { result.Quality = Quality.Unknown; }
|
||||
break;
|
||||
case BitRate.B256:
|
||||
result.Quality = Quality.MP3_256;
|
||||
case Codec.MP3CBR:
|
||||
if (bitrate == BitRate.B096) { result.Quality = Quality.MP3_096; }
|
||||
else if (bitrate == BitRate.B128) { result.Quality = Quality.MP3_128; }
|
||||
else if (bitrate == BitRate.B160) { result.Quality = Quality.MP3_160; }
|
||||
else if (bitrate == BitRate.B192) { result.Quality = Quality.MP3_192; }
|
||||
else if (bitrate == BitRate.B256) { result.Quality = Quality.MP3_256; }
|
||||
else if (bitrate == BitRate.B320) { result.Quality = Quality.MP3_320; }
|
||||
else { result.Quality = Quality.Unknown; }
|
||||
break;
|
||||
case BitRate.B320:
|
||||
result.Quality = Quality.MP3_320;
|
||||
case Codec.FLAC:
|
||||
if (sampleSize == SampleSize.S24) {result.Quality = Quality.FLAC_24;}
|
||||
else {result.Quality = Quality.FLAC;}
|
||||
break;
|
||||
case BitRate.B512:
|
||||
result.Quality = Quality.MP3_512;
|
||||
case Codec.ALAC:
|
||||
result.Quality = Quality.ALAC;
|
||||
break;
|
||||
case BitRate.FLAC:
|
||||
result.Quality = Quality.FLAC;
|
||||
case Codec.WMA:
|
||||
result.Quality = Quality.WMA;
|
||||
break;
|
||||
case BitRate.VBR:
|
||||
result.Quality = Quality.MP3_VBR;
|
||||
case Codec.WAV:
|
||||
result.Quality = Quality.WAV;
|
||||
break;
|
||||
case Codec.AAC:
|
||||
if (bitrate == BitRate.B192) { result.Quality = Quality.AAC_192; }
|
||||
else if (bitrate == BitRate.B256) { result.Quality = Quality.AAC_256; }
|
||||
else if (bitrate == BitRate.B320) { result.Quality = Quality.AAC_320; }
|
||||
else { result.Quality = Quality.AAC_VBR; }
|
||||
break;
|
||||
case Codec.AACVBR:
|
||||
result.Quality = Quality.AAC_VBR;
|
||||
break;
|
||||
case Codec.OGG:
|
||||
if (bitrate == BitRate.B160) { result.Quality = Quality.VORBIS_Q5; }
|
||||
else if (bitrate == BitRate.B192) { result.Quality = Quality.VORBIS_Q6; }
|
||||
else if (bitrate == BitRate.B224) { result.Quality = Quality.VORBIS_Q7; }
|
||||
else if (bitrate == BitRate.B256) { result.Quality = Quality.VORBIS_Q8; }
|
||||
else if (bitrate == BitRate.B320) { result.Quality = Quality.VORBIS_Q9; }
|
||||
else if (bitrate == BitRate.B500) { result.Quality = Quality.VORBIS_Q10; }
|
||||
break;
|
||||
case Codec.Unknown:
|
||||
if (bitrate == BitRate.B192) { result.Quality = Quality.MP3_192; }
|
||||
else if (bitrate == BitRate.B256) { result.Quality = Quality.MP3_256; }
|
||||
else if (bitrate == BitRate.B320) { result.Quality = Quality.MP3_320; }
|
||||
else if (bitrate == BitRate.VBR) { result.Quality = Quality.MP3_VBR_V2; }
|
||||
else { result.Quality = Quality.Unknown; }
|
||||
break;
|
||||
default:
|
||||
result.Quality = Quality.Unknown;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -130,15 +153,21 @@ namespace NzbDrone.Core.Parser
|
|||
return result;
|
||||
}
|
||||
|
||||
private static BitRate ParseCodec(string name)
|
||||
private static Codec ParseCodec(string name)
|
||||
{
|
||||
var match = BitRateRegex.Match(name);
|
||||
var match = CodecRegex.Match(name);
|
||||
|
||||
if (!match.Success) return BitRate.Unknown;
|
||||
if (match.Groups["FLAC"].Success) return BitRate.FLAC;
|
||||
if (match.Groups["VBR"].Success) return BitRate.VBR;
|
||||
if (!match.Success) { return Codec.Unknown; }
|
||||
if (match.Groups["FLAC"].Success) { return Codec.FLAC; }
|
||||
if (match.Groups["ALAC"].Success) { return Codec.ALAC; }
|
||||
if (match.Groups["WMA"].Success) { return Codec.WMA; }
|
||||
if (match.Groups["WAV"].Success) { return Codec.WAV; }
|
||||
if (match.Groups["AAC"].Success) { return Codec.AAC; }
|
||||
if (match.Groups["OGG"].Success) { return Codec.OGG; }
|
||||
if (match.Groups["MP3VBR"].Success) { return Codec.MP3VBR; }
|
||||
if (match.Groups["MP3CBR"].Success) { return Codec.MP3CBR; }
|
||||
|
||||
return BitRate.Unknown;
|
||||
return Codec.Unknown;
|
||||
}
|
||||
|
||||
private static BitRate ParseBitRate(string name)
|
||||
|
@ -147,16 +176,83 @@ namespace NzbDrone.Core.Parser
|
|||
var match = BitRateRegex.Match(name);
|
||||
|
||||
if (!match.Success) return BitRate.Unknown;
|
||||
if (match.Groups["B192"].Success) return BitRate.B192;
|
||||
if (match.Groups["B256"].Success) return BitRate.B256;
|
||||
if (match.Groups["B320"].Success) return BitRate.B320;
|
||||
if (match.Groups["B512"].Success) return BitRate.B512;
|
||||
if (match.Groups["FLAC"].Success) return BitRate.FLAC;
|
||||
if (match.Groups["VBR"].Success) return BitRate.VBR;
|
||||
if (match.Groups["B096"].Success) { return BitRate.B096; }
|
||||
if (match.Groups["B128"].Success) { return BitRate.B128; }
|
||||
if (match.Groups["B160"].Success) { return BitRate.B160; }
|
||||
if (match.Groups["B192"].Success) { return BitRate.B192; }
|
||||
if (match.Groups["B224"].Success) { return BitRate.B224; }
|
||||
if (match.Groups["B256"].Success) { return BitRate.B256; }
|
||||
if (match.Groups["B320"].Success) { return BitRate.B320; }
|
||||
if (match.Groups["B500"].Success) { return BitRate.B500; }
|
||||
if (match.Groups["VBR"].Success) { return BitRate.VBR; }
|
||||
if (match.Groups["VBRV0"].Success) { return BitRate.VBRV0; }
|
||||
if (match.Groups["VBRV2"].Success) { return BitRate.VBRV2; }
|
||||
|
||||
return BitRate.Unknown;
|
||||
}
|
||||
|
||||
private static SampleSize ParseSampleSize(string name)
|
||||
{
|
||||
var match = SampleSizeRegex.Match(name);
|
||||
|
||||
if (!match.Success) { return SampleSize.Unknown; }
|
||||
if (match.Groups["S24"].Success) { return SampleSize.S24; }
|
||||
|
||||
return SampleSize.Unknown;
|
||||
}
|
||||
|
||||
private static Quality FindQuality(Codec codec, int bitrate, int sampleSize = 0)
|
||||
{
|
||||
switch (codec)
|
||||
{
|
||||
case Codec.MP3VBR:
|
||||
return Quality.MP3_VBR;
|
||||
case Codec.MP3CBR:
|
||||
if (bitrate == 8) { return Quality.MP3_008; }
|
||||
if (bitrate == 16) { return Quality.MP3_016; }
|
||||
if (bitrate == 24) { return Quality.MP3_024; }
|
||||
if (bitrate == 32) { return Quality.MP3_032; }
|
||||
if (bitrate == 40) { return Quality.MP3_040; }
|
||||
if (bitrate == 48) { return Quality.MP3_048; }
|
||||
if (bitrate == 56) { return Quality.MP3_056; }
|
||||
if (bitrate == 64) { return Quality.MP3_064; }
|
||||
if (bitrate == 80) { return Quality.MP3_080; }
|
||||
if (bitrate == 96) { return Quality.MP3_096; }
|
||||
if (bitrate == 112) { return Quality.MP3_112; }
|
||||
if (bitrate == 128) { return Quality.MP3_128; }
|
||||
if (bitrate == 160) { return Quality.MP3_160; }
|
||||
if (bitrate == 192) { return Quality.MP3_192; }
|
||||
if (bitrate == 224) { return Quality.MP3_224; }
|
||||
if (bitrate == 256) { return Quality.MP3_256; }
|
||||
if (bitrate == 320) { return Quality.MP3_320; }
|
||||
return Quality.Unknown;
|
||||
case Codec.FLAC:
|
||||
if (sampleSize == 24) {return Quality.FLAC_24;}
|
||||
return Quality.FLAC;
|
||||
case Codec.ALAC:
|
||||
return Quality.ALAC;
|
||||
case Codec.WMA:
|
||||
return Quality.WMA;
|
||||
case Codec.WAV:
|
||||
return Quality.WAV;
|
||||
case Codec.AAC:
|
||||
if (bitrate == 192) { return Quality.AAC_192; }
|
||||
if (bitrate == 256) { return Quality.AAC_256; }
|
||||
if (bitrate == 320) { return Quality.AAC_320; }
|
||||
return Quality.AAC_VBR;
|
||||
case Codec.OGG:
|
||||
if (bitrate == 160) { return Quality.VORBIS_Q5; }
|
||||
if (bitrate == 192) { return Quality.VORBIS_Q6; }
|
||||
if (bitrate == 224) { return Quality.VORBIS_Q7; }
|
||||
if (bitrate == 256) { return Quality.VORBIS_Q8; }
|
||||
if (bitrate == 320) { return Quality.VORBIS_Q9; }
|
||||
if (bitrate == 500) { return Quality.VORBIS_Q10; }
|
||||
return Quality.Unknown;
|
||||
default:
|
||||
return Quality.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
private static QualityModel ParseQualityModifiers(string name, string normalizedName)
|
||||
{
|
||||
var result = new QualityModel { Quality = Quality.Unknown };
|
||||
|
@ -166,7 +262,7 @@ namespace NzbDrone.Core.Parser
|
|||
result.Revision.Version = 2;
|
||||
}
|
||||
|
||||
var versionRegexResult = VersionRegex.Match(normalizedName);
|
||||
Match versionRegexResult = VersionRegex.Match(normalizedName);
|
||||
|
||||
if (versionRegexResult.Success)
|
||||
{
|
||||
|
@ -175,7 +271,7 @@ namespace NzbDrone.Core.Parser
|
|||
|
||||
//TODO: re-enable this when we have a reliable way to determine real
|
||||
//TODO: Only treat it as a real if it comes AFTER the season/epsiode number
|
||||
var realRegexResult = RealRegex.Matches(name);
|
||||
MatchCollection realRegexResult = RealRegex.Matches(name);
|
||||
|
||||
if (realRegexResult.Count > 0)
|
||||
{
|
||||
|
@ -186,14 +282,39 @@ namespace NzbDrone.Core.Parser
|
|||
}
|
||||
}
|
||||
|
||||
public enum BitRate
|
||||
public enum Codec
|
||||
{
|
||||
B192,
|
||||
B256,
|
||||
B320,
|
||||
B512,
|
||||
VBR,
|
||||
MP3CBR,
|
||||
MP3VBR,
|
||||
FLAC,
|
||||
ALAC,
|
||||
WMA,
|
||||
AAC,
|
||||
AACVBR,
|
||||
OGG,
|
||||
WAV,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
public enum BitRate
|
||||
{
|
||||
B096,
|
||||
B128,
|
||||
B160,
|
||||
B192,
|
||||
B224,
|
||||
B256,
|
||||
B320,
|
||||
B500,
|
||||
VBR,
|
||||
VBRV0,
|
||||
VBRV2,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
public enum SampleSize
|
||||
{
|
||||
S24,
|
||||
Unknown
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Http.Dispatchers;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Qualities;
|
||||
|
@ -16,6 +18,8 @@ namespace NzbDrone.Core.Profiles.Qualities
|
|||
List<Profile> All();
|
||||
Profile Get(int id);
|
||||
bool Exists(int id);
|
||||
Profile GetDefaultProfile(string name, Quality cutoff = null, params Quality[] allowed);
|
||||
|
||||
}
|
||||
|
||||
public class ProfileService : IProfileService, IHandle<ApplicationStartedEvent>
|
||||
|
@ -66,45 +70,112 @@ namespace NzbDrone.Core.Profiles.Qualities
|
|||
return _profileRepository.Exists(id);
|
||||
}
|
||||
|
||||
private Profile AddDefaultProfile(string name, Quality cutoff, params Quality[] allowed)
|
||||
{
|
||||
var items = Quality.DefaultQualityDefinitions
|
||||
.OrderBy(v => v.Weight)
|
||||
.Select(v => new ProfileQualityItem { Quality = v.Quality, Allowed = allowed.Contains(v.Quality) })
|
||||
.ToList();
|
||||
|
||||
var profile = new Profile { Name = name,
|
||||
Cutoff = (int)cutoff,
|
||||
Items = items};
|
||||
|
||||
return Add(profile);
|
||||
}
|
||||
|
||||
public void Handle(ApplicationStartedEvent message)
|
||||
{
|
||||
if (All().Any()) return;
|
||||
|
||||
_logger.Info("Setting up default quality profiles");
|
||||
|
||||
AddDefaultProfile("Any",
|
||||
Quality.Unknown,
|
||||
AddDefaultProfile("Any", Quality.Unknown,
|
||||
Quality.Unknown,
|
||||
Quality.MP3_008,
|
||||
Quality.MP3_016,
|
||||
Quality.MP3_024,
|
||||
Quality.MP3_032,
|
||||
Quality.MP3_040,
|
||||
Quality.MP3_048,
|
||||
Quality.MP3_056,
|
||||
Quality.MP3_064,
|
||||
Quality.MP3_080,
|
||||
Quality.MP3_096,
|
||||
Quality.MP3_112,
|
||||
Quality.MP3_128,
|
||||
Quality.MP3_160,
|
||||
Quality.MP3_192,
|
||||
Quality.MP3_224,
|
||||
Quality.MP3_256,
|
||||
Quality.MP3_320,
|
||||
Quality.MP3_512,
|
||||
Quality.MP3_VBR,
|
||||
Quality.FLAC);
|
||||
|
||||
AddDefaultProfile("Lossless",
|
||||
Quality.MP3_VBR_V2,
|
||||
Quality.AAC_192,
|
||||
Quality.AAC_256,
|
||||
Quality.AAC_320,
|
||||
Quality.AAC_VBR,
|
||||
Quality.VORBIS_Q5,
|
||||
Quality.VORBIS_Q6,
|
||||
Quality.VORBIS_Q7,
|
||||
Quality.VORBIS_Q8,
|
||||
Quality.VORBIS_Q9,
|
||||
Quality.VORBIS_Q10,
|
||||
Quality.WMA,
|
||||
Quality.ALAC,
|
||||
Quality.FLAC,
|
||||
Quality.FLAC);
|
||||
Quality.FLAC_24);
|
||||
|
||||
AddDefaultProfile("Standard",
|
||||
Quality.MP3_192,
|
||||
AddDefaultProfile("Lossless", Quality.FLAC,
|
||||
Quality.FLAC,
|
||||
Quality.ALAC,
|
||||
Quality.FLAC_24);
|
||||
|
||||
AddDefaultProfile("Standard", Quality.MP3_192,
|
||||
Quality.MP3_192,
|
||||
Quality.MP3_256,
|
||||
Quality.MP3_320);
|
||||
}
|
||||
|
||||
public Profile GetDefaultProfile(string name, Quality cutoff = null, params Quality[] allowed)
|
||||
{
|
||||
var groupedQualites = Quality.DefaultQualityDefinitions.GroupBy(q => q.GroupWeight);
|
||||
var items = new List<ProfileQualityItem>();
|
||||
var groupId = 1000;
|
||||
var profileCutoff = cutoff == null ? Quality.Unknown.Id : cutoff.Id;
|
||||
|
||||
foreach (var group in groupedQualites)
|
||||
{
|
||||
if (group.Count() == 1)
|
||||
{
|
||||
var quality = group.First().Quality;
|
||||
items.Add(new ProfileQualityItem { Quality = quality, Allowed = allowed.Contains(quality) });
|
||||
continue;
|
||||
}
|
||||
|
||||
var groupAllowed = group.Any(g => allowed.Contains(g.Quality));
|
||||
|
||||
items.Add(new ProfileQualityItem
|
||||
{
|
||||
Id = groupId,
|
||||
Name = group.First().GroupName,
|
||||
Items = group.Select(g => new ProfileQualityItem
|
||||
{
|
||||
Quality = g.Quality,
|
||||
Allowed = groupAllowed
|
||||
}).ToList(),
|
||||
Allowed = groupAllowed
|
||||
});
|
||||
|
||||
if (group.Any(s => s.Quality.Id == profileCutoff))
|
||||
{
|
||||
profileCutoff = groupId;
|
||||
}
|
||||
|
||||
groupId++;
|
||||
}
|
||||
|
||||
var qualityProfile = new Profile
|
||||
{
|
||||
Name = name,
|
||||
Cutoff = profileCutoff,
|
||||
Items = items
|
||||
};
|
||||
|
||||
return qualityProfile;
|
||||
}
|
||||
|
||||
private Profile AddDefaultProfile(string name, Quality cutoff, params Quality[] allowed)
|
||||
{
|
||||
var profile = GetDefaultProfile(name, cutoff, allowed);
|
||||
|
||||
return Add(profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,23 +57,79 @@ namespace NzbDrone.Core.Qualities
|
|||
|
||||
public static Quality Unknown => new Quality(0, "Unknown");
|
||||
public static Quality MP3_192 => new Quality(1, "MP3-192");
|
||||
public static Quality MP3_VBR => new Quality(2, "MP3-VBR");
|
||||
public static Quality MP3_VBR => new Quality(2, "MP3-VBR-V0");
|
||||
public static Quality MP3_256 => new Quality(3, "MP3-256");
|
||||
public static Quality MP3_320 => new Quality(4, "MP3-320");
|
||||
public static Quality MP3_512 => new Quality(5, "MP3-512");
|
||||
public static Quality MP3_160 => new Quality(5, "MP3-160");
|
||||
public static Quality FLAC => new Quality(6, "FLAC");
|
||||
public static Quality ALAC => new Quality(7, "ALAC");
|
||||
public static Quality MP3_VBR_V2 => new Quality(8, "MP3-VBR-V2");
|
||||
public static Quality AAC_192 => new Quality(9, "AAC-192");
|
||||
public static Quality AAC_256 => new Quality(10, "AAC-256");
|
||||
public static Quality AAC_320 => new Quality(11, "AAC-320");
|
||||
public static Quality AAC_VBR => new Quality(12, "AAC-VBR");
|
||||
public static Quality WAV => new Quality(13, "WAV");
|
||||
public static Quality VORBIS_Q10 => new Quality(14, "OGG Vorbis Q10");
|
||||
public static Quality VORBIS_Q9 => new Quality(15, "OGG Vorbis Q9");
|
||||
public static Quality VORBIS_Q8 => new Quality(16, "OGG Vorbis Q8");
|
||||
public static Quality VORBIS_Q7 => new Quality(17, "OGG Vorbis Q7");
|
||||
public static Quality VORBIS_Q6 => new Quality(18, "OGG Vorbis Q6");
|
||||
public static Quality VORBIS_Q5 => new Quality(19, "OGG Vorbis Q5");
|
||||
public static Quality WMA => new Quality(20, "WMA");
|
||||
public static Quality FLAC_24 => new Quality(21, "FLAC 24bit");
|
||||
public static Quality MP3_128 => new Quality(22, "MP3-128");
|
||||
public static Quality MP3_096 => new Quality(23, "MP3-96"); // For Current Files Only
|
||||
public static Quality MP3_080 => new Quality(24, "MP3-80"); // For Current Files Only
|
||||
public static Quality MP3_064 => new Quality(25, "MP3-64"); // For Current Files Only
|
||||
public static Quality MP3_056 => new Quality(26, "MP3-56"); // For Current Files Only
|
||||
public static Quality MP3_048 => new Quality(27, "MP3-48"); // For Current Files Only
|
||||
public static Quality MP3_040 => new Quality(28, "MP3-40"); // For Current Files Only
|
||||
public static Quality MP3_032 => new Quality(29, "MP3-32"); // For Current Files Only
|
||||
public static Quality MP3_024 => new Quality(30, "MP3-24"); // For Current Files Only
|
||||
public static Quality MP3_016 => new Quality(31, "MP3-16"); // For Current Files Only
|
||||
public static Quality MP3_008 => new Quality(32, "MP3-8"); // For Current Files Only
|
||||
public static Quality MP3_112 => new Quality(33, "MP3-112"); // For Current Files Only
|
||||
public static Quality MP3_224 => new Quality(34, "MP3-224"); // For Current Files Only
|
||||
|
||||
static Quality()
|
||||
{
|
||||
All = new List<Quality>
|
||||
{
|
||||
Unknown,
|
||||
MP3_008,
|
||||
MP3_016,
|
||||
MP3_024,
|
||||
MP3_032,
|
||||
MP3_040,
|
||||
MP3_048,
|
||||
MP3_056,
|
||||
MP3_064,
|
||||
MP3_080,
|
||||
MP3_096,
|
||||
MP3_112,
|
||||
MP3_128,
|
||||
MP3_160,
|
||||
MP3_192,
|
||||
MP3_224,
|
||||
MP3_VBR,
|
||||
MP3_256,
|
||||
MP3_320,
|
||||
MP3_512,
|
||||
MP3_VBR_V2,
|
||||
AAC_192,
|
||||
AAC_256,
|
||||
AAC_320,
|
||||
AAC_VBR,
|
||||
WMA,
|
||||
VORBIS_Q10,
|
||||
VORBIS_Q9,
|
||||
VORBIS_Q8,
|
||||
VORBIS_Q7,
|
||||
VORBIS_Q6,
|
||||
VORBIS_Q5,
|
||||
ALAC,
|
||||
FLAC,
|
||||
FLAC_24,
|
||||
WAV
|
||||
};
|
||||
|
||||
AllLookup = new Quality[All.Select(v => v.Id).Max() + 1];
|
||||
|
@ -84,13 +140,41 @@ namespace NzbDrone.Core.Qualities
|
|||
|
||||
DefaultQualityDefinitions = new HashSet<QualityDefinition>
|
||||
{
|
||||
new QualityDefinition(Quality.Unknown) { Weight = 1, MinSize = 0, MaxSize = 100 },
|
||||
new QualityDefinition(Quality.MP3_192) { Weight = 2, MinSize = 0, MaxSize = 100 },
|
||||
new QualityDefinition(Quality.MP3_VBR) { Weight = 3, MinSize = 0, MaxSize = 100 },
|
||||
new QualityDefinition(Quality.MP3_256) { Weight = 4, MinSize = 0, MaxSize = 100 },
|
||||
new QualityDefinition(Quality.MP3_320) { Weight = 5, MinSize = 0, MaxSize = 100 },
|
||||
new QualityDefinition(Quality.MP3_512) { Weight = 6, MinSize = 0, MaxSize = 100 },
|
||||
new QualityDefinition(Quality.FLAC) { Weight = 7, MinSize = 0, MaxSize = null },
|
||||
new QualityDefinition(Quality.Unknown) { Weight = 1, MinSize = 0, MaxSize = 100, GroupWeight = 1},
|
||||
new QualityDefinition(Quality.MP3_008) { Weight = 2, MinSize = 0, MaxSize = 100, GroupName = "Trash Quality Lossy", GroupWeight = 2 },
|
||||
new QualityDefinition(Quality.MP3_016) { Weight = 3, MinSize = 0, MaxSize = 100, GroupName = "Trash Quality Lossy", GroupWeight = 2 },
|
||||
new QualityDefinition(Quality.MP3_024) { Weight = 4, MinSize = 0, MaxSize = 100, GroupName = "Trash Quality Lossy", GroupWeight = 2 },
|
||||
new QualityDefinition(Quality.MP3_032) { Weight = 5, MinSize = 0, MaxSize = 100, GroupName = "Trash Quality Lossy", GroupWeight = 2 },
|
||||
new QualityDefinition(Quality.MP3_040) { Weight = 6, MinSize = 0, MaxSize = 100, GroupName = "Trash Quality Lossy", GroupWeight = 2 },
|
||||
new QualityDefinition(Quality.MP3_048) { Weight = 7, MinSize = 0, MaxSize = 100, GroupName = "Trash Quality Lossy", GroupWeight = 2 },
|
||||
new QualityDefinition(Quality.MP3_056) { Weight = 8, MinSize = 0, MaxSize = 100, GroupName = "Trash Quality Lossy", GroupWeight = 2 },
|
||||
new QualityDefinition(Quality.MP3_064) { Weight = 9, MinSize = 0, MaxSize = 100, GroupName = "Trash Quality Lossy", GroupWeight = 2 },
|
||||
new QualityDefinition(Quality.MP3_080) { Weight = 10, MinSize = 0, MaxSize = 100, GroupName = "Trash Quality Lossy", GroupWeight = 2 },
|
||||
new QualityDefinition(Quality.MP3_096) { Weight = 11, MinSize = 0, MaxSize = 100, GroupName = "Poor Quality Lossy", GroupWeight = 3 },
|
||||
new QualityDefinition(Quality.MP3_112) { Weight = 12, MinSize = 0, MaxSize = 100, GroupName = "Poor Quality Lossy", GroupWeight = 3 },
|
||||
new QualityDefinition(Quality.MP3_128) { Weight = 13, MinSize = 0, MaxSize = 100, GroupName = "Poor Quality Lossy", GroupWeight = 3 },
|
||||
new QualityDefinition(Quality.VORBIS_Q5) { Weight = 14, MinSize = 0, MaxSize = 100, GroupName = "Poor Quality Lossy", GroupWeight = 3 },
|
||||
new QualityDefinition(Quality.MP3_160) { Weight = 14, MinSize = 0, MaxSize = 100, GroupName = "Poor Quality Lossy", GroupWeight = 3 },
|
||||
new QualityDefinition(Quality.MP3_192) { Weight = 15, MinSize = 0, MaxSize = 100, GroupName = "Low Quality Lossy", GroupWeight = 4 },
|
||||
new QualityDefinition(Quality.VORBIS_Q6) { Weight = 15, MinSize = 0, MaxSize = 100, GroupName = "Low Quality Lossy", GroupWeight = 4 },
|
||||
new QualityDefinition(Quality.AAC_192) { Weight = 15, MinSize = 0, MaxSize = 100, GroupName = "Low Quality Lossy", GroupWeight = 4 },
|
||||
new QualityDefinition(Quality.WMA) { Weight = 15, MinSize = 0, MaxSize = 100, GroupName = "Low Quality Lossy", GroupWeight = 4 },
|
||||
new QualityDefinition(Quality.MP3_224) { Weight = 16, MinSize = 0, MaxSize = 100, GroupName = "Low Quality Lossy", GroupWeight = 4 },
|
||||
new QualityDefinition(Quality.VORBIS_Q7) { Weight = 17, MinSize = 0, MaxSize = 100, GroupName = "Mid Quality Lossy", GroupWeight = 5 },
|
||||
new QualityDefinition(Quality.MP3_VBR_V2) { Weight = 18, MinSize = 0, MaxSize = 100, GroupName = "Mid Quality Lossy", GroupWeight = 5 },
|
||||
new QualityDefinition(Quality.MP3_256) { Weight = 18, MinSize = 0, MaxSize = 100, GroupName = "Mid Quality Lossy", GroupWeight = 5 },
|
||||
new QualityDefinition(Quality.VORBIS_Q8) { Weight = 18, MinSize = 0, MaxSize = 100, GroupName = "Mid Quality Lossy", GroupWeight = 5 },
|
||||
new QualityDefinition(Quality.AAC_256) { Weight = 18, MinSize = 0, MaxSize = 100, GroupName = "Mid Quality Lossy", GroupWeight = 5 },
|
||||
new QualityDefinition(Quality.MP3_VBR) { Weight = 19, MinSize = 0, MaxSize = 100, GroupName = "High Quality Lossy", GroupWeight = 6 },
|
||||
new QualityDefinition(Quality.AAC_VBR) { Weight = 19, MinSize = 0, MaxSize = 100, GroupName = "High Quality Lossy", GroupWeight = 6 },
|
||||
new QualityDefinition(Quality.MP3_320) { Weight = 20, MinSize = 0, MaxSize = 100, GroupName = "High Quality Lossy", GroupWeight = 6 },
|
||||
new QualityDefinition(Quality.VORBIS_Q9) { Weight = 20, MinSize = 0, MaxSize = 100, GroupName = "High Quality Lossy", GroupWeight = 6 },
|
||||
new QualityDefinition(Quality.AAC_320) { Weight = 20, MinSize = 0, MaxSize = 100, GroupName = "High Quality Lossy", GroupWeight = 6 },
|
||||
new QualityDefinition(Quality.VORBIS_Q10) { Weight = 12, MinSize = 0, MaxSize = 100, GroupName = "High Quality Lossy", GroupWeight = 6 },
|
||||
new QualityDefinition(Quality.ALAC) { Weight = 22, MinSize = 0, MaxSize = null, GroupName = "Lossless", GroupWeight = 7 },
|
||||
new QualityDefinition(Quality.FLAC) { Weight = 22, MinSize = 0, MaxSize = null, GroupName = "Lossless", GroupWeight = 7 },
|
||||
new QualityDefinition(Quality.FLAC_24) { Weight = 23, MinSize = 0, MaxSize = null, GroupName = "Lossless", GroupWeight = 7 },
|
||||
new QualityDefinition(Quality.WAV) { Weight = 24, MinSize = 0, MaxSize = null, GroupWeight = 8}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace NzbDrone.Core.Qualities
|
|||
public string Title { get; set; }
|
||||
|
||||
public string GroupName { get; set; }
|
||||
public int GroupWeight { get; set; }
|
||||
public int Weight { get; set; }
|
||||
|
||||
public double? MinSize { get; set; }
|
||||
|
|
Loading…
Reference in New Issue