using System; using System.Collections.Generic; using System.Threading.Tasks; using API.Constants; using API.Data; using API.DTOs.Statistics; using API.Entities; using API.Entities.Enums; using API.Extensions; using API.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; namespace API.Controllers; public class StatsController : BaseApiController { private readonly IStatisticService _statService; private readonly IUnitOfWork _unitOfWork; private readonly UserManager _userManager; public StatsController(IStatisticService statService, IUnitOfWork unitOfWork, UserManager userManager) { _statService = statService; _unitOfWork = unitOfWork; _userManager = userManager; } [HttpGet("user/{userId}/read")] [ResponseCache(CacheProfileName = "Statistics")] public async Task> GetUserReadStatistics(int userId) { var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername()); if (user!.Id != userId && !await _userManager.IsInRoleAsync(user, PolicyConstants.AdminRole)) return Unauthorized("You are not authorized to view another user's statistics"); return Ok(await _statService.GetUserReadStatistics(userId, new List())); } [Authorize("RequireAdminRole")] [HttpGet("server/stats")] [ResponseCache(CacheProfileName = "Statistics")] public async Task> GetHighLevelStats() { return Ok(await _statService.GetServerStatistics()); } [Authorize("RequireAdminRole")] [HttpGet("server/count/year")] [ResponseCache(CacheProfileName = "Statistics")] public async Task>>> GetYearStatistics() { return Ok(await _statService.GetYearCount()); } [Authorize("RequireAdminRole")] [HttpGet("server/count/publication-status")] [ResponseCache(CacheProfileName = "Statistics")] public async Task>>> GetPublicationStatus() { return Ok(await _statService.GetPublicationCount()); } [Authorize("RequireAdminRole")] [HttpGet("server/count/manga-format")] [ResponseCache(CacheProfileName = "Statistics")] public async Task>>> GetMangaFormat() { return Ok(await _statService.GetMangaFormatCount()); } [Authorize("RequireAdminRole")] [HttpGet("server/top/years")] [ResponseCache(CacheProfileName = "Statistics")] public async Task>>> GetTopYears() { return Ok(await _statService.GetTopYears()); } /// /// Returns users with the top reads in the server /// /// /// [Authorize("RequireAdminRole")] [HttpGet("server/top/users")] [ResponseCache(CacheProfileName = "Statistics")] public async Task>> GetTopReads(int days = 0) { return Ok(await _statService.GetTopUsers(days)); } /// /// A breakdown of different files, their size, and format /// /// [Authorize("RequireAdminRole")] [HttpGet("server/file-breakdown")] [ResponseCache(CacheProfileName = "Statistics")] public async Task>> GetFileSize() { return Ok(await _statService.GetFileBreakdown()); } /// /// Returns reading history events for a give or all users, broken up by day, and format /// /// If 0, defaults to all users, else just userId /// If 0, defaults to all time, else just those days asked for /// [HttpGet("reading-count-by-day")] [ResponseCache(CacheProfileName = "Statistics")] public async Task>>> ReadCountByDay(int userId = 0, int days = 0) { var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername()); var isAdmin = User.IsInRole(PolicyConstants.AdminRole); if (!isAdmin && userId != user!.Id) return BadRequest(); return Ok(await _statService.ReadCountByDay(userId, days)); } [HttpGet("day-breakdown")] [Authorize("RequireAdminRole")] [ResponseCache(CacheProfileName = "Statistics")] public ActionResult>> GetDayBreakdown() { return Ok(_statService.GetDayBreakdown()); } [HttpGet("user/reading-history")] [ResponseCache(CacheProfileName = "Statistics")] public async Task>> GetReadingHistory(int userId) { var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername()); var isAdmin = User.IsInRole(PolicyConstants.AdminRole); if (!isAdmin && userId != user!.Id) return BadRequest(); return Ok(await _statService.GetReadingHistory(userId)); } /// /// Returns a count of pages read per year for a given userId. /// /// If userId is 0 and user is not an admin, API will default to userId /// [HttpGet("pages-per-year")] [ResponseCache(CacheProfileName = "Statistics")] public async Task>>> GetPagesReadPerYear(int userId = 0) { var isAdmin = User.IsInRole(PolicyConstants.AdminRole); if (!isAdmin) userId = await _unitOfWork.UserRepository.GetUserIdByUsernameAsync(User.GetUsername()); return Ok(_statService.GetPagesReadCountByYear(userId)); } /// /// Returns a count of words read per year for a given userId. /// /// If userId is 0 and user is not an admin, API will default to userId /// [HttpGet("words-per-year")] [ResponseCache(CacheProfileName = "Statistics")] public async Task>>> GetWordsReadPerYear(int userId = 0) { var isAdmin = User.IsInRole(PolicyConstants.AdminRole); if (!isAdmin) userId = await _unitOfWork.UserRepository.GetUserIdByUsernameAsync(User.GetUsername()); return Ok(_statService.GetWordsReadCountByYear(userId)); } }