mirror of
https://github.com/Readarr/Readarr
synced 2025-12-16 05:12:42 +01:00
parent
7c5188638f
commit
a7c0eabb56
11 changed files with 122 additions and 5 deletions
|
|
@ -79,6 +79,12 @@ const bookTokens = [
|
|||
|
||||
{ token: '{Book Disambiguation}', example: 'Disambiguation' },
|
||||
|
||||
{ token: '{Book Series}', example: 'Series Title' },
|
||||
|
||||
{ token: '{Book SeriesPosition}', example: '1' },
|
||||
|
||||
{ token: '{Book SeriesTitle}', example: 'Series Title #1' },
|
||||
|
||||
{ token: '{PartNumber:0}', example: '2' },
|
||||
{ token: '{PartNumber:00}', example: '02' },
|
||||
{ token: '{PartCount:0}', example: '9' },
|
||||
|
|
|
|||
|
|
@ -28,10 +28,23 @@ public void Setup()
|
|||
.With(s => s.Name = "Avenged Sevenfold")
|
||||
.Build();
|
||||
|
||||
var series = Builder<Series>
|
||||
.CreateNew()
|
||||
.With(x => x.Title = "Series Title")
|
||||
.Build();
|
||||
|
||||
var seriesLink = Builder<SeriesBookLink>
|
||||
.CreateListOfSize(1)
|
||||
.All()
|
||||
.With(s => s.Position = "1-2")
|
||||
.With(s => s.Series = series)
|
||||
.BuildListOfNew();
|
||||
|
||||
_book = Builder<Book>
|
||||
.CreateNew()
|
||||
.With(s => s.Title = "Hail to the King")
|
||||
.With(s => s.AuthorMetadata = _author.Metadata.Value)
|
||||
.With(s => s.SeriesLinks = seriesLink)
|
||||
.Build();
|
||||
|
||||
_edition = Builder<Edition>
|
||||
|
|
|
|||
|
|
@ -35,10 +35,23 @@ public void Setup()
|
|||
})
|
||||
.Build();
|
||||
|
||||
var series = Builder<Series>
|
||||
.CreateNew()
|
||||
.With(x => x.Title = "Series Title")
|
||||
.Build();
|
||||
|
||||
var seriesLink = Builder<SeriesBookLink>
|
||||
.CreateListOfSize(1)
|
||||
.All()
|
||||
.With(s => s.Position = "1-2")
|
||||
.With(s => s.Series = series)
|
||||
.BuildListOfNew();
|
||||
|
||||
_book = Builder<Book>
|
||||
.CreateNew()
|
||||
.With(s => s.Title = "Hybrid Theory")
|
||||
.With(s => s.AuthorMetadata = _author.Metadata.Value)
|
||||
.With(s => s.SeriesLinks = seriesLink)
|
||||
.Build();
|
||||
|
||||
_edition = Builder<Edition>
|
||||
|
|
@ -247,6 +260,33 @@ public void should_cleanup_Book_Title()
|
|||
.Should().Be("Hybrid.Theory.2000");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_set_series()
|
||||
{
|
||||
_namingConfig.StandardBookFormat = "{Book Series}";
|
||||
|
||||
Subject.BuildBookFileName(_author, _edition, _trackFile)
|
||||
.Should().Be("Series Title");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_set_series_number()
|
||||
{
|
||||
_namingConfig.StandardBookFormat = "{Book SeriesPosition}";
|
||||
|
||||
Subject.BuildBookFileName(_author, _edition, _trackFile)
|
||||
.Should().Be("1-2");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_set_series_title()
|
||||
{
|
||||
_namingConfig.StandardBookFormat = "{Book SeriesTitle}";
|
||||
|
||||
Subject.BuildBookFileName(_author, _edition, _trackFile)
|
||||
.Should().Be("Series Title #1-2");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_set_part_number()
|
||||
{
|
||||
|
|
@ -434,7 +474,7 @@ public void should_replace_double_period_with_single_period()
|
|||
{
|
||||
_namingConfig.StandardBookFormat = "{Author.Name}.{Book.Title}";
|
||||
|
||||
Subject.BuildBookFileName(new Author { Name = "In The Woods." }, new Edition { Title = "30 Rock", Book = new Book { AuthorMetadata = new AuthorMetadata { Name = "Author" } } }, _trackFile)
|
||||
Subject.BuildBookFileName(new Author { Name = "In The Woods." }, new Edition { Title = "30 Rock", Book = new Book { AuthorMetadata = new AuthorMetadata { Name = "Author" }, SeriesLinks = new List<SeriesBookLink>() } }, _trackFile)
|
||||
.Should().Be("In.The.Woods.30.Rock");
|
||||
}
|
||||
|
||||
|
|
@ -443,7 +483,7 @@ public void should_replace_triple_period_with_single_period()
|
|||
{
|
||||
_namingConfig.StandardBookFormat = "{Author.Name}.{Book.Title}";
|
||||
|
||||
Subject.BuildBookFileName(new Author { Name = "In The Woods..." }, new Edition { Title = "30 Rock", Book = new Book { AuthorMetadata = new AuthorMetadata { Name = "Author" } } }, _trackFile)
|
||||
Subject.BuildBookFileName(new Author { Name = "In The Woods..." }, new Edition { Title = "30 Rock", Book = new Book { AuthorMetadata = new AuthorMetadata { Name = "Author" }, SeriesLinks = new List<SeriesBookLink>() } }, _trackFile)
|
||||
.Should().Be("In.The.Woods.30.Rock");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,10 +28,23 @@ public void Setup()
|
|||
.With(s => s.Name = "Alien Ant Farm")
|
||||
.Build();
|
||||
|
||||
var series = Builder<Series>
|
||||
.CreateNew()
|
||||
.With(x => x.Title = "Series Title")
|
||||
.Build();
|
||||
|
||||
var seriesLink = Builder<SeriesBookLink>
|
||||
.CreateListOfSize(1)
|
||||
.All()
|
||||
.With(s => s.Position = "1-2")
|
||||
.With(s => s.Series = series)
|
||||
.BuildListOfNew();
|
||||
|
||||
_book = Builder<Book>
|
||||
.CreateNew()
|
||||
.With(s => s.Title = "Anthology")
|
||||
.With(s => s.AuthorMetadata = _author.Metadata.Value)
|
||||
.With(s => s.SeriesLinks = seriesLink)
|
||||
.Build();
|
||||
|
||||
_edition = Builder<Edition>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ namespace NzbDrone.Core.Books
|
|||
public class SeriesBookLink : Entity<SeriesBookLink>
|
||||
{
|
||||
public string Position { get; set; }
|
||||
public int SeriesPosition { get; set; }
|
||||
public int SeriesId { get; set; }
|
||||
public int BookId { get; set; }
|
||||
public bool IsPrimary { get; set; }
|
||||
|
|
@ -18,6 +19,7 @@ public class SeriesBookLink : Entity<SeriesBookLink>
|
|||
public override void UseMetadataFrom(SeriesBookLink other)
|
||||
{
|
||||
Position = other.Position;
|
||||
SeriesPosition = other.SeriesPosition;
|
||||
IsPrimary = other.IsPrimary;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(18)]
|
||||
public class AddSeriesPosition : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Alter.Table("SeriesBookLink").AddColumn("SeriesPosition").AsInt32().WithDefaultValue(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -196,7 +196,8 @@ private static void MapSeriesLinks(List<Series> series, List<Book> books, Author
|
|||
Book = bookDict[l.ForeignWorkId.ToString()],
|
||||
Series = curr,
|
||||
IsPrimary = l.Primary,
|
||||
Position = l.PositionInSeries
|
||||
Position = l.PositionInSeries,
|
||||
SeriesPosition = l.SeriesPosition
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -245,6 +245,17 @@ private void AddBookTokens(Dictionary<string, Func<TokenMatch, string>> tokenHan
|
|||
tokenHandlers["{Book CleanSubtitle}"] = m => CleanTitle(subtitle);
|
||||
tokenHandlers["{Book SubtitleThe}"] = m => TitleThe(subtitle);
|
||||
|
||||
var seriesLinks = edition.Book.Value.SeriesLinks.Value;
|
||||
if (seriesLinks.Any())
|
||||
{
|
||||
var primarySeries = seriesLinks.OrderBy(x => x.SeriesPosition).First();
|
||||
var seriesTitle = primarySeries.Series?.Value?.Title + (primarySeries.Position.IsNotNullOrWhiteSpace() ? $" #{primarySeries.Position}" : string.Empty);
|
||||
|
||||
tokenHandlers["{Book Series}"] = m => primarySeries.Series.Value.Title;
|
||||
tokenHandlers["{Book SeriesPosition}"] = m => primarySeries.Position;
|
||||
tokenHandlers["{Book SeriesTitle}"] = m => seriesTitle;
|
||||
}
|
||||
|
||||
if (edition.Disambiguation != null)
|
||||
{
|
||||
tokenHandlers["{Book Disambiguation}"] = m => edition.Disambiguation;
|
||||
|
|
|
|||
|
|
@ -37,12 +37,24 @@ public FileNameSampleService(IBuildFileNames buildFileNames)
|
|||
}
|
||||
};
|
||||
|
||||
var series = new Series
|
||||
{
|
||||
Title = "Series Title"
|
||||
};
|
||||
|
||||
var seriesLink = new SeriesBookLink
|
||||
{
|
||||
Position = "1",
|
||||
Series = series
|
||||
};
|
||||
|
||||
_standardBook = new Book
|
||||
{
|
||||
Title = "The Book Title",
|
||||
ReleaseDate = System.DateTime.Today,
|
||||
Author = _standardAuthor,
|
||||
AuthorMetadata = _standardAuthor.Metadata.Value
|
||||
AuthorMetadata = _standardAuthor.Metadata.Value,
|
||||
SeriesLinks = new List<SeriesBookLink> { seriesLink }
|
||||
};
|
||||
|
||||
_standardEdition = new Edition
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@ public static BookResource ToResource(this Book model)
|
|||
var title = selectedEdition?.Title ?? model.Title;
|
||||
var authorTitle = $"{model.Author?.Value?.Metadata?.Value?.SortNameLastFirst} {title}";
|
||||
|
||||
var seriesLinks = model.SeriesLinks?.Value?.OrderBy(x => x.SeriesPosition);
|
||||
var seriesTitle = seriesLinks?.Select(x => x?.Series?.Value?.Title + (x?.Position.IsNotNullOrWhiteSpace() ?? false ? $" #{x.Position}" : string.Empty)).ConcatToString("; ");
|
||||
|
||||
return new BookResource
|
||||
{
|
||||
Id = model.Id,
|
||||
|
|
@ -67,7 +70,7 @@ public static BookResource ToResource(this Book model)
|
|||
Genres = model.Genres,
|
||||
Title = title,
|
||||
AuthorTitle = authorTitle,
|
||||
SeriesTitle = model.SeriesLinks?.Value?.Select(x => x?.Series?.Value?.Title + (x?.Position.IsNotNullOrWhiteSpace() ?? false ? $" #{x.Position}" : string.Empty)).ConcatToString("; "),
|
||||
SeriesTitle = seriesTitle,
|
||||
Disambiguation = selectedEdition?.Disambiguation,
|
||||
Overview = selectedEdition?.Overview,
|
||||
Images = selectedEdition?.Images ?? new List<MediaCover>(),
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ namespace Readarr.Api.V1.Series
|
|||
public class SeriesBookLinkResource : RestResource
|
||||
{
|
||||
public string Position { get; set; }
|
||||
public int SeriesPosition { get; set; }
|
||||
public int SeriesId { get; set; }
|
||||
public int BookId { get; set; }
|
||||
}
|
||||
|
|
@ -20,6 +21,7 @@ public static SeriesBookLinkResource ToResource(this SeriesBookLink model)
|
|||
{
|
||||
Id = model.Id,
|
||||
Position = model.Position,
|
||||
SeriesPosition = model.SeriesPosition,
|
||||
SeriesId = model.SeriesId,
|
||||
BookId = model.BookId
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue