using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;
using RMuseum.Models.Auth.Memory;
using RMuseum.Models.Auth.ViewModel;
using RMuseum.Models.Ganjoor;
using RMuseum.Models.Ganjoor.ViewModels;
using RMuseum.Models.GanjoorAudio.ViewModels;
using RMuseum.Services;
using RSecurityBackend.Models.Auth.Memory;
using RSecurityBackend.Models.Auth.ViewModels;
using RSecurityBackend.Models.Generic;
using RSecurityBackend.Models.Image;
using RSecurityBackend.Services;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
namespace RMuseum.Controllers
{
[Produces("application/json")]
[Route("api/ganjoor")]
public class GanjoorController : Controller
{
///
/// get list of poets
///
///
///
///
[HttpGet]
[Route("poets")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorPoetViewModel[]))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task GetPoets(bool websitePoets = true, bool includeBio = true)
{
var cacheKey = $"ganjoor/poets/{websitePoets}/{includeBio}";
if (!_memoryCache.TryGetValue(cacheKey, out GanjoorPoetViewModel[] poets))
{
RServiceResult res =
await _ganjoorService.GetPoets(websitePoets, includeBio);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
poets = res.Result;
_memoryCache.Set(cacheKey, poets);
}
return Ok(poets);
}
///
/// poet by id
///
///
///
[HttpGet]
[Route("poet/{id}")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorPoetCompleteViewModel))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task GetPoetById(int id)
{
var cacheKey = $"poet/byid/{id}";
if (!_memoryCache.TryGetValue(cacheKey, out GanjoorPoetCompleteViewModel poet))
{
RServiceResult res =
await _ganjoorService.GetPoetById(id);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (res.Result == null)
return NotFound();
poet = res.Result;
_memoryCache.Set(cacheKey, poet);
}
return Ok(poet);
}
///
/// poet by url
///
///
///
[HttpGet]
[Route("poet")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorPoetCompleteViewModel))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task GetPoetByUrl(string url)
{
var cacheKey = $"poet/byurl/{url}";
if (!_memoryCache.TryGetValue(cacheKey, out GanjoorPoetCompleteViewModel poet))
{
RServiceResult res =
await _ganjoorService.GetPoetByUrl(url);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (res.Result == null)
return NotFound();
poet = res.Result;
_memoryCache.Set(cacheKey, poet);
}
return Ok(poet);
}
///
/// get poet image
///
/// sample: hafez
///
[HttpGet("poet/image/{url}.png")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(FileStreamResult))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task Get(string url)
{
var cacheKey = $"poet/image/{url}.png";
var cacheKeyForLastModified = $"{cacheKey}/lastModified";
if (!_memoryCache.TryGetValue(cacheKey, out string imagePath) || !_memoryCache.TryGetValue(cacheKeyForLastModified, out DateTime lastModified))
{
RServiceResult poet = await _ganjoorService.GetPoetImageIdByUrl($"/{url}");
if (!string.IsNullOrEmpty(poet.ExceptionString))
return BadRequest(poet.ExceptionString);
if (poet.Result == Guid.Empty)
return NotFound();
RServiceResult img =
await _imageFileService.GetImage(poet.Result);
if (!string.IsNullOrEmpty(img.ExceptionString))
return BadRequest(img.ExceptionString);
if (img.Result == null)
return NotFound();
lastModified = img.Result.LastModified;
RServiceResult imgPath = _imageFileService.GetImagePath(img.Result);
if (!string.IsNullOrEmpty(imgPath.ExceptionString))
return BadRequest(imgPath.ExceptionString);
imagePath = imgPath.Result;
_memoryCache.Set(cacheKey, imagePath);
_memoryCache.Set(cacheKeyForLastModified, lastModified);
}
Response.GetTypedHeaders().LastModified = lastModified;
var requestHeaders = Request.GetTypedHeaders();
if (requestHeaders.IfModifiedSince.HasValue &&
requestHeaders.IfModifiedSince.Value >= lastModified)
{
return StatusCode(StatusCodes.Status304NotModified);
}
return new FileStreamResult(new FileStream(imagePath, FileMode.Open, FileAccess.Read), "image/png");
}
///
/// cat by id
///
///
///
///
[HttpGet]
[Route("cat/{id}")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorPoetCompleteViewModel))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task GetCatById(int id, bool poems = true)
{
var cacheKey = $"cat/byid/{id}/{poems}";
if (!_memoryCache.TryGetValue(cacheKey, out GanjoorPoetCompleteViewModel cat))
{
RServiceResult res =
await _ganjoorService.GetCatById(id, poems);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (res.Result == null)
return NotFound();
cat = res.Result;
_memoryCache.Set(cacheKey, cat);
}
return Ok(cat);
}
///
/// cat by url
///
///
///
///
[HttpGet]
[Route("cat")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorPoetCompleteViewModel))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task GetCatByUrl(string url, bool poems = true)
{
var cacheKey = $"cat/byurl/{url}/{poems}";
if (!_memoryCache.TryGetValue(cacheKey, out GanjoorPoetCompleteViewModel cat))
{
RServiceResult res =
await _ganjoorService.GetCatByUrl(url, poems);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (res.Result == null)
return NotFound();
cat = res.Result;
_memoryCache.Set(cacheKey, cat);
}
return Ok(cat);
}
///
/// page by url
///
///
///
///
[HttpGet]
[Route("page")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorPageCompleteViewModel))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task GetPageByUrl(string url, bool catPoems = false)
{
RServiceResult res =
await _ganjoorService.GetPageByUrl(url, catPoems);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (res.Result == null)
return NotFound();
return Ok(res.Result);
}
///
/// modify page
///
///
///
///
[HttpPut]
[Route("page/{id}")]
[Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + SecurableItem.ModifyOperationShortName)]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorPageCompleteViewModel))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task ModifyPage(int id, [FromBody]GanjoorModifyPageViewModel page)
{
Guid userId =
new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value);
RServiceResult res =
await _ganjoorService.ModifyPage(id, userId, page);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (res.Result == null)
return NotFound();
return Ok(res.Result);
}
///
/// page url by id
///
///
///
[HttpGet]
[Route("pageurl")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task GetPageUrlById(int id)
{
RServiceResult res =
await _ganjoorService.GetPageUrlById(id);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (string.IsNullOrEmpty(res.Result))
return NotFound();
return Ok(res.Result);
}
///
/// get poem by id
///
///
///
///
///
///
///
///
/// not implemented yet
///
/// next/previous
///
[HttpGet]
[Route("poem/{id}")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorPoemCompleteViewModel))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task GetPoemById(int id, bool catInfo = true, bool catPoems = false, bool rhymes = true, bool recitations = true, bool images = true, bool songs = true, bool comments = true, bool verseDetails = true, bool navigation = true)
{
RServiceResult res =
await _ganjoorService.GetPoemById(id, catInfo, catPoems, rhymes, recitations, images, songs, comments, verseDetails, navigation);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (res.Result == null)
return NotFound();
return Ok(res.Result);
}
///
/// get poem by url
///
///
///
///
/// not implemented yet
///
///
/// not implemented yet
/// not implemented yet
///
/// next/previous
///
[HttpGet]
[Route("poem")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorPoemCompleteViewModel))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task GetPoemByUrl(string url, bool catInfo = true, bool catPoems = false, bool rhymes = true, bool recitations = true, bool images = true, bool songs = true, bool comments = true, bool verseDetails = true, bool navigation = true)
{
RServiceResult res =
await _ganjoorService.GetPoemByUrl(url, catInfo, catPoems, rhymes, recitations, images, songs, comments, verseDetails, navigation);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (res.Result == null)
return NotFound();
return Ok(res.Result);
}
///
/// get poem recitations (PlainText/HtmlText are intentionally empty)
///
///
///
[HttpGet]
[Route("poem/{id}/recitations")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(PublicRecitationViewModel[]))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task GetPoemRecitations(int id)
{
RServiceResult res =
await _ganjoorService.GetPoemRecitations(id);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
return Ok(res.Result);
}
///
/// get poem images (PlainText/HtmlText are intentionally empty)
///
///
///
[HttpGet]
[Route("poem/{id}/images")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(PoemRelatedImage[]))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task GetPoemImages(int id)
{
RServiceResult res =
await _ganjoorService.GetPoemImages(id);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
return Ok(res.Result);
}
///
/// get poem songs
///
///
///
///
///
[HttpGet]
[Route("poem/{id}/songs")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(PoemMusicTrackViewModel[]))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task GetPoemSongs(int id, bool approved, PoemMusicTrackType trackType = PoemMusicTrackType.All)
{
RServiceResult res =
await _ganjoorService.GetPoemSongs(id, approved, trackType);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
return Ok(res.Result);
}
///
/// suggest song for poem
///
///
///
[HttpPost]
[Route("song")]
[Authorize]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(PoemMusicTrackViewModel))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.Forbidden)]
public async Task SuggestSong([FromBody] PoemMusicTrackViewModel song)
{
Guid userId =
new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value);
Guid sessionId =
new Guid(User.Claims.FirstOrDefault(c => c.Type == "SessionId").Value);
RServiceResult sessionCheckResult = await _appUserService.SessionExists(userId, sessionId);
if (!string.IsNullOrEmpty(sessionCheckResult.ExceptionString))
{
return StatusCode((int)HttpStatusCode.Forbidden);
}
var res =
await _ganjoorService.SuggestSong(userId, song);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
return Ok(res.Result);
}
///
/// get next unreviewed song
///
///
///
///
[HttpGet]
[Route("song")]
[Authorize]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(PoemMusicTrackViewModel))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.Forbidden)]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task GetNextUnreviewedSong(int skip = 0, bool onlyMine = false)
{
Guid userId =
new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value);
Guid sessionId =
new Guid(User.Claims.FirstOrDefault(c => c.Type == "SessionId").Value);
RServiceResult sessionCheckResult = await _appUserService.SessionExists(userId, sessionId);
if (!string.IsNullOrEmpty(sessionCheckResult.ExceptionString))
{
return StatusCode((int)HttpStatusCode.Forbidden);
}
var res =
await _ganjoorService.GetNextUnreviewedSong(skip, onlyMine ? userId : Guid.Empty);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (res.Result == null)
return NotFound();
var resCount = await _ganjoorService.GetUnreviewedSongsCount(onlyMine ? userId : Guid.Empty);
if (!string.IsNullOrEmpty(resCount.ExceptionString))
return BadRequest(resCount.ExceptionString);
// Paging Header
HttpContext.Response.Headers.Add("paging-headers",
JsonConvert.SerializeObject(
new PaginationMetadata()
{
totalCount = resCount.Result,
pageSize = -1,
currentPage = -1,
hasNextPage = false,
hasPreviousPage = false,
totalPages = -1
})
);
return Ok(res.Result);
}
///
/// review song
///
///
///
[HttpPut]
[Route("song")]
[Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.ReviewSongs)]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(PoemMusicTrackViewModel))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.Forbidden)]
public async Task ReviewSong([FromBody] PoemMusicTrackViewModel song)
{
var res =
await _ganjoorService.ReviewSong(song);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
return Ok(res.Result);
}
///
/// directly insert a poem related song
///
///
///
[HttpPost]
[Route("song/add")]
[Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.AddSongs)]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(PoemMusicTrackViewModel))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.Forbidden)]
public async Task DirectInsertSong([FromBody] PoemMusicTrackViewModel song)
{
var res =
await _ganjoorService.DirectInsertSong(song);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
return Ok(res.Result);
}
///
/// get a random poem from hafez
///
///
[HttpGet]
[Route("hafez/faal")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorPoemCompleteViewModel))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task Faal()
{
RServiceResult res =
await _ganjoorService.Faal();
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
return Ok(res.Result);
}
///
/// get recent comments
///
///
///
///
[HttpGet]
[Route("comments")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task GetRecentComments([FromQuery] PagingParameterModel paging, Guid? filterUserId = null)
{
var comments = await _ganjoorService.GetRecentComments(paging, filterUserId == null ? Guid.Empty : (Guid)filterUserId, true);
if (!string.IsNullOrEmpty(comments.ExceptionString))
{
return BadRequest(comments.ExceptionString);
}
// Paging Header
HttpContext.Response.Headers.Add("paging-headers", JsonConvert.SerializeObject(comments.Result.PagingMeta));
return Ok(comments.Result.Items);
}
///
/// get logged on users recent comments
///
///
///
[HttpGet]
[Route("comments/mine")]
[Authorize]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task GetMyRecentComments([FromQuery] PagingParameterModel paging)
{
Guid userId =
new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value);
Guid sessionId =
new Guid(User.Claims.FirstOrDefault(c => c.Type == "SessionId").Value);
RServiceResult sessionCheckResult = await _appUserService.SessionExists(userId, sessionId);
if (!string.IsNullOrEmpty(sessionCheckResult.ExceptionString))
{
return StatusCode((int)HttpStatusCode.Forbidden);
}
var comments = await _ganjoorService.GetRecentComments(paging, userId, false);
if (!string.IsNullOrEmpty(comments.ExceptionString))
{
return BadRequest(comments.ExceptionString);
}
// Paging Header
HttpContext.Response.Headers.Add("paging-headers", JsonConvert.SerializeObject(comments.Result.PagingMeta));
return Ok(comments.Result.Items);
}
///
/// post new comment
///
///
///
[HttpPost]
[Route("comment")]
[Authorize]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorCommentSummaryViewModel))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.Forbidden)]
public async Task NewComment([FromBody] GanjoorCommentPostViewModel comment)
{
string clientIPAddress = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString();
Guid userId =
new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value);
Guid sessionId =
new Guid(User.Claims.FirstOrDefault(c => c.Type == "SessionId").Value);
RServiceResult sessionCheckResult = await _appUserService.SessionExists(userId, sessionId);
if (!string.IsNullOrEmpty(sessionCheckResult.ExceptionString))
{
return StatusCode((int)HttpStatusCode.Forbidden);
}
var res =
await _ganjoorService.NewComment(userId, clientIPAddress, comment.PoemId, comment.HtmlComment, comment.InReplyToId);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
return Ok(res.Result);
}
///
/// edit user's own comment
///
///
///
///
[HttpPut]
[Route("comment/{id}")]
[Authorize]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
[ProducesResponseType((int)HttpStatusCode.Forbidden)]
public async Task EditMyComment(int id, [FromBody] string comment)
{
Guid userId =
new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value);
Guid sessionId =
new Guid(User.Claims.FirstOrDefault(c => c.Type == "SessionId").Value);
RServiceResult sessionCheckResult = await _appUserService.SessionExists(userId, sessionId);
if (!string.IsNullOrEmpty(sessionCheckResult.ExceptionString))
{
return StatusCode((int)HttpStatusCode.Forbidden);
}
var res =
await _ganjoorService.EditMyComment(userId, id, comment);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (!res.Result)
return NotFound();
return Ok();
}
///
/// delete user's own comment
///
///
///
[HttpDelete]
[Route("comment")]
[Authorize]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
[ProducesResponseType((int)HttpStatusCode.Forbidden)]
public async Task DeleteMyComment(int id)
{
Guid userId =
new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value);
Guid sessionId =
new Guid(User.Claims.FirstOrDefault(c => c.Type == "SessionId").Value);
RServiceResult sessionCheckResult = await _appUserService.SessionExists(userId, sessionId);
if (!string.IsNullOrEmpty(sessionCheckResult.ExceptionString))
{
return StatusCode((int)HttpStatusCode.Forbidden);
}
var res =
await _ganjoorService.DeleteMyComment(userId, id);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (!res.Result)
return NotFound();
return Ok();
}
///
/// report a comment
///
///
/// id of reported record
[HttpPost]
[Route("comment/report")]
[Authorize]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(int))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.Forbidden)]
public async Task ReportComment([FromBody] GanjoorPostReportCommentViewModel report)
{
Guid userId =
new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value);
Guid sessionId =
new Guid(User.Claims.FirstOrDefault(c => c.Type == "SessionId").Value);
RServiceResult sessionCheckResult = await _appUserService.SessionExists(userId, sessionId);
if (!string.IsNullOrEmpty(sessionCheckResult.ExceptionString))
{
return StatusCode((int)HttpStatusCode.Forbidden);
}
RServiceResult res = await _ganjoorService.ReportComment(userId, report);
if (!string.IsNullOrEmpty(res.ExceptionString))
{
return BadRequest(res.ExceptionString);
}
return Ok(res.Result);
}
///
/// delete a report (without deleting corresponding comment)
///
///
///
[HttpDelete]
[Route("comment/report/{id}")]
[Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.ModerateOperationShortName)]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(int))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.Forbidden)]
public async Task DeleteReport(int id)
{
RServiceResult res = await _ganjoorService.DeleteReport(id);
if (!string.IsNullOrEmpty(res.ExceptionString))
{
return BadRequest(res.ExceptionString);
}
if(!res.Result)
{
return NotFound();
}
return Ok();
}
///
/// get list of reported comments
///
///
///
[HttpGet]
[Route("comments/reported")]
[Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.ModerateOperationShortName)]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task GetReportedComments([FromQuery] PagingParameterModel paging)
{
var comments = await _ganjoorService.GetReportedComments(paging);
if (!string.IsNullOrEmpty(comments.ExceptionString))
{
return BadRequest(comments.ExceptionString);
}
// Paging Header
HttpContext.Response.Headers.Add("paging-headers", JsonConvert.SerializeObject(comments.Result.PagingMeta));
return Ok(comments.Result.Items);
}
///
/// delete other users comment comment
///
///
///
///
[HttpPost]
[Route("comment/moderate/{id}")]
[Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.ModerateOperationShortName)]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
[ProducesResponseType((int)HttpStatusCode.Forbidden)]
public async Task DeleteModerateComment(int id, [FromBody]string reason)
{
var res =
await _ganjoorService.DeleteModerateComment(id, reason);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (!res.Result)
return NotFound();
return Ok();
}
///
/// imports data from ganjoor SQLite database
///
///
[HttpPost]
[Route("sqliteimport")]
[Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.ImportOperationShortName)]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(bool))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task ImportLocalSQLiteDb()
{
RServiceResult res =
await _ganjoorService.ImportLocalSQLiteDb();
if (res.Result)
return Ok();
return BadRequest(res.ExceptionString);
}
///
/// imports data from ganjoor MySql database
///
///
[HttpPost]
[Route("mysqlimport")]
[Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.ImportOperationShortName)]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(bool))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public IActionResult ImportFromMySql()
{
RServiceResult res =
_ganjoorService.ImportFromMySql();
if (res.Result)
return Ok();
return BadRequest(res.ExceptionString);
}
///
/// Get user public profile
///
///
///
[HttpGet("user/profile/{id}")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorUserPublicProfile))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task GetUserPublicProfile(Guid id)
{
RServiceResult userInfo = await _appUserService.GetUserInformation(id);
if (userInfo.Result == null)
{
if (string.IsNullOrEmpty(userInfo.ExceptionString))
return NotFound();
return BadRequest(userInfo.ExceptionString);
}
return Ok
(
new GanjoorUserPublicProfile()
{
Id = id,
NickName = userInfo.Result.NickName,
Bio = userInfo.Result.Bio,
Website = userInfo.Result.Website,
RImageId = userInfo.Result.RImageId
}
);
}
///
/// Get Similar Poems accroding to prosody and rhyme informations
///
///
/// cannot be empty
/// can be empty
/// send 0 for all
/// return value is not complete or valid for some parts, you should use only the valid parts!
[HttpGet]
[Route("poems/similar")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task GetSimilarPoems([FromQuery]PagingParameterModel paging, string metre, string rhyme, int poetId = 0)
{
var pagedResult = await _ganjoorService.GetSimilarPoems(paging, metre, rhyme, poetId == 0 ? (int?) null : poetId);
if (!string.IsNullOrEmpty(pagedResult.ExceptionString))
return BadRequest(pagedResult.ExceptionString);
// Paging Header
HttpContext.Response.Headers.Add("paging-headers", JsonConvert.SerializeObject(pagedResult.Result.PagingMeta));
return Ok(pagedResult.Result.Items);
}
///
/// search
///
///
///
///
///
///
[HttpGet]
[Route("poems/search")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task Search([FromQuery] PagingParameterModel paging, string term, int poetId = 0, int catId = 0)
{
var pagedResult = await _ganjoorService.Search(paging, term, poetId == 0 ? (int?)null : poetId, catId == 0 ? (int?)null: catId);
if (!string.IsNullOrEmpty(pagedResult.ExceptionString))
return BadRequest(pagedResult.ExceptionString);
// Paging Header
HttpContext.Response.Headers.Add("paging-headers", JsonConvert.SerializeObject(pagedResult.Result.PagingMeta));
return Ok(pagedResult.Result.Items);
}
///
/// returns ganjoor metre list ordered by rhythm
///
///
[HttpGet]
[Route("rhythms")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(IEnumerable))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public async Task GetGanjoorMetres()
{
var res = await _ganjoorService.GetGanjoorMetres();
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
return Ok(res.Result);
}
///
/// add site banner (send form) with these fields: alt, url and an image attachment
///
///
[HttpPost]
[Route("site/banner")]
[Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.Banners)]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorSiteBannerViewModel))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.Unauthorized)]
public async Task AddSiteBanner()
{
try
{
if (!Request.Form.TryGetValue("alt", out Microsoft.Extensions.Primitives.StringValues alt))
{
return BadRequest("alt is null");
}
if (!Request.Form.TryGetValue("url", out Microsoft.Extensions.Primitives.StringValues url))
{
return BadRequest("url is null");
}
if(Request.Form.Files.Count != 1)
{
return BadRequest("a single image is not provided");
}
using Stream stream = Request.Form.Files[0].OpenReadStream();
RServiceResult res = await _ganjoorService.AddSiteBanner(stream, Request.Form.Files[0].FileName, alt.ToString(), url.ToString(), false);
if (!string.IsNullOrEmpty(res.ExceptionString))
{
return BadRequest(res.ExceptionString);
}
return Ok(res.Result);
}
catch (Exception exp)
{
return BadRequest(exp.ToString());
}
}
///
/// modify site banner
///
///
///
///
[HttpPut]
[Route("site/banner/{id}")]
[Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.Banners)]
[ProducesResponseType((int)HttpStatusCode.OK)]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.Unauthorized)]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task ModifySiteBanner(int id, [FromBody] GanjoorSiteBannerModifyViewModel model)
{
try
{
RServiceResult res = await _ganjoorService.ModifySiteBanner(id, model.AlternateText, model.TargetUrl, model.Active);
if (!string.IsNullOrEmpty(res.ExceptionString))
{
return BadRequest(res.ExceptionString);
}
if(!res.Result)
{
return NotFound();
}
return Ok();
}
catch (Exception exp)
{
return BadRequest(exp.ToString());
}
}
///
/// delete site banner
///
///
///
[HttpDelete]
[Route("site/banner")]
[Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.Banners)]
[ProducesResponseType((int)HttpStatusCode.OK)]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.Unauthorized)]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task DeleteSiteBanner(int id)
{
try
{
RServiceResult res = await _ganjoorService.DeleteSiteBanner(id);
if (!string.IsNullOrEmpty(res.ExceptionString))
{
return BadRequest(res.ExceptionString);
}
if (!res.Result)
{
return NotFound();
}
return Ok();
}
catch (Exception exp)
{
return BadRequest(exp.ToString());
}
}
///
/// get all defined site banners
///
///
[HttpGet]
[Route("site/banners")]
[Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.Banners)]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorSiteBannerViewModel[]))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.Unauthorized)]
public async Task GetSiteBanners()
{
try
{
RServiceResult res = await _ganjoorService.GetSiteBanners();
if (!string.IsNullOrEmpty(res.ExceptionString))
{
return BadRequest(res.ExceptionString);
}
return Ok(res.Result);
}
catch (Exception exp)
{
return BadRequest(exp.ToString());
}
}
///
/// get a random active site banner
///
///
[HttpGet]
[Route("site/banner")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorSiteBannerViewModel))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.Unauthorized)]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task GetARandomActiveSiteBanner()
{
try
{
RServiceResult res = await _ganjoorService.GetARandomActiveSiteBanner();
if (!string.IsNullOrEmpty(res.ExceptionString))
{
return BadRequest(res.ExceptionString);
}
return Ok(res.Result); //this might be null
}
catch (Exception exp)
{
return BadRequest(exp.ToString());
}
}
///
/// examine site pages for broken links
///
///
[HttpPost]
[Route("healthcheck")]
[Authorize(Policy = RMuseumSecurableItem.GanjoorEntityShortName + ":" + RMuseumSecurableItem.ImportOperationShortName)]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(bool))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
public IActionResult HealthCheckContents()
{
RServiceResult res =
_ganjoorService.HealthCheckContents();
if (res.Result)
return Ok();
return BadRequest(res.ExceptionString);
}
///
/// Ganjoor Service
///
protected readonly IGanjoorService _ganjoorService;
///
/// IAppUserService instance
///
protected IAppUserService _appUserService;
///
/// for client IP resolution
///
protected IHttpContextAccessor _httpContextAccessor;
///
/// Image Service
///
protected readonly IImageFileService _imageFileService;
///
/// IMemoryCache
///
protected readonly IMemoryCache _memoryCache;
///
/// constructor
///
///
///
///
///
///
public GanjoorController(IGanjoorService ganjoorService, IAppUserService appUserService, IHttpContextAccessor httpContextAccessor, IImageFileService imageFileService, IMemoryCache memoryCache)
{
_ganjoorService = ganjoorService;
_appUserService = appUserService;
_httpContextAccessor = httpContextAccessor;
_imageFileService = imageFileService;
_memoryCache = memoryCache;
}
}
}