Пример #1
0
        /// <summary>
        /// Binds the grid.
        /// </summary>
        private void BindGrid()
        {
            var rockContext         = new RockContext();
            var mediaElementService = new MediaElementService(rockContext);

            // Use AsNoTracking() since these records won't be modified, and therefore don't need to be tracked by the EF change tracker
            var qry = mediaElementService.Queryable().AsNoTracking().Where(a => a.MediaFolderId == _mediaFolder.Id);

            // name filter
            string nameFilter = gfFilter.GetUserPreference(UserPreferenceKey.Name);

            if (!string.IsNullOrEmpty(nameFilter))
            {
                qry = qry.Where(a => a.Name.Contains(nameFilter));
            }

            var sortProperty = gElementList.SortProperty;

            if (gElementList.AllowSorting && sortProperty != null)
            {
                qry = qry.Sort(sortProperty);
            }
            else
            {
                qry = qry.OrderBy(a => a.Name);
            }

            gElementList.EntityTypeId = EntityTypeCache.GetId <MediaElement>();
            gElementList.DataSource   = qry.ToList();
            gElementList.DataBind();
        }
Пример #2
0
        /// <summary>
        /// Sets the value. ( as Guid )
        /// </summary>
        /// <param name="control">The control.</param>
        /// <param name="configurationValues">The configuration values.</param>
        /// <param name="value">The value.</param>
        public override void SetEditValue(System.Web.UI.Control control, Dictionary <string, ConfigurationValue> configurationValues, string value)
        {
            if (!(control is MediaElementPicker mediaElementPicker))
            {
                return;
            }

            var mediaElementGuid = value.AsGuidOrNull();

            if (mediaElementGuid.HasValue)
            {
                using (var rockContext = new RockContext())
                {
                    var mediaElementInfo = new MediaElementService(rockContext).Queryable()
                                           .Where(a => a.Guid == mediaElementGuid.Value)
                                           .Select(a => new
                    {
                        a.Id,
                        a.MediaFolderId,
                        a.MediaFolder.MediaAccountId
                    })
                                           .SingleOrDefault();

                    if (mediaElementInfo != null)
                    {
                        var limitAccountId = GetLimitToAccountId(configurationValues);
                        var limitFolderId  = GetLimitToFolderId(configurationValues);

                        bool accountOk = limitAccountId.IsNullOrZero() || limitAccountId.Value == mediaElementInfo.MediaAccountId;
                        bool folderOk  = limitFolderId.IsNullOrZero() || limitFolderId.Value == mediaElementInfo.MediaFolderId;

                        // This is a little odd, but here is the logic.
                        // If the admin has limited to a specific folder or account
                        // then we need to enforce that. Which means if the old
                        // value is for a different folder/account then we
                        // basically just don't set the value because they won't
                        // be able to save it anyway. Similar logic to a custom
                        // drop down list where the admin removes one of the
                        // options. The next time the value is edited it won't
                        // be selected anymore because it doesn't exist.
                        if (accountOk && folderOk)
                        {
                            mediaElementPicker.MediaElementId = mediaElementInfo.Id;

                            return;
                        }
                    }
                }
            }

            // We couldn't find the stored value or there wasn't one, set
            // the defaults to nothing selected and ensure the forced
            // account and folder are still selected.
            mediaElementPicker.MediaElementId = null;
            SetAccountAndFolderValues(mediaElementPicker, configurationValues);
        }
Пример #3
0
        /// <summary>
        /// Sets the edit value from IEntity.Id value
        /// </summary>
        /// <param name="control">The control.</param>
        /// <param name="configurationValues">The configuration values.</param>
        /// <param name="id">The identifier.</param>
        public void SetEditValueFromEntityId(System.Web.UI.Control control, Dictionary <string, ConfigurationValue> configurationValues, int?id)
        {
            if (id.HasValue)
            {
                using (var rockContext = new RockContext())
                {
                    var mediaGuid = new MediaElementService(rockContext).GetGuid(id.Value);

                    SetEditValue(control, configurationValues, mediaGuid.ToStringSafe());
                }
            }
            else
            {
                SetEditValue(control, configurationValues, string.Empty);
            }
        }
