From 32826ef4f52eae6f608c96505b646400b7c1c08b Mon Sep 17 00:00:00 2001 From: Hamid Reza Mohammadi Date: Thu, 30 Dec 2021 15:32:16 +0330 Subject: [PATCH] #268 added API for processing probable poem metres --- RMuseum/Controllers/GanjoorController.cs | 42 +++++ RMuseum/RMuseum.xml | 62 +++++-- RMuseum/Services/IGanjoorService.cs | 8 + .../GanjoorService-Maintenance.cs | 88 ---------- .../GanjoorService-ProbableMetres.cs | 156 ++++++++++++++++++ 5 files changed, 254 insertions(+), 102 deletions(-) create mode 100644 RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-ProbableMetres.cs diff --git a/RMuseum/Controllers/GanjoorController.cs b/RMuseum/Controllers/GanjoorController.cs index c2362720..c9f37a12 100644 --- a/RMuseum/Controllers/GanjoorController.cs +++ b/RMuseum/Controllers/GanjoorController.cs @@ -2254,6 +2254,48 @@ namespace RMuseum.Controllers return Ok(res.Result); } + /// + /// save ganjoor poem probable metre + /// + /// + /// + /// + [HttpPut] + [Route("probablemetre/save/{id}")] + [Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + SecurableItem.ModifyOperationShortName)] + [ProducesResponseType((int)HttpStatusCode.OK)] + [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] + [ProducesResponseType((int)HttpStatusCode.NotFound)] + public async Task SaveGanjoorPoemProbableMetre(int id, [FromBody] string metre) + { + RServiceResult res = + await _ganjoorService.SaveGanjoorPoemProbableMetre(id, metre); + if (!string.IsNullOrEmpty(res.ExceptionString)) + return BadRequest(res.ExceptionString); + return Ok(); + } + + /// + /// dismiss ganjoor poem probable metre + /// + /// + /// + + [HttpDelete] + [Route("probablemetre/dismiss/{id}")] + [Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + SecurableItem.ModifyOperationShortName)] + [ProducesResponseType((int)HttpStatusCode.OK)] + [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] + [ProducesResponseType((int)HttpStatusCode.NotFound)] + public async Task DismissGanjoorPoemProbableMetre(int id) + { + RServiceResult res = + await _ganjoorService.SaveGanjoorPoemProbableMetre(id, "dismissed"); + if (!string.IsNullOrEmpty(res.ExceptionString)) + return BadRequest(res.ExceptionString); + return Ok(); + } + /// /// readonly mode /// diff --git a/RMuseum/RMuseum.xml b/RMuseum/RMuseum.xml index fb7a03e7..a34b8770 100644 --- a/RMuseum/RMuseum.xml +++ b/RMuseum/RMuseum.xml @@ -1371,6 +1371,21 @@ + + + save ganjoor poem probable metre + + + + + + + + dismiss ganjoor poem probable metre + + + + readonly mode @@ -10072,6 +10087,14 @@ + + + save ganjoor poem probable metre + + problable metre id + + + translation service implementation @@ -11281,6 +11304,9 @@ IGanjoorService implementation + + IGanjoorService implementation + @@ -11363,20 +11389,6 @@ - - - Start finding missing rhthms - - - - - - - - get next ganjoor poem probable metre - - - start generating sub cats TOC @@ -11437,6 +11449,28 @@ + + + Start finding missing rhthms + + + + + + + + get next ganjoor poem probable metre + + + + + + save ganjoor poem probable metre + + problable metre id + + + get a poem related poems diff --git a/RMuseum/Services/IGanjoorService.cs b/RMuseum/Services/IGanjoorService.cs index 9420ed0b..9a8a6ee4 100644 --- a/RMuseum/Services/IGanjoorService.cs +++ b/RMuseum/Services/IGanjoorService.cs @@ -695,5 +695,13 @@ namespace RMuseum.Services /// /// Task> GetNextGanjoorPoemProbableMetre(); + + /// + /// save ganjoor poem probable metre + /// + /// problable metre id + /// + /// + Task> SaveGanjoorPoemProbableMetre(int id, string metre); } } diff --git a/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-Maintenance.cs b/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-Maintenance.cs index 5683a1fc..9e33edee 100644 --- a/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-Maintenance.cs +++ b/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-Maintenance.cs @@ -97,94 +97,6 @@ namespace RMuseum.Services.Implementation return new RServiceResult(true); } - /// - /// Start finding missing rhthms - /// - /// - /// - /// - public RServiceResult StartFindingMissingRhythms(bool onlyPoemsWithRhymes, int poemsNum = 1000) - { - _backgroundTaskQueue.QueueBackgroundWorkItem - ( - async token => - { - using (RMuseumDbContext context = new RMuseumDbContext(new DbContextOptions())) //this is long running job, so _context might be already been freed/collected by GC - { - LongRunningJobProgressServiceEF jobProgressServiceEF = new LongRunningJobProgressServiceEF(context); - var job = (await jobProgressServiceEF.NewJob($"StartFindingMissingRhythms", "Query data")).Result; - try - { - var poemIds = await context.GanjoorPoems.AsNoTracking() - .Where(p => - p.GanjoorMetreId == null && (onlyPoemsWithRhymes == false || !string.IsNullOrEmpty(p.RhymeLetters)) - && - false == (context.GanjoorVerses.Where(v => v.PoemId == p.Id && (v.VersePosition == VersePosition.Paragraph || v.VersePosition == VersePosition.Single)).Any() ) - ) - .Take(poemsNum) - .Select(p => p.Id) - .ToArrayAsync(); - await jobProgressServiceEF.UpdateJob(job.Id, 0, $"Total: {poemIds.Length}"); - var metres = await context.GanjoorMetres.OrderBy(m => m.Rhythm).AsNoTracking().Select(m => m.Rhythm).ToArrayAsync(); - - using (HttpClient httpClient = new HttpClient()) - { - for (int i = 0; i < poemIds.Length; i++) - { - var id = poemIds[i]; - if ((await context.GanjoorPoemProbableMetres.Where(p => p.PoemId == id).AnyAsync()) == true) - continue; - - var res = await _FindPoemRhythm(id, context, httpClient, metres, true ); - if (res.Result == null) - res.Result = ""; - - GanjoorPoemProbableMetre prometre = new GanjoorPoemProbableMetre() - { - PoemId = id, - Metre = res.Result - }; - - context.GanjoorPoemProbableMetres.Add(prometre); - - await jobProgressServiceEF.UpdateJob(job.Id, i); - } - } - - await jobProgressServiceEF.UpdateJob(job.Id, 100, "", true); - } - catch (Exception exp) - { - await jobProgressServiceEF.UpdateJob(job.Id, 100, "", false, exp.ToString()); - } - - } - }); - - return new RServiceResult(true); - } - - /// - /// get next ganjoor poem probable metre - /// - /// - public async Task> GetNextGanjoorPoemProbableMetre() - { - var next = await _context.GanjoorPoemProbableMetres.Where(p => p.Metre != "dismissed").AsNoTracking().FirstOrDefaultAsync(); - if (next == null) - return new RServiceResult(null); - var res = await GetPoemById(next.PoemId); - if (!string.IsNullOrEmpty(res.ExceptionString)) - return new RServiceResult(null, res.ExceptionString); - if (res.Result == null) - return new RServiceResult(null, "poem does not exist!"); - res.Result.GanjoorMetre = new GanjoorMetre() - { - Rhythm = next.Metre - }; - return res; - } - private async Task _GeneratingSubCatsTOC(Guid userId, RMuseumDbContext context, LongRunningJobProgressServiceEF jobProgressServiceEF, RLongRunningJobStatus job, int catId) { foreach (var cat in await context.GanjoorCategories.AsNoTracking().Where(c => c.ParentId == catId).ToListAsync()) diff --git a/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-ProbableMetres.cs b/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-ProbableMetres.cs new file mode 100644 index 00000000..62ef5282 --- /dev/null +++ b/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-ProbableMetres.cs @@ -0,0 +1,156 @@ +using Microsoft.EntityFrameworkCore; +using RMuseum.DbContext; +using RMuseum.Models.Ganjoor; +using RMuseum.Models.Ganjoor.ViewModels; +using RMuseum.Services.Implementation.ImportedFromDesktopGanjoor; +using RSecurityBackend.Models.Generic; +using RSecurityBackend.Models.Generic.Db; +using RSecurityBackend.Services.Implementation; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace RMuseum.Services.Implementation +{ + /// + /// IGanjoorService implementation + /// + public partial class GanjoorService : IGanjoorService + { + /// + /// Start finding missing rhthms + /// + /// + /// + /// + public RServiceResult StartFindingMissingRhythms(bool onlyPoemsWithRhymes, int poemsNum = 1000) + { + _backgroundTaskQueue.QueueBackgroundWorkItem + ( + async token => + { + using (RMuseumDbContext context = new RMuseumDbContext(new DbContextOptions())) //this is long running job, so _context might be already been freed/collected by GC + { + LongRunningJobProgressServiceEF jobProgressServiceEF = new LongRunningJobProgressServiceEF(context); + var job = (await jobProgressServiceEF.NewJob($"StartFindingMissingRhythms", "Query data")).Result; + try + { + var poemIds = await context.GanjoorPoems.AsNoTracking() + .Where(p => + p.GanjoorMetreId == null && (onlyPoemsWithRhymes == false || !string.IsNullOrEmpty(p.RhymeLetters)) + && + false == (context.GanjoorVerses.Where(v => v.PoemId == p.Id && (v.VersePosition == VersePosition.Paragraph || v.VersePosition == VersePosition.Single)).Any()) + ) + .Take(poemsNum) + .Select(p => p.Id) + .ToArrayAsync(); + await jobProgressServiceEF.UpdateJob(job.Id, 0, $"Total: {poemIds.Length}"); + var metres = await context.GanjoorMetres.OrderBy(m => m.Rhythm).AsNoTracking().Select(m => m.Rhythm).ToArrayAsync(); + + using (HttpClient httpClient = new HttpClient()) + { + for (int i = 0; i < poemIds.Length; i++) + { + var id = poemIds[i]; + if ((await context.GanjoorPoemProbableMetres.Where(p => p.PoemId == id).AnyAsync()) == true) + continue; + + var res = await _FindPoemRhythm(id, context, httpClient, metres, true); + if (res.Result == null) + res.Result = ""; + + GanjoorPoemProbableMetre prometre = new GanjoorPoemProbableMetre() + { + PoemId = id, + Metre = res.Result + }; + + context.GanjoorPoemProbableMetres.Add(prometre); + + await jobProgressServiceEF.UpdateJob(job.Id, i); + } + } + + await jobProgressServiceEF.UpdateJob(job.Id, 100, "", true); + } + catch (Exception exp) + { + await jobProgressServiceEF.UpdateJob(job.Id, 100, "", false, exp.ToString()); + } + + } + }); + + return new RServiceResult(true); + } + + /// + /// get next ganjoor poem probable metre + /// + /// + public async Task> GetNextGanjoorPoemProbableMetre() + { + var next = await _context.GanjoorPoemProbableMetres.Where(p => p.Metre != "dismissed").AsNoTracking().FirstOrDefaultAsync(); + if (next == null) + return new RServiceResult(null); + var res = await GetPoemById(next.PoemId); + if (!string.IsNullOrEmpty(res.ExceptionString)) + return new RServiceResult(null, res.ExceptionString); + if (res.Result == null) + return new RServiceResult(null, "poem does not exist!"); + res.Result.GanjoorMetre = new GanjoorMetre() + { + Rhythm = next.Metre + }; + return res; + } + + /// + /// save ganjoor poem probable metre + /// + /// problable metre id + /// + /// + public async Task> SaveGanjoorPoemProbableMetre(int id, string metre) + { + try + { + var item = await _context.GanjoorPoemProbableMetres.Where(p => p.Id == id).SingleAsync(); + metre = metre.Trim(); + if (string.IsNullOrEmpty(metre)) + metre = "dismissed"; + if (metre == "dismissed") + { + item.Metre = "dismissed"; + _context.Update(item); + await _context.SaveChangesAsync(); + return new RServiceResult(true); + } + var rhythm = await _context.GanjoorMetres.AsNoTracking().Where(m => m.Rhythm == metre).SingleOrDefaultAsync(); + if(rhythm == null) + { + rhythm = new GanjoorMetre() + { + Rhythm = metre, + VerseCount = 0 + }; + _context.GanjoorMetres.Add(rhythm); + await _context.SaveChangesAsync(); + } + var poem = await _context.GanjoorPoems.Where(p => p.Id == item.PoemId).SingleAsync(); + poem.GanjoorMetreId = rhythm.Id; + _context.Update(poem); + _context.Remove(item); + await _context.SaveChangesAsync(); + return new RServiceResult(true); + } + catch(Exception exp) + { + return new RServiceResult(false, exp.ToString()); + } + } + } +} \ No newline at end of file