track view work

This commit is contained in:
Steven Hildreth 2019-01-05 16:40:33 -06:00
parent f50b6ae360
commit c3da91765a
8 changed files with 450 additions and 347 deletions

View file

@ -1,8 +1,11 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using Roadie.Library.Models.Releases;
using Roadie.Library.Models.Statistics; using Roadie.Library.Models.Statistics;
using Roadie.Library.Models.Users; using Roadie.Library.Models.Users;
using System; using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
namespace Roadie.Library.Models namespace Roadie.Library.Models
{ {
@ -14,7 +17,7 @@ namespace Roadie.Library.Models
[MaxLength(50)] [MaxLength(50)]
public string AmgId { get; set; } public string AmgId { get; set; }
public DataToken Artist { get; set; } public ArtistList Artist { get; set; }
public Image ArtistThumbnail { get; set; } public Image ArtistThumbnail { get; set; }
public long FileSize { get; set; } public long FileSize { get; set; }
@ -35,11 +38,34 @@ namespace Roadie.Library.Models
public string MusicBrainzId { get; set; } public string MusicBrainzId { get; set; }
[MaxLength(65535)] [MaxLength(65535)]
[JsonIgnore]
[IgnoreDataMember]
public string PartTitles { get; set; } public string PartTitles { get; set; }
private IEnumerable<string> _partTitles = null;
public IEnumerable<string> PartTitlesList
{
get
{
if (this._partTitles == null)
{
if (string.IsNullOrEmpty(this.PartTitles))
{
return null;
}
return this.PartTitles.Split('|');
}
return this._partTitles;
}
set
{
this._partTitles = value;
}
}
public int PlayedCount { get; set; } public int PlayedCount { get; set; }
public short Rating { get; set; } public short Rating { get; set; }
public DataToken Release { get; set; } public ReleaseList Release { get; set; }
public string ReleaseMediaId { get; set; } public string ReleaseMediaId { get; set; }
@ -51,6 +77,7 @@ namespace Roadie.Library.Models
public TrackStatistics Statistics { get; set; } public TrackStatistics Statistics { get; set; }
public Image Thumbnail { get; set; } public Image Thumbnail { get; set; }
public Image MediumThumbnail { get; set; }
[MaxLength(250)] [MaxLength(250)]
[Required] [Required]
@ -59,7 +86,7 @@ namespace Roadie.Library.Models
/// <summary> /// <summary>
/// Track Artist, not release artist. If this is present then the track has an artist different than the release. /// Track Artist, not release artist. If this is present then the track has an artist different than the release.
/// </summary> /// </summary>
public DataToken TrackArtist { get; set; } public ArtistList TrackArtist { get; set; }
public Image TrackArtistThumbnail { get; set; } public Image TrackArtistThumbnail { get; set; }
@ -68,6 +95,6 @@ namespace Roadie.Library.Models
public UserTrack UserRating { get; set; } public UserTrack UserRating { get; set; }
public string PlayUrl { get; set; } public string TrackPlayUrl { get; set; }
} }
} }

View file

@ -38,6 +38,8 @@ namespace Roadie.Api.Services
Task<OperationResult<bool>> SetTrackBookmark(Guid trackId, User roadieUser, bool isBookmarked); Task<OperationResult<bool>> SetTrackBookmark(Guid trackId, User roadieUser, bool isBookmarked);
Task<OperationResult<short>> SetTrackRating(Guid trackId, User roadieUser, short rating); Task<OperationResult<short>> SetTrackRating(Guid trackId, User roadieUser, short rating);
Task<OperationResult<bool>> SetTrackDisliked(Guid trackId, User roadieUser, bool isDisliked);
Task<OperationResult<bool>> SetTrackFavorite(Guid releaseId, User roadieUser, bool isFavorite);
} }
} }

View file

