#399 StartImportingLocalPDF

This commit is contained in:
Hamid Reza Mohammadi 2023-07-22 10:30:41 +03:30
parent 312a3f2da8
commit 208efea5ec
5 changed files with 294 additions and 234 deletions

View File

@ -166,7 +166,7 @@ namespace RMuseum.Models.PDFLibrary
public string OriginalFileUrl { get; set; }
/// <summary>
/// specific authors for this edition AKA. translators
/// contributers
/// </summary>
public ICollection<AuthorRole> Contributers { get; set; }

View File

@ -11927,7 +11927,7 @@
</member>
<member name="P:RMuseum.Models.PDFLibrary.PDFBook.Contributers">
<summary>
specific authors for this edition AKA. translators
contributers
</summary>
</member>
<member name="P:RMuseum.Models.PDFLibrary.PDFBook.Pages">
@ -17395,6 +17395,13 @@
طول تصویر بندانگشتی
</summary>
</member>
<member name="M:RMuseum.Services.Implementation.PDFLibraryService.StartImportingLocalPDF(RMuseum.Models.PDFLibrary.ViewModels.NewPDFBookViewModel)">
<summary>
start importing local pdf file
</summary>
<param name="model"></param>
<returns></returns>
</member>
<member name="F:RMuseum.Services.Implementation.PDFLibraryService._context">
<summary>
Database Context
@ -18198,6 +18205,13 @@
PDF Library Services
</summary>
</member>
<member name="M:RMuseum.Services.IPDFLibraryService.StartImportingLocalPDF(RMuseum.Models.PDFLibrary.ViewModels.NewPDFBookViewModel)">
<summary>
start importing local pdf file
</summary>
<param name="model"></param>
<returns></returns>
</member>
<member name="T:RMuseum.Services.IPictureFileService">
<summary>
manipulating picture files

View File

@ -1,9 +1,18 @@
namespace RMuseum.Services
using RMuseum.Models.PDFLibrary.ViewModels;
using RSecurityBackend.Models.Generic;
namespace RMuseum.Services
{
/// <summary>
/// PDF Library Services
/// </summary>
public interface IPDFLibraryService
{
/// <summary>
/// start importing local pdf file
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
RServiceResult<bool> StartImportingLocalPDF(NewPDFBookViewModel model);
}
}

View File

