#203 activating language combo + last user contribution api

This commit is contained in:
Hamid Reza Mohammadi 2021-09-16 19:01:37 +04:30
parent df23e98f33
commit 7cf14c1e5b
7 changed files with 276 additions and 116 deletions

View File

@ -19,12 +19,28 @@
}
else
{
<select name="languages" id="languages">
@foreach (var language in Model.Languages)
<select name="languages" id="languages">
@foreach (var language in Model.Languages)
{
@if (language.Id == Model.Translation.Language.Id)
{
<option value="@language.Id" selected>@language.Name</option>
}
else
{
<option value="@language.Id">@language.Name</option>
}
</select>
}
</select>
<script>
$('#languages').change(
function () {
var langId = $('#languages option:selected').val();
location.href = '/User/Translate?id=@Model.PageInformation.Id&lang=' + String(langId);
}
);
</script>
<p><a role="button" target="_blank" href="/User/Languages" class="actionlink">معرفی زبان‌ها و نویسش‌ها</a></p>

View File

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
@ -27,6 +28,11 @@ namespace GanjooRazor.Areas.User.Pages
/// </summary>
public GanjoorLanguage[] Languages { get; set; }
/// <summary>
/// translations
/// </summary>
public GanjoorPoemTranslationViewModel[] Translations { get; set; }
/// <summary>
/// translation
/// </summary>
@ -98,32 +104,92 @@ namespace GanjooRazor.Areas.User.Pages
{
if (await GanjoorSessionChecker.PrepareClient(secureClient, Request, Response))
{
HttpResponseMessage response = await secureClient.GetAsync($"{APIRoot.Url}/api/translations/languages");
int poemId = int.Parse(Request.Query["id"]);
int langId = string.IsNullOrEmpty(Request.Query["lang"]) ? -1 : int.Parse(Request.Query["lang"]);
HttpResponseMessage response = await secureClient.GetAsync($"{APIRoot.Url}/api/translations/poem/{poemId}/language/{langId}");
if (!response.IsSuccessStatusCode)
{
FatalError = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
return Page();
}
response.EnsureSuccessStatusCode();
var translations = JsonConvert.DeserializeObject<GanjoorPoemTranslationViewModel[]>(await response.Content.ReadAsStringAsync());
var userInfoResponse = await secureClient.GetAsync($"{APIRoot.Url}/api/users/{Request.Cookies["UserId"]}");
if (userInfoResponse.IsSuccessStatusCode)
if (!response.IsSuccessStatusCode)
{
UserInfo = JsonConvert.DeserializeObject<PublicRAppUser>(await userInfoResponse.Content.ReadAsStringAsync());
FatalError = JsonConvert.DeserializeObject<string>(await response.Content.ReadAsStringAsync());
return Page();
}
UserInfo = JsonConvert.DeserializeObject<PublicRAppUser>(await userInfoResponse.Content.ReadAsStringAsync());
if (langId == -1)
{
var lastLangResp = await secureClient.GetAsync($"{APIRoot.Url}/api/translations/user/lastlanguage");
if (response.StatusCode != HttpStatusCode.NotFound)
{
var lang = JsonConvert.DeserializeObject<GanjoorLanguage>(await lastLangResp.Content.ReadAsStringAsync());
langId = lang.Id;
}
}
Languages = JsonConvert.DeserializeObject<GanjoorLanguage[]>(await response.Content.ReadAsStringAsync());
if (langId != -1)
{
Translations = translations;
foreach (var translation in translations)
if (translation.ContributerId == UserInfo.Id && langId == translation.Language.Id)
{
Translation = translation;
break;
}
}
else if (translations.Length > 0)
{
foreach (var translation in translations)
if (translation.ContributerId == UserInfo.Id)
{
Translation = translation;
langId = Translation.Language.Id;
break;
}
if (langId == -1)
{
Translation = translations[0];
langId = Translation.Language.Id;
}
Translations = translations.Where(t => t.Language.Id == langId).ToArray();
}
HttpResponseMessage responseLanguages = await secureClient.GetAsync($"{APIRoot.Url}/api/translations/languages");
if (!responseLanguages.IsSuccessStatusCode)
{
FatalError = JsonConvert.DeserializeObject<string>(await responseLanguages.Content.ReadAsStringAsync());
return Page();
}
responseLanguages.EnsureSuccessStatusCode();
Languages = JsonConvert.DeserializeObject<GanjoorLanguage[]>(await responseLanguages.Content.ReadAsStringAsync());
if(Languages.Length == 0)
{
FatalError = "<a role=\"button\" target=\"_blank\" href=\"/User/Languages\" class=\"actionlink\">معرفی زبان‌ها و نویسش‌ها</a>";
return Page();
}
var pageUrlResponse = await secureClient.GetAsync($"{APIRoot.Url}/api/ganjoor/pageurl?id={Request.Query["id"]}");
if (langId == -1)
{
langId = Languages[0].Id;
}
var pageUrlResponse = await secureClient.GetAsync($"{APIRoot.Url}/api/ganjoor/pageurl?id={poemId}");
pageUrlResponse.EnsureSuccessStatusCode();
var pageUrl = JsonConvert.DeserializeObject<string>(await pageUrlResponse.Content.ReadAsStringAsync());
@ -131,23 +197,30 @@ namespace GanjooRazor.Areas.User.Pages
pageQuery.EnsureSuccessStatusCode();
PageInformation = JObject.Parse(await pageQuery.Content.ReadAsStringAsync()).ToObject<GanjoorPageCompleteViewModel>();
Translation = new GanjoorPoemTranslationViewModel()
if(Translation == null)
{
Language = Languages[0],
PoemId = PageInformation.Id,
Title = "",
Published = false,
Description = "",
ContributerName = UserInfo.NickName == null ? UserInfo.Id.ToString() : UserInfo.NickName,
TranslatedVerses = PageInformation.Poem.Verses.Select(v =>
new GanjoorVerseTranslationViewModel()
Translation = new GanjoorPoemTranslationViewModel()
{
Verse = v,
TText = ""
}
Language = Languages.Where(l => l.Id == langId).Single(),
PoemId = PageInformation.Id,
Title = "",
Published = false,
Description = "",
ContributerName = UserInfo.NickName == null ? UserInfo.Id.ToString() : UserInfo.NickName,
TranslatedVerses = PageInformation.Poem.Verses.Select(v =>
new GanjoorVerseTranslationViewModel()
{
Verse = v,
TText = ""
}
).ToArray()
};
};
Translations = new GanjoorPoemTranslationViewModel[] { Translation };
}
}
else
{

View File

@ -32,7 +32,7 @@ namespace RMuseum.Controllers
}
/// <summary>
/// get langauge by id
/// get language by id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
@ -50,7 +50,7 @@ namespace RMuseum.Controllers
}
/// <summary>
/// add new langauge
/// add new language
/// </summary>
/// <param name="lang"></param>
/// <returns></returns>
@ -110,10 +110,12 @@ namespace RMuseum.Controllers
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task<IActionResult> GetPublishedTranslationsAsync(int id)
{
var res = await _translationService.GetPublishedTranslationsAsync(id);
var res = await _translationService.GetPoemTranslationsAsync(-1, id, true, false);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
return Ok(res.Result);
if (res.Result.Length > 0)
return Ok(res.Result[0]);
return NotFound();
}
/// <summary>
@ -122,14 +124,53 @@ namespace RMuseum.Controllers
/// <param name="id"></param>
/// <param name="lang"></param>
/// <returns></returns>
[HttpGet("poem/{id}/langauge/{lang}/published")]
[HttpGet("poem/{id}/language/{lang}/published")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorPoemTranslationViewModel))]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task<IActionResult> GetPublishedTranslationAsync(int id, int lang)
{
var res = await _translationService.GetPublishedTranslationAsync(id, lang);
var res = await _translationService.GetPoemTranslationsAsync(lang, id, true, false);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (res.Result.Length > 0)
return Ok(res.Result[0]);
return NotFound();
}
/// <summary>
/// get all translations of a poem in a specific language
/// </summary>
/// <param name="id"></param>
/// <param name="lang">send -1 for all languages</param>
/// <returns></returns>
[HttpGet("poem/{id}/language/{lang}")]
[Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.Translations)]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorPoemTranslationViewModel[]))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task<IActionResult> GetPoemTranslationsAsync(int id, int lang)
{
var res = await _translationService.GetPoemTranslationsAsync(lang, id, false, true);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
return Ok(res.Result);
}
/// <summary>
/// last language user has contributed in its translation
/// </summary>
/// <returns></returns>
[HttpGet("user/lastlanguage")]
[Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.Translations)]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorLanguage))]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task<IActionResult> GetLastUserContributedLanguage()
{
Guid userId = new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value);
var res = await _translationService.GetLastUserContributedLanguage(userId);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (res.Result == null)