@ -1,5 +1,6 @@
using Mapster; using Mapster;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Newtonsoft.Json; using Newtonsoft.Json;
using Roadie.Api.Hubs; using Roadie.Api.Hubs;
@ -118,9 +119,12 @@ namespace Roadie.Api.Services
public async Task<OperationResult<PlayActivityList>> CreatePlayActivity(User roadieUser, TrackStreamInfo streamInfo) public async Task<OperationResult<PlayActivityList>> CreatePlayActivity(User roadieUser, TrackStreamInfo streamInfo)
{ {
var sw = Stopwatch.StartNew(); var sw = Stopwatch.StartNew();
var track = this.DbContext.Tracks
var track = this.GetTrack(streamInfo.Track.Value); .Include(x => x.ReleaseMedia)
.Include(x => x.ReleaseMedia.Release)
.Include(x => x.ReleaseMedia.Release.Artist)
.Include(x => x.TrackArtist)
.FirstOrDefault(x => x.RoadieId == SafeParser.ToGuid(streamInfo.Track.Value));
if (track == null) if (track == null)
{ {
return new OperationResult<PlayActivityList>($"CreatePlayActivity: Unable To Find Track [{ streamInfo.Track.Value }]"); return new OperationResult<PlayActivityList>($"CreatePlayActivity: Unable To Find Track [{ streamInfo.Track.Value }]");
@ -148,16 +152,26 @@ namespace Roadie.Api.Services
} }
userTrack.LastPlayed = now; userTrack.LastPlayed = now;
userTrack.PlayedCount++; userTrack.PlayedCount++;
userTrack.PlayedCount = (userTrack.PlayedCount ?? 0) + 1;
this.CacheManager.ClearRegion(user.CacheRegion); this.CacheManager.ClearRegion(user.CacheRegion);
} }
var release = this.GetRelease(track.ReleaseMedia.Release.RoadieId); var release = this.DbContext.Releases.Include(x => x.Artist).FirstOrDefault(x => x.RoadieId == track.ReleaseMedia.Release.RoadieId);
release.LastPlayed = now; release.LastPlayed = now;
release.PlayedCount++; release.PlayedCount = (release.PlayedCount ?? 0) + 1;
var artist = this.GetArtist(release.Artist.RoadieId); var artist = this.DbContext.Artists.FirstOrDefault(x => x.RoadieId == release.Artist.RoadieId);
artist.LastPlayed = now; artist.LastPlayed = now;
artist.PlayedCount++; artist.PlayedCount = (artist.PlayedCount ?? 0) + 1;
data.Artist trackArtist = null;
if (track.ArtistId.HasValue)
{
trackArtist = this.DbContext.Artists.FirstOrDefault(x => x.Id == track.ArtistId);
trackArtist.LastPlayed = now;
trackArtist.PlayedCount = (trackArtist.PlayedCount ?? 0) + 1;
this.CacheManager.ClearRegion(trackArtist.CacheRegion);
}
this.CacheManager.ClearRegion(track.CacheRegion); this.CacheManager.ClearRegion(track.CacheRegion);
this.CacheManager.ClearRegion(track.ReleaseMedia.Release.CacheRegion); this.CacheManager.ClearRegion(track.ReleaseMedia.Release.CacheRegion);

View file

