#404 synching ganjoor/naskban links

This commit is contained in:
Hamid Reza Mohammadi 2023-08-01 12:33:30 +03:30
parent a922d7e3c0
commit bccfc992a5
6 changed files with 159 additions and 6 deletions

View File

@ -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);
}
/// <summary>
/// synchronize https:://naskban.ir links (logs in and then out to naskban.ir using auth info)
/// </summary>
/// <param name="loginViewModel"></param>
/// <returns>number of synched links</returns>
[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<IActionResult> 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);
}

View File

@ -1280,7 +1280,7 @@ namespace RMuseum.Controllers
/// <returns></returns>
[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<IActionResult> GetUnsyncedPDFGanjoorLinksAsync()

View File

@ -129,5 +129,10 @@ namespace RMuseum.Models.GanjoorIntegration
/// page number
/// </summary>
public int PageNumber { get; set; }
/// <summary>
/// naskban link id
/// </summary>
public Guid? NaskbanLinkId { get; set; }
}
}

View File

@ -1991,6 +1991,13 @@
<param name="id"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Controllers.GanjoorController.SynchronizeNaskbanLinksAsync(RSecurityBackend.Models.Auth.ViewModels.LoginViewModel)">
<summary>
synchronize https:://naskban.ir links (logs in and then out to naskban.ir using auth info)
</summary>
<param name="loginViewModel"></param>
<returns>number of synched links</returns>
</member>
<member name="P:RMuseum.Controllers.GanjoorController.ReadOnlyMode">
<summary>
readonly mode
@ -6607,6 +6614,11 @@
page number
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorIntegration.PinterestLink.NaskbanLinkId">
<summary>
naskban link id
</summary>
</member>
<member name="T:RMuseum.Models.GanjoorIntegration.ReviewResult">
<summary>
Review Result
@ -15182,6 +15194,15 @@
<param name="ignoreSumup"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Services.IGanjoorService.SynchronizeNaskbanLinksAsync(System.Guid,System.String,System.String)">
<summary>
synchronize naskban links
</summary>
<param name="ganjoorUserId"></param>
<param name="naskbanUserName"></param>
<param name="naskbanPassword"></param>
<returns>number of synched items</returns>
</member>
<member name="T:RMuseum.Services.IGanjoorTranslationService">
<summary>
translation service implementation
@ -17869,6 +17890,15 @@
<param name="id"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Services.Implementation.GanjoorService.SynchronizeNaskbanLinksAsync(System.Guid,System.String,System.String)">
<summary>
synchronize naskban links
</summary>
<param name="ganjoorUserId"></param>
<param name="naskbanUserName"></param>
<param name="naskbanPassword"></param>
<returns>number of synched items</returns>
</member>
<member name="P:RMuseum.Services.Implementation.GanjoorService.AggressiveCacheEnabled">
<summary>
aggressive cache

View File

@ -1190,5 +1190,15 @@ namespace RMuseum.Services
/// <param name="ignoreSumup"></param>
/// <returns></returns>
Task<RServiceResult<PoemGeoDateTag[]>> GetCatPoemGeoDateTagsAsync(int catId, bool ignoreSumup = false);
/// <summary>
/// synchronize naskban links
/// </summary>
/// <param name="ganjoorUserId"></param>
/// <param name="naskbanUserName"></param>
/// <param name="naskbanPassword"></param>
/// <returns>number of synched items</returns>
Task<RServiceResult<int>> SynchronizeNaskbanLinksAsync(Guid ganjoorUserId, string naskbanUserName, string naskbanPassword);
}
}

View File

@ -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
}
}
/// <summary>
/// synchronize naskban links
/// </summary>
/// <param name="ganjoorUserId"></param>
/// <param name="naskbanUserName"></param>
/// <param name="naskbanPassword"></param>
/// <returns>number of synched items</returns>
public async Task<RServiceResult<int>> 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<int>(0, "login error: " + JsonConvert.DeserializeObject<string>(await loginResponse.Content.ReadAsStringAsync()));
}
LoggedOnUserModelEx loggedOnUser = JsonConvert.DeserializeObject<LoggedOnUserModelEx>(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<int>(0, "unsync error: " + JsonConvert.DeserializeObject<string>(await unsyncedResponse.Content.ReadAsStringAsync()));
}
var unsynchronizeds = JsonConvert.DeserializeObject<PDFGanjoorLink[]>(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<int>(unsynchronizeds.Length);
}
}
catch (Exception exp)
{
return new RServiceResult<int>(0, exp.ToString());
}
}
/// <summary>
/// aggressive cache
/// </summary>