Projects (GanjooRazor -> DivanRazor, GanjoorService.sln -> DivanService.sln), files, folders, classes, namespaces, settings, API routes (/api/divan) and DB tables (Divan*). External addresses (ganjoor.net, github.com/ganjoor) unchanged. Migrations renamed consistently (no pending model changes); requires a fresh database. Upstream RUNNING_LOCALLY/SEMANTIC_SEARCH docs archived unmodified under docs/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
622 lines
27 KiB
C#
622 lines
27 KiB
C#
using Microsoft.EntityFrameworkCore;
|
||
using RMuseum.Models.Divan;
|
||
using RSecurityBackend.Models.Generic;
|
||
using System;
|
||
using System.Data;
|
||
using System.Linq;
|
||
using System.Threading.Tasks;
|
||
using DNTPersianUtils.Core;
|
||
using RMuseum.Models.Divan.ViewModels;
|
||
using RMuseum.DbContext;
|
||
using System.Collections.Generic;
|
||
|
||
namespace RMuseum.Services.Implementation
|
||
{
|
||
/// <summary>
|
||
/// IDivanService implementation
|
||
/// </summary>
|
||
public partial class DivanService : IDivanService
|
||
{
|
||
public async Task<RServiceResult<int>> _BreakPoemAsync(RMuseumDbContext context, int poemId, int vOrder, Guid userId, DivanPoemCompleteViewModel poem, DivanPage parentPage, string poemTitleStaticPart)
|
||
{
|
||
if (poem.Next == null)
|
||
{
|
||
return await _BreakLastPoemInItsCategoryAsync(context, poemId, vOrder, userId, poem, parentPage, poemTitleStaticPart);
|
||
}
|
||
var dbMainPoem = await context.DivanPoems.Include(p => p.DivanMetre).Where(p => p.Id == poemId).SingleOrDefaultAsync();
|
||
|
||
if(dbMainPoem.Title.IndexOf(poemTitleStaticPart) != 0)
|
||
return new RServiceResult<int>(-1, $"dbMainPoem.Title.IndexOf(poemTitleStaticPart) != 0");
|
||
|
||
if (!int.TryParse(dbMainPoem.UrlSlug.Substring("sh".Length), out int mainPoemSlugNumber))
|
||
return new RServiceResult<int>(-1, $"slug error for the last poem in the category: {dbMainPoem.UrlSlug}");
|
||
|
||
|
||
var dbPage = await context.DivanPages.Where(p => p.Id == poemId).SingleOrDefaultAsync();
|
||
|
||
var catPage = await context.DivanPages.AsNoTracking().Where(p => p.DivanPageType == DivanPageType.CatPage && p.CatId == dbMainPoem.CatId).SingleOrDefaultAsync();
|
||
|
||
var poemList = await context.DivanPoems.AsNoTracking().Where(p => p.CatId == dbMainPoem.CatId && p.Id > dbMainPoem.Id).OrderBy(p => p.Id).ToListAsync();
|
||
|
||
var lastPoemInCategory = poemList.Last();
|
||
|
||
if (!int.TryParse(lastPoemInCategory.UrlSlug.Substring("sh".Length), out int newPoemSlugNumber))
|
||
return new RServiceResult<int>(-1, $"slug error for the last poem in the category: {lastPoemInCategory.UrlSlug}");
|
||
|
||
string nextPoemUrlSluf = $"sh{newPoemSlugNumber + 1}";
|
||
|
||
var maxPoemId = await context.DivanPoems.MaxAsync(p => p.Id);
|
||
if (await context.DivanPages.MaxAsync(p => p.Id) > maxPoemId)
|
||
maxPoemId = await context.DivanPages.MaxAsync(p => p.Id);
|
||
var nextPoemId = 1 + maxPoemId;
|
||
|
||
string nextPoemTitle = $"{poemTitleStaticPart} {(newPoemSlugNumber + 1).ToPersianNumbers()}";
|
||
|
||
DivanPoem dbNewPoem = new DivanPoem()
|
||
{
|
||
Id = nextPoemId,
|
||
CatId = poem.Category.Cat.Id,
|
||
Title = nextPoemTitle,
|
||
UrlSlug = nextPoemUrlSluf,
|
||
FullTitle = $"{parentPage.FullTitle} » {nextPoemTitle}",
|
||
FullUrl = $"{parentPage.FullUrl}/{nextPoemUrlSluf}",
|
||
SourceName = poem.SourceName,
|
||
SourceUrlSlug = poem.SourceUrlSlug,
|
||
Language = dbMainPoem.Language,
|
||
MixedModeOrder = dbMainPoem.MixedModeOrder,
|
||
Published = dbMainPoem.Published,
|
||
};
|
||
|
||
DivanPage dbPoemNewPage = new DivanPage()
|
||
{
|
||
Id = nextPoemId,
|
||
DivanPageType = DivanPageType.PoemPage,
|
||
Published = true,
|
||
PageOrder = -1,
|
||
Title = dbNewPoem.Title,
|
||
FullTitle = dbNewPoem.FullTitle,
|
||
UrlSlug = dbNewPoem.UrlSlug,
|
||
FullUrl = dbNewPoem.FullUrl,
|
||
HtmlText = dbNewPoem.HtmlText,
|
||
PoetId = parentPage.PoetId,
|
||
CatId = poem.Category.Cat.Id,
|
||
PoemId = nextPoemId,
|
||
PostDate = DateTime.Now,
|
||
ParentId = parentPage.Id,
|
||
};
|
||
context.DivanPoems.Add(dbNewPoem);
|
||
context.DivanPages.Add(dbPoemNewPage);
|
||
await context.SaveChangesAsync();
|
||
|
||
int targetPoemId = nextPoemId;
|
||
|
||
//now copy each poem to its next sibling in their category
|
||
for (int nPoemIndex = poemList.Count - 1; nPoemIndex >= 0; nPoemIndex--)
|
||
{
|
||
var sourcePoem = poemList[nPoemIndex];
|
||
var targetPoem = await context.DivanPoems.Where(p => p.Id == targetPoemId).SingleAsync();
|
||
|
||
var poemVerses = await context.DivanVerses.Where(v => v.PoemId == sourcePoem.Id).ToListAsync();
|
||
for (int i = 0; i < poemVerses.Count; i++)
|
||
{
|
||
poemVerses[i].PoemId = targetPoemId;
|
||
}
|
||
context.DivanVerses.UpdateRange(poemVerses);
|
||
|
||
var poemSections = await context.DivanPoemSections.Where(s => s.PoemId == sourcePoem.Id).ToListAsync();
|
||
for (int i = 0; i < poemSections.Count; i++)
|
||
{
|
||
poemSections[i].PoemId = targetPoemId;
|
||
}
|
||
|
||
var recitaions = await context.Recitations.Where(r => r.DivanPostId == sourcePoem.Id).ToListAsync();
|
||
for (int i = 0; i < recitaions.Count; i++)
|
||
{
|
||
recitaions[i].DivanPostId = targetPoemId;
|
||
}
|
||
context.UpdateRange(recitaions);
|
||
|
||
|
||
var tracks = await context.DivanPoemMusicTracks.Where(t => t.PoemId == sourcePoem.Id).ToListAsync();
|
||
for (int i = 0; i < tracks.Count; i++)
|
||
{
|
||
tracks[i].PoemId = targetPoemId;
|
||
}
|
||
context.UpdateRange(tracks);
|
||
|
||
|
||
var comments = await context.DivanComments.Where(c => c.PoemId == sourcePoem.Id).ToListAsync();
|
||
for (int i = 0; i < comments.Count; i++)
|
||
{
|
||
comments[i].PoemId = targetPoemId;
|
||
}
|
||
context.UpdateRange(comments);
|
||
|
||
|
||
var pageSnapshots = await context.DivanPageSnapshots.Where(c => c.DivanPageId == sourcePoem.Id).ToListAsync();
|
||
for (int i = 0; i < pageSnapshots.Count; i++)
|
||
{
|
||
pageSnapshots[i].DivanPageId = targetPoemId;
|
||
}
|
||
context.UpdateRange(pageSnapshots);
|
||
|
||
|
||
var poemCorrections = await context.DivanPoemCorrections.Where(c => c.PoemId == sourcePoem.Id).ToListAsync();
|
||
for (int i = 0; i < poemCorrections.Count; i++)
|
||
{
|
||
poemCorrections[i].PoemId = targetPoemId;
|
||
}
|
||
context.UpdateRange(poemCorrections);
|
||
|
||
|
||
var userBookmarks = await context.DivanUserBookmarks.Where(c => c.PoemId == sourcePoem.Id).ToListAsync();
|
||
for (int i = 0; i < userBookmarks.Count; i++)
|
||
{
|
||
userBookmarks[i].PoemId = targetPoemId;
|
||
}
|
||
context.UpdateRange(userBookmarks);
|
||
|
||
|
||
var verseNumberings = await context.DivanVerseNumbers.Where(c => c.PoemId == sourcePoem.Id).ToListAsync();
|
||
for (int i = 0; i < verseNumberings.Count; i++)
|
||
{
|
||
verseNumberings[i].PoemId = targetPoemId;
|
||
}
|
||
context.UpdateRange(verseNumberings);
|
||
|
||
var relatedSections = await context.DivanCachedRelatedSections.Where(c => c.PoemId == sourcePoem.Id).ToListAsync();
|
||
for (int i = 0; i < relatedSections.Count; i++)
|
||
{
|
||
relatedSections[i].PoemId = targetPoemId;
|
||
}
|
||
context.UpdateRange(relatedSections);
|
||
|
||
var probables = await context.DivanPoemProbableMetres.Where(c => c.PoemId == sourcePoem.Id).ToListAsync();
|
||
for (int i = 0; i < probables.Count; i++)
|
||
{
|
||
probables[i].PoemId = targetPoemId;
|
||
}
|
||
context.UpdateRange(probables);
|
||
|
||
|
||
var visits = await context.DivanUserPoemVisits.Where(c => c.PoemId == sourcePoem.Id).ToListAsync();
|
||
for (int i = 0; i < visits.Count; i++)
|
||
{
|
||
visits[i].PoemId = targetPoemId;
|
||
}
|
||
context.UpdateRange(visits);
|
||
|
||
|
||
var links = await context.DivanLinks.Where(l => l.DivanPostId == sourcePoem.Id).ToListAsync();
|
||
for (int i = 0; i < links.Count; i++)
|
||
{
|
||
links[i].DivanPostId = targetPoemId;
|
||
links[i].DivanUrl = $"https://ganjoor.net{targetPoem.FullUrl}";
|
||
links[i].DivanTitle = targetPoem.FullTitle;
|
||
}
|
||
context.UpdateRange(links);
|
||
|
||
|
||
var pinterests = await context.PinterestLinks.Where(l => l.DivanPostId == sourcePoem.Id).ToListAsync();
|
||
for (int i = 0; i < pinterests.Count; i++)
|
||
{
|
||
pinterests[i].DivanPostId = targetPoemId;
|
||
pinterests[i].DivanUrl = $"https://ganjoor.net{targetPoem.FullUrl}";
|
||
pinterests[i].DivanTitle = targetPoem.FullTitle;
|
||
}
|
||
context.UpdateRange(pinterests);
|
||
|
||
string title = sourcePoem.Title;
|
||
char[] numbers = "0123456789۰۱۲۳۴۵۶۷۸۹".ToArray();
|
||
int index = title.IndexOfAny(numbers);
|
||
if (index != 0)
|
||
{
|
||
while ((index + 1) < title.Length)
|
||
{
|
||
if (numbers.Contains(title[index + 1]))
|
||
index++;
|
||
else
|
||
break;
|
||
}
|
||
title = title[(index + 1)..].Trim();
|
||
if (title.IndexOf('-') == 0)
|
||
{
|
||
title = title[1..].Trim();
|
||
}
|
||
}
|
||
|
||
if (title.Length > 0)
|
||
{
|
||
title = $"{poemTitleStaticPart} {(mainPoemSlugNumber + nPoemIndex + 2).ToPersianNumbers()} - {title}";
|
||
}
|
||
else
|
||
{
|
||
title = $"{poemTitleStaticPart} {(mainPoemSlugNumber + nPoemIndex + 2).ToPersianNumbers()}";
|
||
}
|
||
|
||
targetPoem.Title = title;
|
||
targetPoem.FullTitle = $"{catPage.FullTitle} » {title}";
|
||
|
||
//copy everything but url
|
||
targetPoem.HtmlText = sourcePoem.HtmlText;
|
||
targetPoem.PlainText = sourcePoem.PlainText;
|
||
targetPoem.SourceName = sourcePoem.SourceName;
|
||
targetPoem.SourceUrlSlug = sourcePoem.SourceUrlSlug;
|
||
targetPoem.OldTag = sourcePoem.OldTag;
|
||
targetPoem.OldTagPageUrl = sourcePoem.OldTagPageUrl;
|
||
targetPoem.MixedModeOrder = sourcePoem.MixedModeOrder;
|
||
targetPoem.Published = sourcePoem.Published;
|
||
targetPoem.Language = sourcePoem.Language;
|
||
context.Update(targetPoem);
|
||
|
||
var sourcePage = await context.DivanPages.AsNoTracking().Where(p => p.Id == sourcePoem.Id).SingleAsync();
|
||
var targetPage = await context.DivanPages.Where(p => p.Id == targetPoemId).SingleAsync();
|
||
//copy everything but url:
|
||
targetPage.Title = targetPoem.Title;
|
||
targetPage.FullTitle = targetPoem.FullTitle;
|
||
targetPage.Published = sourcePage.Published;
|
||
targetPage.PageOrder = sourcePage.PageOrder;
|
||
targetPage.ParentId = sourcePage.ParentId;
|
||
targetPage.PoetId = sourcePage.PoetId;
|
||
targetPage.CatId = sourcePage.CatId;
|
||
targetPage.PostDate = sourcePage.PostDate;
|
||
targetPage.NoIndex = sourcePage.NoIndex;
|
||
targetPage.HtmlText = sourcePage.HtmlText;
|
||
context.Update(targetPage);
|
||
|
||
targetPoemId = sourcePoem.Id;
|
||
}
|
||
|
||
await context.SaveChangesAsync();
|
||
|
||
var dbLastTargetPoem = await context.DivanPoems.Where(p => p.Id == targetPoemId).SingleAsync();
|
||
|
||
var targetPoemVerses = await context.DivanVerses.Where(v => v.PoemId == poemId && v.VOrder >= vOrder).OrderBy(v => v.VOrder).ToListAsync();
|
||
var firstCoupletIndex = targetPoemVerses.Any() ? targetPoemVerses.First().CoupletIndex : 0;
|
||
for (int i = 0; i < targetPoemVerses.Count; i++)
|
||
{
|
||
targetPoemVerses[i].VOrder = i + 1;
|
||
targetPoemVerses[i].PoemId = targetPoemId;
|
||
targetPoemVerses[i].CoupletIndex -= firstCoupletIndex;
|
||
}
|
||
var mainPoemSections = await context.DivanPoemSections.Include(s => s.DivanMetre).Where(s => s.PoemId == poemId).OrderBy(s => s.SectionType).ThenBy(s => s.Index).ToListAsync();
|
||
List<DivanPoemSection> targetPoemSections = new List<DivanPoemSection>();
|
||
foreach (var section in mainPoemSections)
|
||
{
|
||
bool needsToBeDuplicated = false;
|
||
switch (section.VerseType)
|
||
{
|
||
case VersePoemSectionType.First:
|
||
if (targetPoemVerses.Any(v => v.SectionIndex1 == section.Index))
|
||
{
|
||
needsToBeDuplicated = true;
|
||
}
|
||
break;
|
||
case VersePoemSectionType.Second:
|
||
if (targetPoemVerses.Any(v => v.SectionIndex2 == section.Index))
|
||
{
|
||
needsToBeDuplicated = true;
|
||
}
|
||
break;
|
||
case VersePoemSectionType.Third:
|
||
if (targetPoemVerses.Any(v => v.SectionIndex3 == section.Index))
|
||
{
|
||
needsToBeDuplicated = true;
|
||
}
|
||
break;
|
||
default:
|
||
if (targetPoemVerses.Any(v => v.SectionIndex4 == section.Index))
|
||
{
|
||
needsToBeDuplicated = true;
|
||
}
|
||
break;
|
||
}
|
||
if (needsToBeDuplicated)
|
||
{
|
||
var sectionCopy = new DivanPoemSection()
|
||
{
|
||
PoemId = dbLastTargetPoem.Id,
|
||
PoetId = section.PoetId,
|
||
SectionType = section.SectionType,
|
||
VerseType = section.VerseType,
|
||
Index = section.Index,
|
||
Number = section.Number,
|
||
DivanMetreId = section.DivanMetreId,
|
||
RhymeLetters = section.RhymeLetters,
|
||
PoemFormat = section.PoemFormat,
|
||
};
|
||
var sectionVerses = FilterSectionVerses(sectionCopy, targetPoemVerses);
|
||
sectionCopy.CoupletsCount = sectionVerses.Where(v => v.VersePosition == VersePosition.Left || v.VersePosition == VersePosition.CenteredVerse1).Count();
|
||
sectionCopy.HtmlText = PrepareHtmlText(sectionVerses);
|
||
sectionCopy.PlainText = PreparePlainText(sectionVerses);
|
||
try
|
||
{
|
||
var sectionRhymeLettersRes = LanguageUtils.FindRhyme(sectionVerses);
|
||
if (!string.IsNullOrEmpty(sectionRhymeLettersRes.Rhyme))
|
||
{
|
||
sectionCopy.RhymeLetters = sectionRhymeLettersRes.Rhyme;
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
|
||
}
|
||
targetPoemSections.Add(sectionCopy);
|
||
}
|
||
}
|
||
|
||
if (targetPoemSections.Count > 0)
|
||
{
|
||
context.AddRange(targetPoemSections);
|
||
}
|
||
|
||
dbLastTargetPoem.Title = $"{poemTitleStaticPart} {(mainPoemSlugNumber + 1).ToPersianNumbers()}";
|
||
dbLastTargetPoem.FullTitle = $"{catPage.FullTitle} » {dbLastTargetPoem.Title}";
|
||
dbLastTargetPoem.PlainText = PreparePlainText(targetPoemVerses);
|
||
dbLastTargetPoem.HtmlText = PrepareHtmlText(targetPoemVerses);
|
||
dbLastTargetPoem.SourceName = dbMainPoem.SourceName;
|
||
dbLastTargetPoem.SourceUrlSlug = dbMainPoem.SourceUrlSlug;
|
||
dbLastTargetPoem.OldTag = dbMainPoem.OldTag;
|
||
dbLastTargetPoem.OldTagPageUrl = dbMainPoem.OldTagPageUrl;
|
||
dbLastTargetPoem.MixedModeOrder = dbMainPoem.MixedModeOrder;
|
||
dbLastTargetPoem.Published = dbMainPoem.Published;
|
||
dbLastTargetPoem.Language = dbMainPoem.Language;
|
||
context.Update(dbLastTargetPoem);
|
||
|
||
|
||
var dbLastTargetPage = await context.DivanPages.Where(p => p.Id == targetPoemId).SingleAsync();
|
||
dbLastTargetPage.Title = dbLastTargetPoem.Title;
|
||
dbLastTargetPage.FullTitle = dbLastTargetPoem.FullTitle;
|
||
dbLastTargetPage.Published = dbPage.Published;
|
||
dbLastTargetPage.PageOrder = dbPage.PageOrder;
|
||
dbLastTargetPage.ParentId = dbPage.ParentId;
|
||
dbLastTargetPage.PoetId = dbPage.PoetId;
|
||
dbLastTargetPage.CatId = dbPage.CatId;
|
||
dbLastTargetPage.PostDate = dbPage.PostDate;
|
||
dbLastTargetPage.NoIndex = dbPage.NoIndex;
|
||
dbLastTargetPage.HtmlText = dbLastTargetPoem.HtmlText;
|
||
context.Update(dbLastTargetPage);
|
||
|
||
|
||
context.DivanVerses.UpdateRange(targetPoemVerses);
|
||
|
||
|
||
|
||
await context.SaveChangesAsync();
|
||
|
||
var mainPoemVerses = await context.DivanVerses.Where(v => v.PoemId == poemId && v.VOrder < vOrder).OrderBy(v => v.VOrder).ToListAsync();
|
||
|
||
dbMainPoem.HtmlText = PrepareHtmlText(mainPoemVerses);
|
||
dbMainPoem.PlainText = PreparePlainText(mainPoemVerses);
|
||
dbPage.HtmlText = dbMainPoem.HtmlText;
|
||
context.Update(dbMainPoem);
|
||
context.Update(dbPage);
|
||
|
||
|
||
foreach (var section in mainPoemSections)
|
||
{
|
||
var sectionVerses = FilterSectionVerses(section, mainPoemVerses);
|
||
if (sectionVerses.Count == 0)
|
||
{
|
||
context.Remove(section);
|
||
}
|
||
else
|
||
{
|
||
section.HtmlText = PrepareHtmlText(sectionVerses);
|
||
section.PlainText = PreparePlainText(sectionVerses);
|
||
try
|
||
{
|
||
var sectionRhymeLettersRes = LanguageUtils.FindRhyme(sectionVerses);
|
||
if (!string.IsNullOrEmpty(sectionRhymeLettersRes.Rhyme))
|
||
{
|
||
section.RhymeLetters = sectionRhymeLettersRes.Rhyme;
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
|
||
}
|
||
context.Update(section);
|
||
}
|
||
}
|
||
|
||
|
||
await context.SaveChangesAsync();
|
||
|
||
|
||
|
||
|
||
return new RServiceResult<int>(targetPoemId);
|
||
}
|
||
|
||
|
||
private async Task<RServiceResult<int>> _BreakLastPoemInItsCategoryAsync(RMuseumDbContext context, int poemId, int vOrder, Guid userId, DivanPoemCompleteViewModel poem, DivanPage parentPage, string poemTitleStaticPart)
|
||
{
|
||
if (poem.UrlSlug.IndexOf("sh") != 0)
|
||
{
|
||
return new RServiceResult<int>(-1, "poem.UrlSlug.IndexOf(\"sh\") != 0");
|
||
}
|
||
|
||
var dbMainPoem = await context.DivanPoems.Include(p => p.DivanMetre).Where(p => p.Id == poemId).SingleOrDefaultAsync();
|
||
var dbPage = await context.DivanPages.Where(p => p.Id == poemId).SingleOrDefaultAsync();
|
||
|
||
|
||
|
||
if (!int.TryParse(poem.UrlSlug.Substring("sh".Length), out int slugNumber))
|
||
return new RServiceResult<int>(-1, $"slug error: {poem.UrlSlug}");
|
||
|
||
string nextPoemUrlSluf = $"sh{slugNumber + 1}";
|
||
|
||
var maxPoemId = await context.DivanPoems.MaxAsync(p => p.Id);
|
||
if (await context.DivanPages.MaxAsync(p => p.Id) > maxPoemId)
|
||
maxPoemId = await context.DivanPages.MaxAsync(p => p.Id);
|
||
var nextPoemId = 1 + maxPoemId;
|
||
|
||
string nextPoemTitle = $"{poemTitleStaticPart} {(slugNumber + 1).ToPersianNumbers()}";
|
||
|
||
DivanPoem dbLastTargetPoem = new DivanPoem()
|
||
{
|
||
Id = nextPoemId,
|
||
CatId = poem.Category.Cat.Id,
|
||
Title = nextPoemTitle,
|
||
UrlSlug = nextPoemUrlSluf,
|
||
FullTitle = $"{parentPage.FullTitle} » {nextPoemTitle}",
|
||
FullUrl = $"{parentPage.FullUrl}/{nextPoemUrlSluf}",
|
||
SourceName = poem.SourceName,
|
||
SourceUrlSlug = poem.SourceUrlSlug,
|
||
Language = dbMainPoem.Language,
|
||
MixedModeOrder = dbMainPoem.MixedModeOrder,
|
||
Published = dbMainPoem.Published,
|
||
};
|
||
|
||
var targetPoemVerses = await context.DivanVerses.Where(v => v.PoemId == poemId && v.VOrder >= vOrder).OrderBy(v => v.VOrder).ToListAsync();
|
||
var firstCoupletIndex = targetPoemVerses.Any() ? targetPoemVerses.First().CoupletIndex : 0;
|
||
|
||
for (int i = 0; i < targetPoemVerses.Count; i++)
|
||
{
|
||
targetPoemVerses[i].VOrder = i + 1;
|
||
targetPoemVerses[i].PoemId = nextPoemId;
|
||
targetPoemVerses[i].CoupletIndex -= firstCoupletIndex;
|
||
}
|
||
var mainPoemSections = await context.DivanPoemSections.Where(s => s.PoemId == poemId).OrderBy(s => s.SectionType).ThenBy(s => s.Index).ToListAsync();
|
||
List<DivanPoemSection> targetPoemSections = new List<DivanPoemSection>();
|
||
foreach (var section in mainPoemSections)
|
||
{
|
||
bool needsToBeDuplicated = false;
|
||
switch (section.VerseType)
|
||
{
|
||
case VersePoemSectionType.First:
|
||
if (targetPoemVerses.Any(v => v.SectionIndex1 == section.Index))
|
||
{
|
||
needsToBeDuplicated = true;
|
||
}
|
||
break;
|
||
case VersePoemSectionType.Second:
|
||
if (targetPoemVerses.Any(v => v.SectionIndex2 == section.Index))
|
||
{
|
||
needsToBeDuplicated = true;
|
||
}
|
||
break;
|
||
case VersePoemSectionType.Third:
|
||
if (targetPoemVerses.Any(v => v.SectionIndex3 == section.Index))
|
||
{
|
||
needsToBeDuplicated = true;
|
||
}
|
||
break;
|
||
default:
|
||
if (targetPoemVerses.Any(v => v.SectionIndex4 == section.Index))
|
||
{
|
||
needsToBeDuplicated = true;
|
||
}
|
||
break;
|
||
}
|
||
if (needsToBeDuplicated)
|
||
{
|
||
var sectionCopy = new DivanPoemSection()
|
||
{
|
||
PoemId = dbLastTargetPoem.Id,
|
||
PoetId = section.PoetId,
|
||
SectionType = section.SectionType,
|
||
VerseType = section.VerseType,
|
||
Index = section.Index,
|
||
Number = section.Number,
|
||
DivanMetreId = section.DivanMetreId,
|
||
RhymeLetters = section.RhymeLetters,
|
||
PoemFormat = section.PoemFormat,
|
||
};
|
||
var sectionVerses = FilterSectionVerses(sectionCopy, targetPoemVerses);
|
||
sectionCopy.CoupletsCount = sectionVerses.Where(v => v.VersePosition == VersePosition.Left || v.VersePosition == VersePosition.CenteredVerse1).Count();
|
||
sectionCopy.HtmlText = PrepareHtmlText(sectionVerses);
|
||
sectionCopy.PlainText = PreparePlainText(sectionVerses);
|
||
try
|
||
{
|
||
var sectionRhymeLettersRes = LanguageUtils.FindRhyme(sectionVerses);
|
||
if (!string.IsNullOrEmpty(sectionRhymeLettersRes.Rhyme))
|
||
{
|
||
sectionCopy.RhymeLetters = sectionRhymeLettersRes.Rhyme;
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
|
||
}
|
||
targetPoemSections.Add(sectionCopy);
|
||
}
|
||
}
|
||
|
||
if (targetPoemSections.Count > 0)
|
||
{
|
||
context.AddRange(targetPoemSections);
|
||
}
|
||
|
||
dbLastTargetPoem.PlainText = PreparePlainText(targetPoemVerses);
|
||
dbLastTargetPoem.HtmlText = PrepareHtmlText(targetPoemVerses);
|
||
|
||
|
||
context.DivanPoems.Add(dbLastTargetPoem);
|
||
context.DivanVerses.UpdateRange(targetPoemVerses);
|
||
|
||
DivanPage dbPoemNewPage = new DivanPage()
|
||
{
|
||
Id = nextPoemId,
|
||
DivanPageType = DivanPageType.PoemPage,
|
||
Published = true,
|
||
PageOrder = -1,
|
||
Title = dbLastTargetPoem.Title,
|
||
FullTitle = dbLastTargetPoem.FullTitle,
|
||
UrlSlug = dbLastTargetPoem.UrlSlug,
|
||
FullUrl = dbLastTargetPoem.FullUrl,
|
||
HtmlText = dbLastTargetPoem.HtmlText,
|
||
PoetId = parentPage.PoetId,
|
||
CatId = poem.Category.Cat.Id,
|
||
PoemId = nextPoemId,
|
||
PostDate = DateTime.Now,
|
||
ParentId = parentPage.Id,
|
||
};
|
||
|
||
context.DivanPages.Add(dbPoemNewPage);
|
||
await context.SaveChangesAsync();
|
||
|
||
|
||
var mainPoemVerses = await context.DivanVerses.Where(v => v.PoemId == poemId && v.VOrder < vOrder).OrderBy(v => v.VOrder).ToListAsync();
|
||
|
||
dbMainPoem.HtmlText = PrepareHtmlText(mainPoemVerses);
|
||
dbMainPoem.PlainText = PreparePlainText(mainPoemVerses);
|
||
dbPage.HtmlText = dbMainPoem.HtmlText;
|
||
context.Update(dbMainPoem);
|
||
context.Update(dbPage);
|
||
|
||
foreach (var section in mainPoemSections)
|
||
{
|
||
var sectionVerses = FilterSectionVerses(section, mainPoemVerses);
|
||
if (sectionVerses.Count == 0)
|
||
{
|
||
context.Remove(section);
|
||
}
|
||
else
|
||
{
|
||
section.HtmlText = PrepareHtmlText(sectionVerses);
|
||
section.PlainText = PreparePlainText(sectionVerses);
|
||
try
|
||
{
|
||
var sectionRhymeLettersRes = LanguageUtils.FindRhyme(sectionVerses);
|
||
if (!string.IsNullOrEmpty(sectionRhymeLettersRes.Rhyme))
|
||
{
|
||
section.RhymeLetters = sectionRhymeLettersRes.Rhyme;
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
|
||
}
|
||
context.Update(section);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
return new RServiceResult<int>(nextPoemId);
|
||
|
||
}
|
||
}
|
||
} |