From 7e2a263992e2d4495163cc5814bf6f4a580d91ee Mon Sep 17 00:00:00 2001 From: Hamid Reza Mohammadi Date: Sat, 29 Mar 2025 10:14:37 +0330 Subject: [PATCH] #478 user contributions page --- GanjooRazor/Pages/Contribs.cshtml | 144 ++++++++++++++++++++ GanjooRazor/Pages/Contribs.cshtml.cs | 171 ++++++++++++++++++++++++ GanjooRazor/Pages/_FooterPartial.cshtml | 5 + 3 files changed, 320 insertions(+) create mode 100644 GanjooRazor/Pages/Contribs.cshtml create mode 100644 GanjooRazor/Pages/Contribs.cshtml.cs diff --git a/GanjooRazor/Pages/Contribs.cshtml b/GanjooRazor/Pages/Contribs.cshtml new file mode 100644 index 00000000..ebb9e403 --- /dev/null +++ b/GanjooRazor/Pages/Contribs.cshtml @@ -0,0 +1,144 @@ +@page +@model GanjooRazor.Pages.ContribsModel +@{ + Layout = null; +} + + + + + + + گنجور » مشارکت‌های کاربران + + + + + + + + + + + + @if (!string.IsNullOrEmpty(Model.LastError)) + { + @Html.Raw(Model.LastError) + } + else + { +
+

گنجور

+
+
+ + + + @{ + if (Model.Poet != null) + { + + } + } + + +
+
+
+ + + +
+ + + +
+
+

+ گنجور » مشارکت‌های کاربران +

+ +

محتوا

+
+ + + + @Html.Raw(Model.PagingToolsHtml) + +
+ + + + +
+ + + + + @if (!string.IsNullOrEmpty(ViewData["GoogleAnalyticsCode"].ToString())) + { + + + + } + } + + + + + + + diff --git a/GanjooRazor/Pages/Contribs.cshtml.cs b/GanjooRazor/Pages/Contribs.cshtml.cs new file mode 100644 index 00000000..51941167 --- /dev/null +++ b/GanjooRazor/Pages/Contribs.cshtml.cs @@ -0,0 +1,171 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Caching.Memory; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json; +using RMuseum.Models.Ganjoor.ViewModels; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using DNTPersianUtils.Core; +using RMuseum.Models.Auth.ViewModel; +using RMuseum.Services.Implementation; +using RSecurityBackend.Models.Auth.Memory; +using RSecurityBackend.Models.Generic; +using static Microsoft.EntityFrameworkCore.DbLoggerCategory; +using static System.Runtime.InteropServices.JavaScript.JSType; +using System.Linq; +using System.Net.Http.Headers; +using System.Net; +using System.Xml.Linq; +using System; + +namespace GanjooRazor.Pages +{ + [IgnoreAntiforgeryToken(Order = 1001)] + public class ContribsModel : LoginPartialEnabledPageModel + { + public List Poets { get; set; } + public int PoetId { get; set; } + public GanjoorPoetCompleteViewModel Poet { get; set; } + public string PagingToolsHtml { get; set; } + public string LastError { get; set; } + + /// + /// aggressive cache + /// + public bool AggressiveCacheEnabled + { + get + { + try + { + return bool.Parse(Configuration["AggressiveCacheEnabled"]); + } + catch + { + return false; + } + } + } + + + + 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); + } + } + + 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); + } + } + + 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); + } + } + return new OkObjectResult(poet); + } + + public async Task OnGetAsync() + { + if (bool.Parse(Configuration["MaintenanceMode"])) + { + return StatusCode(503); + } + + LoggedIn = !string.IsNullOrEmpty(Request.Cookies["Token"]); + + PoetId = string.IsNullOrEmpty(Request.Query["a"]) ? 0 : int.Parse(Request.Query["a"]); + + ViewData["GoogleAnalyticsCode"] = Configuration["GoogleAnalyticsCode"]; + + //todo: use html master layout or make it partial + // 1. poets + if (false == (await preparePoets())) + return Page(); + + if (PoetId != 0) + { + if (false == (await preparePoet())) + return Page(); + } + + + + return Page(); + } + + /// + /// memory cache + /// + private readonly IMemoryCache _memoryCache; + + /// + /// configration file reader (appsettings.json) + /// + private readonly IConfiguration Configuration; + + /// + /// constructor + /// + /// + /// + /// + public ContribsModel(HttpClient httpClient, IMemoryCache memoryCache, IConfiguration configuration) : base(httpClient) + { + _memoryCache = memoryCache; + Configuration + = configuration; + } + } +} diff --git a/GanjooRazor/Pages/_FooterPartial.cshtml b/GanjooRazor/Pages/_FooterPartial.cshtml index c6e1e57e..8dc0ee27 100644 --- a/GanjooRazor/Pages/_FooterPartial.cshtml +++ b/GanjooRazor/Pages/_FooterPartial.cshtml @@ -122,6 +122,11 @@ پرسش‌های متداول +
  • + + مشارکت‌ها + +
  • حمایت مالی