From 97f3d7f6f9839a7e2bfedb65e89791e60f934484 Mon Sep 17 00:00:00 2001 From: Hamid Reza Mohammadi Date: Sun, 16 Aug 2026 18:15:28 +0330 Subject: [PATCH] tajik public data #498 --- RMuseum/Controllers/GanjoorController.cs | 76 +++++++++++++++++++ RMuseum/RMuseum.xml | 46 +++++++++++ RMuseum/Services/IGanjoorService.cs | 25 ++++++ .../GanjoorService-TajikPublicDataExport.cs | 3 + 4 files changed, 150 insertions(+) diff --git a/RMuseum/Controllers/GanjoorController.cs b/RMuseum/Controllers/GanjoorController.cs index 57d1ff37..05467363 100644 --- a/RMuseum/Controllers/GanjoorController.cs +++ b/RMuseum/Controllers/GanjoorController.cs @@ -8,6 +8,7 @@ using Newtonsoft.Json; using RMuseum.Models.Auth.Memory; using RMuseum.Models.Auth.ViewModel; using RMuseum.Models.Ganjoor; +using RMuseum.Models.Ganjoor.PublicExport; using RMuseum.Models.Ganjoor.ViewModels; using RMuseum.Models.GanjoorAudio.ViewModels; using RMuseum.Models.GanjoorIntegration; @@ -2423,6 +2424,81 @@ namespace RMuseum.Controllers } } + /// + /// start exporting all published Ganjoor data to the public git-tracked JSON data set + /// + /// + [HttpPost("publicdata/batchexport")] + [Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.ImportOperationShortName)] + [ProducesResponseType((int)HttpStatusCode.OK)] + [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] + [ProducesResponseType((int)HttpStatusCode.Unauthorized)] + public IActionResult StartBatchExportPublicGitData() + { + try + { + var res = _ganjoorService.StartBatchExportPublicGitData(); + if (!string.IsNullOrEmpty(res.ExceptionString)) + return BadRequest(res.ExceptionString); + return Ok(); + } + catch (Exception exp) + { + return BadRequest(exp.ToString()); + } + } + + /// + /// start exporting the Tajik (Cyrillic) overlay data to its own, separate public + /// git-tracked JSON data set — only poets/categories/poems with an actual Tajik + /// translation are included + /// + /// + [HttpPost("tajik/publicdata/batchexport")] + [Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.ImportOperationShortName)] + [ProducesResponseType((int)HttpStatusCode.OK)] + [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] + [ProducesResponseType((int)HttpStatusCode.Unauthorized)] + public IActionResult StartBatchExportTajikPublicGitData() + { + try + { + var res = _ganjoorService.StartBatchExportTajikPublicGitData(); + if (!string.IsNullOrEmpty(res.ExceptionString)) + return BadRequest(res.ExceptionString); + return Ok(); + } + catch (Exception exp) + { + return BadRequest(exp.ToString()); + } + } + + /// + /// (re)build local Ganjoor content from a public data export tree (local folder or HTTP) — + /// intended for local development use, not for production servers + /// + /// + [HttpPost("publicdata/import")] + [Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.ImportOperationShortName)] + [ProducesResponseType((int)HttpStatusCode.OK)] + [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] + [ProducesResponseType((int)HttpStatusCode.Unauthorized)] + public IActionResult StartImportFromPublicDataRepo([FromBody] PublicDataImportRequestDto request) + { + try + { + var res = _ganjoorService.StartImportFromPublicDataRepo(request.UseHttp, request.Location, request.PoetId); + if (!string.IsNullOrEmpty(res.ExceptionString)) + return BadRequest(res.ExceptionString); + return Ok(); + } + catch (Exception exp) + { + return BadRequest(exp.ToString()); + } + } + /// /// Get user public profile /// diff --git a/RMuseum/RMuseum.xml b/RMuseum/RMuseum.xml index bfebbe4c..e860605b 100644 --- a/RMuseum/RMuseum.xml +++ b/RMuseum/RMuseum.xml @@ -1775,6 +1775,27 @@ + + + start exporting all published Ganjoor data to the public git-tracked JSON data set + + + + + + start exporting the Tajik (Cyrillic) overlay data to its own, separate public + git-tracked JSON data set — only poets/categories/poems with an actual Tajik + translation are included + + + + + + (re)build local Ganjoor content from a public data export tree (local folder or HTTP) — + intended for local development use, not for production servers + + + Get user public profile @@ -17523,6 +17544,31 @@ + + + start exporting all published data (poets/categories/poems/verses) to the public + git-tracked JSON data set, committing and pushing changes since the last run + + + + + + start exporting the Tajik (Cyrillic) overlay data to its own separate git-tracked JSON + data set — only entities that actually have a Tajik translation are included + + + + + + (re)build local Ganjoor content (poets/categories/poems/verses/sections + their pages) + from a public data export tree, read locally or over HTTP. Safe to re-run — existing + entities (by id) are left untouched, only missing ones are added. + + true: fetch over HTTP (location is a base URL). false: read from a local folder (location is a path). + base URL or local folder path of the exported data tree + 0 imports every poet; a specific id imports only that poet (useful on a slow connection) + + examine site pages for broken links diff --git a/RMuseum/Services/IGanjoorService.cs b/RMuseum/Services/IGanjoorService.cs index 90b011e2..39024c18 100644 --- a/RMuseum/Services/IGanjoorService.cs +++ b/RMuseum/Services/IGanjoorService.cs @@ -633,6 +633,31 @@ namespace RMuseum.Services /// RServiceResult StartBatchGenerateGDBFiles(); + /// + /// start exporting all published data (poets/categories/poems/verses) to the public + /// git-tracked JSON data set, committing and pushing changes since the last run + /// + /// + RServiceResult StartBatchExportPublicGitData(); + + /// + /// start exporting the Tajik (Cyrillic) overlay data to its own separate git-tracked JSON + /// data set — only entities that actually have a Tajik translation are included + /// + /// + RServiceResult StartBatchExportTajikPublicGitData(); + + /// + /// (re)build local Ganjoor content (poets/categories/poems/verses/sections + their pages) + /// from a public data export tree, read locally or over HTTP. Safe to re-run — existing + /// entities (by id) are left untouched, only missing ones are added. + /// + /// true: fetch over HTTP (location is a base URL). false: read from a local folder (location is a path). + /// base URL or local folder path of the exported data tree + /// 0 imports every poet; a specific id imports only that poet (useful on a slow connection) + /// + RServiceResult StartImportFromPublicDataRepo(bool useHttp, string location, int poetId = 0); + /// /// examine site pages for broken links /// diff --git a/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-TajikPublicDataExport.cs b/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-TajikPublicDataExport.cs index 04f21a5e..85112885 100644 --- a/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-TajikPublicDataExport.cs +++ b/RMuseum/Services/Implementation/GanjoorService-Partials/GanjoorService-TajikPublicDataExport.cs @@ -292,6 +292,9 @@ namespace RMuseum.Services.Implementation return $@"# ganjoor-tajik-data +**[▶ Live demo](https://ganjoor.github.io/tjmini/)** — Мини-Ганҷур, a minimal reading app built +on this data, running client-side in your browser with no server of its own. + Cyrillic Tajik transliteration/translation overlay for [Ganjoor](https://ganjoor.net)'s poetry content. This is a **separate, sparser** data set from [ganjoor-data](https://github.com/ganjoor/ganjoor-data) — Tajik coverage only exists for some