Closes #3562pull/6576/head
parent
c99d81e79b
commit
f8a0751775
@ -0,0 +1,191 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Datastore.Migration;
|
||||
using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
[TestFixture]
|
||||
public class release_typeFixture : MigrationTest<release_type>
|
||||
{
|
||||
[Test]
|
||||
public void should_convert_single_episode_without_folder()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("EpisodeFiles").Row(new
|
||||
{
|
||||
SeriesId = 1,
|
||||
SeasonNumber = 1,
|
||||
RelativePath = "Season 01/S01E05.mkv",
|
||||
Size = 125.Megabytes(),
|
||||
DateAdded = DateTime.UtcNow.AddDays(-5),
|
||||
OriginalFilePath = "Series.Title.S01E05.720p.HDTV.x265-Sonarr.mkv",
|
||||
ReleaseGroup = "Sonarr",
|
||||
Quality = new QualityModel(Quality.HDTV720p).ToJson(),
|
||||
Languages = "[1]"
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<EpisodeFile203>("SELECT * FROM \"EpisodeFiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
|
||||
items.First().ReleaseType.Should().Be((int)ReleaseType.SingleEpisode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_convert_single_episode_with_folder()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("EpisodeFiles").Row(new
|
||||
{
|
||||
SeriesId = 1,
|
||||
SeasonNumber = 1,
|
||||
RelativePath = "Season 01/S01E05.mkv",
|
||||
Size = 125.Megabytes(),
|
||||
DateAdded = DateTime.UtcNow.AddDays(-5),
|
||||
OriginalFilePath = "Series.Title.S01E05.720p.HDTV.x265-Sonarr/S01E05.mkv",
|
||||
ReleaseGroup = "Sonarr",
|
||||
Quality = new QualityModel(Quality.HDTV720p).ToJson(),
|
||||
Languages = "[1]"
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<EpisodeFile203>("SELECT * FROM \"EpisodeFiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
|
||||
items.First().ReleaseType.Should().Be((int)ReleaseType.SingleEpisode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_convert_multi_episode_without_folder()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("EpisodeFiles").Row(new
|
||||
{
|
||||
SeriesId = 1,
|
||||
SeasonNumber = 1,
|
||||
RelativePath = "Season 01/S01E05.mkv",
|
||||
Size = 125.Megabytes(),
|
||||
DateAdded = DateTime.UtcNow.AddDays(-5),
|
||||
OriginalFilePath = "Series.Title.S01E05E06.720p.HDTV.x265-Sonarr.mkv",
|
||||
ReleaseGroup = "Sonarr",
|
||||
Quality = new QualityModel(Quality.HDTV720p).ToJson(),
|
||||
Languages = "[1]"
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<EpisodeFile203>("SELECT * FROM \"EpisodeFiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
|
||||
items.First().ReleaseType.Should().Be((int)ReleaseType.MultiEpisode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_convert_multi_episode_with_folder()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("EpisodeFiles").Row(new
|
||||
{
|
||||
SeriesId = 1,
|
||||
SeasonNumber = 1,
|
||||
RelativePath = "Season 01/S01E05.mkv",
|
||||
Size = 125.Megabytes(),
|
||||
DateAdded = DateTime.UtcNow.AddDays(-5),
|
||||
OriginalFilePath = "Series.Title.S01E05E06.720p.HDTV.x265-Sonarr/S01E05E06.mkv",
|
||||
ReleaseGroup = "Sonarr",
|
||||
Quality = new QualityModel(Quality.HDTV720p).ToJson(),
|
||||
Languages = "[1]"
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<EpisodeFile203>("SELECT * FROM \"EpisodeFiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
|
||||
items.First().ReleaseType.Should().Be((int)ReleaseType.MultiEpisode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_convert_season_pack_with_folder()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("EpisodeFiles").Row(new
|
||||
{
|
||||
SeriesId = 1,
|
||||
SeasonNumber = 1,
|
||||
RelativePath = "Season 01/S01E05.mkv",
|
||||
Size = 125.Megabytes(),
|
||||
DateAdded = DateTime.UtcNow.AddDays(-5),
|
||||
OriginalFilePath = "Series.Title.S01.720p.HDTV.x265-Sonarr/S01E05.mkv",
|
||||
ReleaseGroup = "Sonarr",
|
||||
Quality = new QualityModel(Quality.HDTV720p).ToJson(),
|
||||
Languages = "[1]"
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<EpisodeFile203>("SELECT * FROM \"EpisodeFiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
|
||||
items.First().ReleaseType.Should().Be((int)ReleaseType.SeasonPack);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_convert_episode_without_original_file_path()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("EpisodeFiles").Row(new
|
||||
{
|
||||
SeriesId = 1,
|
||||
SeasonNumber = 1,
|
||||
RelativePath = "Season 01/S01E05.mkv",
|
||||
Size = 125.Megabytes(),
|
||||
DateAdded = DateTime.UtcNow.AddDays(-5),
|
||||
ReleaseGroup = "Sonarr",
|
||||
Quality = new QualityModel(Quality.HDTV720p).ToJson(),
|
||||
Languages = "[1]"
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<EpisodeFile203>("SELECT * FROM \"EpisodeFiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
|
||||
items.First().ReleaseType.Should().Be((int)ReleaseType.Unknown);
|
||||
}
|
||||
|
||||
public class EpisodeFile203
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int SeriesId { get; set; }
|
||||
public int SeasonNumber { get; set; }
|
||||
public string RelativePath { get; set; }
|
||||
public long Size { get; set; }
|
||||
public DateTime DateAdded { get; set; }
|
||||
public string OriginalFilePath { get; set; }
|
||||
public string SceneName { get; set; }
|
||||
public string ReleaseGroup { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
public long IndexerFlags { get; set; }
|
||||
public MediaInfoModel MediaInfo { get; set; }
|
||||
public List<int> Languages { get; set; }
|
||||
public long ReleaseType { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.CustomFormats
|
||||
{
|
||||
public class SeasonPackSpecificationValidator : AbstractValidator<SeasonPackSpecification>
|
||||
{
|
||||
public SeasonPackSpecificationValidator()
|
||||
{
|
||||
RuleFor(c => c.Value).Custom((releaseType, context) =>
|
||||
{
|
||||
if (!Enum.IsDefined(typeof(ReleaseType), releaseType))
|
||||
{
|
||||
context.AddFailure($"Invalid release type condition value: {releaseType}");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class SeasonPackSpecification : CustomFormatSpecificationBase
|
||||
{
|
||||
private static readonly SeasonPackSpecificationValidator Validator = new ();
|
||||
|
||||
public override int Order => 10;
|
||||
public override string ImplementationName => "Release Type";
|
||||
|
||||
[FieldDefinition(1, Label = "ReleaseType", Type = FieldType.Select, SelectOptions = typeof(ReleaseType))]
|
||||
public int Value { get; set; }
|
||||
|
||||
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
|
||||
{
|
||||
return input.ReleaseType == (ReleaseType)Value;
|
||||
}
|
||||
|
||||
public override NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using Dapper;
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(203)]
|
||||
public class release_type : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Alter.Table("Blocklist").AddColumn("ReleaseType").AsInt32().WithDefaultValue(0);
|
||||
Alter.Table("EpisodeFiles").AddColumn("ReleaseType").AsInt32().WithDefaultValue(0);
|
||||
|
||||
Execute.WithConnection(UpdateEpisodeFiles);
|
||||
}
|
||||
|
||||
private void UpdateEpisodeFiles(IDbConnection conn, IDbTransaction tran)
|
||||
{
|
||||
var updates = new List<object>();
|
||||
|
||||
using (var cmd = conn.CreateCommand())
|
||||
{
|
||||
cmd.Transaction = tran;
|
||||
cmd.CommandText = "SELECT \"Id\", \"OriginalFilePath\" FROM \"EpisodeFiles\" WHERE \"OriginalFilePath\" IS NOT NULL";
|
||||
|
||||
using var reader = cmd.ExecuteReader();
|
||||
while (reader.Read())
|
||||
{
|
||||
var id = reader.GetInt32(0);
|
||||
var originalFilePath = reader.GetString(1);
|
||||
|
||||
var folderName = Path.GetDirectoryName(originalFilePath);
|
||||
var fileName = Path.GetFileNameWithoutExtension(originalFilePath);
|
||||
var title = folderName.IsNullOrWhiteSpace() ? fileName : folderName;
|
||||
var parsedEpisodeInfo = Parser.Parser.ParseTitle(title);
|
||||
|
||||
if (parsedEpisodeInfo != null && parsedEpisodeInfo.ReleaseType != ReleaseType.Unknown)
|
||||
{
|
||||
updates.Add(new
|
||||
{
|
||||
Id = id,
|
||||
ReleaseType = (int)parsedEpisodeInfo.ReleaseType
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var updateEpisodeFilesSql = "UPDATE \"EpisodeFiles\" SET \"ReleaseType\" = @ReleaseType WHERE \"Id\" = @Id";
|
||||
conn.Execute(updateEpisodeFilesSql, updates, transaction: tran);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
using NzbDrone.Core.Annotations;
|
||||
|
||||
namespace NzbDrone.Core.Parser.Model
|
||||
{
|
||||
public enum ReleaseType
|
||||
{
|
||||
Unknown = 0,
|
||||
|
||||
[FieldOption(label: "Single Episode")]
|
||||
SingleEpisode = 1,
|
||||
|
||||
[FieldOption(label: "Multi-Episode")]
|
||||
MultiEpisode = 2,
|
||||
|
||||
[FieldOption(label: "Season Pack")]
|
||||
SeasonPack = 3
|
||||
}
|
||||
}
|
Loading…
Reference in new issue