diff --git a/RMuseum/Controllers/RecitationController.cs b/RMuseum/Controllers/RecitationController.cs index 0da50104..507b50b7 100644 --- a/RMuseum/Controllers/RecitationController.cs +++ b/RMuseum/Controllers/RecitationController.cs @@ -972,6 +972,24 @@ namespace RMuseum.Controllers return Ok(res.Result.Items); } + /// + /// compute poem recitations order (no update) + /// + /// + /// + [HttpGet("votes/{poemId}/scores")] + [AllowAnonymous] + [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))] + [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] + public async Task ComputePoemRecitationsOrdersAsync(int poemId) + { + var res = await _audioService.ComputePoemRecitationsOrdersAsync(poemId, false); + if (!string.IsNullOrEmpty(res.ExceptionString)) + return BadRequest(res.ExceptionString); + + return Ok(res.Result); + } + /// /// readonly mode /// diff --git a/RMuseum/Models/GanjoorAudio/ViewModels/RecitationOrderingViewModel.cs b/RMuseum/Models/GanjoorAudio/ViewModels/RecitationOrderingViewModel.cs new file mode 100644 index 00000000..90e4f7e2 --- /dev/null +++ b/RMuseum/Models/GanjoorAudio/ViewModels/RecitationOrderingViewModel.cs @@ -0,0 +1,38 @@ +namespace RMuseum.Models.GanjoorAudio.ViewModels +{ + /// + /// Recitation Ordering View Model + /// + public class RecitationOrderingViewModel + { + /// + /// recitation + /// + public int RecitationId { get; set; } + + /// + /// earlyness advatage + /// + public int EarlynessAdvantage { get; set; } + + /// + /// upvotes from users other than the owner + /// + public int UpVotes { get; set; } + + /// + /// approved mistaked + /// + public int Mistakes { get; set; } + + /// + /// total scores + /// + public int TotalScores { get; set; } + + /// + /// computed order + /// + public int ComputedOrder { get; set; } + } +} diff --git a/RMuseum/Services/IRecitationService.cs b/RMuseum/Services/IRecitationService.cs index 35b5b56d..adbfe518 100644 --- a/RMuseum/Services/IRecitationService.cs +++ b/RMuseum/Services/IRecitationService.cs @@ -232,11 +232,12 @@ namespace RMuseum.Services Task> AcceptReportedErrorAsync(int id); /// - /// reorder poem recitations by user upvotes + being elder score + /// compute poem recitations order /// /// + /// /// - Task> ReOrderPoemRecitationsAsync(int poemId); + Task> ComputePoemRecitationsOrdersAsync(int poemId, bool update = true); /// /// up vote a recitation diff --git a/RMuseum/Services/Implementation/RecitationService.cs b/RMuseum/Services/Implementation/RecitationService.cs index b8d764c9..3fb7b6cc 100644 --- a/RMuseum/Services/Implementation/RecitationService.cs +++ b/RMuseum/Services/Implementation/RecitationService.cs @@ -1870,45 +1870,69 @@ namespace RMuseum.Services.Implementationa } /// - /// reorder poem recitations by user upvotes + being elder score + /// compute poem recitations order /// /// + /// /// - public async Task> ReOrderPoemRecitationsAsync(int poemId) + public async Task> ComputePoemRecitationsOrdersAsync(int poemId, bool update = true) { try { - var recitations = + var recitations = await _context.Recitations .Where(r => r.ReviewStatus == AudioReviewStatus.Approved && r.GanjoorPostId == poemId) .OrderByDescending(r => r.Id) //this causes the oldest recirations to become the first one .ToListAsync(); - for (var i = 0; i< recitations.Count; i++) + List scores = new List(); + + for (var i = 0; i < recitations.Count; i++) { var recitation = recitations[i]; + RecitationOrderingViewModel score = new RecitationOrderingViewModel() + { + RecitationId = recitation.Id, + EarlynessAdvantage = recitations.Count - 1 - i, + UpVotes = await _context.RecitationUserUpVotes.AsNoTracking().Where(r => r.RecitationId == recitation.Id && r.UserId != recitation.OwnerId) + .CountAsync(), + Mistakes = 0 + }; + + + score.TotalScores = score.EarlynessAdvantage + + score.UpVotes + - score.Mistakes; + //audio order is used as a temporary variable in the following line and soon is get replaced by computed value - recitation.AudioOrder = - recitations.Count - 1 - i + - await _context.RecitationUserUpVotes.AsNoTracking().Where(r => r.RecitationId == recitation.Id && r.UserId != recitation.OwnerId) - .CountAsync(); //this way oldest recitations have an advantage which could be beaten by user ranks over time + recitation.AudioOrder = score.TotalScores; + + scores.Add(score); } recitations.Sort((a, b) => a.AudioOrder.CompareTo(b.AudioOrder)); for (var i = 0; i < recitations.Count; i++) { recitations[i].AudioOrder = i + 1; - _context.Update(recitations[i]); + + scores.Where(s => s.RecitationId == recitations[i].Id).Single().ComputedOrder = i + 1; + + if (update) + { + _context.Update(recitations[i]); + } + } - await _context.SaveChangesAsync(); + if (update) + await _context.SaveChangesAsync(); - return new RServiceResult(true); + return new RServiceResult(scores.ToArray()); } catch (Exception exp) { - return new RServiceResult(false, exp.ToString()); + return new RServiceResult(null, exp.ToString()); } } @@ -1947,7 +1971,7 @@ namespace RMuseum.Services.Implementationa _context.RecitationUserUpVotes.Add(vote); await _context.SaveChangesAsync(); - await ReOrderPoemRecitationsAsync(recitation.GanjoorPostId); + await ComputePoemRecitationsOrdersAsync(recitation.GanjoorPostId); return new RServiceResult(true); @@ -1977,7 +2001,7 @@ namespace RMuseum.Services.Implementationa _context.Remove(vote); await _context.SaveChangesAsync(); - await ReOrderPoemRecitationsAsync(recitation.GanjoorPostId); + await ComputePoemRecitationsOrdersAsync(recitation.GanjoorPostId); return new RServiceResult(true);