refactoring

This commit is contained in:
Hamid Reza Mohammadi 2026-07-15 13:52:28 +03:30
parent 64ab66aacd
commit 35bf4c1bc2
5 changed files with 275 additions and 561 deletions

View File

@ -3,11 +3,10 @@ using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using DNTPersianUtils.Core;
using GanjooRazor.Utils;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@ -17,27 +16,19 @@ using RMuseum.Services.Implementation;
using RSecurityBackend.Models.Auth.Memory;
using RSecurityBackend.Models.Generic;
namespace GanjooRazor.Pages
{
[IgnoreAntiforgeryToken(Order = 1001)]
public class HashiehaModel : LoginPartialEnabledPageModel
{
/// <summary>
/// memory cache
/// </summary>
private readonly IMemoryCache _memoryCache;
private readonly PoetCacheService _poetCache;
/// <summary>
/// constructor
/// </summary>
/// <param name="httpClient"></param>
/// <param name="memoryCache"></param>
/// <param name="configuration"></param>
public HashiehaModel(HttpClient httpClient, IMemoryCache memoryCache, IConfiguration configuration) : base(httpClient, configuration)
public HashiehaModel(HttpClient httpClient, IConfiguration configuration, PoetCacheService poetCache) : base(httpClient, configuration)
{
_memoryCache = memoryCache;
_poetCache = poetCache;
}
public List<GanjoorPoetViewModel> Poets { get; set; }
@ -46,71 +37,18 @@ namespace GanjooRazor.Pages
public string PagingToolsHtml { get; set; }
public string LastError { get; set; }
private async Task<bool> preparePoets()
{
var cacheKey = $"/api/ganjoor/poets";
if (!_memoryCache.TryGetValue(cacheKey, out List<GanjoorPoetViewModel> poets))
{
var response = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poets");
if (!response.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
return false;
}
poets = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject<List<GanjoorPoetViewModel>>();
if (AggressiveCacheEnabled)
{
_memoryCache.Set(cacheKey, poets, TimeSpan.FromHours(1));
}
}
Poets = poets;
return true;
}
private async Task<bool> preparePoet()
{
var cacheKey = $"/api/ganjoor/poet/{PoetId}";
if (!_memoryCache.TryGetValue(cacheKey, out GanjoorPoetCompleteViewModel poet))
{
var poetResponse = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poet/{PoetId}");
if (!poetResponse.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await poetResponse.Content.ReadAsStringAsync());
return false;
}
poet = JObject.Parse(await poetResponse.Content.ReadAsStringAsync()).ToObject<GanjoorPoetCompleteViewModel>();
if (AggressiveCacheEnabled)
{
_memoryCache.Set(cacheKey, poet, TimeSpan.FromHours(1));
}
}
Poet = poet;
return true;
}
public List<GanjoorCommentFullViewModel> Comments { get; set; }
public async Task<IActionResult> OnGetPoetInformationAsync(int id)
{
if (id == 0)
return new OkObjectResult(null);
var cacheKey = $"/api/ganjoor/poet/{id}";
if (!_memoryCache.TryGetValue(cacheKey, out GanjoorPoetCompleteViewModel poet))
{
var poetResponse = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poet/{id}");
if (!poetResponse.IsSuccessStatusCode)
{
return BadRequest(JsonConvert.DeserializeObject<string>(await poetResponse.Content.ReadAsStringAsync()));
}
poet = JObject.Parse(await poetResponse.Content.ReadAsStringAsync()).ToObject<GanjoorPoetCompleteViewModel>();
if (AggressiveCacheEnabled)
{
_memoryCache.Set(cacheKey, poet, TimeSpan.FromHours(1));
}
return new OkObjectResult(null);
}
var (success, poet, error) = await _poetCache.GetPoetAsync(id, AggressiveCacheEnabled);
if (!success)
{
return BadRequest(error);
}
return new OkObjectResult(poet);
}
@ -129,26 +67,35 @@ namespace GanjooRazor.Pages
public async Task<IActionResult> OnGetAsync()
{
if (bool.Parse(Configuration["MaintenanceMode"]))
var maintenanceResult = TryGetMaintenanceModeResult();
if (maintenanceResult != null)
{
return StatusCode(503);
return maintenanceResult;
}
LoggedIn = !string.IsNullOrEmpty(Request.Cookies["Token"]);
InitializeCommonPageState();
PoetId = string.IsNullOrEmpty(Request.Query["a"]) ? 0 : int.Parse(Request.Query["a"]);
ViewData["TrackingScript"] = Configuration["TrackingScript"] != null && string.IsNullOrEmpty(Request.Cookies["Token"]) ? Configuration["TrackingScript"].Replace("loggedon", "") : Configuration["TrackingScript"];
//todo: use html master layout or make it partial
// 1. poets
if (false == (await preparePoets()))
var (poetsOk, poets, poetsError) = await _poetCache.GetPoetsAsync(AggressiveCacheEnabled);
if (!poetsOk)
{
LastError = poetsError;
return Page();
}
Poets = poets;
if (PoetId != 0)
{
if (false == (await preparePoet()))
var (poetOk, poet, poetError) = await _poetCache.GetPoetAsync(PoetId, AggressiveCacheEnabled);
if (!poetOk)
{
LastError = poetError;
return Page();
}
Poet = poet;
}
// 2. search comments
@ -170,7 +117,7 @@ namespace GanjooRazor.Pages
var responseUserProfile = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/user/profile/{filterUserId}");
if (!responseUserProfile.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await responseUserProfile.Content.ReadAsStringAsync());
LastError = await ReadErrorMessageAsync(responseUserProfile);
return Page();
}
@ -180,7 +127,7 @@ namespace GanjooRazor.Pages
var responseContributions = await _httpClient.GetAsync($"{APIRoot.Url}/api/contributions/{filterUserId}");
if (!responseContributions.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await responseContributions.Content.ReadAsStringAsync());
LastError = await ReadErrorMessageAsync(responseContributions);
return Page();
}
@ -194,31 +141,19 @@ namespace GanjooRazor.Pages
if (!string.IsNullOrEmpty(Request.Cookies["Token"]))
{
using (HttpClient secureClient = new HttpClient())
{
secureClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Request.Cookies["Token"]);
var res = await secureClient.GetAsync($"{APIRoot.Url}/api/users/securableitems");
if (res.IsSuccessStatusCode)
{
SecurableItem[] secuarbleItems = JsonConvert.DeserializeObject<SecurableItem[]>(await res.Content.ReadAsStringAsync());
var userSecurableItem = secuarbleItems.Where(s => s.ShortName == SecurableItem.UserEntityShortName).FirstOrDefault();
if (userSecurableItem != null)
{
var administerOperation = userSecurableItem.Operations.Where(o => o.ShortName == SecurableItem.Administer).FirstOrDefault();
if (administerOperation != null)
{
CanAdministerUsers = administerOperation.Status;
}
}
}
}
// Was previously a hand-rolled HttpClient with the Bearer token set directly from
// the cookie, manually searching /api/users/securableitems for a matching
// securable + operation. GanjoorSessionChecker.IsPermitted already does exactly
// this and (unlike the hand-rolled version) goes through PrepareClient's session
// renewal, so it also correctly handles a token that needs refreshing.
CanAdministerUsers = await GanjoorSessionChecker.IsPermitted(Request, Response, SecurableItem.UserEntityShortName, SecurableItem.Administer);
}
url += $"&filterUserId={filterUserId}";
}
if(!string.IsNullOrEmpty(Query))
if (!string.IsNullOrEmpty(Query))
{
Query = Query.ApplyCorrectYeKe().Trim();
bool quotes = Query.IndexOf("\"") != -1;
@ -232,7 +167,7 @@ namespace GanjooRazor.Pages
var response = await _httpClient.GetAsync(url);
if (!response.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
LastError = await ReadErrorMessageAsync(response);
return Page();
}
@ -253,7 +188,7 @@ namespace GanjooRazor.Pages
htmlText = $"<div>{Environment.NewLine}";
string queryFilterUserId = string.IsNullOrEmpty(filterUserId) ? "" : $"&amp;userid={filterUserId}";
if (!string.IsNullOrEmpty(Query))
{
{
queryFilterUserId += $"&amp;w={WebUtility.UrlEncode(Query)}";
}
if (paginationMetadata.currentPage > 3)

View File

@ -1,8 +1,6 @@
using GanjooRazor.Models;
using GanjooRazor.Utils;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@ -10,7 +8,6 @@ using RMuseum.Models.Auth.Memory;
using RMuseum.Models.Ganjoor.ViewModels;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
@ -37,12 +34,15 @@ namespace GanjooRazor.Pages
public bool ModeratePoetPhotos { get; set; }
// Kept local rather than PoetCacheService: unlike every other page that fetches the poet
// list, this one prefixes each poet's ImageUrl with APIRoot.InternetUrl before use, which
// the shared service intentionally doesn't do (no other caller needed it).
private async Task<List<GanjoorPoetViewModel>> _PreparePoets()
{
var response = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poets");
if (!response.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
LastError = await ReadErrorMessageAsync(response);
return new List<GanjoorPoetViewModel>();
}
var poets = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject<List<GanjoorPoetViewModel>>();
@ -56,21 +56,20 @@ namespace GanjooRazor.Pages
}
public async Task<IActionResult> OnGetAsync()
{
if (bool.Parse(Configuration["MaintenanceMode"]))
var maintenanceResult = TryGetMaintenanceModeResult();
if (maintenanceResult != null)
{
return StatusCode(503);
return maintenanceResult;
}
LoggedIn = !string.IsNullOrEmpty(Request.Cookies["Token"]);
InitializeCommonPageState();
if (!string.IsNullOrEmpty(Request.Query["p"]))
{
var response = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poet?url=/{Request.Query["p"]}");
if (!response.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
LastError = await ReadErrorMessageAsync(response);
return Page();
}
Poet = JObject.Parse(await response.Content.ReadAsStringAsync()).ToObject<GanjoorPoetCompleteViewModel>().Poet;
@ -79,7 +78,7 @@ namespace GanjooRazor.Pages
var responseLines = await _httpClient.GetAsync($"{APIRoot.Url}/api/poetspecs/poet/{Poet.Id}");
if (!responseLines.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await responseLines.Content.ReadAsStringAsync());
LastError = await ReadErrorMessageAsync(responseLines);
return Page();
}
SpecLines = JArray.Parse(await responseLines.Content.ReadAsStringAsync()).ToObject<List<GanjoorPoetSuggestedSpecLineViewModel>>();
@ -87,7 +86,7 @@ namespace GanjooRazor.Pages
var responsePhotos = await _httpClient.GetAsync($"{APIRoot.Url}/api/poetphotos/poet/{Poet.Id}");
if (!responsePhotos.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await responsePhotos.Content.ReadAsStringAsync());
LastError = await ReadErrorMessageAsync(responsePhotos);
return Page();
}
Photos = JArray.Parse(await responsePhotos.Content.ReadAsStringAsync()).ToObject<List<GanjoorPoetSuggestedPictureViewModel>>();
@ -114,68 +113,50 @@ namespace GanjooRazor.Pages
return Page();
}
public async Task<ActionResult> OnPostSuggestAsync(int poetId, string contents)
private IActionResult SpecLineErrorPartial(string error)
{
string error = "";
if (string.IsNullOrEmpty(contents))
error = "متن خالی است.";
else
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
var response = await secureClient.PostAsync($"{APIRoot.Url}/api/poetspecs",
new StringContent(
JsonConvert.SerializeObject
(
new GanjoorPoetSuggestedSpecLineViewModel()
{
PoetId = poetId,
Contents = contents,
}
),
Encoding.UTF8, "application/json")
);
if (response.StatusCode == HttpStatusCode.OK)
{
var line = JsonConvert.DeserializeObject<GanjoorPoetSuggestedSpecLineViewModel>(await response.Content.ReadAsStringAsync());
return new PartialViewResult()
{
ViewName = "_PoetSpecLinePartial",
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
{
Model = new _PoetSpecLinePartialModel()
{
Line = line
}
}
};
}
else
{
error = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
}
}
else
{
error = "لطفاً از گنجور خارج و مجددا به آن وارد شوید.";
}
}
return new PartialViewResult()
return Partial("_PoetSpecLinePartial", new _PoetSpecLinePartialModel()
{
ViewName = "_PoetSpecLinePartial",
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
Line = new GanjoorPoetSuggestedSpecLineViewModel()
{
Model = new _PoetSpecLinePartialModel()
{
Line = new GanjoorPoetSuggestedSpecLineViewModel()
{
Id = 0,
Contents = error
}
}
Id = 0,
Contents = error
}
};
});
}
public Task<IActionResult> OnPostSuggestAsync(int poetId, string contents)
{
if (string.IsNullOrEmpty(contents))
{
return Task.FromResult(SpecLineErrorPartial("متن خالی است."));
}
return WithSecureClientAsync(async secureClient =>
{
var response = await secureClient.PostAsync($"{APIRoot.Url}/api/poetspecs",
new StringContent(
JsonConvert.SerializeObject
(
new GanjoorPoetSuggestedSpecLineViewModel()
{
PoetId = poetId,
Contents = contents,
}
),
Encoding.UTF8, "application/json")
);
if (response.IsSuccessStatusCode)
{
var line = JsonConvert.DeserializeObject<GanjoorPoetSuggestedSpecLineViewModel>(await response.Content.ReadAsStringAsync());
return Partial("_PoetSpecLinePartial", new _PoetSpecLinePartialModel()
{
Line = line
});
}
return SpecLineErrorPartial(await ReadErrorMessageAsync(response));
}, SpecLineErrorPartial(NotLoggedInMessage));
}
public async Task<IActionResult> OnPostAsync(PoetPhotoSuggestionUploadModel Upload)
@ -189,6 +170,9 @@ namespace GanjooRazor.Pages
if (Upload.Image == null)
LastError = "تصویر انتخاب نشده است.";
else
// Kept as its own using/PrepareClient block rather than WithSecureClientAsync: this
// handler needs to fall through to OnGetAsync() regardless of outcome (success,
// upload failure, or auth failure), which doesn't fit the early-return helper shape.
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
@ -210,7 +194,7 @@ namespace GanjooRazor.Pages
HttpResponseMessage response = await secureClient.PostAsync($"{APIRoot.Url}/api/poetphotos", form);
if (!response.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
LastError = await ReadErrorMessageAsync(response);
}
else
{
@ -222,7 +206,7 @@ namespace GanjooRazor.Pages
}
else
{
LastError = "لطفاً از گنجور خارج و مجددا به آن وارد شوید.";
LastError = NotLoggedInMessage;
}
}
@ -231,83 +215,55 @@ namespace GanjooRazor.Pages
return await OnGetAsync();
}
public async Task<IActionResult> OnPutChoosePhotoAsync(int id)
public Task<IActionResult> OnPutChoosePhotoAsync(int id)
{
using (HttpClient secureClient = new HttpClient())
return WithSecureClientAsync(async secureClient =>
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
var responsePhoto = await secureClient.GetAsync($"{APIRoot.Url}/api/poetphotos/{id}");
if (!responsePhoto.IsSuccessStatusCode)
{
var responsePhoto = await secureClient.GetAsync($"{APIRoot.Url}/api/poetphotos/{id}");
if (!responsePhoto.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await responsePhoto.Content.ReadAsStringAsync());
return new BadRequestObjectResult(LastError);
}
var photo = JsonConvert.DeserializeObject<GanjoorPoetSuggestedPictureViewModel>(await responsePhoto.Content.ReadAsStringAsync());
photo.ChosenOne = true;
var response = await secureClient.PutAsync($"{APIRoot.Url}/api/poetphotos", new StringContent(JsonConvert.SerializeObject(photo), Encoding.UTF8, "application/json"));
if (response.StatusCode != HttpStatusCode.OK)
{
return new BadRequestObjectResult(JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync()));
}
LastError = await ReadErrorMessageAsync(responsePhoto);
return new BadRequestObjectResult(LastError);
}
else
var photo = JsonConvert.DeserializeObject<GanjoorPoetSuggestedPictureViewModel>(await responsePhoto.Content.ReadAsStringAsync());
photo.ChosenOne = true;
var response = await secureClient.PutAsync($"{APIRoot.Url}/api/poetphotos", new StringContent(JsonConvert.SerializeObject(photo), Encoding.UTF8, "application/json"));
if (!response.IsSuccessStatusCode)
{
return new BadRequestObjectResult("لطفاً از گنجور خارج و مجددا به آن وارد شوید.");
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
}
}
return new OkResult();
return new OkResult();
});
}
public async Task<IActionResult> OnDeleteAsync(int id)
public Task<IActionResult> OnDeleteAsync(int id)
{
using (HttpClient secureClient = new HttpClient())
return WithSecureClientAsync(async secureClient =>
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
var response = await secureClient.DeleteAsync($"{APIRoot.Url}/api/poetphotos/{id}");
if (!response.IsSuccessStatusCode)
{
var response = await secureClient.DeleteAsync($"{APIRoot.Url}/api/poetphotos/{id}");
if (response.StatusCode != HttpStatusCode.OK)
{
return new BadRequestObjectResult(JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync()));
}
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
}
else
{
return new BadRequestObjectResult("لطفاً از گنجور خارج و مجددا به آن وارد شوید.");
}
}
return new OkResult();
return new OkResult();
});
}
public async Task<IActionResult> OnDeleteSpecLineAsync(int id)
public Task<IActionResult> OnDeleteSpecLineAsync(int id)
{
using (HttpClient secureClient = new HttpClient())
return WithSecureClientAsync(async secureClient =>
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
var response = await secureClient.DeleteAsync($"{APIRoot.Url}/api/poetspecs/{id}");
if (!response.IsSuccessStatusCode)
{
var response = await secureClient.DeleteAsync($"{APIRoot.Url}/api/poetspecs/{id}");
if (response.StatusCode != HttpStatusCode.OK)
{
return new BadRequestObjectResult(JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync()));
}
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
}
else
{
return new BadRequestObjectResult("لطفاً از گنجور خارج و مجددا به آن وارد شوید.");
}
}
return new OkResult();
return new OkResult();
});
}
public PhotosModel(HttpClient httpClient, IConfiguration configuration) : base(httpClient, configuration)
{
}
}
}

View File

@ -6,10 +6,8 @@ using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using DNTPersianUtils.Core;
using GanjooRazor.Utils;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@ -22,23 +20,14 @@ namespace GanjooRazor.Pages
[IgnoreAntiforgeryToken(Order = 1001)]
public class SearchModel : LoginPartialEnabledPageModel
{
/// <summary>
/// memory cache
/// </summary>
private readonly IMemoryCache _memoryCache;
private readonly PoetCacheService _poetCache;
/// <summary>
/// constructor
/// </summary>
/// <param name="httpClient"></param>
/// <param name="memoryCache"></param>
/// <param name="configuration"></param>
public SearchModel(HttpClient httpClient, IMemoryCache memoryCache, IConfiguration configuration) : base(httpClient, configuration)
public SearchModel(HttpClient httpClient, IConfiguration configuration, PoetCacheService poetCache) : base(httpClient, configuration)
{
_memoryCache = memoryCache;
_poetCache = poetCache;
}
public List<GanjoorPoetViewModel> Poets { get; set; }
@ -63,67 +52,16 @@ namespace GanjooRazor.Pages
public string LastError { get; set; }
public int[] ExceptPoetId { get; set; }
private async Task<bool> preparePoets()
{
var cacheKey = $"/api/ganjoor/poets";
if (!_memoryCache.TryGetValue(cacheKey, out List<GanjoorPoetViewModel> poets))
{
var response = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poets");
if (!response.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
return false;
}
poets = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject<List<GanjoorPoetViewModel>>();
if (AggressiveCacheEnabled)
{
_memoryCache.Set(cacheKey, poets, TimeSpan.FromHours(1));
}
}
Poets = poets;
return true;
}
private async Task<bool> preparePoet()
{
var cacheKey = $"/api/ganjoor/poet/{PoetId}";
if (!_memoryCache.TryGetValue(cacheKey, out GanjoorPoetCompleteViewModel poet))
{
var poetResponse = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poet/{PoetId}");
if (!poetResponse.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await poetResponse.Content.ReadAsStringAsync());
return false;
}
poet = JObject.Parse(await poetResponse.Content.ReadAsStringAsync()).ToObject<GanjoorPoetCompleteViewModel>();
if (AggressiveCacheEnabled)
{
_memoryCache.Set(cacheKey, poet, TimeSpan.FromHours(1));
}
}
Poet = poet;
return true;
}
public async Task<IActionResult> OnGetPoetInformationAsync(int id)
{
if (id == 0)
return new OkObjectResult(null);
var cacheKey = $"/api/ganjoor/poet/{id}";
if (!_memoryCache.TryGetValue(cacheKey, out GanjoorPoetCompleteViewModel poet))
{
var poetResponse = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poet/{id}");
if (!poetResponse.IsSuccessStatusCode)
{
return BadRequest(JsonConvert.DeserializeObject<string>(await poetResponse.Content.ReadAsStringAsync()));
}
poet = JObject.Parse(await poetResponse.Content.ReadAsStringAsync()).ToObject<GanjoorPoetCompleteViewModel>();
if (AggressiveCacheEnabled)
{
_memoryCache.Set(cacheKey, poet, TimeSpan.FromHours(1));
}
return new OkObjectResult(null);
}
var (success, poet, error) = await _poetCache.GetPoetAsync(id, AggressiveCacheEnabled);
if (!success)
{
return BadRequest(error);
}
return new OkObjectResult(poet);
}
@ -148,12 +86,13 @@ namespace GanjooRazor.Pages
public async Task<IActionResult> OnGetAsync()
{
if (bool.Parse(Configuration["MaintenanceMode"]))
var maintenanceResult = TryGetMaintenanceModeResult();
if (maintenanceResult != null)
{
return StatusCode(503);
return maintenanceResult;
}
LoggedIn = !string.IsNullOrEmpty(Request.Cookies["Token"]);
InitializeCommonPageState();
Query = Request.Query["s"].ApplyCorrectYeKe().Trim();
ExactSearch = Request.Query["es"] == "1";
@ -196,7 +135,7 @@ namespace GanjooRazor.Pages
var catResponse = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/cat/{CatId}?poems=false&mainSections=false");
if (!catResponse.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await catResponse.Content.ReadAsStringAsync());
LastError = await ReadErrorMessageAsync(catResponse);
return Page();
}
else
@ -220,12 +159,15 @@ namespace GanjooRazor.Pages
StatsAtTop = !string.IsNullOrEmpty(Request.Query["stats"]);
ViewData["TrackingScript"] = Configuration["TrackingScript"] != null && string.IsNullOrEmpty(Request.Cookies["Token"]) ? Configuration["TrackingScript"].Replace("loggedon", "") : Configuration["TrackingScript"];
//todo: use html master layout or make it partial
// 1. poets
if (false == (await preparePoets()))
var (poetsOk, poets, poetsError) = await _poetCache.GetPoetsAsync(AggressiveCacheEnabled);
if (!poetsOk)
{
LastError = poetsError;
return Page();
}
Poets = poets;
var poetName = Poets.SingleOrDefault(p => p.Id == PoetId);
if (poetName != null)
@ -254,8 +196,13 @@ namespace GanjooRazor.Pages
if (PoetId != 0)
{
if (false == (await preparePoet()))
var (poetOk, poet, poetError) = await _poetCache.GetPoetAsync(PoetId, AggressiveCacheEnabled);
if (!poetOk)
{
LastError = poetError;
return Page();
}
Poet = poet;
}
// 2. search verses
@ -293,7 +240,7 @@ namespace GanjooRazor.Pages
if (!searchQueryResponse.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await searchQueryResponse.Content.ReadAsStringAsync());
LastError = await ReadErrorMessageAsync(searchQueryResponse);
return Page();
}
@ -436,7 +383,7 @@ namespace GanjooRazor.Pages
return htmlText;
}
public async Task<ActionResult> OnGetWordCountsByPoetAsync(string term, int poetId, int catId, bool blur)
public async Task<IActionResult> OnGetWordCountsByPoetAsync(string term, int poetId, int catId, bool blur)
{
if (term == null) return new BadRequestObjectResult("term is null");
term = term.Replace("\"", "");
@ -449,7 +396,7 @@ namespace GanjooRazor.Pages
if (term == null) return new BadRequestObjectResult("term is empty");
}
string url = $"{APIRoot.Url}/api/ganjoor/wordcounts/bycat?term={term}";
if(poetId != 0)
if (poetId != 0)
{
url += $"&poetId={poetId}";
}
@ -462,26 +409,19 @@ namespace GanjooRazor.Pages
if (!wordCountsResponse.IsSuccessStatusCode)
{
return new BadRequestObjectResult(JsonConvert.DeserializeObject<string>(await wordCountsResponse.Content.ReadAsStringAsync()));
return new BadRequestObjectResult(await ReadErrorMessageAsync(wordCountsResponse));
}
var wordCounts = JsonConvert.DeserializeObject<PoetOrCatWordStat[]>(await wordCountsResponse.Content.ReadAsStringAsync());
string countStr = wordCountsResponse.Headers.GetValues("items-count").FirstOrDefault();
return new PartialViewResult()
return Partial("_CategoryWordsCountByCatPartial", new _CategoryWordsCountByCatPartialModel()
{
ViewName = "_CategoryWordsCountByCatPartial",
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
{
Model = new _CategoryWordsCountByCatPartialModel()
{
Term = term,
WordStats = wordCounts,
Whole = catId == 0 && poetId == 0,
TotalCount = string.IsNullOrEmpty(countStr) ? 0 : int.Parse(countStr),
Blur = blur,
}
}
};
Term = term,
WordStats = wordCounts,
Whole = catId == 0 && poetId == 0,
TotalCount = string.IsNullOrEmpty(countStr) ? 0 : int.Parse(countStr),
Blur = blur,
});
}
}

