tajik fix
This commit is contained in:
parent
35947fc1f7
commit
9a70dc333c
@ -4546,6 +4546,27 @@ namespace RMuseum.Controllers
|
||||
return BadRequest(res.ExceptionString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// recovery job: regenerates TajikHtmlText for every Tajik poem from its TajikVerses,
|
||||
/// overwriting whatever is currently stored - use after RegenerateTajikCatAndPoetHtmlText
|
||||
/// (or anything else) may have corrupted poem pages. Check the Admin area's
|
||||
/// LongRunningJobs page for progress.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[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<bool> res =
|
||||
_ganjoorService.RestoreTajikPoemHtmlTextAsync();
|
||||
if (res.Result)
|
||||
return Ok();
|
||||
return BadRequest(res.ExceptionString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// tajik poets
|
||||
/// </summary>
|
||||
|
||||
@ -1591,6 +1591,15 @@ namespace RMuseum.Services
|
||||
/// <returns></returns>
|
||||
RServiceResult<bool> RegenerateTajikCatAndPoetHtmlTextAsync();
|
||||
|
||||
/// <summary>
|
||||
/// recovery job: regenerates TajikHtmlText for every Tajik poem from its TajikVerses,
|
||||
/// overwriting whatever is currently stored. Safe to run on every poem regardless of
|
||||
/// whether it was actually affected by anything - it recomputes each poem's correct
|
||||
/// HTML from its real verse data every time.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
RServiceResult<bool> RestoreTajikPoemHtmlTextAsync();
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -255,11 +255,100 @@ namespace RMuseum.Services.Implementation
|
||||
foreach (var tajikCat in tajikCats)
|
||||
{
|
||||
await jobProgressServiceEF.UpdateJob(job.Id, done, $"cat: {tajikCat.Id}");
|
||||
var tajikPage = await context.TajikPages.Where(p => p.Id == tajikCat.Id).SingleOrDefaultAsync();
|
||||
if (tajikPage != null)
|
||||
// tajikCat.Id is the CATEGORY's own id (GanjoorCategories.Id), which is a
|
||||
// completely different id space from GanjoorPages.Id (catPageId is generated
|
||||
// independently at import time - see GanjoorService-SQLiteImport.cs). Must
|
||||
// resolve the actual CatPage's GanjoorPages.Id first, exactly like the poet
|
||||
// loop above already does - using tajikCat.Id directly here previously
|
||||
// caused TajikPages rows to be looked up (and overwritten) by the wrong id,
|
||||
// corrupting whichever unrelated page (often a poem) happened to have that id.
|
||||
var catPage = await context.GanjoorPages.AsNoTracking().Where(p => p.GanjoorPageType == GanjoorPageType.CatPage && p.CatId == tajikCat.Id).SingleOrDefaultAsync();
|
||||
if (catPage != null)
|
||||
{
|
||||
tajikPage.TajikHtmlText = await PrepareTajikCatHtmlTextAsync(context, tajikCat);
|
||||
await context.SaveChangesAsync();
|
||||
var tajikPage = await context.TajikPages.Where(p => p.Id == catPage.Id).SingleOrDefaultAsync();
|
||||
if (tajikPage != null)
|
||||
{
|
||||
tajikPage.TajikHtmlText = await PrepareTajikCatHtmlTextAsync(context, tajikCat);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
done++;
|
||||
}
|
||||
|
||||
await jobProgressServiceEF.UpdateJob(job.Id, 100, "", true);
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
await jobProgressServiceEF.UpdateJob(job.Id, 100, "", false, exp.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
return new RServiceResult<bool>(false, exp.ToString());
|
||||
}
|
||||
return new RServiceResult<bool>(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// recovery job: regenerates TajikHtmlText for every Tajik poem from its TajikVerses,
|
||||
/// overwriting whatever is currently stored. GanjoorTajikVerse rows carry no VersePosition
|
||||
/// of their own, so it's recovered by joining back to the original GanjoorVerses row with
|
||||
/// the same Id (the SQLite import sets GanjoorTajikVerse.Id = the original verse's Id).
|
||||
/// Safe to run on every poem regardless of whether it was actually affected by the CatPage
|
||||
/// id bug that RegenerateTajikCatAndPoetHtmlTextAsync had (see its cat-loop comment) - this
|
||||
/// simply recomputes each poem's correct HTML from its real verse data every time, so poems
|
||||
/// that were never touched come out unchanged.
|
||||
/// </summary>
|
||||
public RServiceResult<bool> RestoreTajikPoemHtmlTextAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_backgroundTaskQueue.QueueBackgroundWorkItem
|
||||
(
|
||||
async token =>
|
||||
{
|
||||
using (RMuseumDbContext context = new RMuseumDbContext(new DbContextOptions<RMuseumDbContext>()))
|
||||
{
|
||||
LongRunningJobProgressServiceEF jobProgressServiceEF = new LongRunningJobProgressServiceEF(context);
|
||||
var job = (await jobProgressServiceEF.NewJob("RestoreTajikPoemHtmlText", "Query data")).Result;
|
||||
|
||||
try
|
||||
{
|
||||
var tajikPoems = await context.TajikPoems.AsNoTracking().ToListAsync();
|
||||
int done = 0;
|
||||
foreach (var tajikPoem in tajikPoems)
|
||||
{
|
||||
await jobProgressServiceEF.UpdateJob(job.Id, done, $"poem: {tajikPoem.Id}");
|
||||
|
||||
var tajikVerses = await context.TajikVerses.AsNoTracking().Where(v => v.PoemId == tajikPoem.Id).ToListAsync();
|
||||
if (tajikVerses.Count > 0)
|
||||
{
|
||||
var originalVerses = await context.GanjoorVerses.AsNoTracking().Where(v => v.PoemId == tajikPoem.Id).ToListAsync();
|
||||
var verses = tajikVerses
|
||||
.Select(tv =>
|
||||
{
|
||||
var original = originalVerses.SingleOrDefault(v => v.Id == tv.Id);
|
||||
return new GanjoorVerse()
|
||||
{
|
||||
VOrder = tv.VOrder,
|
||||
VersePosition = original != null ? original.VersePosition : VersePosition.Paragraph,
|
||||
Text = tv.TajikText,
|
||||
};
|
||||
})
|
||||
.OrderBy(v => v.VOrder)
|
||||
.ToList();
|
||||
|
||||
// TajikPages.Id == the poem's own Id for poem pages (see
|
||||
// GanjoorService-TajikSQLiteImport.cs) - no GanjoorPages lookup needed here
|
||||
var tajikPage = await context.TajikPages.Where(p => p.Id == tajikPoem.Id).SingleOrDefaultAsync();
|
||||
if (tajikPage != null)
|
||||
{
|
||||
tajikPage.TajikHtmlText = PrepareHtmlText(verses);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
done++;
|
||||
}
|
||||
|
||||
@ -458,11 +458,12 @@ html, body {
|
||||
.tg-cat-page p:has(> a:only-child) {
|
||||
font-family: 'PT Sans', sans-serif;
|
||||
font-size: 1rem;
|
||||
text-align: center;
|
||||
text-align: start;
|
||||
margin: 0;
|
||||
padding: 10px 14px;
|
||||
border-bottom: 1px solid var(--tg-rule);
|
||||
max-width: 620px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.tg-poet-page p:has(> a:only-child):first-of-type,
|
||||
@ -475,6 +476,16 @@ html, body {
|
||||
.tg-cat-page p:has(> a:only-child) a {
|
||||
color: var(--tg-accent-deep);
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* the excerpt trailing the link (": ..." from PrepareTajikCatHtmlTextAsync /
|
||||
PrepareTajikPoetHtmlTextAsync) is plain text in the same <p>, so it can only
|
||||
be dimmed via the paragraph's own color - the link's explicit color above
|
||||
still wins for the title itself */
|
||||
.tg-poet-page p:has(> a:only-child),
|
||||
.tg-cat-page p:has(> a:only-child) {
|
||||
color: var(--tg-ink-soft);
|
||||
}
|
||||
|
||||
.tg-poet-page p:has(> a:only-child):hover,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user