/// <summary>
 /// Populates the FileDetail object's properties from the given Content object's properties.
 /// </summary>
 /// <param name="thisObject">Current FileDetail instance on which the extension method is called</param>
 /// <param name="details">Content model from which values to be read</param>
 public static void SetValuesFrom(this FileDetail thisObject, Content details)
 {
     if (details != null && thisObject != null)
     {
         thisObject.ContentID = details.ContentID;
         thisObject.Name = details.Filename;
         thisObject.AzureID = details.ContentAzureID;
         thisObject.AzureURL = details.ContentAzureURL;
         thisObject.Size = details.Size.HasValue ? details.Size.Value : 0;
     }
 }
        /// <summary>
        /// Populates the ContentDetails object's properties from the given Content's object's properties.
        /// </summary>
        /// <param name="thisObject">Current content details model on which the extension method is called</param>
        /// <param name="content">ContentsView model from which values to be read</param>
        public static void SetValuesFrom(this ContentDetails thisObject, Content content)
        {
            if (thisObject != null && content != null)
            {
                var start = DateTime.Now;
                // Populate the base values using the EntityViewModel's SetValuesFrom method.
                (thisObject as EntityDetails).SetValuesFrom(content);
                
                var contentData = new DataDetail();
                thisObject.ContentData = contentData.SetValuesFrom(content);
                
                thisObject.Citation = content.Citation;
                thisObject.DownloadCount = content.DownloadCount ?? 0;

                // Get the distributed by user.
                thisObject.DistributedBy = content.DistributedBy;

                // Produced by is equivalent to created by.
                thisObject.ProducedBy = content.User.FirstName + " " + content.User.LastName;

                thisObject.TourLength = content.TourRunLength;

                // Set Thumbnail properties.
                var thumbnailDetail = new FileDetail {AzureID = content.ThumbnailID ?? Guid.Empty};
                thisObject.Thumbnail = thumbnailDetail;

                // Set video properties.
                var video = content.ContentRelation.FirstOrDefault(cr => cr.ContentRelationshipTypeID == (int)AssociatedContentRelationshipType.Video);
                if (video != null)
                {
                    var videoDetails = new DataDetail();
                    thisObject.Video = videoDetails.SetValuesFrom(video.Content1);
                }

                // Set associated file details.
                thisObject.AssociatedFiles = GetAssociatedFiles(content);
                
            }
        }
        /// <summary>
        /// Populates the FileDetail object's properties from the given Content object's properties.
        /// </summary>
        /// <param name="thisObject">Current FileDetail instance on which the extension method is called</param>
        /// <param name="content">Content model from which values to be read</param>
        public static DataDetail SetValuesFrom(this DataDetail thisObject, Content content)
        {
            if (content != null)
            {
                // Set Content Type.
                ContentTypes type = content.TypeID.ToEnum<int, ContentTypes>(ContentTypes.Generic);

                if (type == ContentTypes.Link)
                {
                    thisObject = new LinkDetail(content.ContentUrl, content.ContentID);
                }
                else
                {
                    var fileDetail = new FileDetail();
                    fileDetail.SetValuesFrom(content);
                    thisObject = fileDetail;
                }

                thisObject.Name = content.Filename;
                thisObject.ContentType = type;
            }

            return thisObject;
        }
        /// <summary>
        /// Uploads all files to azure.
        /// </summary>
        /// <param name="contentDetails">Details of the content.</param>
        private bool UploadFilesToAzure(ContentDetails contentDetails, Content content)
        {
            var uploadStatus = true;

            // Upload content data.
            var fileDetail = contentDetails.ContentData as FileDetail;
            if (fileDetail != null && content.ContentAzureID != fileDetail.AzureID)
            {
                // Move the content file from temporary container to file container.
                uploadStatus = MoveFile(fileDetail);
            }

            // Upload video.
            if (contentDetails.Video != null && uploadStatus)
            {
                var videoDetail = contentDetails.Video as FileDetail;
                if (videoDetail != null)
                {
                    // Move the video file from temporary container to file container.
                    uploadStatus = MoveFile(videoDetail);
                }
            }

            return uploadStatus;
        }
        /// <summary>
        /// Sets the Content-Tags relations for given Tags. If the tags are not there in the DB, they will be added.
        /// </summary>
        /// <param name="tagsString">Comma separated tags string</param>
        /// <param name="content">Content to which tags to be related</param>
        private void SetContentTags(string tagsString, Content content)
        {
            // Delete all existing tags which are not part of the new tags list.
            content.RemoveTags(tagsString);

            // Create Tags and relationships.
            if (!string.IsNullOrWhiteSpace(tagsString))
            {
                var tagsArray = tagsString.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Trim());
                if (tagsArray != null && tagsArray.Count() > 0)
                {
                    var notExistingTags = from tag in tagsArray
                                          where Enumerable.FirstOrDefault(content.ContentTags, t => t.Tag.Name == tag) == null
                                          select tag;

                    foreach (var tag in notExistingTags)
                    {
                        var objTag = _tagRepository.GetItem((Tag t) => t.Name == tag);

                        if (objTag == null)
                        {
                            objTag = new Tag();
                            objTag.Name = tag;
                        }

                        var contentTag = new ContentTags();
                        contentTag.Content = content;
                        contentTag.Tag = objTag;

                        content.ContentTags.Add(contentTag);
                    }
                }
            }
        }
        /// <summary>
        /// Creates the relationship for associated contents.
        /// </summary>
        /// <param name="content">Content which has to be updated.</param>
        /// <param name="contentDetails">Details of the content.</param>
        private static void CreateAssociateContents(Content content, ContentDetails contentDetails)
        {
            if (contentDetails.AssociatedFiles != null && contentDetails.AssociatedFiles.Count() > 0)
            {
                foreach (var dataDetails in contentDetails.AssociatedFiles)
                {
                    // Create new associated file only if contentId is not set
                    if (!dataDetails.ContentID.HasValue || dataDetails.ContentID.Value <= 0)
                    {
                        var associatedContent = new Content();
                        associatedContent.SetValuesFrom(contentDetails, dataDetails);

                        // Note that Modifying user is the one who is creating the associated contents.
                        associatedContent.CreatedByID = content.ModifiedByID.Value;

                        var associatedRelation = new ContentRelation()
                        {
                            Content = content,
                            Content1 = associatedContent,
                            ContentRelationshipTypeID = (int)AssociatedContentRelationshipType.Associated
                        };
                        content.ContentRelation.Add(associatedRelation);
                    }
                }
            }
        }
        /// <summary>
        /// Updates the relationship for associated contents.
        /// </summary>
        /// <param name="contentDetails">Details of the content.</param>
        /// <param name="content">Content which has to be updated.</param>
        private static void UpdateAssociateContents(ContentDetails contentDetails, Content content)
        {
            var deletedById = content.ModifiedByID.Value;

            // Get all Existing files list.
            var newFilesIDs = contentDetails.AssociatedFiles
                .Where(af => (af.ContentID.HasValue) && (af.ContentID.Value > 0))
                .Select(af => af.ContentID.Value);

            // Delete all existing associated files which are not part of the new associated file list.
            var removeAssociatedFiles = from cr in content.ContentRelation
                                        where cr.ContentRelationshipTypeID == (int)AssociatedContentRelationshipType.Associated
                                            && !newFilesIDs.Contains(cr.Content1.ContentID)
                                        select cr;

            foreach (var item in Enumerable.ToList(removeAssociatedFiles))
            {
                item.Content1.IsDeleted = true;
                item.Content1.DeletedByID = deletedById;
                item.Content1.DeletedDatetime = DateTime.UtcNow;

                content.ContentRelation.Remove(item);
            }

            // Create new associated files.
            CreateAssociateContents(content, contentDetails);
        }
        /// <summary>
        /// Updates the relationship for video and content.
        /// </summary>
        /// <param name="content">Content which has to be updated.</param>
        /// <param name="contentDetails">Details of the content.</param>
        private static void CreateVideo(Content content, ContentDetails contentDetails)
        {
            if (contentDetails.Video != null)
            {
                var videoContent = new Content();
                videoContent.SetValuesFrom(contentDetails, contentDetails.Video);

                // Note that Modifying user is the one who is creating the video.
                videoContent.CreatedByID = content.ModifiedByID.Value;

                var contentRelation = new ContentRelation()
                {
                    Content = content,
                    Content1 = videoContent,
                    ContentRelationshipTypeID = (int)AssociatedContentRelationshipType.Video
                };

                content.ContentRelation.Add(contentRelation);
            }
        }
        /// <summary>
        /// Updates the relationship for video and content.
        /// </summary>
        /// <param name="content">Content which has to be updated.</param>
        /// <param name="contentDetails">Details of the content.</param>
        private static void UpdateVideo(Content content, ContentDetails contentDetails)
        {
            var videoDetail = contentDetails.Video as FileDetail;
            if (videoDetail != null)
            {
                var deletedById = content.ModifiedByID.Value;

                var existingVideo = Enumerable.Where(content.ContentRelation, cr => cr.ContentRelationshipTypeID == (int)AssociatedContentRelationshipType.Video
                                    && cr.Content1.IsDeleted == false).FirstOrDefault();

                if (existingVideo != null)
                {
                    // Remove the previous videos from azure.
                    existingVideo.Content1.IsDeleted = true;
                    existingVideo.Content1.DeletedByID = deletedById;
                    existingVideo.Content1.DeletedDatetime = DateTime.UtcNow;

                    content.ContentRelation.Remove(existingVideo);
                }

                CreateVideo(content, contentDetails);
            }
        }
        /// <summary>
        /// Updates the relationship for parent and content.
        /// </summary>
        /// <param name="contentDetails">Details of the content.</param>
        /// <param name="content">Content which has to be updated.</param>
        private static void UpdateParent(ContentDetails contentDetails, Content content)
        {
            // Few things to be noted:
            // a) Obviously the count to be 1 always.
            // b) A content can be child of only once parent community or folder
            if (Enumerable.ElementAt(content.CommunityContents, 0).CommunityID != contentDetails.ParentID)
            {
                if (content.CommunityContents.Count > 0)
                {
                    content.CommunityContents.Clear();
                }

                var comCont = new CommunityContents()
                {
                    CommunityID = contentDetails.ParentID,
                    Content = content
                };

                // Add the relationship
                content.CommunityContents.Add(comCont);
            }
        }
        /// <summary>
        /// Gets the role of the user on the given Content.
        /// </summary>
        /// <param name="content">Content on which user role has to be found</param>
        /// <param name="userId">Current user id</param>
        /// <returns>UserRole on the content</returns>
        public UserRole GetContentUserRole(Content content, long? userId)
        {
            var userRole = UserRole.Visitor;

            if (content != null)
            {
                if (userId.HasValue && content.CreatedByID == userId.Value)
                {
                    userRole = UserRole.Owner;
                }
                else
                {
                    var accessType = _contentRepository.GetContentAccessType(content.ContentID);
                    var parent = Enumerable.FirstOrDefault(content.CommunityContents);
                    if (parent != null)
                    {
                        if (userId.HasValue)
                        {
                            userRole = _userRepository.GetUserRole(userId.Value, parent.Community.CommunityID);
                        }

                        if (userRole == UserRole.Moderator)
                        {
                            // In case of user is Moderator for the parent community, he should be considered as moderator inherited so 
                            // that he will be having permissions to edit/delete this content.
                            userRole = UserRole.ModeratorInheritted;
                        }
                        else if (userRole == UserRole.Contributor)
                        {
                            // In case of user is Contributor for the parent community, he should be considered as Owner if the content
                            // is created by him. If the content is not created by him, he should be considered as Reader.
                            if (content.CreatedByID == userId)
                            {
                                userRole = UserRole.Owner;
                            }
                            else
                            {
                                userRole = UserRole.Reader;
                            }
                        }
                    }

                    // 1. In case if Private content, only users who are given access (Reader/Contributor/Moderator/Owner) can access them.
                    // 2. If the required user role is not higher or equal to the user role, then return null.
                    if (accessType == AccessType.Private.ToString() && userRole < UserRole.Reader)
                    {
                        // No permissions for the user on the given community
                        return UserRole.None;
                    }
                }
            }

            return userRole;
        }
        /// <summary>
        /// Creates the new content in Layerscape with the given details passed in ContentsView instance.
        /// </summary>
        /// <param name="contentDetails">Details of the content</param>
        /// <returns>Id of the content created. Returns -1 is creation is failed.</returns>
        public long CreateContent(ContentDetails contentDetails)
        {
            // Make sure content is not null
            this.CheckNotNull(() => new { contentDetails });

            long contentId = -1;

            var userRole = GetCommunityUserRole(contentDetails.ParentID, contentDetails.CreatedByID);
            if (!CanCreateContent(userRole))
            {
                // TODO: Throw custom permissions exception which will be shown to user in error page.
                throw new HttpException(401, Resources.NoPermissionCreateContentMessage);
            }

            // Upload content data, thumbnail, video and associated file to azure.
            // Since the associated files are already stored in the Temporary container.
            // We need to move the files to actual container.
            if (UploadFilesToAzure(contentDetails))
            {
                if (MoveAssociatedFiles(contentDetails))
                {
                    try
                    {
                        // Create a new instance of content details
                        var content = new Content();

                        // Set values from content details.
                        content.SetValuesFrom(contentDetails);

                        // Set the thumbnail ID.
                        content.ThumbnailID = MoveThumbnail(contentDetails.Thumbnail);

                        // Set Created and modified time.
                        content.CreatedDatetime = content.ModifiedDatetime = DateTime.UtcNow;

                        // Set Created and modified IDs.
                        content.ModifiedByID = contentDetails.CreatedByID;
                        content.CreatedByID = contentDetails.CreatedByID;

                        // Set Default Values.
                        content.IsDeleted = false;
                        content.IsSearchable = true;
                        content.IsOffensive = false;
                        content.DownloadCount = 0;

                        var parentCommunity = _communityRepository.GetItem(c => c.CommunityID == contentDetails.ParentID);
                        if (parentCommunity != null)
                        {
                            parentCommunity.ModifiedByID = contentDetails.CreatedByID;
                            parentCommunity.ModifiedDatetime = DateTime.UtcNow;

                            // Updated Parent child relationship
                            var comCont = new CommunityContents()
                            {
                                Community = parentCommunity,
                                Content = content
                            };

                            // Add the relationship
                            content.CommunityContents.Add(comCont);
                        }

                        // Update video file details in database.
                        CreateVideo(content, contentDetails);

                        // Update associated files details in database.
                        CreateAssociateContents(content, contentDetails);

                        // Update Tags.
                        SetContentTags(contentDetails.Tags, content);

                        //// TODO: Update Permissions Details.
                        //// TODO: Update Consumed size of the user. If the size is more than allowed throw error.

                        _contentRepository.Add(content);

                        // Save changes to the database
                        _contentRepository.SaveChanges();

                        // Get the content ID from database. We need to retrieve it from the database as it is a identity column.
                        contentId = content.ContentID;
                    }
                    catch (Exception)
                    {
                        // Delete Uploaded Content/Video/Thumbnail
                        // Note:- Deleting associated files as will be handled by a worker role 
                        //  which will delete temporary file from container.
                        DeleteUploadedFiles(contentDetails);
                        throw;
                    }
                }
                else
                {
                    // Delete Uploaded Content/Video/Thumbnail
                    // Note:- Deleting associated files as will be handled by a worker role 
                    //  which will delete temporary file from container.
                    DeleteUploadedFiles(contentDetails);
                }
            }
            return contentId;
        }
