mirror of
https://github.com/Radarr/Radarr.git
synced 2024-09-17 15:02:34 +02:00
parent
fa60c28e9c
commit
8799da55d3
@ -0,0 +1,174 @@
|
|||||||
|
using System.Security.Policy;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Datastore.Migration;
|
||||||
|
using NzbDrone.Core.NetImport.RadarrList;
|
||||||
|
using NzbDrone.Core.NetImport.RadarrList2.IMDbList;
|
||||||
|
using NzbDrone.Core.NetImport.RadarrList2.StevenLu;
|
||||||
|
using NzbDrone.Core.NetImport.StevenLu;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class new_list_serverFixture : MigrationTest<new_list_server>
|
||||||
|
{
|
||||||
|
private JsonSerializerOptions _serializerSettings;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_serializerSettings = new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
AllowTrailingCommas = true,
|
||||||
|
IgnoreNullValues = false,
|
||||||
|
PropertyNameCaseInsensitive = true,
|
||||||
|
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||||
|
WriteIndented = true
|
||||||
|
};
|
||||||
|
|
||||||
|
_serializerSettings.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("https://api.radarr.video/v2")]
|
||||||
|
[TestCase("https://staging.api.radarr.video")]
|
||||||
|
public void should_switch_some_radarr_to_imdb(string url)
|
||||||
|
{
|
||||||
|
var db = WithMigrationTestDb(c =>
|
||||||
|
{
|
||||||
|
var rows = Builder<new_list_server.NetImportDefinition178>.CreateListOfSize(6)
|
||||||
|
.All()
|
||||||
|
.With(x => x.Implementation = typeof(RadarrListImport).Name)
|
||||||
|
.With(x => x.ConfigContract = typeof(RadarrListSettings).Name)
|
||||||
|
.TheFirst(1)
|
||||||
|
.With(x => x.Settings = JsonSerializer.Serialize(new new_list_server.RadarrListSettings177
|
||||||
|
{
|
||||||
|
APIURL = url,
|
||||||
|
Path = "/imdb/top250"
|
||||||
|
}, _serializerSettings))
|
||||||
|
.TheNext(1)
|
||||||
|
.With(x => x.Settings = JsonSerializer.Serialize(new new_list_server.RadarrListSettings177
|
||||||
|
{
|
||||||
|
APIURL = url,
|
||||||
|
Path = "/imdb/popular"
|
||||||
|
}, _serializerSettings))
|
||||||
|
.TheNext(1)
|
||||||
|
.With(x => x.Settings = JsonSerializer.Serialize(new new_list_server.RadarrListSettings177
|
||||||
|
{
|
||||||
|
APIURL = url,
|
||||||
|
Path = "/imdb/missing"
|
||||||
|
}, _serializerSettings))
|
||||||
|
.TheNext(1)
|
||||||
|
.With(x => x.Settings = JsonSerializer.Serialize(new new_list_server.RadarrListSettings177
|
||||||
|
{
|
||||||
|
APIURL = url,
|
||||||
|
Path = "/imdb/list?listId=ls001"
|
||||||
|
}, _serializerSettings))
|
||||||
|
.TheNext(1)
|
||||||
|
.With(x => x.Settings = JsonSerializer.Serialize(new new_list_server.RadarrListSettings177
|
||||||
|
{
|
||||||
|
APIURL = url,
|
||||||
|
Path = "/imdb/list?listId=ls00ad"
|
||||||
|
}, _serializerSettings))
|
||||||
|
.TheNext(1)
|
||||||
|
.With(x => x.Settings = JsonSerializer.Serialize(new new_list_server.RadarrListSettings177
|
||||||
|
{
|
||||||
|
APIURL = url,
|
||||||
|
Path = "/imdb/list?listId=ur002"
|
||||||
|
}, _serializerSettings))
|
||||||
|
.BuildListOfNew();
|
||||||
|
|
||||||
|
var i = 1;
|
||||||
|
foreach (var row in rows)
|
||||||
|
{
|
||||||
|
row.Id = i++;
|
||||||
|
c.Insert.IntoTable("NetImport").Row(row);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var items = db.Query<new_list_server.NetImportDefinition178>("SELECT * FROM NetImport");
|
||||||
|
|
||||||
|
items.Should().HaveCount(6);
|
||||||
|
|
||||||
|
VerifyRow(items[0], typeof(IMDbListImport).Name, typeof(IMDbListSettings).Name, new IMDbListSettings { ListId = "top250" });
|
||||||
|
VerifyRow(items[1], typeof(IMDbListImport).Name, typeof(IMDbListSettings).Name, new IMDbListSettings { ListId = "popular" });
|
||||||
|
VerifyRow(items[2], typeof(RadarrListImport).Name, typeof(RadarrListSettings).Name, new RadarrListSettings { Url = url + "/imdb/missing" });
|
||||||
|
VerifyRow(items[3], typeof(IMDbListImport).Name, typeof(IMDbListSettings).Name, new IMDbListSettings { ListId = "ls001" });
|
||||||
|
VerifyRow(items[4], typeof(RadarrListImport).Name, typeof(RadarrListSettings).Name, new RadarrListSettings { Url = url + "/imdb/list?listId=ls00ad" });
|
||||||
|
VerifyRow(items[5], typeof(IMDbListImport).Name, typeof(IMDbListSettings).Name, new IMDbListSettings { ListId = "ur002" });
|
||||||
|
}
|
||||||
|
|
||||||
|
public void should_switch_some_stevenlu_stevenlu2()
|
||||||
|
{
|
||||||
|
var rows = Builder<new_list_server.NetImportDefinition178>.CreateListOfSize(6)
|
||||||
|
.All()
|
||||||
|
.With(x => x.Implementation = typeof(StevenLuImport).Name)
|
||||||
|
.With(x => x.ConfigContract = typeof(StevenLuSettings).Name)
|
||||||
|
.TheFirst(1)
|
||||||
|
.With(x => x.Settings = JsonSerializer.Serialize(new new_list_server.StevenLuSettings178
|
||||||
|
{
|
||||||
|
Link = "https://s3.amazonaws.com/popular-movies/movies.json"
|
||||||
|
}, _serializerSettings))
|
||||||
|
.TheNext(1)
|
||||||
|
.With(x => x.Settings = JsonSerializer.Serialize(new new_list_server.StevenLuSettings178
|
||||||
|
{
|
||||||
|
Link = "https://s3.amazonaws.com/popular-movies/movies-metacritic-min50.json"
|
||||||
|
}, _serializerSettings))
|
||||||
|
.TheNext(1)
|
||||||
|
.With(x => x.Settings = JsonSerializer.Serialize(new new_list_server.StevenLuSettings178
|
||||||
|
{
|
||||||
|
Link = "https://s3.amazonaws.com/popular-movies/movies-imdb-min8.json"
|
||||||
|
}, _serializerSettings))
|
||||||
|
.TheNext(1)
|
||||||
|
.With(x => x.Settings = JsonSerializer.Serialize(new new_list_server.StevenLuSettings178
|
||||||
|
{
|
||||||
|
Link = "https://s3.amazonaws.com/popular-movies/movies-rottentomatoes-min70.json"
|
||||||
|
}, _serializerSettings))
|
||||||
|
.TheNext(1)
|
||||||
|
.With(x => x.Settings = JsonSerializer.Serialize(new new_list_server.StevenLuSettings178
|
||||||
|
{
|
||||||
|
Link = "https://s3.amazonaws.com/popular-movies/movies-min70.json"
|
||||||
|
}, _serializerSettings))
|
||||||
|
.TheNext(1)
|
||||||
|
.With(x => x.Settings = JsonSerializer.Serialize(new new_list_server.StevenLuSettings178
|
||||||
|
{
|
||||||
|
Link = "https://aapjeisbaas.nl/api/v1/popular-movies/imdb?fresh=True&max=20&rating=6&votes=50000"
|
||||||
|
}, _serializerSettings))
|
||||||
|
.BuildListOfNew();
|
||||||
|
|
||||||
|
var db = WithMigrationTestDb(c =>
|
||||||
|
{
|
||||||
|
var i = 1;
|
||||||
|
foreach (var row in rows)
|
||||||
|
{
|
||||||
|
row.Id = i++;
|
||||||
|
c.Insert.IntoTable("NetImport").Row(row);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var items = db.Query<new_list_server.NetImportDefinition178>("SELECT * FROM NetImport");
|
||||||
|
|
||||||
|
items.Should().HaveCount(5);
|
||||||
|
|
||||||
|
VerifyRow(items[0], typeof(StevenLu2Import).Name, typeof(StevenLu2Import).Name, new StevenLu2Settings { Source = (int)StevenLuSource.Standard, MinScore = 5 });
|
||||||
|
VerifyRow(items[1], typeof(StevenLu2Import).Name, typeof(StevenLu2Import).Name, new StevenLu2Settings { Source = (int)StevenLuSource.Metacritic, MinScore = 5 });
|
||||||
|
VerifyRow(items[2], typeof(StevenLu2Import).Name, typeof(StevenLu2Import).Name, new StevenLu2Settings { Source = (int)StevenLuSource.Imdb, MinScore = 8 });
|
||||||
|
VerifyRow(items[3], typeof(StevenLu2Import).Name, typeof(StevenLu2Import).Name, new StevenLu2Settings { Source = (int)StevenLuSource.RottenTomatoes, MinScore = 7 });
|
||||||
|
|
||||||
|
// Bad formats so should not get changed
|
||||||
|
VerifyRow(items[4], rows[4].Implementation, rows[4].ConfigContract, rows[4].Settings);
|
||||||
|
VerifyRow(items[5], rows[5].Implementation, rows[5].ConfigContract, rows[5].Settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void VerifyRow(new_list_server.NetImportDefinition178 row, string impl, string config, object settings)
|
||||||
|
{
|
||||||
|
row.Implementation.Should().Be(impl);
|
||||||
|
row.ConfigContract.Should().Be(config);
|
||||||
|
row.Settings.Should().Be(JsonSerializer.Serialize(settings, _serializerSettings));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
221
src/NzbDrone.Core/Datastore/Migration/178_new_list_server.cs
Normal file
221
src/NzbDrone.Core/Datastore/Migration/178_new_list_server.cs
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Dapper;
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(178)]
|
||||||
|
public class new_list_server : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
private static readonly Regex ImdbIdRegex = new Regex(@"^/?imdb/list\?listId=(?<id>(ls|ur)\d+)$",
|
||||||
|
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
private readonly JsonSerializerOptions _serializerSettings;
|
||||||
|
|
||||||
|
public new_list_server()
|
||||||
|
{
|
||||||
|
_serializerSettings = new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
AllowTrailingCommas = true,
|
||||||
|
IgnoreNullValues = false,
|
||||||
|
PropertyNameCaseInsensitive = true,
|
||||||
|
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||||
|
WriteIndented = true
|
||||||
|
};
|
||||||
|
|
||||||
|
_serializerSettings.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Execute.WithConnection(FixRadarrLists);
|
||||||
|
Execute.WithConnection(FixStevenLuLists);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FixRadarrLists(IDbConnection conn, IDbTransaction tran)
|
||||||
|
{
|
||||||
|
var rows = conn.Query<NetImportDefinition178>($"SELECT * FROM NetImport WHERE ConfigContract = 'RadarrListSettings'");
|
||||||
|
|
||||||
|
var radarrUrls = new List<string>
|
||||||
|
{
|
||||||
|
"https://api.radarr.video/v2",
|
||||||
|
"https://staging.api.radarr.video"
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var row in rows)
|
||||||
|
{
|
||||||
|
var settings = JsonSerializer.Deserialize<RadarrListSettings177>(row.Settings, _serializerSettings);
|
||||||
|
object newSettings;
|
||||||
|
|
||||||
|
if (!radarrUrls.Contains(settings.APIURL))
|
||||||
|
{
|
||||||
|
// Combine root and path in new settings
|
||||||
|
newSettings = new RadarrListSettings178
|
||||||
|
{
|
||||||
|
Url = settings.APIURL.TrimEnd('/') + '/' + settings.Path.TrimStart('/')
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// It should be an imdb list
|
||||||
|
if (settings.Path == "/imdb/top250")
|
||||||
|
{
|
||||||
|
newSettings = new IMDbListSettings178
|
||||||
|
{
|
||||||
|
ListId = "top250"
|
||||||
|
};
|
||||||
|
row.ConfigContract = "IMDbListSettings";
|
||||||
|
row.Implementation = "IMDbListImport";
|
||||||
|
}
|
||||||
|
else if (settings.Path == "/imdb/popular")
|
||||||
|
{
|
||||||
|
newSettings = new IMDbListSettings178
|
||||||
|
{
|
||||||
|
ListId = "popular"
|
||||||
|
};
|
||||||
|
row.ConfigContract = "IMDbListSettings";
|
||||||
|
row.Implementation = "IMDbListImport";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var match = ImdbIdRegex.Match(settings.Path);
|
||||||
|
if (match.Success)
|
||||||
|
{
|
||||||
|
newSettings = new IMDbListSettings178
|
||||||
|
{
|
||||||
|
ListId = match.Groups["id"].Value
|
||||||
|
};
|
||||||
|
row.ConfigContract = "IMDbListSettings";
|
||||||
|
row.Implementation = "IMDbListImport";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newSettings = new RadarrListSettings178
|
||||||
|
{
|
||||||
|
Url = settings.APIURL.TrimEnd('/') + '/' + settings.Path.TrimStart('/')
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
row.Settings = JsonSerializer.Serialize(newSettings, _serializerSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
var updateSql = "UPDATE NetImport SET Implementation = @Implementation, " +
|
||||||
|
"ConfigContract = @ConfigContract, " +
|
||||||
|
"Settings = @Settings " +
|
||||||
|
"WHERE Id = @Id";
|
||||||
|
|
||||||
|
conn.Execute(updateSql, rows, transaction: tran);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FixStevenLuLists(IDbConnection conn, IDbTransaction tran)
|
||||||
|
{
|
||||||
|
var rows = conn.Query<NetImportDefinition178>($"SELECT * FROM NetImport WHERE ConfigContract = 'StevenLuSettings'");
|
||||||
|
|
||||||
|
var updated = new List<NetImportDefinition178>();
|
||||||
|
|
||||||
|
var scores = new[] { 5, 6, 7, 8, 50, 60, 70, 80 };
|
||||||
|
|
||||||
|
foreach (var row in rows)
|
||||||
|
{
|
||||||
|
var settings = JsonSerializer.Deserialize<StevenLuSettings178>(row.Settings, _serializerSettings);
|
||||||
|
|
||||||
|
if (settings.Link.StartsWith("https://s3.amazonaws.com/popular-movies"))
|
||||||
|
{
|
||||||
|
var newSettings = new StevenLu2Settings178();
|
||||||
|
|
||||||
|
// convert to 2
|
||||||
|
if (settings.Link == "https://s3.amazonaws.com/popular-movies/movies.json")
|
||||||
|
{
|
||||||
|
newSettings.Source = (int)StevenLuSource178.Standard;
|
||||||
|
newSettings.MinScore = 5;
|
||||||
|
updated.Add(row);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var split = settings.Link.Split('/').Last().Split('-');
|
||||||
|
if (split.Length == 3 &&
|
||||||
|
split[0] == "movies" &&
|
||||||
|
Enum.TryParse(split[1], out StevenLuSource178 source) &&
|
||||||
|
int.TryParse(split[2], out var score) &&
|
||||||
|
scores.Contains(score))
|
||||||
|
{
|
||||||
|
newSettings.Source = (int)source;
|
||||||
|
newSettings.MinScore = source == StevenLuSource178.Imdb ? score : score / 10;
|
||||||
|
updated.Add(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
row.ConfigContract = "StevenLu2Settings";
|
||||||
|
row.Implementation = "StevenLu2Import";
|
||||||
|
row.Settings = JsonSerializer.Serialize(newSettings, _serializerSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var updateSql = "UPDATE NetImport SET Implementation = @Implementation, " +
|
||||||
|
"ConfigContract = @ConfigContract, " +
|
||||||
|
"Settings = @Settings " +
|
||||||
|
"WHERE Id = @Id";
|
||||||
|
conn.Execute(updateSql, updated, transaction: tran);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NetImportDefinition178 : ModelBase
|
||||||
|
{
|
||||||
|
public bool Enabled { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Implementation { get; set; }
|
||||||
|
public string ConfigContract { get; set; }
|
||||||
|
public string Settings { get; set; }
|
||||||
|
public bool EnableAuto { get; set; }
|
||||||
|
public string RootFolderPath { get; set; }
|
||||||
|
public bool ShouldMonitor { get; set; }
|
||||||
|
public int ProfileId { get; set; }
|
||||||
|
public int MinimumAvailability { get; set; }
|
||||||
|
public string Tags { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RadarrListSettings177
|
||||||
|
{
|
||||||
|
public string APIURL { get; set; }
|
||||||
|
public string Path { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RadarrListSettings178
|
||||||
|
{
|
||||||
|
public string Url { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IMDbListSettings178
|
||||||
|
{
|
||||||
|
public string ListId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class StevenLuSettings178
|
||||||
|
{
|
||||||
|
public string Link { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class StevenLu2Settings178
|
||||||
|
{
|
||||||
|
public int Source { get; set; }
|
||||||
|
|
||||||
|
public int MinScore { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum StevenLuSource178
|
||||||
|
{
|
||||||
|
Standard,
|
||||||
|
Imdb,
|
||||||
|
Metacritic,
|
||||||
|
RottenTomatoes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ public enum NetImportType
|
|||||||
Program,
|
Program,
|
||||||
TMDB,
|
TMDB,
|
||||||
Trakt,
|
Trakt,
|
||||||
Other
|
Other,
|
||||||
|
Advanced
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,9 @@ namespace NzbDrone.Core.NetImport.RSSImport
|
|||||||
{
|
{
|
||||||
public class RSSImport : HttpNetImportBase<RSSImportSettings>
|
public class RSSImport : HttpNetImportBase<RSSImportSettings>
|
||||||
{
|
{
|
||||||
public override string Name => "RSSList";
|
public override string Name => "RSS List";
|
||||||
|
|
||||||
public override NetImportType ListType => NetImportType.Other;
|
public override NetImportType ListType => NetImportType.Advanced;
|
||||||
public override bool Enabled => true;
|
public override bool Enabled => true;
|
||||||
public override bool EnableAuto => false;
|
public override bool EnableAuto => false;
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@ namespace NzbDrone.Core.NetImport.RadarrList
|
|||||||
{
|
{
|
||||||
public class RadarrListImport : HttpNetImportBase<RadarrListSettings>
|
public class RadarrListImport : HttpNetImportBase<RadarrListSettings>
|
||||||
{
|
{
|
||||||
public override string Name => "Radarr Lists";
|
public override string Name => "Custom Lists";
|
||||||
|
|
||||||
public override NetImportType ListType => NetImportType.Other;
|
public override NetImportType ListType => NetImportType.Advanced;
|
||||||
public override bool Enabled => true;
|
public override bool Enabled => true;
|
||||||
public override bool EnableAuto => false;
|
public override bool EnableAuto => false;
|
||||||
|
|
||||||
@ -32,34 +32,6 @@ public override IEnumerable<ProviderDefinition> DefaultDefinitions
|
|||||||
{
|
{
|
||||||
yield return def;
|
yield return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
yield return new NetImportDefinition
|
|
||||||
{
|
|
||||||
Name = "IMDb Top 250",
|
|
||||||
Enabled = Enabled,
|
|
||||||
EnableAuto = true,
|
|
||||||
ProfileId = 1,
|
|
||||||
Implementation = GetType().Name,
|
|
||||||
Settings = new RadarrListSettings { Path = "/imdb/top250" },
|
|
||||||
};
|
|
||||||
yield return new NetImportDefinition
|
|
||||||
{
|
|
||||||
Name = "IMDb Popular Movies",
|
|
||||||
Enabled = Enabled,
|
|
||||||
EnableAuto = true,
|
|
||||||
ProfileId = 1,
|
|
||||||
Implementation = GetType().Name,
|
|
||||||
Settings = new RadarrListSettings { Path = "/imdb/popular" },
|
|
||||||
};
|
|
||||||
yield return new NetImportDefinition
|
|
||||||
{
|
|
||||||
Name = "IMDb List",
|
|
||||||
Enabled = Enabled,
|
|
||||||
EnableAuto = true,
|
|
||||||
ProfileId = 1,
|
|
||||||
Implementation = GetType().Name,
|
|
||||||
Settings = new RadarrListSettings { Path = "/imdb/list?listId=LISTID" },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,20 +12,11 @@ public class RadarrListRequestGenerator : INetImportRequestGenerator
|
|||||||
public IHttpClient HttpClient { get; set; }
|
public IHttpClient HttpClient { get; set; }
|
||||||
public Logger Logger { get; set; }
|
public Logger Logger { get; set; }
|
||||||
|
|
||||||
public int MaxPages { get; set; }
|
|
||||||
|
|
||||||
public RadarrListRequestGenerator()
|
|
||||||
{
|
|
||||||
MaxPages = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual NetImportPageableRequestChain GetMovies()
|
public virtual NetImportPageableRequestChain GetMovies()
|
||||||
{
|
{
|
||||||
var pageableRequests = new NetImportPageableRequestChain();
|
var pageableRequests = new NetImportPageableRequestChain();
|
||||||
|
|
||||||
var baseUrl = $"{Settings.APIURL.TrimEnd("/")}";
|
var request = new NetImportRequest(Settings.Url, HttpAccept.Json);
|
||||||
|
|
||||||
var request = new NetImportRequest($"{baseUrl}{Settings.Path}", HttpAccept.Json);
|
|
||||||
|
|
||||||
request.HttpRequest.SuppressHttpError = true;
|
request.HttpRequest.SuppressHttpError = true;
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ public class RadarrSettingsValidator : AbstractValidator<RadarrListSettings>
|
|||||||
{
|
{
|
||||||
public RadarrSettingsValidator()
|
public RadarrSettingsValidator()
|
||||||
{
|
{
|
||||||
RuleFor(c => c.APIURL).ValidRootUrl();
|
RuleFor(c => c.Url).ValidRootUrl();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,17 +17,8 @@ public class RadarrListSettings : IProviderConfig
|
|||||||
{
|
{
|
||||||
private static readonly RadarrSettingsValidator Validator = new RadarrSettingsValidator();
|
private static readonly RadarrSettingsValidator Validator = new RadarrSettingsValidator();
|
||||||
|
|
||||||
public RadarrListSettings()
|
[FieldDefinition(0, Label = "List URL", HelpText = "The URL for the movie list")]
|
||||||
{
|
public string Url { get; set; }
|
||||||
APIURL = "https://api.radarr.video/v2";
|
|
||||||
Path = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
[FieldDefinition(0, Label = "Radarr API URL", HelpText = "Link to to Radarr API URL. Use https://staging.api.radarr.video if you are on nightly.")]
|
|
||||||
public string APIURL { get; set; }
|
|
||||||
|
|
||||||
[FieldDefinition(1, Label = "Path to list", HelpText = "Path to the list proxied by the Radarr API. Check the wiki for available lists.")]
|
|
||||||
public string Path { get; set; }
|
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Cloud;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.NetImport.RadarrList2.IMDbList
|
||||||
|
{
|
||||||
|
public class IMDbListImport : HttpNetImportBase<IMDbListSettings>
|
||||||
|
{
|
||||||
|
private readonly IHttpRequestBuilderFactory _radarrMetadata;
|
||||||
|
|
||||||
|
public override string Name => "IMDb Lists";
|
||||||
|
|
||||||
|
public override NetImportType ListType => NetImportType.Other;
|
||||||
|
public override bool Enabled => true;
|
||||||
|
public override bool EnableAuto => false;
|
||||||
|
|
||||||
|
public IMDbListImport(IRadarrCloudRequestBuilder requestBuilder,
|
||||||
|
IHttpClient httpClient,
|
||||||
|
INetImportStatusService netImportStatusService,
|
||||||
|
IConfigService configService,
|
||||||
|
IParsingService parsingService,
|
||||||
|
Logger logger)
|
||||||
|
: base(httpClient, netImportStatusService, configService, parsingService, logger)
|
||||||
|
{
|
||||||
|
_radarrMetadata = requestBuilder.RadarrMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<ProviderDefinition> DefaultDefinitions
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
foreach (var def in base.DefaultDefinitions)
|
||||||
|
{
|
||||||
|
yield return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield return new NetImportDefinition
|
||||||
|
{
|
||||||
|
Name = "IMDb Top 250",
|
||||||
|
Enabled = Enabled,
|
||||||
|
EnableAuto = true,
|
||||||
|
ProfileId = 1,
|
||||||
|
Implementation = GetType().Name,
|
||||||
|
Settings = new IMDbListSettings { ListId = "top250" },
|
||||||
|
};
|
||||||
|
yield return new NetImportDefinition
|
||||||
|
{
|
||||||
|
Name = "IMDb Popular Movies",
|
||||||
|
Enabled = Enabled,
|
||||||
|
EnableAuto = true,
|
||||||
|
ProfileId = 1,
|
||||||
|
Implementation = GetType().Name,
|
||||||
|
Settings = new IMDbListSettings { ListId = "popular" },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override INetImportRequestGenerator GetRequestGenerator()
|
||||||
|
{
|
||||||
|
return new IMDbListRequestGenerator()
|
||||||
|
{
|
||||||
|
Settings = Settings,
|
||||||
|
Logger = _logger,
|
||||||
|
HttpClient = _httpClient,
|
||||||
|
RequestBuilder = _radarrMetadata
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IParseNetImportResponse GetParser()
|
||||||
|
{
|
||||||
|
return new RadarrList2Parser();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
using NzbDrone.Common.Http;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.NetImport.RadarrList2.IMDbList
|
||||||
|
{
|
||||||
|
public class IMDbListRequestGenerator : RadarrList2RequestGeneratorBase
|
||||||
|
{
|
||||||
|
public IMDbListSettings Settings { get; set; }
|
||||||
|
|
||||||
|
protected override HttpRequest GetHttpRequest()
|
||||||
|
{
|
||||||
|
return RequestBuilder.Create()
|
||||||
|
.SetSegment("route", $"list/imdb/{Settings.ListId}")
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
using FluentValidation;
|
||||||
|
using NzbDrone.Core.Annotations;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
using NzbDrone.Core.Validation;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.NetImport.RadarrList2.IMDbList
|
||||||
|
{
|
||||||
|
public class IMDbSettingsValidator : AbstractValidator<IMDbListSettings>
|
||||||
|
{
|
||||||
|
public IMDbSettingsValidator()
|
||||||
|
{
|
||||||
|
RuleFor(c => c.ListId)
|
||||||
|
.Matches(@"^top250$|^popular$|^ls\d+$|^ur\d+$")
|
||||||
|
.WithMessage("List ID mist be 'top250', 'popular', an IMDb List ID of the form 'ls12345678' or an IMDb user watchlist of the form 'ur12345678'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IMDbListSettings : IProviderConfig
|
||||||
|
{
|
||||||
|
private static readonly IMDbSettingsValidator Validator = new IMDbSettingsValidator();
|
||||||
|
|
||||||
|
public IMDbListSettings()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[FieldDefinition(1, Label = "List/User ID", HelpText = "IMDb list ID (e.g ls12345678), IMDb user ID (e.g. ur12345678), 'top250' or 'popular'")]
|
||||||
|
public string ListId { get; set; }
|
||||||
|
|
||||||
|
public NzbDroneValidationResult Validate()
|
||||||
|
{
|
||||||
|
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
src/NzbDrone.Core/NetImport/RadarrList2/RadarrList2Parser.cs
Normal file
56
src/NzbDrone.Core/NetImport/RadarrList2/RadarrList2Parser.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
|
||||||
|
using NzbDrone.Core.Movies;
|
||||||
|
using NzbDrone.Core.NetImport.Exceptions;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.NetImport.RadarrList2
|
||||||
|
{
|
||||||
|
public class RadarrList2Parser : IParseNetImportResponse
|
||||||
|
{
|
||||||
|
public IList<Movie> ParseResponse(NetImportResponse netMovieImporterResponse)
|
||||||
|
{
|
||||||
|
var importResponse = netMovieImporterResponse;
|
||||||
|
|
||||||
|
var movies = new List<Movie>();
|
||||||
|
|
||||||
|
if (!PreProcess(importResponse))
|
||||||
|
{
|
||||||
|
return movies;
|
||||||
|
}
|
||||||
|
|
||||||
|
var jsonResponse = JsonConvert.DeserializeObject<List<MovieResource>>(importResponse.Content);
|
||||||
|
|
||||||
|
// no movies were return
|
||||||
|
if (jsonResponse == null)
|
||||||
|
{
|
||||||
|
return movies;
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonResponse.SelectList(m => new Movie { TmdbId = m.TmdbId });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual bool PreProcess(NetImportResponse listResponse)
|
||||||
|
{
|
||||||
|
if (listResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
|
||||||
|
{
|
||||||
|
throw new NetImportException(listResponse,
|
||||||
|
"Radarr API call resulted in an unexpected StatusCode [{0}]",
|
||||||
|
listResponse.HttpResponse.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listResponse.HttpResponse.Headers.ContentType != null &&
|
||||||
|
listResponse.HttpResponse.Headers.ContentType.Contains("text/json") &&
|
||||||
|
listResponse.HttpRequest.Headers.Accept != null &&
|
||||||
|
!listResponse.HttpRequest.Headers.Accept.Contains("text/json"))
|
||||||
|
{
|
||||||
|
throw new NetImportException(listResponse,
|
||||||
|
"Radarr API responded with html content. Site is likely blocked or unavailable.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.NetImport.RadarrList2
|
||||||
|
{
|
||||||
|
public abstract class RadarrList2RequestGeneratorBase : INetImportRequestGenerator
|
||||||
|
{
|
||||||
|
public IHttpRequestBuilderFactory RequestBuilder { get; set; }
|
||||||
|
public IHttpClient HttpClient { get; set; }
|
||||||
|
public Logger Logger { get; set; }
|
||||||
|
|
||||||
|
protected abstract HttpRequest GetHttpRequest();
|
||||||
|
|
||||||
|
public virtual NetImportPageableRequestChain GetMovies()
|
||||||
|
{
|
||||||
|
var pageableRequests = new NetImportPageableRequestChain();
|
||||||
|
|
||||||
|
var httpRequest = GetHttpRequest();
|
||||||
|
|
||||||
|
var request = new NetImportRequest(httpRequest.Url.ToString(), HttpAccept.Json);
|
||||||
|
|
||||||
|
request.HttpRequest.SuppressHttpError = true;
|
||||||
|
|
||||||
|
pageableRequests.Add(new List<NetImportRequest> { request });
|
||||||
|
return pageableRequests;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Cloud;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.NetImport.RadarrList2.StevenLu
|
||||||
|
{
|
||||||
|
public class StevenLu2Import : HttpNetImportBase<StevenLu2Settings>
|
||||||
|
{
|
||||||
|
private readonly IHttpRequestBuilderFactory _radarrMetadata;
|
||||||
|
|
||||||
|
public override string Name => "StevenLu List";
|
||||||
|
|
||||||
|
public override NetImportType ListType => NetImportType.Other;
|
||||||
|
public override bool Enabled => true;
|
||||||
|
public override bool EnableAuto => false;
|
||||||
|
|
||||||
|
public StevenLu2Import(IRadarrCloudRequestBuilder requestBuilder,
|
||||||
|
IHttpClient httpClient,
|
||||||
|
INetImportStatusService netImportStatusService,
|
||||||
|
IConfigService configService,
|
||||||
|
IParsingService parsingService,
|
||||||
|
Logger logger)
|
||||||
|
: base(httpClient, netImportStatusService, configService, parsingService, logger)
|
||||||
|
{
|
||||||
|
_radarrMetadata = requestBuilder.RadarrMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override INetImportRequestGenerator GetRequestGenerator()
|
||||||
|
{
|
||||||
|
return new StevenLu2RequestGenerator()
|
||||||
|
{
|
||||||
|
Settings = Settings,
|
||||||
|
Logger = _logger,
|
||||||
|
HttpClient = _httpClient,
|
||||||
|
RequestBuilder = _radarrMetadata
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IParseNetImportResponse GetParser()
|
||||||
|
{
|
||||||
|
return new RadarrList2Parser();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
using NzbDrone.Common.Http;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.NetImport.RadarrList2.StevenLu
|
||||||
|
{
|
||||||
|
public class StevenLu2RequestGenerator : RadarrList2RequestGeneratorBase
|
||||||
|
{
|
||||||
|
public StevenLu2Settings Settings { get; set; }
|
||||||
|
|
||||||
|
protected override HttpRequest GetHttpRequest()
|
||||||
|
{
|
||||||
|
var builder = RequestBuilder.Create()
|
||||||
|
.SetSegment("route", $"list/stevenlu");
|
||||||
|
|
||||||
|
if (Settings.Source != (int)StevenLuSource.Standard)
|
||||||
|
{
|
||||||
|
var source = ((StevenLuSource)Settings.Source).ToString().ToLower();
|
||||||
|
|
||||||
|
var minScore = Settings.Source == (int)StevenLuSource.Imdb ? Settings.MinScore : Settings.MinScore * 10;
|
||||||
|
builder.Resource($"{source}/{minScore}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.Build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
using FluentValidation;
|
||||||
|
using NzbDrone.Core.Annotations;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
using NzbDrone.Core.Validation;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.NetImport.RadarrList2.StevenLu
|
||||||
|
{
|
||||||
|
public class StevenLu2SettingsValidator : AbstractValidator<StevenLu2Settings>
|
||||||
|
{
|
||||||
|
public StevenLu2SettingsValidator()
|
||||||
|
{
|
||||||
|
RuleFor(c => c.MinScore).GreaterThanOrEqualTo(x => 5).LessThanOrEqualTo(x => 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum StevenLuSource
|
||||||
|
{
|
||||||
|
Standard,
|
||||||
|
Imdb,
|
||||||
|
Metacritic,
|
||||||
|
RottenTomatoes
|
||||||
|
}
|
||||||
|
|
||||||
|
public class StevenLu2Settings : IProviderConfig
|
||||||
|
{
|
||||||
|
private static readonly StevenLu2SettingsValidator Validator = new StevenLu2SettingsValidator();
|
||||||
|
|
||||||
|
public StevenLu2Settings()
|
||||||
|
{
|
||||||
|
MinScore = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
[FieldDefinition(1, Label = "Rating source", Type = FieldType.Select, SelectOptions = typeof(StevenLuSource), HelpText = "StevenLu ratings source")]
|
||||||
|
public int Source { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(1, Label = "Minimum Score", Type = FieldType.Number, HelpText = "Only applies if 'Rating source' is not 'Standard'")]
|
||||||
|
public int MinScore { get; set; }
|
||||||
|
|
||||||
|
public NzbDroneValidationResult Validate()
|
||||||
|
{
|
||||||
|
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,9 +7,9 @@ namespace NzbDrone.Core.NetImport.StevenLu
|
|||||||
{
|
{
|
||||||
public class StevenLuImport : HttpNetImportBase<StevenLuSettings>
|
public class StevenLuImport : HttpNetImportBase<StevenLuSettings>
|
||||||
{
|
{
|
||||||
public override string Name => "StevenLu";
|
public override string Name => "StevenLu Custom";
|
||||||
|
|
||||||
public override NetImportType ListType => NetImportType.Other;
|
public override NetImportType ListType => NetImportType.Advanced;
|
||||||
public override bool Enabled => true;
|
public override bool Enabled => true;
|
||||||
public override bool EnableAuto => false;
|
public override bool EnableAuto => false;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user