#112 adding admin and user areas and changing some of queries to AsNoTracking

This commit is contained in:
Hamid Reza Mohammadi 2021-05-11 20:19:02 +04:30
parent 0f32b2848c
commit d2a4cf46f9
19 changed files with 2084 additions and 34 deletions

View File

@ -0,0 +1,55 @@
@page
@model GanjooRazor.Areas.Admin.Pages.BannersModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
Layout = "_AdminLayout";
ViewData["Title"] = "آگاهی‌ها";
}
<h1>@ViewData["Title"]</h1>
<p>@Model.LastMessage</p>
<form method="post" enctype="multipart/form-data">
<input type="file" asp-for="Upload.Image" />
<input asp-for="Upload.Alt" />
<input style="text-align:left;direction:ltr;" asp-for="Upload.Url" />
<input type="submit" value="بارگذاری" />
</form>
@if (Model.Banners != null)
{
<table>
@foreach (var banner in Model.Banners)
{
<tr id="tr-@banner.Id">
<td>متن جایگزین: <input type="text" name="alt-@banner.Id" id="alt-@banner.Id" value="@banner.AlternateText" /> </td>
<td>نشانی مقصد:<input type="text" name="url-@banner.Id" id="url-@banner.Id" style="text-align:left;direction:ltr;" value=@banner.TargetUrl /> </td>
<td><img src="@($"{GanjooRazor.APIRoot.InternetUrl}/{banner.ImageUrl}")" alt="@banner.AlternateText" width="200" /></td>
@if (banner.Active)
{
<td>فعال <input type="checkbox" name="active-@banner.Id" id="active-@banner.Id" checked /> </td>
}
else
{
<td>فعال <input type="checkbox" name="active-@banner.Id" id="active-@banner.Id" /> </td>
}
<td>
<a role="button" onclick="editBanner(@banner.Id)" class="actionlink" title="ویرایش آگاهی">✎</a>
<a role="button" onclick="deleteBanner(@banner.Id)" class="actionlink" title="حذف آگاهی">🗑</a>
</td>
</tr>
}
</table>
<div style="visibility:hidden">
<form method="post" id="editbannerform">
<input type="text" name="id" id="id" />
<input type="text" name="alt" id="alt" />
<input type="text" name="url" id="url" />
<input type="checkbox" name="active" id="active" />
</form>
</div>
}

View File

@ -0,0 +1,157 @@
using GanjooRazor.Models;
using GanjooRazor.Utils;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Newtonsoft.Json;
using RMuseum.Models.Ganjoor.ViewModels;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace GanjooRazor.Areas.Admin.Pages
{
[IgnoreAntiforgeryToken(Order = 1001)]
public class BannersModel : PageModel
{
/// <summary>
/// image
/// </summary>
[BindProperty]
public BannerUploadModel Upload { get; set; }
/// <summary>
/// last message
/// </summary>
public string LastMessage { get; set; }
/// <summary>
/// banners
/// </summary>
public GanjoorSiteBannerViewModel[] Banners { get; set; }
public async Task<IActionResult> OnGetAsync()
{
LastMessage = "";
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
var response = await secureClient.GetAsync($"{APIRoot.Url}/api/ganjoor/site/banners");
if (!response.IsSuccessStatusCode)
{
LastMessage = await response.Content.ReadAsStringAsync();
}
response.EnsureSuccessStatusCode();
Banners = JsonConvert.DeserializeObject<GanjoorSiteBannerViewModel[]>(await response.Content.ReadAsStringAsync());
}
else
{
LastMessage = "لطفا از گنجور خارج و مجددا به آن وارد شوید.";
}
}
return Page();
}
/// <summary>
/// edit
/// </summary>
/// <returns></returns>
public async Task<IActionResult> OnPutEditAsync(int id, string alt, string url, bool active)
{
LastMessage = "";
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
GanjoorSiteBannerModifyViewModel model = new GanjoorSiteBannerModifyViewModel()
{
AlternateText = alt,
TargetUrl = url,
Active = active
};
HttpResponseMessage response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/site/banner/{id}", new StringContent(JsonConvert.SerializeObject(model), Encoding.UTF8, "application/json"));
if (!response.IsSuccessStatusCode)
{
LastMessage = await response.Content.ReadAsStringAsync();
}
}
else
{
LastMessage = "لطفا از گنجور خارج و مجددا به آن وارد شوید.";
}
}
return new JsonResult(true);
}
public async Task<IActionResult> OnDeleteAsync(int id)
{
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
var response = await secureClient.DeleteAsync($"{APIRoot.Url}/api/ganjoor/site/banner?id={id}");
if (response.StatusCode != HttpStatusCode.OK)
{
return Redirect($"/login?redirect={Request.Path}&error={await response.Content.ReadAsStringAsync()}");
}
}
}
return new JsonResult(true);
}
public async Task<IActionResult> OnPostAsync(BannerUploadModel Upload)
{
LastMessage = "";
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
MultipartFormDataContent form = new MultipartFormDataContent();
using (MemoryStream stream = new MemoryStream())
{
form.Add(new StringContent(Upload.Alt), "alt");
form.Add(new StringContent(Upload.Url), "url");
await Upload.Image.CopyToAsync(stream);
var fileContent = stream.ToArray();
form.Add(new ByteArrayContent(fileContent, 0, fileContent.Length), Upload.Image.FileName, Upload.Image.FileName);
HttpResponseMessage response = await secureClient.PostAsync($"{APIRoot.Url}/api/ganjoor/site/banner", form);
if (!response.IsSuccessStatusCode)
{
LastMessage = await response.Content.ReadAsStringAsync();
}
}
}
else
{
LastMessage = "لطفا از گنجور خارج و مجددا به آن وارد شوید.";
}
}
return Page();
}
}
}

View File

@ -0,0 +1,119 @@
@page
@model GanjooRazor.Areas.Admin.Pages.ModifyPageModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
Layout = "_AdminLayout";
ViewData["Title"] = "ویرایش";
}
<h1>@ViewData["Title"]</h1>
<p>@Model.LastMessage</p>
<form method="post">
<table style="width:100%" class="noborder">
<tr>
<td>
<span class="inputlabel">شناسهٔ صفحه: </span>
</td>
<td>
<span class="inputlabel"><a href="/?p=@Request.Query["id"]">@Request.Query["id"]</a></span>
</td>
</tr>
<tr>
<td>
<span class="inputlabel">عنوان: </span>
</td>
<td>
<input asp-for="ModifyModel.Title" />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">نامک: </span>
</td>
<td>
<input style="text-align:left;direction:ltr;" asp-for="ModifyModel.UrlSlug" />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">متن: </span>
</td>
<td>
<textarea asp-for="ModifyModel.HtmlText" tabindex="4" rows="20" cols="80"></textarea>
</td>
</tr>
<tr>
<td>
<span class="inputlabel">منبع (شعر): </span>
</td>
<td>
<table>
<tr>
<td><span>نام:</span> <input asp-for="ModifyModel.SourceName" /></td>
</tr>
<tr>
<td><span>نشانی:</span> <input style="text-align:left;direction:ltr;" asp-for="ModifyModel.SourceUrlSlug" /></td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<span class="inputlabel">دسته‌بندی کهن (شعر): </span>
</td>
<td>
<table>
<tr>
<td><span>نام:</span> <input asp-for="ModifyModel.OldTag" /></td>
</tr>
<tr>
<td><span>نشانی:</span> <input style="text-align:left;direction:ltr;" asp-for="ModifyModel.OldTagPageUrl" /></td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<span class="inputlabel">وزن (شعر): </span>
</td>
<td>
<input asp-for="ModifyModel.Rhythm" list="rythms" />
<datalist id="rythms">
@if(Model.Rhythms != null)
@foreach(var rythm in Model.Rhythms)
{
<option value="@rythm.Rhythm">@rythm.Rhythm</option>
}
</datalist>
</td>
</tr>
<tr>
<td>
<span class="inputlabel">حروف قافیه (شعر): </span>
</td>
<td>
<input asp-for="ModifyModel.RhymeLetters" />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">توضیح این ویرایش: </span>
</td>
<td>
<input asp-for="ModifyModel.Note" />
</td>
</tr>
<tr>
<td colspan="2">
<button type="submit" name="approve" id="approve" style="width:100%;color:white;background-color:green">ذخیره</button>
</td>
</tr>
</table>
</form>

View File

