示例#1
0
        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>());
        }
示例#2
0
        public async Task <OperationResult <TrackStreamInfo> > TrackStreamInfo(Guid trackId, long beginBytes, long endBytes, User roadieUser)
        {
            var track = this.DbContext.Tracks.FirstOrDefault(x => x.RoadieId == trackId);

            if (track == null)
            {
                // Not Found try recanning release
                var release = (from r in this.DbContext.Releases
                               join rm in this.DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
                               where rm.Id == track.ReleaseMediaId
                               select r).FirstOrDefault();
                if (!release.IsLocked ?? false)
                {
                    await this.AdminService.ScanRelease(new Library.Identity.ApplicationUser
                    {
                        Id = roadieUser.Id.Value
                    }, release.RoadieId, false, true);
                }
                track = this.DbContext.Tracks.FirstOrDefault(x => x.RoadieId == trackId);
                if (track == null)
                {
                    return(new OperationResult <TrackStreamInfo>($"TrackStreamInfo: Unable To Find Track [{ trackId }]"));
                }
            }
            if (!track.IsValid)
            {
                return(new OperationResult <TrackStreamInfo>($"TrackStreamInfo: Invalid Track. Track Id [{trackId}], FilePath [{track.FilePath}], Filename [{track.FileName}]"));
            }
            string trackPath = null;

            try
            {
                trackPath = track.PathToTrack(this.Configuration, this.Configuration.LibraryFolder);
            }
            catch (Exception ex)
            {
                return(new OperationResult <TrackStreamInfo>(ex));
            }
            var trackFileInfo = new FileInfo(trackPath);

            if (!trackFileInfo.Exists)
            {
                // Not Found try recanning release
                var release = (from r in this.DbContext.Releases
                               join rm in this.DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
                               where rm.Id == track.ReleaseMediaId
                               select r).FirstOrDefault();
                if (!release.IsLocked ?? false)
                {
                    await this.AdminService.ScanRelease(new Library.Identity.ApplicationUser
                    {
                        Id = roadieUser.Id.Value
                    }, release.RoadieId, false, true);
                }
                track = this.DbContext.Tracks.FirstOrDefault(x => x.RoadieId == trackId);
                if (track == null)
                {
                    return(new OperationResult <TrackStreamInfo>($"TrackStreamInfo: Unable To Find Track [{ trackId }]"));
                }
                try
                {
                    trackPath = track.PathToTrack(this.Configuration, this.Configuration.LibraryFolder);
                }
                catch (Exception ex)
                {
                    return(new OperationResult <TrackStreamInfo>(ex));
                }
                if (!trackFileInfo.Exists)
                {
                    track.UpdateTrackMissingFile();
                    await this.DbContext.SaveChangesAsync();

                    return(new OperationResult <TrackStreamInfo>($"TrackStreamInfo: TrackId [{trackId}] Unable to Find Track [{trackFileInfo.FullName}]"));
                }
            }
            var contentDurationTimeSpan = TimeSpan.FromMilliseconds((double)(track.Duration ?? 0));
            var info = new TrackStreamInfo
            {
                FileName           = this.HttpEncoder.UrlEncode(track.FileName).ToContentDispositionFriendly(),
                ContentDisposition = $"attachment; filename=\"{ this.HttpEncoder.UrlEncode(track.FileName).ToContentDispositionFriendly() }\"",
                ContentDuration    = contentDurationTimeSpan.TotalSeconds.ToString(),
            };
            var cacheTimeout  = 86400; // 24 hours
            var contentLength = (endBytes - beginBytes) + 1;

            info.Track = new DataToken
            {
                Text  = track.Title,
                Value = track.RoadieId.ToString()
            };
            info.BeginBytes        = beginBytes;
            info.EndBytes          = endBytes;
            info.ContentRange      = $"bytes {beginBytes}-{endBytes}/{contentLength}";
            info.ContentLength     = contentLength.ToString();
            info.IsFullRequest     = beginBytes == 0 && endBytes == (trackFileInfo.Length - 1);
            info.IsEndRangeRequest = beginBytes > 0 && endBytes != (trackFileInfo.Length - 1);
            info.LastModified      = (track.LastUpdated ?? track.CreatedDate).ToString("R");
            info.Etag         = track.Etag;
            info.CacheControl = $"public, max-age={ cacheTimeout.ToString() } ";
            info.Expires      = DateTime.UtcNow.AddMinutes(cacheTimeout).ToString("R");
            int bytesToRead = (int)(endBytes - beginBytes) + 1;

            byte[] trackBytes = new byte[bytesToRead];
            using (var fs = trackFileInfo.OpenRead())
            {
                try
                {
                    fs.Seek(beginBytes, SeekOrigin.Begin);
                    var r = fs.Read(trackBytes, 0, bytesToRead);
                }
                catch (Exception ex)
                {
                    return(new OperationResult <TrackStreamInfo>(ex));
                }
            }
            info.Bytes = trackBytes;
            return(new OperationResult <TrackStreamInfo>
            {
                IsSuccess = true,
                Data = info
            });
        }