View File

@ -1,4 +1,7 @@
namespace RMuseum.Models.Ganjoor.ViewModels
using DNTPersianUtils.Core;
using System;
namespace RMuseum.Models.Ganjoor.ViewModels
{
/// <summary>
/// poem translation view model
@ -35,13 +38,36 @@
public string Description { get; set; }
/// <summary>
/// contributer name
/// might be empty in anonymous apis
/// </summary>
public Guid ContributerId { get; set; }
/// <summary>
/// contributer name - might be empty in anonymous apis
/// </summary>
public string ContributerName { get; set; }
/// <summary>
/// datetime
/// </summary>
public DateTime DateTime { get; set; }
/// <summary>
/// translated verses
/// </summary>
public GanjoorVerseTranslationViewModel[] TranslatedVerses { get; set; }
/// <summary>
/// to string
/// </summary>
/// <returns></returns>
public override string ToString()
{
if(Id != 0)
{
return $"{ContributerName}-{DateTime.ToFriendlyPersianDateTextify()}";
}
return "جدید";
}
}
}

View File

@ -1642,14 +1642,14 @@
</member>
<member name="M:RMuseum.Controllers.TranslationController.GetLanguageAsync(System.Int32)">
<summary>
get langauge by id
get language by id
</summary>
<param name="id"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Controllers.TranslationController.AddLanguageAsync(RMuseum.Models.Ganjoor.GanjoorLanguage)">
<summary>
add new langauge
add new language
</summary>
<param name="lang"></param>
<returns></returns>
@ -1676,6 +1676,20 @@
<param name="lang"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Controllers.TranslationController.GetPoemTranslationsAsync(System.Int32,System.Int32)">
<summary>
get all translations of a poem in a specific language
</summary>
<param name="id"></param>
<param name="lang">send -1 for all languages</param>
<returns></returns>
</member>
<member name="M:RMuseum.Controllers.TranslationController.GetLastUserContributedLanguage">
<summary>
last language user has contributed in its translation
</summary>
<returns></returns>
</member>
<member name="M:RMuseum.Controllers.TranslationController.AddOrUpdatePoemTranslation(RMuseum.Models.Ganjoor.ViewModels.GanjoorPoemTranslationViewModel)">
<summary>
add translation for a poem (please specify verses VORder, Id is not processed)
@ -6223,9 +6237,19 @@
comments or description
</summary>
</member>
<member name="P:RMuseum.Models.Ganjoor.ViewModels.GanjoorPoemTranslationViewModel.ContributerId">
<summary>
might be empty in anonymous apis
</summary>
</member>
<member name="P:RMuseum.Models.Ganjoor.ViewModels.GanjoorPoemTranslationViewModel.ContributerName">
<summary>
contributer name
contributer name - might be empty in anonymous apis
</summary>
</member>
<member name="P:RMuseum.Models.Ganjoor.ViewModels.GanjoorPoemTranslationViewModel.DateTime">
<summary>
datetime
</summary>
</member>
<member name="P:RMuseum.Models.Ganjoor.ViewModels.GanjoorPoemTranslationViewModel.TranslatedVerses">
@ -6233,6 +6257,12 @@
translated verses
</summary>
</member>
<member name="M:RMuseum.Models.Ganjoor.ViewModels.GanjoorPoemTranslationViewModel.ToString">
<summary>
to string
</summary>
<returns></returns>
</member>
<member name="T:RMuseum.Models.Ganjoor.ViewModels.GanjoorPoetCompleteViewModel">
<summary>
Poet Complete Information
@ -8508,19 +8538,21 @@
<param name="userId"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Services.IGanjoorTranslationService.GetPublishedTranslationsAsync(System.Int32)">
<summary>
get translations for a poem
</summary>
<param name="poemId"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Services.IGanjoorTranslationService.GetPublishedTranslationAsync(System.Int32,System.Int32)">
<member name="M:RMuseum.Services.IGanjoorTranslationService.GetPoemTranslationsAsync(System.Int32,System.Int32,System.Boolean,System.Boolean)">
<summary>
get translation
</summary>
<param name="langId"></param>
<param name="langId">-1 all languages</param>
<param name="poemId"></param>
<param name="onlyPublished"></param>
<param name="includeUserInfo"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Services.IGanjoorTranslationService.GetLastUserContributedLanguage(System.Guid)">
<summary>
get last language the user contributed to its translation
</summary>
<param name="userId"></param>
<returns></returns>
</member>
<member name="T:RMuseum.Services.Implementation.ArtifactService">
@ -10165,19 +10197,21 @@
<param name="translation"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Services.Implementation.GanjoorTranslationService.GetPublishedTranslationAsync(System.Int32,System.Int32)">
<member name="M:RMuseum.Services.Implementation.GanjoorTranslationService.GetLastUserContributedLanguage(System.Guid)">
<summary>
get last language the user contributed to its translation
</summary>
<param name="userId"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Services.Implementation.GanjoorTranslationService.GetPoemTranslationsAsync(System.Int32,System.Int32,System.Boolean,System.Boolean)">
<summary>
get translation
</summary>
<param name="langId"></param>
<param name="poemId"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Services.Implementation.GanjoorTranslationService.GetPublishedTranslationsAsync(System.Int32)">
<summary>
get translations for a poem
</summary>
<param name="poemId"></param>
<param name="onlyPublished"></param>
<param name="includeUserInfo"></param>
<returns></returns>
</member>
<member name="F:RMuseum.Services.Implementation.GanjoorTranslationService._context">