@ -0,0 +1,127 @@
using GanjooRazor.Utils;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RMuseum.Models.Ganjoor;
using RMuseum.Models.Ganjoor.ViewModels;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace GanjooRazor.Areas.Admin.Pages
{
public class ModifyPageModel : PageModel
{
/// <summary>
/// HttpClient instance
/// </summary>
private readonly HttpClient _httpClient;
/// <summary>
/// constructor
/// </summary>
/// <param name="httpClient"></param>
public ModifyPageModel(HttpClient httpClient)
{
_httpClient = httpClient;
}
/// <summary>
/// Corresponding Ganojoor Page
/// </summary>
/// <summary>
/// api model
/// </summary>
[BindProperty]
public GanjoorModifyPageViewModel ModifyModel { get; set; }
/// <summary>
/// rythm
/// </summary>
public GanjoorMetre[] Rhythms { get; set; }
/// <summary>
/// last message
/// </summary>
public string LastMessage { get; set; }
public async Task<IActionResult> OnGetAsync()
{
LastMessage = Request.Query["edit"] == "true" ? "ویرایش انجام شد." : "";
if (string.IsNullOrEmpty(Request.Query["id"]))
{
return StatusCode(StatusCodes.Status500InternalServerError, "شناسهٔ صفحه مشخص نیست.");
}
var rhythmResponse = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/rhythms");
rhythmResponse.EnsureSuccessStatusCode();
Rhythms = JsonConvert.DeserializeObject<GanjoorMetre[]>(await rhythmResponse.Content.ReadAsStringAsync());
var pageUrlResponse = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/pageurl?id={Request.Query["id"]}");
if (!pageUrlResponse.IsSuccessStatusCode)
{
return StatusCode(StatusCodes.Status500InternalServerError, await pageUrlResponse.Content.ReadAsStringAsync());
}
pageUrlResponse.EnsureSuccessStatusCode();
var pageUrl = JsonConvert.DeserializeObject<string>(await pageUrlResponse.Content.ReadAsStringAsync());
var pageQuery = await _httpClient.GetAsync($"{APIRoot.Url}/api/ganjoor/page?url={pageUrl}");
if (!pageQuery.IsSuccessStatusCode)
{
return StatusCode(StatusCodes.Status500InternalServerError, await pageQuery.Content.ReadAsStringAsync());
}
GanjoorPageCompleteViewModel page = JObject.Parse(await pageQuery.Content.ReadAsStringAsync()).ToObject<GanjoorPageCompleteViewModel>();
ModifyModel = new GanjoorModifyPageViewModel()
{
Title = page.Title,
UrlSlug = page.UrlSlug,
HtmlText = page.HtmlText,
Note = "",
SourceName = page.Poem == null ? null : page.Poem.SourceName,
SourceUrlSlug = page.Poem == null ? null : page.Poem.SourceUrlSlug,
OldTag = page.Poem == null ? null : page.Poem.OldTag,
OldTagPageUrl = page.Poem == null ? null : page.Poem.OldTagPageUrl,
RhymeLetters = page.Poem == null ? null : page.Poem.RhymeLetters,
Rhythm = page.Poem == null ? null : page.Poem.GanjoorMetre == null ? null : page.Poem.GanjoorMetre.Rhythm
};
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
var putResponse = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/page/{Request.Query["id"]}", new StringContent(JsonConvert.SerializeObject(ModifyModel), Encoding.UTF8, "application/json"));
if (!putResponse.IsSuccessStatusCode)
{
LastMessage = await putResponse.Content.ReadAsStringAsync();
}
else
{
return Redirect($"/Admin/ModifyPage?id={Request.Query["id"]}&edit=true");
}
}
else
{
LastMessage = "لطفا از گنجور خارج و مجددا به آن وارد شوید.";
}
}
return Page();
}
}
}

View File

@ -0,0 +1,100 @@
@page
@model GanjooRazor.Areas.User.Pages.AddSongModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
Layout = "_Layout";
ViewData["Title"] = "آهنگ مرتبط از منابع دلخواه";
await GanjooRazor.Utils.GanjoorSessionChecker.ApplyPermissionsToViewData(Request, Response, ViewData);
}
<h1>@ViewData["Title"]</h1>
@if (Model.LastError != "")
{
<h2>@Model.LastError</h2>
}
<form method="post">
<table style="width:100%" class="noborder">
<tr>
<td>
<span class="inputlabel">شناسهٔ شعر: </span>
</td>
<td>
<input asp-for="PoemMusicTrackViewModel.PoemId" />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">خواننده: </span>
</td>
<td>
<input style="width:100%" asp-for="PoemMusicTrackViewModel.ArtistName" /><br />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">نشانی خواننده:</span>
</td>
<td>
<input style="width:100%;text-align:left;direction:ltr;" asp-for="PoemMusicTrackViewModel.ArtistUrl" />
</td>
</tr>
<tr>
<td>
</td>
<td>
</td>
</tr>
<tr>
<td>
<span class="inputlabel">آلبوم:</span>
</td>
<td>
<input style="width:100%" asp-for="PoemMusicTrackViewModel.AlbumName" /><br />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">نشانی آلبوم:</span>
</td>
<td>
<input style="width:100%;text-align:left;direction:ltr;" asp-for="PoemMusicTrackViewModel.AlbumUrl" />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">آهنگ:</span>
</td>
<td>
<input style="width:100%" asp-for="PoemMusicTrackViewModel.TrackName" />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">نشانی آهنگ:</span>
</td>
<td>
<input style="width:100%;text-align:left;direction:ltr;" asp-for="PoemMusicTrackViewModel.TrackUrl" />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">توضیح: </span>
</td>
<td>
<input style="width:100%" asp-for="PoemMusicTrackViewModel.Description" /><br />
</td>
</tr>
<tr>
<td colspan="2">
<button type="submit" name="approve" id="approve" style="width:100%;color:white;background-color:green">تأیید</button>
</td>
</tr>
</table>
</form>

View File

@ -0,0 +1,77 @@
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using GanjooRazor.Utils;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Newtonsoft.Json;
using RMuseum.Models.Ganjoor.ViewModels;
namespace GanjooRazor.Areas.User.Pages
{
public class AddSongModel : PageModel
{
/// <summary>
/// Last Error
/// </summary>
public string LastError { get; set; }
/// <summary>
/// api model
/// </summary>
[BindProperty]
public PoemMusicTrackViewModel PoemMusicTrackViewModel { get; set; }
/// <summary>
/// poem id
/// </summary>
public int PoemId { get; set; }
public void OnGet()
{
PoemMusicTrackViewModel = new PoemMusicTrackViewModel()
{
TrackType = RMuseum.Models.Ganjoor.PoemMusicTrackType.BeepTunesOrKhosousi,
PoemId = 0,
ArtistName = "محمدرضا شجریان",
ArtistUrl = "http://beeptunes.com/artist/3403349",
AlbumName = "اجراهای خصوصی",
AlbumUrl = "http://khosousi.com",
TrackName = "",
TrackUrl = "",
Approved = false,
Rejected = false,
BrokenLink = false,
Description = ""
};
}
public async Task<IActionResult> OnPostAsync()
{
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
var putResponse = await secureClient.PostAsync($"{APIRoot.Url}/api/ganjoor/song/add", new StringContent(JsonConvert.SerializeObject(PoemMusicTrackViewModel), Encoding.UTF8, "application/json"));
if (!putResponse.IsSuccessStatusCode)
{
LastError = await putResponse.Content.ReadAsStringAsync();
}
}
else
{
LastError = "لطفا از گنجور خارج و مجددا به آن وارد شوید.";
}
}
if (!string.IsNullOrEmpty(LastError))
{
return Page();
}
return Redirect("/User/AddSong");
}
}
}

View File