@ -16,223 +16,165 @@ using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace RMuseum.Services.Implementation
{
public partial class PDFLibraryService
{
private async Task<RServiceResult<bool>> StartImportingLocalPDFFile(int bookId, int? volumeId, int volumeOrder, string filePath, string srcUrl, bool skipUpload)
private async Task<RServiceResult<PDFBook>> ImportLocalPDFFile(RMuseumDbContext context, int bookId, int? volumeId, int volumeOrder, string filePath, string srcUrl, bool skipUpload)
{
try
string fileChecksum = PoemAudio.ComputeCheckSum(filePath);
if (
(
await context.ImportJobs
.Where(j => j.JobType == JobType.Pdf && j.SrcContent == fileChecksum && !(j.Status == ImportJobStatus.Failed || j.Status == ImportJobStatus.Aborted))
.SingleOrDefaultAsync()
)
!=
null
)
{
return new RServiceResult<PDFBook>(null, $"Job is already scheduled or running for importing pdf file {filePath} (duplicated checksum: {fileChecksum})");
}
if (!string.IsNullOrEmpty(srcUrl))
{
string fileChecksum = PoemAudio.ComputeCheckSum(filePath);
if (
(
await _context.ImportJobs
.Where(j => j.JobType == JobType.Pdf && j.SrcContent == fileChecksum && !(j.Status == ImportJobStatus.Failed || j.Status == ImportJobStatus.Aborted))
.SingleOrDefaultAsync()
)
(await context.PDFBooks.Where(a => a.OriginalSourceUrl == srcUrl).SingleOrDefaultAsync())
!=
null
)
{
return new RServiceResult<bool>(false, $"Job is already scheduled or running for importing pdf file {filePath} (duplicated checksum: {fileChecksum})");
return new RServiceResult<PDFBook>(null, $"duplicated srcUrl '{srcUrl}'");
}
if (!string.IsNullOrEmpty(srcUrl))
}
if (
(await context.PDFBooks.Where(a => a.FileMD5CheckSum == fileChecksum).SingleOrDefaultAsync())
!=
null
)
{
return new RServiceResult<PDFBook>(null, $"duplicated pdf with checksum '{fileChecksum}'");
}
ImportJob job = new ImportJob()
{
JobType = JobType.Pdf,
SrcContent = fileChecksum,
ResourceNumber = filePath,
FriendlyUrl = "",
SrcUrl = srcUrl,
QueueTime = DateTime.Now,
ProgressPercent = 0,
Status = ImportJobStatus.NotStarted
};
await context.ImportJobs.AddAsync
(
job
);
await context.SaveChangesAsync();
try
{
var folderNumber = await context.PDFBooks.CountAsync();
while (Directory.Exists(Path.Combine(_imageFileService.ImageStoragePath, $"pdfbook-{folderNumber}")))
{
if (
(await _context.PDFBooks.Where(a => a.OriginalSourceUrl == srcUrl).SingleOrDefaultAsync())
!=
null
)
{
return new RServiceResult<bool>(false, $"duplicated srcUrl '{srcUrl}'");
}
folderNumber++;
}
if (
(await _context.PDFBooks.Where(a => a.FileMD5CheckSum == fileChecksum).SingleOrDefaultAsync())
!=
null
)
Directory.CreateDirectory(Path.Combine(_imageFileService.ImageStoragePath, $"pdfbook-{folderNumber}"));
PDFBook pdfBook = new PDFBook()
{
return new RServiceResult<bool>(false, $"duplicated pdf with checksum '{fileChecksum}'");
}
ImportJob job = new ImportJob()
{
JobType = JobType.Pdf,
SrcContent = fileChecksum,
ResourceNumber = filePath,
FriendlyUrl = "",
SrcUrl = srcUrl,
QueueTime = DateTime.Now,
ProgressPercent = 0,
Status = ImportJobStatus.NotStarted
Status = PublishStatus.Draft,
DateTime = DateTime.Now,
LastModified = DateTime.Now,
FileMD5CheckSum = fileChecksum,
OriginalSourceUrl = srcUrl,
OriginalFileName = Path.GetFileName(filePath),
StorageFolderName = $"pdfbook-{folderNumber}",
BookId = bookId,
VolumeOrder = volumeOrder,
MultiVolumePDFCollectionId = volumeId,
};
await _context.ImportJobs.AddAsync
(
job
);
await _context.SaveChangesAsync();
_backgroundTaskQueue.QueueBackgroundWorkItem
(
async token =>
{
try
{
using (RMuseumDbContext context = new RMuseumDbContext(new DbContextOptions<RMuseumDbContext>()))
{
var folderNumber = await context.PDFBooks.CountAsync();
while (Directory.Exists(Path.Combine(_imageFileService.ImageStoragePath, $"pdfbook-{folderNumber}")))
{
folderNumber++;
}
Directory.CreateDirectory(Path.Combine(_imageFileService.ImageStoragePath, $"pdfbook-{folderNumber}"));
PDFBook pdfBook = new PDFBook()
{
Status = PublishStatus.Draft,
DateTime = DateTime.Now,
LastModified = DateTime.Now,
FileMD5CheckSum = fileChecksum,
OriginalSourceUrl = srcUrl,
OriginalFileName = Path.GetFileName(filePath),
StorageFolderName = $"pdfbook-{folderNumber}",
BookId = bookId,
VolumeOrder = volumeOrder,
MultiVolumePDFCollectionId = volumeId,
};
job.FriendlyUrl = pdfBook.StorageFolderName;
List<RTagValue> meta = new List<RTagValue>();
using (RMuseumDbContext importJobUpdaterDb = new RMuseumDbContext(new DbContextOptions<RMuseumDbContext>()))
{
job.StartTime = DateTime.Now;
job.Status = ImportJobStatus.Running;
job.SrcContent = "";
importJobUpdaterDb.Update(job);
await importJobUpdaterDb.SaveChangesAsync();
}
List<PDFPage> pages = await _ImportAndReturnPDFJobImages(pdfBook, job, 0);
pdfBook.Tags = meta.ToArray();
pdfBook.Pages = pages.ToArray();
pdfBook.PageCount = pages.Count;
if (pages.Count == 0)
{
job.EndTime = DateTime.Now;
job.Status = ImportJobStatus.Failed;
job.Exception = "Pages.Count == 0";
context.Update(job);
await context.SaveChangesAsync();
return;
}
string pdfFilePath = Path.Combine(Path.Combine(_imageFileService.ImageStoragePath, pdfBook.StorageFolderName), pdfBook.OriginalFileName);
using (FileStream fs = new FileStream(pdfFilePath, FileMode.Open))
{
var pdfStorageResult = await _imageFileService.Add(null, fs, pdfBook.OriginalFileName, pdfBook.StorageFolderName, false);
if (!string.IsNullOrEmpty(pdfStorageResult.ExceptionString))
{
job.EndTime = DateTime.Now;
job.Status = ImportJobStatus.Failed;
job.Exception = $"pdfStorageResult.ExceptionString: {pdfStorageResult.ExceptionString}";
job.EndTime = DateTime.Now;
context.Update(job);
await context.SaveChangesAsync();
return;
}
pdfStorageResult.Result.ContentType = "application/pdf";
pdfBook.PDFFile = pdfStorageResult.Result;
}
await context.PDFBooks.AddAsync(pdfBook);
await context.SaveChangesAsync();
var book = await context.Books.Where(b => b.Id == bookId).SingleAsync();
if(book.CoverImageId == null)
{
book.CoverImage = pdfBook.CoverImage.DuplicateExcludingId(pdfBook.CoverImage);
context.Update(book);
await context.SaveChangesAsync();
}
var resFTPUpload = await _UploadPDFBookToExternalServer(pdfBook, context, skipUpload);
if (!string.IsNullOrEmpty(resFTPUpload.ExceptionString))
{
job.EndTime = DateTime.Now;
job.Status = ImportJobStatus.Failed;
job.Exception = $"UploadArtifactToExternalServer: {resFTPUpload.ExceptionString}";
job.EndTime = DateTime.Now;
context.Update(job);
await context.SaveChangesAsync();
return;
}
job.ProgressPercent = 100;
job.Status = ImportJobStatus.Succeeded;
job.EndTime = DateTime.Now;
context.Update(job);
await context.SaveChangesAsync();
}
}
catch (Exception exp)
{
using (RMuseumDbContext importJobUpdaterDb = new RMuseumDbContext(new DbContextOptions<RMuseumDbContext>()))
{
job.EndTime = DateTime.Now;
job.Status = ImportJobStatus.Failed;
job.Exception = exp.ToString();
importJobUpdaterDb.Update(job);
await importJobUpdaterDb.SaveChangesAsync();
}
}
}
);
return new RServiceResult<bool>(true);
job.FriendlyUrl = pdfBook.StorageFolderName;
List<RTagValue> meta = new List<RTagValue>();
using (RMuseumDbContext importJobUpdaterDb = new RMuseumDbContext(new DbContextOptions<RMuseumDbContext>()))
{
job.StartTime = DateTime.Now;
job.Status = ImportJobStatus.Running;
job.SrcContent = "";
importJobUpdaterDb.Update(job);
await importJobUpdaterDb.SaveChangesAsync();
}
List<PDFPage> pages = await _ImportAndReturnPDFJobImages(pdfBook, job, 0);
pdfBook.Tags = meta.ToArray();
pdfBook.Pages = pages.ToArray();
pdfBook.PageCount = pages.Count;
if (pages.Count == 0)
{
job.EndTime = DateTime.Now;
job.Status = ImportJobStatus.Failed;
job.Exception = "Pages.Count == 0";
context.Update(job);
await context.SaveChangesAsync();
return new RServiceResult<PDFBook>(null, job.Exception);
}
string pdfFilePath = Path.Combine(Path.Combine(_imageFileService.ImageStoragePath, pdfBook.StorageFolderName), pdfBook.OriginalFileName);
using (FileStream fs = new FileStream(pdfFilePath, FileMode.Open))
{
var pdfStorageResult = await _imageFileService.Add(null, fs, pdfBook.OriginalFileName, pdfBook.StorageFolderName, false);
if (!string.IsNullOrEmpty(pdfStorageResult.ExceptionString))
{
job.EndTime = DateTime.Now;
job.Status = ImportJobStatus.Failed;
job.Exception = $"pdfStorageResult.ExceptionString: {pdfStorageResult.ExceptionString}";
job.EndTime = DateTime.Now;
context.Update(job);
await context.SaveChangesAsync();
return new RServiceResult<PDFBook>(null, job.Exception);
}
pdfStorageResult.Result.ContentType = "application/pdf";
pdfBook.PDFFile = pdfStorageResult.Result;
}
await context.PDFBooks.AddAsync(pdfBook);
await context.SaveChangesAsync();
var book = await context.Books.Where(b => b.Id == bookId).SingleAsync();
if (book.CoverImageId == null)
{
book.CoverImage = pdfBook.CoverImage.DuplicateExcludingId(pdfBook.CoverImage);
context.Update(book);
await context.SaveChangesAsync();
}
var resFTPUpload = await _UploadPDFBookToExternalServer(pdfBook, context, skipUpload);
if (!string.IsNullOrEmpty(resFTPUpload.ExceptionString))
{
job.EndTime = DateTime.Now;
job.Status = ImportJobStatus.Failed;
job.Exception = $"UploadArtifactToExternalServer: {resFTPUpload.ExceptionString}";
job.EndTime = DateTime.Now;
context.Update(job);
await context.SaveChangesAsync();
return new RServiceResult<PDFBook>(null, job.Exception);
}
job.ProgressPercent = 100;
job.Status = ImportJobStatus.Succeeded;
job.EndTime = DateTime.Now;
context.Update(job);
await context.SaveChangesAsync();
return new RServiceResult<PDFBook>(pdfBook);
}
catch (Exception exp)
{
return new RServiceResult<bool>(false, exp.ToString());
job.EndTime = DateTime.Now;
job.Status = ImportJobStatus.Failed;
job.Exception = exp.ToString();
job.EndTime = DateTime.Now;
context.Update(job);
await context.SaveChangesAsync();
return new RServiceResult<PDFBook>(null, job.Exception);
}
}
private async Task<List<PDFPage>> _ImportAndReturnPDFJobImages(PDFBook pdfBook, ImportJob job, int order)
{
List<PDFPage> pages = new List<PDFPage>();
string pdfFilePath = job.ResourceNumber;
string intermediateFolder = Path.Combine(Path.GetDirectoryName(pdfFilePath), Path.GetFileNameWithoutExtension(pdfFilePath));
Directory.CreateDirectory(intermediateFolder);
List<string> fileNames = new List<string>();
int imageOrder = 1;
using (FileStream fs = File.OpenRead(pdfFilePath))
@ -249,7 +191,6 @@ namespace RMuseum.Services.Implementation
imageOrder++;
}
}
foreach (string fileName in fileNames)
{
using (RMuseumDbContext importJobUpdaterDb = new RMuseumDbContext(new DbContextOptions<RMuseumDbContext>()))
@ -258,9 +199,7 @@ namespace RMuseum.Services.Implementation
importJobUpdaterDb.Update(job);
await importJobUpdaterDb.SaveChangesAsync();
}
order++;
PDFPage page = new PDFPage()
{
PageNumber = order,
@ -268,30 +207,23 @@ namespace RMuseum.Services.Implementation
Tags = new RTagValue[] { },
LastModified = DateTime.Now
};
string thumbnailImageName = $"{page.PageNumber}".PadLeft(5, '0') + ".jpg";
string thumbnailPath = Path.Combine(Path.Combine(_imageFileService.ImageStoragePath, pdfBook.StorageFolderName), thumbnailImageName);
if (File.Exists(thumbnailPath))
{
File.Delete(thumbnailPath);
}
using (Image img = Image.FromFile(fileName))
{
int imageWidth = img.Width;
int imageHeight = img.Height;
int thumbnailImageWidth = ThumbnailImageWidth;
int thumbnailImageHeight = ThumbnailImageWidth * imageHeight / imageWidth;
if (thumbnailImageHeight > ThumbnailImageMaxHeight)
{
thumbnailImageHeight = ThumbnailImageMaxHeight;
thumbnailImageWidth = thumbnailImageHeight * imageWidth / imageHeight;
}
//روی خود img تأثیر می گذارد
// به احتمال قوی داریم روی تصویر resize کار می‌کنیم
Image thumbnail = new Bitmap(thumbnailImageWidth, thumbnailImageHeight);
@ -302,42 +234,32 @@ namespace RMuseum.Services.Implementation
using (MemoryStream msThumbnail = new MemoryStream())
{
thumbnail.Save(msThumbnail, ImageFormat.Jpeg);
msThumbnail.Seek(0, SeekOrigin.Begin);
RServiceResult<RImage> picture = await _imageFileService.Add(null, msThumbnail, thumbnailImageName, pdfBook.StorageFolderName);
if (picture.Result == null)
{
throw new Exception($"_imageFileService.Add : {picture.ExceptionString}");
}
page.ThumbnailImage = picture.Result;
if (page.PageNumber == 1)
{
pdfBook.CoverImage = picture.Result.DuplicateExcludingId(picture.Result);
}
}
}
pages.Add(page);
}
foreach (var fileName in fileNames)
{
File.Delete(fileName);
}
Directory.Delete(intermediateFolder, true);
return pages;
}
private async Task<RServiceResult<bool>> _UploadPDFBookToExternalServer(PDFBook book, RMuseumDbContext context, bool skipUpload)
{
LongRunningJobProgressServiceEF jobProgressServiceEF = new LongRunningJobProgressServiceEF(context);
var job = (await jobProgressServiceEF.NewJob("_UploadArtifactToExternalServer", $"Uploading {book.StorageFolderName}")).Result;
try
{
if (bool.Parse(Configuration.GetSection("ExternalFTPServer")["UploadEnabled"]))
@ -348,40 +270,29 @@ namespace RMuseum.Services.Implementation
Configuration.GetSection("ExternalFTPServer")["Username"],
Configuration.GetSection("ExternalFTPServer")["Password"]
);
if (!skipUpload)
{
ftpClient.ValidateCertificate += FtpClient_ValidateCertificate;
await ftpClient.AutoConnect();
ftpClient.Config.RetryAttempts = 3;
}
var localPDFFilePath = _imageFileService.GetImagePath(book.PDFFile).Result;
var remotePDFFilePath = $"{Configuration.GetSection("ExternalFTPServer")["RootPath"]}/images/{book.StorageFolderName}/{Path.GetFileName(localPDFFilePath)}";
if (!skipUpload)
{
await jobProgressServiceEF.UpdateJob(job.Id, 0, localPDFFilePath);
await ftpClient.UploadFile(localPDFFilePath, remotePDFFilePath, createRemoteDir: true);
}
var localCoverImageFilePath = _imageFileService.GetImagePath(book.CoverImage).Result;
var remoteCoverImageFilePath = $"{Configuration.GetSection("ExternalFTPServer")["RootPath"]}/images/{book.StorageFolderName}/{Path.GetFileName(localCoverImageFilePath)}";
if (!skipUpload)
{
await jobProgressServiceEF.UpdateJob(job.Id, 0, localCoverImageFilePath);
await ftpClient.UploadFile(localCoverImageFilePath, remoteCoverImageFilePath, createRemoteDir: true);
}
book.ExternalPDFFileUrl = remotePDFFilePath;
book.ExtenalCoverImageUrl = remoteCoverImageFilePath;
context.Update(book);
foreach (var item in book.Pages)
{
var localFilePath = _imageFileService.GetImagePath(item.ThumbnailImage).Result;
@ -394,14 +305,12 @@ namespace RMuseum.Services.Implementation
await ftpClient.UploadFile(localFilePath, remoteFilePath, createRemoteDir: true);
}
}
if (!skipUpload)
{
await ftpClient.Disconnect();
}
await jobProgressServiceEF.UpdateJob(job.Id, 100, "", true);
}
return new RServiceResult<bool>(true);
}
catch (Exception exp)
@ -410,24 +319,17 @@ namespace RMuseum.Services.Implementation
return new RServiceResult<bool>(false, exp.ToString());
}
}
private void FtpClient_ValidateCertificate(BaseFtpClient control, FtpSslValidationEventArgs e)
{
e.Accept = true;
}
/// <summary>
/// عرض تصویر بندانگشتی
/// </summary>
protected int ThumbnailImageWidth { get { return int.Parse($"{Configuration.GetSection("PictureFileService")["ThumbnailImageWidth"]}"); } }
/// <summary>
/// طول تصویر بندانگشتی
/// </summary>
protected int ThumbnailImageMaxHeight { get { return int.Parse($"{Configuration.GetSection("PictureFileService")["ThumbnailMaxHeight"]}"); } }
}
}

