using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using RMuseum.Models.Auth.Memory; using RMuseum.Models.PDFLibrary; using RMuseum.Models.PDFLibrary.ViewModels; using RMuseum.Services; using RSecurityBackend.Models.Auth.Memory; using RSecurityBackend.Models.Generic; using System.Linq; using System; using System.Net; using System.Threading.Tasks; using RSecurityBackend.Services; using System.Collections.Generic; using Newtonsoft.Json; using RMuseum.Models.Artifact; using RMuseum.Services.Implementation; using RMuseum.Models.GanjoorIntegration.ViewModels; using RMuseum.Models.GanjoorIntegration; namespace RMuseum.Controllers { [Produces("application/json")] [Route("api/pdf")] public class PDFLibraryController : Controller { /// ///get all published pdfbooks (including CoverImage info but not pages or tagibutes info) - check paging-headers for paging info /// /// /// [HttpGet] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetAllPDFBooksAsync([FromQuery] PagingParameterModel paging) { var pdfBooksInfo = await _pdfService.GetAllPDFBooksAsync(paging, new PublishStatus[] { PublishStatus.Published }); if (!string.IsNullOrEmpty(pdfBooksInfo.ExceptionString)) { return BadRequest(pdfBooksInfo.ExceptionString); } if (pdfBooksInfo.Result.Books.Count() > 0) { DateTime lastModification = pdfBooksInfo.Result.Books.Max(i => i.LastModified); Response.GetTypedHeaders().LastModified = lastModification; var requestHeaders = Request.GetTypedHeaders(); if (requestHeaders.IfModifiedSince.HasValue && requestHeaders.IfModifiedSince.Value >= lastModification) { return StatusCode(StatusCodes.Status304NotModified); } } // Paging Header HttpContext.Response.Headers.Add("paging-headers", JsonConvert.SerializeObject(pdfBooksInfo.Result.PagingMeta)); return Ok(pdfBooksInfo.Result.Books); } /// /// get all pdf books visible by user (including CoverImage info but not items info) /// /// /// [HttpGet] [Route("secure")] [Authorize] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetUserVisiblePDFBooksAsync([FromQuery] PagingParameterModel paging) { RServiceResult v = await _GetUserVisiblePDFBooksStatusSetAsync ( new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value), new Guid(User.Claims.FirstOrDefault(c => c.Type == "SessionId").Value) ); if (!string.IsNullOrEmpty(v.ExceptionString)) return BadRequest(v.ExceptionString); PublishStatus[] visibleItems = v.Result; if (visibleItems.Length == 1 && visibleItems[0] == PublishStatus.Published) //Caching { return await GetAllPDFBooksAsync(paging); } RServiceResult<(PaginationMetadata PagingMeta, PDFBook[] Books)> itemsInfo = await _pdfService.GetAllPDFBooksAsync(paging, visibleItems); if (!string.IsNullOrEmpty(itemsInfo.ExceptionString)) { return BadRequest(itemsInfo.ExceptionString); } if (itemsInfo.Result.Books.Count() > 0) { DateTime lastModification = itemsInfo.Result.Books.Max(i => i.LastModified); Response.GetTypedHeaders().LastModified = lastModification; var requestHeaders = Request.GetTypedHeaders(); if (requestHeaders.IfModifiedSince.HasValue && requestHeaders.IfModifiedSince.Value >= lastModification) { return StatusCode(StatusCodes.Status304NotModified); } } // Paging Header HttpContext.Response.Headers.Add("paging-headers", JsonConvert.SerializeObject(itemsInfo.Result.PagingMeta)); return Ok(itemsInfo.Result.Books); } /// /// secure get a pdf book /// /// /// /// /// /// [HttpGet("secure/{id}")] [Authorize] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(PDFBook))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] [ProducesResponseType((int)HttpStatusCode.NotFound)] public async Task GetUserVisiblePDFBookAsync(int id, bool includePages = false, bool includeBookText = false, bool includePageText = false) { RServiceResult v = await _GetUserVisiblePDFBooksStatusSetAsync ( new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value), new Guid(User.Claims.FirstOrDefault(c => c.Type == "SessionId").Value) ); if (!string.IsNullOrEmpty(v.ExceptionString)) return BadRequest(v.ExceptionString); PublishStatus[] visibleItems = v.Result; RServiceResult bookRes = null; if (visibleItems.Length == 1 && visibleItems[0] == PublishStatus.Published) { bookRes = await _pdfService.GetPDFBookByIdAsync(id, new PublishStatus[] { PublishStatus.Published }, includePages, includeBookText, includePageText); if (!string.IsNullOrEmpty(bookRes.ExceptionString)) { return BadRequest(bookRes.ExceptionString); } if (bookRes.Result == null) return NotFound(); } if (bookRes == null) { bookRes = await _pdfService.GetPDFBookByIdAsync(id, visibleItems, includePages, includeBookText, includePageText); } if (!string.IsNullOrEmpty(bookRes.ExceptionString)) { return BadRequest(bookRes.ExceptionString); } if (bookRes.Result == null) return NotFound(); Response.GetTypedHeaders().LastModified = bookRes.Result.LastModified; var requestHeaders = Request.GetTypedHeaders(); if (requestHeaders.IfModifiedSince.HasValue && requestHeaders.IfModifiedSince.Value >= bookRes.Result.LastModified) { return StatusCode(StatusCodes.Status304NotModified); } return Ok(bookRes.Result); } private async Task> _GetUserVisiblePDFBooksStatusSetAsync(Guid loggedOnUserId, Guid sessionId) { RServiceResult canView = await _userPermissionChecker.Check ( loggedOnUserId, sessionId, RMuseumSecurableItem.PDFLibraryEntityShortName, RMuseumSecurableItem.ViewDraftOperationShortName ); if (!string.IsNullOrEmpty(canView.ExceptionString)) return new RServiceResult(null, canView.ExceptionString); PublishStatus[] visibleItems = canView.Result ? new PublishStatus[] { PublishStatus.Published, PublishStatus.Restricted, PublishStatus.Draft, PublishStatus.Awaiting } : new PublishStatus[] { PublishStatus.Published }; return new RServiceResult(visibleItems); } /// /// get published PDF Book by id /// /// /// /// /// /// [HttpGet("{id}")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(PDFBook))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] [ProducesResponseType((int)HttpStatusCode.NotFound)] public async Task GetPDFBookByIdAsync(int id, bool includePages = false, bool includeBookText = false, bool includePageText = false) { var bookRes = await _pdfService.GetPDFBookByIdAsync(id, new PublishStatus[] { PublishStatus.Published }, includePages, includeBookText, includePageText); if (!string.IsNullOrEmpty(bookRes.ExceptionString)) { return BadRequest(bookRes.ExceptionString); } if (bookRes.Result == null) return NotFound(); Response.GetTypedHeaders().LastModified = bookRes.Result.LastModified; var requestHeaders = Request.GetTypedHeaders(); if (requestHeaders.IfModifiedSince.HasValue && requestHeaders.IfModifiedSince.Value >= bookRes.Result.LastModified) { return StatusCode(StatusCodes.Status304NotModified); } return Ok(bookRes.Result); } /// /// start importing a local pdf file /// /// /// [HttpPost] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.AddOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task StartImportingLocalPDFAsync([FromBody] NewPDFBookViewModel model) { var res = await _pdfService.StartImportingLocalPDFAsync(model); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(); } /// /// import from known sources /// /// /// [HttpPost("import")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.AddOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task StartImportingKnownSourceAsync([FromBody]string srcUrl) { var res = await _pdfService.StartImportingKnownSourceAsync(srcUrl); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(); } /// /// batch import soha library /// /// /// /// [HttpPost("soha/{start}/{end}")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.AddOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public IActionResult BatchImportSohaLibraryAsync(int start, int end) { _pdfService.BatchImportSohaLibraryAsync(start, end); return Ok(); } /// /// batch import eliteraturebook.com library /// /// start from 0 /// /// [HttpPost("elit/{ajaxPageIndexStart}/{ajaxPageIndexEnd}")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.AddOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public IActionResult BatchImportELiteratureBookLibraryAsync(int ajaxPageIndexStart, int ajaxPageIndexEnd) { _pdfService.BatchImportELiteratureBookLibraryAsync(ajaxPageIndexStart, ajaxPageIndexEnd); return Ok(); } /// /// edit pdf book master record (user should have additional permissions pdf:awaiting and pdf:publish to change status of pdf book) /// /// /// editing related collections such as pages and attributed or complex properties such as CoverImage is ignored /// /// /// [HttpPut] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.ModifyOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] [ProducesResponseType((int)HttpStatusCode.NotFound)] public async Task PutPDFBookAsync([FromBody] PDFBook pdf) { Guid loggedOnUserId = new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value); Guid sessionId = new Guid(User.Claims.FirstOrDefault(c => c.Type == "SessionId").Value); RServiceResult canChangeStatusToAwaiting = await _userPermissionChecker.Check ( loggedOnUserId, sessionId, RMuseumSecurableItem.PDFLibraryEntityShortName, RMuseumSecurableItem.ToAwaitingStatusOperationShortName ); if (!string.IsNullOrEmpty(canChangeStatusToAwaiting.ExceptionString)) return BadRequest(canChangeStatusToAwaiting.ExceptionString); RServiceResult canPublish = await _userPermissionChecker.Check ( loggedOnUserId, sessionId, RMuseumSecurableItem.PDFLibraryEntityShortName, RMuseumSecurableItem.PublishOperationShortName ); if (!string.IsNullOrEmpty(canPublish.ExceptionString)) return BadRequest(canPublish.ExceptionString); RServiceResult itemInfo = await _pdfService.EditPDFBookMasterRecordAsync(pdf, canChangeStatusToAwaiting.Result, canPublish.Result); if (!string.IsNullOrEmpty(itemInfo.ExceptionString)) { return BadRequest(itemInfo.ExceptionString); } if (itemInfo == null) { return NotFound(); } return Ok(); } /// /// Copy PDF Book Cover Image From Page Thumbnail image /// /// /// /// [HttpPut("{id}/cover/{pageId}")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.ModifyOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task SetPDFBookCoverImageFromPageAsync(int id, int pageId) { RServiceResult res = await _pdfService.SetPDFBookCoverImageFromPageAsync(id, pageId); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(); return Ok(); } /// /// remove unpublished pdf book /// /// /// [HttpDelete("{bookId}")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.DeleteOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(bool))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] [ProducesResponseType((int)HttpStatusCode.Forbidden)] public async Task RemovePDFBookAsync(int bookId) { RServiceResult res = await _pdfService.RemovePDFBookAsync(bookId); if (!string.IsNullOrEmpty(res.ExceptionString)) { return BadRequest(res.ExceptionString); } return Ok(res.Result); } /// /// add new tag value to pdf book /// /// /// only name is processed /// [HttpPost("tagvalue/{pdfBookId}")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + RMuseumSecurableItem.EditTagValueOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(RTagValue))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task TagPDFBookAsync(int pdfBookId, [FromBody] RTag tag) { RServiceResult res = await _pdfService.TagPDFBookAsync(pdfBookId, tag); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(res.Result); } /// /// edit pdf book attribute value /// /// /// editable fields are limited /// /// /// /// apply on all same value tags /// [HttpPut("tagvalue/{pdfBookId}/{global=true}")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + RMuseumSecurableItem.EditTagValueOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] [ProducesResponseType((int)HttpStatusCode.NotFound)] public async Task EditPDFBookTagValueAsync(int pdfBookId, bool global, [FromBody] RTagValue tagvalue) { RServiceResult itemInfo = await _pdfService.EditPDFBookTagValueAsync(pdfBookId, tagvalue, global); if (!string.IsNullOrEmpty(itemInfo.ExceptionString)) { return BadRequest(itemInfo.ExceptionString); } if (itemInfo == null) { return NotFound(); } return Ok(); ; } /// /// remove tag from pdf book /// /// /// /// [HttpDelete("tagvalue/{pdfBookId}/{tagValueId}")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + RMuseumSecurableItem.EditTagValueOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(bool))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] [ProducesResponseType((int)HttpStatusCode.Forbidden)] public async Task UnTagPDFBookAsync(int pdfBookId, Guid tagValueId) { RServiceResult res = await _pdfService.UnTagPDFBookAsync(pdfBookId, tagValueId); if (!string.IsNullOrEmpty(res.ExceptionString)) { return BadRequest(res.ExceptionString); } return Ok(res.Result); } /// /// get tagged publish pdfbooks (including CoverImage info but not pages or tagibutes info) /// /// /// /// [HttpGet("tagged/{tagUrl}/{valueUrl}")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetByTagValueAsync(string tagUrl, string valueUrl) { RServiceResult itemsInfo = await _pdfService.GetPDFBookByTagValueAsync(tagUrl, valueUrl, new PublishStatus[] { PublishStatus.Published }); if (!string.IsNullOrEmpty(itemsInfo.ExceptionString)) { return BadRequest(itemsInfo.ExceptionString); } if (itemsInfo.Result.Length > 0) { DateTime lastModification = itemsInfo.Result.Max(i => i.LastModified); Response.GetTypedHeaders().LastModified = lastModification; var requestHeaders = Request.GetTypedHeaders(); if (requestHeaders.IfModifiedSince.HasValue && requestHeaders.IfModifiedSince.Value >= lastModification) { return StatusCode(StatusCodes.Status304NotModified); } } return Ok(itemsInfo.Result); } /// /// get authors /// /// /// /// [HttpGet("author")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetAuthorsAsync([FromQuery] PagingParameterModel paging, string authorName = null) { var authorsRes = await _pdfService.GetAuthorsAsync(paging, authorName); if (!string.IsNullOrEmpty(authorsRes.ExceptionString)) { return BadRequest(authorsRes.ExceptionString); } if (authorsRes.Result.Authors.Count() > 0) { DateTime lastModification = authorsRes.Result.Authors.Max(i => i.LastModified); Response.GetTypedHeaders().LastModified = lastModification; var requestHeaders = Request.GetTypedHeaders(); if (requestHeaders.IfModifiedSince.HasValue && requestHeaders.IfModifiedSince.Value >= lastModification) { return StatusCode(StatusCodes.Status304NotModified); } } // Paging Header HttpContext.Response.Headers.Add("paging-headers", JsonConvert.SerializeObject(authorsRes.Result.PagingMeta)); return Ok(authorsRes.Result.Authors); } /// /// get author by id /// /// /// [HttpGet("author/{id}")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(Author))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetAuthorByIdAsync(int id) { var authorsRes = await _pdfService.GetAuthorByIdAsync(id); if (!string.IsNullOrEmpty(authorsRes.ExceptionString)) { return BadRequest(authorsRes.ExceptionString); } if(authorsRes.Result == null) { return NotFound(); } return Ok(authorsRes.Result); } /// /// add a new author /// /// /// [HttpPost("author")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.AddOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(Author))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task AddAuthorAsync([FromBody] Author author) { var res = await _pdfService.AddAuthorAsync(author); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(res.Result); } /// /// edit an existing author /// /// /// [HttpPut("author")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.ModifyOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task UpdateAuthorAsync([FromBody] Author author) { var res = await _pdfService.UpdateAuthorAsync(author); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(); } /// /// delete an existing author /// /// /// [HttpDelete("author/{id}")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.DeleteOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task DeleteAuthorAsync(int id) { var res = await _pdfService.DeleteAuthorAsync(id); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(); } [HttpPost("pdfbook/{pdfBookId}/contributor")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.ModifyOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task AddPDFBookContributerAsync(int pdfBookId, [FromBody] AuthorRole role) { var res = await _pdfService.AddPDFBookContributerAsync(pdfBookId, role.Author.Id, role.Role); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(); } /// /// delete an existing contribution from pdf book /// /// /// /// [HttpDelete("pdfbook/{pdfBookId}/contributor/{contributorRecordId}")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.ModifyOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task DeletePDFBookContributerAsync(int pdfBookId, int contributorRecordId) { var res = await _pdfService.DeletePDFBookContributerAsync(pdfBookId, contributorRecordId); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(); } /// /// pdf book by contributer /// /// /// /// /// [HttpGet("pdfbook/by/contributer/{authorId}")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetPublishedPDFBooksByAuthorAsync([FromQuery] PagingParameterModel paging, int authorId, string role = null) { var pdfBooksInfo = await _pdfService.GetPublishedPDFBooksByAuthorAsync(paging, authorId, role); if (!string.IsNullOrEmpty(pdfBooksInfo.ExceptionString)) { return BadRequest(pdfBooksInfo.ExceptionString); } if (pdfBooksInfo.Result.Books.Count() > 0) { DateTime lastModification = pdfBooksInfo.Result.Books.Max(i => i.LastModified); Response.GetTypedHeaders().LastModified = lastModification; var requestHeaders = Request.GetTypedHeaders(); if (requestHeaders.IfModifiedSince.HasValue && requestHeaders.IfModifiedSince.Value >= lastModification) { return StatusCode(StatusCodes.Status304NotModified); } } // Paging Header HttpContext.Response.Headers.Add("paging-headers", JsonConvert.SerializeObject(pdfBooksInfo.Result.PagingMeta)); return Ok(pdfBooksInfo.Result.Books); } /// /// get published pdf books by author stats (group by role) /// /// /// [HttpGet("pdfbook/by/contributer/{authorId}/groupby/role")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetPublishedPDFBookbyAuthorGroupedByRoleAsync(int authorId) { var res = await _pdfService.GetPublishedPDFBookbyAuthorGroupedByRoleAsync(authorId); if (!string.IsNullOrEmpty(res.ExceptionString)) { return BadRequest(res.ExceptionString); } return Ok(res.Result); } /// /// get all books /// /// /// [HttpGet("book")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetAllBooksAsync([FromQuery] PagingParameterModel paging) { var res = await _pdfService.GetAllBooksAsync(paging); if (!string.IsNullOrEmpty(res.ExceptionString)) { return BadRequest(res.ExceptionString); } if (res.Result.Books.Count() > 0) { DateTime lastModification = res.Result.Books.Max(i => i.LastModified); Response.GetTypedHeaders().LastModified = lastModification; var requestHeaders = Request.GetTypedHeaders(); if (requestHeaders.IfModifiedSince.HasValue && requestHeaders.IfModifiedSince.Value >= lastModification) { return StatusCode(StatusCodes.Status304NotModified); } } // Paging Header HttpContext.Response.Headers.Add("paging-headers", JsonConvert.SerializeObject(res.Result.PagingMeta)); return Ok(res.Result.Books); } /// /// book by id /// /// /// [HttpGet("book/{id}")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(Book))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetBookByIdAsync(int id) { var res = await _pdfService.GetBookByIdAsync(id); if (!string.IsNullOrEmpty(res.ExceptionString)) { return BadRequest(res.ExceptionString); } return Ok(res.Result); } /// /// add a new book /// /// /// [HttpPost("book")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.AddOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(Book))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task AddBookAsync([FromBody] Book book) { var res = await _pdfService.AddBookAsync(book); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(res.Result); } /// /// update book /// /// /// [HttpPut("book")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.ModifyOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task UpdateBookAsync([FromBody] Book book) { var res = await _pdfService.UpdateBookAsync(book); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(); } /// /// delete book /// /// /// [HttpDelete("book")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.DeleteOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task DeleteBookAsync(int id) { var res = await _pdfService.DeleteBookAsync(id); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(); } /// /// add book author /// /// /// /// [HttpPost("book/{bookId}/author")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.ModifyOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task AddBookAuthorAsync(int bookId, [FromBody] AuthorRole role) { var res = await _pdfService.AddBookAuthorAsync(bookId, role.Author.Id, role.Role); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(); } /// /// delete an existing author from book /// /// /// /// [HttpDelete("book/{bookId}/author/{authorRecordId}")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.ModifyOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task DeleteBookAuthorAsync(int bookId, int authorRecordId) { var res = await _pdfService.DeleteBookAuthorAsync(bookId, authorRecordId); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(); } /// /// books by author /// /// /// /// /// [HttpGet("book/by/author/{authorId}")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetBooksByAuthorAsync([FromQuery] PagingParameterModel paging, int authorId, string role = null) { var res = await _pdfService.GetBooksByAuthorAsync(paging, authorId, role); if (!string.IsNullOrEmpty(res.ExceptionString)) { return BadRequest(res.ExceptionString); } if (res.Result.Books.Count() > 0) { DateTime lastModification = res.Result.Books.Max(i => i.LastModified); Response.GetTypedHeaders().LastModified = lastModification; var requestHeaders = Request.GetTypedHeaders(); if (requestHeaders.IfModifiedSince.HasValue && requestHeaders.IfModifiedSince.Value >= lastModification) { return StatusCode(StatusCodes.Status304NotModified); } } // Paging Header HttpContext.Response.Headers.Add("paging-headers", JsonConvert.SerializeObject(res.Result.PagingMeta)); return Ok(res.Result.Books); } /// /// get books by author stats (group by role) /// /// /// [HttpGet("book/by/author/{authorId}/groupby/role")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetBookbyAuthorGroupedByRoleAsync(int authorId) { var res = await _pdfService.GetBookbyAuthorGroupedByRoleAsync(authorId); if (!string.IsNullOrEmpty(res.ExceptionString)) { return BadRequest(res.ExceptionString); } return Ok(res.Result); } /// /// get book related pdf books /// /// /// /// [HttpGet("book/{bookId}/pdfs")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetBookRelatedPDFBooksAsync([FromQuery] PagingParameterModel paging, int sourceId) { var res = await _pdfService.GetBookRelatedPDFBooksAsync(paging, sourceId); if (!string.IsNullOrEmpty(res.ExceptionString)) { return BadRequest(res.ExceptionString); } if (res.Result.Books.Count() > 0) { DateTime lastModification = res.Result.Books.Max(i => i.LastModified); Response.GetTypedHeaders().LastModified = lastModification; var requestHeaders = Request.GetTypedHeaders(); if (requestHeaders.IfModifiedSince.HasValue && requestHeaders.IfModifiedSince.Value >= lastModification) { return StatusCode(StatusCodes.Status304NotModified); } } // Paging Header HttpContext.Response.Headers.Add("paging-headers", JsonConvert.SerializeObject(res.Result.PagingMeta)); return Ok(res.Result.Books); } /// /// volumes by id /// /// /// [HttpGet("volumes/{id}")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(MultiVolumePDFCollection))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetMultiVolumePDFCollectionByIdAsync(int id) { var res = await _pdfService.GetMultiVolumePDFCollectionByIdAsync(id); if (!string.IsNullOrEmpty(res.ExceptionString)) { return BadRequest(res.ExceptionString); } return Ok(res.Result); } /// /// add a new multi volume pdf collection /// /// /// [HttpPost("volumes")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.AddOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(MultiVolumePDFCollection))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task AddMultiVolumePDFCollectionAsync([FromBody] MultiVolumePDFCollection volumes) { var res = await _pdfService.AddMultiVolumePDFCollectionAsync(volumes); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(res.Result); } /// /// update multi volume pdf collection /// /// /// [HttpPut("volumes")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.ModifyOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task UpdateMultiVolumePDFCollectionAsync([FromBody] MultiVolumePDFCollection volumes) { var res = await _pdfService.UpdateMultiVolumePDFCollectionAsync(volumes); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(res.Result); } /// /// delete multi volume pdf collection /// /// /// [HttpDelete("volumes")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.DeleteOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task DeleteMultiVolumePDFCollectionAsync(int id) { var res = await _pdfService.DeleteMultiVolumePDFCollectionAsync(id); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(res.Result); } /// /// get volumes pdf books /// /// /// [HttpGet("volumes/{volumeId}/pdfs")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetVolumesPDFBooks(int volumeId) { var res = await _pdfService.GetVolumesPDFBooks(volumeId); if (!string.IsNullOrEmpty(res.ExceptionString)) { return BadRequest(res.ExceptionString); } return Ok(res.Result); } /// /// get all sources /// /// [HttpGet("source")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetPDFSourcesAsync() { var res = await _pdfService.GetPDFSourcesAsync(); if (!string.IsNullOrEmpty(res.ExceptionString)) { return BadRequest(res.ExceptionString); } return Ok(res.Result); } /// /// source by id /// /// /// [HttpGet("source/{id}")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(PDFSource))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetPDFSourceByIdAsync(int id) { var res = await _pdfService.GetPDFSourceByIdAsync(id); if (!string.IsNullOrEmpty(res.ExceptionString)) { return BadRequest(res.ExceptionString); } return Ok(res.Result); } /// /// add a new source /// /// /// [HttpPost("source")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.AddOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(PDFSource))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task AddPDFSourceAsync([FromBody] PDFSource source) { var res = await _pdfService.AddPDFSourceAsync(source); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(res.Result); } /// /// update source /// /// /// [HttpPut("source")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.ModifyOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task UpdatePDFSourceAsync([FromBody] PDFSource source) { var res = await _pdfService.UpdatePDFSourceAsync(source); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(); } /// /// delete book /// /// /// [HttpDelete("source")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.DeleteOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task DeletePDFSourceAsync(int id) { var res = await _pdfService.DeletePDFSourceAsync(id); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(); } /// /// get pdf source pdfs /// /// /// /// [HttpGet("source/{sourceId}/pdfs")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetSourceRelatedPDFBooksAsync([FromQuery] PagingParameterModel paging, int sourceId) { var res = await _pdfService.GetSourceRelatedPDFBooksAsync(paging, sourceId); if (!string.IsNullOrEmpty(res.ExceptionString)) { return BadRequest(res.ExceptionString); } if (res.Result.Books.Count() > 0) { DateTime lastModification = res.Result.Books.Max(i => i.LastModified); Response.GetTypedHeaders().LastModified = lastModification; var requestHeaders = Request.GetTypedHeaders(); if (requestHeaders.IfModifiedSince.HasValue && requestHeaders.IfModifiedSince.Value >= lastModification) { return StatusCode(StatusCodes.Status304NotModified); } } // Paging Header HttpContext.Response.Headers.Add("paging-headers", JsonConvert.SerializeObject(res.Result.PagingMeta)); return Ok(res.Result.Books); } /// /// search pdf books (titles and authors and translators and tags) /// /// /// /// [HttpGet] [Route("search")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task SearchPDFBooksAsync([FromQuery] PagingParameterModel paging, string term) { var pagedResult = await _pdfService.SearchPDFBooksAsync(paging, term); if (!string.IsNullOrEmpty(pagedResult.ExceptionString)) return BadRequest(pagedResult.ExceptionString); // Paging Header HttpContext.Response.Headers.Add("paging-headers", JsonConvert.SerializeObject(pagedResult.Result.PagingMeta)); return Ok(pagedResult.Result.Items); } /// /// search pdf book pages text /// /// /// /// /// [HttpGet] [Route("search/pdfbook/{id}/text")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task SearchPDFPagesTextAsync([FromQuery] PagingParameterModel paging, int id, string term) { var pagedResult = await _pdfService.SearchPDFPagesTextAsync(paging, id, term); if (!string.IsNullOrEmpty(pagedResult.ExceptionString)) return BadRequest(pagedResult.ExceptionString); // Paging Header HttpContext.Response.Headers.Add("paging-headers", JsonConvert.SerializeObject(pagedResult.Result.PagingMeta)); return Ok(pagedResult.Result.Items); } /// /// search book text /// /// /// /// [HttpGet] [Route("search/pages/text")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task SearchPDFBookForPDFPagesTextAsync([FromQuery] PagingParameterModel paging, string term) { var pagedResult = await _pdfService.SearchPDFBookForPDFPagesTextAsync(paging, term); if (!string.IsNullOrEmpty(pagedResult.ExceptionString)) return BadRequest(pagedResult.ExceptionString); // Paging Header HttpContext.Response.Headers.Add("paging-headers", JsonConvert.SerializeObject(pagedResult.Result.PagingMeta)); return Ok(pagedResult.Result.Books); } /// /// suggest ganjoor link /// /// /// [HttpPost] [Route("ganjoor")] [Authorize] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task SuggestGanjoorLinkAsync([FromBody] PDFGanjoorLinkSuggestion link) { Guid loggedOnUserId = new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value); RServiceResult suggestion = await _pdfService.SuggestGanjoorLinkAsync(loggedOnUserId, link); if (!string.IsNullOrEmpty(suggestion.ExceptionString)) return BadRequest(suggestion.ExceptionString); return Ok(); } /// /// finds next awaiting suggested link /// return value might be null (has paging-headers) /// /// has paging-headers /// /// return value might be null [HttpGet] [Route("ganjoor/nextunreviewed")] [Authorize] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorLinkViewModel))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetNextUnreviewedGanjoorLinkAsync(int skip) { RServiceResult res = await _pdfService.GetNextUnreviewedGanjoorLinkAsync(skip); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); var resCount = await _pdfService.GetUnreviewedGanjoorLinksCountAsync(); if (!string.IsNullOrEmpty(resCount.ExceptionString)) return BadRequest(resCount.ExceptionString); // Paging Header HttpContext.Response.Headers.Add("paging-headers", JsonConvert.SerializeObject( new PaginationMetadata() { totalCount = resCount.Result, pageSize = -1, currentPage = -1, hasNextPage = false, hasPreviousPage = false, totalPages = -1 }) ); return Ok(res.Result); } /// /// review suggested ganjoor link /// /// /// /// [HttpPut] [Route("ganjoor/review/{linkId}/{result}")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + RMuseumSecurableItem.ReviewGanjoorLinksOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task ReviewSuggestedLinkAsync(Guid linkId, ReviewResult result) { Guid loggedOnUserId = new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value); RServiceResult suggestion = await _pdfService.ReviewSuggestedLinkAsync(linkId, loggedOnUserId, result); if (!string.IsNullOrEmpty(suggestion.ExceptionString)) return BadRequest(suggestion.ExceptionString); return Ok(); } /// /// ganjoor approved unsycned links /// /// [HttpGet] [Route("ganjoor/unsynched")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + RMuseumSecurableItem.ReviewGanjoorLinksOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(PDFGanjoorLink[]))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetUnsyncedPDFGanjoorLinksAsync() { RServiceResult res = await _pdfService.GetUnsyncedPDFGanjoorLinksAsync(); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(res.Result); } /// /// synchronize ganjoor link /// /// /// [HttpPut] [Route("ganjoor/sync/{linkId}")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + RMuseumSecurableItem.ReviewGanjoorLinksOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task SynchronizePDFGanjoorLinkAsync(Guid linkId) { Guid loggedOnUserId = new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value); RServiceResult suggestion = await _pdfService.SynchronizePDFGanjoorLinkAsync(linkId); if (!string.IsNullOrEmpty(suggestion.ExceptionString)) return BadRequest(suggestion.ExceptionString); return Ok(); } /// /// next un-ocred pdf book /// /// [HttpGet] [Route("ocr/nextunocred")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.ModifyOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(PDFBook))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetNextUnOCRedPDFBookAsync() { RServiceResult res = await _pdfService.GetNextUnOCRedPDFBookAsync(); if (!string.IsNullOrEmpty(res.ExceptionString)) return BadRequest(res.ExceptionString); return Ok(res.Result); } /// /// set page ocr info /// /// /// [HttpPut] [Route("ocr")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.ModifyOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] [ProducesResponseType((int)HttpStatusCode.NotFound)] public async Task SetPDFPageOCRInfoAsync([FromBody] PDFPageOCRDataViewModel pdf) { RServiceResult res = await _pdfService.SetPDFPageOCRInfoAsync(pdf); if (!string.IsNullOrEmpty(res.ExceptionString)) { return BadRequest(res.ExceptionString); } return Ok(); } /// /// fill book text /// /// [HttpPut] [Route("ocr/fillbooktext")] [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + SecurableItem.ModifyOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] [ProducesResponseType((int)HttpStatusCode.NotFound)] public IActionResult StartFillingMissingBookTextsAsync() { _pdfService.StartFillingMissingBookTextsAsync(); return Ok(); } /// /// page of published book by page number /// /// /// /// [HttpGet("{pdfBookId}/page/{pageNumber}")] [AllowAnonymous] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(PDFPage))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] [ProducesResponseType((int)HttpStatusCode.NotFound)] public async Task GetPDFPageAsync(int pdfBookId, int pageNumber) { var bookRes = await _pdfService.GetPDFPageAsync(pdfBookId, pageNumber); if (!string.IsNullOrEmpty(bookRes.ExceptionString)) { return BadRequest(bookRes.ExceptionString); } if (bookRes.Result == null) return NotFound(); Response.GetTypedHeaders().LastModified = bookRes.Result.LastModified; var requestHeaders = Request.GetTypedHeaders(); if (requestHeaders.IfModifiedSince.HasValue && requestHeaders.IfModifiedSince.Value >= bookRes.Result.LastModified) { return StatusCode(StatusCodes.Status304NotModified); } return Ok(bookRes.Result); } /// /// PDF Service /// protected readonly IPDFLibraryService _pdfService; /// /// IUserPermissionChecker instance /// protected IUserPermissionChecker _userPermissionChecker; /// /// constructor /// /// /// public PDFLibraryController(IPDFLibraryService pdfService, IUserPermissionChecker userPermissionChecker) { _pdfService = pdfService; _userPermissionChecker = userPermissionChecker; } } }