@ -0,0 +1,128 @@
@page
@model GanjooRazor.Areas.Panel.Pages.IndexModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
Layout = "_Layout";
ViewData["Title"] = "پیشخان کاربر";
await GanjooRazor.Utils.GanjoorSessionChecker.ApplyPermissionsToViewData(Request, Response, ViewData);
}
<h1>@ViewData["Title"]</h1>
@if (Model.LastError != "")
{
<h2>@Model.LastError</h2>
}
else
{
<form method="post" asp-page-handler="SetMyPass">
<table style="width:100%" class="noborder">
<tr>
<td colspan="2">
<h2>تغییر گذرواژه</h2>
</td>
</tr>
<tr>
<td>
<span class="inputlabel">گذرواژهٔ کنونی: </span>
</td>
<td>
<input type="password" style="width:100%" asp-for="ChangePasswordModel.OldPassword" /><br />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">گذرواژهٔ جدید: </span>
</td>
<td>
<input type="password" style="width:100%" asp-for="ChangePasswordModel.NewPassword" /><br />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">تکرار گذرواژهٔ جدید: </span>
</td>
<td>
<input type="password" style="width:100%" asp-for="ChangePasswordModel.NewPasswordRepeat" /><br />
</td>
</tr>
<tr>
<td>
@Model.PasswordChanged
</td>
<td>
<button type="submit" name="approve" id="approve" style="width:100%;color:white;background-color:green">تغییر گذرواژه</button>
</td>
</tr>
</table>
</form>
<form method="post" asp-page-handler="SetMyInfo">
<table style="width:100%" class="noborder">
<tr>
<td colspan="2">
<h2>تغییر مشخصات</h2>
</td>
</tr>
<tr>
<td>
<span class="inputlabel">نام: </span>
</td>
<td>
<input style="width:100%" asp-for="UserInfo.FirstName" /><br />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">نام خانوادگی: </span>
</td>
<td>
<input style="width:100%" asp-for="UserInfo.SureName" /><br />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">نام مستعار (نمایش در حاشیه‌ها): </span>
</td>
<td>
<input style="width:100%" asp-for="UserInfo.NickName" /><br />
</td>
</tr>
<tr>
<td>
<span class="inputlabel"><a target="_blank" href="@Html.Raw(Model.UserInfo.Website)">وبگاه:</a></span>
</td>
<td>
<input style="width:100%;text-align:left;direction:ltr;" asp-for="UserInfo.Website" />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">دربارهٔ من: </span>
</td>
<td>
<textarea asp-for="UserInfo.Bio" class="editor"></textarea>
</td>
</tr>
<tr>
<td>
<input type="hidden" asp-for="UserInfo.Id" />
<input type="hidden" asp-for="UserInfo.Email" />
<input type="hidden" asp-for="UserInfo.Username" />
<input type="hidden" asp-for="UserInfo.Password" />
<input type="hidden" asp-for="UserInfo.PhoneNumber" />
<input type="hidden" asp-for="UserInfo.Status" />
<input type="hidden" asp-for="UserInfo.RImageId" />
</td>
<td>
<button type="submit" name="approve" id="approve" style="width:100%;color:white;background-color:green">ذخیره</button>
</td>
</tr>
<tr>
<td colspan="2">
<a href="/hashieha/?userid=@Model.UserInfo.Id" target="_blank">نمایهٔ عمومی من</a>
</td>
</tr>
</table>
</form>
}

View File

@ -0,0 +1,165 @@
using GanjooRazor.Models.User;
using GanjooRazor.Utils;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Newtonsoft.Json;
using RSecurityBackend.Models.Auth.ViewModels;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace GanjooRazor.Areas.Panel.Pages
{
public class IndexModel : PageModel
{
/// <summary>
/// api model
/// </summary>
[BindProperty]
public RegisterRAppUser UserInfo { get; set; }
[BindProperty]
public ChangePasswordModel ChangePasswordModel { get; set; }
/// <summary>
/// Last Error
/// </summary>
public string LastError { get; set; }
/// <summary>
/// password changed
/// </summary>
public string PasswordChanged { get; set; }
/// <summary>
/// get
/// </summary>
public async Task OnGetAsync()
{
LastError = "";
PasswordChanged = "";
await _PreparePage();
}
private async Task _PreparePage()
{
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
var userInfoResponse = await secureClient.GetAsync($"{APIRoot.Url}/api/users/{Request.Cookies["UserId"]}");
if (userInfoResponse.IsSuccessStatusCode)
{
PublicRAppUser userInfo = JsonConvert.DeserializeObject<PublicRAppUser>(await userInfoResponse.Content.ReadAsStringAsync());
UserInfo = new RegisterRAppUser()
{
Id = userInfo.Id,
Username = userInfo.Username,
FirstName = userInfo.FirstName,
SureName = userInfo.SureName,
NickName = userInfo.NickName,
PhoneNumber = userInfo.PhoneNumber,
Email = userInfo.Email,
Website = userInfo.Website,
Bio = userInfo.Bio,
RImageId = userInfo.RImageId,
Status = userInfo.Status,
IsAdmin = false,
Password = ""
};
}
else
{
LastError = await userInfoResponse.Content.ReadAsStringAsync();
}
}
else
{
LastError = "لطفا از گنجور خارج و مجددا به آن وارد شوید.";
}
}
}
public async Task<IActionResult> OnPostSetMyInfoAsync(RegisterRAppUser UserInfo)
{
LastError = "";
PasswordChanged = "";
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
var isAdminResponse = await secureClient.GetAsync($"{APIRoot.Url}/api/users/isadmin?userId={Request.Cookies["UserId"]}");
if (isAdminResponse.IsSuccessStatusCode)
{
UserInfo.IsAdmin = JsonConvert.DeserializeObject<bool>(await isAdminResponse.Content.ReadAsStringAsync());
var putResponse = await secureClient.PutAsync($"{APIRoot.Url}/api/users/{Request.Cookies["UserId"]}", new StringContent(JsonConvert.SerializeObject(UserInfo), Encoding.UTF8, "application/json"));
if(!putResponse.IsSuccessStatusCode)
{
LastError = await putResponse.Content.ReadAsStringAsync();
}
}
else
{
LastError = await isAdminResponse.Content.ReadAsStringAsync();
}
}
else
{
LastError = "لطفا از گنجور خارج و مجددا به آن وارد شوید.";
}
}
await _PreparePage();
return Page();
}
public async Task<IActionResult> OnPostSetMyPassAsync(ChangePasswordModel ChangePasswordModel)
{
LastError = "";
PasswordChanged = "";
if (ChangePasswordModel.NewPasswordRepeat != ChangePasswordModel.NewPassword)
{
LastError = "گذرواژهٔ جدید با تکرار آن همسان نیست.";
return Page();
}
if(ChangePasswordModel.NewPassword == ChangePasswordModel.OldPassword)
{
LastError = "گذرواژهٔ جدید با گذرواژهٔ کنونی یکسان است.";
return Page();
}
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
var changePassResp = await secureClient.PostAsync($"{APIRoot.Url}/api/users/setmypassword",
new StringContent(JsonConvert.SerializeObject
(
new SetPasswordModel()
{
OldPassword = ChangePasswordModel.OldPassword,
NewPassword = ChangePasswordModel.NewPassword
}
),
Encoding.UTF8, "application/json"));
if (!changePassResp.IsSuccessStatusCode)
{
LastError = await changePassResp.Content.ReadAsStringAsync();
}
else
{
PasswordChanged = "گذرواژهٔ شما به درستی تغییر کرد.";
}
}
else
{
LastError = "لطفا از گنجور خارج و مجددا به آن وارد شوید.";
}
}
await _PreparePage();
return Page();
}
}
}

View File

