{Environment.NewLine}";
string queryFilterUserId = string.IsNullOrEmpty(filterUserId) ? "" : $"&userid={filterUserId}";
if (!string.IsNullOrEmpty(Query))
- {
+ {
queryFilterUserId += $"&w={WebUtility.UrlEncode(Query)}";
}
if (paginationMetadata.currentPage > 3)
diff --git a/GanjooRazor/Pages/Photos.cshtml.cs b/GanjooRazor/Pages/Photos.cshtml.cs
index ab5157cf..1c48705d 100644
--- a/GanjooRazor/Pages/Photos.cshtml.cs
+++ b/GanjooRazor/Pages/Photos.cshtml.cs
@@ -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
> _PreparePoets()
{
var response = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poets");
if (!response.IsSuccessStatusCode)
{
- LastError = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
+ LastError = await ReadErrorMessageAsync(response);
return new List();
}
var poets = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject>();
@@ -56,21 +56,20 @@ namespace GanjooRazor.Pages
}
public async Task 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(await response.Content.ReadAsStringAsync());
+ LastError = await ReadErrorMessageAsync(response);
return Page();
}
Poet = JObject.Parse(await response.Content.ReadAsStringAsync()).ToObject().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(await responseLines.Content.ReadAsStringAsync());
+ LastError = await ReadErrorMessageAsync(responseLines);
return Page();
}
SpecLines = JArray.Parse(await responseLines.Content.ReadAsStringAsync()).ToObject>();
@@ -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(await responsePhotos.Content.ReadAsStringAsync());
+ LastError = await ReadErrorMessageAsync(responsePhotos);
return Page();
}
Photos = JArray.Parse(await responsePhotos.Content.ReadAsStringAsync()).ToObject>();
@@ -114,68 +113,50 @@ namespace GanjooRazor.Pages
return Page();
}
- public async Task 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(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(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 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(await response.Content.ReadAsStringAsync());
+ return Partial("_PoetSpecLinePartial", new _PoetSpecLinePartialModel()
+ {
+ Line = line
+ });
+ }
+
+ return SpecLineErrorPartial(await ReadErrorMessageAsync(response));
+ }, SpecLineErrorPartial(NotLoggedInMessage));
}
public async Task 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(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 OnPutChoosePhotoAsync(int id)
+ public Task 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(await responsePhoto.Content.ReadAsStringAsync());
- return new BadRequestObjectResult(LastError);
- }
- var photo = JsonConvert.DeserializeObject(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(await response.Content.ReadAsStringAsync()));
- }
+ LastError = await ReadErrorMessageAsync(responsePhoto);
+ return new BadRequestObjectResult(LastError);
}
- else
+ var photo = JsonConvert.DeserializeObject(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 OnDeleteAsync(int id)
+ public Task 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(await response.Content.ReadAsStringAsync()));
- }
+ return new BadRequestObjectResult(await ReadErrorMessageAsync(response));
}
- else
- {
- return new BadRequestObjectResult("لطفاً از گنجور خارج و مجددا به آن وارد شوید.");
- }
- }
-
- return new OkResult();
+ return new OkResult();
+ });
}
- public async Task OnDeleteSpecLineAsync(int id)
+ public Task 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(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)
{
-
}
}
}
diff --git a/GanjooRazor/Pages/Search.cshtml.cs b/GanjooRazor/Pages/Search.cshtml.cs
index 6c271b2f..402db382 100644
--- a/GanjooRazor/Pages/Search.cshtml.cs
+++ b/GanjooRazor/Pages/Search.cshtml.cs
@@ -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
{
-
- ///
- /// memory cache
- ///
- private readonly IMemoryCache _memoryCache;
-
-
+ private readonly PoetCacheService _poetCache;
///
/// constructor
///
- ///
- ///
- ///
- 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 Poets { get; set; }
@@ -63,67 +52,16 @@ namespace GanjooRazor.Pages
public string LastError { get; set; }
public int[] ExceptPoetId { get; set; }
- private async Task preparePoets()
- {
- var cacheKey = $"/api/ganjoor/poets";
- if (!_memoryCache.TryGetValue(cacheKey, out List poets))
- {
- var response = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poets");
- if (!response.IsSuccessStatusCode)
- {
- LastError = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
- return false;
- }
- poets = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject>();
- if (AggressiveCacheEnabled)
- {
- _memoryCache.Set(cacheKey, poets, TimeSpan.FromHours(1));
- }
- }
-
- Poets = poets;
- return true;
- }
-
- private async Task 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(await poetResponse.Content.ReadAsStringAsync());
- return false;
- }
- poet = JObject.Parse(await poetResponse.Content.ReadAsStringAsync()).ToObject();
- if (AggressiveCacheEnabled)
- {
- _memoryCache.Set(cacheKey, poet, TimeSpan.FromHours(1));
- }
- }
-
- Poet = poet;
- return true;
- }
-
public async Task 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(await poetResponse.Content.ReadAsStringAsync()));
- }
- poet = JObject.Parse(await poetResponse.Content.ReadAsStringAsync()).ToObject();
- 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 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(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(await searchQueryResponse.Content.ReadAsStringAsync());
+ LastError = await ReadErrorMessageAsync(searchQueryResponse);
return Page();
}
@@ -436,7 +383,7 @@ namespace GanjooRazor.Pages
return htmlText;
}
- public async Task OnGetWordCountsByPoetAsync(string term, int poetId, int catId, bool blur)
+ public async Task 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(await wordCountsResponse.Content.ReadAsStringAsync()));
+ return new BadRequestObjectResult(await ReadErrorMessageAsync(wordCountsResponse));
}
var wordCounts = JsonConvert.DeserializeObject(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,
+ });
}
}
diff --git a/GanjooRazor/Pages/Simi.cshtml.cs b/GanjooRazor/Pages/Simi.cshtml.cs
index ee43819e..839299dc 100644
--- a/GanjooRazor/Pages/Simi.cshtml.cs
+++ b/GanjooRazor/Pages/Simi.cshtml.cs
@@ -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
{
- ///
- /// memory cache
- ///
- private readonly IMemoryCache _memoryCache;
-
-
+ private readonly PoetCacheService _poetCache;
///
/// constructor
///
- ///
- ///
- ///
- 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 Poets { get; set; }
@@ -71,58 +61,12 @@ namespace GanjooRazor.Pages
///
public bool CanEdit { get; set; }
- private async Task preparePoets()
- {
- var cacheKey = $"/api/ganjoor/poets";
- if (!_memoryCache.TryGetValue(cacheKey, out List poets))
- {
- var response = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poets");
- if (!response.IsSuccessStatusCode)
- {
- LastError = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
- return false;
- }
- poets = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject>();
- if (AggressiveCacheEnabled)
- {
- _memoryCache.Set(cacheKey, poets, TimeSpan.FromHours(1));
- }
- }
-
- Poets = poets;
-
- await ReadLanguagesAsync();
- return true;
- }
-
- private async Task 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(await poetResponse.Content.ReadAsStringAsync());
- return false;
- }
- poet = JObject.Parse(await poetResponse.Content.ReadAsStringAsync()).ToObject();
- 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(await response.Content.ReadAsStringAsync());
+ LastError = await ReadErrorMessageAsync(response);
return;
}
@@ -142,39 +86,33 @@ namespace GanjooRazor.Pages
public async Task 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(await poetResponse.Content.ReadAsStringAsync()));
- }
- poet = JObject.Parse(await poetResponse.Content.ReadAsStringAsync()).ToObject();
- 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 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(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(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();
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(await response.Content.ReadAsStringAsync());
+ LastError = await ReadErrorMessageAsync(response);
return Page();
}
@@ -426,7 +372,7 @@ namespace GanjooRazor.Pages
{
htmlText = $"{Environment.NewLine}";
string authorParam = PoetId != 0 ? $"&a={PoetId}" : "";
- if(authorParam != "" && CatId != 0)
+ if (authorParam != "" && CatId != 0)
{
authorParam += $"&c={CatId}";
}
@@ -463,64 +409,55 @@ namespace GanjooRazor.Pages
}
public string HtmlText { get; set; }
- public async Task
OnPostSendSectionMetreSuggestionAsync(int poemId, int sectionIndex, string rhythm)
+ public Task 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(await sectionResponse.Content.ReadAsStringAsync()));
- }
- var sections = JsonConvert.DeserializeObject(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(await correctionResponse.Content.ReadAsStringAsync()));
-
- }
-
- if(null != JsonConvert.DeserializeObject(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(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(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(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);
+ });
}
}
diff --git a/GanjooRazor/Pages/Tagged.cshtml.cs b/GanjooRazor/Pages/Tagged.cshtml.cs
index 6c479d59..ebeb3b92 100644
--- a/GanjooRazor/Pages/Tagged.cshtml.cs
+++ b/GanjooRazor/Pages/Tagged.cshtml.cs
@@ -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
{
- ///
- /// memory cache
- ///
- private readonly IMemoryCache _memoryCache;
-
-
+ private readonly PoetCacheService _poetCache;
///
/// constructor
///
- ///
- ///
- ///
- 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 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(await response.Content.ReadAsStringAsync());
+ LastError = await ReadErrorMessageAsync(response);
return;
}
Languages = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
}
- private async Task preparePoets()
- {
- var cacheKey = $"/api/ganjoor/poets";
- if (!_memoryCache.TryGetValue(cacheKey, out List poets))
- {
- var response = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poets");
- if (!response.IsSuccessStatusCode)
- {
- LastError = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
- return false;
- }
- poets = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject>();
- if (AggressiveCacheEnabled)
- {
- _memoryCache.Set(cacheKey, poets, TimeSpan.FromHours(1));
- }
- }
-
- Poets = poets;
-
- await ReadLanguagesAsync();
- return true;
- }
-
- private async Task 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(await poetResponse.Content.ReadAsStringAsync());
- return false;
- }
- poet = JObject.Parse(await poetResponse.Content.ReadAsStringAsync()).ToObject();
- if (AggressiveCacheEnabled)
- {
- _memoryCache.Set(cacheKey, poet, TimeSpan.FromHours(1));
- }
- }
-
- Poet = poet;
- return true;
- }
-
public async Task 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(await poetResponse.Content.ReadAsStringAsync()));
- }
- poet = JObject.Parse(await poetResponse.Content.ReadAsStringAsync()).ToObject();
- 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 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(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(await response.Content.ReadAsStringAsync());
+ LastError = await ReadErrorMessageAsync(response);
return Page();
}