protected async Task <OperationResult <bool> > ToggleTrackFavorite(Guid trackId, User user, bool isFavorite) { var result = false; try { var track = DbContext.Tracks .Include(x => x.ReleaseMedia) .Include(x => x.ReleaseMedia.Release) .Include(x => x.ReleaseMedia.Release.Artist) .Include(x => x.TrackArtist) .FirstOrDefault(x => x.RoadieId == trackId); if (track == null) { return(new OperationResult <bool>(true, $"Invalid Track Id [{trackId}]")); } var userTrack = DbContext.UserTracks.FirstOrDefault(x => x.TrackId == track.Id && x.UserId == user.Id); if (userTrack == null) { userTrack = new data.UserTrack { IsFavorite = isFavorite, UserId = user.Id, TrackId = track.Id }; DbContext.UserTracks.Add(userTrack); } else { userTrack.IsFavorite = isFavorite; userTrack.LastUpdated = DateTime.UtcNow; } await DbContext.SaveChangesAsync(); CacheManager.ClearRegion(user.CacheRegion); CacheManager.ClearRegion(track.CacheRegion); CacheManager.ClearRegion(track.ReleaseMedia.Release.CacheRegion); CacheManager.ClearRegion(track.ReleaseMedia.Release.Artist.CacheRegion); Logger.LogDebug($"ToggleTrackFavorite: User `{ user }`, Track `{ track }`, isFavorite: [{ isFavorite }]"); result = true; } catch (DbException ex) { Logger.LogError($"ToggleTrackFavorite DbException [{ ex }]"); } return(new OperationResult <bool> { IsSuccess = result, Data = result }); }
protected async Task <OperationResult <bool> > ToggleTrackFavorite(Guid trackId, ApplicationUser user, bool isFavorite) { var track = DbContext.Tracks .Include(x => x.ReleaseMedia) .Include(x => x.ReleaseMedia.Release) .Include(x => x.ReleaseMedia.Release.Artist) .Include(x => x.TrackArtist) .FirstOrDefault(x => x.RoadieId == trackId); if (track == null) { return(new OperationResult <bool>(true, $"Invalid Track Id [{trackId}]")); } var userTrack = DbContext.UserTracks.FirstOrDefault(x => x.TrackId == track.Id && x.UserId == user.Id); if (userTrack == null) { userTrack = new data.UserTrack { IsFavorite = isFavorite, UserId = user.Id, TrackId = track.Id }; DbContext.UserTracks.Add(userTrack); } else { userTrack.IsFavorite = isFavorite; userTrack.LastUpdated = DateTime.UtcNow; } await DbContext.SaveChangesAsync(); CacheManager.ClearRegion(user.CacheRegion); CacheManager.ClearRegion(track.CacheRegion); CacheManager.ClearRegion(track.ReleaseMedia.Release.CacheRegion); CacheManager.ClearRegion(track.ReleaseMedia.Release.Artist.CacheRegion); return(new OperationResult <bool> { IsSuccess = true, Data = true }); }
public async Task <OperationResult <PlayActivityList> > CreatePlayActivity(User roadieUser, TrackStreamInfo streamInfo) { try { var sw = Stopwatch.StartNew(); var track = this.DbContext.Tracks .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) { return(new OperationResult <PlayActivityList>($"CreatePlayActivity: Unable To Find Track [{ streamInfo.Track.Value }]")); } if (!track.IsValid) { return(new OperationResult <PlayActivityList>($"CreatePlayActivity: Invalid Track. Track Id [{streamInfo.Track.Value}], FilePath [{track.FilePath}], Filename [{track.FileName}]")); } data.UserTrack userTrack = null; var now = DateTime.UtcNow; try { var user = roadieUser != null?this.DbContext.Users.FirstOrDefault(x => x.RoadieId == roadieUser.UserId) : null; if (user != null) { userTrack = this.DbContext.UserTracks.FirstOrDefault(x => x.UserId == user.Id && x.TrackId == track.Id); if (userTrack == null) { userTrack = new data.UserTrack(now) { UserId = user.Id, TrackId = track.Id }; this.DbContext.UserTracks.Add(userTrack); } userTrack.LastPlayed = now; userTrack.PlayedCount = (userTrack.PlayedCount ?? 0) + 1; this.CacheManager.ClearRegion(user.CacheRegion); await this.DbContext.SaveChangesAsync(); } } catch (Exception ex) { this.Logger.LogError(ex, $"Error in CreatePlayActivity, Creating UserTrack: User `{ roadieUser}` TrackId [{ track.Id }"); } track.PlayedCount = (track.PlayedCount ?? 0) + 1; track.LastPlayed = now; var release = this.DbContext.Releases.Include(x => x.Artist).FirstOrDefault(x => x.RoadieId == track.ReleaseMedia.Release.RoadieId); release.LastPlayed = now; release.PlayedCount = (release.PlayedCount ?? 0) + 1; var artist = this.DbContext.Artists.FirstOrDefault(x => x.RoadieId == release.Artist.RoadieId); artist.LastPlayed = now; 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.ReleaseMedia.Release.CacheRegion); this.CacheManager.ClearRegion(track.ReleaseMedia.Release.Artist.CacheRegion); var pl = new PlayActivityList { Artist = new DataToken { Text = track.ReleaseMedia.Release.Artist.Name, Value = track.ReleaseMedia.Release.Artist.RoadieId.ToString() }, TrackArtist = track.TrackArtist == null ? null : new DataToken { Text = track.TrackArtist.Name, Value = track.TrackArtist.RoadieId.ToString() }, Release = new DataToken { Text = track.ReleaseMedia.Release.Title, Value = track.ReleaseMedia.Release.RoadieId.ToString() }, Track = new DataToken { Text = track.Title, Value = track.RoadieId.ToString() }, User = new DataToken { Text = roadieUser.UserName, Value = roadieUser.UserId.ToString() }, PlayedDateDateTime = userTrack?.LastPlayed, ReleasePlayUrl = $"{ this.HttpContext.BaseUrl }/play/release/{ track.ReleaseMedia.Release.RoadieId}", Rating = track.Rating, UserRating = userTrack?.Rating, TrackPlayUrl = $"{ this.HttpContext.BaseUrl }/play/track/{ track.RoadieId}.mp3", ArtistThumbnail = this.MakeArtistThumbnailImage(track.TrackArtist != null ? track.TrackArtist.RoadieId : track.ReleaseMedia.Release.Artist.RoadieId), ReleaseThumbnail = this.MakeReleaseThumbnailImage(track.ReleaseMedia.Release.RoadieId), UserThumbnail = this.MakeUserThumbnailImage(roadieUser.UserId) }; if (!roadieUser.IsPrivate) { try { await this.PlayActivityHub.Clients.All.SendAsync("SendActivity", pl); } catch (Exception ex) { this.Logger.LogError(ex); } } await this.DbContext.SaveChangesAsync(); sw.Stop(); return(new OperationResult <PlayActivityList> { Data = pl, IsSuccess = userTrack != null, OperationTime = sw.ElapsedMilliseconds }); } catch (Exception ex) { this.Logger.LogError(ex, $"CreatePlayActivity RoadieUser `{ roadieUser }` StreamInfo `{ streamInfo }`"); } return(new OperationResult <PlayActivityList>()); }
/// <summary> /// The user has played a track. /// </summary> public override async Task <OperationResult <bool> > Scrobble(User roadieUser, ScrobbleInfo scrobble) { try { // If less than half of duration then do nothing if (scrobble.ElapsedTimeOfTrackPlayed.TotalSeconds < (scrobble.TrackDuration.TotalSeconds / 2)) { return(new OperationResult <bool> { Data = true, IsSuccess = true }); } var sw = Stopwatch.StartNew(); var track = this.DbContext.Tracks .Include(x => x.ReleaseMedia) .Include(x => x.ReleaseMedia.Release) .Include(x => x.ReleaseMedia.Release.Artist) .Include(x => x.TrackArtist) .FirstOrDefault(x => x.RoadieId == scrobble.TrackId); if (track == null) { return(new OperationResult <bool>($"Scrobble: Unable To Find Track [{ scrobble.TrackId }]")); } if (!track.IsValid) { return(new OperationResult <bool>($"Scrobble: Invalid Track. Track Id [{scrobble.TrackId}], FilePath [{track.FilePath}], Filename [{track.FileName}]")); } data.UserTrack userTrack = null; var now = DateTime.UtcNow; var success = false; try { var user = this.DbContext.Users.FirstOrDefault(x => x.RoadieId == roadieUser.UserId); userTrack = this.DbContext.UserTracks.FirstOrDefault(x => x.UserId == roadieUser.Id && x.TrackId == track.Id); if (userTrack == null) { userTrack = new data.UserTrack(now) { UserId = user.Id, TrackId = track.Id }; this.DbContext.UserTracks.Add(userTrack); } userTrack.LastPlayed = now; userTrack.PlayedCount = (userTrack.PlayedCount ?? 0) + 1; track.PlayedCount = (track.PlayedCount ?? 0) + 1; track.LastPlayed = now; var release = this.DbContext.Releases.Include(x => x.Artist).FirstOrDefault(x => x.RoadieId == track.ReleaseMedia.Release.RoadieId); release.LastPlayed = now; release.PlayedCount = (release.PlayedCount ?? 0) + 1; var artist = this.DbContext.Artists.FirstOrDefault(x => x.RoadieId == release.Artist.RoadieId); artist.LastPlayed = now; 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); } await this.DbContext.SaveChangesAsync(); this.CacheManager.ClearRegion(track.CacheRegion); this.CacheManager.ClearRegion(track.ReleaseMedia.Release.CacheRegion); this.CacheManager.ClearRegion(track.ReleaseMedia.Release.Artist.CacheRegion); this.CacheManager.ClearRegion(user.CacheRegion); success = true; } catch (Exception ex) { this.Logger.LogError(ex, $"Error in Scrobble, Creating UserTrack: User `{ roadieUser}` TrackId [{ track.Id }"); } sw.Stop(); this.Logger.LogInformation($"RoadieScrobbler: RoadieUser `{ roadieUser }` Scrobble `{ scrobble }`"); return(new OperationResult <bool> { Data = success, IsSuccess = userTrack != null, OperationTime = sw.ElapsedMilliseconds }); } catch (Exception ex) { this.Logger.LogError(ex, $"Scrobble RoadieUser `{ roadieUser }` Scrobble `{ scrobble }`"); } return(new OperationResult <bool>()); }
protected async Task <OperationResult <short> > SetTrackRating(Guid trackId, ApplicationUser user, short rating) { var sw = Stopwatch.StartNew(); var track = DbContext.Tracks .Include(x => x.ReleaseMedia) .Include(x => x.ReleaseMedia.Release) .Include(x => x.ReleaseMedia.Release.Artist) .Include(x => x.TrackArtist) .FirstOrDefault(x => x.RoadieId == trackId); if (track == null) { return(new OperationResult <short>(true, $"Invalid Track Id [{trackId}]")); } var now = DateTime.UtcNow; var userTrack = DbContext.UserTracks.FirstOrDefault(x => x.TrackId == track.Id && x.UserId == user.Id); if (userTrack == null) { userTrack = new data.UserTrack { Rating = rating, UserId = user.Id, TrackId = track.Id }; DbContext.UserTracks.Add(userTrack); } else { userTrack.Rating = rating; userTrack.LastUpdated = now; } await DbContext.SaveChangesAsync(); var ratings = DbContext.UserTracks.Where(x => x.TrackId == track.Id && x.Rating > 0).Select(x => x.Rating); if (ratings != null && ratings.Any()) { track.Rating = (short)ratings.Average(x => (decimal)x); } else { track.Rating = 0; } track.LastUpdated = now; await DbContext.SaveChangesAsync(); await UpdateReleaseRank(track.ReleaseMedia.Release.Id); CacheManager.ClearRegion(user.CacheRegion); CacheManager.ClearRegion(track.CacheRegion); CacheManager.ClearRegion(track.ReleaseMedia.Release.CacheRegion); CacheManager.ClearRegion(track.ReleaseMedia.Release.Artist.CacheRegion); if (track.TrackArtist != null) { CacheManager.ClearRegion(track.TrackArtist.CacheRegion); } sw.Stop(); return(new OperationResult <short> { IsSuccess = true, Data = track.Rating, OperationTime = sw.ElapsedMilliseconds }); }