From 647982f36447e30704991bb58aa43154d603b95d Mon Sep 17 00:00:00 2001 From: Hamid Reza Mohammadi Date: Wed, 4 May 2022 16:57:07 +0430 Subject: [PATCH] docs: #315 extracting Hashieha page to make it searchable --- GanjooRazor/Pages/Hashieha.cshtml | 220 +++++++++++++++++++++ GanjooRazor/Pages/Hashieha.cshtml.cs | 278 +++++++++++++++++++++++++++ GanjooRazor/Pages/Index.cshtml.cs | 6 +- 3 files changed, 501 insertions(+), 3 deletions(-) create mode 100644 GanjooRazor/Pages/Hashieha.cshtml create mode 100644 GanjooRazor/Pages/Hashieha.cshtml.cs diff --git a/GanjooRazor/Pages/Hashieha.cshtml b/GanjooRazor/Pages/Hashieha.cshtml new file mode 100644 index 00000000..8270d688 --- /dev/null +++ b/GanjooRazor/Pages/Hashieha.cshtml @@ -0,0 +1,220 @@ +@page +@using DNTPersianUtils.Core; +@model GanjooRazor.Pages.HashiehaModel +@{ + Layout = null; +} + + + + + + + + @ViewData["Title"] + + + + + + + + + + + @if (!string.IsNullOrEmpty(Model.LastError)) + { + @Html.Raw(Model.LastError) + } + else + { +
+

گنجور

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

+ @Model.Title +