@ -597,6 +597,43 @@ namespace Roadie.Api.Services
}; };
} }
protected async Task<OperationResult<bool>> ToggleTrackDisliked(Guid trackId, ApplicationUser user, bool isDisliked)
{
var track = this.GetTrack(trackId);
if (track == null)
{
return new OperationResult<bool>(true, $"Invalid Track Id [{ trackId }]");
}
var userTrack = this.DbContext.UserTracks.FirstOrDefault(x => x.TrackId == track.Id && x.UserId == user.Id);
if (userTrack == null)
{
userTrack = new data.UserTrack
{
IsDisliked = isDisliked,
UserId = user.Id,
TrackId = track.Id
};
this.DbContext.UserTracks.Add(userTrack);
}
else
{
userTrack.IsDisliked = isDisliked;
userTrack.LastUpdated = DateTime.UtcNow;
}
await this.DbContext.SaveChangesAsync();
this.CacheManager.ClearRegion(user.CacheRegion);
this.CacheManager.ClearRegion(track.CacheRegion);
this.CacheManager.ClearRegion(track.ReleaseMedia.Release.CacheRegion);
this.CacheManager.ClearRegion(track.ReleaseMedia.Release.Artist.CacheRegion);
return new OperationResult<bool>
{
IsSuccess = true,
Data = true
};
}
private Image MakeImage(Guid id, string type, int? width, int? height, string caption = null, bool includeCachebuster = false) private Image MakeImage(Guid id, string type, int? width, int? height, string caption = null, bool includeCachebuster = false)
{ {

View file

@ -41,129 +41,6 @@ namespace Roadie.Api.Services
this.BookmarkService = bookmarkService; this.BookmarkService = bookmarkService;
} }
public async Task<OperationResult<Track>> ById(User roadieUser, Guid id, IEnumerable<string> includes)
{
var sw = Stopwatch.StartNew();
sw.Start();
var cacheKey = string.Format("urn:track_by_id_operation:{0}:{1}", id, includes == null ? "0" : string.Join("|", includes));
var result = await this.CacheManager.GetAsync<OperationResult<Track>>(cacheKey, async () =>
{
return await this.TrackByIdAction(id, includes);
}, data.Track.CacheRegionUrn(id));
if (result?.Data != null && roadieUser != null)
{
var track = this.GetTrack(id);
var userBookmarkResult = await this.BookmarkService.List(roadieUser, new PagedRequest(), false, BookmarkType.Track);
if (userBookmarkResult.IsSuccess)
{
result.Data.UserBookmarked = userBookmarkResult?.Rows?.FirstOrDefault(x => x.Bookmark.Value == track.RoadieId.ToString()) != null;
}
var userTrack = this.DbContext.UserTracks.FirstOrDefault(x => x.TrackId == track.Id && x.UserId == roadieUser.Id);
if (userTrack != null)
{
result.Data.UserRating = new UserTrack
{
Rating = userTrack.Rating,
IsDisliked = userTrack.IsDisliked ?? false,
IsFavorite = userTrack.IsFavorite ?? false,
LastPlayed = userTrack.LastPlayed,
PlayedCount = userTrack.PlayedCount
};
}
}
sw.Stop();
return new OperationResult<Track>(result.Messages)
{
Data = result?.Data,
Errors = result?.Errors,
IsNotFoundResult = result?.IsNotFoundResult ?? false,
IsSuccess = result?.IsSuccess ?? false,
OperationTime = sw.ElapsedMilliseconds
};
}
private Task<OperationResult<Track>> TrackByIdAction(Guid id, IEnumerable<string> includes)
{
var sw = Stopwatch.StartNew();
sw.Start();
var track = this.GetTrack(id);
if (track == null)
{
return Task.FromResult(new OperationResult<Track>(true, string.Format("Track Not Found [{0}]", id)));
}
var result = track.Adapt<Track>();
result.PlayUrl = $"{ this.HttpContext.BaseUrl }/play/track/{track.RoadieId}.mp3";
result.IsLocked = (track.IsLocked ?? false) ||
(track.ReleaseMedia.IsLocked ?? false) ||
(track.ReleaseMedia.Release.IsLocked ?? false ) ||
(track.ReleaseMedia.Release.Artist.IsLocked ?? false);
result.Thumbnail = base.MakeTrackThumbnailImage(id);
result.ReleaseMediaId = track.ReleaseMedia.RoadieId.ToString();
result.Artist = new DataToken
{
Text = track.ReleaseMedia.Release.Artist.Name,
Value = track.ReleaseMedia.Release.Artist.RoadieId.ToString()
};
result.ArtistThumbnail = this.MakeArtistThumbnailImage(track.ReleaseMedia.Release.Artist.RoadieId);
result.Release = new DataToken
{
Text = track.ReleaseMedia.Release.Title,
Value = track.ReleaseMedia.Release.RoadieId.ToString()
};
result.ReleaseThumbnail = this.MakeReleaseThumbnailImage(track.ReleaseMedia.Release.RoadieId);
if(track.ArtistId.HasValue)
{
var trackArtist = this.DbContext.Artists.FirstOrDefault(x => x.Id == track.ArtistId);
if(trackArtist == null)
{
this.Logger.LogWarning($"Unable to find Track Artist [{ track.ArtistId }");
}
else
{
result.TrackArtist = new DataToken
{
Text = trackArtist.Name,
Value = trackArtist.RoadieId.ToString()
};
result.TrackArtistThumbnail = this.MakeArtistThumbnailImage(trackArtist.RoadieId);
}
}
if (includes != null && includes.Any())
{
if (includes.Contains("stats"))
{
var userTracks = (from t in this.DbContext.Tracks
join ut in this.DbContext.UserTracks on t.Id equals ut.TrackId into tt
from ut in tt.DefaultIfEmpty()
where t.Id == track.Id
select ut).ToArray();
if (userTracks.Any())
{
result.Statistics = new Library.Models.Statistics.TrackStatistics
{
DislikedCount = userTracks.Count(x => x.IsDisliked ?? false),
FavoriteCount = userTracks.Count(x => x.IsFavorite ?? false),
PlayedCount = userTracks.Sum(x => x.PlayedCount),
FileSizeFormatted = ((long?)track.FileSize).ToFileSize(),
Time = new TimeInfo((decimal)track.Duration).ToFullFormattedString()
};
}
}
}
sw.Stop();
return Task.FromResult(new OperationResult<Track>
{
Data = result,
IsSuccess = result != null,
OperationTime = sw.ElapsedMilliseconds
});
}
public static long DetermineByteEndFromHeaders(IHeaderDictionary headers, long fileLength) public static long DetermineByteEndFromHeaders(IHeaderDictionary headers, long fileLength)
{ {
var defaultFileLength = fileLength - 1; var defaultFileLength = fileLength - 1;
@ -216,18 +93,59 @@ namespace Roadie.Api.Services
return result; return result;
} }
public async Task<OperationResult<Track>> ById(User roadieUser, Guid id, IEnumerable<string> includes)
{
var sw = Stopwatch.StartNew();
sw.Start();
var cacheKey = string.Format("urn:track_by_id_operation:{0}:{1}", id, includes == null ? "0" : string.Join("|", includes));
var result = await this.CacheManager.GetAsync<OperationResult<Track>>(cacheKey, async () =>
{
return await this.TrackByIdAction(id, includes);
}, data.Track.CacheRegionUrn(id));
if (result?.Data != null && roadieUser != null)
{
var user = this.GetUser(roadieUser.UserId);
var track = this.GetTrack(id);
result.Data.TrackPlayUrl = this.MakeTrackPlayUrl(user, track.Id, track.RoadieId);
var userBookmarkResult = await this.BookmarkService.List(roadieUser, new PagedRequest(), false, BookmarkType.Track);
if (userBookmarkResult.IsSuccess)
{
result.Data.UserBookmarked = userBookmarkResult?.Rows?.FirstOrDefault(x => x.Bookmark.Value == track.RoadieId.ToString()) != null;
}
var userTrack = this.DbContext.UserTracks.FirstOrDefault(x => x.TrackId == track.Id && x.UserId == roadieUser.Id);
if (userTrack != null)
{
result.Data.UserRating = new UserTrack
{
Rating = userTrack.Rating,
IsDisliked = userTrack.IsDisliked ?? false,
IsFavorite = userTrack.IsFavorite ?? false,
LastPlayed = userTrack.LastPlayed,
PlayedCount = userTrack.PlayedCount
};
}
}
sw.Stop();
return new OperationResult<Track>(result.Messages)
{
Data = result?.Data,
Errors = result?.Errors,
IsNotFoundResult = result?.IsNotFoundResult ?? false,
IsSuccess = result?.IsSuccess ?? false,
OperationTime = sw.ElapsedMilliseconds
};
}
public Task<Library.Models.Pagination.PagedResult<TrackList>> List(PagedRequest request, User roadieUser, bool? doRandomize = false, Guid? releaseId = null) public Task<Library.Models.Pagination.PagedResult<TrackList>> List(PagedRequest request, User roadieUser, bool? doRandomize = false, Guid? releaseId = null)
{ {
try try
{ {
var sw = new Stopwatch(); var sw = new Stopwatch();
sw.Start(); sw.Start();
int? rowCount = null; int? rowCount = null;
if(!string.IsNullOrEmpty(request.Sort)) if (!string.IsNullOrEmpty(request.Sort))
{ {
request.Sort = request.Sort.Replace("Release.Text", "Release.Release.Text"); request.Sort = request.Sort.Replace("Release.Text", "Release.Release.Text");
} }
@ -426,22 +344,22 @@ namespace Roadie.Api.Services
Text = x.ti.Title, Text = x.ti.Title,
Value = x.ti.RoadieId.ToString() Value = x.ti.RoadieId.ToString()
}, },
Release = x.rl,
LastPlayed = x.ti.LastPlayed,
Artist = x.ra, Artist = x.ra,
TrackArtist = x.ta,
TrackNumber = playListTrackPositions.ContainsKey(x.ti.Id) ? playListTrackPositions[x.ti.Id] : x.ti.TrackNumber,
MediaNumber = x.rmi.MediaNumber,
CreatedDate = x.ti.CreatedDate, CreatedDate = x.ti.CreatedDate,
LastUpdated = x.ti.LastUpdated,
Duration = x.ti.Duration, Duration = x.ti.Duration,
FileSize = x.ti.FileSize, FileSize = x.ti.FileSize,
ReleaseDate = x.rl.ReleaseDateDateTime, LastPlayed = x.ti.LastPlayed,
LastUpdated = x.ti.LastUpdated,
MediaNumber = x.rmi.MediaNumber,
PlayedCount = x.ti.PlayedCount, PlayedCount = x.ti.PlayedCount,
Rating = x.ti.Rating, Rating = x.ti.Rating,
Release = x.rl,
ReleaseDate = x.rl.ReleaseDateDateTime,
Thumbnail = this.MakeTrackThumbnailImage(x.ti.RoadieId),
Title = x.ti.Title, Title = x.ti.Title,
TrackPlayUrl = this.MakeTrackPlayUrl(user, x.ti.Id, x.ti.RoadieId), TrackArtist = x.ta,
Thumbnail = this.MakeTrackThumbnailImage(x.ti.RoadieId) TrackNumber = playListTrackPositions.ContainsKey(x.ti.Id) ? playListTrackPositions[x.ti.Id] : x.ti.TrackNumber,
TrackPlayUrl = this.MakeTrackPlayUrl(user, x.ti.Id, x.ti.RoadieId)
}); });
string sortBy = null; string sortBy = null;
@ -486,9 +404,9 @@ namespace Roadie.Api.Services
where releaseIds.Contains(ur.ReleaseId) where releaseIds.Contains(ur.ReleaseId)
select ur).ToArray(); select ur).ToArray();
foreach(var userReleaseRating in userReleaseRatings) foreach (var userReleaseRating in userReleaseRatings)
{ {
foreach(var row in rows.Where(x => x.Release.DatabaseId == userReleaseRating.ReleaseId)) foreach (var row in rows.Where(x => x.Release.DatabaseId == userReleaseRating.ReleaseId))
{ {
row.Release.UserRating = userReleaseRating.Adapt<UserRelease>(); row.Release.UserRating = userReleaseRating.Adapt<UserRelease>();
} }
@ -528,18 +446,12 @@ namespace Roadie.Api.Services
} }
} }
} }
} }
if (rows.Any()) if (rows.Any())
{ {
foreach (var row in rows) foreach (var row in rows)
{ {
row.PlayedCount = (from ut in this.DbContext.UserTracks
join tr in this.DbContext.Tracks on ut.TrackId equals tr.Id
where ut.TrackId == row.DatabaseId
select ut.PlayedCount).Sum() ?? 0;
row.FavoriteCount = (from ut in this.DbContext.UserTracks row.FavoriteCount = (from ut in this.DbContext.UserTracks
join tr in this.DbContext.Tracks on ut.TrackId equals tr.Id join tr in this.DbContext.Tracks on ut.TrackId equals tr.Id
where ut.TrackId == row.DatabaseId where ut.TrackId == row.DatabaseId
@ -566,7 +478,6 @@ namespace Roadie.Api.Services
Message = "An Error has occured" Message = "An Error has occured"
}); });
} }
} }
public async Task<OperationResult<TrackStreamInfo>> TrackStreamInfo(Guid trackId, long beginBytes, long endBytes) public async Task<OperationResult<TrackStreamInfo>> TrackStreamInfo(Guid trackId, long beginBytes, long endBytes)
@ -641,5 +552,72 @@ namespace Roadie.Api.Services
Data = info Data = info
}; };
} }
private Task<OperationResult<Track>> TrackByIdAction(Guid id, IEnumerable<string> includes)
{
var sw = Stopwatch.StartNew();
sw.Start();
var track = this.GetTrack(id);
if (track == null)
{
return Task.FromResult(new OperationResult<Track>(true, string.Format("Track Not Found [{0}]", id)));
}
var result = track.Adapt<Track>();
result.IsLocked = (track.IsLocked ?? false) ||
(track.ReleaseMedia.IsLocked ?? false) ||
(track.ReleaseMedia.Release.IsLocked ?? false) ||
(track.ReleaseMedia.Release.Artist.IsLocked ?? false);
result.Thumbnail = base.MakeTrackThumbnailImage(id);
result.MediumThumbnail = base.MakeThumbnailImage(id, "track", this.Configuration.MediumImageSize.Width, this.Configuration.MediumImageSize.Height);
result.ReleaseMediaId = track.ReleaseMedia.RoadieId.ToString();
result.Artist = ArtistList.FromDataArtist(track.ReleaseMedia.Release.Artist, this.MakeArtistThumbnailImage(track.ReleaseMedia.Release.Artist.RoadieId));
result.ArtistThumbnail = this.MakeArtistThumbnailImage(track.ReleaseMedia.Release.Artist.RoadieId);
result.Release = ReleaseList.FromDataRelease(track.ReleaseMedia.Release, track.ReleaseMedia.Release.Artist, this.HttpContext.BaseUrl, this.MakeArtistThumbnailImage(track.ReleaseMedia.Release.Artist.RoadieId), this.MakeReleaseThumbnailImage(track.ReleaseMedia.Release.RoadieId));
result.ReleaseThumbnail = this.MakeReleaseThumbnailImage(track.ReleaseMedia.Release.RoadieId);
if (track.ArtistId.HasValue)
{
var trackArtist = this.DbContext.Artists.FirstOrDefault(x => x.Id == track.ArtistId);
if (trackArtist == null)
{
this.Logger.LogWarning($"Unable to find Track Artist [{ track.ArtistId }");
}
else
{
result.TrackArtist = ArtistList.FromDataArtist(trackArtist, this.MakeArtistThumbnailImage(trackArtist.RoadieId));
result.TrackArtistThumbnail = this.MakeArtistThumbnailImage(trackArtist.RoadieId);
}
}
if (includes != null && includes.Any())
{
if (includes.Contains("stats"))
{
result.Statistics = new Library.Models.Statistics.TrackStatistics
{
FileSizeFormatted = ((long?)track.FileSize).ToFileSize(),
Time = new TimeInfo((decimal)track.Duration).ToFullFormattedString(),
PlayedCount = track.PlayedCount
};
var userTracks = (from t in this.DbContext.Tracks
join ut in this.DbContext.UserTracks on t.Id equals ut.TrackId
where t.Id == track.Id
select ut).ToArray();
if (userTracks != null && userTracks.Any())
{
result.Statistics.DislikedCount = userTracks.Count(x => x.IsDisliked ?? false);
result.Statistics.FavoriteCount = userTracks.Count(x => x.IsFavorite ?? false);
}
}
}
sw.Stop();
return Task.FromResult(new OperationResult<Track>
{
Data = result,
IsSuccess = result != null,
OperationTime = sw.ElapsedMilliseconds
});
}
} }
} }

