New: Release Type (Single/Multi episode and Season Pack) for Custom Formats
Closes #3562
This commit is contained in:
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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,6 +49,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
_rejectedDecisions.Add(new ImportDecision(new LocalEpisode(), new Rejection("Rejected!")));
|
_rejectedDecisions.Add(new ImportDecision(new LocalEpisode(), new Rejection("Rejected!")));
|
||||||
_rejectedDecisions.Add(new ImportDecision(new LocalEpisode(), new Rejection("Rejected!")));
|
_rejectedDecisions.Add(new ImportDecision(new LocalEpisode(), new Rejection("Rejected!")));
|
||||||
_rejectedDecisions.Add(new ImportDecision(new LocalEpisode(), new Rejection("Rejected!")));
|
_rejectedDecisions.Add(new ImportDecision(new LocalEpisode(), new Rejection("Rejected!")));
|
||||||
|
_rejectedDecisions.ForEach(r => r.LocalEpisode.FileEpisodeInfo = new ParsedEpisodeInfo());
|
||||||
|
|
||||||
foreach (var episode in episodes)
|
foreach (var episode in episodes)
|
||||||
{
|
{
|
||||||
|
@ -59,7 +60,8 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
Episodes = new List<Episode> { episode },
|
Episodes = new List<Episode> { episode },
|
||||||
Path = Path.Combine(series.Path, "30 Rock - S01E01 - Pilot.avi"),
|
Path = Path.Combine(series.Path, "30 Rock - S01E01 - Pilot.avi"),
|
||||||
Quality = new QualityModel(Quality.Bluray720p),
|
Quality = new QualityModel(Quality.Bluray720p),
|
||||||
ReleaseGroup = "DRONE"
|
ReleaseGroup = "DRONE",
|
||||||
|
FileEpisodeInfo = new ParsedEpisodeInfo()
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ namespace NzbDrone.Core.Blocklisting
|
||||||
public DownloadProtocol Protocol { get; set; }
|
public DownloadProtocol Protocol { get; set; }
|
||||||
public string Indexer { get; set; }
|
public string Indexer { get; set; }
|
||||||
public IndexerFlags IndexerFlags { get; set; }
|
public IndexerFlags IndexerFlags { get; set; }
|
||||||
|
public ReleaseType ReleaseType { get; set; }
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
public string TorrentInfoHash { get; set; }
|
public string TorrentInfoHash { get; set; }
|
||||||
public List<Language> Languages { get; set; }
|
public List<Language> Languages { get; set; }
|
||||||
|
|
|
@ -194,6 +194,11 @@ namespace NzbDrone.Core.Blocklisting
|
||||||
blocklist.IndexerFlags = flags;
|
blocklist.IndexerFlags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Enum.TryParse(message.Data.GetValueOrDefault("releaseType"), true, out ReleaseType releaseType))
|
||||||
|
{
|
||||||
|
blocklist.ReleaseType = releaseType;
|
||||||
|
}
|
||||||
|
|
||||||
_blocklistRepository.Insert(blocklist);
|
_blocklistRepository.Insert(blocklist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,8 @@ namespace NzbDrone.Core.CustomFormats
|
||||||
Series = remoteEpisode.Series,
|
Series = remoteEpisode.Series,
|
||||||
Size = size,
|
Size = size,
|
||||||
Languages = remoteEpisode.Languages,
|
Languages = remoteEpisode.Languages,
|
||||||
IndexerFlags = remoteEpisode.Release?.IndexerFlags ?? 0
|
IndexerFlags = remoteEpisode.Release?.IndexerFlags ?? 0,
|
||||||
|
ReleaseType = remoteEpisode.ParsedEpisodeInfo.ReleaseType
|
||||||
};
|
};
|
||||||
|
|
||||||
return ParseCustomFormat(input);
|
return ParseCustomFormat(input);
|
||||||
|
@ -76,7 +77,8 @@ namespace NzbDrone.Core.CustomFormats
|
||||||
Series = series,
|
Series = series,
|
||||||
Size = blocklist.Size ?? 0,
|
Size = blocklist.Size ?? 0,
|
||||||
Languages = blocklist.Languages,
|
Languages = blocklist.Languages,
|
||||||
IndexerFlags = blocklist.IndexerFlags
|
IndexerFlags = blocklist.IndexerFlags,
|
||||||
|
ReleaseType = blocklist.ReleaseType
|
||||||
};
|
};
|
||||||
|
|
||||||
return ParseCustomFormat(input);
|
return ParseCustomFormat(input);
|
||||||
|
@ -88,6 +90,7 @@ namespace NzbDrone.Core.CustomFormats
|
||||||
|
|
||||||
long.TryParse(history.Data.GetValueOrDefault("size"), out var size);
|
long.TryParse(history.Data.GetValueOrDefault("size"), out var size);
|
||||||
Enum.TryParse(history.Data.GetValueOrDefault("indexerFlags"), true, out IndexerFlags indexerFlags);
|
Enum.TryParse(history.Data.GetValueOrDefault("indexerFlags"), true, out IndexerFlags indexerFlags);
|
||||||
|
Enum.TryParse(history.Data.GetValueOrDefault("releaseType"), out ReleaseType releaseType);
|
||||||
|
|
||||||
var episodeInfo = new ParsedEpisodeInfo
|
var episodeInfo = new ParsedEpisodeInfo
|
||||||
{
|
{
|
||||||
|
@ -104,7 +107,8 @@ namespace NzbDrone.Core.CustomFormats
|
||||||
Series = series,
|
Series = series,
|
||||||
Size = size,
|
Size = size,
|
||||||
Languages = history.Languages,
|
Languages = history.Languages,
|
||||||
IndexerFlags = indexerFlags
|
IndexerFlags = indexerFlags,
|
||||||
|
ReleaseType = releaseType
|
||||||
};
|
};
|
||||||
|
|
||||||
return ParseCustomFormat(input);
|
return ParseCustomFormat(input);
|
||||||
|
@ -128,6 +132,7 @@ namespace NzbDrone.Core.CustomFormats
|
||||||
Size = localEpisode.Size,
|
Size = localEpisode.Size,
|
||||||
Languages = localEpisode.Languages,
|
Languages = localEpisode.Languages,
|
||||||
IndexerFlags = localEpisode.IndexerFlags,
|
IndexerFlags = localEpisode.IndexerFlags,
|
||||||
|
ReleaseType = localEpisode.ReleaseType,
|
||||||
Filename = Path.GetFileName(localEpisode.Path)
|
Filename = Path.GetFileName(localEpisode.Path)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -188,7 +193,7 @@ namespace NzbDrone.Core.CustomFormats
|
||||||
ReleaseTitle = releaseTitle,
|
ReleaseTitle = releaseTitle,
|
||||||
Quality = episodeFile.Quality,
|
Quality = episodeFile.Quality,
|
||||||
Languages = episodeFile.Languages,
|
Languages = episodeFile.Languages,
|
||||||
ReleaseGroup = episodeFile.ReleaseGroup
|
ReleaseGroup = episodeFile.ReleaseGroup,
|
||||||
};
|
};
|
||||||
|
|
||||||
var input = new CustomFormatInput
|
var input = new CustomFormatInput
|
||||||
|
@ -198,7 +203,8 @@ namespace NzbDrone.Core.CustomFormats
|
||||||
Size = episodeFile.Size,
|
Size = episodeFile.Size,
|
||||||
Languages = episodeFile.Languages,
|
Languages = episodeFile.Languages,
|
||||||
IndexerFlags = episodeFile.IndexerFlags,
|
IndexerFlags = episodeFile.IndexerFlags,
|
||||||
Filename = Path.GetFileName(episodeFile.RelativePath)
|
ReleaseType = episodeFile.ReleaseType,
|
||||||
|
Filename = Path.GetFileName(episodeFile.RelativePath),
|
||||||
};
|
};
|
||||||
|
|
||||||
return ParseCustomFormat(input, allCustomFormats);
|
return ParseCustomFormat(input, allCustomFormats);
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace NzbDrone.Core.CustomFormats
|
||||||
public IndexerFlags IndexerFlags { get; set; }
|
public IndexerFlags IndexerFlags { get; set; }
|
||||||
public List<Language> Languages { get; set; }
|
public List<Language> Languages { get; set; }
|
||||||
public string Filename { get; set; }
|
public string Filename { get; set; }
|
||||||
|
public ReleaseType ReleaseType { get; set; }
|
||||||
|
|
||||||
public CustomFormatInput()
|
public CustomFormatInput()
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,11 +11,11 @@ namespace NzbDrone.Core.CustomFormats
|
||||||
public IndexerFlagSpecificationValidator()
|
public IndexerFlagSpecificationValidator()
|
||||||
{
|
{
|
||||||
RuleFor(c => c.Value).NotEmpty();
|
RuleFor(c => c.Value).NotEmpty();
|
||||||
RuleFor(c => c.Value).Custom((qualityValue, context) =>
|
RuleFor(c => c.Value).Custom((flag, context) =>
|
||||||
{
|
{
|
||||||
if (!Enum.IsDefined(typeof(IndexerFlags), qualityValue))
|
if (!Enum.IsDefined(typeof(IndexerFlags), flag))
|
||||||
{
|
{
|
||||||
context.AddFailure($"Invalid indexer flag condition value: {qualityValue}");
|
context.AddFailure($"Invalid indexer flag condition value: {flag}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -170,6 +170,7 @@ namespace NzbDrone.Core.History
|
||||||
history.Data.Add("SeriesMatchType", message.Episode.SeriesMatchType.ToString());
|
history.Data.Add("SeriesMatchType", message.Episode.SeriesMatchType.ToString());
|
||||||
history.Data.Add("ReleaseSource", message.Episode.ReleaseSource.ToString());
|
history.Data.Add("ReleaseSource", message.Episode.ReleaseSource.ToString());
|
||||||
history.Data.Add("IndexerFlags", message.Episode.Release.IndexerFlags.ToString());
|
history.Data.Add("IndexerFlags", message.Episode.Release.IndexerFlags.ToString());
|
||||||
|
history.Data.Add("ReleaseType", message.Episode.ParsedEpisodeInfo.ReleaseType.ToString());
|
||||||
|
|
||||||
if (!message.Episode.ParsedEpisodeInfo.ReleaseHash.IsNullOrWhiteSpace())
|
if (!message.Episode.ParsedEpisodeInfo.ReleaseHash.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
|
@ -222,6 +223,7 @@ namespace NzbDrone.Core.History
|
||||||
history.Data.Add("CustomFormatScore", message.EpisodeInfo.CustomFormatScore.ToString());
|
history.Data.Add("CustomFormatScore", message.EpisodeInfo.CustomFormatScore.ToString());
|
||||||
history.Data.Add("Size", message.EpisodeInfo.Size.ToString());
|
history.Data.Add("Size", message.EpisodeInfo.Size.ToString());
|
||||||
history.Data.Add("IndexerFlags", message.ImportedEpisode.IndexerFlags.ToString());
|
history.Data.Add("IndexerFlags", message.ImportedEpisode.IndexerFlags.ToString());
|
||||||
|
history.Data.Add("ReleaseType", message.ImportedEpisode.ReleaseType.ToString());
|
||||||
|
|
||||||
_historyRepository.Insert(history);
|
_historyRepository.Insert(history);
|
||||||
}
|
}
|
||||||
|
@ -283,6 +285,7 @@ namespace NzbDrone.Core.History
|
||||||
history.Data.Add("ReleaseGroup", message.EpisodeFile.ReleaseGroup);
|
history.Data.Add("ReleaseGroup", message.EpisodeFile.ReleaseGroup);
|
||||||
history.Data.Add("Size", message.EpisodeFile.Size.ToString());
|
history.Data.Add("Size", message.EpisodeFile.Size.ToString());
|
||||||
history.Data.Add("IndexerFlags", message.EpisodeFile.IndexerFlags.ToString());
|
history.Data.Add("IndexerFlags", message.EpisodeFile.IndexerFlags.ToString());
|
||||||
|
history.Data.Add("ReleaseType", message.EpisodeFile.ReleaseType.ToString());
|
||||||
|
|
||||||
_historyRepository.Insert(history);
|
_historyRepository.Insert(history);
|
||||||
}
|
}
|
||||||
|
@ -315,6 +318,7 @@ namespace NzbDrone.Core.History
|
||||||
history.Data.Add("ReleaseGroup", message.EpisodeFile.ReleaseGroup);
|
history.Data.Add("ReleaseGroup", message.EpisodeFile.ReleaseGroup);
|
||||||
history.Data.Add("Size", message.EpisodeFile.Size.ToString());
|
history.Data.Add("Size", message.EpisodeFile.Size.ToString());
|
||||||
history.Data.Add("IndexerFlags", message.EpisodeFile.IndexerFlags.ToString());
|
history.Data.Add("IndexerFlags", message.EpisodeFile.IndexerFlags.ToString());
|
||||||
|
history.Data.Add("ReleaseType", message.EpisodeFile.ReleaseType.ToString());
|
||||||
|
|
||||||
_historyRepository.Insert(history);
|
_historyRepository.Insert(history);
|
||||||
}
|
}
|
||||||
|
@ -343,6 +347,7 @@ namespace NzbDrone.Core.History
|
||||||
history.Data.Add("Message", message.Message);
|
history.Data.Add("Message", message.Message);
|
||||||
history.Data.Add("ReleaseGroup", message.TrackedDownload?.RemoteEpisode?.ParsedEpisodeInfo?.ReleaseGroup);
|
history.Data.Add("ReleaseGroup", message.TrackedDownload?.RemoteEpisode?.ParsedEpisodeInfo?.ReleaseGroup);
|
||||||
history.Data.Add("Size", message.TrackedDownload?.DownloadItem.TotalSize.ToString());
|
history.Data.Add("Size", message.TrackedDownload?.DownloadItem.TotalSize.ToString());
|
||||||
|
history.Data.Add("ReleaseType", message.TrackedDownload?.RemoteEpisode?.ParsedEpisodeInfo?.ReleaseType.ToString());
|
||||||
|
|
||||||
historyToAdd.Add(history);
|
historyToAdd.Add(history);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1597,6 +1597,7 @@
|
||||||
"ReleaseSceneIndicatorUnknownMessage": "Numbering varies for this episode and release does not match any known mappings.",
|
"ReleaseSceneIndicatorUnknownMessage": "Numbering varies for this episode and release does not match any known mappings.",
|
||||||
"ReleaseSceneIndicatorUnknownSeries": "Unknown episode or series.",
|
"ReleaseSceneIndicatorUnknownSeries": "Unknown episode or series.",
|
||||||
"ReleaseTitle": "Release Title",
|
"ReleaseTitle": "Release Title",
|
||||||
|
"ReleaseType": "Release Type",
|
||||||
"Reload": "Reload",
|
"Reload": "Reload",
|
||||||
"RemotePath": "Remote Path",
|
"RemotePath": "Remote Path",
|
||||||
"RemotePathMappingBadDockerPathHealthCheckMessage": "You are using docker; download client {downloadClientName} places downloads in {path} but this is not a valid {osName} path. Review your remote path mappings and download client settings.",
|
"RemotePathMappingBadDockerPathHealthCheckMessage": "You are using docker; download client {downloadClientName} places downloads in {path} but this is not a valid {osName} path. Review your remote path mappings and download client settings.",
|
||||||
|
|
|
@ -27,6 +27,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
public LazyLoaded<List<Episode>> Episodes { get; set; }
|
public LazyLoaded<List<Episode>> Episodes { get; set; }
|
||||||
public LazyLoaded<Series> Series { get; set; }
|
public LazyLoaded<Series> Series { get; set; }
|
||||||
public List<Language> Languages { get; set; }
|
public List<Language> Languages { get; set; }
|
||||||
|
public ReleaseType ReleaseType { get; set; }
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
|
|
|
@ -97,6 +97,11 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
episodeFile.ReleaseGroup = localEpisode.ReleaseGroup;
|
episodeFile.ReleaseGroup = localEpisode.ReleaseGroup;
|
||||||
episodeFile.Languages = localEpisode.Languages;
|
episodeFile.Languages = localEpisode.Languages;
|
||||||
|
|
||||||
|
// Prefer the release type from the download client, folder and finally the file so we have the most accurate information.
|
||||||
|
episodeFile.ReleaseType = localEpisode.DownloadClientEpisodeInfo?.ReleaseType ??
|
||||||
|
localEpisode.FolderEpisodeInfo?.ReleaseType ??
|
||||||
|
localEpisode.FileEpisodeInfo.ReleaseType;
|
||||||
|
|
||||||
if (downloadClientItem?.DownloadId.IsNotNullOrWhiteSpace() == true)
|
if (downloadClientItem?.DownloadId.IsNotNullOrWhiteSpace() == true)
|
||||||
{
|
{
|
||||||
var grabHistory = _historyService.FindByDownloadId(downloadClientItem.DownloadId)
|
var grabHistory = _historyService.FindByDownloadId(downloadClientItem.DownloadId)
|
||||||
|
@ -107,12 +112,27 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
{
|
{
|
||||||
episodeFile.IndexerFlags = flags;
|
episodeFile.IndexerFlags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prefer the release type from the grabbed history
|
||||||
|
if (Enum.TryParse(grabHistory?.Data.GetValueOrDefault("releaseType"), true, out ReleaseType releaseType))
|
||||||
|
{
|
||||||
|
episodeFile.ReleaseType = releaseType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
episodeFile.IndexerFlags = localEpisode.IndexerFlags;
|
episodeFile.IndexerFlags = localEpisode.IndexerFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fall back to parsed information if history is unavailable or missing
|
||||||
|
if (episodeFile.ReleaseType == ReleaseType.Unknown)
|
||||||
|
{
|
||||||
|
// Prefer the release type from the download client, folder and finally the file so we have the most accurate information.
|
||||||
|
episodeFile.ReleaseType = localEpisode.DownloadClientEpisodeInfo?.ReleaseType ??
|
||||||
|
localEpisode.FolderEpisodeInfo?.ReleaseType ??
|
||||||
|
localEpisode.FileEpisodeInfo.ReleaseType;
|
||||||
|
}
|
||||||
|
|
||||||
bool copyOnly;
|
bool copyOnly;
|
||||||
switch (importMode)
|
switch (importMode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -119,6 +119,10 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
|
|
||||||
localEpisode.FileEpisodeInfo = fileEpisodeInfo;
|
localEpisode.FileEpisodeInfo = fileEpisodeInfo;
|
||||||
localEpisode.Size = _diskProvider.GetFileSize(localEpisode.Path);
|
localEpisode.Size = _diskProvider.GetFileSize(localEpisode.Path);
|
||||||
|
localEpisode.ReleaseType = localEpisode.DownloadClientEpisodeInfo?.ReleaseType ??
|
||||||
|
localEpisode.FolderEpisodeInfo?.ReleaseType ??
|
||||||
|
localEpisode.FileEpisodeInfo?.ReleaseType ??
|
||||||
|
ReleaseType.Unknown;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.Languages;
|
using NzbDrone.Core.Languages;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
|
@ -17,6 +18,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
public List<Language> Languages { get; set; }
|
public List<Language> Languages { get; set; }
|
||||||
public string ReleaseGroup { get; set; }
|
public string ReleaseGroup { get; set; }
|
||||||
public int IndexerFlags { get; set; }
|
public int IndexerFlags { get; set; }
|
||||||
|
public ReleaseType ReleaseType { get; set; }
|
||||||
public string DownloadId { get; set; }
|
public string DownloadId { get; set; }
|
||||||
|
|
||||||
public bool Equals(ManualImportFile other)
|
public bool Equals(ManualImportFile other)
|
||||||
|
|
|
@ -2,6 +2,7 @@ using System.Collections.Generic;
|
||||||
using NzbDrone.Core.CustomFormats;
|
using NzbDrone.Core.CustomFormats;
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Languages;
|
using NzbDrone.Core.Languages;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
public List<CustomFormat> CustomFormats { get; set; }
|
public List<CustomFormat> CustomFormats { get; set; }
|
||||||
public int CustomFormatScore { get; set; }
|
public int CustomFormatScore { get; set; }
|
||||||
public int IndexerFlags { get; set; }
|
public int IndexerFlags { get; set; }
|
||||||
|
public ReleaseType ReleaseType { get; set; }
|
||||||
public IEnumerable<Rejection> Rejections { get; set; }
|
public IEnumerable<Rejection> Rejections { get; set; }
|
||||||
|
|
||||||
public ManualImportItem()
|
public ManualImportItem()
|
||||||
|
|
|
@ -425,6 +425,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
item.Size = _diskProvider.GetFileSize(decision.LocalEpisode.Path);
|
item.Size = _diskProvider.GetFileSize(decision.LocalEpisode.Path);
|
||||||
item.Rejections = decision.Rejections;
|
item.Rejections = decision.Rejections;
|
||||||
item.IndexerFlags = (int)decision.LocalEpisode.IndexerFlags;
|
item.IndexerFlags = (int)decision.LocalEpisode.IndexerFlags;
|
||||||
|
item.ReleaseType = decision.LocalEpisode.ReleaseType;
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
@ -444,6 +445,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
item.Quality = episodeFile.Quality;
|
item.Quality = episodeFile.Quality;
|
||||||
item.Languages = episodeFile.Languages;
|
item.Languages = episodeFile.Languages;
|
||||||
item.IndexerFlags = (int)episodeFile.IndexerFlags;
|
item.IndexerFlags = (int)episodeFile.IndexerFlags;
|
||||||
|
item.ReleaseType = episodeFile.ReleaseType;
|
||||||
item.Size = _diskProvider.GetFileSize(item.Path);
|
item.Size = _diskProvider.GetFileSize(item.Path);
|
||||||
item.Rejections = Enumerable.Empty<Rejection>();
|
item.Rejections = Enumerable.Empty<Rejection>();
|
||||||
item.EpisodeFileId = episodeFile.Id;
|
item.EpisodeFileId = episodeFile.Id;
|
||||||
|
@ -481,6 +483,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
Quality = file.Quality,
|
Quality = file.Quality,
|
||||||
Languages = file.Languages,
|
Languages = file.Languages,
|
||||||
IndexerFlags = (IndexerFlags)file.IndexerFlags,
|
IndexerFlags = (IndexerFlags)file.IndexerFlags,
|
||||||
|
ReleaseType = file.ReleaseType,
|
||||||
Series = series,
|
Series = series,
|
||||||
Size = 0
|
Size = 0
|
||||||
};
|
};
|
||||||
|
@ -510,6 +513,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
localEpisode.Quality = file.Quality;
|
localEpisode.Quality = file.Quality;
|
||||||
localEpisode.Languages = file.Languages;
|
localEpisode.Languages = file.Languages;
|
||||||
localEpisode.IndexerFlags = (IndexerFlags)file.IndexerFlags;
|
localEpisode.IndexerFlags = (IndexerFlags)file.IndexerFlags;
|
||||||
|
localEpisode.ReleaseType = file.ReleaseType;
|
||||||
|
|
||||||
// TODO: Cleanup non-tracked downloads
|
// TODO: Cleanup non-tracked downloads
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ namespace NzbDrone.Core.Parser.Model
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
public List<Language> Languages { get; set; }
|
public List<Language> Languages { get; set; }
|
||||||
public IndexerFlags IndexerFlags { get; set; }
|
public IndexerFlags IndexerFlags { get; set; }
|
||||||
|
public ReleaseType ReleaseType { get; set; }
|
||||||
public MediaInfoModel MediaInfo { get; set; }
|
public MediaInfoModel MediaInfo { get; set; }
|
||||||
public bool ExistingFile { get; set; }
|
public bool ExistingFile { get; set; }
|
||||||
public bool SceneSource { get; set; }
|
public bool SceneSource { get; set; }
|
||||||
|
|
|
@ -90,6 +90,29 @@ namespace NzbDrone.Core.Parser.Model
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ReleaseType ReleaseType
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (EpisodeNumbers.Length > 1 || AbsoluteEpisodeNumbers.Length > 1)
|
||||||
|
{
|
||||||
|
return Model.ReleaseType.MultiEpisode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EpisodeNumbers.Length == 1 || AbsoluteEpisodeNumbers.Length == 1)
|
||||||
|
{
|
||||||
|
return Model.ReleaseType.SingleEpisode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FullSeason)
|
||||||
|
{
|
||||||
|
return Model.ReleaseType.SeasonPack;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Model.ReleaseType.Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
var episodeString = "[Unknown Episode]";
|
var episodeString = "[Unknown Episode]";
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -209,6 +209,11 @@ namespace Sonarr.Api.V3.EpisodeFiles
|
||||||
{
|
{
|
||||||
episodeFile.IndexerFlags = (IndexerFlags)resourceEpisodeFile.IndexerFlags;
|
episodeFile.IndexerFlags = (IndexerFlags)resourceEpisodeFile.IndexerFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (resourceEpisodeFile.ReleaseType != null)
|
||||||
|
{
|
||||||
|
episodeFile.ReleaseType = (ReleaseType)resourceEpisodeFile.ReleaseType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_mediaFileService.Update(episodeFiles);
|
_mediaFileService.Update(episodeFiles);
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace Sonarr.Api.V3.EpisodeFiles
|
||||||
public List<CustomFormatResource> CustomFormats { get; set; }
|
public List<CustomFormatResource> CustomFormats { get; set; }
|
||||||
public int CustomFormatScore { get; set; }
|
public int CustomFormatScore { get; set; }
|
||||||
public int? IndexerFlags { get; set; }
|
public int? IndexerFlags { get; set; }
|
||||||
|
public int? ReleaseType { get; set; }
|
||||||
public MediaInfoResource MediaInfo { get; set; }
|
public MediaInfoResource MediaInfo { get; set; }
|
||||||
|
|
||||||
public bool QualityCutoffNotMet { get; set; }
|
public bool QualityCutoffNotMet { get; set; }
|
||||||
|
@ -33,34 +34,6 @@ namespace Sonarr.Api.V3.EpisodeFiles
|
||||||
|
|
||||||
public static class EpisodeFileResourceMapper
|
public static class EpisodeFileResourceMapper
|
||||||
{
|
{
|
||||||
private static EpisodeFileResource ToResource(this EpisodeFile model)
|
|
||||||
{
|
|
||||||
if (model == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new EpisodeFileResource
|
|
||||||
{
|
|
||||||
Id = model.Id,
|
|
||||||
|
|
||||||
SeriesId = model.SeriesId,
|
|
||||||
SeasonNumber = model.SeasonNumber,
|
|
||||||
RelativePath = model.RelativePath,
|
|
||||||
|
|
||||||
// Path
|
|
||||||
Size = model.Size,
|
|
||||||
DateAdded = model.DateAdded,
|
|
||||||
SceneName = model.SceneName,
|
|
||||||
ReleaseGroup = model.ReleaseGroup,
|
|
||||||
Languages = model.Languages,
|
|
||||||
Quality = model.Quality,
|
|
||||||
MediaInfo = model.MediaInfo.ToResource(model.SceneName)
|
|
||||||
|
|
||||||
// QualityCutoffNotMet
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EpisodeFileResource ToResource(this EpisodeFile model, NzbDrone.Core.Tv.Series series, IUpgradableSpecification upgradableSpecification, ICustomFormatCalculationService formatCalculationService)
|
public static EpisodeFileResource ToResource(this EpisodeFile model, NzbDrone.Core.Tv.Series series, IUpgradableSpecification upgradableSpecification, ICustomFormatCalculationService formatCalculationService)
|
||||||
{
|
{
|
||||||
if (model == null)
|
if (model == null)
|
||||||
|
@ -90,7 +63,8 @@ namespace Sonarr.Api.V3.EpisodeFiles
|
||||||
QualityCutoffNotMet = upgradableSpecification.QualityCutoffNotMet(series.QualityProfile.Value, model.Quality),
|
QualityCutoffNotMet = upgradableSpecification.QualityCutoffNotMet(series.QualityProfile.Value, model.Quality),
|
||||||
CustomFormats = customFormats.ToResource(false),
|
CustomFormats = customFormats.ToResource(false),
|
||||||
CustomFormatScore = customFormatScore,
|
CustomFormatScore = customFormatScore,
|
||||||
IndexerFlags = (int)model.IndexerFlags
|
IndexerFlags = (int)model.IndexerFlags,
|
||||||
|
ReleaseType = (int)model.ReleaseType,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ using NzbDrone.Common.Crypto;
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Languages;
|
using NzbDrone.Core.Languages;
|
||||||
using NzbDrone.Core.MediaFiles.EpisodeImport.Manual;
|
using NzbDrone.Core.MediaFiles.EpisodeImport.Manual;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using Sonarr.Api.V3.CustomFormats;
|
using Sonarr.Api.V3.CustomFormats;
|
||||||
using Sonarr.Api.V3.Episodes;
|
using Sonarr.Api.V3.Episodes;
|
||||||
|
@ -31,6 +32,7 @@ namespace Sonarr.Api.V3.ManualImport
|
||||||
public List<CustomFormatResource> CustomFormats { get; set; }
|
public List<CustomFormatResource> CustomFormats { get; set; }
|
||||||
public int CustomFormatScore { get; set; }
|
public int CustomFormatScore { get; set; }
|
||||||
public int IndexerFlags { get; set; }
|
public int IndexerFlags { get; set; }
|
||||||
|
public ReleaseType ReleaseType { get; set; }
|
||||||
public IEnumerable<Rejection> Rejections { get; set; }
|
public IEnumerable<Rejection> Rejections { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +69,7 @@ namespace Sonarr.Api.V3.ManualImport
|
||||||
// QualityWeight
|
// QualityWeight
|
||||||
DownloadId = model.DownloadId,
|
DownloadId = model.DownloadId,
|
||||||
IndexerFlags = model.IndexerFlags,
|
IndexerFlags = model.IndexerFlags,
|
||||||
|
ReleaseType = model.ReleaseType,
|
||||||
Rejections = model.Rejections
|
Rejections = model.Rejections
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue