divan/DivanRazor/Pages/Hashieha.cshtml.cs
Anas Rashid e3e3819c78 Urdu public pages, batch 2 (#2): auth, errors, map, FAQ, similar poems, people pages, page titles
- translate remaining public views and page-model strings (titles, messages, relation names)
- Urdu stopword list for word-frequency stats (replaces Persian list)
- error pages: drop list of alternative Ganjoor services

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 00:22:09 +02:00

227 lines
8.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using DNTPersianUtils.Core;
using DivanRazor.Utils;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OutputCaching;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RMuseum.Models.Auth.ViewModel;
using RMuseum.Models.Divan.ViewModels;
using RMuseum.Services.Implementation;
using RSecurityBackend.Models.Auth.Memory;
using RSecurityBackend.Models.Generic;
namespace DivanRazor.Pages
{
[OutputCache(PolicyName = "DivanPublicPage")]
public class HashiehaModel : LoginPartialEnabledPageModel
{
private readonly PoetCacheService _poetCache;
/// <summary>
/// constructor
/// </summary>
public HashiehaModel(HttpClient httpClient, IConfiguration configuration, PoetCacheService poetCache) : base(httpClient, configuration)
{
_poetCache = poetCache;
}
public List<DivanPoetViewModel> Poets { get; set; }
public int PoetId { get; set; }
public DivanPoetCompleteViewModel Poet { get; set; }
public string PagingToolsHtml { get; set; }
public string LastError { get; set; }
public List<DivanCommentFullViewModel> Comments { get; set; }
public async Task<IActionResult> OnGetPoetInformationAsync(int id)
{
if (id == 0)
{
return new OkObjectResult(null);
}
var (success, poet, error) = await _poetCache.GetPoetAsync(id, EditorCacheBypass);
if (!success)
{
return BadRequest(error);
}
return new OkObjectResult(poet);
}
public DivanUserPublicProfile Profile { get; set; }
public UserContributionsViewModel Contributions { get; set; }
public string Title { get; set; }
public string HomeLink { get; set; }
public bool CanAdministerUsers { get; set; }
public string Query { get; set; }
public async Task<IActionResult> OnGetAsync()
{
var maintenanceResult = TryGetMaintenanceModeResult();
if (maintenanceResult != null)
{
return maintenanceResult;
}
InitializeCommonPageState();
PoetId = string.IsNullOrEmpty(Request.Query["a"]) ? 0 : int.Parse(Request.Query["a"]);
//todo: use html master layout or make it partial
// 1. poets
var (poetsOk, poets, poetsError) = await _poetCache.GetPoetsAsync(EditorCacheBypass);
if (!poetsOk)
{
LastError = poetsError;
return Page();
}
Poets = poets;
if (PoetId != 0)
{
var (poetOk, poet, poetError) = await _poetCache.GetPoetAsync(PoetId, EditorCacheBypass);
if (!poetOk)
{
LastError = poetError;
return Page();
}
Poet = poet;
}
// 2. search comments
int pageNumber = 1;
if (!string.IsNullOrEmpty(Request.Query["page"]))
{
pageNumber = int.Parse(Request.Query["page"]);
}
Query = Request.Query["w"];
var filterUserId = Request.Query["userid"];
string url = $"{APIRoot.Url}/api/divan/comments?PageNumber={pageNumber}&PageSize=20";
Title = "حاشیے";
HomeLink = "/hashieha";
if (!string.IsNullOrEmpty(filterUserId))
{
var responseUserProfile = await _httpClient.GetAsync($"{APIRoot.Url}/api/divan/user/profile/{filterUserId}");
if (!responseUserProfile.IsSuccessStatusCode)
{
LastError = await ReadErrorMessageAsync(responseUserProfile);
return Page();
}
Profile = JsonConvert.DeserializeObject<DivanUserPublicProfile>(await responseUserProfile.Content.ReadAsStringAsync());
var responseContributions = await _httpClient.GetAsync($"{APIRoot.Url}/api/contributions/{filterUserId}");
if (!responseContributions.IsSuccessStatusCode)
{
LastError = await ReadErrorMessageAsync(responseContributions);
return Page();
}
Contributions = JsonConvert.DeserializeObject<UserContributionsViewModel>(await responseContributions.Content.ReadAsStringAsync());
ViewData["Title"] = $"دیوان » حاشیے: {Profile.NickName}";
Title = $"حاشیے: {Profile.NickName}";
HomeLink = $"/hashieha?userid={filterUserId}";
if (!string.IsNullOrEmpty(Request.Cookies["Token"]))
{
// 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. DivanSessionChecker.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 DivanSessionChecker.IsPermitted(Request, Response, SecurableItem.UserEntityShortName, SecurableItem.Administer);
}
url += $"&filterUserId={filterUserId}";
}
if (!string.IsNullOrEmpty(Query))
{
Query = Query.ApplyCorrectYeKe().Trim();
bool quotes = Query.IndexOf("\"") != -1;
Query = LanguageUtils.MakeTextSearchable(Query); //replace zwnj with space
if (quotes)
Query = $"\"{Query}\"";
url += $"&term={Query}";
}
var response = await _httpClient.GetAsync(url);
if (!response.IsSuccessStatusCode)
{
LastError = await ReadErrorMessageAsync(response);
return Page();
}
Comments = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject<List<DivanCommentFullViewModel>>();
string paginnationMetadata = response.Headers.GetValues("paging-headers").FirstOrDefault();
PaginationMetadata paginationMetadata = JsonConvert.DeserializeObject<PaginationMetadata>(paginnationMetadata);
string htmlText = "";
if (paginationMetadata.totalPages > 1)
{
if (pageNumber > 1)
ViewData["Title"] += $" - صفحہ {pageNumber.ToPersianNumbers()}";
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)
{
htmlText += $"<a href=\"/hashieha/?page=1{queryFilterUserId}\"><div class=\"circled-number\">۱</div></a> …";
}
for (int i = paginationMetadata.currentPage - 2; i <= (paginationMetadata.currentPage + 2); i++)
{
if (i >= 1 && i <= paginationMetadata.totalPages)
{
if (i == paginationMetadata.currentPage)
{
htmlText += $"<div class=\"circled-number-diff\">{i.ToPersianNumbers()}</div>{Environment.NewLine}";
}
else
{
htmlText += $"<a href=\"/hashieha/?page={i}{queryFilterUserId}\"><div class=\"circled-number\">{i.ToPersianNumbers()}</div></a>{Environment.NewLine}";
}
}
}
if (paginationMetadata.totalPages > (paginationMetadata.currentPage + 2))
{
htmlText += $"… <a href=\"/hashieha/?page={paginationMetadata.totalPages}{queryFilterUserId}\"><div class=\"circled-number\">{paginationMetadata.totalPages.ToPersianNumbers()}</div></a>{Environment.NewLine}";
}
htmlText += $"</div>{Environment.NewLine}";
}
ViewData["Title"] = $"دیوان » {Title}";
PagingToolsHtml = htmlText;
return Page();
}
}
}