Пример #4
0
        /// <summary>
        /// Handles the DeleteClick event of the gElementList control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Rock.Web.UI.Controls.RowEventArgs"/> instance containing the event data.</param>
        protected void gElementList_DeleteClick(object sender, Rock.Web.UI.Controls.RowEventArgs e)
        {
            var rockContext         = new RockContext();
            var mediaElementService = new MediaElementService(rockContext);
            var mediaElement        = mediaElementService.Get(e.RowKeyId);

            if (mediaElement != null)
            {
                string errorMessage;
                if (!mediaElementService.CanDelete(mediaElement, out errorMessage))
                {
                    mdGridWarning.Show(errorMessage, ModalAlertType.Information);
                    return;
                }

                mediaElementService.Delete(mediaElement);
                rockContext.SaveChanges();
            }

            BindGrid();
        }
Пример #5
0
        /// <summary>
        /// Reads new values entered by the user for the field ( as Guid )
        /// </summary>
        /// <param name="control">Parent control that controls were added to in the CreateEditControl() method</param>
        /// <param name="configurationValues">The configuration values.</param>
        /// <returns></returns>
        public override string GetEditValue(System.Web.UI.Control control, Dictionary <string, ConfigurationValue> configurationValues)
        {
            if (control is MediaElementPicker mediaElementPicker)
            {
                var rockContext = new RockContext();

                if (mediaElementPicker.MediaElementId.IsNotNullOrZero())
                {
                    var mediaElementGuid = new MediaElementService(rockContext).Queryable()
                                           .Where(a => a.Id == mediaElementPicker.MediaElementId.Value)
                                           .Select(a => a.Guid)
                                           .SingleOrDefault();

                    if (mediaElementGuid != null)
                    {
                        return(mediaElementGuid.ToString());
                    }
                }
            }

            return(null);
        }
Пример #6
0
        /// <summary>
        /// Formats the value as HTML.
        /// </summary>
        /// <param name="parentControl">The parent control.</param>
        /// <param name="value">The value.</param>
        /// <param name="configurationValues">The configuration values.</param>
        /// <param name="condensed">if set to <c>true</c> then the value will be displayed in a condensed area; otherwise <c>false</c>.</param>
        /// <returns></returns>
        public override string FormatValueAsHtml(Control parentControl, string value, Dictionary <string, ConfigurationValue> configurationValues, bool condensed = false)
        {
            var mediaElementGuid = value.AsGuidOrNull();

            if (!mediaElementGuid.HasValue)
            {
                return(string.Empty);
            }

            using (var rockContext = new RockContext())
            {
                var mediaInfo = new MediaElementService(rockContext).Queryable()
                                .Where(a => a.Guid == mediaElementGuid.Value)
                                .Select(a => new
                {
                    a.Name,
                    a.ThumbnailDataJson
                })
                                .SingleOrDefault();

                if (mediaInfo == null)
                {
                    return(string.Empty);
                }

                var thumbnails   = mediaInfo.ThumbnailDataJson.FromJsonOrNull <List <MediaElementThumbnailData> >();
                var thumbnailUrl = string.Empty;

                if (thumbnails != null)
                {
                    if (condensed)
                    {
                        // Attempt to get the smallest thumbnail above 400px in
                        // width. If that fails then just get the largest
                        // thumbnail we have available.
                        thumbnailUrl = thumbnails.Where(t => t.Link.IsNotNullOrWhiteSpace() && t.Width >= 400)
                                       .OrderBy(t => t.Height)
                                       .Select(t => t.Link)
                                       .FirstOrDefault() ?? string.Empty;

                        if (thumbnailUrl == string.Empty)
                        {
                            thumbnailUrl = thumbnails.Where(t => t.Link.IsNotNullOrWhiteSpace())
                                           .OrderByDescending(t => t.Height)
                                           .Select(t => t.Link)
                                           .FirstOrDefault() ?? string.Empty;
                        }
                    }
                    else
                    {
                        thumbnailUrl = thumbnails.Where(t => t.Link.IsNotNullOrWhiteSpace())
                                       .OrderByDescending(t => t.Height)
                                       .Select(t => t.Link)
                                       .FirstOrDefault() ?? string.Empty;
                    }
                }

                if (condensed)
                {
                    return($"<img src='{thumbnailUrl}' alt='{mediaInfo.Name.EncodeXml( true )}' class='img-responsive grid-img' />");
                }
                else
                {
                    return($"<img src='{thumbnailUrl}' alt='{mediaInfo.Name.EncodeXml( true )}' class='img-responsive' />");
                }
            }
        }
Пример #7
0
        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
            });
        }