Example #13
0
        public ActionResult GetTourAuthorThumb(Guid tourId)
        {
            var tour = _contentService.GetContentDetails(tourId);
            var thumb = tour.AssociatedFiles.FirstOrDefault();
            var thumbContent = new Content();
            thumbContent.SetValuesFrom(tour, thumb);

            var blobDetails = _blobService.GetFile(thumbContent.ContentAzureID);
            if (blobDetails != null && blobDetails.Data != null)
            {
                blobDetails.MimeType = Constants.DefaultThumbnailMimeType;

                // Update the response header.
                Response.AddHeader("Content-Encoding", blobDetails.MimeType);

                // Set the position to Begin.
                blobDetails.Data.Seek(0, SeekOrigin.Begin);
                return new FileStreamResult(blobDetails.Data, blobDetails.MimeType);
            }
            return new EmptyResult();

        }
        /// <summary>
        /// Gets the associated files from content input view model.
        /// </summary>
        /// <param name="content">Input view model.</param>
        /// <returns>Associated files.</returns>
        private static IEnumerable<DataDetail> GetAssociatedFiles(Content content)
        {
            var associatedFiles = new List<DataDetail>();
            if (content.ContentRelation.Count > 0)
            {
                for (int i = 0; i < content.ContentRelation.Count; i++)
                {
                    var contentRelation = content.ContentRelation.ElementAt(i);

                    if (contentRelation.ContentRelationshipTypeID == (int)AssociatedContentRelationshipType.Associated)
                    {
                        // If the posted file details does not have the following details 
                        // then do not process the file.
                        var fileDetail = new DataDetail();
                        associatedFiles.Add(fileDetail.SetValuesFrom(content.ContentRelation.ElementAt(i).Content1));
                    }
                }
            }

            return associatedFiles;
        }
Example #15
0
        /// <summary>
        /// Check whether the user can edit/delete the content.
        /// </summary>
        /// <param name="content">Content instance</param>
        /// <param name="userId">User Identification</param>
        /// <param name="userRole">Role of the User.</param>
        /// <returns>True if the user has permission to edit/delete  the content; Otherwise False.</returns>
        protected static bool CanEditDeleteContent(Content content, long userId, UserRole userRole)
        {
            var canDelete = false;
            if (content != null)
            {
                if (userRole == UserRole.Contributor && content.CreatedByID == userId)
                {
                    // Contributors can edit/delete only content that they have added, they cannot modify/delete content added by others
                    canDelete = true;
                }
                else if (userRole >= UserRole.Moderator)
                {
                    // Owners and moderators can edit/remove content added by anyone else
                    canDelete = true;
                }
            }

            return canDelete;
        }