public MediaElementInteraction GetWatchInteraction([FromUri] Guid?mediaElementGuid = null, [FromUri] Guid?personGuid = null, Guid?personAliasGuid = null) { var rockContext = Service.Context as RockContext; var personService = new PersonService(rockContext); var personAliasService = new PersonAliasService(rockContext); var interactionService = new InteractionService(rockContext); int?personAliasId; // Get the person alias to associate with the interaction in // order of provided Person.Guid, then PersonAlias.Guid, then // the logged in Person. if (personGuid.HasValue) { personAliasId = personAliasService.GetPrimaryAliasId(personGuid.Value); } else if (personAliasGuid.HasValue) { personAliasId = personAliasService.GetId(personAliasGuid.Value); } else { personAliasId = GetPersonAliasId(rockContext); } // Verify we have a person alias, otherwise bail out. if (!personAliasId.HasValue) { var errorResponse = Request.CreateErrorResponse(HttpStatusCode.BadRequest, $"The personAliasId could not be determined."); throw new HttpResponseException(errorResponse); } MediaElement mediaElement = null; // In the future we might make MediaElementGuid optional so // perform the check this way rather than making it required // in the parameter list. if (mediaElementGuid.HasValue) { mediaElement = new MediaElementService(rockContext).GetNoTracking(mediaElementGuid.Value); } // Ensure we have our required MediaElement. if (mediaElement == null) { var errorResponse = Request.CreateErrorResponse(HttpStatusCode.BadRequest, $"The MediaElement could not be found."); throw new HttpResponseException(errorResponse); } // Get (or create) the component. var interactionChannelId = InteractionChannelCache.Get(SystemGuid.InteractionChannel.MEDIA_EVENTS).Id; var interactionComponentId = InteractionComponentCache.GetComponentIdByChannelIdAndEntityId(interactionChannelId, mediaElement.Id, mediaElement.Name); Interaction interaction = interactionService.Queryable() .AsNoTracking() .Include(a => a.PersonAlias) .Where(a => a.InteractionComponentId == interactionComponentId) .Where(a => a.PersonAliasId == personAliasId || a.PersonAlias.Person.Aliases.Any(b => b.Id == personAliasId)) .OrderByDescending(a => a.InteractionEndDateTime) .ThenByDescending(a => a.InteractionDateTime) .FirstOrDefault(); if (interaction == null) { var errorResponse = Request.CreateErrorResponse(HttpStatusCode.NotFound, $"The Interaction could not be found."); throw new HttpResponseException(errorResponse); } var data = interaction.InteractionData.FromJsonOrNull <MediaWatchedInteractionData>(); return(new MediaElementInteraction { InteractionGuid = interaction.Guid, MediaElementGuid = mediaElement.Guid, PersonGuid = interaction.PersonAlias.Person?.Guid, PersonAliasGuid = interaction.PersonAlias.Guid, RelatedEntityTypeId = interaction.RelatedEntityTypeId, RelatedEntityId = interaction.RelatedEntityId, WatchMap = data?.WatchMap ?? string.Empty }); }
public MediaElementInteraction PostWatchInteraction(MediaElementInteraction mediaInteraction) { var rockContext = Service.Context as RockContext; var personService = new PersonService(rockContext); var personAliasService = new PersonAliasService(rockContext); var interactionService = new InteractionService(rockContext); int?personAliasId; if (!IsWatchMapValid(mediaInteraction.WatchMap)) { var errorResponse = Request.CreateErrorResponse(HttpStatusCode.BadRequest, $"The WatchMap contains invalid characters."); throw new HttpResponseException(errorResponse); } // Get the person alias to associate with the interaction in // order of provided Person.Guid, then PersonAlias.Guid, then // the logged in Person. if (mediaInteraction.PersonGuid.HasValue) { personAliasId = personAliasService.GetPrimaryAliasId(mediaInteraction.PersonGuid.Value); } else if (mediaInteraction.PersonAliasGuid.HasValue) { personAliasId = personAliasService.GetId(mediaInteraction.PersonAliasGuid.Value); } else { personAliasId = GetPersonAliasId(rockContext); } var mediaElement = new MediaElementService(rockContext).GetNoTracking(mediaInteraction.MediaElementGuid); // Ensure we have our required MediaElement. if (mediaElement == null) { var errorResponse = Request.CreateErrorResponse(HttpStatusCode.BadRequest, $"The MediaElement could not be found."); throw new HttpResponseException(errorResponse); } // Get (or create) the component. var interactionChannelId = InteractionChannelCache.Get(SystemGuid.InteractionChannel.MEDIA_EVENTS).Id; var interactionComponentId = InteractionComponentCache.GetComponentIdByChannelIdAndEntityId(interactionChannelId, mediaElement.Id, mediaElement.Name); Interaction interaction = null; if (mediaInteraction.InteractionGuid.HasValue) { // Look for an existing Interaction by it's Guid and the // component it is supposed to show up under. But also // check that the RelatedEntityTypeId/RelatedEntityId values // are either null or match what was passed by the user. // Finally also make sure the Interaction Person Alias is // either the one for this user OR if there is a Person // record attached to that alias that the alias Id we have is // also attached to that Person record OR the interaction is // not tied to a person. interaction = interactionService.Queryable() .Where(a => a.Guid == mediaInteraction.InteractionGuid.Value && a.InteractionComponentId == interactionComponentId) .Where(a => !a.RelatedEntityTypeId.HasValue || !mediaInteraction.RelatedEntityTypeId.HasValue || a.RelatedEntityTypeId == mediaInteraction.RelatedEntityTypeId) .Where(a => !a.RelatedEntityId.HasValue || !mediaInteraction.RelatedEntityId.HasValue || a.RelatedEntityId == mediaInteraction.RelatedEntityId) .Where(a => !a.PersonAliasId.HasValue || a.PersonAliasId == personAliasId || a.PersonAlias.Person.Aliases.Any(b => b.Id == personAliasId)) .SingleOrDefault(); } var watchedPercentage = CalculateWatchedPercentage(mediaInteraction.WatchMap); if (interaction != null) { // Update the interaction data with the new watch map. var data = interaction.InteractionData.FromJsonOrNull <MediaWatchedInteractionData>() ?? new MediaWatchedInteractionData(); data.WatchMap = mediaInteraction.WatchMap; data.WatchedPercentage = watchedPercentage; interaction.InteractionData = data.ToJson(); interaction.InteractionLength = watchedPercentage; interaction.InteractionEndDateTime = RockDateTime.Now; interaction.PersonAliasId = interaction.PersonAliasId ?? personAliasId; if (mediaInteraction.RelatedEntityTypeId.HasValue) { interaction.RelatedEntityTypeId = mediaInteraction.RelatedEntityTypeId; } if (mediaInteraction.RelatedEntityId.HasValue) { interaction.RelatedEntityId = mediaInteraction.RelatedEntityId; } } else { // Generate the interaction data from the watch map. var data = new MediaWatchedInteractionData { WatchMap = mediaInteraction.WatchMap, WatchedPercentage = watchedPercentage }; interaction = interactionService.CreateInteraction(interactionComponentId, null, "Watch", string.Empty, data.ToJson(), personAliasId, RockDateTime.Now, null, null, null, null, null, null); interaction.InteractionLength = watchedPercentage; interaction.InteractionEndDateTime = RockDateTime.Now; interaction.RelatedEntityTypeId = mediaInteraction.RelatedEntityTypeId; interaction.RelatedEntityId = mediaInteraction.RelatedEntityId; interactionService.Add(interaction); } rockContext.SaveChanges(); mediaInteraction.InteractionGuid = interaction.Guid; return(mediaInteraction); }