mirror of https://github.com/ErsatzTV/ErsatzTV.git
				
				
			
				 23 changed files with 5474 additions and 77 deletions
			
			
		@ -0,0 +1,247 @@
				@@ -0,0 +1,247 @@
					 | 
				
			||||
using System.Text; | 
				
			||||
using Bugsnag; | 
				
			||||
using ErsatzTV.Core.Metadata.Nfo; | 
				
			||||
using FluentAssertions; | 
				
			||||
using Moq; | 
				
			||||
using NUnit.Framework; | 
				
			||||
 | 
				
			||||
namespace ErsatzTV.Core.Tests.Metadata.Nfo; | 
				
			||||
 | 
				
			||||
[TestFixture] | 
				
			||||
public class OtherVideoNfoReaderTests | 
				
			||||
{ | 
				
			||||
    [SetUp] | 
				
			||||
    public void SetUp() => _otherVideoNfoReader = new OtherVideoNfoReader(new Mock<IClient>().Object); | 
				
			||||
 | 
				
			||||
    private OtherVideoNfoReader _otherVideoNfoReader; | 
				
			||||
 | 
				
			||||
    [Test] | 
				
			||||
    public async Task ParsingNfo_Should_Return_Error() | 
				
			||||
    { | 
				
			||||
        await using var stream = | 
				
			||||
            new MemoryStream(Encoding.UTF8.GetBytes(@"https://www.themoviedb.org/movie/11-star-wars")); | 
				
			||||
 | 
				
			||||
        Either<BaseError, OtherVideoNfo> result = await _otherVideoNfoReader.Read(stream); | 
				
			||||
 | 
				
			||||
        result.IsLeft.Should().BeTrue(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    [Test] | 
				
			||||
    public async Task MetadataNfo_Should_Return_Nfo() | 
				
			||||
    { | 
				
			||||
        await using var stream = new MemoryStream(Encoding.UTF8.GetBytes(@"<movie></movie>")); | 
				
			||||
 | 
				
			||||
        Either<BaseError, OtherVideoNfo> result = await _otherVideoNfoReader.Read(stream); | 
				
			||||
 | 
				
			||||
        result.IsRight.Should().BeTrue(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    [Test] | 
				
			||||
    public async Task CombinationNfo_Should_Return_Nfo() | 
				
			||||
    { | 
				
			||||
        await using var stream = new MemoryStream( | 
				
			||||
            Encoding.UTF8.GetBytes( | 
				
			||||
                @"<movie></movie>
 | 
				
			||||
https://www.themoviedb.org/movie/11-star-wars"));
 | 
				
			||||
 | 
				
			||||
        Either<BaseError, OtherVideoNfo> result = await _otherVideoNfoReader.Read(stream); | 
				
			||||
 | 
				
			||||
        result.IsRight.Should().BeTrue(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    [Test] | 
				
			||||
    public async Task FullSample_Should_Return_Nfo() | 
				
			||||
    { | 
				
			||||
        await using var stream = new MemoryStream( | 
				
			||||
            Encoding.UTF8.GetBytes( | 
				
			||||
                @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes"" ?>
 | 
				
			||||
<movie> | 
				
			||||
    <title>Zack Snyder's Justice League</title> | 
				
			||||
    <originaltitle>Zack Snyder's Justice League</originaltitle> | 
				
			||||
    <sorttitle>Justice League 2</sorttitle> | 
				
			||||
    <ratings> | 
				
			||||
        <rating name=""imdb"" max=""10"" default=""true""> | 
				
			||||
            <value>8.300000</value> | 
				
			||||
            <votes>197786</votes> | 
				
			||||
        </rating> | 
				
			||||
        <rating name=""themoviedb"" max=""10""> | 
				
			||||
            <value>8.700000</value> | 
				
			||||
            <votes>3461</votes> | 
				
			||||
        </rating> | 
				
			||||
        <rating name=""trakt"" max=""10""> | 
				
			||||
            <value>8.195670</value> | 
				
			||||
            <votes>4247</votes> | 
				
			||||
        </rating> | 
				
			||||
    </ratings> | 
				
			||||
    <userrating>0</userrating> | 
				
			||||
    <top250>140</top250> | 
				
			||||
    <outline></outline> | 
				
			||||
    <plot>Determined to ensure Superman's ultimate sacrifice was not in vain, Bruce Wayne aligns forces with Diana Prince with plans to recruit a team of metahumans to protect the world from an approaching threat of catastrophic proportions.</plot> | 
				
			||||
    <tagline></tagline> | 
				
			||||
    <runtime>242</runtime> | 
				
			||||
    <thumb spoof="""" cache="""" aspect=""poster"" preview="""">https://assets.fanart.tv/fanart/movies/791373/movieposter/zack-snyders-justice-league-603fdb873f474.jpg</thumb>
 | 
				
			||||
    <thumb spoof="""" cache="""" aspect=""poster"" preview="""">https://image.tmdb.org/t/p/original/tnAuB8q5vv7Ax9UAEje5Xi4BXik.jpg</thumb>
 | 
				
			||||
    <thumb spoof="""" cache="""" aspect=""landscape"" preview="""">https://assets.fanart.tv/fanart/movies/791373/moviethumb/zack-snyders-justice-league-6050310135cf6.jpg</thumb>
 | 
				
			||||
    <thumb spoof="""" cache="""" aspect=""landscape"" preview="""">https://image.tmdb.org/t/p/original/wcYBuOZDP6Vi8Ye4qax3Zx9dCan.jpg</thumb>
 | 
				
			||||
    <thumb spoof="""" cache="""" aspect=""keyart"" preview="""">https://assets.fanart.tv/fanart/movies/791373/movieposter/zack-snyders-justice-league-603fdba9bdd16.jpg</thumb>
 | 
				
			||||
    <thumb spoof="""" cache="""" aspect=""clearlogo"" preview="""">https://assets.fanart.tv/fanart/movies/791373/hdmovielogo/zack-snyders-justice-league-5ed3f2e4952e9.png</thumb>
 | 
				
			||||
    <thumb spoof="""" cache="""" aspect=""banner"" preview="""">https://assets.fanart.tv/fanart/movies/791373/moviebanner/zack-snyders-justice-league-6050049514d4c.jpg</thumb>
 | 
				
			||||
    <fanart> | 
				
			||||
        <thumb colors="""" preview=""https://assets.fanart.tv/preview/movies/791373/moviebackground/zack-snyders-justice-league-5fee5b9fe0e0d.jpg"">https://assets.fanart.tv/fanart/movies/791373/moviebackground/zack-snyders-justice-league-5fee5b9fe0e0d.jpg</thumb>
 | 
				
			||||
        <thumb colors="""" preview=""https://image.tmdb.org/t/p/w780/43NwryODVEsbBDC0jK3wYfVyb5q.jpg"">https://image.tmdb.org/t/p/original/43NwryODVEsbBDC0jK3wYfVyb5q.jpg</thumb>
 | 
				
			||||
    </fanart> | 
				
			||||
    <mpaa>Australia:M</mpaa> | 
				
			||||
    <playcount>0</playcount> | 
				
			||||
    <lastplayed></lastplayed> | 
				
			||||
    <id>791373</id> | 
				
			||||
    <uniqueid type=""imdb"">tt12361974</uniqueid> | 
				
			||||
    <uniqueid type=""tmdb"" default=""true"">791373</uniqueid> | 
				
			||||
    <genre>SuperHero</genre> | 
				
			||||
    <tag>TV Recording</tag> | 
				
			||||
    <set> | 
				
			||||
        <name>Justice League Collection</name> | 
				
			||||
        <overview>Based on the DC Comics superhero team</overview> | 
				
			||||
    </set> | 
				
			||||
    <country>USA</country> | 
				
			||||
    <credits>Chris Terrio</credits> | 
				
			||||
    <director>Zack Snyder</director> | 
				
			||||
    <premiered>2021-03-18</premiered> | 
				
			||||
    <year>2021</year> | 
				
			||||
    <status></status> | 
				
			||||
    <code></code> | 
				
			||||
    <aired></aired> | 
				
			||||
    <studio>Warner Bros. Pictures</studio> | 
				
			||||
    <trailer></trailer> | 
				
			||||
    <fileinfo> | 
				
			||||
        <streamdetails> | 
				
			||||
            <video> | 
				
			||||
                <codec>hevc</codec> | 
				
			||||
                <aspect>1.777778</aspect> | 
				
			||||
                <width>1920</width> | 
				
			||||
                <height>1080</height> | 
				
			||||
                <durationinseconds>14528</durationinseconds> | 
				
			||||
                <stereomode></stereomode> | 
				
			||||
            </video> | 
				
			||||
            <audio> | 
				
			||||
                <codec>ac3</codec> | 
				
			||||
                <language>eng</language> | 
				
			||||
                <channels>6</channels> | 
				
			||||
            </audio> | 
				
			||||
            <audio> | 
				
			||||
                <codec>ac3</codec> | 
				
			||||
                <language>fre</language> | 
				
			||||
                <channels>6</channels> | 
				
			||||
            </audio> | 
				
			||||
            <subtitle> | 
				
			||||
                <language>eng</language> | 
				
			||||
            </subtitle> | 
				
			||||
        </streamdetails> | 
				
			||||
    </fileinfo> | 
				
			||||
    <actor> | 
				
			||||
        <name>Ben Affleck</name> | 
				
			||||
        <role>Bruce Wayne / Batman</role> | 
				
			||||
        <order>0</order> | 
				
			||||
        <thumb>https://image.tmdb.org/t/p/original/u525jeDOzg9hVdvYfeehTGnw7Aa.jpg</thumb>
 | 
				
			||||
    </actor> | 
				
			||||
    <actor> | 
				
			||||
        <name>Henry Cavill</name> | 
				
			||||
        <role>Clark Kent / Superman / Kal-El</role> | 
				
			||||
        <order>1</order> | 
				
			||||
        <thumb>https://image.tmdb.org/t/p/original/hErUwonrQgY5Y7RfxOfv8Fq11MB.jpg</thumb>
 | 
				
			||||
    </actor> | 
				
			||||
    <actor> | 
				
			||||
        <name>Gal Gadot</name> | 
				
			||||
        <role>Diana Prince / Wonder Woman</role> | 
				
			||||
        <order>2</order> | 
				
			||||
        <thumb>https://image.tmdb.org/t/p/original/fysvehTvU6bE3JgxaOTRfvQJzJ4.jpg</thumb>
 | 
				
			||||
    </actor> | 
				
			||||
    <resume> | 
				
			||||
        <position>0.000000</position> | 
				
			||||
        <total>0.000000</total> | 
				
			||||
    </resume> | 
				
			||||
    <dateadded>2021-03-26 11:35:50</dateadded> | 
				
			||||
</movie>"));
 | 
				
			||||
 | 
				
			||||
        Either<BaseError, OtherVideoNfo> result = await _otherVideoNfoReader.Read(stream); | 
				
			||||
 | 
				
			||||
        result.IsRight.Should().BeTrue(); | 
				
			||||
 | 
				
			||||
        foreach (OtherVideoNfo nfo in result.RightToSeq()) | 
				
			||||
        { | 
				
			||||
            nfo.Title.Should().Be("Zack Snyder's Justice League"); | 
				
			||||
            nfo.SortTitle.Should().Be("Justice League 2"); | 
				
			||||
            nfo.Outline.Should().BeNullOrEmpty(); | 
				
			||||
            nfo.Year.Should().Be(2021); | 
				
			||||
            nfo.ContentRating.Should().Be("Australia:M"); | 
				
			||||
 | 
				
			||||
            nfo.Premiered.IsSome.Should().BeTrue(); | 
				
			||||
            foreach (DateTime premiered in nfo.Premiered) | 
				
			||||
            { | 
				
			||||
                premiered.Should().Be(new DateTime(2021, 03, 18)); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            nfo.Plot.Should().Be( | 
				
			||||
                "Determined to ensure Superman's ultimate sacrifice was not in vain, Bruce Wayne aligns forces with Diana Prince with plans to recruit a team of metahumans to protect the world from an approaching threat of catastrophic proportions."); | 
				
			||||
            nfo.Tagline.Should().BeNullOrEmpty(); | 
				
			||||
            nfo.Genres.Should().BeEquivalentTo(new List<string> { "SuperHero" }); | 
				
			||||
            nfo.Tags.Should().BeEquivalentTo(new List<string> { "TV Recording" }); | 
				
			||||
            nfo.Studios.Should().BeEquivalentTo(new List<string> { "Warner Bros. Pictures" }); | 
				
			||||
            nfo.Actors.Should().BeEquivalentTo( | 
				
			||||
                new List<ActorNfo> | 
				
			||||
                { | 
				
			||||
                    new() | 
				
			||||
                    { | 
				
			||||
                        Name = "Ben Affleck", Order = 0, Role = "Bruce Wayne / Batman", | 
				
			||||
                        Thumb = "https://image.tmdb.org/t/p/original/u525jeDOzg9hVdvYfeehTGnw7Aa.jpg" | 
				
			||||
                    }, | 
				
			||||
                    new() | 
				
			||||
                    { | 
				
			||||
                        Name = "Henry Cavill", Order = 1, Role = "Clark Kent / Superman / Kal-El", | 
				
			||||
                        Thumb = "https://image.tmdb.org/t/p/original/hErUwonrQgY5Y7RfxOfv8Fq11MB.jpg" | 
				
			||||
                    }, | 
				
			||||
                    new() | 
				
			||||
                    { | 
				
			||||
                        Name = "Gal Gadot", Order = 2, Role = "Diana Prince / Wonder Woman", | 
				
			||||
                        Thumb = "https://image.tmdb.org/t/p/original/fysvehTvU6bE3JgxaOTRfvQJzJ4.jpg" | 
				
			||||
                    } | 
				
			||||
                }); | 
				
			||||
            nfo.Writers.Should().BeEquivalentTo(new List<string> { "Chris Terrio" }); | 
				
			||||
            nfo.Directors.Should().BeEquivalentTo(new List<string> { "Zack Snyder" }); | 
				
			||||
            nfo.UniqueIds.Should().BeEquivalentTo( | 
				
			||||
                new List<UniqueIdNfo> | 
				
			||||
                { | 
				
			||||
                    new() { Type = "imdb", Guid = "tt12361974", Default = false }, | 
				
			||||
                    new() { Type = "tmdb", Guid = "791373", Default = true } | 
				
			||||
                }); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    [Test] | 
				
			||||
    public async Task MetadataNfo_With_Tag_Should_Return_Nfo() | 
				
			||||
    { | 
				
			||||
        await using var stream = new MemoryStream(Encoding.UTF8.GetBytes(@"<movie><tag>Test Tag</tag></movie>")); | 
				
			||||
 | 
				
			||||
        Either<BaseError, OtherVideoNfo> result = await _otherVideoNfoReader.Read(stream); | 
				
			||||
 | 
				
			||||
        result.IsRight.Should().BeTrue(); | 
				
			||||
        foreach (OtherVideoNfo nfo in result.RightToSeq()) | 
				
			||||
        { | 
				
			||||
            nfo.Tags.Should().BeEquivalentTo(new List<string> { "Test Tag" }); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    [Test] | 
				
			||||
    public async Task MetadataNfo_With_Outline_Should_Return_Nfo() | 
				
			||||
    { | 
				
			||||
        await using var stream = | 
				
			||||
            new MemoryStream(Encoding.UTF8.GetBytes(@"<movie><outline>Test Outline</outline></movie>")); | 
				
			||||
 | 
				
			||||
        Either<BaseError, OtherVideoNfo> result = await _otherVideoNfoReader.Read(stream); | 
				
			||||
 | 
				
			||||
        result.IsRight.Should().BeTrue(); | 
				
			||||
        foreach (OtherVideoNfo nfo in result.RightToSeq()) | 
				
			||||
        { | 
				
			||||
            nfo.Outline.Should().Be("Test Outline"); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,8 @@
				@@ -0,0 +1,8 @@
					 | 
				
			||||
using ErsatzTV.Core.Metadata.Nfo; | 
				
			||||
 | 
				
			||||
namespace ErsatzTV.Core.Interfaces.Metadata.Nfo; | 
				
			||||
 | 
				
			||||
public interface IOtherVideoNfoReader | 
				
			||||
{ | 
				
			||||
    Task<Either<BaseError, OtherVideoNfo>> Read(Stream input); | 
				
			||||
} | 
				
			||||
@ -0,0 +1,52 @@
				@@ -0,0 +1,52 @@
					 | 
				
			||||
using System.Xml.Serialization; | 
				
			||||
 | 
				
			||||
namespace ErsatzTV.Core.Metadata.Nfo; | 
				
			||||
 | 
				
			||||
[XmlRoot("movie")] | 
				
			||||
public class OtherVideoNfo | 
				
			||||
{ | 
				
			||||
    [XmlElement("title")] | 
				
			||||
    public string Title { get; set; } | 
				
			||||
 | 
				
			||||
    [XmlElement("sorttitle")] | 
				
			||||
    public string SortTitle { get; set; } | 
				
			||||
 | 
				
			||||
    [XmlElement("outline")] | 
				
			||||
    public string Outline { get; set; } | 
				
			||||
 | 
				
			||||
    [XmlElement("year")] | 
				
			||||
    public int Year { get; set; } | 
				
			||||
 | 
				
			||||
    [XmlElement("mpaa")] | 
				
			||||
    public string ContentRating { get; set; } | 
				
			||||
 | 
				
			||||
    [XmlElement("premiered")] | 
				
			||||
    public Option<DateTime> Premiered { get; set; } | 
				
			||||
 | 
				
			||||
    [XmlElement("plot")] | 
				
			||||
    public string Plot { get; set; } | 
				
			||||
 | 
				
			||||
    [XmlElement("tagline")] | 
				
			||||
    public string Tagline { get; set; } | 
				
			||||
 | 
				
			||||
    [XmlElement("genre")] | 
				
			||||
    public List<string> Genres { get; set; } | 
				
			||||
 | 
				
			||||
    [XmlElement("tag")] | 
				
			||||
    public List<string> Tags { get; set; } | 
				
			||||
 | 
				
			||||
    [XmlElement("studio")] | 
				
			||||
    public List<string> Studios { get; set; } | 
				
			||||
 | 
				
			||||
    [XmlElement("actor")] | 
				
			||||
    public List<ActorNfo> Actors { get; set; } | 
				
			||||
 | 
				
			||||
    [XmlElement("credits")] | 
				
			||||
    public List<string> Writers { get; set; } | 
				
			||||
 | 
				
			||||
    [XmlElement("director")] | 
				
			||||
    public List<string> Directors { get; set; } | 
				
			||||
 | 
				
			||||
    [XmlElement("uniqueid")] | 
				
			||||
    public List<UniqueIdNfo> UniqueIds { get; set; } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,114 @@
				@@ -0,0 +1,114 @@
					 | 
				
			||||
using System.Xml; | 
				
			||||
using Bugsnag; | 
				
			||||
using ErsatzTV.Core.Errors; | 
				
			||||
using ErsatzTV.Core.Interfaces.Metadata.Nfo; | 
				
			||||
 | 
				
			||||
namespace ErsatzTV.Core.Metadata.Nfo; | 
				
			||||
 | 
				
			||||
public class OtherVideoNfoReader : NfoReader<OtherVideoNfo>, IOtherVideoNfoReader | 
				
			||||
{ | 
				
			||||
    private readonly IClient _client; | 
				
			||||
 | 
				
			||||
    public OtherVideoNfoReader(IClient client) => _client = client; | 
				
			||||
 | 
				
			||||
    public async Task<Either<BaseError, OtherVideoNfo>> Read(Stream input) | 
				
			||||
    { | 
				
			||||
        try | 
				
			||||
        { | 
				
			||||
            var settings = new XmlReaderSettings { Async = true, ConformanceLevel = ConformanceLevel.Fragment }; | 
				
			||||
            using var reader = XmlReader.Create(input, settings); | 
				
			||||
            OtherVideoNfo nfo = null; | 
				
			||||
            var done = false; | 
				
			||||
 | 
				
			||||
            while (!done && await reader.ReadAsync()) | 
				
			||||
            { | 
				
			||||
                switch (reader.NodeType) | 
				
			||||
                { | 
				
			||||
                    case XmlNodeType.Element: | 
				
			||||
                        switch (reader.Name.ToLowerInvariant()) | 
				
			||||
                        { | 
				
			||||
                            case "movie": | 
				
			||||
                                nfo = new OtherVideoNfo | 
				
			||||
                                { | 
				
			||||
                                    Genres = new List<string>(), | 
				
			||||
                                    Tags = new List<string>(), | 
				
			||||
                                    Studios = new List<string>(), | 
				
			||||
                                    Actors = new List<ActorNfo>(), | 
				
			||||
                                    Writers = new List<string>(), | 
				
			||||
                                    Directors = new List<string>(), | 
				
			||||
                                    UniqueIds = new List<UniqueIdNfo>() | 
				
			||||
                                }; | 
				
			||||
                                break; | 
				
			||||
                            case "title": | 
				
			||||
                                await ReadStringContent(reader, nfo, (movie, title) => movie.Title = title); | 
				
			||||
                                break; | 
				
			||||
                            case "sorttitle": | 
				
			||||
                                await ReadStringContent(reader, nfo, (movie, sortTitle) => movie.SortTitle = sortTitle); | 
				
			||||
                                break; | 
				
			||||
                            case "outline": | 
				
			||||
                                await ReadStringContent(reader, nfo, (movie, outline) => movie.Outline = outline); | 
				
			||||
                                break; | 
				
			||||
                            case "year": | 
				
			||||
                                await ReadIntContent(reader, nfo, (movie, year) => movie.Year = year); | 
				
			||||
                                break; | 
				
			||||
                            case "mpaa": | 
				
			||||
                                await ReadStringContent( | 
				
			||||
                                    reader, | 
				
			||||
                                    nfo, | 
				
			||||
                                    (movie, contentRating) => movie.ContentRating = contentRating); | 
				
			||||
                                break; | 
				
			||||
                            case "premiered": | 
				
			||||
                                await ReadDateTimeContent( | 
				
			||||
                                    reader, | 
				
			||||
                                    nfo, | 
				
			||||
                                    (movie, premiered) => movie.Premiered = premiered); | 
				
			||||
                                break; | 
				
			||||
                            case "plot": | 
				
			||||
                                await ReadStringContent(reader, nfo, (movie, plot) => movie.Plot = plot); | 
				
			||||
                                break; | 
				
			||||
                            case "genre": | 
				
			||||
                                await ReadStringContent(reader, nfo, (movie, genre) => movie.Genres.Add(genre)); | 
				
			||||
                                break; | 
				
			||||
                            case "tag": | 
				
			||||
                                await ReadStringContent(reader, nfo, (movie, tag) => movie.Tags.Add(tag)); | 
				
			||||
                                break; | 
				
			||||
                            case "studio": | 
				
			||||
                                await ReadStringContent(reader, nfo, (movie, studio) => movie.Studios.Add(studio)); | 
				
			||||
                                break; | 
				
			||||
                            case "actor": | 
				
			||||
                                ReadActor(reader, nfo, (movie, actor) => movie.Actors.Add(actor)); | 
				
			||||
                                break; | 
				
			||||
                            case "credits": | 
				
			||||
                                await ReadStringContent(reader, nfo, (movie, writer) => movie.Writers.Add(writer)); | 
				
			||||
                                break; | 
				
			||||
                            case "director": | 
				
			||||
                                await ReadStringContent( | 
				
			||||
                                    reader, | 
				
			||||
                                    nfo, | 
				
			||||
                                    (movie, director) => movie.Directors.Add(director)); | 
				
			||||
                                break; | 
				
			||||
                            case "uniqueid": | 
				
			||||
                                await ReadUniqueId(reader, nfo, (movie, uniqueid) => movie.UniqueIds.Add(uniqueid)); | 
				
			||||
                                break; | 
				
			||||
                        } | 
				
			||||
 | 
				
			||||
                        break; | 
				
			||||
                    case XmlNodeType.EndElement: | 
				
			||||
                        if (reader.Name == "movie") | 
				
			||||
                        { | 
				
			||||
                            done = true; | 
				
			||||
                        } | 
				
			||||
 | 
				
			||||
                        break; | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            return Optional(nfo).ToEither((BaseError)new FailedToReadNfo()); | 
				
			||||
        } | 
				
			||||
        catch (Exception ex) | 
				
			||||
        { | 
				
			||||
            _client.Notify(ex); | 
				
			||||
            return new FailedToReadNfo(ex.ToString()); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						@ -0,0 +1,209 @@
				@@ -0,0 +1,209 @@
					 | 
				
			||||
using Microsoft.EntityFrameworkCore.Migrations; | 
				
			||||
 | 
				
			||||
#nullable disable | 
				
			||||
 | 
				
			||||
namespace ErsatzTV.Infrastructure.Migrations | 
				
			||||
{ | 
				
			||||
    public partial class Expand_OtherVideoMetadata : Migration | 
				
			||||
    { | 
				
			||||
        protected override void Up(MigrationBuilder migrationBuilder) | 
				
			||||
        { | 
				
			||||
            migrationBuilder.DropForeignKey( | 
				
			||||
                name: "FK_Actor_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "Actor"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.DropForeignKey( | 
				
			||||
                name: "FK_Genre_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "Genre"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.DropForeignKey( | 
				
			||||
                name: "FK_MetadataGuid_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "MetadataGuid"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.DropForeignKey( | 
				
			||||
                name: "FK_Studio_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "Studio"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.AddColumn<int>( | 
				
			||||
                name: "OtherVideoMetadataId", | 
				
			||||
                table: "Writer", | 
				
			||||
                type: "INTEGER", | 
				
			||||
                nullable: true); | 
				
			||||
 | 
				
			||||
            migrationBuilder.AddColumn<string>( | 
				
			||||
                name: "ContentRating", | 
				
			||||
                table: "OtherVideoMetadata", | 
				
			||||
                type: "TEXT", | 
				
			||||
                nullable: true); | 
				
			||||
 | 
				
			||||
            migrationBuilder.AddColumn<string>( | 
				
			||||
                name: "Outline", | 
				
			||||
                table: "OtherVideoMetadata", | 
				
			||||
                type: "TEXT", | 
				
			||||
                nullable: true); | 
				
			||||
 | 
				
			||||
            migrationBuilder.AddColumn<string>( | 
				
			||||
                name: "Plot", | 
				
			||||
                table: "OtherVideoMetadata", | 
				
			||||
                type: "TEXT", | 
				
			||||
                nullable: true); | 
				
			||||
 | 
				
			||||
            migrationBuilder.AddColumn<string>( | 
				
			||||
                name: "Tagline", | 
				
			||||
                table: "OtherVideoMetadata", | 
				
			||||
                type: "TEXT", | 
				
			||||
                nullable: true); | 
				
			||||
 | 
				
			||||
            migrationBuilder.AddColumn<int>( | 
				
			||||
                name: "OtherVideoMetadataId", | 
				
			||||
                table: "Director", | 
				
			||||
                type: "INTEGER", | 
				
			||||
                nullable: true); | 
				
			||||
 | 
				
			||||
            migrationBuilder.CreateIndex( | 
				
			||||
                name: "IX_Writer_OtherVideoMetadataId", | 
				
			||||
                table: "Writer", | 
				
			||||
                column: "OtherVideoMetadataId"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.CreateIndex( | 
				
			||||
                name: "IX_Director_OtherVideoMetadataId", | 
				
			||||
                table: "Director", | 
				
			||||
                column: "OtherVideoMetadataId"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.AddForeignKey( | 
				
			||||
                name: "FK_Actor_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "Actor", | 
				
			||||
                column: "OtherVideoMetadataId", | 
				
			||||
                principalTable: "OtherVideoMetadata", | 
				
			||||
                principalColumn: "Id", | 
				
			||||
                onDelete: ReferentialAction.Cascade); | 
				
			||||
 | 
				
			||||
            migrationBuilder.AddForeignKey( | 
				
			||||
                name: "FK_Director_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "Director", | 
				
			||||
                column: "OtherVideoMetadataId", | 
				
			||||
                principalTable: "OtherVideoMetadata", | 
				
			||||
                principalColumn: "Id", | 
				
			||||
                onDelete: ReferentialAction.Cascade); | 
				
			||||
 | 
				
			||||
            migrationBuilder.AddForeignKey( | 
				
			||||
                name: "FK_Genre_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "Genre", | 
				
			||||
                column: "OtherVideoMetadataId", | 
				
			||||
                principalTable: "OtherVideoMetadata", | 
				
			||||
                principalColumn: "Id", | 
				
			||||
                onDelete: ReferentialAction.Cascade); | 
				
			||||
 | 
				
			||||
            migrationBuilder.AddForeignKey( | 
				
			||||
                name: "FK_MetadataGuid_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "MetadataGuid", | 
				
			||||
                column: "OtherVideoMetadataId", | 
				
			||||
                principalTable: "OtherVideoMetadata", | 
				
			||||
                principalColumn: "Id", | 
				
			||||
                onDelete: ReferentialAction.Cascade); | 
				
			||||
 | 
				
			||||
            migrationBuilder.AddForeignKey( | 
				
			||||
                name: "FK_Studio_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "Studio", | 
				
			||||
                column: "OtherVideoMetadataId", | 
				
			||||
                principalTable: "OtherVideoMetadata", | 
				
			||||
                principalColumn: "Id", | 
				
			||||
                onDelete: ReferentialAction.Cascade); | 
				
			||||
 | 
				
			||||
            migrationBuilder.AddForeignKey( | 
				
			||||
                name: "FK_Writer_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "Writer", | 
				
			||||
                column: "OtherVideoMetadataId", | 
				
			||||
                principalTable: "OtherVideoMetadata", | 
				
			||||
                principalColumn: "Id", | 
				
			||||
                onDelete: ReferentialAction.Cascade); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        protected override void Down(MigrationBuilder migrationBuilder) | 
				
			||||
        { | 
				
			||||
            migrationBuilder.DropForeignKey( | 
				
			||||
                name: "FK_Actor_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "Actor"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.DropForeignKey( | 
				
			||||
                name: "FK_Director_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "Director"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.DropForeignKey( | 
				
			||||
                name: "FK_Genre_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "Genre"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.DropForeignKey( | 
				
			||||
                name: "FK_MetadataGuid_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "MetadataGuid"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.DropForeignKey( | 
				
			||||
                name: "FK_Studio_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "Studio"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.DropForeignKey( | 
				
			||||
                name: "FK_Writer_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "Writer"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.DropIndex( | 
				
			||||
                name: "IX_Writer_OtherVideoMetadataId", | 
				
			||||
                table: "Writer"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.DropIndex( | 
				
			||||
                name: "IX_Director_OtherVideoMetadataId", | 
				
			||||
                table: "Director"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.DropColumn( | 
				
			||||
                name: "OtherVideoMetadataId", | 
				
			||||
                table: "Writer"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.DropColumn( | 
				
			||||
                name: "ContentRating", | 
				
			||||
                table: "OtherVideoMetadata"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.DropColumn( | 
				
			||||
                name: "Outline", | 
				
			||||
                table: "OtherVideoMetadata"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.DropColumn( | 
				
			||||
                name: "Plot", | 
				
			||||
                table: "OtherVideoMetadata"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.DropColumn( | 
				
			||||
                name: "Tagline", | 
				
			||||
                table: "OtherVideoMetadata"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.DropColumn( | 
				
			||||
                name: "OtherVideoMetadataId", | 
				
			||||
                table: "Director"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.AddForeignKey( | 
				
			||||
                name: "FK_Actor_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "Actor", | 
				
			||||
                column: "OtherVideoMetadataId", | 
				
			||||
                principalTable: "OtherVideoMetadata", | 
				
			||||
                principalColumn: "Id"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.AddForeignKey( | 
				
			||||
                name: "FK_Genre_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "Genre", | 
				
			||||
                column: "OtherVideoMetadataId", | 
				
			||||
                principalTable: "OtherVideoMetadata", | 
				
			||||
                principalColumn: "Id"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.AddForeignKey( | 
				
			||||
                name: "FK_MetadataGuid_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "MetadataGuid", | 
				
			||||
                column: "OtherVideoMetadataId", | 
				
			||||
                principalTable: "OtherVideoMetadata", | 
				
			||||
                principalColumn: "Id"); | 
				
			||||
 | 
				
			||||
            migrationBuilder.AddForeignKey( | 
				
			||||
                name: "FK_Studio_OtherVideoMetadata_OtherVideoMetadataId", | 
				
			||||
                table: "Studio", | 
				
			||||
                column: "OtherVideoMetadataId", | 
				
			||||
                principalTable: "OtherVideoMetadata", | 
				
			||||
                principalColumn: "Id"); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue