song-of-the-day/song_of_the_day/Pages/SongSubmission.cshtml.cs

238 lines
8.4 KiB
C#

using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Microsoft.VisualBasic;
namespace sotd.Pages;
public class SongSubmissionModel : PageModel
{
private readonly ILogger<UserModel> _logger;
private SongResolver songResolver;
private string _submitUrl;
private SpotifyApiClient spotifyApiClient;
private SignalIntegration signalIntegration;
public SongSubmissionModel(ILogger<UserModel> logger, SongResolver songResolver, SpotifyApiClient spotifyApiClient, SignalIntegration signalIntegration)
{
_logger = logger;
this.spotifyApiClient = spotifyApiClient;
this.songResolver = songResolver;
this.signalIntegration = signalIntegration;
_submitUrl = string.Empty;
SongData = new Song();
}
[Parameter]
public int? SubmissionIndex { get; set; }
[BindProperty]
public bool IsValidUrl { get; set; } = true;
[BindProperty]
public bool IsPageReadonly { get; set; } = false;
[BindProperty]
public SuggestionHelper SuggestionHelper { get; set; } = null;
[BindProperty]
public List<SongSuggestion> UserSongSubmissions { get; set; } = [];
[BindProperty(SupportsGet = true)]
public string SubmitUrl
{
get
{
return _submitUrl;
}
set
{
_submitUrl = value == null ? string.Empty : value.ToString();
Uri? newValue = default;
try
{
newValue = new Uri(_submitUrl);
}
catch (UriFormatException)
{
IsValidUrl = false;
return;
}
IsValidUrl = true;
if (this.songResolver.CanValidate(newValue))
{
this.SongData = this.songResolver.ResolveSongAsync(newValue).Result;
}
}
}
public List<SpotifyAPI.Web.FullTrack> SpotifySuggestions
{
get
{
var suggestionList = new List<SpotifyAPI.Web.FullTrack>();
if (!string.IsNullOrEmpty(this.SongData.Name) && !string.IsNullOrEmpty(this.SongData.Artist))
{
suggestionList.AddRange(spotifyApiClient.GetTrackCandidatesAsync(this.SongData.Name, this.SongData.Artist).Result);
}
return suggestionList;
}
}
public IActionResult OnGetSpotifySuggestions(string song, string artist, string submitUrl, SongProvider provider, string spotifyId)
{
this.SongData.Name = song;
this.SongData.Artist = artist;
this.SongData.Url = submitUrl;
this.SongData.Provider = provider;
this.SongData.SpotifyId = spotifyId;
return Partial("_SpotifySongSuggestionsPartial", this.SpotifySuggestions);
}
[BindProperty]
public string CanSubmit
{
get
{
var disableCondition = !(string.IsNullOrEmpty(SongData?.Artist) && string.IsNullOrEmpty(SongData?.Name));
return disableCondition ? "" : "disabled";
}
}
[BindProperty(SupportsGet = true)]
public Song SongData { get; set; }
[BindProperty(SupportsGet = true)]
public bool HasUsedSuggestion { get; set; } = true;
private async Task UpdateGroup(SongSuggestion suggestion)
{
var isItToday = suggestion.Date.Date == DateTime.Today;
var dateString = isItToday ? "submission for today" : "submission from " + suggestion.Date.ToString("dd. MM. yyyy");
var displayName = string.IsNullOrEmpty(suggestion.User.NickName) ? suggestion.User.Name : suggestion.User.NickName;
var imageBuilder = await songResolver.GetPreviewImageAsync(suggestion.Song.SpotifyId);
var previewData = new LinkPreviewAttachment()
{
Title = suggestion.Song.Name,
Description = suggestion.Song.Artist,
Url = suggestion.Song.Url,
Base64Image = imageBuilder.ToString(),
};
await signalIntegration.SendMessageToGroupAsync($"**{displayName}**'s " + dateString + $" is: \n\n {suggestion.Song.Url}", previewData);
if (suggestion.HasUsedSuggestion)
{
await signalIntegration.SendMessageToGroupAsync($"The suggestion used for this pick was: \n\n **{suggestion.SuggestionHelper.Title}**'s \n\n {suggestion.SuggestionHelper.Description}");
}
}
public async Task<IActionResult> OnPost(int? submissionIndex)
{
if (submissionIndex == null)
{
throw new Exception("Attempt to submit song without submissionId");
}
// Todo implement save submission
using var dci = DataContext.Instance;
var suggestion = dci.SongSuggestions
.Include(s => s.User)
.Include(s => s.SuggestionHelper)
.Where(s => s.Id == submissionIndex)
.FirstOrDefault();
if (suggestion == null)
{
throw new Exception("Attempt to submit song with invalid submissionId");
}
this.SongData.Artist = Request.Form["Artist"];
this.SongData.Url = Request.Form["SubmitUrl"];
this.SongData.Name = Request.Form["Name"];
this.SongData.SpotifyId = Request.Form["SpotifyId"];
this.SongData.Provider = Enum.Parse<SongProvider>(Request.Form["Provider"]);
// Let's check if we already have this song in the DB
var songToUse = dci.Songs.Where(s => s.SpotifyId == this.SongData.SpotifyId).FirstOrDefault();
if (songToUse == null)
{
// Song was not in DB yet, creating a new one
var newSong = new Song()
{
SpotifyId = this.SongData.SpotifyId,
Artist = this.SongData.Artist,
Name = this.SongData.Name,
Url = this.SongData.Url,
Provider = this.SongData.Provider,
};
var dbRecord = dci.Songs.Add(newSong);
var newId = await dci.SaveChangesAsync();
songToUse = dbRecord.Entity;
}
suggestion.Song = songToUse;
suggestion.UserHasSubmitted = true;
suggestion.HasUsedSuggestion = this.HasUsedSuggestion;
dci.Update(suggestion);
await dci.SaveChangesAsync();
// load overview page again after submitting
await UpdateGroup(suggestion);
return RedirectToPage("SongSubmission");
}
public void OnGet(int? submissionIndex)
{
this.SubmissionIndex = submissionIndex;
// we want to show overview, so we need to fetch user submission list
if (submissionIndex == null)
{
using var dci = DataContext.Instance;
var currentUserName = this.User.Identity.Name;
this.UserSongSubmissions = dci.SongSuggestions
.Include(s => s.SuggestionHelper)
.Include(s => s.Song)
.Where(s => s.User.LdapUserName.Equals(currentUserName))
.OrderByDescending(s => s.Date)
.ToList();
}
else
{
using var dci = DataContext.Instance;
var songSuggestion = dci.SongSuggestions
.Include(s => s.SuggestionHelper)
.Include(s => s.Song)
.Where(s => s.Id.Equals(submissionIndex.Value))
.First();
this.SuggestionHelper = songSuggestion.SuggestionHelper;
this.SongData = songSuggestion.Song == null ? new Song() : songSuggestion.Song;
this.SubmitUrl = this.SongData.Url;
if (!string.IsNullOrEmpty(this.SongData.Name) && !string.IsNullOrEmpty(this.SongData.Artist))
{
this.IsPageReadonly = true;
}
}
}
public IActionResult OnGetUpdate()
{
var songUrl = Request.Query["SubmitUrl"];
this.SubmitUrl = songUrl.ToString();
var songPartialModel = new SongPartialModel()
{
InnerSong = SongData,
IsPageReadonly = false
};
return Partial("_SongPartial", songPartialModel); ;
}
}