view rank get endpoint for movies added

This commit is contained in:
2024-09-21 22:04:35 +02:00
Unverified
parent 40fdc3f345
commit d2779cc54e
4 changed files with 146 additions and 56 deletions

View File

@@ -11,18 +11,41 @@ namespace WatchIt.WebAPI.Controllers;
[ApiController] [ApiController]
[Route("movies")] [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] [HttpGet]
[AllowAnonymous] [AllowAnonymous]
[ProducesResponseType(typeof(IEnumerable<MovieResponse>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(IEnumerable<MovieResponse>), StatusCodes.Status200OK)]
public async Task<ActionResult> GetAll(MovieQueryParameters query) => await moviesControllerService.GetAll(query); public async Task<ActionResult> GetAllMovies(MovieQueryParameters query) => await _moviesControllerService.GetAllMovies(query);
[HttpGet("{id}")] [HttpGet("{id}")]
[AllowAnonymous] [AllowAnonymous]
[ProducesResponseType(typeof(MovieResponse), StatusCodes.Status200OK)] [ProducesResponseType(typeof(MovieResponse), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult> Get([FromRoute]long id) => await moviesControllerService.Get(id); public async Task<ActionResult> GetMovie([FromRoute] long id) => await _moviesControllerService.GetMovie(id);
[HttpPost] [HttpPost]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
@@ -30,7 +53,7 @@ public class MoviesController(IMoviesControllerService moviesControllerService)
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)]
public async Task<ActionResult> Post([FromBody]MovieRequest body) => await moviesControllerService.Post(body); public async Task<ActionResult> PostMovie([FromBody] MovieRequest body) => await _moviesControllerService.PostMovie(body);
[HttpPut("{id}")] [HttpPut("{id}")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
@@ -38,12 +61,26 @@ public class MoviesController(IMoviesControllerService moviesControllerService)
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)]
public async Task<ActionResult> Put([FromRoute]long id, [FromBody]MovieRequest body) => await moviesControllerService.Put(id, body); public async Task<ActionResult> PutMovie([FromRoute] long id, [FromBody]MovieRequest body) => await _moviesControllerService.PutMovie(id, body);
[HttpDelete("{id}")] [HttpDelete("{id}")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)] [ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)]
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)]
public async Task<ActionResult> Delete([FromRoute] long id) => await moviesControllerService.Delete(id); public async Task<ActionResult> DeleteMovie([FromRoute] long id) => await _moviesControllerService.DeleteMovie(id);
#endregion
#region View count
[HttpGet("view")]
[AllowAnonymous]
[ProducesResponseType(typeof(IEnumerable<MovieResponse>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<ActionResult> GetMoviesViewRank([FromQuery] int first = 5, [FromQuery] int days = 7) => await _moviesControllerService.GetMoviesViewRank(first, days);
#endregion
#endregion
} }

View File

@@ -5,9 +5,11 @@ namespace WatchIt.WebAPI.Services.Controllers.Movies;
public interface IMoviesControllerService public interface IMoviesControllerService
{ {
Task<RequestResult> GetAll(MovieQueryParameters query); Task<RequestResult> GetAllMovies(MovieQueryParameters query);
Task<RequestResult> Get(long id); Task<RequestResult> GetMovie(long id);
Task<RequestResult> Post(MovieRequest data); Task<RequestResult> PostMovie(MovieRequest data);
Task<RequestResult> Put(long id, MovieRequest data); Task<RequestResult> PutMovie(long id, MovieRequest data);
Task<RequestResult> Delete(long id); Task<RequestResult> DeleteMovie(long id);
Task<RequestResult> GetMoviesViewRank(int first, int days);
} }

View File

@@ -7,20 +7,44 @@ using WatchIt.WebAPI.Services.Utility.User;
namespace WatchIt.WebAPI.Services.Controllers.Movies; namespace WatchIt.WebAPI.Services.Controllers.Movies;
public class MoviesControllerService(DatabaseContext database, IUserService userService) : IMoviesControllerService public class MoviesControllerService : IMoviesControllerService
{ {
#region SERVICES
private readonly DatabaseContext _database;
private readonly IUserService _userService;
#endregion
#region CONSTRUCTORS
public MoviesControllerService(DatabaseContext database, IUserService userService)
{
_database = database;
_userService = userService;
}
#endregion
#region PUBLIC METHODS #region PUBLIC METHODS
public async Task<RequestResult> GetAll(MovieQueryParameters query) #region Main
public async Task<RequestResult> GetAllMovies(MovieQueryParameters query)
{ {
IEnumerable<MovieResponse> data = await database.MediaMovies.Select(x => new MovieResponse(x)).ToListAsync(); IEnumerable<MovieResponse> data = await _database.MediaMovies.Select(x => new MovieResponse(x)).ToListAsync();
data = query.PrepareData(data); data = query.PrepareData(data);
return RequestResult.Ok(data); return RequestResult.Ok(data);
} }
public async Task<RequestResult> Get(long id) public async Task<RequestResult> 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) if (item is null)
{ {
return RequestResult.NotFound(); return RequestResult.NotFound();
@@ -30,33 +54,33 @@ public class MoviesControllerService(DatabaseContext database, IUserService user
return RequestResult.Ok(data); return RequestResult.Ok(data);
} }
public async Task<RequestResult> Post(MovieRequest data) public async Task<RequestResult> PostMovie(MovieRequest data)
{ {
UserValidator validator = userService.GetValidator().MustBeAdmin(); UserValidator validator = _userService.GetValidator().MustBeAdmin();
if (!validator.IsValid) if (!validator.IsValid)
{ {
return RequestResult.Forbidden(); return RequestResult.Forbidden();
} }
Media mediaItem = data.CreateMedia(); Media mediaItem = data.CreateMedia();
await database.Media.AddAsync(mediaItem); await _database.Media.AddAsync(mediaItem);
await database.SaveChangesAsync(); await _database.SaveChangesAsync();
MediaMovie mediaMovieItem = data.CreateMediaMovie(mediaItem.Id); MediaMovie mediaMovieItem = data.CreateMediaMovie(mediaItem.Id);
await database.MediaMovies.AddAsync(mediaMovieItem); await _database.MediaMovies.AddAsync(mediaMovieItem);
await database.SaveChangesAsync(); await _database.SaveChangesAsync();
return RequestResult.Created($"movies/{mediaItem.Id}", new MovieResponse(mediaMovieItem)); return RequestResult.Created($"movies/{mediaItem.Id}", new MovieResponse(mediaMovieItem));
} }
public async Task<RequestResult> Put(long id, MovieRequest data) public async Task<RequestResult> PutMovie(long id, MovieRequest data)
{ {
UserValidator validator = userService.GetValidator().MustBeAdmin(); UserValidator validator = _userService.GetValidator().MustBeAdmin();
if (!validator.IsValid) if (!validator.IsValid)
{ {
return RequestResult.Forbidden(); 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) if (item is null)
{ {
return RequestResult.NotFound(); return RequestResult.NotFound();
@@ -64,49 +88,74 @@ public class MoviesControllerService(DatabaseContext database, IUserService user
data.UpdateMediaMovie(item); data.UpdateMediaMovie(item);
data.UpdateMedia(item.Media); data.UpdateMedia(item.Media);
await database.SaveChangesAsync(); await _database.SaveChangesAsync();
return RequestResult.NoContent(); return RequestResult.NoContent();
} }
public async Task<RequestResult> Delete(long id) public async Task<RequestResult> DeleteMovie(long id)
{ {
UserValidator validator = userService.GetValidator().MustBeAdmin(); UserValidator validator = _userService.GetValidator().MustBeAdmin();
if (!validator.IsValid) if (!validator.IsValid)
{ {
return RequestResult.Forbidden(); 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) if (item is null)
{ {
return RequestResult.NotFound(); return RequestResult.NotFound();
} }
database.MediaMovies.Attach(item); _database.MediaMovies.Attach(item);
database.MediaMovies.Remove(item); _database.MediaMovies.Remove(item);
database.MediaPosterImages.Attach(item.Media.MediaPosterImage!); _database.MediaPosterImages.Attach(item.Media.MediaPosterImage!);
database.MediaPosterImages.Remove(item.Media.MediaPosterImage!); _database.MediaPosterImages.Remove(item.Media.MediaPosterImage!);
database.MediaPhotoImages.AttachRange(item.Media.MediaPhotoImages); _database.MediaPhotoImages.AttachRange(item.Media.MediaPhotoImages);
database.MediaPhotoImages.RemoveRange(item.Media.MediaPhotoImages); _database.MediaPhotoImages.RemoveRange(item.Media.MediaPhotoImages);
database.MediaGenres.AttachRange(item.Media.MediaGenres); _database.MediaGenres.AttachRange(item.Media.MediaGenres);
database.MediaGenres.RemoveRange(item.Media.MediaGenres); _database.MediaGenres.RemoveRange(item.Media.MediaGenres);
database.MediaProductionCountries.AttachRange(item.Media.MediaProductionCountries); _database.MediaProductionCountries.AttachRange(item.Media.MediaProductionCountries);
database.MediaProductionCountries.RemoveRange(item.Media.MediaProductionCountries); _database.MediaProductionCountries.RemoveRange(item.Media.MediaProductionCountries);
database.PersonActorRoles.AttachRange(item.Media.PersonActorRoles); _database.PersonActorRoles.AttachRange(item.Media.PersonActorRoles);
database.PersonActorRoles.RemoveRange(item.Media.PersonActorRoles); _database.PersonActorRoles.RemoveRange(item.Media.PersonActorRoles);
database.PersonCreatorRoles.AttachRange(item.Media.PersonCreatorRoles); _database.PersonCreatorRoles.AttachRange(item.Media.PersonCreatorRoles);
database.PersonCreatorRoles.RemoveRange(item.Media.PersonCreatorRoles); _database.PersonCreatorRoles.RemoveRange(item.Media.PersonCreatorRoles);
database.RatingsMedia.AttachRange(item.Media.RatingMedia); _database.RatingsMedia.AttachRange(item.Media.RatingMedia);
database.RatingsMedia.RemoveRange(item.Media.RatingMedia); _database.RatingsMedia.RemoveRange(item.Media.RatingMedia);
database.ViewCountsMedia.AttachRange(item.Media.ViewCountsMedia); _database.ViewCountsMedia.AttachRange(item.Media.ViewCountsMedia);
database.ViewCountsMedia.RemoveRange(item.Media.ViewCountsMedia); _database.ViewCountsMedia.RemoveRange(item.Media.ViewCountsMedia);
database.Media.Attach(item.Media); _database.Media.Attach(item.Media);
database.Media.Remove(item.Media); _database.Media.Remove(item.Media);
await database.SaveChangesAsync(); await _database.SaveChangesAsync();
return RequestResult.NoContent(); return RequestResult.NoContent();
} }
#endregion #endregion
#region View count
public async Task<RequestResult> GetMoviesViewRank(int first, int days)
{
if (first < 1 || days < 1)
{
return RequestResult.BadRequest();
}
DateOnly startDate = DateOnly.FromDateTime(DateTime.Now).AddDays(-days);
IEnumerable<MediaMovie> 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<MovieResponse> data = rawData.Select(x => new MovieResponse(x));
return RequestResult.Ok(data);
}
#endregion
#endregion
} }

View File

@@ -33,16 +33,18 @@ public partial class MediaPage : ComponentBase
#region FIELDS #region FIELDS
private bool _loaded = false; private bool _loaded;
private string? _error; private string? _error;
private MediaResponse? _media; private MediaResponse? _media;
private MovieResponse? _movie;
private IEnumerable<GenreResponse> _genres; private User? _user;
private MediaRatingResponse _globalRating;
private MediaPhotoResponse? _background; private MediaPhotoResponse? _background;
private MediaPosterResponse? _poster; private MediaPosterResponse? _poster;
private User? _user; private IEnumerable<GenreResponse> _genres;
private MediaRatingResponse _globalRating;
private MovieResponse? _movie;
private short? _userRating; private short? _userRating;