que and playlist work

This commit is contained in:
Steven Hildreth 2018-12-30 14:57:06 -06:00
parent a22bed9ce4
commit 7716013a2a
6 changed files with 290 additions and 77 deletions

View file

@ -36,6 +36,7 @@ namespace Roadie.Library.Factories
this.ReleaseLookupEngine = releaseLookupEngine;
}
[Obsolete("Use Service Methods")]
protected IEnumerable<int> ArtistIdsForRelease(int releaseId)
{
var trackArtistIds = (from r in this.DbContext.Releases
@ -48,6 +49,7 @@ namespace Roadie.Library.Factories
return trackArtistIds.Distinct().ToArray();
}
[Obsolete("Use Service Methods")]
/// <summary>
/// Update the counts for all artists on a release (both track and release artists)
/// </summary>
@ -59,6 +61,7 @@ namespace Roadie.Library.Factories
}
}
[Obsolete("Use Service Methods")]
protected async Task UpdateArtistCounts(int artistId, DateTime now)
{
var artist = this.DbContext.Artists.FirstOrDefault(x => x.Id == artistId);
@ -77,6 +80,7 @@ namespace Roadie.Library.Factories
}
}
[Obsolete("Use Service Methods")]
protected async Task UpdateLabelCounts(int labelId, DateTime now)
{
var label = this.DbContext.Labels.FirstOrDefault(x => x.Id == labelId);
@ -100,6 +104,7 @@ namespace Roadie.Library.Factories
}
}
[Obsolete("Use Service Methods")]
protected async Task UpdateReleaseCounts(int releaseId, DateTime now)
{
var release = this.DbContext.Releases.FirstOrDefault(x => x.Id == releaseId);

View file

@ -19,6 +19,7 @@ namespace Roadie.Library.Factories
{
}
[Obsolete("Use PlaylistService")]
public async Task<OperationResult<bool>> AddTracksToPlaylist(Playlist playlist, IEnumerable<Guid> trackIds)
{
var sw = new Stopwatch();
@ -57,6 +58,7 @@ namespace Roadie.Library.Factories
};
}
[Obsolete("Use PlaylistService")]
public async Task<OperationResult<bool>> ReorderPlaylist(Playlist playlist)
{
var sw = new Stopwatch();

View file

@ -5,13 +5,20 @@ using Roadie.Library.Models.Users;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using data = Roadie.Library.Data;
namespace Roadie.Api.Services
{
public interface IPlaylistService
{
Task<OperationResult<PlaylistList>> AddNewPlaylist(User user, Playlist model);
Task<OperationResult<bool>> AddTracksToPlaylist(data.Playlist playlist, IEnumerable<Guid> trackIds);
Task<OperationResult<Playlist>> ById(User roadieUser, Guid id, IEnumerable<string> includes = null);
Task<PagedResult<PlaylistList>> List(PagedRequest request, User roadieUser = null);
Task<OperationResult<bool>> ReorderPlaylist(data.Playlist playlist);
}
}

View file

@ -10,7 +10,6 @@ using Roadie.Library.Extensions;
using Roadie.Library.Models;
using Roadie.Library.Models.Pagination;
using Roadie.Library.Models.Playlists;
using Roadie.Library.Models.Releases;
using Roadie.Library.Models.Users;
using Roadie.Library.Utility;
using System;
@ -39,6 +38,70 @@ namespace Roadie.Api.Services
this.BookmarkService = bookmarkService;
}
public async Task<OperationResult<PlaylistList>> AddNewPlaylist(User user, Playlist model)
{
var playlist = new data.Playlist
{
IsPublic = model.IsPublic,
Description = model.Description,
Name = model.Name,
UserId = user.Id
};
this.DbContext.Playlists.Add(playlist);
await this.DbContext.SaveChangesAsync();
var r = await this.AddTracksToPlaylist(playlist, model.Tracks.OrderBy(x => x.ListNumber).Select(x => x.Track.Id));
var request = new PagedRequest
{
FilterToPlaylistId = playlist.RoadieId
};
var result = await this.List(request, user);
return new OperationResult<PlaylistList>
{
Data = result.Rows.First(),
IsSuccess = true
};
}
public async Task<OperationResult<bool>> AddTracksToPlaylist(data.Playlist playlist, IEnumerable<Guid> trackIds)
{
var sw = new Stopwatch();
sw.Start();
var result = false;
var now = DateTime.UtcNow;
var existingTracksForPlaylist = (from plt in this.DbContext.PlaylistTracks
join t in this.DbContext.Tracks on plt.TrackId equals t.Id
where plt.PlayListId == playlist.Id
select t);
var newTracksForPlaylist = (from t in this.DbContext.Tracks
where (from x in trackIds select x).Contains(t.RoadieId)
where !(from x in existingTracksForPlaylist select x.RoadieId).Contains(t.RoadieId)
select t).ToArray();
foreach (var newTrackForPlaylist in newTracksForPlaylist)
{
this.DbContext.PlaylistTracks.Add(new data.PlaylistTrack
{
TrackId = newTrackForPlaylist.Id,
PlayListId = playlist.Id
});
}
playlist.LastUpdated = now;
await this.DbContext.SaveChangesAsync();
result = true;
var r = await this.ReorderPlaylist(playlist);
result = result && r.IsSuccess;
await base.UpdatePlaylistCounts(playlist.Id, now);
return new OperationResult<bool>
{
IsSuccess = result,
Data = result
};
}
public async Task<OperationResult<Playlist>> ById(User roadieUser, Guid id, IEnumerable<string> includes = null)
{
var sw = Stopwatch.StartNew();
@ -68,6 +131,87 @@ namespace Roadie.Api.Services
};
}
public Task<Library.Models.Pagination.PagedResult<PlaylistList>> List(PagedRequest request, User roadieUser = null)
{
var sw = new Stopwatch();
sw.Start();
int[] playlistWithArtistTrackIds = new int[0];
if (request.FilterToArtistId.HasValue)
{
playlistWithArtistTrackIds = (from pl in this.DbContext.Playlists
join pltr in this.DbContext.PlaylistTracks on pl.Id equals pltr.PlayListId
join t in this.DbContext.Tracks on pltr.TrackId equals t.Id
join rm in this.DbContext.ReleaseMedias on t.ReleaseMediaId equals rm.Id
join r in this.DbContext.Releases on rm.ReleaseId equals r.Id
join a in this.DbContext.Artists on r.ArtistId equals a.Id
where a.RoadieId == request.FilterToArtistId
select pl.Id
).ToArray();
}
int[] playlistReleaseTrackIds = new int[0];
if (request.FilterToReleaseId.HasValue)
{
playlistReleaseTrackIds = (from pl in this.DbContext.Playlists
join pltr in this.DbContext.PlaylistTracks on pl.Id equals pltr.PlayListId
join t in this.DbContext.Tracks on pltr.TrackId equals t.Id
join rm in this.DbContext.ReleaseMedias on t.ReleaseMediaId equals rm.Id
join r in this.DbContext.Releases on rm.ReleaseId equals r.Id
where r.RoadieId == request.FilterToReleaseId
select pl.Id
).ToArray();
}
var result = (from pl in this.DbContext.Playlists
join u in this.DbContext.Users on pl.UserId equals u.Id
where (request.FilterToPlaylistId == null || pl.RoadieId == request.FilterToPlaylistId)
where (request.FilterToArtistId == null || playlistWithArtistTrackIds.Contains(pl.Id))
where (request.FilterToReleaseId == null || playlistReleaseTrackIds.Contains(pl.Id))
where ((roadieUser == null && pl.IsPublic) || (roadieUser != null && u.RoadieId == roadieUser.UserId || pl.IsPublic))
where (request.FilterValue.Length == 0 || (request.FilterValue.Length > 0 && (pl.Name != null && pl.Name.Contains(request.FilterValue))))
select PlaylistList.FromDataPlaylist(pl, u, this.MakePlaylistThumbnailImage(pl.RoadieId), this.MakeUserThumbnailImage(u.RoadieId)));
var sortBy = string.IsNullOrEmpty(request.Sort) ? request.OrderValue(new Dictionary<string, string> { { "Playlist.Text", "ASC" } }) : request.OrderValue(null);
var rowCount = result.Count();
var rows = result.OrderBy(sortBy).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
sw.Stop();
return Task.FromResult(new Library.Models.Pagination.PagedResult<PlaylistList>
{
TotalCount = rowCount,
CurrentPage = request.PageValue,
TotalPages = (int)Math.Ceiling((double)rowCount / request.LimitValue),
OperationTime = sw.ElapsedMilliseconds,
Rows = rows
});
}
public async Task<OperationResult<bool>> ReorderPlaylist(data.Playlist playlist)
{
var sw = new Stopwatch();
sw.Start();
var result = false;
var now = DateTime.UtcNow;
if (playlist != null)
{
var looper = 0;
foreach (var playlistTrack in this.DbContext.PlaylistTracks.Where(x => x.PlayListId == playlist.Id).OrderBy(x => x.CreatedDate))
{
looper++;
playlistTrack.ListNumber = looper;
playlistTrack.LastUpdated = now;
}
await this.DbContext.SaveChangesAsync();
result = true;
}
return new OperationResult<bool>
{
IsSuccess = result,
Data = result
};
}
private Task<OperationResult<Playlist>> PlaylistByIdAction(Guid id, IEnumerable<string> includes = null)
{
var sw = Stopwatch.StartNew();
@ -109,27 +253,26 @@ namespace Roadie.Api.Services
if (includes.Contains("tracks"))
{
result.Tracks = (from plt in playlistTracks
join rm in this.DbContext.ReleaseMedias on plt.t.ReleaseMediaId equals rm.Id
join r in this.DbContext.Releases on rm.ReleaseId equals r.Id
join releaseArtist in this.DbContext.Artists on r.ArtistId equals releaseArtist.Id
join trackArtist in this.DbContext.Artists on plt.t.ArtistId equals trackArtist.Id into tas
from trackArtist in tas.DefaultIfEmpty()
select new PlaylistTrack
{
ListNumber = plt.pltr.ListNumber,
Track = TrackList.FromDataTrack(plt.t,
rm.MediaNumber,
r,
releaseArtist,
trackArtist,
this.HttpContext.BaseUrl,
this.MakeTrackThumbnailImage(plt.t.RoadieId),
this.MakeReleaseThumbnailImage(r.RoadieId),
this.MakeArtistThumbnailImage(releaseArtist.RoadieId),
this.MakeArtistThumbnailImage(trackArtist == null ? null : (Guid?)trackArtist.RoadieId))
}).ToArray();
join rm in this.DbContext.ReleaseMedias on plt.t.ReleaseMediaId equals rm.Id
join r in this.DbContext.Releases on rm.ReleaseId equals r.Id
join releaseArtist in this.DbContext.Artists on r.ArtistId equals releaseArtist.Id
join trackArtist in this.DbContext.Artists on plt.t.ArtistId equals trackArtist.Id into tas
from trackArtist in tas.DefaultIfEmpty()
select new PlaylistTrack
{
ListNumber = plt.pltr.ListNumber,
Track = TrackList.FromDataTrack(plt.t,
rm.MediaNumber,
r,
releaseArtist,
trackArtist,
this.HttpContext.BaseUrl,
this.MakeTrackThumbnailImage(plt.t.RoadieId),
this.MakeReleaseThumbnailImage(r.RoadieId),
this.MakeArtistThumbnailImage(releaseArtist.RoadieId),
this.MakeArtistThumbnailImage(trackArtist == null ? null : (Guid?)trackArtist.RoadieId))
}).ToArray();
}
}
sw.Stop();
@ -139,61 +282,6 @@ namespace Roadie.Api.Services
IsSuccess = result != null,
OperationTime = sw.ElapsedMilliseconds
});
}
public Task<Library.Models.Pagination.PagedResult<PlaylistList>> List(PagedRequest request, User roadieUser = null)
{
var sw = new Stopwatch();
sw.Start();
int[] playlistWithArtistTrackIds = new int[0];
if(request.FilterToArtistId.HasValue)
{
playlistWithArtistTrackIds = (from pl in this.DbContext.Playlists
join pltr in this.DbContext.PlaylistTracks on pl.Id equals pltr.PlayListId
join t in this.DbContext.Tracks on pltr.TrackId equals t.Id
join rm in this.DbContext.ReleaseMedias on t.ReleaseMediaId equals rm.Id
join r in this.DbContext.Releases on rm.ReleaseId equals r.Id
join a in this.DbContext.Artists on r.ArtistId equals a.Id
where a.RoadieId == request.FilterToArtistId
select pl.Id
).ToArray();
}
int[] playlistReleaseTrackIds = new int[0];
if(request.FilterToReleaseId.HasValue)
{
playlistReleaseTrackIds = (from pl in this.DbContext.Playlists
join pltr in this.DbContext.PlaylistTracks on pl.Id equals pltr.PlayListId
join t in this.DbContext.Tracks on pltr.TrackId equals t.Id
join rm in this.DbContext.ReleaseMedias on t.ReleaseMediaId equals rm.Id
join r in this.DbContext.Releases on rm.ReleaseId equals r.Id
where r.RoadieId == request.FilterToReleaseId
select pl.Id
).ToArray();
}
var result = (from pl in this.DbContext.Playlists
join u in this.DbContext.Users on pl.UserId equals u.Id
where (request.FilterToPlaylistId == null || pl.RoadieId == request.FilterToPlaylistId)
where (request.FilterToArtistId == null || playlistWithArtistTrackIds.Contains(pl.Id))
where (request.FilterToReleaseId == null || playlistReleaseTrackIds.Contains(pl.Id))
where ((roadieUser == null && pl.IsPublic) || (roadieUser != null && u.RoadieId == roadieUser.UserId || pl.IsPublic))
where (request.FilterValue.Length == 0 || (request.FilterValue.Length > 0 && (pl.Name != null && pl.Name.Contains(request.FilterValue))))
select PlaylistList.FromDataPlaylist(pl, u, this.MakePlaylistThumbnailImage(pl.RoadieId), this.MakeUserThumbnailImage(u.RoadieId)));
var sortBy = string.IsNullOrEmpty(request.Sort) ? request.OrderValue(new Dictionary<string, string> { { "Playlist.Text", "ASC" } }) : request.OrderValue(null);
var rowCount = result.Count();
var rows = result.OrderBy(sortBy).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
sw.Stop();
return Task.FromResult(new Library.Models.Pagination.PagedResult<PlaylistList>
{
TotalCount = rowCount,
CurrentPage = request.PageValue,
TotalPages = (int)Math.Ceiling((double)rowCount / request.LimitValue),
OperationTime = sw.ElapsedMilliseconds,
Rows = rows
});
}
}
}