View file

@ -468,6 +468,16 @@ namespace Roadie.Api.Services
return await base.ToggleReleaseFavorite(releaseId, user, isFavorite); return await base.ToggleReleaseFavorite(releaseId, user, isFavorite);
} }
public async Task<OperationResult<bool>> SetTrackFavorite(Guid trackId, User roadieUser, bool isFavorite)
{
var user = this.GetUser(roadieUser.UserId);
if (user == null)
{
return new OperationResult<bool>(true, $"Invalid User [{ roadieUser }]");
}
return await base.ToggleTrackFavorite(trackId, user, isFavorite);
}
public async Task<OperationResult<bool>> SetReleaseDisliked(Guid releaseId, User roadieUser, bool isDisliked) public async Task<OperationResult<bool>> SetReleaseDisliked(Guid releaseId, User roadieUser, bool isDisliked)
{ {
var user = this.GetUser(roadieUser.UserId); var user = this.GetUser(roadieUser.UserId);
@ -521,12 +531,24 @@ namespace Roadie.Api.Services
return await base.SetTrackRating(trackId, user, rating); return await base.SetTrackRating(trackId, user, rating);
} }
public async Task<OperationResult<bool>> SetTrackDisliked(Guid trackId, User roadieUser, bool isDisliked)
{
var user = this.GetUser(roadieUser.UserId);
if (user == null)
{
return new OperationResult<bool>(true, $"Invalid User [{ roadieUser }]");
}
return await base.ToggleTrackDisliked(trackId, user, isDisliked);
}
private async Task<OperationResult<bool>> SetBookmark(ApplicationUser user, Library.Enums.BookmarkType bookmarktype, int bookmarkTargetId, bool isBookmarked) private async Task<OperationResult<bool>> SetBookmark(ApplicationUser user, Library.Enums.BookmarkType bookmarktype, int bookmarkTargetId, bool isBookmarked)
{ {
var bookmark = this.DbContext.Bookmarks.FirstOrDefault(x => x.BookmarkTargetId == bookmarkTargetId && var bookmark = this.DbContext.Bookmarks.FirstOrDefault(x => x.BookmarkTargetId == bookmarkTargetId &&
x.BookmarkType == bookmarktype && x.BookmarkType == bookmarktype &&
x.UserId == user.Id); x.UserId == user.Id);
if (isBookmarked) if (!isBookmarked)
{ {
// Remove bookmark // Remove bookmark
if (bookmark != null) if (bookmark != null)

View file

@ -56,7 +56,7 @@ namespace Roadie.Api.Controllers
{ {
Response.StatusCode = (int)HttpStatusCode.NotFound; Response.StatusCode = (int)HttpStatusCode.NotFound;
} }
var release = await this.ReleaseService.ById(user, Guid.Parse(track.Data.Release.Value), new string[1] { "tracks" }); var release = await this.ReleaseService.ById(user, track.Data.Release.Id, new string[1] { "tracks" });
if (release == null || release.IsNotFoundResult) if (release == null || release.IsNotFoundResult)
{ {
Response.StatusCode = (int)HttpStatusCode.NotFound; Response.StatusCode = (int)HttpStatusCode.NotFound;

View file

@ -10,7 +10,6 @@ using Roadie.Library.Models.Pagination;
using Roadie.Library.Models.Users; using Roadie.Library.Models.Users;
using System; using System;
using System.Net; using System.Net;
using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Roadie.Api.Controllers namespace Roadie.Api.Controllers
@ -21,8 +20,8 @@ namespace Roadie.Api.Controllers
[Authorize] [Authorize]
public class UserController : EntityControllerBase public class UserController : EntityControllerBase
{ {
private IUserService UserService { get; }
private readonly ITokenService TokenService; private readonly ITokenService TokenService;
private IUserService UserService { get; }
public UserController(IUserService userService, ILoggerFactory logger, ICacheManager cacheManager, IConfiguration configuration, ITokenService tokenService, UserManager<ApplicationUser> userManager) public UserController(IUserService userService, ILoggerFactory logger, ICacheManager cacheManager, IConfiguration configuration, ITokenService tokenService, UserManager<ApplicationUser> userManager)
: base(cacheManager, configuration, userManager) : base(cacheManager, configuration, userManager)
@ -54,6 +53,213 @@ namespace Roadie.Api.Controllers
return Ok(result); return Ok(result);
} }
[HttpGet]
[ProducesResponseType(200)]
public async Task<IActionResult> List([FromQuery]PagedRequest request)
{
var result = await this.UserService.List(request);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
return Ok(result);
}
[HttpPost("setArtistBookmark/{artistId}/{isBookmarked}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetArtistBookmark(Guid artistId, bool isBookmarked)
{
var result = await this.UserService.SetArtistBookmark(artistId, await this.CurrentUserModel(), isBookmarked);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setArtistDisliked/{artistId}/{isDisliked}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetArtistDisliked(Guid artistId, bool isDisliked)
{
var result = await this.UserService.SetArtistDisliked(artistId, await this.CurrentUserModel(), isDisliked);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setArtistFavorite/{artistId}/{isFavorite}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetArtistFavorite(Guid artistId, bool isFavorite)
{
var result = await this.UserService.SetArtistFavorite(artistId, await this.CurrentUserModel(), isFavorite);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setArtistRating/{releaseId}/{rating}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetArtistRating(Guid releaseId, short rating)
{
var result = await this.UserService.SetArtistRating(releaseId, await this.CurrentUserModel(), rating);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setCollectionBookmark/{collectionId}/{isBookmarked}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetCollectionBookmark(Guid collectionId, bool isBookmarked)
{
var result = await this.UserService.SetCollectionBookmark(collectionId, await this.CurrentUserModel(), isBookmarked);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setLabelBookmark/{labelId}/{isBookmarked}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetLabelBookmark(Guid labelId, bool isBookmarked)
{
var result = await this.UserService.SetLabelBookmark(labelId, await this.CurrentUserModel(), isBookmarked);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setPlaylistBookmark/{playlistId}/{isBookmarked}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetPlaylistBookmark(Guid playlistId, bool isBookmarked)
{
var result = await this.UserService.SetPlaylistBookmark(playlistId, await this.CurrentUserModel(), isBookmarked);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setReleaseBookmark/{releaseId}/{isBookmarked}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetReleaseBookmark(Guid releaseId, bool isBookmarked)
{
var result = await this.UserService.SetReleaseBookmark(releaseId, await this.CurrentUserModel(), isBookmarked);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setReleaseDisliked/{releaseId}/{isDisliked}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetReleaseDisliked(Guid releaseId, bool isDisliked)
{
var result = await this.UserService.SetReleaseDisliked(releaseId, await this.CurrentUserModel(), isDisliked);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setReleaseFavorite/{releaseId}/{isFavorite}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetReleaseFavorite(Guid releaseId, bool isFavorite)
{
var result = await this.UserService.SetReleaseFavorite(releaseId, await this.CurrentUserModel(), isFavorite);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setReleaseRating/{releaseId}/{rating}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetReleaseRating(Guid releaseId, short rating)
{
var result = await this.UserService.SetReleaseRating(releaseId, await this.CurrentUserModel(), rating);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setTrackBookmark/{trackId}/{isBookmarked}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetTrackBookmark(Guid trackId, bool isBookmarked)
{
var result = await this.UserService.SetTrackBookmark(trackId, await this.CurrentUserModel(), isBookmarked);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setTrackDisliked/{trackId}/{isDisliked}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetTrackDisliked(Guid trackId, bool isDisliked)
{
var result = await this.UserService.SetTrackDisliked(trackId, await this.CurrentUserModel(), isDisliked);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setTrackFavorite/{trackId}/{isFavorite}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetTrackFavorite(Guid trackId, bool isFavorite)
{
var result = await this.UserService.SetTrackFavorite(trackId, await this.CurrentUserModel(), isFavorite);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setTrackRating/{trackId}/{rating}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetTrackRating(Guid trackId, short rating)
{
var result = await this.UserService.SetTrackRating(trackId, await this.CurrentUserModel(), rating);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("profile/edit")] [HttpPost("profile/edit")]
[ProducesResponseType(200)] [ProducesResponseType(200)]
public async Task<IActionResult> UpdateProfile(User model) public async Task<IActionResult> UpdateProfile(User model)
@ -90,193 +296,10 @@ namespace Roadie.Api.Controllers
}); });
} }
[HttpPost("setArtistRating/{releaseId}/{rating}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetArtistRating(Guid releaseId, short rating)
{
var result = await this.UserService.SetArtistRating(releaseId, await this.CurrentUserModel(), rating);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setReleaseRating/{releaseId}/{rating}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetReleaseRating(Guid releaseId, short rating)
{
var result = await this.UserService.SetReleaseRating(releaseId, await this.CurrentUserModel(), rating);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setTrackRating/{releaseId}/{rating}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetTrackRating(Guid releaseId, short rating)
{
var result = await this.UserService.SetTrackRating(releaseId, await this.CurrentUserModel(), rating);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setArtistFavorite/{artistId}/{isFavorite}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetArtistFavorite(Guid artistId, bool isFavorite)
{
var result = await this.UserService.SetArtistFavorite(artistId, await this.CurrentUserModel(), isFavorite);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setArtistDisliked/{artistId}/{isDisliked}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetArtistDisliked(Guid artistId, bool isDisliked)
{
var result = await this.UserService.SetArtistDisliked(artistId, await this.CurrentUserModel(), isDisliked);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setReleaseFavorite/{releaseId}/{isFavorite}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetReleaseFavorite(Guid releaseId, bool isFavorite)
{
var result = await this.UserService.SetReleaseFavorite(releaseId, await this.CurrentUserModel(), isFavorite);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setReleaseDisliked/{releaseId}/{isDisliked}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetReleaseDisliked(Guid releaseId, bool isDisliked)
{
var result = await this.UserService.SetReleaseDisliked(releaseId, await this.CurrentUserModel(), isDisliked);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setArtistBookmark/{artistId}/{isBookmarked}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetArtistBookmark(Guid artistId, bool isBookmarked)
{
var result = await this.UserService.SetArtistBookmark(artistId, await this.CurrentUserModel(), isBookmarked);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setReleaseBookmark/{releaseId}/{isBookmarked}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetReleaseBookmark(Guid releaseId, bool isBookmarked)
{
var result = await this.UserService.SetReleaseBookmark(releaseId, await this.CurrentUserModel(), isBookmarked);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setTrackBookmark/{trackId}/{isBookmarked}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetTrackBookmark(Guid trackId, bool isBookmarked)
{
var result = await this.UserService.SetTrackBookmark(trackId, await this.CurrentUserModel(), isBookmarked);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setPlaylistBookmark/{playlistId}/{isBookmarked}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetPlaylistBookmark(Guid playlistId, bool isBookmarked)
{
var result = await this.UserService.SetPlaylistBookmark(playlistId, await this.CurrentUserModel(), isBookmarked);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setCollectionBookmark/{collectionId}/{isBookmarked}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetCollectionBookmark(Guid collectionId, bool isBookmarked)
{
var result = await this.UserService.SetCollectionBookmark(collectionId, await this.CurrentUserModel(), isBookmarked);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpPost("setLabelBookmark/{labelId}/{isBookmarked}")]
[ProducesResponseType(200)]
public async Task<IActionResult> SetLabelBookmark(Guid labelId, bool isBookmarked)
{
var result = await this.UserService.SetLabelBookmark(labelId, await this.CurrentUserModel(), isBookmarked);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
this.CacheManager.ClearRegion(EntityControllerBase.ControllerCacheRegionUrn);
return Ok(result);
}
[HttpGet]
[ProducesResponseType(200)]
public async Task<IActionResult> List([FromQuery]PagedRequest request)
{
var result = await this.UserService.List(request);
if (!result.IsSuccess)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
return Ok(result);
}
public class PagingParams public class PagingParams
{ {
public int Page { get; set; } = 1;
public int Limit { get; set; } = 5; public int Limit { get; set; } = 5;
public int Page { get; set; } = 1;
} }
} }
} }