View File

@ -56,19 +56,21 @@ namespace RMuseum.Services
/// <returns></returns>
Task<RServiceResult<GanjoorPoemTranslationViewModel>> AddPoemTranslation(Guid userId, GanjoorPoemTranslationViewModel translation);
/// <summary>
/// get translations for a poem
/// </summary>
/// <param name="poemId"></param>
/// <returns></returns>
Task<RServiceResult<GanjoorPoemTranslationViewModel[]>> GetPublishedTranslationsAsync(int poemId);
/// <summary>
/// get translation
/// </summary>
/// <param name="langId"></param>
/// <param name="langId">-1 all languages</param>
/// <param name="poemId"></param>
/// <param name="onlyPublished"></param>
/// <param name="includeUserInfo"></param>
/// <returns></returns>
Task<RServiceResult<GanjoorPoemTranslationViewModel>> GetPublishedTranslationAsync(int langId, int poemId);
Task<RServiceResult<GanjoorPoemTranslationViewModel[]>> GetPoemTranslationsAsync(int langId, int poemId, bool onlyPublished, bool includeUserInfo);
/// <summary>
/// get last language the user contributed to its translation
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
Task<RServiceResult<GanjoorLanguage>> GetLastUserContributedLanguage(Guid userId);
}
}

View File

