mirror of
https://github.com/sphildreth/roadie
synced 2024-11-10 06:44:12 +00:00
Genre work. Artist counts now are both tracks and releases.
This commit is contained in:
parent
f5e57d083d
commit
70d754aa5f
11 changed files with 112 additions and 59 deletions
|
@ -26,7 +26,7 @@ namespace Roadie.Library.Data
|
|||
public ICollection<CollectionRelease> Collections { get; set; }
|
||||
|
||||
[Column("duration")]
|
||||
public int? Duration { get; set; } // TODO update this on release scan
|
||||
public int? Duration { get; set; }
|
||||
|
||||
[Column("discogsId")]
|
||||
[MaxLength(50)]
|
||||
|
|
|
@ -6,6 +6,7 @@ using Roadie.Library.Encoding;
|
|||
using Roadie.Library.Engines;
|
||||
using Roadie.Library.SearchEngines.MetaData;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
@ -35,6 +36,29 @@ namespace Roadie.Library.Factories
|
|||
this.ReleaseLookupEngine = releaseLookupEngine;
|
||||
}
|
||||
|
||||
protected IEnumerable<int> ArtistIdsForRelease(int releaseId)
|
||||
{
|
||||
var trackArtistIds = (from r in this.DbContext.Releases
|
||||
join rm in this.DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
|
||||
join tr in this.DbContext.Tracks on rm.Id equals tr.ReleaseMediaId
|
||||
where r.Id == releaseId
|
||||
where tr.ArtistId != null
|
||||
select tr.ArtistId.Value).ToList();
|
||||
trackArtistIds.Add(this.DbContext.Releases.FirstOrDefault(x => x.Id == releaseId).ArtistId);
|
||||
return trackArtistIds.Distinct().ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the counts for all artists on a release (both track and release artists)
|
||||
/// </summary>
|
||||
protected async Task UpdateArtistCountsForRelease(int releaseId, DateTime now)
|
||||
{
|
||||
foreach(var artistId in this.ArtistIdsForRelease(releaseId))
|
||||
{
|
||||
await this.UpdateArtistCounts(artistId, now);
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task UpdateArtistCounts(int artistId, DateTime now)
|
||||
{
|
||||
var artist = this.DbContext.Artists.FirstOrDefault(x => x.Id == artistId);
|
||||
|
@ -44,8 +68,9 @@ namespace Roadie.Library.Factories
|
|||
artist.TrackCount = (from r in this.DbContext.Releases
|
||||
join rm in this.DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
|
||||
join tr in this.DbContext.Tracks on rm.Id equals tr.ReleaseMediaId
|
||||
where r.ArtistId == artistId
|
||||
where (tr.ArtistId == artistId || r.ArtistId == artistId)
|
||||
select tr).Count();
|
||||
|
||||
artist.LastUpdated = now;
|
||||
await this.DbContext.SaveChangesAsync();
|
||||
this.CacheManager.ClearRegion(artist.CacheRegion);
|
||||
|
|
|
@ -809,8 +809,9 @@ namespace Roadie.Library.Factories
|
|||
|
||||
sw.Stop();
|
||||
|
||||
|
||||
await base.UpdateReleaseCounts(release.Id, now);
|
||||
await base.UpdateArtistCounts(release.ArtistId, now);
|
||||
await base.UpdateArtistCountsForRelease(release.Id, now);
|
||||
if(release.Labels != null && release.Labels.Any())
|
||||
{
|
||||
foreach(var label in release.Labels)
|
||||
|
|
|
@ -8,6 +8,8 @@ namespace Roadie.Library.Models
|
|||
public class GenreList : EntityInfoModelBase
|
||||
{
|
||||
public DataToken Genre { get; set; }
|
||||
public int? ReleaseCount { get; set; }
|
||||
public int? ArtistCount { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -219,13 +219,10 @@ namespace Roadie.Api.Services
|
|||
if (includes.Contains("stats"))
|
||||
{
|
||||
tsw.Restart();
|
||||
|
||||
// TODO this should be on artist properties to speed up fetch times
|
||||
|
||||
var artistTracks = (from r in this.DbContext.Releases
|
||||
join rm in this.DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
|
||||
join t in this.DbContext.Tracks on rm.Id equals t.ReleaseMediaId
|
||||
where r.ArtistId == artist.Id
|
||||
where (r.ArtistId == artist.Id || t.ArtistId == artist.Id)
|
||||
select new
|
||||
{
|
||||
t.Id,
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace Roadie.Api.Services
|
|||
{
|
||||
}
|
||||
|
||||
public Task<Library.Models.Pagination.PagedResult<GenreList>> List(User roadieUser, PagedRequest request)
|
||||
public Task<Library.Models.Pagination.PagedResult<GenreList>> List(User roadieUser, PagedRequest request, bool? doRandomize = false)
|
||||
{
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
@ -39,6 +39,12 @@ namespace Roadie.Api.Services
|
|||
request.Sort = request.Sort.Replace("lastUpdated", "lastUpdatedDateTime");
|
||||
}
|
||||
var result = (from g in this.DbContext.Genres
|
||||
let releaseCount = (from rg in this.DbContext.ReleaseGenres
|
||||
where rg.GenreId == g.Id
|
||||
select rg.Id).Count()
|
||||
let artistCount = (from rg in this.DbContext.ArtistGenres
|
||||
where rg.GenreId == g.Id
|
||||
select rg.Id).Count()
|
||||
where (request.FilterValue.Length == 0 || (g.Name.Contains(request.FilterValue)))
|
||||
select new GenreList
|
||||
{
|
||||
|
@ -49,14 +55,25 @@ namespace Roadie.Api.Services
|
|||
Text = g.Name,
|
||||
Value = g.RoadieId.ToString()
|
||||
},
|
||||
ReleaseCount = releaseCount,
|
||||
ArtistCount = artistCount,
|
||||
CreatedDate = g.CreatedDate,
|
||||
LastUpdated = g.LastUpdated,
|
||||
});
|
||||
|
||||
GenreList[] rows = null;
|
||||
var rowCount = result.Count();
|
||||
var sortBy = string.IsNullOrEmpty(request.Sort) ? request.OrderValue(new Dictionary<string, string> { { "Genre.Text", "ASC" } }) : request.OrderValue(null);
|
||||
rows = result.OrderBy(sortBy).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
|
||||
if (doRandomize ?? false)
|
||||
{
|
||||
var randomLimit = roadieUser?.RandomReleaseLimit ?? 100;
|
||||
request.Limit = request.LimitValue > randomLimit ? randomLimit : request.LimitValue;
|
||||
rows = result.OrderBy(x => Guid.NewGuid()).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
var sortBy = string.IsNullOrEmpty(request.Sort) ? request.OrderValue(new Dictionary<string, string> { { "Genre.Text", "ASC" } }) : request.OrderValue(null);
|
||||
rows = result.OrderBy(sortBy).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
|
||||
}
|
||||
sw.Stop();
|
||||
return Task.FromResult(new Library.Models.Pagination.PagedResult<GenreList>
|
||||
{
|
||||
|
|
|
@ -7,6 +7,6 @@ namespace Roadie.Api.Services
|
|||
{
|
||||
public interface IGenreService
|
||||
{
|
||||
Task<PagedResult<GenreList>> List(User roadieUser, PagedRequest request);
|
||||
Task<PagedResult<GenreList>> List(User roadieUser, PagedRequest request, bool? doRandomize = false);
|
||||
}
|
||||
}
|
|
@ -732,7 +732,6 @@ namespace Roadie.Api.Services
|
|||
}
|
||||
if (includes.Contains("stats"))
|
||||
{
|
||||
// TODO move these to release properties to speed up fetch times
|
||||
var releaseTracks = (from r in this.DbContext.Releases
|
||||
join rm in this.DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
|
||||
join t in this.DbContext.Tracks on rm.Id equals t.ReleaseMediaId
|
||||
|
|
|
@ -366,51 +366,59 @@ namespace Roadie.Api.Services
|
|||
/// </summary>
|
||||
public async Task<subsonic.SubsonicOperationResult<subsonic.Response>> GetAlbum(subsonic.Request request, User roadieUser)
|
||||
{
|
||||
var releaseId = SafeParser.ToGuid(request.id);
|
||||
if (!releaseId.HasValue)
|
||||
try
|
||||
{
|
||||
return new subsonic.SubsonicOperationResult<subsonic.Response>(subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Release [{ request.ReleaseId}]");
|
||||
}
|
||||
var release = this.GetRelease(releaseId.Value);
|
||||
if (release == null)
|
||||
{
|
||||
return new subsonic.SubsonicOperationResult<subsonic.Response>(subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Release [{ request.ReleaseId}]");
|
||||
}
|
||||
var trackPagedRequest = request.PagedRequest;
|
||||
trackPagedRequest.Sort = "TrackNumber";
|
||||
trackPagedRequest.Order = "ASC";
|
||||
var releaseTracks = await this.TrackService.List(trackPagedRequest, roadieUser, false, releaseId);
|
||||
var userRelease = roadieUser == null ? null : this.DbContext.UserReleases.FirstOrDefault(x => x.ReleaseId == release.Id && x.UserId == roadieUser.Id);
|
||||
var genre = release.Genres.FirstOrDefault();
|
||||
return new subsonic.SubsonicOperationResult<subsonic.Response>
|
||||
{
|
||||
IsSuccess = true,
|
||||
Data = new subsonic.Response
|
||||
var releaseId = SafeParser.ToGuid(request.id);
|
||||
if (!releaseId.HasValue)
|
||||
{
|
||||
version = SubsonicService.SubsonicVersion,
|
||||
status = subsonic.ResponseStatus.ok,
|
||||
ItemElementName = subsonic.ItemChoiceType.album,
|
||||
Item = new subsonic.AlbumWithSongsID3
|
||||
{
|
||||
artist = release.Artist.Name,
|
||||
artistId = subsonic.Request.ArtistIdIdentifier + release.Artist.RoadieId.ToString(),
|
||||
coverArt = subsonic.Request.ReleaseIdIdentifier + release.RoadieId.ToString(),
|
||||
created = release.CreatedDate,
|
||||
duration = release.Duration.ToSecondsFromMilliseconds(),
|
||||
genre = genre == null ? null : genre.Genre.Name,
|
||||
id = subsonic.Request.ReleaseIdIdentifier + release.RoadieId.ToString(),
|
||||
name = release.Title,
|
||||
playCount = releaseTracks.Rows.Sum(x => x.PlayedCount) ?? 0,
|
||||
playCountSpecified = releaseTracks.Rows.Any(),
|
||||
songCount = releaseTracks.Rows.Count(),
|
||||
starred = userRelease?.LastUpdated ?? userRelease?.CreatedDate ?? DateTime.UtcNow,
|
||||
starredSpecified = userRelease?.IsFavorite ?? false,
|
||||
year = release.ReleaseDate != null ? release.ReleaseDate.Value.Year : 0,
|
||||
yearSpecified = release.ReleaseDate != null,
|
||||
song = this.SubsonicChildrenForTracks(releaseTracks.Rows)
|
||||
}
|
||||
return new subsonic.SubsonicOperationResult<subsonic.Response>(subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Release [{ request.ReleaseId}]");
|
||||
}
|
||||
};
|
||||
var release = this.GetRelease(releaseId.Value);
|
||||
if (release == null)
|
||||
{
|
||||
return new subsonic.SubsonicOperationResult<subsonic.Response>(subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Release [{ request.ReleaseId}]");
|
||||
}
|
||||
var trackPagedRequest = request.PagedRequest;
|
||||
trackPagedRequest.Sort = "TrackNumber";
|
||||
trackPagedRequest.Order = "ASC";
|
||||
var releaseTracks = await this.TrackService.List(trackPagedRequest, roadieUser, false, releaseId);
|
||||
var userRelease = roadieUser == null ? null : this.DbContext.UserReleases.FirstOrDefault(x => x.ReleaseId == release.Id && x.UserId == roadieUser.Id);
|
||||
var genre = release.Genres.FirstOrDefault();
|
||||
return new subsonic.SubsonicOperationResult<subsonic.Response>
|
||||
{
|
||||
IsSuccess = true,
|
||||
Data = new subsonic.Response
|
||||
{
|
||||
version = SubsonicService.SubsonicVersion,
|
||||
status = subsonic.ResponseStatus.ok,
|
||||
ItemElementName = subsonic.ItemChoiceType.album,
|
||||
Item = new subsonic.AlbumWithSongsID3
|
||||
{
|
||||
artist = release.Artist.Name,
|
||||
artistId = subsonic.Request.ArtistIdIdentifier + release.Artist.RoadieId.ToString(),
|
||||
coverArt = subsonic.Request.ReleaseIdIdentifier + release.RoadieId.ToString(),
|
||||
created = release.CreatedDate,
|
||||
duration = release.Duration.ToSecondsFromMilliseconds(),
|
||||
genre = genre == null ? null : genre.Genre.Name,
|
||||
id = subsonic.Request.ReleaseIdIdentifier + release.RoadieId.ToString(),
|
||||
name = release.Title,
|
||||
playCount = releaseTracks.Rows.Sum(x => x.PlayedCount) ?? 0,
|
||||
playCountSpecified = releaseTracks.Rows.Any(),
|
||||
songCount = releaseTracks.Rows.Count(),
|
||||
starred = userRelease?.LastUpdated ?? userRelease?.CreatedDate ?? DateTime.UtcNow,
|
||||
starredSpecified = userRelease?.IsFavorite ?? false,
|
||||
year = release.ReleaseDate != null ? release.ReleaseDate.Value.Year : 0,
|
||||
yearSpecified = release.ReleaseDate != null,
|
||||
song = this.SubsonicChildrenForTracks(releaseTracks.Rows)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, "GetAlbum Request [{0}], User [{1}]", JsonConvert.SerializeObject(request), roadieUser.ToString());
|
||||
}
|
||||
return new subsonic.SubsonicOperationResult<subsonic.Response>(subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Release [{ request.ReleaseId}]");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -516,11 +516,14 @@ namespace Roadie.Api.Services
|
|||
where ua.UserId == roadieUser.Id
|
||||
where trackArtistIds.Contains(ua.ArtistId)
|
||||
select ua).ToArray();
|
||||
foreach (var userTrackArtistRating in userTrackArtistRatings)
|
||||
if (userTrackArtistRatings != null && userTrackArtistRatings.Any())
|
||||
{
|
||||
foreach (var artistTrack in rows.Where(x => x.TrackArtist.DatabaseId == userTrackArtistRating.ArtistId))
|
||||
foreach (var userTrackArtistRating in userTrackArtistRatings)
|
||||
{
|
||||
artistTrack.Artist.UserRating = userTrackArtistRating.Adapt<UserArtist>();
|
||||
foreach (var artistTrack in rows.Where(x => x.TrackArtist != null && x.TrackArtist.DatabaseId == userTrackArtistRating.ArtistId))
|
||||
{
|
||||
artistTrack.Artist.UserRating = userTrackArtistRating.Adapt<UserArtist>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,10 +57,11 @@ namespace Roadie.Api.Controllers
|
|||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(200)]
|
||||
public async Task<IActionResult> List([FromQuery]PagedRequest request)
|
||||
public async Task<IActionResult> List([FromQuery]PagedRequest request, bool? doRandomize = false)
|
||||
{
|
||||
var result = await this.GenreService.List(roadieUser: await this.CurrentUserModel(),
|
||||
request: request);
|
||||
request: request,
|
||||
doRandomize: doRandomize);
|
||||
if (!result.IsSuccess)
|
||||
{
|
||||
return StatusCode((int)HttpStatusCode.InternalServerError);
|
||||
|
|
Loading…
Reference in a new issue