using FictionArchive.Service.NovelService.Models.Enums; using FictionArchive.Service.NovelService.Models.Localization; using FictionArchive.Service.NovelService.Models.Novels; using FictionArchive.Service.NovelService.Models.SourceAdapters; using FictionArchive.Service.NovelService.Services.SourceAdapters; using Microsoft.EntityFrameworkCore; namespace FictionArchive.Service.NovelService.Services; public class NovelUpdateService { private readonly NovelServiceDbContext _dbContext; private readonly ILogger _logger; private readonly IEnumerable _sourceAdapters; public NovelUpdateService(NovelServiceDbContext dbContext, ILogger logger, IEnumerable sourceAdapters) { _dbContext = dbContext; _logger = logger; _sourceAdapters = sourceAdapters; } public async Task ImportNovel(string novelUrl) { NovelMetadata? metadata = null; foreach (ISourceAdapter sourceAdapter in _sourceAdapters) { if (await sourceAdapter.CanProcessNovel(novelUrl)) { metadata = await sourceAdapter.GetMetadata(novelUrl); } } if (metadata == null) { throw new NotSupportedException("The provided novel url is currently unsupported."); } var systemTags = metadata.SystemTags.Select(tag => new NovelTag() { Key = tag, DisplayName = LocalizationKey.CreateFromText(tag, metadata.RawLanguage), TagType = TagType.System }); var sourceTags = metadata.SourceTags.Select(tag => new NovelTag() { Key = tag, DisplayName = LocalizationKey.CreateFromText(tag, metadata.RawLanguage), TagType = TagType.External }); var addedNovel = _dbContext.Novels.Add(new Novel() { Author = new Person() { Name = LocalizationKey.CreateFromText(metadata.AuthorName, metadata.RawLanguage), ExternalUrl = metadata.AuthorUrl, }, RawLanguage = metadata.RawLanguage, Url = metadata.Url, ExternalId = metadata.ExternalId, Chapters = metadata.Chapters.Select(chapter => { return new Chapter() { Order = chapter.Order, Url = chapter.Url, Revision = chapter.Revision, Name = LocalizationKey.CreateFromText(chapter.Name, metadata.RawLanguage), Body = new LocalizationKey() { Texts = new List() } }; }).ToList(), Description = LocalizationKey.CreateFromText(metadata.Description, metadata.RawLanguage), Name = LocalizationKey.CreateFromText(metadata.Name, metadata.RawLanguage), RawStatus = metadata.RawStatus, Tags = sourceTags.Concat(systemTags).ToList(), Source = new Source() { Name = metadata.SourceDescriptor.Name, Url = metadata.SourceDescriptor.Url, Key = metadata.SourceDescriptor.Key, } }); await _dbContext.SaveChangesAsync(); return addedNovel.Entity; } public async Task PullChapterContents(uint novelId, uint chapterNumber) { var novel = await _dbContext.Novels.Where(novel => novel.Id == novelId) .Include(novel => novel.Chapters) .ThenInclude(chapter => chapter.Body) .ThenInclude(body => body.Texts) .Include(novel => novel.Source) .FirstOrDefaultAsync(); var chapter = novel.Chapters.Where(chapter => chapter.Order == chapterNumber).FirstOrDefault(); var adapter = _sourceAdapters.FirstOrDefault(adapter => adapter.SourceDescriptor.Key == novel.Source.Key); var rawChapter = await adapter.GetRawChapter(chapter.Url); chapter.Body.Texts.Add(new LocalizationText() { Text = rawChapter, Language = novel.RawLanguage }); await _dbContext.SaveChangesAsync(); return chapter; } }