@ -0,0 +1,91 @@
@page
@model GanjooRazor.Areas.User.Pages.MyCommentsModel
@using DNTPersianUtils.Core
@{
Layout = "_Layout";
ViewData["Title"] = "حاشیه‌های من";
await GanjooRazor.Utils.GanjoorSessionChecker.ApplyPermissionsToViewData(Request, Response, ViewData);
string color = "gray";
}
<h1>@ViewData["Title"]</h1>
@if (Model.LastError != "")
{
<h2>@Model.LastError</h2>
}
else
{
<p style="text-align:center">
@foreach (var paginationLink in Model.PaginationLinks)
{
if (!string.IsNullOrEmpty(paginationLink.Url))
{
<a href="@paginationLink.Url">@paginationLink.Name</a>
}
else
{
@paginationLink.Name
}
}
</p>
@foreach (var comment in Model.Comments)
{
if (color == "gray")
color = "white";
else
color = "gray";
<div style="background-color:@color" id="comment-@comment.Id">
<blockquote>
<div id="comment-text-@comment.Id">
@Html.Raw(comment.HtmlComment)
</div>
<p>
@comment.AuthorName <small>در @comment.CommentDate.ToFriendlyPersianDateTextify()</small> دربارهٔ <a href="@comment.Poem.UrlSlug">@comment.Poem.Title</a>
</p>
</blockquote>
<p>
<a role="button" onclick="deleteMyComment(@comment.Id)" class="actionlink" title="حذف حاشیه">🗑</a>
<a role="button" onclick="editMyComment(@comment.Id)" class="actionlink" title="ویرایش حاشیه">✎</a>
</p>
</div>
<hr />
}
<p style="text-align:center">
@foreach (var paginationLink in Model.PaginationLinks)
{
if (!string.IsNullOrEmpty(paginationLink.Url))
{
<a href="@paginationLink.Url">@paginationLink.Name</a>
}
else
{
@paginationLink.Name
}
}
</p>
<div id="id02" class="modal">
<span onclick="document.getElementById('id02').style.display='none'"
class="close" title="بستن">&times;</span>
<form class="modal-content animate" method="post" id="editcommentform" action="?handler=EditComment">
<table style="max-width:100%; width:100%; margin:0">
<tr>
<td>
<textarea name="editCommentText" id="editCommentText" class="inputTextarea editor" tabindex="4" rows="10" style="width:100%"></textarea>
<input type="hidden" name="editCommentId" id="editCommentId" value="" />
</td>
</tr>
<tr>
<td>
<button name="editcomment" id="editcomment" class="inputSubmit" onclick="return editComment();" style="width:100%">ویرایش حاشیه</button>
</td>
</tr>
</table>
</form>
</div>
}

View File

@ -0,0 +1,174 @@
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using DNTPersianUtils.Core;
using GanjooRazor.Utils;
using GSpotifyProxy.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RMuseum.Models.Ganjoor.ViewModels;
using RSecurityBackend.Models.Generic;
namespace GanjooRazor.Areas.User.Pages
{
[IgnoreAntiforgeryToken(Order = 1001)]
public class MyCommentsModel : PageModel
{
// <summary>
/// Last Error
/// </summary>
public string LastError { get; set; }
/// <summary>
/// comments
/// </summary>
public List<GanjoorCommentFullViewModel> Comments { get; set; }
/// <summary>
/// pagination links
/// </summary>
public List<NameIdUrlImage> PaginationLinks { get; set; }
public async Task<IActionResult> OnGetAsync()
{
LastError = "";
using (HttpClient secureClient = new HttpClient())
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
{
int pageNumber = 1;
if (!string.IsNullOrEmpty(Request.Query["page"]))
{
pageNumber = int.Parse(Request.Query["page"]);
}
var response = await secureClient.GetAsync($"{APIRoot.Url}/api/ganjoor/comments/mine?PageNumber={pageNumber}&PageSize=20");
if (!response.IsSuccessStatusCode)
{
LastError = await response.Content.ReadAsStringAsync();
return Page();
}
response.EnsureSuccessStatusCode();
Comments = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject<List<GanjoorCommentFullViewModel>>();
string paginnationMetadata = response.Headers.GetValues("paging-headers").FirstOrDefault();
if (!string.IsNullOrEmpty(paginnationMetadata))
{
PaginationMetadata paginationMetadata = JsonConvert.DeserializeObject<PaginationMetadata>(paginnationMetadata);
PaginationLinks = new List<NameIdUrlImage>();
if (paginationMetadata.totalPages > 1)
{
if (paginationMetadata.currentPage > 3)
{
PaginationLinks.Add
(
new NameIdUrlImage()
{
Name = "صفحهٔ اول",
Url = "/User/MyComments/?page=1"
}
);
}
for (int i = (paginationMetadata.currentPage - 2); i <= (paginationMetadata.currentPage + 2); i++)
{
if (i >= 1 && i <= paginationMetadata.totalPages)
{
if (i == paginationMetadata.currentPage)
{
PaginationLinks.Add
(
new NameIdUrlImage()
{
Name = i.ToPersianNumbers(),
}
);
}
else
{
PaginationLinks.Add
(
new NameIdUrlImage()
{
Name = i.ToPersianNumbers(),
Url = $"/User/MyComments/?page={i}"
}
);
}
}
}
if (paginationMetadata.totalPages > (paginationMetadata.currentPage + 2))
{
PaginationLinks.Add
(
new NameIdUrlImage()
{
Name = "... ",
}
);
PaginationLinks.Add
(
new NameIdUrlImage()
{
Name = "صفحهٔ آخر",
Url = $"/User/MyComments/?page={paginationMetadata.totalPages}"
}
);
}
}
}
}
}
else
{
LastError = "لطفا از گنجور خارج و مجددا به آن وارد شوید.";
}
return Page();
}
public async Task<IActionResult> OnDeleteMyComment(int id)
{
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
var response = await secureClient.DeleteAsync($"{APIRoot.Url}/api/ganjoor/comment?id={id}");
if (response.StatusCode != HttpStatusCode.OK)
{
return Redirect($"/login?redirect={Request.Path}&error={await response.Content.ReadAsStringAsync()}");
}
}
}
return new JsonResult(true);
}
public async Task<IActionResult> OnPutMyComment(int id, string comment)
{
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
var response = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/comment/{id}", new StringContent(JsonConvert.SerializeObject(comment), Encoding.UTF8, "application/json"));
if (response.StatusCode != HttpStatusCode.OK)
{
return Redirect($"/login?redirect={Request.Path}&error={await response.Content.ReadAsStringAsync()}");
}
}
}
return new JsonResult(true);
}
}
}

View File

@ -0,0 +1,71 @@
@page
@model GanjooRazor.Areas.User.Pages.NotificationsModel
@using DNTPersianUtils.Core
@{
Layout = "_Layout";
ViewData["Title"] = "اعلان‌های من";
await GanjooRazor.Utils.GanjoorSessionChecker.ApplyPermissionsToViewData(Request, Response, ViewData);
string color = "gray";
}
<h1>@ViewData["Title"]</h1>
@if (Model.LastError != "")
{
<h2>@Model.LastError</h2>
}
else
{
<p style="text-align:center">
@foreach (var paginationLink in Model.PaginationLinks)
{
if (!string.IsNullOrEmpty(paginationLink.Url))
{
<a href="@paginationLink.Url">@paginationLink.Name</a>
}
else
{
@paginationLink.Name
}
}
</p>
@foreach (var notification in Model.Notifications)
{
if (color == "gray")
color = "white";
else
color = "gray";
<div style="background-color:@color" id="notification-@notification.Id">
<blockquote>
<p>
@notification.Subject <small>در @notification.DateTime.ToFriendlyPersianDateTextify()</small>
</p>
<div id="notification-text-@notification.Id">
@Html.Raw(notification.HtmlText)
</div>
</blockquote>
<p>
<a role="button" onclick="deleteNotification('@notification.Id')" class="actionlink" title="حذف">🗑</a>
</p>
</div>
<hr />
}
<p style="text-align:center">
@foreach (var paginationLink in Model.PaginationLinks)
{
if (!string.IsNullOrEmpty(paginationLink.Url))
{
<a href="@paginationLink.Url">@paginationLink.Name</a>
}
else
{
@paginationLink.Name
}
}
</p>
}

View File

@ -0,0 +1,158 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using DNTPersianUtils.Core;
using GanjooRazor.Utils;
using GSpotifyProxy.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RMuseum.Models.Ganjoor.ViewModels;
using RSecurityBackend.Models.Generic;
using RSecurityBackend.Models.Notification.ViewModels;
namespace GanjooRazor.Areas.User.Pages
{
[IgnoreAntiforgeryToken(Order = 1001)]
public class NotificationsModel : PageModel
{
// <summary>
/// Last Error
/// </summary>
public string LastError { get; set; }
/// <summary>
/// pagination links
/// </summary>
public List<NameIdUrlImage> PaginationLinks { get; set; }
/// <summary>
/// Notifications
/// </summary>
public List<RUserNotificationViewModel> Notifications { get; set; }
public async Task<IActionResult> OnGetAsync()
{
LastError = "";
using (HttpClient secureClient = new HttpClient())
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
{
int pageNumber = 1;
if (!string.IsNullOrEmpty(Request.Query["page"]))
{
pageNumber = int.Parse(Request.Query["page"]);
}
var response = await secureClient.GetAsync($"{APIRoot.Url}/api/notifications/paginated?PageNumber={pageNumber}&PageSize=20");
if (!response.IsSuccessStatusCode)
{
LastError = await response.Content.ReadAsStringAsync();
return Page();
}
response.EnsureSuccessStatusCode();
Notifications = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject<List<RUserNotificationViewModel>>();
string paginnationMetadata = response.Headers.GetValues("paging-headers").FirstOrDefault();
if (!string.IsNullOrEmpty(paginnationMetadata))
{
PaginationMetadata paginationMetadata = JsonConvert.DeserializeObject<PaginationMetadata>(paginnationMetadata);
PaginationLinks = new List<NameIdUrlImage>();
if (paginationMetadata.totalPages > 1)
{
if (paginationMetadata.currentPage > 3)
{
PaginationLinks.Add
(
new NameIdUrlImage()
{
Name = "صفحهٔ اول",
Url = "/User/Notifications/?page=1"
}
);
}
for (int i = (paginationMetadata.currentPage - 2); i <= (paginationMetadata.currentPage + 2); i++)
{
if (i >= 1 && i <= paginationMetadata.totalPages)
{
if (i == paginationMetadata.currentPage)
{
PaginationLinks.Add
(
new NameIdUrlImage()
{
Name = i.ToPersianNumbers(),
}
);
}
else
{
PaginationLinks.Add
(
new NameIdUrlImage()
{
Name = i.ToPersianNumbers(),
Url = $"/User/Notifications/?page={i}"
}
);
}
}
}
if (paginationMetadata.totalPages > (paginationMetadata.currentPage + 2))
{
PaginationLinks.Add
(
new NameIdUrlImage()
{
Name = "... ",
}
);
PaginationLinks.Add
(
new NameIdUrlImage()
{
Name = "صفحهٔ آخر",
Url = $"/User/Notifications/?page={paginationMetadata.totalPages}"
}
);
}
}
}
}
}
else
{
LastError = "لطفا از گنجور خارج و مجددا به آن وارد شوید.";
}
return Page();
}
public async Task<IActionResult> OnDeleteNotification(Guid id)
{
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
var response = await secureClient.DeleteAsync($"{APIRoot.Url}/api/notifications/{id}");
if (response.StatusCode != HttpStatusCode.OK)
{
return Redirect($"/login?redirect={Request.Path}&error={await response.Content.ReadAsStringAsync()}");
}
}
}
return new JsonResult(true);
}
}
}

View File

@ -0,0 +1,75 @@
@page
@model GanjooRazor.Areas.User.Pages.ReportedCommentsModel
@using DNTPersianUtils.Core
@{
Layout = "_Layout";
ViewData["Title"] = "حاشیه‌های گزارش شده";
await GanjooRazor.Utils.GanjoorSessionChecker.ApplyPermissionsToViewData(Request, Response, ViewData);
string color = "gray";
}
<h1>@ViewData["Title"]</h1>
@if (Model.LastError != "")
{
<h2>@Model.LastError</h2>
}
else
{
<p style="text-align:center">
@foreach (var paginationLink in Model.PaginationLinks)
{
if (!string.IsNullOrEmpty(paginationLink.Url))
{
<a href="@paginationLink.Url">@paginationLink.Name</a>
}
else
{
@paginationLink.Name
}
}
</p>
@foreach (var report in Model.Reports)
{
if (color == "gray")
color = "white";
else
color = "gray";
<div style="background-color:@color" id="comment-@report.Comment.Id">
<p style="color:red">
@report.ReasonCode
</p>
<hr />
<p style="color:red">
@report.ReasonText
</p>
<hr />
<blockquote>
@Html.Raw(report.Comment.HtmlComment)
<p>
@report.Comment.AuthorName <small>در @report.Comment.CommentDate.ToFriendlyPersianDateTextify()</small> دربارهٔ <a href="@report.Comment.Poem.UrlSlug">@report.Comment.Poem.Title</a>
</p>
</blockquote>
<a role="button" onclick="deleteComment(@report.Comment.Id, '@report.ReasonCode', '@report.ReasonText')" class="actionlink" style="color:green" title="تأیید و حذف حاشیه">✓ درست می‌گوید</a>
&nbsp;&nbsp;&nbsp;
<a role="button" onclick="deleteReport(@report.Id, @report.Comment.Id)" class="actionlink" style="color:red" title="حذف گزارش">گزارش نابجا ❌</a>
</div>
<hr />
}
<p style="text-align:center">
@foreach (var paginationLink in Model.PaginationLinks)
{
if (!string.IsNullOrEmpty(paginationLink.Url))
{
<a href="@paginationLink.Url">@paginationLink.Name</a>
}
else
{
@paginationLink.Name
}
}
</p>
}

View File

@ -0,0 +1,189 @@
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using DNTPersianUtils.Core;
using GanjooRazor.Utils;
using GSpotifyProxy.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RMuseum.Models.Ganjoor.ViewModels;
using RSecurityBackend.Models.Generic;
using System.Text;
namespace GanjooRazor.Areas.User.Pages
{
[IgnoreAntiforgeryToken(Order = 1001)]
public class ReportedCommentsModel : PageModel
{
/// <summary>
/// Last Error
/// </summary>
public string LastError { get; set; }
/// <summary>
/// comments
/// </summary>
public List<GanjoorCommentAbuseReportViewModel> Reports { get; set; }
/// <summary>
/// pagination links
/// </summary>
public List<NameIdUrlImage> PaginationLinks { get; set; }
public async Task<IActionResult> OnGetAsync()
{
LastError = "";
using (HttpClient secureClient = new HttpClient())
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
{
int pageNumber = 1;
if (!string.IsNullOrEmpty(Request.Query["page"]))
{
pageNumber = int.Parse(Request.Query["page"]);
}
var response = await secureClient.GetAsync($"{APIRoot.Url}/api/ganjoor/comments/reported?PageNumber={pageNumber}&PageSize=20");
if (!response.IsSuccessStatusCode)
{
LastError = await response.Content.ReadAsStringAsync();
return Page();
}
response.EnsureSuccessStatusCode();
Reports = JArray.Parse(await response.Content.ReadAsStringAsync()).ToObject<List<GanjoorCommentAbuseReportViewModel>>();
string paginnationMetadata = response.Headers.GetValues("paging-headers").FirstOrDefault();
if (!string.IsNullOrEmpty(paginnationMetadata))
{
PaginationMetadata paginationMetadata = JsonConvert.DeserializeObject<PaginationMetadata>(paginnationMetadata);
PaginationLinks = new List<NameIdUrlImage>();
if (paginationMetadata.totalPages > 1)
{
if (paginationMetadata.currentPage > 3)
{
PaginationLinks.Add
(
new NameIdUrlImage()
{
Name = "صفحهٔ اول",
Url = "/User/ReportedComments/?page=1"
}
);
}
for (int i = (paginationMetadata.currentPage - 2); i <= (paginationMetadata.currentPage + 2); i++)
{
if (i >= 1 && i <= paginationMetadata.totalPages)
{
if (i == paginationMetadata.currentPage)
{
PaginationLinks.Add
(
new NameIdUrlImage()
{
Name = i.ToPersianNumbers(),
}
);
}
else
{
PaginationLinks.Add
(
new NameIdUrlImage()
{
Name = i.ToPersianNumbers(),
Url = $"/User/ReportedComments/?page={i}"
}
);
}
}
}
if (paginationMetadata.totalPages > (paginationMetadata.currentPage + 2))
{
PaginationLinks.Add
(
new NameIdUrlImage()
{
Name = "... ",
}
);
PaginationLinks.Add
(
new NameIdUrlImage()
{
Name = "صفحهٔ آخر",
Url = $"/User/ReportedComments/?page={paginationMetadata.totalPages}"
}
);
}
}
}
}
}
else
{
LastError = "لطفا از گنجور خارج و مجددا به آن وارد شوید.";
}
return Page();
}
public async Task<IActionResult> OnPostModerateComment(int id, string reasonCode, string reasonText)
{
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
string reason;
switch(reasonCode)
{
case "offensive":
reason = "توهین آمیز است. " + reasonText;
break;
case "bogus":
reason = "نامفهوم است. " + reasonText;
break;
default:
reason = reasonText;
break;
}
var response = await secureClient.PostAsync($"{APIRoot.Url}/api/ganjoor/comment/moderate/{id}", new StringContent(JsonConvert.SerializeObject(reason), Encoding.UTF8, "application/json"));
if (response.StatusCode != HttpStatusCode.OK)
{
return Redirect($"/login?redirect={Request.Path}&error={await response.Content.ReadAsStringAsync()}");
}
}
}
return await OnGetAsync();
}
public async Task<IActionResult> OnDeleteReport(int id)
{
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
var response = await secureClient.DeleteAsync($"{APIRoot.Url}/api/ganjoor/comment/report/{id}");
if (response.StatusCode != HttpStatusCode.OK)
{
return Redirect($"/login?redirect={Request.Path}&error={await response.Content.ReadAsStringAsync()}");
}
}
}
return await OnGetAsync();
}
}
}

