/// <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; }
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; }
/// <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; }