Пример #8
0
        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);
        }
        /// <summary>
        /// Updates the options from a <see cref="MediaElement"/>. If one is
        /// not found then no changes are made.
        /// </summary>
        /// <param name="options">The options to be updated.</param>
        /// <param name="mediaElementId">The media element identifier.</param>
        /// <param name="mediaElementGuid">The media element unique identifier.</param>
        /// <param name="autoResumeInDays">The number of days back to look for an existing watch map to auto-resume from. Pass -1 to mean forever or 0 to disable.</param>
        /// <param name="combinePlayStatisticsInDays">The number of days back to look for an existing interaction to be updated. Pass -1 to mean forever or 0 to disable.</param>
        /// <param name="currentPerson">The person to use when searching for existing interactions.</param>
        internal static void UpdateValuesFromMedia(this MediaPlayerOptions options, int?mediaElementId, Guid?mediaElementGuid, int autoResumeInDays, int combinePlayStatisticsInDays, Person currentPerson)
        {
            if (!mediaElementId.HasValue && !mediaElementGuid.HasValue)
            {
                return;
            }

            using (var rockContext = new RockContext())
            {
                var          mediaElementService    = new MediaElementService(rockContext);
                var          interactionService     = new InteractionService(rockContext);
                var          mediaEventsChannelGuid = Rock.SystemGuid.InteractionChannel.MEDIA_EVENTS.AsGuid();
                var          now          = RockDateTime.Now;
                MediaElement mediaElement = null;

                // Load the media element by either Id or Guid value.
                if (mediaElementId.HasValue)
                {
                    mediaElement = mediaElementService.Get(mediaElementId.Value);
                }
                else
                {
                    mediaElement = mediaElementService.Get(mediaElementGuid.Value);
                }

                // No media found means we don't have anything to do.
                if (mediaElement == null)
                {
                    return;
                }

                options.MediaUrl         = mediaElement.DefaultFileUrl;
                options.MediaElementGuid = mediaElement.Guid;

                // Let the users value override the default thumbnail.
                if (options.PosterUrl.IsNullOrWhiteSpace())
                {
                    options.PosterUrl = mediaElement.DefaultThumbnailUrl;
                }

                // Check if either autoResumeInDays or combinePlayStatisticsInDays
                // are enabled. If not we are done.
                if (autoResumeInDays == 0 && combinePlayStatisticsInDays == 0)
                {
                    return;
                }

                // If we don't have a person, then we can't get interactions.
                if (currentPerson == null)
                {
                    return;
                }

                // Build a query to find Interactions for this person having
                // previously watched this media element.
                var interactionQry = interactionService.Queryable()
                                     .Where(i => i.InteractionComponent.InteractionChannel.Guid == mediaEventsChannelGuid &&
                                            i.InteractionComponent.EntityId == mediaElement.Id &&
                                            i.PersonAlias.PersonId == currentPerson.Id);

                // A negative value means "forever".
                int daysBack = Math.Max(autoResumeInDays >= 0 ? autoResumeInDays : int.MaxValue,
                                        combinePlayStatisticsInDays >= 0 ? combinePlayStatisticsInDays : int.MaxValue);

                // A value of MaxValue means "forever" now so we don't need
                // to filter on it.
                if (daysBack != int.MaxValue)
                {
                    var limitDateTime = now.AddDays(-daysBack);

                    interactionQry = interactionQry.Where(i => i.InteractionDateTime >= limitDateTime);
                }

                // Look for the most recent Interaction.
                var interaction = interactionQry.OrderByDescending(i => i.InteractionDateTime)
                                  .Select(i => new
                {
                    i.Guid,
                    i.InteractionDateTime,
                    i.InteractionData
                })
                                  .FirstOrDefault();

                // If we didn't find any interaction then we are done.
                if (interaction == null)
                {
                    return;
                }

                // Check if this interaction is within our auto-resume window.
                if (autoResumeInDays != 0)
                {
                    if (autoResumeInDays < 0 || interaction.InteractionDateTime >= now.AddDays(-autoResumeInDays))
                    {
                        options.ResumePlaying = true;

                        var data = interaction.InteractionData.FromJsonOrNull <MediaWatchedInteractionData>();
                        options.Map = data?.WatchMap;
                    }
                }

                // Check if this interaction is within our combine window.
                if (combinePlayStatisticsInDays != 0)
                {
                    if (combinePlayStatisticsInDays < 0 || interaction.InteractionDateTime >= now.AddDays(-combinePlayStatisticsInDays))
                    {
                        options.InteractionGuid = interaction.Guid;
                    }
                }
            }
        }