View File

@ -1,6 +1,12 @@
using Microsoft.Extensions.Configuration;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using RMuseum.DbContext;
using RMuseum.Models.PDFLibrary;
using RMuseum.Models.PDFLibrary.ViewModels;
using RSecurityBackend.Models.Generic;
using RSecurityBackend.Services;
using System.Collections.Generic;
using System.Linq;
namespace RMuseum.Services.Implementation
{
@ -10,6 +16,135 @@ namespace RMuseum.Services.Implementation
public partial class PDFLibraryService : IPDFLibraryService
{
/// <summary>
/// start importing local pdf file
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public RServiceResult<bool> StartImportingLocalPDF(NewPDFBookViewModel model)
{
_backgroundTaskQueue.QueueBackgroundWorkItem
(
async token =>
{
using (RMuseumDbContext context = new RMuseumDbContext(new DbContextOptions<RMuseumDbContext>()))
{
var pdfRes = await ImportLocalPDFFile(context, model.BookId, model.MultiVolumePDFCollectionId, model.VolumeOrder, model.LocalImportingPDFFilePath, model.OriginalSourceUrl, model.SkipUpload);
if (pdfRes.Result != null)
{
var pdfBook = pdfRes.Result;
pdfBook.Title = model.Title;
pdfBook.SubTitle = model.SubTitle;
pdfBook.AuthorsLine = model.AuthorsLine;
pdfBook.ISBN = model.ISBN;
pdfBook.Description = model.Description;
pdfBook.IsTranslation = model.IsTranslation;
pdfBook.TranslatorsLine = model.TranslatorsLine;
pdfBook.TitleInOriginalLanguage = model.TitleInOriginalLanguage;
pdfBook.PublisherLine = model.PublisherLine;
pdfBook.PublishingDate = model.PublishingDate;
pdfBook.PublishingLocation = model.PublishingLocation;
pdfBook.PublishingNumber = model.PublishingNumber;
pdfBook.ClaimedPageCount = model.ClaimedPageCount;
pdfBook.OriginalSourceName = model.OriginalSourceName;
pdfBook.OriginalFileUrl = model.OriginalFileUrl;
List<AuthorRole> roles = new List<AuthorRole>();
if(model.WriterId != null)
{
roles.Add(new AuthorRole()
{
Author = await context.Authors.Where(a => a.Id == model.WriterId).SingleAsync(),
Role = "نویسنده",
});
}
if (model.Writer2Id != null)
{
roles.Add(new AuthorRole()
{
Author = await context.Authors.Where(a => a.Id == model.Writer2Id).SingleAsync(),
Role = "نویسنده",
});
}
if (model.Writer3Id != null)
{
roles.Add(new AuthorRole()
{
Author = await context.Authors.Where(a => a.Id == model.Writer3Id).SingleAsync(),
Role = "نویسنده",
});
}
if (model.Writer4Id != null)
{
roles.Add(new AuthorRole()
{
Author = await context.Authors.Where(a => a.Id == model.Writer4Id).SingleAsync(),
Role = "نویسنده",
});
}
if(model.TranslatorId != null)
{
roles.Add(new AuthorRole()
{
Author = await context.Authors.Where(a => a.Id == model.TranslatorId).SingleAsync(),
Role = "مترجم",
});
}
if (model.Translator2Id != null)
{
roles.Add(new AuthorRole()
{
Author = await context.Authors.Where(a => a.Id == model.Translator2Id).SingleAsync(),
Role = "مترجم",
});
}
if (model.Translator3Id != null)
{
roles.Add(new AuthorRole()
{
Author = await context.Authors.Where(a => a.Id == model.Translator3Id).SingleAsync(),
Role = "مترجم",
});
}
if (model.Translator4Id != null)
{
roles.Add(new AuthorRole()
{
Author = await context.Authors.Where(a => a.Id == model.Translator4Id).SingleAsync(),
Role = "مترجم",
});
}
if (model.CollectorId != null)
{
roles.Add(new AuthorRole()
{
Author = await context.Authors.Where(a => a.Id == model.CollectorId).SingleAsync(),
Role = "مصحح",
});
}
if (model.Collector2Id != null)
{
roles.Add(new AuthorRole()
{
Author = await context.Authors.Where(a => a.Id == model.Collector2Id).SingleAsync(),
Role = "مصحح",
});
}
if(roles.Count > 0)
{
pdfBook.Contributers = roles;
}
context.Update(pdfBook);
await context.SaveChangesAsync();
}
}
}
);
return new RServiceResult<bool>(true);
}
/// <summary>
/// Database Context
/// </summary>