public bool DeletePartyWithHost(PartyGoer host) { List <string> partyKeys = new List <string>(); foreach (var key in _parties.Keys) { if (_parties[key].IsHost(host)) { partyKeys.Add(key); } } if (partyKeys.Count > 1) { throw new Exception($"Host: {host?.GetId()} is hosting {partyKeys.Count} parties. A host should only host 1 party at a time."); } if (partyKeys == null) { throw new Exception($"Host: {host?.GetId()} is not hosting a party"); } _parties.Remove(partyKeys.First()); return(true); }
public async Task <string> GetPartyGoerAccessTokenAsync(PartyGoer partyGoer) { if (await _spotifyAuthentication.DoesAccessTokenNeedRefreshAsync(partyGoer.GetId())) { await _spotifyHttpClient.RefreshTokenForUserAsync(partyGoer.GetId()); } return(await _spotifyAuthentication.GetAccessTokenAsync(partyGoer)); }
public async Task <HttpResponseMessage> SendHttpRequestAsync(PartyGoer user, SpotifyEndpoint spotifyEndpoint, ApiParameters queryStringParameters, object requestBodyParameters) { await RefreshTokenForUserAsync(user.GetId()); string spotifyEndpointUrl = spotifyEndpoint.EndpointUrl; // look to see if spotifyendpoint has keys if (spotifyEndpoint?.Keys != null) { // we need to verify these keys exist in api parameters foreach (string key in spotifyEndpoint.Keys) { if (!queryStringParameters.Keys.ContainsKey(key)) { throw new Exception($"Endpoint: {spotifyEndpoint} says it contains a key: {key} but it is not found in parameters"); } spotifyEndpointUrl = spotifyEndpointUrl.Replace(key, queryStringParameters.Keys[key]); } } using (var requestMessage = new HttpRequestMessage(spotifyEndpoint.HttpMethod, spotifyEndpointUrl + AddQueryStrings(queryStringParameters))) { requestMessage.Headers.Authorization = await _spotifyAuthentication.GetAuthenticationHeaderForPartyGoerAsync(user.GetId()); if (requestBodyParameters != null) { requestMessage.Content = new StringContent(JsonConvert.SerializeObject(requestBodyParameters)); } return(await _httpClient.SendAsync(requestMessage)); } }
public async Task <List <Device> > GetUserDevicesAsync(PartyGoer partyGoer) { HttpResponseMessage response = await SendHttpRequestAsync(partyGoer.GetId(), _apiEndpoints[ApiEndpointType.GetUserDevices]); if (response.IsSuccessStatusCode) { JObject json = JObject.Parse(await response.Content.ReadAsStringAsync()); List <Device> devices = new List <Device>(); foreach (var item in json["devices"]) { devices.Add(new Device { Name = item["name"].ToString(), Active = item["is_active"].Value <bool>(), Id = item["id"].ToString() }); } return(devices); } else { SpotifyApiException exception = new SpotifyApiException("Unable to get users devices from Spotify"); await _logService.LogExceptionAsync(exception, await response.Content.ReadAsStringAsync()); throw exception; } }
public async Task <IActionResult> Authorized(string code) { try { PartyGoer newUser = await _authenticationService.AuthenticateUserWithAccessCodeAsync(code); if (!newUser.HasPremium()) { // TODO: create this return(RedirectToAction("NoPremium", "Error")); } // Get details from spotify of user var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme); identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, newUser.GetId())); var principal = new ClaimsPrincipal(identity); await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal); await _logService.LogUserActivityAsync(newUser, "Successfully authenticated through Spotify"); return(RedirectToAction("App", "Party")); } catch (Exception) { // TODO: CHANGE THIS TO THE IDNEX PAGE ON HOME return(RedirectToAction("App", "Party")); } }
public bool LeaveParty(PartyGoer attendee) { List <string> partyKeys = new List <string>(); foreach (var key in _parties.Keys) { if (_parties[key].IsListener(attendee)) { partyKeys.Add(key); } } if (partyKeys.Count > 1) { partyKeys.ForEach(p => _parties[p].LeaveParty(attendee)); throw new PartyGoerWasInMultiplePartiesException($"The user {attendee} was in {partyKeys.Count} but was successfully removed from them"); } if (partyKeys == null || partyKeys.Count == 0) { throw new Exception($"The attendee: {attendee.GetId()} is not currently in a party"); } _parties[partyKeys.First()].LeaveParty(attendee); return(true); }
public void JoinParty(PartyGoer partyGoer) { _listeners.TryAdd(partyGoer.GetId(), partyGoer); if (_listeners.Count == 1) { _host = partyGoer; } }
public List <PartierContribution> GetContributions(PartyGoer partier) { return(_contributions.Where(p => p.ContributedBy == partier.GetId()).Select(p => new PartierContribution { Id = p.Id, ContributionId = p.ContributionId, Name = p.Name, Type = p.Type }).ToList()); }
public async Task TogglePlaybackAsync(PartyGoer partyGoer) { // Grabbing partier by reference, so any change I make to it will change it in the list if (_listeners.TryGetValue(partyGoer.GetId(), out PartyGoer partier)) { partier.ToggleMusicPlaybackState(); await DomainEvents.RaiseAsync(new ToggleMusicState { Listener = partier, State = DeterminePlaybackState(partier.IsMusicPaused()) }); } }
public async Task RemoveContributionAsync(string partyCode, PartyGoer partier, Guid contributionId) { Party party = await _partyRepository.GetPartyWithCodeAsync(partyCode); if (!party.IsListener(partier)) { throw new Exception($"{partier.GetId()} is not part of party {partyCode} but tried to remove contribution {contributionId}"); } party.RemoveContribution(partier, contributionId); }
public async Task <List <PartierContribution> > GetContributionsAsync(string partyCode, PartyGoer partier) { Party party = await _partyRepository.GetPartyWithCodeAsync(partyCode); if (!party.IsListener(partier)) { throw new Exception($"{partier.GetId()} is not part of party {partyCode} but tried to get their contributions to that party"); } return(await party.GetUserContributionsAsync(partier)); }
public Party(PartyGoer host) { _host = host; _listeners = new Dictionary <string, PartyGoer> { { host.GetId(), host } }; _partyCode = GeneratePartyCode(); _trackPositionTime = new Stopwatch(); _queue = new Queue(); _history = new List <Track>(); _nextTrackTimer = new Timer(async(obj) => await NextTrackAsync()); _usersThatDislikeCurrentSong = new List <PartyGoer>(); _contributionManager = new ContributionManager(); }
public async Task <IActionResult> GetUserDetails() { PartyGoer currentUser = await _partyGoerService.GetCurrentPartyGoerAsync(); Party party = await _partyService.GetPartyWithAttendeeAsync(currentUser); if (party != null) { return(Ok(new { IsInParty = true, Party = new { PartyCode = party.GetPartyCode() }, Details = new { Id = currentUser.GetId() } })); } else { return(Ok(new { IsInParty = false, UserDetails = new { Id = currentUser.GetId() } })); } }
public void LeaveParty(PartyGoer partyGoer) { _listeners.Remove(partyGoer.GetId()); if (IsHost(partyGoer)) { if (_listeners.Count > 0) { _host = _listeners.First().Value; } else { _host = null; } } }
public async Task <Domain.Errors.ServiceResult <UpdateSongError> > UpdateSongForPartyGoerAsync(PartyGoer partyGoer, List <string> songUris, int currentSongProgressInMs) { string perferredDeviceId = partyGoer.GetPerferredDeviceId(); ApiParameters parameters = null; if (!string.IsNullOrWhiteSpace(perferredDeviceId)) { parameters = new ApiParameters { Parameters = new Dictionary <string, string> { { "device_id", perferredDeviceId } } }; } HttpResponseMessage response = null; if (parameters != null) { response = await SendHttpRequestAsync(partyGoer, _apiEndpoints[ApiEndpointType.PlaySong], parameters, new StartUserPlaybackSong { uris = songUris.Select(song => song.Contains("spotify:track:") ? song : $"spotify:track:{song}".Split('+').First()).ToList(), position_ms = currentSongProgressInMs }); } else { response = await SendHttpRequestAsync(partyGoer, _apiEndpoints[ApiEndpointType.PlaySong], new StartUserPlaybackSong { uris = songUris.Select(song => song.Contains("spotify:track:") ? song : $"spotify:track:{song}".Split('+').First()).ToList(), position_ms = currentSongProgressInMs }); } Domain.Errors.ServiceResult <UpdateSongError> error = new Domain.Errors.ServiceResult <UpdateSongError>(); if (response.IsSuccessStatusCode) { return(error); } else { await _logService.LogExceptionAsync(new Exception($"Unable to update song for {partyGoer.GetId()}"), await response.Content.ReadAsStringAsync()); // TODO: Check status codes and add specific messaging for status codes based on Spotifys API error.AddError(new UpdateSongError($"Unable to update song for {partyGoer.GetId()}")); return(error); } }
public Task <string> GetAccessTokenAsync(PartyGoer partyGoer) { return(Task.FromResult(AuthenticationTokens[partyGoer.GetId()].AccessToken)); }
public async Task <HttpResponseMessage> SendHttpRequestAsync(PartyGoer user, SpotifyEndpoint spotifyEndpoint, object content = null, bool useQueryString = false) { return(await SendHttpRequestAsync(user.GetId(), spotifyEndpoint, content, useQueryString)); }
public bool IsListener(PartyGoer listenerInQuestion) { return(_listeners.ContainsKey(listenerInQuestion.GetId())); }
public void RemoveContribution(PartyGoer partier, Guid contributionId) { _contributions.RemoveAll(p => p.ContributedBy == partier.GetId() && p.ContributionId == contributionId); }
public async Task LogUserActivityAsync(PartyGoer user, string activity) { await _repository.LogUserActivityAsync(user.GetId(), activity); }
public async Task <IActionResult> RemoveUserContribution(string partyCode, Guid contributionId) { PartyGoer partier = await _partyGoerService.GetCurrentPartyGoerAsync(); try { await _partyService.RemoveContributionAsync(partyCode, partier, contributionId); return(StatusCode(200)); } catch (Exception ex) { await _logService.LogExceptionAsync(ex, $"Failed to remove contribution {contributionId} for user {partier.GetId()}"); return(StatusCode(500)); } }
public async Task ConnectToParty(string partyCode) { PartyGoer partier = await _partyGoerService.GetCurrentPartyGoerAsync(); if (!await _partyService.IsUserPartyingAsync(partier) && !await _partyService.IsUserHostingAPartyAsync(partier)) { await _partyService.JoinPartyAsync(new Domain.DTO.PartyCodeDTO { PartyCode = partyCode }, partier); await Groups.AddToGroupAsync(Context.ConnectionId, partyCode); await Clients.Group(partyCode).SendAsync("UpdateParty", $"{Context.UserIdentifier} has joined the party {partyCode}"); } // Add the partier to real-time connection group await Groups.AddToGroupAsync(Context.ConnectionId, partyCode); await Clients.GroupExcept(partyCode, new List <string> { Context.ConnectionId }).SendAsync("NewListener", Context.UserIdentifier); Party party = await _partyService.GetPartyWithAttendeeAsync(partier); // Update the view of the partier to the current playlist await Clients.Client(Context.ConnectionId).SendAsync("InitialPartyLoad", new { Song = party.GetCurrentSong(), Position = party.GetCurrentPositionInSong() }, party.GetHistory(), party.GetQueue(), new { PartyCode = party.GetPartyCode(), Listeners = ConvertToListenerModel(party.GetListeners()), Host = party.GetHost().GetId() } );; // check for explicit music if (!partier.CanListenToExplicitSongs() && party.HasExplicitTracks()) { await Clients.Client(Context.ConnectionId).SendAsync("ExplicitSong", "You have filtering explicit music turned on in Spotify and there are explicit songs in the queue. We will not play the explicit song for you but continue playback when a non explicit song comes on."); } await Clients.Client(Context.ConnectionId).SendAsync("InitializeWebPlayer", await _partyGoerService.GetPartyGoerAccessTokenAsync(partier)); // make sure that the users spotify is connected if (string.IsNullOrEmpty(await _spotifyHttpClient.GetUsersActiveDeviceAsync(partier.GetId()))) { await Clients.Client(Context.ConnectionId).SendAsync("ConnectSpotify", ""); } await _logService.LogUserActivityAsync(partier, $"Joined real time collobration in party with code {partyCode}"); return; }