+ @if (Model.Profile != null) + { +
+

+ @Model.Profile.NickName + + @if (!string.IsNullOrEmpty(Model.Profile.Website)) + { + 🌐 + } + + @if (Model.CanAdministerUsers) + { + # + } +

+ + @if (!string.IsNullOrEmpty(Model.Profile.Bio)) + { +

+ @Html.Raw(Model.Profile.Bio) +

+ } +
+
+ } + + +
+ +
+
+ @if (Model.Comments.Count == 0) + { +

حاشیه‌ای با مشخصات مورد نظر شما پیدا نشد.

+ } + else + foreach (var comment in Model.Comments) + { +
+

+ @if (comment.UserId == null) + { + @comment.AuthorName + } + else + { + @comment.AuthorName + } + + در @comment.CommentDate.ToFriendlyPersianDateTextify() + @if (comment.InReplyTo != null) + { + + @(" ")در پاسخ به @comment.InReplyTo.AuthorName + + } + + @(" ")دربارهٔ @comment.Poem.Title: +

+ @if (comment.CoupletIndex != -1) + { +
+ @comment.CoupletSummary +
+ } +
+ @Html.Raw(comment.HtmlComment) +
+
 
+
+
+ } +
+ + + + @Html.Raw(Model.PagingToolsHtml) + +
+ + + + + +
+ + + + + + @if (!string.IsNullOrEmpty(ViewData["GoogleAnalyticsCode"].ToString())) + { + + } + } + + + + + + diff --git a/GanjooRazor/Pages/Hashieha.cshtml.cs b/GanjooRazor/Pages/Hashieha.cshtml.cs new file mode 100644 index 00000000..358ec295 --- /dev/null +++ b/GanjooRazor/Pages/Hashieha.cshtml.cs @@ -0,0 +1,278 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using DNTPersianUtils.Core; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Configuration; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using RMuseum.Models.Auth.ViewModel; +using RMuseum.Models.Ganjoor.ViewModels; +using RSecurityBackend.Models.Auth.Memory; +using RSecurityBackend.Models.Generic; + + +namespace GanjooRazor.Pages +{ + [IgnoreAntiforgeryToken(Order = 1001)] + public class HashiehaModel : LoginPartialEnabledPageModel + { + /// + /// memory cache + /// + private readonly IMemoryCache _memoryCache; + + /// + /// configration file reader (appsettings.json) + /// + private readonly IConfiguration Configuration; + + + /// + /// constructor + /// + /// + /// + /// + public HashiehaModel(HttpClient httpClient, IMemoryCache memoryCache, IConfiguration configuration) : base(httpClient) + { + _memoryCache = memoryCache; + Configuration + = configuration; + } + + /// + /// aggressive cache + /// + public bool AggressiveCacheEnabled + { + get + { + try + { + return bool.Parse(Configuration["AggressiveCacheEnabled"]); + } + catch + { + return false; + } + } + } + + 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; } + + 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 List Comments { get; set; } + + 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 GanjoorUserPublicProfile Profile { get; set; } + + public string Title { get; set; } + + public bool CanAdministerUsers { get; set; } + + + public async Task OnGetAsync() + { + 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(); + } + + // 2. search comments + + int pageNumber = 1; + if (!string.IsNullOrEmpty(Request.Query["page"])) + { + pageNumber = int.Parse(Request.Query["page"]); + } + + var filterUserId = Request.Query["userid"]; + string url = $"{APIRoot.Url}/api/ganjoor/comments?PageNumber={pageNumber}&PageSize=20"; + Title = "حاشیه‌ها"; + if (!string.IsNullOrEmpty(filterUserId)) + { + var responseUserProfile = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/user/profile/{filterUserId}"); + if (!responseUserProfile.IsSuccessStatusCode) + { + LastError = JsonConvert.DeserializeObject(await responseUserProfile.Content.ReadAsStringAsync()); + return Page(); + } + + GanjoorUserPublicProfile profile = JsonConvert.DeserializeObject(await responseUserProfile.Content.ReadAsStringAsync()); + + + ViewData["Title"] = $"گنجور » حاشیه‌های {profile.NickName}"; + + Title = $"حاشیه‌های {profile.NickName}"; + + + + 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(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; + } + } + } + } + } + + + + url += $"&filterUserId={filterUserId}"; + + } + + var response = await _httpClient.GetAsync(url); + if (!response.IsSuccessStatusCode) + { + LastError = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); + return Page(); + } + + + Comments = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject>(); + + string paginnationMetadata = response.Headers.GetValues("paging-headers").FirstOrDefault(); + PaginationMetadata paginationMetadata = JsonConvert.DeserializeObject(paginnationMetadata); + + string htmlText = ""; + + if (paginationMetadata.totalPages > 1) + { + Title += $" - صفحهٔ {pageNumber.ToPersianNumbers()}"; + ViewData["Title"] += $" - صفحهٔ {pageNumber.ToPersianNumbers()}"; + + + htmlText = $"
{Environment.NewLine}"; + string queryFilterUserId = string.IsNullOrEmpty(filterUserId) ? "" : $"&userid={filterUserId}"; + if (paginationMetadata.currentPage > 3) + { + htmlText += $"
۱
…"; + } + for (int i = paginationMetadata.currentPage - 2; i <= (paginationMetadata.currentPage + 2); i++) + { + if (i >= 1 && i <= paginationMetadata.totalPages) + { + if (i == paginationMetadata.currentPage) + { + htmlText += $"
{i.ToPersianNumbers()}
{Environment.NewLine}"; + } + else + { + htmlText += $"
{i.ToPersianNumbers()}
{Environment.NewLine}"; + } + } + } + if (paginationMetadata.totalPages > (paginationMetadata.currentPage + 2)) + { + htmlText += $"…
{paginationMetadata.totalPages.ToPersianNumbers()}
{Environment.NewLine}"; + } + htmlText += $"
{Environment.NewLine}"; + } + + ViewData["Title"] = $"گنجور » {Title}"; + PagingToolsHtml = htmlText; + + return Page(); + } + } +} diff --git a/GanjooRazor/Pages/Index.cshtml.cs b/GanjooRazor/Pages/Index.cshtml.cs index 475aed3c..61f1cb06 100644 --- a/GanjooRazor/Pages/Index.cshtml.cs +++ b/GanjooRazor/Pages/Index.cshtml.cs @@ -764,9 +764,9 @@ namespace GanjooRazor.Pages switch (GanjoorPage.UrlSlug) { - case "hashieha": - await _GenerateHashiehaHtmlText(); - break; + //case "hashieha": + // await _GenerateHashiehaHtmlText(); + // break; case "vazn": await _GenerateVaznHtmlText(); break;