View File

@ -0,0 +1,171 @@
@page
@model GanjooRazor.Areas.User.Pages.ReviewSongsModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
Layout = "_Layout";
ViewData["Title"] = "آهنگ‌های پیشنهادی";
await GanjooRazor.Utils.GanjoorSessionChecker.ApplyPermissionsToViewData(Request, Response, ViewData);
}
<h1>@ViewData["Title"]</h1>
@if (Model.LastError != "")
{
<h2>@Model.LastError</h2>
}
else if (@Model.PoemMusicTrackViewModel == null)
{
<p>پیشنهادی وجود ندارد.</p>
}
else if (@Model.Poem == null)
{
<p>شعر مرتبط یافت نشد!</p>
}
else
{
<form method="post">
<table style="width:100%" class="noborder">
<tr>
<td>
<span class="inputlabel">شعر: </span>
</td>
<td>
<a href="@Html.Raw(Model.Poem.FullUrl)" target="_blank">@Model.Poem.FullTitle</a>
<input type="hidden" asp-for="PoemMusicTrackViewModel.Id" />
</td>
</tr>
<tr>
<td colspan="2">
@{
switch (Model.PoemMusicTrackViewModel.TrackType)
{
case RMuseum.Models.Ganjoor.PoemMusicTrackType.Spotify:
<img src="/image/spotify.png" alt="اسپاتیفای" height="32" />
break;
case RMuseum.Models.Ganjoor.PoemMusicTrackType.Golha:
<img src="/image/golha.png" alt="گلها" height="32" />
break;
default:
<img src="/image/beeptunes.png" alt="بیپ‌تونز" height="32" />
break;
}
}
</td>
</tr>
<tr>
<td>
<span class="inputlabel">خواننده: </span>
</td>
<td>
<input style="width:100%" asp-for="PoemMusicTrackViewModel.ArtistName" /><br />
</td>
</tr>
<tr>
<td>
<span class="inputlabel"><a target="_blank" href="@Html.Raw(Model.PoemMusicTrackViewModel.ArtistUrl)">نشانی خواننده:</a></span>
</td>
<td>
<input style="width:100%;text-align:left;direction:ltr;" asp-for="PoemMusicTrackViewModel.ArtistUrl" />
</td>
</tr>
<tr>
<td>
</td>
<td>
</td>
</tr>
<tr>
<td>
<span class="inputlabel">آلبوم:</span>
</td>
<td>
<input style="width:100%" asp-for="PoemMusicTrackViewModel.AlbumName" /><br />
</td>
</tr>
<tr>
<td>
<span class="inputlabel"><a target="_blank" href="@Html.Raw(Model.PoemMusicTrackViewModel.AlbumUrl)">نشانی آلبوم:</a></span>
</td>
<td>
<input style="width:100%;text-align:left;direction:ltr;" asp-for="PoemMusicTrackViewModel.AlbumUrl" />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">آهنگ:</span>
</td>
<td>
<input style="width:100%" asp-for="PoemMusicTrackViewModel.TrackName" />
</td>
</tr>
<tr>
<td>
<span class="inputlabel"><a target="_blank" href="@Html.Raw(Model.PoemMusicTrackViewModel.TrackUrl)">نشانی آهنگ:</a></span>
</td>
<td>
<input style="width:100%;text-align:left;direction:ltr;" asp-for="PoemMusicTrackViewModel.TrackUrl" />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">توضیح: </span>
</td>
<td>
<input style="width:100%" asp-for="PoemMusicTrackViewModel.Description" /><br />
</td>
</tr>
<tr>
<td>
<button type="submit" name="approve" id="approve" style="width:100%;color:white;background-color:green">تأیید</button>
</td>
<td>
<table style="width:100%" class="noborder">
<tr>
<td>
<button type="submit" name="reject1" id="reject1" style="width:100%;color:white;background-color:darkred">در آهنگ این شعر خوانده نشده</button>
</td>
</tr>
<tr>
<td>
<button type="submit" name="reject1" id="reject1" style="width:100%;color:white;background-color:darkred">لینک یا اطلاعات آهنگ ایراد دارد</button>
</td>
</tr>
<tr>
<td>
<button type="submit" name="reject1" id="reject1" style="width:100%;color:white;background-color:darkred">رد به دلیل دیگر:</button>
</td>
<td>
<input style="width:100%" asp-for="PoemMusicTrackViewModel.RejectionCause" /><br />
</td>
</tr>
<tr>
<td>
<button type="submit" name="next" id="next" style="width:100%;color:white;background-color:orange">بعدی</button>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
تعداد کل:
</td>
<td>
@Model.TotalCount
</td>
</tr>
</table>
</form>
}
@if(ViewData.ContainsKey("ganjoor-songrevu"))
{
<a class="nav-link text-dark" asp-area="User" asp-page="/AddSong">اضافه کردن آهنگ از منبع دلخواه</a>
}

View File

@ -0,0 +1,151 @@
using DNTPersianUtils.Core;
using GanjooRazor.Utils;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Newtonsoft.Json;
using RMuseum.Models.Ganjoor.ViewModels;
using RSecurityBackend.Models.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace GanjooRazor.Areas.User.Pages
{
public class ReviewSongsModel : PageModel
{
/// <summary>
/// Last Error
/// </summary>
public string LastError { get; set; }
/// <summary>
/// api model
/// </summary>
[BindProperty]
public PoemMusicTrackViewModel PoemMusicTrackViewModel { get; set; }
/// <summary>
/// poem model
/// </summary>
public GanjoorPoemCompleteViewModel Poem { get; set; }
/// <summary>
/// skip
/// </summary>
public int Skip { get; set; }
/// <summary>
/// total count
/// </summary>
public int TotalCount { get; set; }
/// <summary>
/// get
/// </summary>
public async Task OnGetAsync()
{
LastError = "";
TotalCount = 0;
Skip = string.IsNullOrEmpty(Request.Query["skip"]) ? 0 : int.Parse(Request.Query["skip"]);
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
var trackResponse = await secureClient.GetAsync($"{APIRoot.Url}/api/ganjoor/song?skip={Skip}&onlyMine=false");
if (!trackResponse.IsSuccessStatusCode)
{
LastError = await trackResponse.Content.ReadAsStringAsync();
}
else
{
string paginnationMetadata = trackResponse.Headers.GetValues("paging-headers").FirstOrDefault();
if (!string.IsNullOrEmpty(paginnationMetadata))
{
TotalCount = JsonConvert.DeserializeObject<PaginationMetadata>(paginnationMetadata).totalCount;
}
PoemMusicTrackViewModel = JsonConvert.DeserializeObject<PoemMusicTrackViewModel>(await trackResponse.Content.ReadAsStringAsync());
PoemMusicTrackViewModel.ArtistName = PoemMusicTrackViewModel.ArtistName.ToPersianNumbers().ApplyCorrectYeKe();
PoemMusicTrackViewModel.AlbumName = PoemMusicTrackViewModel.AlbumName.ToPersianNumbers().ApplyCorrectYeKe();
PoemMusicTrackViewModel.TrackName = PoemMusicTrackViewModel.TrackName.ToPersianNumbers().ApplyCorrectYeKe();
var poemResponse = await secureClient.GetAsync($"{APIRoot.Url}/api/ganjoor/poem/{PoemMusicTrackViewModel.PoemId}?catInfo=false&rhymes=false&recitations=false&images=false&songs=false&comments=false&verseDetails=false&navigation=false");
if (poemResponse.IsSuccessStatusCode)
{
Poem = JsonConvert.DeserializeObject<GanjoorPoemCompleteViewModel>(await poemResponse.Content.ReadAsStringAsync());
}
else
{
LastError = "لطفا از گنجور خارج و مجددا به آن وارد شوید.";
}
}
}
else
{
LastError = "لطفا از گنجور خارج و مجددا به آن وارد شوید.";
}
}
}
public async Task<IActionResult> OnPostAsync()
{
Skip = string.IsNullOrEmpty(Request.Query["skip"]) ? 0 : int.Parse(Request.Query["skip"]);
if (Request.Form["next"].Count == 1)
{
return Redirect($"/User/ReviewSongs/?skip={Skip + 1}");
}
PoemMusicTrackViewModel.Approved = Request.Form["approve"].Count == 1;
PoemMusicTrackViewModel.Rejected = (Request.Form["reject1"].Count + Request.Form["reject2"].Count + Request.Form["reject3"].Count) > 0;
if(string.IsNullOrEmpty(PoemMusicTrackViewModel.RejectionCause))
{
if (Request.Form["reject1"].Count == 1)
{
PoemMusicTrackViewModel.RejectionCause = "در آهنگ این شعر خوانده نشده";
}
else
if (Request.Form["reject2"].Count == 1)
{
PoemMusicTrackViewModel.RejectionCause = "لینک یا اطلاعات آهنگ ایراد دارد";
}
}
using (HttpClient secureClient = new HttpClient())
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
var putResponse = await secureClient.PutAsync($"{APIRoot.Url}/api/ganjoor/song", new StringContent(JsonConvert.SerializeObject(PoemMusicTrackViewModel), Encoding.UTF8, "application/json"));
if (!putResponse.IsSuccessStatusCode)
{
LastError = await putResponse.Content.ReadAsStringAsync();
}
}
else
{
LastError = "لطفا از گنجور خارج و مجددا به آن وارد شوید.";
}
}
if(!string.IsNullOrEmpty(LastError))
{
return Page();
}
return Redirect($"/User/ReviewSongs/?skip={Skip}");
}
}
}