@ -184,68 +184,33 @@ namespace RMuseum.Services.Implementation
}
}
/// <summary>
/// get last language the user contributed to its translation
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public async Task<RServiceResult<GanjoorLanguage>> GetLastUserContributedLanguage(Guid userId)
{
var dbTranslation = await _context.GanjoorPoemTranslations.Where(t => t.UserId == userId).OrderByDescending(t => t.Id).FirstOrDefaultAsync();
if (dbTranslation == null)
return new RServiceResult<GanjoorLanguage>(null);
return await GetLanguageAsync(dbTranslation.LanguageId);
}
/// <summary>
/// get translation
/// </summary>
/// <param name="langId"></param>
/// <param name="poemId"></param>
/// <param name="onlyPublished"></param>
/// <param name="includeUserInfo"></param>
/// <returns></returns>
public async Task<RServiceResult<GanjoorPoemTranslationViewModel>> GetPublishedTranslationAsync(int langId, int poemId)
public async Task<RServiceResult<GanjoorPoemTranslationViewModel[]>> GetPoemTranslationsAsync(int langId, int poemId, bool onlyPublished, bool includeUserInfo)
{
try
{
var dbTranslation = await _context.GanjoorPoemTranslations.Include(t => t.Verses).Where(t => t.LanguageId == langId && t.PoemId == poemId && t.Published == true).Include(t => t.Language).SingleOrDefaultAsync();
if (dbTranslation == null)
return new RServiceResult<GanjoorPoemTranslationViewModel>(null); //not found
var verses = await _context.GanjoorVerses.Where(v => v.PoemId == poemId).ToListAsync();
var verseIds = verses.Select(v => v.Id).ToList();
return new RServiceResult<GanjoorPoemTranslationViewModel>
(
new GanjoorPoemTranslationViewModel()
{
Id = dbTranslation.Id,
Language = dbTranslation.Language,
PoemId = poemId,
Title = dbTranslation.Title,
Description = dbTranslation.Description,
ContributerName = string.IsNullOrEmpty(dbTranslation.User.NickName) ? dbTranslation.User.Id.ToString() : dbTranslation.User.NickName,
TranslatedVerses = dbTranslation.Verses.Select(v =>
new GanjoorVerseTranslationViewModel()
{
Verse = verses.Where(pv => pv.Id == v.VerseId)
.Select(pv =>
new GanjoorVerseViewModel()
{
Id = pv.Id,
VersePosition = pv.VersePosition,
VOrder = pv.VOrder,
Text = pv.Text
}
).Single(),
TText = v.TText
}
).ToArray()
}
);
}
catch (Exception exp)
{
return new RServiceResult<GanjoorPoemTranslationViewModel>(null, exp.ToString());
}
}
/// <summary>
/// get translations for a poem
/// </summary>
/// <param name="poemId"></param>
/// <returns></returns>
public async Task<RServiceResult<GanjoorPoemTranslationViewModel[]>> GetPublishedTranslationsAsync(int poemId)
{
try
{
var dbTranslations = await _context.GanjoorPoemTranslations.Include(t => t.Verses).Where(t => t.PoemId == poemId && t.Published == true).Include(t => t.Language).Include(t => t.User).OrderBy(t => t.LanguageId).ToArrayAsync();
var dbTranslations = await _context.GanjoorPoemTranslations.Include(t => t.Verses).Where(t => t.PoemId == poemId && (langId == -1 || t.LanguageId == langId) && (onlyPublished == false || t.Published == true)).Include(t => t.Language).Include(t => t.User).OrderByDescending(t => t.Id).ToArrayAsync();
List<GanjoorPoemTranslationViewModel> res = new List<GanjoorPoemTranslationViewModel>();
if (dbTranslations.Length > 0)
{
@ -262,7 +227,10 @@ namespace RMuseum.Services.Implementation
PoemId = poemId,
Title = dbTranslation == null ? null : dbTranslation.Title,
Description = dbTranslation.Description,
ContributerName = string.IsNullOrEmpty(dbTranslation.User.NickName) ? dbTranslation.User.Id.ToString() : dbTranslation.User.NickName,
Published = dbTranslation.Published,
ContributerName = includeUserInfo ? string.IsNullOrEmpty(dbTranslation.User.NickName) ? dbTranslation.User.Id.ToString() : dbTranslation.User.NickName : null,
ContributerId = includeUserInfo ? dbTranslation.UserId : Guid.Empty,
DateTime = dbTranslation.DateTime,
TranslatedVerses = dbTranslation.Verses.Select(v =>
new GanjoorVerseTranslationViewModel()
{