diff --git a/RMuseum/Controllers/GanjoorController.cs b/RMuseum/Controllers/GanjoorController.cs index 7d3df737..29436bc9 100644 --- a/RMuseum/Controllers/GanjoorController.cs +++ b/RMuseum/Controllers/GanjoorController.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Authorization; +using Audit.WebApi; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; @@ -3584,6 +3585,31 @@ namespace RMuseum.Controllers return Ok(res.Result); } + /// + /// synchronize https:://naskban.ir links (logs in and then out to naskban.ir using auth info) + /// + /// + /// number of synched links + [HttpPost] + [Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.ModerateOperationShortName)] + [Route("naskban")] + [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(int))] + [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] + public async Task SynchronizeNaskbanLinksAsync( + [AuditIgnore] + [FromBody] + LoginViewModel loginViewModel + ) + { + var userId = + new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value); + var res = await _ganjoorService.SynchronizeNaskbanLinksAsync(userId, loginViewModel.Username, loginViewModel.Password); + + if (!string.IsNullOrEmpty(res.ExceptionString)) + return BadRequest(res.ExceptionString); + return Ok(res.Result); + } + diff --git a/RMuseum/Controllers/PDFLibraryController.cs b/RMuseum/Controllers/PDFLibraryController.cs index d4cbbd96..f1c5749f 100644 --- a/RMuseum/Controllers/PDFLibraryController.cs +++ b/RMuseum/Controllers/PDFLibraryController.cs @@ -1280,7 +1280,7 @@ namespace RMuseum.Controllers /// [HttpGet] [Route("ganjoor/unsynched")] - [AllowAnonymous] + [Authorize(Policy = RMuseumSecurableItem.PDFLibraryEntityShortName + ":" + RMuseumSecurableItem.ReviewGanjoorLinksOperationShortName)] [ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(PDFGanjoorLink[]))] [ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))] public async Task GetUnsyncedPDFGanjoorLinksAsync() diff --git a/RMuseum/Models/GanjoorIntegration/PinterestLink.cs b/RMuseum/Models/GanjoorIntegration/PinterestLink.cs index 39f9b706..f5b7b995 100644 --- a/RMuseum/Models/GanjoorIntegration/PinterestLink.cs +++ b/RMuseum/Models/GanjoorIntegration/PinterestLink.cs @@ -129,5 +129,10 @@ namespace RMuseum.Models.GanjoorIntegration /// page number /// public int PageNumber { get; set; } + + /// + /// naskban link id + /// + public Guid? NaskbanLinkId { get; set; } } } diff --git a/RMuseum/RMuseum.xml b/RMuseum/RMuseum.xml index 49ca7047..2a6556ad 100644 --- a/RMuseum/RMuseum.xml +++ b/RMuseum/RMuseum.xml @@ -1991,6 +1991,13 @@ + + + synchronize https:://naskban.ir links (logs in and then out to naskban.ir using auth info) + + + number of synched links + readonly mode @@ -6607,6 +6614,11 @@ page number + + + naskban link id + + Review Result @@ -15182,6 +15194,15 @@ + + + synchronize naskban links + + + + + number of synched items + translation service implementation @@ -17869,6 +17890,15 @@ + + + synchronize naskban links + + + + + number of synched items + aggressive cache diff --git a/RMuseum/Services/IGanjoorService.cs b/RMuseum/Services/IGanjoorService.cs index cba2f300..1be3961f 100644 --- a/RMuseum/Services/IGanjoorService.cs +++ b/RMuseum/Services/IGanjoorService.cs @@ -1190,5 +1190,15 @@ namespace RMuseum.Services /// /// Task> GetCatPoemGeoDateTagsAsync(int catId, bool ignoreSumup = false); + + + /// + /// synchronize naskban links + /// + /// + /// + /// + /// number of synched items + Task> SynchronizeNaskbanLinksAsync(Guid ganjoorUserId, string naskbanUserName, string naskbanPassword); } } diff --git a/RMuseum/Services/Implementation/GanjoorService.cs b/RMuseum/Services/Implementation/GanjoorService.cs index 84a1b2fc..4b8e56fd 100644 --- a/RMuseum/Services/Implementation/GanjoorService.cs +++ b/RMuseum/Services/Implementation/GanjoorService.cs @@ -25,6 +25,15 @@ using System.IO; using RSecurityBackend.Models.Image; using FluentFTP; using System.Drawing; +using RSecurityBackend.Models.Auth.ViewModels; +using Newtonsoft.Json; +using System.Net; +using System.Text; +using RMuseum.Models.Auth.ViewModel; +using System.Net.Http.Headers; +using RMuseum.Models.GanjoorIntegration.ViewModels; +using RMuseum.Models.GanjoorIntegration; +using Microsoft.VisualBasic.ApplicationServices; namespace RMuseum.Services.Implementation { @@ -1569,7 +1578,7 @@ namespace RMuseum.Services.Implementation where link.DisplayOnPage == true && - link.ReviewResult == Models.GanjoorIntegration.ReviewResult.Approved + link.ReviewResult == ReviewResult.Approved && poem.Id == id orderby link.IsTextOriginalSource descending, link.ReviewDate @@ -1588,17 +1597,17 @@ namespace RMuseum.Services.Implementation join poem in _context.GanjoorPoems on link.GanjoorPostId equals poem.Id where - link.ReviewResult == Models.GanjoorIntegration.ReviewResult.Approved + link.ReviewResult == ReviewResult.Approved && poem.Id == id orderby link.ReviewDate select new PoemRelatedImage() { PoemRelatedImageType = PoemRelatedImageType.ExternalLink, - ThumbnailImageUrl = link.Item.Images.First().ExternalNormalSizeImageUrl.Replace("/norm/", "/thumb/").Replace("/orig/", "/thumb/"), + ThumbnailImageUrl = link.LinkType == LinkType.Naskban ? link.PinterestImageUrl : link.Item.Images.First().ExternalNormalSizeImageUrl.Replace("/norm/", "/thumb/").Replace("/orig/", "/thumb/"), TargetPageUrl = link.PinterestUrl, AltText = link.AltText, - IsTextOriginalSource = false + IsTextOriginalSource = link.IsTextOriginalSource }; museumImages.AddRange(await externalSrc.AsNoTracking().ToListAsync()); @@ -3618,6 +3627,79 @@ namespace RMuseum.Services.Implementation } } + /// + /// synchronize naskban links + /// + /// + /// + /// + /// number of synched items + public async Task> SynchronizeNaskbanLinksAsync(Guid ganjoorUserId, string naskbanUserName, string naskbanPassword) + { + try + { + LoginViewModel loginViewModel = new LoginViewModel() + { + Username = naskbanUserName, + Password = naskbanPassword, + ClientAppName = "Ganjoor API", + Language = "fa-IR" + }; + var loginResponse = await _httpClient.PostAsync("https://api.naskban.ir/api/users/login", new StringContent(JsonConvert.SerializeObject(loginViewModel), Encoding.UTF8, "application/json")); + + if (loginResponse.StatusCode != HttpStatusCode.OK) + { + return new RServiceResult(0, "login error: " + JsonConvert.DeserializeObject(await loginResponse.Content.ReadAsStringAsync())); + } + LoggedOnUserModelEx loggedOnUser = JsonConvert.DeserializeObject(await loginResponse.Content.ReadAsStringAsync()); + + using (HttpClient secureClient = new HttpClient()) + { + secureClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", loggedOnUser.Token); + var unsyncedResponse = await secureClient.GetAsync("https://api.naskban.ir/api/pdf/ganjoor/unsynched"); + if (!unsyncedResponse.IsSuccessStatusCode) + { + return new RServiceResult(0, "unsync error: " + JsonConvert.DeserializeObject(await unsyncedResponse.Content.ReadAsStringAsync())); + } + var unsynchronizeds = JsonConvert.DeserializeObject(await unsyncedResponse.Content.ReadAsStringAsync()); + foreach (var unsynchronized in unsynchronizeds) + { + if(false == await _context.PinterestLinks.Where(p => p.NaskbanLinkId == unsynchronized.Id).AnyAsync() ) + { + PinterestLink link = new PinterestLink() + { + GanjoorPostId = unsynchronized.GanjoorPostId, + GanjoorTitle = unsynchronized.GanjoorTitle, + GanjoorUrl = unsynchronized.GanjoorUrl, + AltText = unsynchronized.PDFPageTitle, + LinkType = LinkType.Naskban, + PinterestUrl = $"https://naskban.ir/{unsynchronized.PDFBookId}/{unsynchronized.PageNumber}", + PinterestImageUrl = unsynchronized.ExternalThumbnailImageUrl, + ReviewResult = ReviewResult.Approved, + SuggestionDate = DateTime.Now, + SuggestedById = ganjoorUserId, + Synchronized = true, + ReviewerId = ganjoorUserId, + IsTextOriginalSource = unsynchronized.IsTextOriginalSource, + PDFBookId = unsynchronized.PDFBookId, + PageNumber = unsynchronized.PageNumber, + NaskbanLinkId = unsynchronized.Id + }; + _context.PinterestLinks.Add(link); + } + await secureClient.PutAsync($"https://api.naskban.ir/api/pdf/ganjoor/sync/{unsynchronized.Id}", null); + } + var logoutUrl = $"https://api.naskban.ir/api/users/delsession?userId={loggedOnUser.User.Id}&sessionId={loggedOnUser.SessionId}"; + await secureClient.DeleteAsync(logoutUrl); + return new RServiceResult(unsynchronizeds.Length); + } + } + catch (Exception exp) + { + return new RServiceResult(0, exp.ToString()); + } + } + /// /// aggressive cache ///