diff --git a/DIWAN.md b/DIWAN.md
deleted file mode 100644
index da75bef5..00000000
--- a/DIWAN.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# دیوان · Diwan site
-
-This is a fork of [GanjoorService](https://github.com/ganjoor/GanjoorService) (GPL-3.0), the software behind ganjoor.net, adapted to serve **classical Urdu poetry and prose** from [diwan-data](https://github.com/anas-rashid/diwan-data).
-
-## Changes from upstream
-
-- **Branding:** "گنجور" becomes "دیوان" throughout the site. Upstream is credited in the footer.
-- **Urdu basics:** pages are `lang="ur"`. The home page, footer and century groups (Hijri centuries, e.g. "تیرہویں صدی ہجری") are in Urdu. Deeper pages, such as admin and account pages, are still Persian.
-- **Fonts:** Noto Nastaliq Urdu by default, with a **نستعلیق / نسخ** switch (Noto Naskh Arabic) at the bottom left. The choice is remembered per browser.
-- **Footer:** links to Ganjoor-only services (Hafez divination, music index, etc.) are removed. Links to the Wikisource source, the data and the code are added.
-- **Linux/Docker:** `Dockerfile` + `docker-compose.yml` (SQL Server 2022, API, site, Caddy for HTTPS).
-- **Config fixes so env vars work:** the four places that read `appsettings.json` directly now also read environment variables. The JWT issuer follows `RSecurityBackend:ApplicationName` instead of the hard-coded "Ganjoor". `deploy/entrypoint.sh` copies the settings that RSecurityBackend reads only from `appsettings.json` (connection string, secret, app name, admin email) into the file at container start.
-- **Links:** `ganjoor.net` links to the site's own pages are now relative. Links to Ganjoor's other services (blog, audio, etc.) are left as they are.
-- **Locale:** `ur-PK`.
-
-## Deploy (Ubuntu/Debian x86-64, e.g. Vultr)
-
-```sh
-# 1. Docker
-curl -fsSL https://get.docker.com | sh
-
-# 2. Code + config
-git clone https://github.com/anas-rashid/diwan.git && cd diwan
-cp .env.example .env && nano .env # domains, passwords, admin email
-
-# 3. DNS: point SITE_DOMAIN and API_DOMAIN (A records) at the server, then:
-docker compose up -d --build # first build takes a few minutes
-docker compose logs -f api # wait for "Application started"
-```
-
-SQL Server needs about 2 GB of RAM. Use a plan with at least 4 GB in total.
-
-### Load the data
-
-1. Open `https://SITE_DOMAIN/login` and sign in with `ADMIN_EMAIL` and the password **`Test!123`**. The first login creates the admin account with that fixed password (RSecurityBackend's default; upstream's guide is wrong about this). **Change it right away** in the user panel.
-2. On the import page that opens (or **Admin → مالی و سایت → درونریزی دادهٔ عمومی**), choose **Internet URL** and enter:
- ```
- https://cdn.jsdelivr.net/gh/anas-rashid/diwan-data@main/
- ```
-3. The import runs in the background (about 11k poems). Century groups are rebuilt automatically when it finishes.
-
-Re-running the import adds new poems and leaves existing ones untouched, so it can be repeated after diwan-data's daily sync.
-
-### Update
-
-```sh
-git pull && docker compose up -d --build
-```
-
-## Build locally (macOS/Linux)
-
-```sh
-cd RMuseum # its global.json pins SDK 10.0.302; newer SDKs fail on some upstream Razor views
-dotnet build RMuseum.csproj -p:EnableWindowsTargeting=true
-dotnet build ../GanjooRazor/GanjooRazor.csproj -p:EnableWindowsTargeting=true
-```
-
-Running it needs SQL Server, so use the Docker setup above. SQL Server's image is x86-64 only.
-
-## License
-
-GPL-3.0, same as upstream (see `LICENSE`). Data: see [diwan-data](https://github.com/anas-rashid/diwan-data).
diff --git a/GanjooRazor/Areas/Admin/Pages/ModifyPage.cshtml b/GanjooRazor/Areas/Admin/Pages/ModifyPage.cshtml
index f7695022..7163dd96 100644
--- a/GanjooRazor/Areas/Admin/Pages/ModifyPage.cshtml
+++ b/GanjooRazor/Areas/Admin/Pages/ModifyPage.cshtml
@@ -228,14 +228,11 @@
چینش پیشفرض ابیات
حذف کش صفحه
بازسازی نقشهٔ سایت
- بازسازی نقشهٔ سایت تاجیکی
بازشماری تعداد ابیات قطعات
بازسازی صفحات آمار و اوزان عروضی
بازسازی صفحات استقبالها
بازسازی آمار منابع دیجیتال
بازسازی دادهٔ عمومی
- بازسازی دادهٔ عمومی تاجیکی
- برگردان تاجیکی
@if (Model.PageInformation.PoetOrCat != null)
diff --git a/GanjooRazor/Areas/Admin/Pages/ModifyPage.cshtml.cs b/GanjooRazor/Areas/Admin/Pages/ModifyPage.cshtml.cs
index e3b9f103..5f16571b 100644
--- a/GanjooRazor/Areas/Admin/Pages/ModifyPage.cshtml.cs
+++ b/GanjooRazor/Areas/Admin/Pages/ModifyPage.cshtml.cs
@@ -303,23 +303,6 @@ namespace GanjooRazor.Areas.Admin.Pages
return new OkObjectResult(false);
}
- public async Task OnPostRebuildTajikSitemapAsync()
- {
- using (HttpClient secureClient = new HttpClient(new GanjoorReloginHandler(Request, Response)))
- {
- if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
- {
- HttpResponseMessage response = await secureClient.PostAsync($"{APIRoot.Url}/api/ganjoor/sitemap/tajik", null);
- if (!response.IsSuccessStatusCode)
- {
- return BadRequest(JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()));
- }
- return new OkObjectResult(true);
- }
- }
- return new OkObjectResult(false);
- }
-
public async Task OnPostRebuildStatsAsync()
{
@@ -360,27 +343,6 @@ namespace GanjooRazor.Areas.Admin.Pages
return new OkObjectResult(false);
}
- ///
- /// (re)generate the separate Tajik (Cyrillic) public data export — same background-job
- /// pattern as the main one, different repo
- ///
- public async Task OnPostRegenerateTajikPublicDataAsync()
- {
- using (HttpClient secureClient = new HttpClient(new GanjoorReloginHandler(Request, Response)))
- {
- if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
- {
- HttpResponseMessage response = await secureClient.PostAsync($"{APIRoot.Url}/api/ganjoor/tajik/publicdata/batchexport", null);
- if (!response.IsSuccessStatusCode)
- {
- return BadRequest(JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()));
- }
- return new OkObjectResult(true);
- }
- }
- return new OkObjectResult(false);
- }
-
public async Task OnPostRefillSectionsCoupletCountsAsync()
{
@@ -436,23 +398,6 @@ namespace GanjooRazor.Areas.Admin.Pages
return new OkObjectResult(false);
}
- public async Task OnPostTransilerateAsync()
- {
- using (HttpClient secureClient = new HttpClient(new GanjoorReloginHandler(Request, Response)))
- {
- if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
- {
- HttpResponseMessage response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/transilerate", null);
- if (!response.IsSuccessStatusCode)
- {
- return BadRequest(JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()));
- }
- return new OkObjectResult(true);
- }
- }
- return new OkObjectResult(false);
- }
-
diff --git a/GanjooRazor/Pages/Shared/_AdminLayout.cshtml b/GanjooRazor/Pages/Shared/_AdminLayout.cshtml
index d8ce5653..ec5476ec 100644
--- a/GanjooRazor/Pages/Shared/_AdminLayout.cshtml
+++ b/GanjooRazor/Pages/Shared/_AdminLayout.cshtml
@@ -158,25 +158,6 @@
});
}
- async function rebuildTajikSitemap() {
- var ok = await upConfirm('آیا از بازسازی نقشهٔ سایت تاجیکی اطمینان دارید؟');
- if (!ok) return;
-
- var url = '?handler=RebuildTajikSitemap';
-
- $.ajax({
- type: "POST",
- url: url,
- error: function () {
- upToast('خطا رخ داد.', 'error');
- },
- success: function () {
- upToast('فرایند بازسازی نقشهٔ سایت تاجیکی شروع شد.', 'success');
- },
-
- });
- }
-
async function rebuildStats() {
@@ -217,25 +198,6 @@
});
}
- async function regenerateTajikPublicData() {
- var ok = await upConfirm('آیا از بازسازی و ارسال دادهٔ عمومی تاجیکی (مخزن گیت جداگانه) اطمینان دارید؟');
- if (!ok) return;
-
- var url = '?handler=RegenerateTajikPublicData';
-
- $.ajax({
- type: "POST",
- url: url,
- error: function () {
- upToast('خطا رخ داد.', 'error');
- },
- success: function () {
- upToast('فرایند بازسازی دادهٔ عمومی تاجیکی در پسزمینه شروع شد.', 'success');
- },
-
- });
- }
-
async function refillCoupletCounts() {
@@ -297,25 +259,6 @@
- async function transilerate() {
- var ok = await upConfirm('آیا از شروع برگردان تاجیکی اطمینان دارید؟');
- if (!ok) return;
-
- var url = '?handler=Transilerate';
-
- $.ajax({
- type: "POST",
- url: url,
- error: function () {
- upToast('خطا رخ داد.', 'error');
- },
- success: function () {
- upToast('فرایند شروع شد.', 'success');
- },
-
- });
- }
-
async function rebuildRebuildWordCounts(poetId) {
var onlyCurrentPoet = await upConfirm('فقط شاعر جاری؟', { danger: false });
if (!onlyCurrentPoet) {
diff --git a/GanjoorService.sln b/GanjoorService.sln
index 033d8808..c40e9896 100644
--- a/GanjoorService.sln
+++ b/GanjoorService.sln
@@ -1,14 +1,12 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 18
-VisualStudioVersion = 18.8.12009.203 stable
+VisualStudioVersion = 18.8.12009.203
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RMuseum", "RMuseum\RMuseum.csproj", "{113EF3DE-E8A9-40EF-9DA0-8DFABB3CDD68}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GanjooRazor", "GanjooRazor\GanjooRazor.csproj", "{48F9CDFA-625F-4743-BF21-BD556F6F33E8}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TajikGanjoor", "TajikGanjoor\TajikGanjoor.csproj", "{1C51EB06-5190-4646-84C7-5EE712C86F57}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -23,10 +21,6 @@ Global
{48F9CDFA-625F-4743-BF21-BD556F6F33E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{48F9CDFA-625F-4743-BF21-BD556F6F33E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{48F9CDFA-625F-4743-BF21-BD556F6F33E8}.Release|Any CPU.Build.0 = Release|Any CPU
- {1C51EB06-5190-4646-84C7-5EE712C86F57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1C51EB06-5190-4646-84C7-5EE712C86F57}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1C51EB06-5190-4646-84C7-5EE712C86F57}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1C51EB06-5190-4646-84C7-5EE712C86F57}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/README.md b/README.md
index 108d6470..72c069c6 100644
--- a/README.md
+++ b/README.md
@@ -1,38 +1,64 @@
-> **This is Diwan (دیوان)**, a fork of GanjoorService that serves classical Urdu poetry and prose. See [DIWAN.md](DIWAN.md) for what changed and how to deploy it. The original README follows.
+# دیوان · Diwan site
-# GanjoorService
-Ganjoor museum and ganjoor.net own backend (ASP.NET Core Web API) and frontend (Razor Pages) code
+Diwan is a standalone project built on a fork of [GanjoorService](https://github.com/ganjoor/GanjoorService) (GPL-3.0), the software behind ganjoor.net, adapted to serve **classical Urdu poetry and prose** from [diwan-data](https://github.com/anas-rashid/diwan-data).
-این کد وب سرویس [گنجینهٔ گنجور](https://museum.ganjoor.net) و [گنجور](https://ganjoor.net) و همچنین کد سایت گنجور است.
+## Changes from upstream
-[فهرست توابع در دسترس](https://api.ganjoor.net)
+- **Tajik removed:** the TajikGanjoor site, Tajik API endpoints, services, export and transliteration are gone. Migration `DiwanRemoveTajik` drops their tables.
-
+- **Branding:** "گنجور" becomes "دیوان" throughout the site. Upstream is credited in the footer.
+- **Urdu basics:** pages are `lang="ur"`. The home page, footer and century groups (Hijri centuries, e.g. "تیرہویں صدی ہجری") are in Urdu. Deeper pages, such as admin and account pages, are still Persian.
+- **Fonts:** Noto Nastaliq Urdu by default, with a **نستعلیق / نسخ** switch (Noto Naskh Arabic) at the bottom left. The choice is remembered per browser.
+- **Footer:** links to Ganjoor-only services (Hafez divination, music index, etc.) are removed. Links to the Wikisource source, the data and the code are added.
+- **Linux/Docker:** `Dockerfile` + `docker-compose.yml` (SQL Server 2022, API, site, Caddy for HTTPS).
+- **Config fixes so env vars work:** the four places that read `appsettings.json` directly now also read environment variables. The JWT issuer follows `RSecurityBackend:ApplicationName` instead of the hard-coded "Ganjoor". `deploy/entrypoint.sh` copies the settings that RSecurityBackend reads only from `appsettings.json` (connection string, secret, app name, admin email) into the file at container start.
+- **Links:** `ganjoor.net` links to the site's own pages are now relative. Links to Ganjoor's other services (blog, audio, etc.) are left as they are.
+- **Locale:** `ur-PK`.
-## Running it locally
+## Deploy (Ubuntu/Debian x86-64, e.g. Vultr)
-New to this codebase and want to run your own copy? See **[RUNNING_LOCALLY.md](RUNNING_LOCALLY.md)**
-for a full step-by-step guide — cloning, database setup, and Visual Studio configuration.
+```sh
+# 1. Docker
+curl -fsSL https://get.docker.com | sh
-The one thing that guide covers in more depth but is worth knowing up front: **the production
-database is never published**, since it contains private/user-linked data. What *is* published is
-a git repository of the poetry content itself (poets, categories, poems — allowlisted, no user
-data): **[github.com/ganjoor/ganjoor-data](https://github.com/ganjoor/ganjoor-data)**. A fresh
-local install can pull real content from there via **Admin → مالی و سایت → درونریزی دادهٔ عمومی**
-(also reachable automatically the first time you run the site against an empty database) instead
-of starting from nothing.
+# 2. Code + config
+git clone https://github.com/anas-rashid/diwan.git && cd diwan
+cp .env.example .env && nano .env # domains, passwords, admin email
-## Semantic search
+# 3. DNS: point SITE_DOMAIN and API_DOMAIN (A records) at the server, then:
+docker compose up -d --build # first build takes a few minutes
+docker compose logs -f api # wait for "Application started"
+```
-The "find a poem about..." feature has its own setup guide, separate from the main one above —
-it needs a downloaded ONNX model and published embeddings data on top of the usual database setup:
-**[SEMANTIC_SEARCH_SETUP.md](SEMANTIC_SEARCH_SETUP.md)**. Also has a real troubleshooting section
-covering the actual problems hit building this feature, not a generic checklist — worth reading
-before assuming something new is broken.
+SQL Server needs about 2 GB of RAM. Use a plan with at least 4 GB in total.
-## Changelog
+### Load the data
-The user-facing changelog shown in the site's footer ("تازههای نرمافزار") is generated and
-maintained from git history. See **[docs/CHANGELOG_PROCESS.md](docs/CHANGELOG_PROCESS.md)** for
-the JSON format and the process for adding new entries.
+1. Open `https://SITE_DOMAIN/login` and sign in with `ADMIN_EMAIL` and the password **`Test!123`**. The first login creates the admin account with that fixed password (RSecurityBackend's default; upstream's guide is wrong about this). **Change it right away** in the user panel.
+2. On the import page that opens (or **Admin → مالی و سایت → درونریزی دادهٔ عمومی**), choose **Internet URL** and enter:
+ ```
+ https://cdn.jsdelivr.net/gh/anas-rashid/diwan-data@main/
+ ```
+3. The import runs in the background (about 11k poems). Century groups are rebuilt automatically when it finishes.
+Re-running the import adds new poems and leaves existing ones untouched, so it can be repeated after diwan-data's daily sync.
+
+### Update
+
+```sh
+git pull && docker compose up -d --build
+```
+
+## Build locally (macOS/Linux)
+
+```sh
+cd RMuseum # its global.json pins SDK 10.0.302; newer SDKs fail on some upstream Razor views
+dotnet build RMuseum.csproj -p:EnableWindowsTargeting=true
+dotnet build ../GanjooRazor/GanjooRazor.csproj -p:EnableWindowsTargeting=true
+```
+
+Running it needs SQL Server, so use the Docker setup above. SQL Server's image is x86-64 only.
+
+## License
+
+GPL-3.0, same as upstream (see `LICENSE`). Data: see [diwan-data](https://github.com/anas-rashid/diwan-data).
diff --git a/RMuseum/Controllers/GanjoorController.cs b/RMuseum/Controllers/GanjoorController.cs
index 7af9bfb0..9823d1c7 100644
--- a/RMuseum/Controllers/GanjoorController.cs
+++ b/RMuseum/Controllers/GanjoorController.cs
@@ -2500,32 +2500,6 @@ namespace RMuseum.Controllers
}
}
- ///
- /// 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
@@ -2904,25 +2878,6 @@ namespace RMuseum.Controllers
return Ok();
}
- ///
- /// build tj.ganjoor.net site map
- ///
- ///
- [HttpPost("sitemap/tajik")]
- [Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + SecurableItem.ModifyOperationShortName)]
- [ProducesResponseType((int)HttpStatusCode.OK)]
- [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
- [ProducesResponseType((int)HttpStatusCode.NotFound)]
- public IActionResult StartBuildingTajikSitemap()
- {
- var res = _ganjoorService.StartBuildingTajikSitemap();
-
- if (!string.IsNullOrEmpty(res.ExceptionString))
- return BadRequest(res.ExceptionString);
-
- return Ok();
- }
-
///
/// regenerate stats page
@@ -4637,161 +4592,6 @@ namespace RMuseum.Controllers
}
- /*
- ///
- /// import tajik from sqlite
- ///
- ///
- ///
- [HttpPost]
- [Route("tajik/sqlite/import/{poetId}")]
- [Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.ImportOperationShortName)]
- [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(bool))]
- [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
- public async Task TajikImportFromSqlite(int poetId = 0)
- {
- IFormFile file = Request.Form.Files[0];
-
- RServiceResult res =
- await _ganjoorService.TajikImportFromSqlite(poetId, file);
- if (res.Result)
- return Ok();
- return BadRequest(res.ExceptionString);
- }*/
-
- [HttpPut]
- [Route("tajik/sqlite/onetime/import")]
- [Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.ImportOperationShortName)]
- [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(bool))]
- [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
- public IActionResult TajikOneTimeImportFromSqlite()
- {
-
- RServiceResult res =
- _ganjoorService.TajikImportFromSqlite(0, "C:\\Tools\\import\\output.s3db");
- if (res.Result)
- return Ok();
- 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.
- /// Runs as a background job - check the Admin area's LongRunningJobs page for progress.
- ///
- ///
- [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 IActionResult RegenerateTajikCatAndPoetHtmlTextAsync()
- {
- RServiceResult res =
- _ganjoorService.RegenerateTajikCatAndPoetHtmlTextAsync();
- if (res.Result)
- return Ok();
- return BadRequest(res.ExceptionString);
- }
-
- ///
- /// recovery job: regenerates TajikHtmlText for Tajik poems whose stored HTML currently
- /// contains a link (the signature left by the CatPage id corruption bug) - use after
- /// RegenerateTajikCatAndPoetHtmlText (or anything else) may have corrupted poem pages.
- /// Check the Admin area's LongRunningJobs page for progress.
- ///
- ///
- [HttpPut]
- [Route("tajik/restore-poem-html")]
- [Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.ImportOperationShortName)]
- [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(bool))]
- [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
- public IActionResult RestoreTajikPoemHtmlTextAsync()
- {
- RServiceResult res =
- _ganjoorService.RestoreTajikPoemHtmlTextAsync();
- if (res.Result)
- return Ok();
- return BadRequest(res.ExceptionString);
- }
-
- ///
- /// tajik poets
- ///
- ///
- [HttpGet]
- [Route("tajik/poets")]
- [AllowAnonymous]
- [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorTajikPoet[]))]
- [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
- public async Task GetTajikPoetsAsync()
- {
- var cacheKey = $"ganjoor/tajik/poets";
- if (!_memoryCache.TryGetValue(cacheKey, out GanjoorTajikPoet[] poets))
- {
- RServiceResult res =
- await _ganjoorService.GetTajikPoetsAsync();
- if (!string.IsNullOrEmpty(res.ExceptionString))
- return BadRequest(res.ExceptionString);
-
- poets = res.Result;
- if (AggressiveCacheEnabled)
- _memoryCache.Set(cacheKey, poets, TimeSpan.FromHours(1));
-
- }
- return Ok(poets);
- }
-
- ///
- /// tajik page by url
- ///
- ///
- ///
- ///
- [HttpGet]
- [Route("tajik/page")]
- [AllowAnonymous]
- [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorPageCompleteViewModel))]
- [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
- [ProducesResponseType((int)HttpStatusCode.NotFound)]
- public async Task GetTajikPageByUrlAsync(string url, bool catPoems = false)
- {
- RServiceResult res =
- await _ganjoorService.GetTajikPageByUrlAsync(url, catPoems);
- if (!string.IsNullOrEmpty(res.ExceptionString))
- return BadRequest(res.ExceptionString);
- if (res.Result == null)
- return NotFound();
- return Ok(res.Result);
- }
-
- ///
- /// search tajik poems
- ///
- ///
- ///
- ///
- ///
- ///
- [HttpGet]
- [Route("tajik/search")]
- [AllowAnonymous]
- [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))]
- [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
-
- public async Task SearchTajikAsync([FromQuery] PagingParameterModel paging, string term, int poetId = 0, int catId = 0)
- {
- var pagedResult = await _ganjoorService.SearchTajikAsync(paging, term, poetId == 0 ? (int?)null : poetId, catId == 0 ? (int?)null : catId);
- if (!string.IsNullOrEmpty(pagedResult.ExceptionString))
- return BadRequest(pagedResult.ExceptionString);
-
- // Paging Header
- HttpContext.Response.Headers.Append("paging-headers", JsonConvert.SerializeObject(pagedResult.Result.PagingMeta));
-
- return Ok(pagedResult.Result.Items);
- }
///
/// fill couplet summaries using open ai
diff --git a/RMuseum/DbContext/RMuseumDbContext.cs b/RMuseum/DbContext/RMuseumDbContext.cs
index 2a679ac2..f7add344 100644
--- a/RMuseum/DbContext/RMuseumDbContext.cs
+++ b/RMuseum/DbContext/RMuseumDbContext.cs
@@ -743,31 +743,6 @@ namespace RMuseum.DbContext
///
public DbSet CategoryWordCountSummaries { get; set; }
- ///
- /// tajik poets
- ///
- public DbSet TajikPoets { get; set; }
-
- ///
- /// tajik cats
- ///
- public DbSet TajikCats { get; set; }
-
- ///
- /// tajik poems
- ///
- public DbSet TajikPoems { get; set; }
-
- ///
- /// tajik verse
- ///
- public DbSet TajikVerses { get; set; }
-
- ///
- /// tajik pages
- ///
- public DbSet TajikPages { get; set; }
-
///
/// ganjoor cat corrections
///
diff --git a/RMuseum/Migrations/20261004213712_DiwanRemoveTajik.Designer.cs b/RMuseum/Migrations/20261004213712_DiwanRemoveTajik.Designer.cs
new file mode 100644
index 00000000..41b3193e
--- /dev/null
+++ b/RMuseum/Migrations/20261004213712_DiwanRemoveTajik.Designer.cs
@@ -0,0 +1,6507 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using RMuseum.DbContext;
+
+#nullable disable
+
+namespace RMuseum.Migrations
+{
+ [DbContext(typeof(RMuseumDbContext))]
+ [Migration("20261004213712_DiwanRemoveTajik")]
+ partial class DiwanRemoveTajik
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "10.0.11")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("ClaimType")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ClaimValue")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RoleId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("ClaimType")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ClaimValue")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.Property("LoginProvider")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("ProviderKey")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("ProviderDisplayName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("RoleId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("LoginProvider")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("Name")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("Value")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens", (string)null);
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Accounting.DonationExpenditure", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Amount")
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("GanjoorDonationId")
+ .HasColumnType("int");
+
+ b.Property("GanjoorExpenseId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GanjoorDonationId");
+
+ b.HasIndex("GanjoorExpenseId");
+
+ b.ToTable("DonationExpenditure");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Accounting.GanjoorDonation", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Amount")
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("AmountString")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DateString")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DonorLink")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DonorName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ExpenditureDesc")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ImportedRecord")
+ .HasColumnType("bit");
+
+ b.Property("RecordDate")
+ .HasColumnType("datetime2");
+
+ b.Property("Remaining")
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("Unit")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("GanjoorDonations");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Accounting.GanjoorExpense", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Amount")
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("Description")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ExpenseDate")
+ .HasColumnType("datetime2");
+
+ b.Property("Unit")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("GanjoorExpenses");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Artifact.RArtifactItemRecord", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CoverImageIndex")
+ .HasColumnType("int");
+
+ b.Property("Description")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DescriptionInEnglish")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("FriendlyUrl")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("LastModified")
+ .HasColumnType("datetime2");
+
+ b.Property("Name")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("NameInEnglish")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Order")
+ .HasColumnType("int");
+
+ b.Property("RArtifactMasterRecordId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RArtifactMasterRecordId", "FriendlyUrl")
+ .IsUnique()
+ .HasFilter("[FriendlyUrl] IS NOT NULL");
+
+ b.HasIndex("RArtifactMasterRecordId", "Order")
+ .IsUnique();
+
+ b.ToTable("Items");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Artifact.RArtifactMasterRecord", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CoverImageId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CoverItemIndex")
+ .HasColumnType("int");
+
+ b.Property("DateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("Description")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DescriptionInEnglish")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("FriendlyUrl")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("ItemCount")
+ .HasColumnType("int");
+
+ b.Property("LastModified")
+ .HasColumnType("datetime2");
+
+ b.Property("Name")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("NameInEnglish")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Status")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CoverImageId");
+
+ b.HasIndex("FriendlyUrl")
+ .IsUnique()
+ .HasFilter("[FriendlyUrl] IS NOT NULL");
+
+ b.HasIndex("LastModified");
+
+ b.HasIndex("CoverItemIndex", "Status");
+
+ b.ToTable("Artifacts");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Artifact.RTag", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("FriendlyUrl")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("GlobalValue")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("NameInEnglish")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Order")
+ .HasColumnType("int");
+
+ b.Property("PluralName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PluralNameInEnglish")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Status")
+ .HasColumnType("int");
+
+ b.Property("TagType")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("FriendlyUrl");
+
+ b.ToTable("Tags");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Artifact.RTagValue", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("BookId")
+ .HasColumnType("int");
+
+ b.Property("FriendlyUrl")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("Order")
+ .HasColumnType("int");
+
+ b.Property("PDFBookId")
+ .HasColumnType("int");
+
+ b.Property("PDFPageId")
+ .HasColumnType("int");
+
+ b.Property("RArtifactItemRecordId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("RArtifactMasterRecordId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("RTagId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Status")
+ .HasColumnType("int");
+
+ b.Property("Value")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ValueInEnglish")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ValueSupplement")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("BookId");
+
+ b.HasIndex("FriendlyUrl");
+
+ b.HasIndex("PDFBookId");
+
+ b.HasIndex("PDFPageId");
+
+ b.HasIndex("RArtifactItemRecordId");
+
+ b.HasIndex("RArtifactMasterRecordId");
+
+ b.HasIndex("RTagId");
+
+ b.ToTable("TagValues");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Bookmark.RUserBookmark", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("DateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("Note")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RAppUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("RArtifactItemRecordId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("RArtifactMasterRecordId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("RBookmarkType")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RAppUserId");
+
+ b.HasIndex("RArtifactItemRecordId");
+
+ b.HasIndex("RArtifactMasterRecordId");
+
+ b.ToTable("UserBookmarks");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.ExternalFTPUpload.QueuedFTPUpload", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("DeleteFileAfterUpload")
+ .HasColumnType("bit");
+
+ b.Property("Error")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LocalFilePath")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ProcessDate")
+ .HasColumnType("datetime2");
+
+ b.Property("Processing")
+ .HasColumnType("bit");
+
+ b.Property("QueueDate")
+ .HasColumnType("datetime2");
+
+ b.Property("RemoteFilePath")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("QueuedFTPUploads");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.FAQ.FAQCategory", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CatOrder")
+ .HasColumnType("int");
+
+ b.Property("Description")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Published")
+ .HasColumnType("bit");
+
+ b.Property("Title")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("FAQCategories");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.FAQ.FAQItem", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("AnswerExcerpt")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CategoryId")
+ .HasColumnType("int");
+
+ b.Property("ContentForSearch")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("FullAnswer")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("HashTag1")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("HashTag2")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("HashTag3")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("HashTag4")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ItemOrderInCategory")
+ .HasColumnType("int");
+
+ b.Property("Pinned")
+ .HasColumnType("bit");
+
+ b.Property("PinnedItemOrder")
+ .HasColumnType("int");
+
+ b.Property("Published")
+ .HasColumnType("bit");
+
+ b.Property("Question")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CategoryId");
+
+ b.ToTable("FAQItems");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Ganjoor.CategoryWordCount", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CatId")
+ .HasColumnType("int");
+
+ b.Property("Count")
+ .HasColumnType("int");
+
+ b.Property("RowNmbrInCat")
+ .HasColumnType("int");
+
+ b.Property("Word")
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CatId", "Word")
+ .IsUnique()
+ .HasFilter("[Word] IS NOT NULL");
+
+ b.ToTable("CategoryWordCounts");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Ganjoor.CategoryWordCountSummary", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CatId")
+ .HasColumnType("int");
+
+ b.Property("TotalWordCount")
+ .HasColumnType("int");
+
+ b.Property("UniqueWordCount")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CatId")
+ .IsUnique();
+
+ b.ToTable("CategoryWordCountSummaries");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Ganjoor.DigitalSource", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CoupletsCount")
+ .HasColumnType("int");
+
+ b.Property("FullName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ShortName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("SourceType")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UrlSlug")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("DigitalSources");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Ganjoor.DiscoverQuotedQueueItem", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("PoemId")
+ .HasColumnType("int");
+
+ b.Property("PoetId")
+ .HasColumnType("int");
+
+ b.Property("RelatedPoemId")
+ .HasColumnType("int");
+
+ b.Property("RelatedPoetId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.ToTable("DiscoverQuotedQueueItems");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Ganjoor.GanjoorCachedRelatedPoem", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("FullTitle")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("FullUrl")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("HtmlExcerpt")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PoemId")
+ .HasColumnType("int");
+
+ b.Property("PoetId")
+ .HasColumnType("int");
+
+ b.Property("PoetImageUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PoetMorePoemsLikeThisCount")
+ .HasColumnType("int");
+
+ b.Property("PoetName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RelationOrder")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("FullUrl");
+
+ b.HasIndex("PoemId");
+
+ b.ToTable("GanjoorCachedRelatedPoems");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Ganjoor.GanjoorCachedRelatedSection", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("FullTitle")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("FullUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("HtmlExcerpt")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PoemId")
+ .HasColumnType("int");
+
+ b.Property("PoetId")
+ .HasColumnType("int");
+
+ b.Property("PoetImageUrl")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PoetMorePoemsLikeThisCount")
+ .HasColumnType("int");
+
+ b.Property("PoetName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RelationOrder")
+ .HasColumnType("int");
+
+ b.Property("SectionIndex")
+ .HasColumnType("int");
+
+ b.Property("TargetPoemId")
+ .HasColumnType("int");
+
+ b.Property("TargetSectionIndex")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PoemId", "SectionIndex");
+
+ b.ToTable("GanjoorCachedRelatedSections");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Ganjoor.GanjoorCat", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("int");
+
+ b.Property("BookName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CatType")
+ .HasColumnType("int");
+
+ b.Property("Description")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DescriptionHtml")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("FullUrl")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("MapName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("MixedModeOrder")
+ .HasColumnType("int");
+
+ b.Property("ParentId")
+ .HasColumnType("int");
+
+ b.Property("PoetId")
+ .HasColumnType("int");
+
+ b.Property("Published")
+ .HasColumnType("bit");
+
+ b.Property("RImageId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("SumUpSubsGeoLocations")
+ .HasColumnType("bit");
+
+ b.Property("TableOfContentsStyle")
+ .HasColumnType("int");
+
+ b.Property("Title")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UrlSlug")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("FullUrl");
+
+ b.HasIndex("PoetId");
+
+ b.HasIndex("RImageId");
+
+ b.HasIndex("ParentId", "PoetId");
+
+ SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("ParentId", "PoetId"), new[] { "Id" });
+
+ b.ToTable("GanjoorCategories");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Ganjoor.GanjoorCatCorrection", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("AffectedTheCat")
+ .HasColumnType("bit");
+
+ b.Property("ApplicationOrder")
+ .HasColumnType("int");
+
+ b.Property("CatId")
+ .HasColumnType("int");
+
+ b.Property("Date")
+ .HasColumnType("datetime2");
+
+ b.Property("Description")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DescriptionHtml")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("HideMyName")
+ .HasColumnType("bit");
+
+ b.Property("Note")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("OriginalDescription")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("OriginalDescriptionHtml")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PageId")
+ .HasColumnType("int");
+
+ b.Property("Result")
+ .HasColumnType("int");
+
+ b.Property("ReviewDate")
+ .HasColumnType("datetime2");
+
+ b.Property("ReviewNote")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Reviewed")
+ .HasColumnType("bit");
+
+ b.Property("ReviewerUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CatId");
+
+ b.HasIndex("ReviewerUserId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("GanjoorCatCorrections");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Ganjoor.GanjoorCentury", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("EndYear")
+ .HasColumnType("int");
+
+ b.Property("HalfCenturyOrder")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ShowInTimeLine")
+ .HasColumnType("bit");
+
+ b.Property("StartYear")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.ToTable("GanjoorCenturies");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Ganjoor.GanjoorCenturyPoet", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("GanjoorCenturyId")
+ .HasColumnType("int");
+
+ b.Property("PoetId")
+ .HasColumnType("int");
+
+ b.Property("PoetOrder")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GanjoorCenturyId");
+
+ b.HasIndex("PoetId");
+
+ b.ToTable("GanjoorCenturyPoet");
+ });
+
+ modelBuilder.Entity("RMuseum.Models.Ganjoor.GanjoorComment", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("AuthorEmail")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("AuthorIpAddress")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property