Fixed: Calculate author statistics correctly

Fixes #1213
pull/1237/head
ta264 3 years ago
parent 12c67891fb
commit 72ae466892

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using FizzWare.NBuilder; using FizzWare.NBuilder;
using FluentAssertions; using FluentAssertions;
@ -17,7 +18,7 @@ namespace NzbDrone.Core.Test.AuthorStatsTests
private Author _author; private Author _author;
private Book _book; private Book _book;
private Edition _edition; private Edition _edition;
private BookFile _trackFile; private List<BookFile> _bookFiles;
[SetUp] [SetUp]
public void Setup() public void Setup()
@ -39,17 +40,24 @@ namespace NzbDrone.Core.Test.AuthorStatsTests
.BuildNew(); .BuildNew();
Db.Insert(_edition); Db.Insert(_edition);
_trackFile = Builder<BookFile>.CreateNew() _bookFiles = Builder<BookFile>.CreateListOfSize(2)
.All()
.With(x => x.Id = 0)
.With(e => e.Author = _author) .With(e => e.Author = _author)
.With(e => e.Edition = _edition) .With(e => e.Edition = _edition)
.With(e => e.EditionId == _edition.Id) .With(e => e.EditionId = _edition.Id)
.With(e => e.Quality = new QualityModel(Quality.MP3)) .With(e => e.Quality = new QualityModel(Quality.MP3))
.BuildNew(); .BuildList();
}
private void GivenBookFile()
{
Db.Insert(_bookFiles[0]);
} }
private void GivenTrackFile() private void GivenTwoBookFiles()
{ {
Db.Insert(_trackFile); Db.InsertMany(_bookFiles);
} }
[Test] [Test]
@ -61,7 +69,7 @@ namespace NzbDrone.Core.Test.AuthorStatsTests
} }
[Test] [Test]
public void should_not_include_unmonitored_track_in_track_count() public void should_not_include_unmonitored_book_in_book_count()
{ {
var stats = Subject.AuthorStatistics(); var stats = Subject.AuthorStatistics();
@ -70,9 +78,9 @@ namespace NzbDrone.Core.Test.AuthorStatsTests
} }
[Test] [Test]
public void should_include_unmonitored_track_with_file_in_track_count() public void should_include_unmonitored_book_with_file_in_book_count()
{ {
GivenTrackFile(); GivenBookFile();
var stats = Subject.AuthorStatistics(); var stats = Subject.AuthorStatistics();
@ -81,7 +89,7 @@ namespace NzbDrone.Core.Test.AuthorStatsTests
} }
[Test] [Test]
public void should_have_size_on_disk_of_zero_when_no_track_file() public void should_have_size_on_disk_of_zero_when_no_book_file()
{ {
var stats = Subject.AuthorStatistics(); var stats = Subject.AuthorStatistics();
@ -90,14 +98,33 @@ namespace NzbDrone.Core.Test.AuthorStatsTests
} }
[Test] [Test]
public void should_have_size_on_disk_when_track_file_exists() public void should_have_size_on_disk_when_book_file_exists()
{
GivenBookFile();
var stats = Subject.AuthorStatistics();
stats.Should().HaveCount(1);
stats.First().SizeOnDisk.Should().Be(_bookFiles[0].Size);
}
[Test]
public void should_count_book_with_two_files_as_one_book()
{ {
GivenTrackFile(); GivenTwoBookFiles();
var stats = Subject.AuthorStatistics(); var stats = Subject.AuthorStatistics();
Db.All<BookFile>().Should().HaveCount(2);
stats.Should().HaveCount(1); stats.Should().HaveCount(1);
stats.First().SizeOnDisk.Should().Be(_trackFile.Size);
var bookStats = stats.First();
bookStats.TotalBookCount.Should().Be(1);
bookStats.BookCount.Should().Be(1);
bookStats.AvailableBookCount.Should().Be(1);
bookStats.SizeOnDisk.Should().Be(_bookFiles.Sum(x => x.Size));
bookStats.BookFileCount.Should().Be(2);
} }
} }
} }

@ -6,9 +6,10 @@ namespace NzbDrone.Core.AuthorStats
public class AuthorStatistics : ResultSet public class AuthorStatistics : ResultSet
{ {
public int AuthorId { get; set; } public int AuthorId { get; set; }
public int BookFileCount { get; set; }
public int BookCount { get; set; } public int BookCount { get; set; }
public int AvailableBookCount { get; set; }
public int TotalBookCount { get; set; } public int TotalBookCount { get; set; }
public int BookFileCount { get; set; }
public long SizeOnDisk { get; set; } public long SizeOnDisk { get; set; }
public List<BookStatistics> BookStatistics { get; set; } public List<BookStatistics> BookStatistics { get; set; }
} }