View file

@ -8,6 +8,7 @@ using Roadie.Library.Identity;
using Roadie.Library.Models;
using Roadie.Library.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using data = Roadie.Library.Data;
@ -603,6 +604,100 @@ namespace Roadie.Api.Services
return new Image($"{this.HttpContext.ImageBaseUrl }/{type}/{id}", caption, null);
}
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);
if (artist != null)
{
artist.ReleaseCount = this.DbContext.Releases.Where(x => x.ArtistId == artistId).Count();
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 (tr.ArtistId == artistId || r.ArtistId == artistId)
select tr).Count();
artist.LastUpdated = now;
await this.DbContext.SaveChangesAsync();
this.CacheManager.ClearRegion(artist.CacheRegion);
}
}
protected async Task UpdatePlaylistCounts(int playlistId, DateTime now)
{
var playlist = this.DbContext.Playlists.FirstOrDefault(x => x.Id == playlistId);
if(playlist != null)
{
var playlistTracks = this.DbContext.PlaylistTracks
.Include(x => x.Track)
.Include("Track.ReleaseMedia")
.Where(x => x.PlayListId == playlist.Id).ToArray();
playlist.TrackCount = (short)playlistTracks.Count();
playlist.Duration = playlistTracks.Sum(x => x.Track.Duration);
playlist.ReleaseCount = (short)playlistTracks.Select(x => x.Track.ReleaseMedia.ReleaseId).Distinct().Count();
playlist.LastUpdated = now;
await this.DbContext.SaveChangesAsync();
this.CacheManager.ClearRegion(playlist.CacheRegion);
}
}
protected async Task UpdateLabelCounts(int labelId, DateTime now)
{
var label = this.DbContext.Labels.FirstOrDefault(x => x.Id == labelId);
if (label != null)
{
label.ReleaseCount = this.DbContext.ReleaseLabels.Where(x => x.LabelId == label.Id).Count();
label.ArtistCount = (from r in this.DbContext.Releases
join rl in this.DbContext.ReleaseLabels on r.Id equals rl.ReleaseId
join a in this.DbContext.Artists on r.ArtistId equals a.Id
where rl.LabelId == label.Id
group a by a.Id into artists
select artists).Select(x => x.Key).Count();
label.TrackCount = (from r in this.DbContext.Releases
join rl in this.DbContext.ReleaseLabels on r.Id equals rl.ReleaseId
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 rl.LabelId == label.Id
select t).Count();
await this.DbContext.SaveChangesAsync();
this.CacheManager.ClearRegion(label.CacheRegion);
}
}
protected async Task UpdateReleaseCounts(int releaseId, DateTime now)
{
var release = this.DbContext.Releases.FirstOrDefault(x => x.Id == releaseId);
if (release != null)
{
release.Duration = (from t in this.DbContext.Tracks
join rm in this.DbContext.ReleaseMedias on t.ReleaseMediaId equals rm.Id
where rm.ReleaseId == releaseId
select t).Sum(x => x.Duration);
await this.DbContext.SaveChangesAsync();
this.CacheManager.ClearRegion(release.CacheRegion);
}
}
}
}

View file

@ -6,8 +6,11 @@ using Microsoft.Extensions.Logging;
using Roadie.Api.Services;
using Roadie.Library.Caching;
using Roadie.Library.Identity;
using Roadie.Library.Models;
using Roadie.Library.Models.Pagination;
using Roadie.Library.Models.Playlists;
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using models = Roadie.Library.Models;
@ -59,5 +62,18 @@ namespace Roadie.Api.Controllers
return Ok(result);
}
[HttpPost("add")]
[ProducesResponseType(200)]
[ProducesResponseType(404)]
public async Task<IActionResult> AddNewPlaylist([FromBody]Playlist model)
{
var result = await this.PlaylistService.AddNewPlaylist(await this.CurrentUserModel(), model);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
return Ok(result);
}
}
}