View File

@ -0,0 +1,26 @@
using Microsoft.AspNetCore.Http;
namespace GanjooRazor.Models
{
/// <summary>
/// banner upload model
/// </summary>
public class BannerUploadModel
{
/// <summary>
/// image
/// </summary>
public IFormFile Image { get; set; }
/// <summary>
/// altername text
/// </summary>
public string Alt { get; set; }
/// <summary>
/// target url
/// </summary>
public string Url { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using RSecurityBackend.Models.Auth.ViewModels;
namespace GanjooRazor.Models.User
{
/// <summary>
/// change password model
/// </summary>
public class ChangePasswordModel : SetPasswordModel
{
/// <summary>
/// new password model
/// </summary>
public string NewPasswordRepeat { get; set; }
}
}

View File

@ -19,8 +19,6 @@ using RSecurityBackend.Services.Implementation;
using DNTPersianUtils.Core;
using System.IO;
using RSecurityBackend.Models.Image;
using Microsoft.Data.SqlClient;
using Dapper;
namespace RMuseum.Services.Implementation
{
@ -58,6 +56,7 @@ namespace RMuseum.Services.Implementation
ImageUrl = poet.RImageId == null ? "" : $"/api/ganjoor/poet/image{cat.FullUrl}.png"
}
)
.AsNoTracking()
.ToListAsync();
StringComparer fa = StringComparer.Create(new CultureInfo("fa-IR"), true);
@ -83,10 +82,10 @@ namespace RMuseum.Services.Implementation
{
try
{
var poet = await _context.GanjoorPoets.Where(p => p.Id == id).FirstOrDefaultAsync();
var poet = await _context.GanjoorPoets.Where(p => p.Id == id).AsNoTracking().FirstOrDefaultAsync();
if (poet == null)
return new RServiceResult<GanjoorPoetCompleteViewModel>(null);
var cat = await _context.GanjoorCategories.Where(c => c.ParentId == null && c.PoetId == id).FirstOrDefaultAsync();
var cat = await _context.GanjoorCategories.Where(c => c.ParentId == null && c.PoetId == id).AsNoTracking().FirstOrDefaultAsync();
return await GetCatById(cat.Id);
}
catch (Exception exp)
@ -109,7 +108,7 @@ namespace RMuseum.Services.Implementation
{
url = url.Substring(0, url.Length - 1);
}
var cat = await _context.GanjoorCategories.Where(c => c.FullUrl == url && c.ParentId == null).SingleOrDefaultAsync();
var cat = await _context.GanjoorCategories.Where(c => c.FullUrl == url && c.ParentId == null).AsNoTracking().SingleOrDefaultAsync();
if (cat == null)
return new RServiceResult<GanjoorPoetCompleteViewModel>(null);
return await GetCatById(cat.Id);
@ -134,10 +133,10 @@ namespace RMuseum.Services.Implementation
{
url = url.Substring(0, url.Length - 1);
}
var cat = await _context.GanjoorCategories.Where(c => c.FullUrl == url && c.ParentId == null).SingleOrDefaultAsync();
var cat = await _context.GanjoorCategories.Where(c => c.FullUrl == url && c.ParentId == null).AsNoTracking().SingleOrDefaultAsync();
if (cat == null)
return new RServiceResult<Guid>(Guid.Empty);
var poet = await _context.GanjoorPoets.Where(p => p.Id == cat.PoetId).SingleOrDefaultAsync();
var poet = await _context.GanjoorPoets.Where(p => p.Id == cat.PoetId).AsNoTracking().SingleOrDefaultAsync();
return new RServiceResult<Guid>((Guid)poet.RImageId);
}
catch (Exception exp)
@ -161,7 +160,7 @@ namespace RMuseum.Services.Implementation
{
url = url.Substring(0, url.Length - 1);
}
var cat = await _context.GanjoorCategories.Where(c => c.FullUrl == url).SingleOrDefaultAsync();
var cat = await _context.GanjoorCategories.Where(c => c.FullUrl == url).AsNoTracking().SingleOrDefaultAsync();
if (cat == null)
return new RServiceResult<GanjoorPoetCompleteViewModel>(null);
return await GetCatById(cat.Id);
@ -183,7 +182,7 @@ namespace RMuseum.Services.Implementation
try
{
var cat = await _context.GanjoorCategories.Include(c => c.Poet).Include(c => c.Parent).Where(c => c.Id == id).FirstOrDefaultAsync();
var cat = await _context.GanjoorCategories.Include(c => c.Poet).Include(c => c.Parent).Where(c => c.Id == id).AsNoTracking().FirstOrDefaultAsync();
if (cat == null)
return new RServiceResult<GanjoorPoetCompleteViewModel>(null);
@ -200,7 +199,7 @@ namespace RMuseum.Services.Implementation
FullUrl = parent.FullUrl
});
parent = await _context.GanjoorCategories.Where(c => c.Id == parent.ParentId).FirstOrDefaultAsync();
parent = await _context.GanjoorCategories.Where(c => c.Id == parent.ParentId).AsNoTracking().FirstOrDefaultAsync();
}
@ -223,7 +222,7 @@ namespace RMuseum.Services.Implementation
FullUrl = c.FullUrl
//other fields null
}
).SingleOrDefaultAsync();
).AsNoTracking().SingleOrDefaultAsync();
int preCatId =
await _context.GanjoorCategories.Where(c => c.PoetId == cat.PoetId && c.ParentId == cat.ParentId && c.Id < id).AnyAsync() ?
@ -244,7 +243,7 @@ namespace RMuseum.Services.Implementation
FullUrl = c.FullUrl
//other fields null
}
).SingleOrDefaultAsync();
).AsNoTracking().SingleOrDefaultAsync();
GanjoorCatViewModel catViewModel = new GanjoorCatViewModel()
{
@ -264,7 +263,7 @@ namespace RMuseum.Services.Implementation
UrlSlug = c.UrlSlug,
FullUrl = c.FullUrl
}
).ToListAsync(),
).AsNoTracking().ToListAsync(),
Poems = poems ? await _context.GanjoorPoems.Where(p => p.CatId == cat.Id).OrderBy(p => p.Id).Select
(
p => new GanjoorPoemSummaryViewModel()
@ -274,7 +273,7 @@ namespace RMuseum.Services.Implementation
UrlSlug = p.UrlSlug,
Excerpt = _context.GanjoorVerses.Where(v => v.PoemId == p.Id && v.VOrder == 1).FirstOrDefault().Text
}
).ToListAsync()
).AsNoTracking().ToListAsync()
:
null
};
@ -294,7 +293,7 @@ namespace RMuseum.Services.Implementation
Nickname = p.Nickname,
Published = p.Published,
ImageUrl = p.RImageId == null ? "" : $"/api/ganjoor/poet/image{_context.GanjoorCategories.Where(c => c.PoetId == p.Id && c.ParentId == null).Single().FullUrl}.png"
}).FirstOrDefaultAsync(),
}).AsNoTracking().FirstOrDefaultAsync(),
Cat = catViewModel
}
);
@ -315,7 +314,7 @@ namespace RMuseum.Services.Implementation
{
try
{
var dbPage = await _context.GanjoorPages.Where(p => p.Id == id).SingleOrDefaultAsync();
var dbPage = await _context.GanjoorPages.Where(p => p.Id == id).AsNoTracking().SingleOrDefaultAsync();
if (dbPage == null)
return new RServiceResult<string>(null); //not found
return new RServiceResult<string>(dbPage.FullUrl);
@ -347,7 +346,7 @@ namespace RMuseum.Services.Implementation
url = url.Substring(0, url.Length - 1);
}
var dbPage = await _context.GanjoorPages.Where(p => p.FullUrl == url).SingleOrDefaultAsync();
var dbPage = await _context.GanjoorPages.Where(p => p.FullUrl == url).AsNoTracking().SingleOrDefaultAsync();
if (dbPage == null)
return new RServiceResult<GanjoorPageCompleteViewModel>(null); //not found
var secondPoet = dbPage.SecondPoetId == null ? null :
@ -368,7 +367,7 @@ namespace RMuseum.Services.Implementation
ImageUrl = poet.RImageId == null ? "" : $"/api/ganjoor/poet/image{cat.FullUrl}.png"
}
)
.SingleAsync();
.AsNoTracking().SingleAsync();
GanjoorPageCompleteViewModel page = new GanjoorPageCompleteViewModel()
{
Id = dbPage.Id,
@ -419,6 +418,7 @@ namespace RMuseum.Services.Implementation
((p.PageOrder < dbPage.PageOrder) || (p.PageOrder == dbPage.PageOrder && p.Id < dbPage.Id)))
.OrderByDescending(p => p.PageOrder)
.ThenByDescending(p => p.Id)
.AsNoTracking()
.FirstOrDefaultAsync();
if(pre != null)
{
@ -434,6 +434,7 @@ namespace RMuseum.Services.Implementation
((p.PageOrder > dbPage.PageOrder) || (p.PageOrder == dbPage.PageOrder && p.Id > dbPage.Id)))
.OrderBy(p => p.PageOrder)
.ThenBy(p => p.Id)
.AsNoTracking()
.FirstOrDefaultAsync();
if (next != null)
{
@ -498,7 +499,7 @@ namespace RMuseum.Services.Implementation
PlainText = "", //poem.PlainText
HtmlText = "",//poem.HtmlText
};
return new RServiceResult<PublicRecitationViewModel[]>(await source.ToArrayAsync());
return new RServiceResult<PublicRecitationViewModel[]>(await source.AsNoTracking().ToArrayAsync());
}
catch (Exception exp)
{
@ -537,7 +538,7 @@ namespace RMuseum.Services.Implementation
UserId = comment.UserId
};
GanjoorCommentSummaryViewModel[] allComments = await source.ToArrayAsync();
GanjoorCommentSummaryViewModel[] allComments = await source.AsNoTracking().ToArrayAsync();
foreach (GanjoorCommentSummaryViewModel comment in allComments)
{
@ -784,7 +785,7 @@ namespace RMuseum.Services.Implementation
private async Task<List<GanjoorComment>> _FindReplies(GanjoorComment comment)
{
List<GanjoorComment> replies = await _context.GanjoorComments.Where(c => c.InReplyToId == comment.Id).ToListAsync();
List<GanjoorComment> replies = await _context.GanjoorComments.Where(c => c.InReplyToId == comment.Id).AsNoTracking().ToListAsync();
List<GanjoorComment> replyToReplies = new List<GanjoorComment>();
foreach (GanjoorComment reply in replies)
{
@ -1022,7 +1023,7 @@ namespace RMuseum.Services.Implementation
AltText = link.AltText,
};
museumImages.AddRange(await externalSrc.ToListAsync());
museumImages.AddRange(await externalSrc.AsNoTracking().ToListAsync());
for (int i = 0; i < museumImages.Count; i++)
{
@ -1092,7 +1093,7 @@ namespace RMuseum.Services.Implementation
{
try
{
var poem = await _context.GanjoorPoems.Include(p => p.GanjoorMetre).Where(p => p.Id == id).SingleOrDefaultAsync();
var poem = await _context.GanjoorPoems.Include(p => p.GanjoorMetre).Where(p => p.Id == id).AsNoTracking().SingleOrDefaultAsync();
if (poem == null)
{
return new RServiceResult<GanjoorPoemCompleteViewModel>(null); //not found
@ -1133,7 +1134,7 @@ namespace RMuseum.Services.Implementation
UrlSlug = p.UrlSlug,
Excerpt = _context.GanjoorVerses.Where(v => v.PoemId == p.Id && v.VOrder == 1).FirstOrDefault().Text
}
).SingleAsync();
).AsNoTracking().SingleAsync();
}
}
@ -1163,7 +1164,7 @@ namespace RMuseum.Services.Implementation
UrlSlug = p.UrlSlug,
Excerpt = _context.GanjoorVerses.Where(v => v.PoemId == p.Id && v.VOrder == 1).FirstOrDefault().Text
}
).SingleAsync();
).AsNoTracking().SingleAsync();
}
}
@ -1201,7 +1202,7 @@ namespace RMuseum.Services.Implementation
VersePosition = v.VersePosition,
Text = v.Text
}
).ToArrayAsync();
).AsNoTracking().ToArrayAsync();
};
@ -1307,7 +1308,7 @@ namespace RMuseum.Services.Implementation
RejectionCause = t.RejectionCause
}
).ToArrayAsync()
).AsNoTracking().ToArrayAsync()
);
}
catch (Exception exp)
@ -1434,7 +1435,7 @@ namespace RMuseum.Services.Implementation
{
var song = await _context.GanjoorPoemMusicTracks
.Where(p => p.Approved == false && p.Rejected == false && (suggestedById == Guid.Empty || p.SuggestedById == suggestedById))
.OrderBy(p => p.Id).Skip(skip).FirstOrDefaultAsync();
.OrderBy(p => p.Id).Skip(skip).AsNoTracking().FirstOrDefaultAsync();
if (song != null)
{
return new RServiceResult<PoemMusicTrackViewModel>
@ -1639,12 +1640,12 @@ namespace RMuseum.Services.Implementation
try
{
int poemId = _GetRandomPoemId(2);
var poem = await _context.GanjoorPoems.Where(p => p.Id == poemId).SingleOrDefaultAsync();
var poem = await _context.GanjoorPoems.Where(p => p.Id == poemId).AsNoTracking().SingleOrDefaultAsync();
PublicRecitationViewModel[] recitations = poem == null ? new PublicRecitationViewModel[] { } : (await GetPoemRecitations(poemId)).Result;
int loopPreventer = 0;
while (poem == null || recitations.Length == 0)
{
poem = await _context.GanjoorPoems.Where(p => p.Id == poemId).SingleOrDefaultAsync();
poem = await _context.GanjoorPoems.Where(p => p.Id == poemId).AsNoTracking().SingleOrDefaultAsync();
recitations = poem == null ? new PublicRecitationViewModel[] { } : (await GetPoemRecitations(poemId)).Result;
loopPreventer++;
if (loopPreventer > 5)
@ -1751,7 +1752,7 @@ namespace RMuseum.Services.Implementation
},
}
);
).AsNoTracking();
(PaginationMetadata PagingMeta, GanjoorPoemCompleteViewModel[] Items) paginatedResult =
@ -1883,7 +1884,7 @@ namespace RMuseum.Services.Implementation
}
},
}
);
).AsNoTracking();
@ -2036,7 +2037,7 @@ namespace RMuseum.Services.Implementation
{
try
{
return new RServiceResult<GanjoorMetre[]>(await _context.GanjoorMetres.OrderBy(m => m.Rhythm).ToArrayAsync());
return new RServiceResult<GanjoorMetre[]>(await _context.GanjoorMetres.OrderBy(m => m.Rhythm).AsNoTracking().ToArrayAsync());
}
catch(Exception exp)
{
@ -2205,7 +2206,7 @@ namespace RMuseum.Services.Implementation
AlternateText = b.AlternateText,
TargetUrl = b.TargetUrl,
Active = b.Active
}).SingleAsync()
}).AsNoTracking().SingleAsync()
);
}