@ -28,7 +28,6 @@ namespace NzbDrone.Core.AuthorStats
public List<BookStatistics> AuthorStatistics() public List<BookStatistics> AuthorStatistics()
{ {
var time = DateTime.UtcNow; var time = DateTime.UtcNow;
var stats = Query(Builder());
#pragma warning disable CS0472 #pragma warning disable CS0472
return Query(Builder().OrWhere<Book>(x => x.ReleaseDate < time) return Query(Builder().OrWhere<Book>(x => x.ReleaseDate < time)
@ -60,10 +59,10 @@ namespace NzbDrone.Core.AuthorStats
.Select(@"Authors.Id AS AuthorId, .Select(@"Authors.Id AS AuthorId,
Books.Id AS BookId, Books.Id AS BookId,
SUM(COALESCE(BookFiles.Size, 0)) AS SizeOnDisk, SUM(COALESCE(BookFiles.Size, 0)) AS SizeOnDisk,
COUNT(Books.Id) AS TotalBookCount, 1 AS TotalBookCount,
SUM(CASE WHEN BookFiles.Id IS NULL THEN 0 ELSE 1 END) AS AvailableBookCount, CASE WHEN BookFiles.Id IS NULL THEN 0 ELSE 1 END AS AvailableBookCount,
SUM(CASE WHEN Books.Monitored = 1 OR BookFiles.Id IS NOT NULL THEN 1 ELSE 0 END) AS BookCount, CASE WHEN Books.Monitored = 1 OR BookFiles.Id IS NOT NULL THEN 1 ELSE 0 END AS BookCount,
SUM(CASE WHEN BookFiles.Id IS NULL THEN 0 ELSE 1 END) AS BookFileCount") CASE WHEN BookFiles.Id IS NULL THEN 0 ELSE COUNT(BookFiles.Id) END AS BookFileCount")
.Join<Edition, Book>((e, b) => e.BookId == b.Id) .Join<Edition, Book>((e, b) => e.BookId == b.Id)
.Join<Book, Author>((book, author) => book.AuthorMetadataId == author.AuthorMetadataId) .Join<Book, Author>((book, author) => book.AuthorMetadataId == author.AuthorMetadataId)
.LeftJoin<Edition, BookFile>((t, f) => t.Id == f.EditionId) .LeftJoin<Edition, BookFile>((t, f) => t.Id == f.EditionId)

@ -56,12 +56,13 @@ namespace NzbDrone.Core.AuthorStats
{ {
var authorStatistics = new AuthorStatistics var authorStatistics = new AuthorStatistics
{ {
BookStatistics = bookStatistics,
BookCount = bookStatistics.Sum(s => s.BookCount),
TotalBookCount = bookStatistics.Sum(s => s.TotalBookCount),
AuthorId = bookStatistics.First().AuthorId, AuthorId = bookStatistics.First().AuthorId,
BookFileCount = bookStatistics.Sum(s => s.BookFileCount), BookFileCount = bookStatistics.Sum(s => s.BookFileCount),
SizeOnDisk = bookStatistics.Sum(s => s.SizeOnDisk) BookCount = bookStatistics.Sum(s => s.BookCount),
AvailableBookCount = bookStatistics.Sum(s => s.AvailableBookCount),
TotalBookCount = bookStatistics.Sum(s => s.TotalBookCount),
SizeOnDisk = bookStatistics.Sum(s => s.SizeOnDisk),
BookStatistics = bookStatistics
}; };
return authorStatistics; return authorStatistics;

@ -8,7 +8,8 @@ namespace NzbDrone.Core.AuthorStats
public int BookId { get; set; } public int BookId { get; set; }
public int BookFileCount { get; set; } public int BookFileCount { get; set; }
public int BookCount { get; set; } public int BookCount { get; set; }
public long SizeOnDisk { get; set; } public int AvailableBookCount { get; set; }
public int TotalBookCount { get; set; } public int TotalBookCount { get; set; }
public long SizeOnDisk { get; set; }
} }
} }

@ -4,8 +4,9 @@ namespace Readarr.Api.V1.Author
{ {
public class AuthorStatisticsResource public class AuthorStatisticsResource
{ {
public int BookCount { get; set; }
public int BookFileCount { get; set; } public int BookFileCount { get; set; }
public int BookCount { get; set; }
public int AvailableBookCount { get; set; }
public int TotalBookCount { get; set; } public int TotalBookCount { get; set; }
public long SizeOnDisk { get; set; } public long SizeOnDisk { get; set; }
@ -18,7 +19,7 @@ namespace Readarr.Api.V1.Author
return 0; return 0;
} }
return BookFileCount / (decimal)BookCount * 100; return AvailableBookCount / (decimal)BookCount * 100;
} }
} }
} }
@ -34,9 +35,10 @@ namespace Readarr.Api.V1.Author
return new AuthorStatisticsResource return new AuthorStatisticsResource
{ {
BookFileCount = model.BookFileCount,
BookCount = model.BookCount, BookCount = model.BookCount,
AvailableBookCount = model.AvailableBookCount,
TotalBookCount = model.TotalBookCount, TotalBookCount = model.TotalBookCount,
BookFileCount = model.BookFileCount,
SizeOnDisk = model.SizeOnDisk SizeOnDisk = model.SizeOnDisk
}; };
} }

Loading…
Cancel
Save