From 30cf219e8d70a2dcac3355706757ddfc7d463d2e Mon Sep 17 00:00:00 2001 From: Hamid Reza Mohammadi Date: Sun, 25 Aug 2024 10:45:45 +0330 Subject: [PATCH] #445 simple search --- TajikGanjoor/Pages/Index.cshtml | 56 +++++++++++- TajikGanjoor/Pages/Index.cshtml.cs | 111 ++++++++++++++++++++++- TajikGanjoor/Pages/Shared/_Layout.cshtml | 4 +- TajikGanjoor/TajikGanjoor.csproj | 4 +- TajikGanjoor/wwwroot/css/site.css | 20 ++++ 5 files changed, 186 insertions(+), 9 deletions(-) diff --git a/TajikGanjoor/Pages/Index.cshtml b/TajikGanjoor/Pages/Index.cshtml index c38f18fa..5b540d2f 100644 --- a/TajikGanjoor/Pages/Index.cshtml +++ b/TajikGanjoor/Pages/Index.cshtml @@ -2,13 +2,13 @@ @model IndexModel -@if(!string.IsNullOrEmpty(Model.LastError)) +@if (!string.IsNullOrEmpty(Model.LastError)) { @Html.Raw(Model.LastError) return; } -@if(Model.Poets == null) +@if (Model.Poets == null) {

Хато дар дарёфт феҳристи суханварон @@ -17,6 +17,58 @@ }

+ @if (Model.IsSearchPage) + { + @if (Model.Poems == null) + { +
+

شعری با مشخصات مورد نظر شما پیدا نشد.

+

+ توصیه‌هایی برای دستیابی به نتیجهٔ مطلوبتر در جستجو: +

+

+ الف) به جای جستجوی متن کامل یک بیت بهتر است حروف کلیدی آن را وارد کنید. از آنجا که اشعار به صورتهای مختلف در نسخه‌های متفاوت نقل شده‌اند ممکن است چیزی که شما در ذهن دارید با چیزی که در پایگاه ما ثبت شده متفاوت باشد. به عنوان نمونه مصرع «کشتی شکستگانیم ای باد شرطه برخیز» از حافظ در بعضی از نسخه‌ها به صورت «کشتی نشستگانیم ای باد شرطه برخیز» ضبط شده و شما با تایپ صورت صورت دوم آن را در گنجور نخواهید یافت. بهتر است برای یافتن این شعر کلماتی مانند کشتی و شرطه را جستجو کنیم. +

+

+ ب) کلماتی را که ممکن است به صورت جدا یا سر هم نوشته شوند در گام اول به صورت جدا امتحان کنید (می شود و نه میشود یا می‌شود). +

+

+ ج) در صورتی که نام سخنور را می‌دانید بهتر است از طریق لیست بازشوی جلوی جعبهٔ جستجو نام او را انتخاب کنید. این توصیه برای زمانی مناسب است که جستجوی عبارت مورد نظر شما باعث می‌شود آثار سخنورانی که مورد نظر شما نیستند در صدر نتایج قرار گیرد و به این وسیله شما می‌خواهید به فهرست محدودتری از نتایج دست پیدا کنید. +

+

+ د) در صورتی که با فنون اولیهٔ جستجو آشنا نیستید یا معمولاً جستجوهایتان به نتیجهٔ مطلوب نمی‌رسد بد نیست نگاهی به این نوشته بیندازید. +

+
+ } + else + for (int poemIndex = 0; poemIndex < Model.Poems.Count; poemIndex++) + { + var poem = Model.Poems[poemIndex]; + +
+ + +

+ @poem.FullTitle +

+
 
+
+ @Html.Raw(poem.PlainText) +
+ + + +
 
+ +
+ } + +
 
