From 40fdc3f3457642aeeef3f72f4bc636a85ee77ae1 Mon Sep 17 00:00:00 2001 From: Mateusz Skoczek Date: Sat, 21 Sep 2024 21:11:21 +0200 Subject: [PATCH 1/2] media view count incrementation endpoint added, media page loading optimized, media view count incrementation on media page added --- .../MediaController.cs | 12 ++++ .../IMediaControllerService.cs | 8 ++- .../MediaControllerService.cs | 46 ++++++++++-- .../Model/Media.cs | 1 + .../IMediaWebAPIService.cs | 2 + .../MediaWebAPIService.cs | 16 +++++ .../{MediaDataPage.razor => MediaPage.razor} | 0 ...iaDataPage.razor.cs => MediaPage.razor.cs} | 70 +++++++++---------- ...DataPage.razor.css => MediaPage.razor.css} | 0 .../WatchIt.Website/appsettings.json | 1 + 10 files changed, 112 insertions(+), 44 deletions(-) rename WatchIt.Website/WatchIt.Website/Pages/{MediaDataPage.razor => MediaPage.razor} (100%) rename WatchIt.Website/WatchIt.Website/Pages/{MediaDataPage.razor.cs => MediaPage.razor.cs} (57%) rename WatchIt.Website/WatchIt.Website/Pages/{MediaDataPage.razor.css => MediaPage.razor.css} (100%) diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs index 75eb1f5..57388b9 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs @@ -81,6 +81,18 @@ public class MediaController(IMediaControllerService mediaControllerService) public async Task DeleteMediaRating([FromRoute] long id) => await mediaControllerService.DeleteMediaRating(id); #endregion + + + + #region VIEW COUNT + + [HttpPost("{id}/view")] + [AllowAnonymous] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task PostMediaView([FromRoute] long id) => await mediaControllerService.PostMediaView(id); + + #endregion diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/IMediaControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/IMediaControllerService.cs index f700a4a..7e26c60 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/IMediaControllerService.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/IMediaControllerService.cs @@ -15,10 +15,12 @@ public interface IMediaControllerService Task GetMediaRatingByUser(long mediaId, long userId); Task PutMediaRating(long mediaId, MediaRatingRequest data); Task DeleteMediaRating(long mediaId); + + Task PostMediaView(long mediaId); - Task GetMediaPoster(long id); - Task PutMediaPoster(long id, MediaPosterRequest data); - Task DeleteMediaPoster(long id); + Task GetMediaPoster(long mediaId); + Task PutMediaPoster(long mediaId, MediaPosterRequest data); + Task DeleteMediaPoster(long mediaId); Task GetPhoto(Guid id); Task GetPhotos(MediaPhotoQueryParameters query); diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/MediaControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/MediaControllerService.cs index 1dd91c8..7f4281d 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/MediaControllerService.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/MediaControllerService.cs @@ -5,6 +5,7 @@ using WatchIt.Common.Model.Media; using WatchIt.Database; using WatchIt.Database.Model.Media; using WatchIt.Database.Model.Rating; +using WatchIt.Database.Model.ViewCount; using WatchIt.WebAPI.Services.Controllers.Common; using WatchIt.WebAPI.Services.Utility.User; @@ -182,13 +183,46 @@ public class MediaControllerService(DatabaseContext database, IUserService userS return RequestResult.Ok(); } + #endregion + + #region View count + + public async Task PostMediaView(long mediaId) + { + Database.Model.Media.Media? item = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); + if (item is null) + { + return RequestResult.NotFound(); + } + + DateOnly dateNow = DateOnly.FromDateTime(DateTime.Now); + ViewCountMedia? viewCount = await database.ViewCountsMedia.FirstOrDefaultAsync(x => x.MediaId == mediaId && x.Date == dateNow); + if (viewCount is null) + { + viewCount = new ViewCountMedia + { + MediaId = mediaId, + Date = dateNow, + ViewCount = 1 + }; + await database.ViewCountsMedia.AddAsync(viewCount); + } + else + { + viewCount.ViewCount++; + } + await database.SaveChangesAsync(); + + return RequestResult.Ok(); + } + #endregion #region Poster - public async Task GetMediaPoster(long id) + public async Task GetMediaPoster(long mediaId) { - Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == id); + Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); if (media is null) { return RequestResult.BadRequest(); @@ -204,7 +238,7 @@ public class MediaControllerService(DatabaseContext database, IUserService userS return RequestResult.Ok(data); } - public async Task PutMediaPoster(long id, MediaPosterRequest data) + public async Task PutMediaPoster(long mediaId, MediaPosterRequest data) { UserValidator validator = userService.GetValidator().MustBeAdmin(); if (!validator.IsValid) @@ -212,7 +246,7 @@ public class MediaControllerService(DatabaseContext database, IUserService userS return RequestResult.Forbidden(); } - Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == id); + Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); if (media is null) { return RequestResult.BadRequest(); @@ -236,7 +270,7 @@ public class MediaControllerService(DatabaseContext database, IUserService userS return RequestResult.Ok(); } - public async Task DeleteMediaPoster(long id) + public async Task DeleteMediaPoster(long mediaId) { UserValidator validator = userService.GetValidator().MustBeAdmin(); if (!validator.IsValid) @@ -244,7 +278,7 @@ public class MediaControllerService(DatabaseContext database, IUserService userS return RequestResult.Forbidden(); } - Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == id); + Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); if (media?.MediaPosterImage != null) { diff --git a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Utility/WatchIt.Website.Services.Utility.Configuration/Model/Media.cs b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Utility/WatchIt.Website.Services.Utility.Configuration/Model/Media.cs index c2ff6ab..fb215e2 100644 --- a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Utility/WatchIt.Website.Services.Utility.Configuration/Model/Media.cs +++ b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Utility/WatchIt.Website.Services.Utility.Configuration/Model/Media.cs @@ -11,6 +11,7 @@ public class Media public string GetMediaRatingByUser { get; set; } public string PutMediaRating { get; set; } public string DeleteMediaRating { get; set; } + public string PostMediaView { get; set; } public string GetPhotoMediaRandomBackground { get; set; } public string GetPoster { get; set; } public string PutPoster { get; set; } diff --git a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.WebAPI/WatchIt.Website.Services.WebAPI.Media/IMediaWebAPIService.cs b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.WebAPI/WatchIt.Website.Services.WebAPI.Media/IMediaWebAPIService.cs index 8868cae..6e9a0df 100644 --- a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.WebAPI/WatchIt.Website.Services.WebAPI.Media/IMediaWebAPIService.cs +++ b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.WebAPI/WatchIt.Website.Services.WebAPI.Media/IMediaWebAPIService.cs @@ -14,6 +14,8 @@ public interface IMediaWebAPIService Task GetMediaRatingByUser(long mediaId, long userId, Action? successAction = null, Action? notFoundAction = null); Task PutMediaRating(long mediaId, MediaRatingRequest body, Action? successAction = null, Action>? badRequestAction = null, Action? unauthorizedAction = null, Action? notFoundAction = null); Task DeleteMediaRating(long mediaId, Action? successAction = null, Action? unauthorizedAction = null); + + Task PostMediaView(long mediaId, Action? successAction = null, Action? notFoundAction = null); Task GetPhotoMediaRandomBackground(long mediaId, Action? successAction = null, Action? notFoundAction = null); Task GetPhotoRandomBackground(Action? successAction = null, Action? notFoundAction = null); diff --git a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.WebAPI/WatchIt.Website.Services.WebAPI.Media/MediaWebAPIService.cs b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.WebAPI/WatchIt.Website.Services.WebAPI.Media/MediaWebAPIService.cs index 16b00df..e8541bd 100644 --- a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.WebAPI/WatchIt.Website.Services.WebAPI.Media/MediaWebAPIService.cs +++ b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.WebAPI/WatchIt.Website.Services.WebAPI.Media/MediaWebAPIService.cs @@ -113,6 +113,22 @@ public class MediaWebAPIService(IHttpClientService httpClientService, IConfigura } #endregion + + #region View count + + public async Task PostMediaView(long mediaId, Action? successAction = null, Action? notFoundAction = null) + { + string url = GetUrl(EndpointsConfiguration.Media.PostMediaView, mediaId); + + HttpRequest request = new HttpRequest(HttpMethodType.Post, url); + + HttpResponse response = await httpClientService.SendRequestAsync(request); + response.RegisterActionFor2XXSuccess(successAction) + .RegisterActionFor404NotFound(notFoundAction) + .ExecuteAction(); + } + + #endregion diff --git a/WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor b/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor similarity index 100% rename from WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor rename to WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor diff --git a/WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.cs similarity index 57% rename from WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor.cs rename to WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.cs index 494706a..b3cfa20 100644 --- a/WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor.cs +++ b/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.cs @@ -9,7 +9,7 @@ using WatchIt.Website.Services.WebAPI.Movies; namespace WatchIt.Website.Pages; -public partial class MediaDataPage : ComponentBase +public partial class MediaPage : ComponentBase { #region SERVICES @@ -56,49 +56,49 @@ public partial class MediaDataPage : ComponentBase { if (firstRender) { - await MediaWebAPIService.GetMedia(Id, data => _media = data, () => _error = $"Media with id {Id} was not found"); - + List step1Tasks = new List(); + List step2Tasks = new List(); + List endTasks = new List(); + + // STEP 0 + step1Tasks.AddRange( + [ + MediaWebAPIService.GetMedia(Id, data => _media = data, () => _error = $"Media with id {Id} was not found") + ]); + + // STEP 1 + await Task.WhenAll(step1Tasks); if (_error is null) { - Task backgroundTask = MediaWebAPIService.GetPhotoMediaRandomBackground(Id, data => _background = data); - Task posterTask = MediaWebAPIService.GetPoster(Id, data => _poster = data); - Task userTask = AuthenticationService.GetUserAsync(); - Task genresTask = MediaWebAPIService.GetMediaGenres(Id, data => _genres = data); - Task globalRatingTask = MediaWebAPIService.GetMediaRating(Id, data => _globalRating = data); - Task specificMediaTask; - if (_media.Type == MediaType.Movie) - { - specificMediaTask = MoviesWebAPIService.Get(Id, data => _movie = data); - } - else - { - // TODO: download tv series info - specificMediaTask = null; - } - - await Task.WhenAll( + step2Tasks.AddRange( [ - userTask, - specificMediaTask, - genresTask, - globalRatingTask, - backgroundTask, - posterTask, + Task.Run(async () => _user = await AuthenticationService.GetUserAsync()) ]); - - _user = await userTask; - } - - if (_user is not null) - { - Task userRatingTask = MediaWebAPIService.GetMediaRatingByUser(Id, _user.Id, data => _userRating = data); - await Task.WhenAll( + endTasks.AddRange( [ - userRatingTask, + MediaWebAPIService.PostMediaView(Id), + MediaWebAPIService.GetPhotoMediaRandomBackground(Id, data => _background = data), + MediaWebAPIService.GetPoster(Id, data => _poster = data), + MediaWebAPIService.GetMediaGenres(Id, data => _genres = data), + MediaWebAPIService.GetMediaRating(Id, data => _globalRating = data), + _media.Type == MediaType.Movie ? MoviesWebAPIService.Get(Id, data => _movie = data) : Task.CompletedTask, ]); } + // STEP 2 + await Task.WhenAll(step2Tasks); + if (_error is null && _user is not null) + { + endTasks.AddRange( + [ + MediaWebAPIService.GetMediaRatingByUser(Id, _user.Id, data => _userRating = data) + ]); + } + + // END + await Task.WhenAll(endTasks); + _loaded = true; StateHasChanged(); } diff --git a/WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor.css b/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.css similarity index 100% rename from WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor.css rename to WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.css diff --git a/WatchIt.Website/WatchIt.Website/appsettings.json b/WatchIt.Website/WatchIt.Website/appsettings.json index c93fcd9..8da2d13 100644 --- a/WatchIt.Website/WatchIt.Website/appsettings.json +++ b/WatchIt.Website/WatchIt.Website/appsettings.json @@ -46,6 +46,7 @@ "GetMediaRatingByUser": "/{0}/rating/{1}", "PutMediaRating": "/{0}/rating", "DeleteMediaRating": "/{0}/rating", + "PostMediaView": "/{0}/view", "GetPhotoMediaRandomBackground": "/{0}/photos/random_background", "GetPoster": "/{0}/poster", From d2779cc54e82a71694d848ce5c31b9970d3449ce Mon Sep 17 00:00:00 2001 From: Mateusz Skoczek Date: Sat, 21 Sep 2024 22:04:35 +0200 Subject: [PATCH 2/2] view rank get endpoint for movies added --- .../MoviesController.cs | 49 ++++++- .../IMoviesControllerService.cs | 12 +- .../MoviesControllerService.cs | 129 ++++++++++++------ .../WatchIt.Website/Pages/MediaPage.razor.cs | 12 +- 4 files changed, 146 insertions(+), 56 deletions(-) diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MoviesController.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MoviesController.cs index 517d6cd..5f87add 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MoviesController.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MoviesController.cs @@ -11,18 +11,41 @@ namespace WatchIt.WebAPI.Controllers; [ApiController] [Route("movies")] -public class MoviesController(IMoviesControllerService moviesControllerService) : ControllerBase +public class MoviesController : ControllerBase { + #region SERVICES + + private readonly IMoviesControllerService _moviesControllerService; + + #endregion + + + + #region CONSTRUCTORS + + public MoviesController(IMoviesControllerService moviesControllerService) + { + _moviesControllerService = moviesControllerService; + } + + #endregion + + + + #region METHODS + + #region Main + [HttpGet] [AllowAnonymous] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - public async Task GetAll(MovieQueryParameters query) => await moviesControllerService.GetAll(query); + public async Task GetAllMovies(MovieQueryParameters query) => await _moviesControllerService.GetAllMovies(query); [HttpGet("{id}")] [AllowAnonymous] [ProducesResponseType(typeof(MovieResponse), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task Get([FromRoute]long id) => await moviesControllerService.Get(id); + public async Task GetMovie([FromRoute] long id) => await _moviesControllerService.GetMovie(id); [HttpPost] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] @@ -30,7 +53,7 @@ public class MoviesController(IMoviesControllerService moviesControllerService) [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task Post([FromBody]MovieRequest body) => await moviesControllerService.Post(body); + public async Task PostMovie([FromBody] MovieRequest body) => await _moviesControllerService.PostMovie(body); [HttpPut("{id}")] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] @@ -38,12 +61,26 @@ public class MoviesController(IMoviesControllerService moviesControllerService) [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task Put([FromRoute]long id, [FromBody]MovieRequest body) => await moviesControllerService.Put(id, body); + public async Task PutMovie([FromRoute] long id, [FromBody]MovieRequest body) => await _moviesControllerService.PutMovie(id, body); [HttpDelete("{id}")] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] [ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)] [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - public async Task Delete([FromRoute] long id) => await moviesControllerService.Delete(id); + public async Task DeleteMovie([FromRoute] long id) => await _moviesControllerService.DeleteMovie(id); + + #endregion + + #region View count + + [HttpGet("view")] + [AllowAnonymous] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public async Task GetMoviesViewRank([FromQuery] int first = 5, [FromQuery] int days = 7) => await _moviesControllerService.GetMoviesViewRank(first, days); + + #endregion + + #endregion } \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Movies/IMoviesControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Movies/IMoviesControllerService.cs index 173f7e7..cc514a5 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Movies/IMoviesControllerService.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Movies/IMoviesControllerService.cs @@ -5,9 +5,11 @@ namespace WatchIt.WebAPI.Services.Controllers.Movies; public interface IMoviesControllerService { - Task GetAll(MovieQueryParameters query); - Task Get(long id); - Task Post(MovieRequest data); - Task Put(long id, MovieRequest data); - Task Delete(long id); + Task GetAllMovies(MovieQueryParameters query); + Task GetMovie(long id); + Task PostMovie(MovieRequest data); + Task PutMovie(long id, MovieRequest data); + Task DeleteMovie(long id); + + Task GetMoviesViewRank(int first, int days); } \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Movies/MoviesControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Movies/MoviesControllerService.cs index 5ab3398..cc5d69e 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Movies/MoviesControllerService.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Movies/MoviesControllerService.cs @@ -7,20 +7,44 @@ using WatchIt.WebAPI.Services.Utility.User; namespace WatchIt.WebAPI.Services.Controllers.Movies; -public class MoviesControllerService(DatabaseContext database, IUserService userService) : IMoviesControllerService +public class MoviesControllerService : IMoviesControllerService { - #region PUBLIC METHODS + #region SERVICES - public async Task GetAll(MovieQueryParameters query) + private readonly DatabaseContext _database; + + private readonly IUserService _userService; + + #endregion + + + + #region CONSTRUCTORS + + public MoviesControllerService(DatabaseContext database, IUserService userService) { - IEnumerable data = await database.MediaMovies.Select(x => new MovieResponse(x)).ToListAsync(); + _database = database; + + _userService = userService; + } + + #endregion + + + #region PUBLIC METHODS + + #region Main + + public async Task GetAllMovies(MovieQueryParameters query) + { + IEnumerable data = await _database.MediaMovies.Select(x => new MovieResponse(x)).ToListAsync(); data = query.PrepareData(data); return RequestResult.Ok(data); } - public async Task Get(long id) + public async Task GetMovie(long id) { - MediaMovie? item = await database.MediaMovies.FirstOrDefaultAsync(x => x.Id == id); + MediaMovie? item = await _database.MediaMovies.FirstOrDefaultAsync(x => x.Id == id); if (item is null) { return RequestResult.NotFound(); @@ -30,33 +54,33 @@ public class MoviesControllerService(DatabaseContext database, IUserService user return RequestResult.Ok(data); } - public async Task Post(MovieRequest data) + public async Task PostMovie(MovieRequest data) { - UserValidator validator = userService.GetValidator().MustBeAdmin(); + UserValidator validator = _userService.GetValidator().MustBeAdmin(); if (!validator.IsValid) { return RequestResult.Forbidden(); } Media mediaItem = data.CreateMedia(); - await database.Media.AddAsync(mediaItem); - await database.SaveChangesAsync(); + await _database.Media.AddAsync(mediaItem); + await _database.SaveChangesAsync(); MediaMovie mediaMovieItem = data.CreateMediaMovie(mediaItem.Id); - await database.MediaMovies.AddAsync(mediaMovieItem); - await database.SaveChangesAsync(); + await _database.MediaMovies.AddAsync(mediaMovieItem); + await _database.SaveChangesAsync(); return RequestResult.Created($"movies/{mediaItem.Id}", new MovieResponse(mediaMovieItem)); } - public async Task Put(long id, MovieRequest data) + public async Task PutMovie(long id, MovieRequest data) { - UserValidator validator = userService.GetValidator().MustBeAdmin(); + UserValidator validator = _userService.GetValidator().MustBeAdmin(); if (!validator.IsValid) { return RequestResult.Forbidden(); } - MediaMovie? item = await database.MediaMovies.FirstOrDefaultAsync(x => x.Id == id); + MediaMovie? item = await _database.MediaMovies.FirstOrDefaultAsync(x => x.Id == id); if (item is null) { return RequestResult.NotFound(); @@ -64,49 +88,74 @@ public class MoviesControllerService(DatabaseContext database, IUserService user data.UpdateMediaMovie(item); data.UpdateMedia(item.Media); - await database.SaveChangesAsync(); + await _database.SaveChangesAsync(); return RequestResult.NoContent(); } - public async Task Delete(long id) + public async Task DeleteMovie(long id) { - UserValidator validator = userService.GetValidator().MustBeAdmin(); + UserValidator validator = _userService.GetValidator().MustBeAdmin(); if (!validator.IsValid) { return RequestResult.Forbidden(); } - MediaMovie? item = await database.MediaMovies.FirstOrDefaultAsync(x => x.Id == id); + MediaMovie? item = await _database.MediaMovies.FirstOrDefaultAsync(x => x.Id == id); if (item is null) { return RequestResult.NotFound(); } - database.MediaMovies.Attach(item); - database.MediaMovies.Remove(item); - database.MediaPosterImages.Attach(item.Media.MediaPosterImage!); - database.MediaPosterImages.Remove(item.Media.MediaPosterImage!); - database.MediaPhotoImages.AttachRange(item.Media.MediaPhotoImages); - database.MediaPhotoImages.RemoveRange(item.Media.MediaPhotoImages); - database.MediaGenres.AttachRange(item.Media.MediaGenres); - database.MediaGenres.RemoveRange(item.Media.MediaGenres); - database.MediaProductionCountries.AttachRange(item.Media.MediaProductionCountries); - database.MediaProductionCountries.RemoveRange(item.Media.MediaProductionCountries); - database.PersonActorRoles.AttachRange(item.Media.PersonActorRoles); - database.PersonActorRoles.RemoveRange(item.Media.PersonActorRoles); - database.PersonCreatorRoles.AttachRange(item.Media.PersonCreatorRoles); - database.PersonCreatorRoles.RemoveRange(item.Media.PersonCreatorRoles); - database.RatingsMedia.AttachRange(item.Media.RatingMedia); - database.RatingsMedia.RemoveRange(item.Media.RatingMedia); - database.ViewCountsMedia.AttachRange(item.Media.ViewCountsMedia); - database.ViewCountsMedia.RemoveRange(item.Media.ViewCountsMedia); - database.Media.Attach(item.Media); - database.Media.Remove(item.Media); - await database.SaveChangesAsync(); + _database.MediaMovies.Attach(item); + _database.MediaMovies.Remove(item); + _database.MediaPosterImages.Attach(item.Media.MediaPosterImage!); + _database.MediaPosterImages.Remove(item.Media.MediaPosterImage!); + _database.MediaPhotoImages.AttachRange(item.Media.MediaPhotoImages); + _database.MediaPhotoImages.RemoveRange(item.Media.MediaPhotoImages); + _database.MediaGenres.AttachRange(item.Media.MediaGenres); + _database.MediaGenres.RemoveRange(item.Media.MediaGenres); + _database.MediaProductionCountries.AttachRange(item.Media.MediaProductionCountries); + _database.MediaProductionCountries.RemoveRange(item.Media.MediaProductionCountries); + _database.PersonActorRoles.AttachRange(item.Media.PersonActorRoles); + _database.PersonActorRoles.RemoveRange(item.Media.PersonActorRoles); + _database.PersonCreatorRoles.AttachRange(item.Media.PersonCreatorRoles); + _database.PersonCreatorRoles.RemoveRange(item.Media.PersonCreatorRoles); + _database.RatingsMedia.AttachRange(item.Media.RatingMedia); + _database.RatingsMedia.RemoveRange(item.Media.RatingMedia); + _database.ViewCountsMedia.AttachRange(item.Media.ViewCountsMedia); + _database.ViewCountsMedia.RemoveRange(item.Media.ViewCountsMedia); + _database.Media.Attach(item.Media); + _database.Media.Remove(item.Media); + await _database.SaveChangesAsync(); return RequestResult.NoContent(); } + + #endregion + + #region View count + + public async Task GetMoviesViewRank(int first, int days) + { + if (first < 1 || days < 1) + { + return RequestResult.BadRequest(); + } + + DateOnly startDate = DateOnly.FromDateTime(DateTime.Now).AddDays(-days); + IEnumerable rawData = await _database.MediaMovies.OrderByDescending(x => x.Media.ViewCountsMedia.Where(y => y.Date >= startDate) + .Sum(y => y.ViewCount)) + .ThenBy(x => x.Id) + .Take(first) + .ToListAsync(); + + IEnumerable data = rawData.Select(x => new MovieResponse(x)); + + return RequestResult.Ok(data); + } + + #endregion #endregion } \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.cs index b3cfa20..31430d2 100644 --- a/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.cs +++ b/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.cs @@ -33,16 +33,18 @@ public partial class MediaPage : ComponentBase #region FIELDS - private bool _loaded = false; + private bool _loaded; private string? _error; private MediaResponse? _media; - private MovieResponse? _movie; - private IEnumerable _genres; - private MediaRatingResponse _globalRating; + + private User? _user; + private MediaPhotoResponse? _background; private MediaPosterResponse? _poster; - private User? _user; + private IEnumerable _genres; + private MediaRatingResponse _globalRating; + private MovieResponse? _movie; private short? _userRating;