#159 generate TOC for all subcategories of a category

This commit is contained in:
Hamid Reza Mohammadi 2021-06-24 19:20:44 +04:30
parent dccee99345
commit 43debed55f
7 changed files with 170 additions and 5 deletions

View File

@ -73,6 +73,8 @@
<p><a href="/Admin/ModifyPage?id=@Model.PageInformation.Id">ویرایش صفحهٔ متناظر</a></p>
<p><a role="button" onclick="startTocGenerationForSubCats(@Model.Cat.Cat.Id)" class="actionlink">شروع تولید مجدد فهرست همهٔ زیربخشها</a></p>
<p><a role="button" onclick="tagCatWithRhymes(@Model.Cat.Cat.Id)" class="actionlink">شروع قافیه‌یابی</a></p>
<table>

View File

@ -144,6 +144,20 @@ namespace GanjooRazor.Areas.Admin.Pages
return new OkObjectResult(false);
}
public async Task<IActionResult> OnPostStartGeneratingSubCatsTOCAsync(int id)
{
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
HttpResponseMessage response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/cat/subcats/startgentoc/{id}", null);
response.EnsureSuccessStatusCode();
return new OkObjectResult(true);
}
}
return new OkObjectResult(false);
}
public async Task<IActionResult> OnPostStartRhythmAnalysisAsync(int id, string rhythm)
{
using (HttpClient secureClient = new HttpClient())

View File

@ -76,6 +76,28 @@
});
}
function startTocGenerationForSubCats(catId) {
if (!confirm('آیا از شروع کار تولید مجدد فهرست همهٔ زیربخشها اطمینان دارید؟'))
return;
var url = '?handler=StartGeneratingSubCatsTOC';
$.ajax({
type: "POST",
url: url,
data: {
id: catId
},
error: function () {
alert('خطا رخ داد.')
},
success: function () {
alert('کار تولید مجدد فهرست همهٔ زیربخشهای بخش شروع شد.')
},
});
}
function tagCatWithRhymes(catId) {
if (!confirm('آیا از شروع کار قافیه‌یابی اطمینان دارید؟'))
return;

View File

@ -489,6 +489,29 @@ namespace RMuseum.Controllers
return Ok(res.Result);
}
/// <summary>
/// start generating sub cats TOC
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpPut("cat/subcats/startgentoc/{id}")]
[Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + SecurableItem.ModifyOperationShortName)]
[ProducesResponseType((int)HttpStatusCode.OK)]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public IActionResult StartGeneratingSubCatsTOC(int id)
{
Guid userId =
new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value);
var res = _ganjoorService.StartGeneratingSubCatsTOC(userId, id);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
return Ok();
}
/// <summary>
/// page by url
/// </summary>

View File

@ -795,6 +795,13 @@
<param name="options"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Controllers.GanjoorController.StartGeneratingSubCatsTOC(System.Int32)">
<summary>
start generating sub cats TOC
</summary>
<param name="id"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Controllers.GanjoorController.GetPageByUrl(System.String,System.Boolean)">
<summary>
page by url
@ -7573,6 +7580,14 @@
<param name="options"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Services.IGanjoorService.StartGeneratingSubCatsTOC(System.Guid,System.Int32)">
<summary>
start generating sub cats TOC
</summary>
<param name="userId"></param>
<param name="catId"></param>
<returns></returns>
</member>
<member name="T:RMuseum.Services.Implementation.ArtifactService">
<summary>
IArtifactService implementation
@ -8960,6 +8975,14 @@
<param name="rhythm"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Services.Implementation.GanjoorService.StartGeneratingSubCatsTOC(System.Guid,System.Int32)">
<summary>
start generating sub cats TOC
</summary>
<param name="userId"></param>
<param name="catId"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Services.Implementation.GanjoorService.GenerateTableOfContents(System.Int32,RMuseum.Models.Ganjoor.GanjoorTOC)">
<summary>
generate category TOC

View File

@ -431,5 +431,13 @@ namespace RMuseum.Services
/// <param name="options"></param>
/// <returns></returns>
Task<RServiceResult<string>> GenerateTableOfContents(int catId, GanjoorTOC options);
/// <summary>
/// start generating sub cats TOC
/// </summary>
/// <param name="userId"></param>
/// <param name="catId"></param>
/// <returns></returns>
RServiceResult<bool> StartGeneratingSubCatsTOC(Guid userId, int catId);
}
}

View File

