From cefc6a767f52a0fbd8f1dd98b369a7bcb0f55bbb Mon Sep 17 00:00:00 2001 From: Hamid Reza Mohammadi Date: Fri, 7 Aug 2026 17:02:54 +0330 Subject: [PATCH] tajik backend fixes --- RMuseum/Controllers/GanjoorController.cs | 21 ++++++++ RMuseum/Services/IGanjoorService.cs | 8 +++ .../GanjoorService-Tajik.cs | 51 +++++++++++++++++++ .../GanjoorService-Transilerate.cs | 12 ++++- 4 files changed, 90 insertions(+), 2 deletions(-) diff --git a/RMuseum/Controllers/GanjoorController.cs b/RMuseum/Controllers/GanjoorController.cs index 0e3dc116..204dfd84 100644 --- a/RMuseum/Controllers/GanjoorController.cs +++ b/RMuseum/Controllers/GanjoorController.cs @@ -4524,6 +4524,27 @@ namespace RMuseum.Controllers return BadRequest(res.ExceptionString); } + /// + /// re-runs the Tajik poet/category HTML generators for every already-imported poet and + /// category page, overwriting their stored TajikHtmlText. Needed one-time after changing + /// either generator function (e.g. adding poem excerpts to the table of contents), since + /// the normal SQLite import skips pages that already exist and never refreshes them. + /// + /// + [HttpPut] + [Route("tajik/regenerate-html")] + [Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.ImportOperationShortName)] + [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(bool))] + [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] + public async Task RegenerateTajikCatAndPoetHtmlTextAsync() + { + RServiceResult res = + await _ganjoorService.RegenerateTajikCatAndPoetHtmlTextAsync(); + if (res.Result) + return Ok(); + return BadRequest(res.ExceptionString); + } + /// /// tajik poets /// diff --git a/RMuseum/Services/IGanjoorService.cs b/RMuseum/Services/IGanjoorService.cs index 69c53c34..125ffa73 100644 --- a/RMuseum/Services/IGanjoorService.cs +++ b/RMuseum/Services/IGanjoorService.cs @@ -1582,6 +1582,14 @@ namespace RMuseum.Services /// Task> SearchTajikAsync(PagingParameterModel paging, string term, int? poetId, int? catId); + /// + /// re-runs the Tajik poet/category HTML generators for every already-imported poet and + /// category page, overwriting their stored TajikHtmlText - needed one-time after changing + /// either generator function, since the normal SQLite import skips pages that already exist + /// + /// + Task> RegenerateTajikCatAndPoetHtmlTextAsync(); + /// diff --git a/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-Tajik.cs b/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-Tajik.cs index 29b61b19..59ed48e8 100644 --- a/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-Tajik.cs +++ b/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-Tajik.cs @@ -144,6 +144,17 @@ namespace RMuseum.Services.Implementation verse.Text = tajikVerses.Where(v => v.VOrder == verse.VOrder).Single().TajikText; } + if (page.Poem.Recitations != null) + { + // no TajikRecitations table exists - this audio metadata has no real Tajik + // translation source anywhere, so transliteration is the only option + foreach (var recitation in page.Poem.Recitations) + { + recitation.AudioTitle = LanguageUtils.TransliteratePersianToTajik(recitation.AudioTitle); + recitation.AudioArtist = LanguageUtils.TransliteratePersianToTajik(recitation.AudioArtist); + } + } + if(page.Poem.Next != null) { var nextPoem = await _context.TajikPoems.AsNoTracking().Where(p => p.Id == page.Poem.Next.Id).SingleOrDefaultAsync(); @@ -195,6 +206,46 @@ namespace RMuseum.Services.Implementation return firstLine.Length > 80 ? firstLine.Substring(0, 80) + "…" : firstLine; } + /// + /// re-runs PrepareTajikPoetHtmlTextAsync / PrepareTajikCatHtmlTextAsync for every poet and + /// category page that already has a stored TajikPages row, overwriting TajikHtmlText with + /// freshly generated output. Needed one-time after changing either generator function + /// (e.g. adding poem excerpts to the table of contents), because the normal SQLite import + /// (GanjoorService-TajikSQLiteImport.cs) explicitly skips pages that already exist and so + /// never refreshes previously generated HTML on its own. + /// + public async Task> RegenerateTajikCatAndPoetHtmlTextAsync() + { + try + { + var tajikPoets = await _context.TajikPoets.AsNoTracking().ToListAsync(); + foreach (var tajikPoet in tajikPoets) + { + var poetPage = await _context.GanjoorPages.AsNoTracking().Where(p => p.GanjoorPageType == GanjoorPageType.PoetPage && p.PoetId == tajikPoet.Id).SingleOrDefaultAsync(); + if (poetPage == null) continue; + var tajikPage = await _context.TajikPages.Where(p => p.Id == poetPage.Id).SingleOrDefaultAsync(); + if (tajikPage == null) continue; + tajikPage.TajikHtmlText = await PrepareTajikPoetHtmlTextAsync(_context, tajikPoet); + } + await _context.SaveChangesAsync(); + + var tajikCats = await _context.TajikCats.AsNoTracking().ToListAsync(); + foreach (var tajikCat in tajikCats) + { + var tajikPage = await _context.TajikPages.Where(p => p.Id == tajikCat.Id).SingleOrDefaultAsync(); + if (tajikPage == null) continue; + tajikPage.TajikHtmlText = await PrepareTajikCatHtmlTextAsync(_context, tajikCat); + } + await _context.SaveChangesAsync(); + + return new RServiceResult(true); + } + catch (Exception exp) + { + return new RServiceResult(false, exp.ToString()); + } + } + /// diff --git a/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-Transilerate.cs b/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-Transilerate.cs index fd9c3541..8639b8c6 100644 --- a/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-Transilerate.cs +++ b/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-Transilerate.cs @@ -43,7 +43,11 @@ namespace RMuseum.Services.Implementation var tajikPoem = tajikPoems.Where(p => p.Id == catPoem.Id).SingleOrDefault(); if(tajikPoem != null) { - html += $"

{LanguageUtils.CleanTextForTransileration(tajikPoem.TajikTitle)}

"; + string excerpt = ExtractExcerpt(tajikPoem.TajikPlainText); + string title = LanguageUtils.CleanTextForTransileration(tajikPoem.TajikTitle); + html += string.IsNullOrEmpty(excerpt) + ? $"

{title}

" + : $"

{title}: {excerpt}

"; } } @@ -76,7 +80,11 @@ namespace RMuseum.Services.Implementation var tajikPoem = tajikPoems.Where(p => p.Id == catPoem.Id).SingleOrDefault(); if(tajikPoem != null) { - html += $"

{LanguageUtils.CleanTextForTransileration(tajikPoem.TajikTitle)}

"; + string excerpt = ExtractExcerpt(tajikPoem.TajikPlainText); + string title = LanguageUtils.CleanTextForTransileration(tajikPoem.TajikTitle); + html += string.IsNullOrEmpty(excerpt) + ? $"

{title}

" + : $"

{title}: {excerpt}

"; } } return html;