View File

@ -7,7 +7,6 @@ using System.Threading.Tasks;
using DNTPersianUtils.Core;
using GanjooRazor.Utils;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@ -17,28 +16,19 @@ using RMuseum.Services.Implementation;
using RMuseum.Utils;
using RSecurityBackend.Models.Generic;
namespace GanjooRazor.Pages
{
[IgnoreAntiforgeryToken(Order = 1001)]
public class SimiModel : LoginPartialEnabledPageModel
{
/// <summary>
/// memory cache
/// </summary>
private readonly IMemoryCache _memoryCache;
private readonly PoetCacheService _poetCache;
/// <summary>
/// constructor
/// </summary>
/// <param name="httpClient"></param>
/// <param name="memoryCache"></param>
/// <param name="configuration"></param>
public SimiModel(HttpClient httpClient, IMemoryCache memoryCache, IConfiguration configuration) : base(httpClient, configuration)
public SimiModel(HttpClient httpClient, IConfiguration configuration, PoetCacheService poetCache) : base(httpClient, configuration)
{
_memoryCache = memoryCache;
_poetCache = poetCache;
}
public List<GanjoorPoetViewModel> Poets { get; set; }
@ -71,58 +61,12 @@ namespace GanjooRazor.Pages
/// </summary>
public bool CanEdit { get; set; }
private async Task<bool> preparePoets()
{
var cacheKey = $"/api/ganjoor/poets";
if (!_memoryCache.TryGetValue(cacheKey, out List<GanjoorPoetViewModel> poets))
{
var response = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poets");
if (!response.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
return false;
}
poets = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject<List<GanjoorPoetViewModel>>();
if (AggressiveCacheEnabled)
{
_memoryCache.Set(cacheKey, poets, TimeSpan.FromHours(1));
}
}
Poets = poets;
await ReadLanguagesAsync();
return true;
}
private async Task<bool> preparePoet()
{
var cacheKey = $"/api/ganjoor/poet/{PoetId}";
if (!_memoryCache.TryGetValue(cacheKey, out GanjoorPoetCompleteViewModel poet))
{
var poetResponse = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poet/{PoetId}");
if (!poetResponse.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await poetResponse.Content.ReadAsStringAsync());
return false;
}
poet = JObject.Parse(await poetResponse.Content.ReadAsStringAsync()).ToObject<GanjoorPoetCompleteViewModel>();
if (AggressiveCacheEnabled)
{
_memoryCache.Set(cacheKey, poet, TimeSpan.FromHours(1));
}
}
Poet = poet;
return true;
}
private async Task ReadLanguagesAsync()
{
HttpResponseMessage response = await _httpClient.GetAsync($"{APIRoot.Url}/api/translations/languages");
if (!response.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
LastError = await ReadErrorMessageAsync(response);
return;
}
@ -142,39 +86,33 @@ namespace GanjooRazor.Pages
public async Task<IActionResult> OnGetPoetInformationAsync(int id)
{
if (id == 0)
return new OkObjectResult(null);
var cacheKey = $"/api/ganjoor/poet/{id}";
if (!_memoryCache.TryGetValue(cacheKey, out GanjoorPoetCompleteViewModel poet))
{
var poetResponse = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poet/{id}");
if (!poetResponse.IsSuccessStatusCode)
{
return BadRequest(JsonConvert.DeserializeObject<string>(await poetResponse.Content.ReadAsStringAsync()));
}
poet = JObject.Parse(await poetResponse.Content.ReadAsStringAsync()).ToObject<GanjoorPoetCompleteViewModel>();
if (AggressiveCacheEnabled)
{
_memoryCache.Set(cacheKey, poet, TimeSpan.FromHours(1));
}
return new OkObjectResult(null);
}
var (success, poet, error) = await _poetCache.GetPoetAsync(id, AggressiveCacheEnabled);
if (!success)
{
return BadRequest(error);
}
return new OkObjectResult(poet);
}
public async Task<IActionResult> OnGetAsync()
{
if (bool.Parse(Configuration["MaintenanceMode"]))
var maintenanceResult = TryGetMaintenanceModeResult();
if (maintenanceResult != null)
{
return StatusCode(503);
return maintenanceResult;
}
bool anyParamsGiven = false;
LoggedIn = !string.IsNullOrEmpty(Request.Cookies["Token"]);
InitializeCommonPageState();
CanEdit = Request.Cookies["CanEdit"] == "True";
PoetId = string.IsNullOrEmpty(Request.Query["a"]) ? 0 : int.Parse(Request.Query["a"]);
CatId = string.IsNullOrEmpty(Request.Query["c"]) ? 0 : int.Parse(Request.Query["c"]);
anyParamsGiven |= PoetId != 0;
@ -189,7 +127,7 @@ namespace GanjooRazor.Pages
anyParamsGiven |= f != null;
Format = GanjoorPoemFormat.Unknown;
if(f != null)
if (f != null)
{
Format = (GanjoorPoemFormat)int.Parse(f);
}
@ -203,28 +141,36 @@ namespace GanjooRazor.Pages
Quoted = quotes && Query.Contains(" ");
ViewData["TrackingScript"] = Configuration["TrackingScript"] != null && string.IsNullOrEmpty(Request.Cookies["Token"]) ? Configuration["TrackingScript"].Replace("loggedon", "") : Configuration["TrackingScript"];
//todo: use html master layout or make it partial
// 1. poets
if (false == (await preparePoets()))
var (poetsOk, poets, poetsError) = await _poetCache.GetPoetsAsync(AggressiveCacheEnabled);
if (!poetsOk)
{
LastError = poetsError;
return Page();
}
Poets = poets;
await ReadLanguagesAsync();
if (PoetId != 0)
{
if (false == (await preparePoet()))
var (poetOk, poet, poetError) = await _poetCache.GetPoetAsync(PoetId, AggressiveCacheEnabled);
if (!poetOk)
{
LastError = poetError;
return Page();
}
Poet = poet;
}
// 2. search verses
var rhythmResponse = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/rhythms?sortOnVerseCount=true");
if (!rhythmResponse.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await rhythmResponse.Content.ReadAsStringAsync());
LastError = await ReadErrorMessageAsync(rhythmResponse);
return Page();
}
@ -269,7 +215,7 @@ namespace GanjooRazor.Pages
CoupletCountsFrom = 0;
if (!string.IsNullOrEmpty(Request.Query["c1"]))
{
if(int.TryParse(Request.Query["c1"], out int i))
if (int.TryParse(Request.Query["c1"], out int i))
{
CoupletCountsFrom = i;
anyParamsGiven = anyParamsGiven || CoupletCountsFrom != 0;
@ -306,14 +252,14 @@ namespace GanjooRazor.Pages
title += $"{poetInfo.Nickname} ";
}
}
if(!string.IsNullOrEmpty(Metre))
if (!string.IsNullOrEmpty(Metre))
{
title += $"با وزن «{Metre}»";
}
if(!string.IsNullOrEmpty(Rhyme))
if (!string.IsNullOrEmpty(Rhyme))
{
if(!string.IsNullOrEmpty(Metre))
if (!string.IsNullOrEmpty(Metre))
{
title += $" و";
}
@ -325,7 +271,7 @@ namespace GanjooRazor.Pages
}
if(Language != "fa-IR")
if (Language != "fa-IR")
{
var langModel = Languages.Where(l => l.Code == Language).FirstOrDefault();
if (langModel != null)
@ -334,7 +280,7 @@ namespace GanjooRazor.Pages
}
}
if(Format != GanjoorPoemFormat.Unknown)
if (Format != GanjoorPoemFormat.Unknown)
{
title += $" در قالب شعری «{GanjoorPoemFormatConvertor.GetString(Format)}»";
}
@ -354,7 +300,7 @@ namespace GanjooRazor.Pages
var catResponse = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/cat/{CatId}?poems=false&mainSections=false");
if (!catResponse.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await catResponse.Content.ReadAsStringAsync());
LastError = await ReadErrorMessageAsync(catResponse);
return Page();
}
else
@ -362,7 +308,7 @@ namespace GanjooRazor.Pages
var cat = JObject.Parse(await catResponse.Content.ReadAsStringAsync()).ToObject<GanjoorPoetCompleteViewModel>();
CatFullUrl = cat.Cat.FullUrl;
CatFullTitle = "";
foreach (var parentCat in cat.Cat.Ancestors)
foreach (var parentCat in cat.Cat.Ancestors)
{
CatFullTitle += parentCat.Title;
CatFullTitle += " »";
@ -392,7 +338,7 @@ namespace GanjooRazor.Pages
string url = $"{APIRoot.Url}/api/ganjoor/poems/similar?PageNumber={pageNumber}&PageSize=20&metre={Metre}&rhyme={Rhyme}&poetId={PoetId}&catId={CatId}&language={Language}&format={(int)Format}&coupletCountsFrom={CoupletCountsFrom}&coupletCountsTo={CoupletCountsTo}";
if(!string.IsNullOrEmpty(Query))
if (!string.IsNullOrEmpty(Query))
{
url += $"&term={Query}";
}
@ -407,7 +353,7 @@ namespace GanjooRazor.Pages
if (!response.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
LastError = await ReadErrorMessageAsync(response);
return Page();
}
@ -426,7 +372,7 @@ namespace GanjooRazor.Pages
{
htmlText = $"<div>{Environment.NewLine}";
string authorParam = PoetId != 0 ? $"&amp;a={PoetId}" : "";
if(authorParam != "" && CatId != 0)
if (authorParam != "" && CatId != 0)
{
authorParam += $"&amp;c={CatId}";
}
@ -463,64 +409,55 @@ namespace GanjooRazor.Pages
}
public string HtmlText { get; set; }
public async Task<IActionResult> OnPostSendSectionMetreSuggestionAsync(int poemId, int sectionIndex, string rhythm)
public Task<IActionResult> OnPostSendSectionMetreSuggestionAsync(int poemId, int sectionIndex, string rhythm)
{
using (HttpClient secureClient = new HttpClient())
return WithSecureClientAsync(async secureClient =>
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
if (rhythm == "null")
rhythm = "";
if (string.IsNullOrEmpty(rhythm))
{
if (rhythm == "null")
rhythm = "";
if(string.IsNullOrEmpty(rhythm))
{
return new BadRequestObjectResult("وزن انتخاب نشده");
}
var sectionResponse = await secureClient.GetAsync($"{APIRoot.Url}/api/ganjoor/sections/{poemId}");
if (!sectionResponse.IsSuccessStatusCode)
{
return new BadRequestObjectResult(JsonConvert.DeserializeObject<string>(await sectionResponse.Content.ReadAsStringAsync()));
}
var sections = JsonConvert.DeserializeObject<GanjoorPoemSection[]>(await sectionResponse.Content.ReadAsStringAsync());
var section = sections.Where(s => s.Index == sectionIndex).Single();
var correctionResponse = await secureClient.GetAsync($"{APIRoot.Url}/api/ganjoor/section/correction/last/{section.Id}");
if (!correctionResponse.IsSuccessStatusCode)
{
return new BadRequestObjectResult(JsonConvert.DeserializeObject<string>(await correctionResponse.Content.ReadAsStringAsync()));
}
if(null != JsonConvert.DeserializeObject<GanjoorPoemSectionCorrectionViewModel>(await correctionResponse.Content.ReadAsStringAsync()))
{
return new BadRequestObjectResult("شما پیشتر پیشنهادی تصحیحی برای این قطع ثبت کرده‌اید.");
}
GanjoorPoemSectionCorrectionViewModel correction = new GanjoorPoemSectionCorrectionViewModel()
{
SectionId = section.Id,
Rhythm = rhythm,
};
HttpResponseMessage response = await secureClient.PostAsync(
$"{APIRoot.Url}/api/ganjoor/section/correction",
new StringContent(JsonConvert.SerializeObject(correction),
Encoding.UTF8,
"application/json"));
if (!response.IsSuccessStatusCode)
{
return new BadRequestObjectResult(JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync()));
}
return new OkObjectResult(true);
return new BadRequestObjectResult("وزن انتخاب نشده");
}
else
var sectionResponse = await secureClient.GetAsync($"{APIRoot.Url}/api/ganjoor/sections/{poemId}");
if (!sectionResponse.IsSuccessStatusCode)
{
return new BadRequestObjectResult("لطفاً از گنجور خارج و مجددا به آن وارد شوید.");
return new BadRequestObjectResult(await ReadErrorMessageAsync(sectionResponse));
}
}
var sections = JsonConvert.DeserializeObject<GanjoorPoemSection[]>(await sectionResponse.Content.ReadAsStringAsync());
var section = sections.Where(s => s.Index == sectionIndex).Single();
var correctionResponse = await secureClient.GetAsync($"{APIRoot.Url}/api/ganjoor/section/correction/last/{section.Id}");
if (!correctionResponse.IsSuccessStatusCode)
{
return new BadRequestObjectResult(await ReadErrorMessageAsync(correctionResponse));
}
if (null != JsonConvert.DeserializeObject<GanjoorPoemSectionCorrectionViewModel>(await correctionResponse.Content.ReadAsStringAsync()))
{
return new BadRequestObjectResult("شما پیشتر پیشنهادی تصحیحی برای این قطع ثبت کرده‌اید.");
}
GanjoorPoemSectionCorrectionViewModel correction = new GanjoorPoemSectionCorrectionViewModel()
{
SectionId = section.Id,
Rhythm = rhythm,
};
HttpResponseMessage response = await secureClient.PostAsync(
$"{APIRoot.Url}/api/ganjoor/section/correction",
new StringContent(JsonConvert.SerializeObject(correction),
Encoding.UTF8,
"application/json"));
if (!response.IsSuccessStatusCode)
{
return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
}
return new OkObjectResult(true);
});
}
}