@ -21,6 +21,7 @@ using Microsoft.Extensions.Caching.Memory;
using System.Net.Http;
using System.Web;
using RMuseum.Services.Implementation.ImportedFromDesktopGanjoor;
using RSecurityBackend.Models.Generic.Db;
namespace RMuseum.Services.Implementation
{
@ -3142,6 +3143,72 @@ namespace RMuseum.Services.Implementation
}
}
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())
{
await jobProgressServiceEF.UpdateJob(job.Id, cat.Id);
var page = await context.GanjoorPages.Where(p => p.FullUrl == cat.FullUrl).SingleAsync();
context.GanjoorPageSnapshots.Add
(
new GanjoorPageSnapshot()
{
GanjoorPageId = page.Id,
MadeObsoleteByUserId = userId,
HtmlText = page.HtmlText,
Note = "تولید گروهی فهرستهای زیربخشها",
RecordDate = DateTime.Now
}
);
page.HtmlText = (await _GenerateTableOfContents(context, cat.Id, GanjoorTOC.TitlesAndFirstVerse)).Result;
context.GanjoorPages.Update(page);
await context.SaveChangesAsync();
await _GeneratingSubCatsTOC(userId, context, jobProgressServiceEF, job, cat.Id);
}
}
/// <summary>
/// start generating sub cats TOC
/// </summary>
/// <param name="userId"></param>
/// <param name="catId"></param>
/// <returns></returns>
public RServiceResult<bool> StartGeneratingSubCatsTOC(Guid userId, int catId)
{
try
{
_backgroundTaskQueue.QueueBackgroundWorkItem
(
async token =>
{
using (RMuseumDbContext context = new RMuseumDbContext(new DbContextOptions<RMuseumDbContext>())) //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($"eneratingSubCatsTOC {catId}", "Query data")).Result;
try
{
await _GeneratingSubCatsTOC(userId, context, jobProgressServiceEF, job, catId);
await jobProgressServiceEF.UpdateJob(job.Id, 100, "", true);
}
catch (Exception exp)
{
await jobProgressServiceEF.UpdateJob(job.Id, 100, "", false, exp.ToString());
}
}
});
return new RServiceResult<bool>(true);
}
catch (Exception exp)
{
return new RServiceResult<bool>(false, exp.ToString());
}
}
/// <summary>
/// generate category TOC
/// </summary>
@ -3149,18 +3216,24 @@ namespace RMuseum.Services.Implementation
/// <param name="options"></param>
/// <returns></returns>
public async Task<RServiceResult<string>> GenerateTableOfContents(int catId, GanjoorTOC options)
{
return await _GenerateTableOfContents(_context, catId, options);
}
private async Task<RServiceResult<string>> _GenerateTableOfContents(RMuseumDbContext context, int catId, GanjoorTOC options)
{
try
{
string html = "";
var subCats = await _context.GanjoorCategories.Where(c => c.ParentId == catId).OrderBy(c => c.Id).AsNoTracking().ToArrayAsync();
var subCats = await context.GanjoorCategories.Where(c => c.ParentId == catId).OrderBy(c => c.Id).AsNoTracking().ToArrayAsync();
foreach(var cat in subCats)
{
html += $"<p><a href=\"{cat.FullUrl}\">{cat.Title}</a></p>{Environment.NewLine}";
}
var poems = await _context.GanjoorPoems.Where(p => p.CatId == catId).OrderBy(p => p.Id).AsNoTracking().ToArrayAsync();
var poems = await context.GanjoorPoems.Where(p => p.CatId == catId).OrderBy(p => p.Id).AsNoTracking().ToArrayAsync();
if(poems.Length > 0)
{
@ -3191,7 +3264,7 @@ namespace RMuseum.Services.Implementation
{
html += $"<p>فهرست شعرها به ترتیب آخر حرف قافیه گردآوری شده است. برای پیدا کردن یک شعر کافی است حرف آخر قافیهٔ آن را در نظر بگیرید تا بتوانید آن را پیدا کنید.</p>{Environment.NewLine}";
var randomPoem = taggedPoems[new Random(DateTime.Now.Millisecond).Next(taggedPoems.Length)];
var randomPoemVerses = await _context.GanjoorVerses.AsNoTracking().Where(p => p.PoemId == randomPoem.Id).OrderBy(v => v.VOrder).ToArrayAsync();
var randomPoemVerses = await context.GanjoorVerses.AsNoTracking().Where(p => p.PoemId == randomPoem.Id).OrderBy(v => v.VOrder).ToArrayAsync();
if(randomPoemVerses.Length > 2)
{
html += $"<p>مثلاً برای پیدا کردن شعری که مصرع <em>{randomPoemVerses[1].Text}</em> مصرع دوم یکی از بیتهای آن است باید شعرهایی را نگاه کنید که آخر حرف قافیهٔ آنها «<em><a href=\"#{ GPersianTextSync.UniquelyFarglisize(randomPoem.RhymeLetters.Substring(randomPoem.RhymeLetters.Length - 1)) }\">{randomPoem.RhymeLetters.Substring(randomPoem.RhymeLetters.Length - 1)}</a></em>» است.</p>{Environment.NewLine}";
@ -3254,7 +3327,7 @@ namespace RMuseum.Services.Implementation
html += $"<p><a href=\"{poem.FullUrl}\">{poem.Title}</a>";
var verses = await _context.GanjoorVerses.AsNoTracking().Where(p => p.PoemId == poem.Id).OrderBy(v => v.VOrder).ToArrayAsync();
var verses = await context.GanjoorVerses.AsNoTracking().Where(p => p.PoemId == poem.Id).OrderBy(v => v.VOrder).ToArrayAsync();
if(verses.Length > 0)
{
@ -3317,7 +3390,7 @@ namespace RMuseum.Services.Implementation
}
html += $"</p>";
html += $"</p>{Environment.NewLine}";
}