+ + + + } + else @if (Model.IsHomePage) { @foreach (var poet in Model.Poets) diff --git a/TajikGanjoor/Pages/Index.cshtml.cs b/TajikGanjoor/Pages/Index.cshtml.cs index 3de9f164..528e8bf3 100644 --- a/TajikGanjoor/Pages/Index.cshtml.cs +++ b/TajikGanjoor/Pages/Index.cshtml.cs @@ -4,10 +4,12 @@ using Microsoft.Extensions.Caching.Memory; using Newtonsoft.Json.Linq; using Newtonsoft.Json; using RMuseum.Models.Ganjoor.ViewModels; -using NAudio.Gui; using RMuseum.Models.Ganjoor; using System.Net; -using System.Reflection; +using DNTPersianUtils.Core; +using System.Drawing; +using RSecurityBackend.Models.Generic; +using System.Text.RegularExpressions; namespace TajikGanjoor.Pages @@ -15,6 +17,9 @@ namespace TajikGanjoor.Pages public class IndexModel : PageModel { public bool IsHomePage { get; set; } + public bool IsSearchPage { get; set; } + + public string Query { get; set; } public List? Poets { get; set; } public bool IsPoetPage { get; set; } public bool IsCatPage { get; set; } @@ -25,6 +30,8 @@ namespace TajikGanjoor.Pages public string PreviousUrl { get; set; } public string PreviousTitle { get; set; } public string BreadCrumpUrls { get; set; } + + public List Poems { get; set; } public async Task OnGetAsync() { if (bool.Parse(Configuration["MaintenanceMode"] ?? false.ToString())) @@ -37,8 +44,106 @@ namespace TajikGanjoor.Pages { return Page(); } + IsSearchPage = !string.IsNullOrEmpty(Request.Query["s"]); + IsHomePage = !IsSearchPage && Request.Path == "/"; + if(IsSearchPage) + { + Query = Request.Query["s"].ToString().Trim(); + int pageNumber = 1; + if (!string.IsNullOrEmpty(Request.Query["page"])) + { + pageNumber = int.Parse(Request.Query["page"]); + } - IsHomePage = Request.Path == "/"; + HttpResponseMessage searchQueryResponse = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/tajik/search?term={Query}&PageNumber={pageNumber}&PageSize=20"); + + if (!searchQueryResponse.IsSuccessStatusCode) + { + LastError = JsonConvert.DeserializeObject(await searchQueryResponse.Content.ReadAsStringAsync()); + return Page(); + } + + Poems = JArray.Parse(await searchQueryResponse.Content.ReadAsStringAsync()).ToObject>(); + if (Poems != null && Poems.Count == 0) + { + Poems = null; + } + + if (Poems != null) + { + // highlight searched word + string[] queryParts = Query.IndexOf('"') == 0 && Query.LastIndexOf('"') == (Query.Length - 1) ? + [Query.Replace("\"", "")] + : + Query.Replace("\"", "").Split(' ', StringSplitOptions.RemoveEmptyEntries); + + foreach (var poem in Poems) + { + string[] lines = poem.PlainText.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries); + List linesInExcerpt = new List(); + for (int i = 0; i < lines.Length; i++) + { + foreach (var queryPart in queryParts) + { + if (lines[i].IndexOf(queryPart) != -1) + { + if (i > 0) + { + if (linesInExcerpt.IndexOf(i - 1) == -1) + { + linesInExcerpt.Add(i - 1); + } + } + if (linesInExcerpt.IndexOf(i) == -1) + { + linesInExcerpt.Add(i); + } + + if (i < (lines.Length - 1)) + linesInExcerpt.Add(i + 1); + + break; + } + } + } + + + + + string plainText = ""; + for (int i = 0; i < linesInExcerpt.Count; i++) + { + if (linesInExcerpt[i] > 0 && linesInExcerpt.IndexOf(linesInExcerpt[i] - 1) == -1) + plainText += "... "; + plainText += $"{lines[linesInExcerpt[i]]}"; + if (linesInExcerpt[i] < (lines.Length - 1) && linesInExcerpt.IndexOf(linesInExcerpt[i] + 1) == -1) + plainText += " ..."; + plainText += $"{Environment.NewLine}"; + } + + string finalPlainText = ""; + foreach (string line in plainText.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries)) + { + finalPlainText += $"

{line}

"; + } + if (linesInExcerpt.Count > 0) + { + poem.PlainText = finalPlainText; + } + + for (int i = 0; i < queryParts.Length; i++) + { + string cssClass = i % 3 == 0 ? "hilite" : i % 3 == 1 ? "hilite2" : "hilite3"; + poem.PlainText = Regex.Replace(poem.PlainText, queryParts[i], $"{queryParts[i]}", RegexOptions.IgnoreCase | RegexOptions.RightToLeft); ; + } + + + } + + + } + } + else if (!IsHomePage) { var pageQuery = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/tajik/page?url={Request.Path}&catPoems=true"); diff --git a/TajikGanjoor/Pages/Shared/_Layout.cshtml b/TajikGanjoor/Pages/Shared/_Layout.cshtml index ef754881..d3210f90 100644 --- a/TajikGanjoor/Pages/Shared/_Layout.cshtml +++ b/TajikGanjoor/Pages/Shared/_Layout.cshtml @@ -15,8 +15,8 @@ @Html.Raw(ViewData["BreadCrumpUrls"])
-
- + +
diff --git a/TajikGanjoor/TajikGanjoor.csproj b/TajikGanjoor/TajikGanjoor.csproj index 4e92bf39..99943df6 100644 --- a/TajikGanjoor/TajikGanjoor.csproj +++ b/TajikGanjoor/TajikGanjoor.csproj @@ -7,11 +7,11 @@ - 1701;1702;8602;8618 + 1701;1702;8602;8618;8601;8604;8625 - 1701;1702;8602;8618 + 1701;1702;8602;8618;8601;8604;8625 diff --git a/TajikGanjoor/wwwroot/css/site.css b/TajikGanjoor/wwwroot/css/site.css index f8d98fcb..db30ba00 100644 --- a/TajikGanjoor/wwwroot/css/site.css +++ b/TajikGanjoor/wwwroot/css/site.css @@ -19,4 +19,24 @@ html { body { margin-bottom: 60px; +} + +.hilite { + color: #000; + background-color: #9cf +} + +.hilite1 { + color: #000; + background-color: #fc6 +} + +.hilite2 { + color: #000; + background-color: #9f6 +} + +.hilite3 { + color: #000; + background-color: #f99 } \ No newline at end of file