using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using RMuseum.Models.Auth.Memory;
using RMuseum.Models.Ganjoor;
using RMuseum.Models.Ganjoor.ViewModels;
using RMuseum.Models.GanjoorAudio.ViewModels;
using RMuseum.Models.GanjoorIntegration.ViewModels;
using RMuseum.Services;
using RSecurityBackend.Models.Generic;
using RSecurityBackend.Services;
using System;
using System.Collections.Generic;
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)
{
RServiceResult res =
await _ganjoorService.GetPoets(websitePoets, includeBio);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
return Ok(res.Result);
}
///
/// 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)
{
RServiceResult res =
await _ganjoorService.GetPoetById(id);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (res.Result == null)
return NotFound();
return Ok(res.Result);
}
///
/// 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)
{
RServiceResult res =
await _ganjoorService.GetPoetByUrl(url);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (res.Result == null)
return NotFound();
return Ok(res.Result);
}
///
/// 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)
{
RServiceResult res =
await _ganjoorService.GetCatById(id, poems);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (res.Result == null)
return NotFound();
return Ok(res.Result);
}
///
/// 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)
{
RServiceResult res =
await _ganjoorService.GetCatByUrl(url, poems);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (res.Result == null)
return NotFound();
return Ok(res.Result);
}
///
/// 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);
}
///
/// 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)
{
var comments = await _ganjoorService.GetRecentComments(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);
}
///
/// 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);
}
///
/// 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);
}
///
/// 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);
}
///
/// Search Verses By query
///
///
///
///
[HttpGet]
[Route("verse/search")]
[AllowAnonymous]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(GanjoorSearchVerseViewModel[]))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
public async Task SearchVersesByQuery(string query, int poetId = 0)
{
RServiceResult res = await _ganjoorService.SearchVersesByQuery(query, poetId);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
if (res.Result == null)
return NotFound();
return Ok(res.Result);
}
///
/// Ganjoor Service
///
protected readonly IGanjoorService _ganjoorService;
///
/// IAppUserService instance
///
protected IAppUserService _appUserService;
///
/// for client IP resolution
///
protected IHttpContextAccessor _httpContextAccessor;
///
/// constructor
///
///
///
///
public GanjoorController(IGanjoorService ganjoorService, IAppUserService appUserService, IHttpContextAccessor httpContextAccessor)
{
_ganjoorService = ganjoorService;
_appUserService = appUserService;
_httpContextAccessor = httpContextAccessor;
}
}
}