View File

@ -1,7 +1,6 @@
using DNTPersianUtils.Core;
using GanjooRazor.Utils;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
@ -20,25 +19,16 @@ namespace GanjooRazor.Pages
[IgnoreAntiforgeryToken(Order = 1001)]
public class TaggedModel : LoginPartialEnabledPageModel
{
/// <summary>
/// memory cache
/// </summary>
private readonly IMemoryCache _memoryCache;
private readonly PoetCacheService _poetCache;
/// <summary>
/// constructor
/// </summary>
/// <param name="httpClient"></param>
/// <param name="memoryCache"></param>
/// <param name="configuration"></param>
public TaggedModel(HttpClient httpClient, IMemoryCache memoryCache, IConfiguration configuration) : base(httpClient, configuration)
public TaggedModel(HttpClient httpClient, IConfiguration configuration, PoetCacheService poetCache) : base(httpClient, configuration)
{
_memoryCache = memoryCache;
_poetCache = poetCache;
}
public List<GanjoorPoetViewModel> Poets { get; set; }
public int PoetId { get; set; }
public GanjoorPoetCompleteViewModel Poet { get; set; }
@ -54,103 +44,59 @@ namespace GanjooRazor.Pages
HttpResponseMessage response = await _httpClient.GetAsync($"{APIRoot.Url}/api/translations/languages");
if (!response.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
LastError = await ReadErrorMessageAsync(response);
return;
}
Languages = JsonConvert.DeserializeObject<GanjoorLanguage[]>(await response.Content.ReadAsStringAsync());
}
private async Task<bool> preparePoets()
{
var cacheKey = $"/api/ganjoor/poets";
if (!_memoryCache.TryGetValue(cacheKey, out List<GanjoorPoetViewModel> poets))
{
var response = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poets");
if (!response.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
return false;
}
poets = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject<List<GanjoorPoetViewModel>>();
if (AggressiveCacheEnabled)
{
_memoryCache.Set(cacheKey, poets, TimeSpan.FromHours(1));
}
}
Poets = poets;
await ReadLanguagesAsync();
return true;
}
private async Task<bool> preparePoet()
{
var cacheKey = $"/api/ganjoor/poet/{PoetId}";
if (!_memoryCache.TryGetValue(cacheKey, out GanjoorPoetCompleteViewModel poet))
{
var poetResponse = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poet/{PoetId}");
if (!poetResponse.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await poetResponse.Content.ReadAsStringAsync());
return false;
}
poet = JObject.Parse(await poetResponse.Content.ReadAsStringAsync()).ToObject<GanjoorPoetCompleteViewModel>();
if (AggressiveCacheEnabled)
{
_memoryCache.Set(cacheKey, poet, TimeSpan.FromHours(1));
}
}
Poet = poet;
return true;
}
public async Task<IActionResult> OnGetPoetInformationAsync(int id)
{
if (id == 0)
return new OkObjectResult(null);
var cacheKey = $"/api/ganjoor/poet/{id}";
if (!_memoryCache.TryGetValue(cacheKey, out GanjoorPoetCompleteViewModel poet))
{
var poetResponse = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poet/{id}");
if (!poetResponse.IsSuccessStatusCode)
{
return BadRequest(JsonConvert.DeserializeObject<string>(await poetResponse.Content.ReadAsStringAsync()));
}
poet = JObject.Parse(await poetResponse.Content.ReadAsStringAsync()).ToObject<GanjoorPoetCompleteViewModel>();
if (AggressiveCacheEnabled)
{
_memoryCache.Set(cacheKey, poet, TimeSpan.FromHours(1));
}
return new OkObjectResult(null);
}
var (success, poet, error) = await _poetCache.GetPoetAsync(id, AggressiveCacheEnabled);
if (!success)
{
return BadRequest(error);
}
return new OkObjectResult(poet);
}
public async Task<IActionResult> OnGetAsync()
{
if (bool.Parse(Configuration["MaintenanceMode"]))
var maintenanceResult = TryGetMaintenanceModeResult();
if (maintenanceResult != null)
{
return StatusCode(503);
return maintenanceResult;
}
LoggedIn = !string.IsNullOrEmpty(Request.Cookies["Token"]);
InitializeCommonPageState();
PoetId = string.IsNullOrEmpty(Request.Query["a"]) ? 0 : int.Parse(Request.Query["a"]);
ViewData["TrackingScript"] = Configuration["TrackingScript"] != null && string.IsNullOrEmpty(Request.Cookies["Token"]) ? Configuration["TrackingScript"].Replace("loggedon", "") : Configuration["TrackingScript"];
//todo: use html master layout or make it partial
// 1. poets
if (false == (await preparePoets()))
var (poetsOk, poets, poetsError) = await _poetCache.GetPoetsAsync(AggressiveCacheEnabled);
if (!poetsOk)
{
LastError = poetsError;
return Page();
}
Poets = poets;
await ReadLanguagesAsync();
if (PoetId != 0)
{
if (false == (await preparePoet()))
var (poetOk, poet, poetError) = await _poetCache.GetPoetAsync(PoetId, AggressiveCacheEnabled);
if (!poetOk)
{
LastError = poetError;
return Page();
}
Poet = poet;
}
// 2. search verses
@ -160,7 +106,7 @@ namespace GanjooRazor.Pages
var rhythmResponse = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/rhythms?sortOnVerseCount=true");
if (!rhythmResponse.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await rhythmResponse.Content.ReadAsStringAsync());
LastError = await ReadErrorMessageAsync(rhythmResponse);
return Page();
}
@ -188,11 +134,11 @@ namespace GanjooRazor.Pages
}
}
var langModel = Languages.Where(l => l.Code == Language).FirstOrDefault();
if(langModel != null)
if (langModel != null)
{
title += $"با زبان غالب «{langModel.Name}»";
}
string url = $"{APIRoot.Url}/api/ganjoor/sections/tagged/language?PageNumber={pageNumber}&PageSize=20&language={Language}&poetId={PoetId}";
@ -200,7 +146,7 @@ namespace GanjooRazor.Pages
if (!response.IsSuccessStatusCode)
{
LastError = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
LastError = await ReadErrorMessageAsync(response);
return Page();
}