/// <summary> /// Creates an instance of <see cref="CacheItemAlbum" /> from <paramref name="album" />. This instance is suitable for storing in cache. /// If <paramref name="album" /> is not inflated, a call to the data store is made to retrieve the child albums and media assets. /// </summary> /// <param name="album">The album.</param> /// <returns>An instance of <see cref="CacheItemAlbum" />.</returns> public static CacheItemAlbum CreateFrom(IAlbum album) { ConcurrentDictionary <int, byte> childAlbumIds; ConcurrentDictionary <int, byte> childMediaObjectIds; if (album.AreChildrenInflated) { childAlbumIds = new ConcurrentDictionary <int, byte>(album.GetChildGalleryObjects(GalleryObjectType.Album).ToDictionary(k => k.Id, v => (byte)0)); childMediaObjectIds = new ConcurrentDictionary <int, byte>(album.GetChildGalleryObjects(GalleryObjectType.MediaObject).ToDictionary(k => k.Id, v => (byte)0)); } else { using (var repo = new AlbumRepository()) { childAlbumIds = new ConcurrentDictionary <int, byte>(repo.Where(a => a.FKAlbumParentId == album.Id).ToDictionary(k => k.AlbumId, v => (byte)0)); } using (var repo = new MediaObjectRepository()) { childMediaObjectIds = new ConcurrentDictionary <int, byte>(repo.Where(a => a.FKAlbumId == album.Id).ToDictionary(k => k.MediaObjectId, v => (byte)0)); } } return(new CacheItemAlbum(album.Id, album.GalleryId, album.Parent.Id, album.GalleryObjectType, album.Sequence, album.DateAdded, CacheItemMetaItem.FromMetaItems(album.MetadataItems, album.Id, album.GalleryObjectType), album.CreatedByUserName, album.LastModifiedByUserName, album.DateLastModified, album.IsPrivate, album.DirectoryName, album.ThumbnailMediaObjectId, album.SortByMetaName, album.SortAscending, album.OwnerUserName, album.OwnerRoleName, childAlbumIds, childMediaObjectIds)); }
/// <summary> /// Adds the media objects in the <paramref name="album"/> to the ZIP archive. Only media objects associated with a /// physical file are added (that is, external media objects are excluded). /// </summary> /// <param name="zos">The ZipOutputStream (ZIP archive) the media object file is to be added to.</param> /// <param name="album">The album to be added to the ZIP archive.</param> /// <param name="imageSize">Size of the image to add to the ZIP archive. This parameter applies only to <see cref="Image"/> /// media objects.</param> /// <param name="basePath">The full path to the directory containing the highest-level media file to be added /// to the ZIP archive. Must include trailing slash. Ex: C:\Inetpub\wwwroot\galleryserverpro\mediaobjects\Summer 2005\sunsets\</param> /// <param name="applyWatermark">Indicates whether to apply a watermark to images as they are added to the archive. /// Applies only for media objects in the <see cref="album"/> that are an <see cref="Image"/>.</param> private void AddZipEntry(ZipOutputStream zos, IAlbum album, DisplayObjectType imageSize, string basePath, bool applyWatermark) { foreach (IAlbum childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album, false, !this._isAuthenticated)) { AddZipEntry(zos, childAlbum, imageSize, basePath, applyWatermark); } foreach (IGalleryObject mediaObject in album.GetChildGalleryObjects(GalleryObjectType.MediaObject, false, !this._isAuthenticated)) { AddFileZipEntry(zos, mediaObject, imageSize, basePath, applyWatermark); } }
/// <summary> /// Deletes the thumbnail and optimized images associated with this album and all its children, but do not delete the /// album's directory or the any other files it contains. /// </summary> /// <param name="album">The album.</param> private static void DeleteSupportFilesOnly(IAlbum album) { foreach (IGalleryObject childGalleryObject in album.GetChildGalleryObjects(GalleryObjectType.MediaObject)) { DeleteThumbnailAndOptimizedImagesFromFileSystem(childGalleryObject); } foreach (IAlbum childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album)) { DeleteSupportFilesOnly(childAlbum); } }
private static void DeleteOriginalFilesFromAlbum(IAlbum album) { // Delete the original file for each item in the album. Then recursively do the same thing to all child albums. foreach (IGalleryObject mediaObject in album.GetChildGalleryObjects(GalleryObjectType.MediaObject)) { mediaObject.DeleteOriginalFile(); GalleryObjectController.SaveGalleryObject(mediaObject); } foreach (IAlbum childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album)) { DeleteOriginalFilesFromAlbum(childAlbum); } }
private static void DeleteHiResImagesFromAlbum(IAlbum album) { // Delete the hi-res image for each image in the album. Then recursively do the same thing to all child albums. foreach (GalleryServerPro.Business.Image image in album.GetChildGalleryObjects(GalleryObjectType.Image)) { image.DeleteHiResImage(); GalleryObjectController.SaveGalleryObject(image); } foreach (IAlbum childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album)) { DeleteHiResImagesFromAlbum(childAlbum); } }
/// <summary> /// Fill the treeview with all albums. All nodes representing albums for which the specified role has permission /// will be checked. If the overload that doesn't take a role parameter is used, then check all checkboxes if the /// isAdministratorChecked parameter is true. /// </summary> /// <param name="role">The role to be updated. If adding a new role, then set this parameter to null.</param> /// <param name="isAdministrator">Indicates whether the administrator permission checkbox has been /// checked or the specified role has administrative permission. Since administrative permission applies to all /// albums, when this parameter is true, all checkboxes for all albums will be checked. An exception is thrown /// if the role.AllowAdministerSite property and the isAdministrator parameter do not match.</param> private void BindAlbumTreeview(IGalleryServerRole role, bool isAdministrator) { if ((role != null) && (role.AllowAdministerSite != isAdministrator)) { throw new ArgumentException("Invalid arguments passed to BindAlbumTreeview method: The role.AllowAdministerSite property and the isAdministrator parameter must match."); } if (role != null) // Role will be null when user is adding a new role { IIntegerCollection albumIds = tvUC.AlbumIdsToCheck; albumIds.Clear(); albumIds.AddRange(role.RootAlbumIds); foreach (IGallery gallery in Factory.LoadGalleries()) { IAlbum rootAlbum = Factory.LoadRootAlbumInstance(gallery.GalleryId); if (role.RootAlbumIds.Contains(rootAlbum.Id)) { // The role applies to all albums. Since the treeview initially renders to two levels, we need // to add the album IDs for the root album's child albums. foreach (IGalleryObject album in rootAlbum.GetChildGalleryObjects(GalleryObjectType.Album)) { albumIds.Add(album.Id); } } } } tvUC.RequiredSecurityPermissions = SecurityActions.AdministerSite | SecurityActions.AdministerGallery; tvUC.Galleries = Factory.LoadGalleries(); tvUC.RootAlbumPrefix = String.Concat(Resources.GalleryServerPro.Site_Gallery_Text, " '{GalleryDescription}': "); tvUC.BindTreeView(); }
/// <summary> /// Performs any necessary actions that must occur before an album is deleted. Specifically, it deletes the owner role /// if one exists for the album, but only when this album is the only one assigned to the role. It also clears out /// <see cref="IGallerySettings.UserAlbumParentAlbumId" /> if the album's ID matches it. This function recursively calls /// itself to make sure all child albums are processed. /// </summary> /// <param name="album">The album to be deleted, or one of its child albums.</param> private static void OnBeforeAlbumDelete(IAlbum album) { // If there is an owner role associated with this album, and the role is not assigned to any other albums, delete it. if (!String.IsNullOrEmpty(album.OwnerRoleName)) { IGalleryServerRole role = RoleController.GetGalleryServerRoles().GetRole(album.OwnerRoleName); if ((role != null) && (role.AllAlbumIds.Count == 1) && role.AllAlbumIds.Contains(album.Id)) { RoleController.DeleteGalleryServerProRole(role.RoleName); } } // If the album is specified as the user album container, clear out the setting. The ValidateBeforeAlbumDelete() // function will throw an exception if user albums are enabled, so this should only happen when user albums // are disabled, so it is safe to clear it out. int userAlbumParentAlbumId = Factory.LoadGallerySetting(album.GalleryId).UserAlbumParentAlbumId; if (album.Id == userAlbumParentAlbumId) { IGallerySettings gallerySettingsWriteable = Factory.LoadGallerySetting(album.GalleryId, true); gallerySettingsWriteable.UserAlbumParentAlbumId = 0; gallerySettingsWriteable.Save(); } // Recursively validate child albums. foreach (IGalleryObject childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album)) { OnBeforeAlbumDelete((IAlbum)childAlbum); } }
/// <summary> /// Set the IsPrivate property of all child albums and media objects of the specified album to have the same value /// as the specified album. /// </summary> /// <param name="album">The album whose child objects are to be updated to have the same IsPrivate value.</param> private static void SynchIsPrivatePropertyOnChildGalleryObjects(IAlbum album) { album.Inflate(true); foreach (IAlbum childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album)) { childAlbum.Inflate(true); // The above Inflate() does not inflate child albums, so we need to explicitly inflate it. childAlbum.IsPrivate = album.IsPrivate; GalleryObjectController.SaveGalleryObject(childAlbum); SynchIsPrivatePropertyOnChildGalleryObjects(childAlbum); } foreach (IGalleryObject childGalleryObject in album.GetChildGalleryObjects(GalleryObjectType.MediaObject)) { childGalleryObject.IsPrivate = album.IsPrivate; GalleryObjectController.SaveGalleryObject(childGalleryObject); } }
public static IQueryable <GalleryItem> GetGalleryItemsHavingTags(string[] tags, string[] people, int galleryId, MetadataItemName sortByMetaName, bool sortAscending) { IAlbum album = GetGalleryObjectsHavingTags(tags, people, galleryId); IList <IGalleryObject> galleryObjects; if (MetadataItemNameEnumHelper.IsValidFormattedMetadataItemName(sortByMetaName)) { galleryObjects = album.GetChildGalleryObjects(GalleryObjectType.All, !Utils.IsAuthenticated).ToSortedList(sortByMetaName, sortAscending, album.GalleryId); } else { galleryObjects = album.GetChildGalleryObjects(GalleryObjectType.All, !Utils.IsAuthenticated).ToSortedList(); } return(ToGalleryItems(galleryObjects).AsQueryable()); }
private static void DeleteOrphanedAlbumRecords(IAlbum album) { // Delete album records that weren't sync'd. foreach (var childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album).Where(a => !a.IsSynchronized)) { childAlbum.DeleteFromGallery(); } }
private bool Initialize(string synchId, IAlbum album, string userName) { if (String.IsNullOrEmpty(userName)) { throw new ArgumentNullException("userName"); } this._userName = userName; #region Set up the _synchStatus instance this._synchStatus = SynchronizationStatus.Instance; // Tell that status instance we are starting a new synchronization. It will throw // SynchronizationInProgressException if another is in progress. this._synchStatus.Start(synchId, CountFiles(album.FullPhysicalPathOnDisk)); #endregion #region Populate the _albumsFromDataStore and _mediaObjectsFromDataStore dictionary objects and set each to IsSynchronized = false this._albumsFromDataStore = new Dictionary <String, IAlbum>(); this._mediaObjectsFromDataStore = new Dictionary <String, IGalleryObject>(this._synchStatus.TotalFileCount); // Fill _albums and _mediaObjects with the albums and media objects for this album as currently stored // in the data store. We'll be comparing these objects with those we find on the hard drive. Act recursively // if IsRecursive = true. Set IsSynchronized = false for each object. (We'll be setting it back to true // as we synchronize each object.) album.IsSynchronized = false; album.RegenerateThumbnailOnSave = this.OverwriteThumbnail; this._albumsFromDataStore.Add(album.FullPhysicalPathOnDisk, album); foreach (IGalleryObject mediaObject in album.GetChildGalleryObjects(GalleryObjectType.MediaObject)) { mediaObject.IsSynchronized = false; mediaObject.RegenerateThumbnailOnSave = this.OverwriteThumbnail; mediaObject.RegenerateOptimizedOnSave = this.OverwriteOptimized; mediaObject.RegenerateMetadataOnSave = this.RegenerateMetadata; if (!String.IsNullOrEmpty(mediaObject.Hashkey)) { this._mediaObjectsFromDataStore.Add(mediaObject.Hashkey, mediaObject); } } if (this._isRecursive) { AddChildAlbumsAndGalleryObjectsAndSetToUnsynchronized(this._albumsFromDataStore, this._mediaObjectsFromDataStore, album); } #endregion // Clear the list of hash keys so we're starting with a fresh load from the data store. MediaObjectHashKeys.Clear(); return(true); }
/// <summary> /// Gets the gallery objects in the album. Includes albums and media objects. /// </summary> /// <param name="albumId">The album ID.</param> /// <param name="sortByMetaName">The sort by meta name id.</param> /// <param name="sortAscending">if set to <c>true</c> [sort ascending].</param> /// <returns>Returns an <see cref="IQueryable" /> instance of <see cref="Entity.GalleryItem" />.</returns> /// <exception cref="InvalidAlbumException">Thrown when an album with the specified /// <paramref name="albumId" /> is not found in the data store.</exception> /// <exception cref="GalleryServerPro.Events.CustomExceptions.GallerySecurityException">Thrown when the user does not have at least one of the requested permissions to the /// specified album.</exception> public static IQueryable <GalleryItem> GetGalleryItemsInAlbum(int albumId, MetadataItemName sortByMetaName, bool sortAscending) { IAlbum album = Factory.LoadAlbumInstance(albumId, true); SecurityManager.ThrowIfUserNotAuthorized(SecurityActions.ViewAlbumOrMediaObject, RoleController.GetGalleryServerRolesForUser(), album.Id, album.GalleryId, Utils.IsAuthenticated, album.IsPrivate, album.IsVirtualAlbum); IList <IGalleryObject> galleryObjects; if (MetadataItemNameEnumHelper.IsValidFormattedMetadataItemName(sortByMetaName)) { galleryObjects = album.GetChildGalleryObjects(GalleryObjectType.All, !Utils.IsAuthenticated).ToSortedList(sortByMetaName, sortAscending, album.GalleryId); } else { galleryObjects = album.GetChildGalleryObjects(GalleryObjectType.All, !Utils.IsAuthenticated).ToSortedList(); } return(ToGalleryItems(galleryObjects).AsQueryable()); }
private static void DeleteOrphanedMediaObjectRecords(IAlbum album) { // Delete media object records that weren't sync'd. var orphanMediaObjects = album.GetChildGalleryObjects(GalleryObjectType.MediaObject) .Where(mo => !mo.IsSynchronized && mo.GalleryObjectType != GalleryObjectType.External); foreach (var mediaObject in orphanMediaObjects) { mediaObject.DeleteFromGallery(); } }
/// <summary> /// Gets the total file size, in KB, of all the high resolution images in the <paramref name="album"/>, including all /// child albums. The total does not include images that do not have a high resolution version, nor does /// it include file size of any other type of media object, such as video or audio files. /// </summary> /// <param name="album">The album for which to retrieve the file size of all high res images.</param> /// <returns>Returns the total file size, in KB, of all the high resolution images in the <paramref name="album"/>.</returns> private static long GetFileSizeKbAllHiResImagesInAlbum(IAlbum album) { // Get the total file size, in KB, of all the high resolution images in the specified album long sumTotal = 0; foreach (IGalleryObject go in album.GetChildGalleryObjects(GalleryObjectType.Image)) { if (go.Original.FileName != go.Optimized.FileName) { sumTotal += go.Original.FileSizeKB; } } foreach (IAlbum childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album)) { sumTotal += GetFileSizeKbAllHiResImagesInAlbum(childAlbum); } return(sumTotal); }
/// <summary> /// Converts the <paramref name="galleryObject" /> to an instance of <see cref="Entity.GalleryItem" />. /// The instance can be JSON-serialized and sent to the browser. /// </summary> /// <param name="galleryObject">The gallery object to convert to an instance of /// <see cref="Entity.GalleryItem" />. It may be a media object or album.</param> /// <param name="browsers">An <see cref="System.Array"/> of browser ids for the current browser. This /// is a list of strings that represent the various categories of browsers the current browser belongs /// to. This is typically populated by calling ToArray() on the Request.Browser.Browsers property. /// If set to null, the property is automatically populated.</param> /// <returns> /// Returns an <see cref="Entity.GalleryItem" /> object containing information /// about the requested item. /// </returns> /// <exception cref="ArgumentNullException">Thrown when <paramref name="galleryObject" /> or /// <paramref name="browsers" /> is null.</exception> /// <exception cref="System.ArgumentOutOfRangeException">Thrown when <paramref name="browsers" /> does /// not contain any elements.</exception> public static GalleryItem ToGalleryItem(IGalleryObject galleryObject, Array browsers) { if (galleryObject == null) { throw new ArgumentNullException("galleryObject"); } if (browsers == null) { throw new ArgumentNullException("browsers"); } if (browsers.Length == 0) { throw new ArgumentOutOfRangeException("browsers", "The browsers array parameter must have at least one element."); } var gItem = new GalleryItem { Id = galleryObject.Id, Title = galleryObject.Title, Caption = galleryObject.Caption, Views = GetViews(galleryObject, browsers).ToArray(), ViewIndex = 0, MimeType = (int)galleryObject.MimeType.TypeCategory, ItemType = (int)galleryObject.GalleryObjectType }; IAlbum album = galleryObject as IAlbum; if (album != null) { gItem.IsAlbum = true; //gItem.DateStart = album.DateStart; //gItem.DateEnd = album.DateEnd; gItem.NumAlbums = album.GetChildGalleryObjects(GalleryObjectType.All, !Utils.IsAuthenticated).Count; gItem.NumMediaItems = album.GetChildGalleryObjects(GalleryObjectType.MediaObject, !Utils.IsAuthenticated).Count; } return(gItem); }
/// <summary> /// Gets the IDs of the child albums of the specified <paramref name="album" />, acting recursively. /// </summary> /// <param name="album">The album.</param> /// <returns>Returns an enumerable list of album ID values.</returns> private static IEnumerable <int> GetChildAlbumIds(IAlbum album) { var albumIds = new List <int>(); foreach (IGalleryObject childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album)) { albumIds.Add(childAlbum.Id); albumIds.AddRange(GetChildAlbumIds((IAlbum)childAlbum)); } return(albumIds); }
public void DisplayThumbnails(IAlbum album) { string msg = string.Empty; //Get the data associated with the album and display IGalleryObjectCollection albumObjects; if (this.PageBase.IsAnonymousUser) { albumObjects = album.GetChildGalleryObjects(true, true); } else { albumObjects = album.GetChildGalleryObjects(true); } if (albumObjects.Count > 0) { // At least one album or media object in album. msg = String.Format(CultureInfo.CurrentCulture, "<p class='addtopmargin2'>{0}</p>", Resources.GalleryServerPro.UC_ThumbnailView_Intro_Text_With_Objects); phMsg.Controls.Add(new LiteralControl(msg)); } else if (this.PageBase.UserCanAddMediaObject) { // No objects, user has permission to add media objects. string innerMsg = String.Format(CultureInfo.CurrentCulture, Resources.GalleryServerPro.UC_ThumbnailView_Intro_Text_No_Objects_User_Has_Add_MediaObject_Permission, album.Id); msg = String.Format(CultureInfo.CurrentCulture, "<p class='addtopmargin2 msgfriendly'>{0}</p>", innerMsg); phMsg.Controls.Add(new LiteralControl(msg)); } else { // No objects, user doesn't have permission to add media objects. msg = String.Format(CultureInfo.CurrentCulture, "<p class='addtopmargin2 msgfriendly'>{0}</p>", Resources.GalleryServerPro.UC_ThumbnailView_Intro_Text_No_Objects); phMsg.Controls.Add(new LiteralControl(msg)); } this.PageBase.SetThumbnailCssStyle(albumObjects); rptr.DataSource = albumObjects; rptr.DataBind(); }
private TreeView GenerateTreeview() { // We'll use a TreeView instance to generate the appropriate XML structure ComponentArt.Web.UI.TreeView tv = new ComponentArt.Web.UI.TreeView(); string handlerPath = String.Concat(Utils.GalleryRoot, "/handler/gettreeviewxml.ashx"); IAlbum parentAlbum = AlbumController.LoadAlbumInstance(this._albumId, true); string securityActionParm = String.Empty; if (SecurityActionEnumHelper.IsValidSecurityAction(this._securityAction)) { securityActionParm = String.Format(CultureInfo.CurrentCulture, "&secaction={0}", (int)this._securityAction); } foreach (IAlbum childAlbum in parentAlbum.GetChildGalleryObjects(GalleryObjectType.Album, true, !Utils.IsAuthenticated)) { TreeViewNode node = new TreeViewNode(); node.Text = Utils.RemoveHtmlTags(childAlbum.Title); node.Value = childAlbum.Id.ToString(CultureInfo.InvariantCulture); node.ID = childAlbum.Id.ToString(CultureInfo.InvariantCulture); if (!String.IsNullOrEmpty(_navigateUrl)) { node.NavigateUrl = Utils.AddQueryStringParameter(_navigateUrl, String.Concat("aid=", childAlbum.Id.ToString(CultureInfo.InvariantCulture))); node.HoverCssClass = "tv0HoverTreeNodeLink"; } bool isUserAuthorized = true; if (SecurityActionEnumHelper.IsValidSecurityAction(this._securityAction)) { isUserAuthorized = Utils.IsUserAuthorized(_securityAction, RoleController.GetGalleryServerRolesForUser(), childAlbum.Id, childAlbum.GalleryId, childAlbum.IsPrivate); } node.ShowCheckBox = isUserAuthorized && _showCheckbox; node.Selectable = isUserAuthorized; if (!isUserAuthorized) { node.HoverCssClass = String.Empty; } if (childAlbum.GetChildGalleryObjects(GalleryObjectType.Album).Count > 0) { string handlerPathWithAlbumId = Utils.AddQueryStringParameter(handlerPath, String.Concat("aid=", childAlbum.Id.ToString(CultureInfo.InvariantCulture))); node.ContentCallbackUrl = String.Format(CultureInfo.CurrentCulture, "{0}{1}&sc={2}&nurl={3}", handlerPathWithAlbumId, securityActionParm, node.ShowCheckBox, Utils.UrlEncode(_navigateUrl)); } tv.Nodes.Add(node); } return(tv); }
private string getAlbumStats(IAlbum album) { //Create a string like: (12 objects, created 3/24/04) int numObjects = album.GetChildGalleryObjects(false, GalleryPage.IsAnonymousUser).Count; if (album.IsVirtualAlbum) { return(String.Format(CultureInfo.CurrentCulture, Resources.GalleryServerPro.UC_Album_Header_Stats_Without_Date_Text, numObjects)); } else { return(String.Format(CultureInfo.CurrentCulture, Resources.GalleryServerPro.UC_Album_Header_Stats_Text, numObjects, album.DateAdded)); } }
private void SynchronizeExternalMediaObjects(IAlbum album) { foreach (IGalleryObject mediaObject in album.GetChildGalleryObjects(GalleryObjectType.External)) { // Check for existence of thumbnail. if (this.OverwriteThumbnail || !File.Exists(mediaObject.Thumbnail.FileNamePhysicalPath)) { mediaObject.RegenerateThumbnailOnSave = true; HelperFunctions.UpdateAuditFields(mediaObject, this._userName); mediaObject.Save(); mediaObject.IsSynchronized = true; } } }
private TreeView GenerateTreeview() { // We'll use a TreeView instance to generate the appropriate XML structure ComponentArt.Web.UI.TreeView tv = new ComponentArt.Web.UI.TreeView(); string handlerPath = String.Concat(Util.GalleryRoot, "/handler/gettreeviewxml.ashx"); IAlbum parentAlbum = Factory.LoadAlbumInstance(this._albumId, true); string securityActionParm = String.Empty; if (SecurityActionEnumHelper.IsValidSecurityAction(this._securityAction)) { securityActionParm = String.Format(CultureInfo.CurrentCulture, "&secaction={0}", (int)this._securityAction); } foreach (IAlbum childAlbum in parentAlbum.GetChildGalleryObjects(GalleryObjectType.Album, true)) { TreeViewNode node = new TreeViewNode(); node.Text = Util.RemoveHtmlTags(childAlbum.Title); node.Value = childAlbum.Id.ToString(CultureInfo.InvariantCulture); node.ID = childAlbum.Id.ToString(CultureInfo.InvariantCulture); bool isUserAuthorized = true; if (SecurityActionEnumHelper.IsValidSecurityAction(this._securityAction)) { isUserAuthorized = Util.IsUserAuthorized(_securityAction, RoleController.GetGalleryServerRolesForUser(), childAlbum.Id, childAlbum.IsPrivate); } node.ShowCheckBox = isUserAuthorized; node.Selectable = isUserAuthorized; if (!isUserAuthorized) { node.HoverCssClass = String.Empty; } if (childAlbum.GetChildGalleryObjects(GalleryObjectType.Album).Count > 0) { node.ContentCallbackUrl = String.Format(CultureInfo.CurrentCulture, "{0}?aid={1}{2}", handlerPath, childAlbum.Id.ToString(CultureInfo.InvariantCulture), securityActionParm); } tv.Nodes.Add(node); } return(tv); }
/// <summary> /// Inspects the specified <paramref name="album" /> to see if the OwnerUserName is in the list of user accounts. If not, the property /// is cleared out (which also clears out the OwnerRoleName property). This function acts recursively on any child albums of the /// <paramref name="album" />. /// </summary> /// <param name="album">The album to inspect.</param> /// <param name="userNames">A list of all usernames in the current membership.</param> private static void DeleteOrphanedAlbumOwner(IAlbum album, List <String> userNames) { if ((!String.IsNullOrEmpty(album.OwnerUserName)) && (!userNames.Contains(album.OwnerUserName))) { if (RoleController.GetUsersInRole(album.OwnerRoleName).Length == 0) { RoleController.DeleteGalleryServerProRole(album.OwnerRoleName); } album.OwnerUserName = String.Empty; // This will also clear out the OwnerRoleName property. GalleryObjectController.SaveGalleryObject(album); } foreach (IAlbum childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album)) { DeleteOrphanedAlbumOwner(childAlbum, userNames); } }
private List <IAlbum> GetOrphanUserAlbums() { // Get a list of all the albums in the user album container that do not belong to a user. List <int> userAlbumIds = new List <int>(); List <IAlbum> orphanUserAlbums = new List <IAlbum>(); // Step 1: Get list of user album ID's. foreach (UserAccount user in UserController.GetAllUsers()) { int userAlbumId = UserController.GetUserAlbumId(user.UserName, GalleryId); if (userAlbumId > int.MinValue) { userAlbumIds.Add(userAlbumId); } } // Step 2: Loop through each album in the user album container and see if the album is in our list of user album IDs. If not, add // to our list of orpan user albums. int albumId = GallerySettingsUpdateable.UserAlbumParentAlbumId; IAlbum userAlbumParent = null; if (albumId > 0) { try { userAlbumParent = AlbumController.LoadAlbumInstance(new AlbumLoadOptions(albumId) { InflateChildObjects = true }); foreach (IAlbum album in userAlbumParent.GetChildGalleryObjects(GalleryObjectType.Album)) { if (!userAlbumIds.Contains(album.Id)) { orphanUserAlbums.Add(album); } } } catch (InvalidAlbumException) { } } return(orphanUserAlbums); }
/// <summary> /// Add the child albums and media objects as stored on disk to the specified dictionary objects. Set /// IsSynchronized = false for each album and media object. This will be set to true as each is processed. /// This method calls itself recursively if IsRecursive = true. /// </summary> /// <param name="albums">A Dictionary object containing relevant albums for this synchronization. The album specified /// in the parentAlbum parameter will be added to this object.</param> /// <param name="mediaObjects">A Dictionary object containing relevant media objects for this synchronization. /// Media objects within the parentAlbum parameter will be added to this object.</param> /// <param name="parentAlbum">The album used as the source for populating the albums and mediaObjects /// parameters.</param> private void AddChildAlbumsAndGalleryObjectsAndSetToUnsynchronized(Dictionary <string, IAlbum> albums, Dictionary <string, IGalleryObject> mediaObjects, IAlbum parentAlbum) { foreach (IAlbum childAlbum in parentAlbum.GetChildGalleryObjects(GalleryObjectType.Album)) { childAlbum.IsSynchronized = false; childAlbum.RegenerateThumbnailOnSave = this.OverwriteThumbnail; try { // There can be situations where the database becomes corrupt, and the same album has two records. When this happens, // the following line will fail. Instead of letting the exception cause the synch to fail, we swallow the exception. // This will cause the album that caused the exception to eventually be deleted, which is what we want. albums.Add(childAlbum.FullPhysicalPathOnDisk, childAlbum); } catch (System.ArgumentException) { } foreach (IGalleryObject mediaObject in childAlbum.GetChildGalleryObjects(GalleryObjectType.MediaObject)) { if (!String.IsNullOrEmpty(mediaObject.Hashkey)) { mediaObject.IsSynchronized = false; mediaObject.RegenerateOptimizedOnSave = this.OverwriteOptimized; mediaObject.RegenerateThumbnailOnSave = this.OverwriteThumbnail; mediaObject.RegenerateMetadataOnSave = this.RegenerateMetadata; try { // There may be situations where the database becomes corrupt, and the same media object has two records. When this happens, // the following line will fail. Instead of letting the exception cause the synch to fail, we swallow the exception. // This will cause the media object that caused the exception to eventually be deleted, which is what we want. mediaObjects.Add(mediaObject.Hashkey, mediaObject); } catch (System.ArgumentException) { } } } if (this._isRecursive) { AddChildAlbumsAndGalleryObjectsAndSetToUnsynchronized(albums, mediaObjects, childAlbum); } } }
private TreeView GenerateTreeview() { // We'll use a TreeView instance to generate the appropriate JSON structure TreeView tv = new TreeView(); IAlbum parentAlbum = AlbumController.LoadAlbumInstance(this._albumId, true); foreach (IAlbum childAlbum in parentAlbum.GetChildGalleryObjects(GalleryObjectType.Album, !Utils.IsAuthenticated).ToSortedList()) { TreeNode node = new TreeNode(); node.Id = String.Concat("tv_", childAlbum.Id.ToString(CultureInfo.InvariantCulture)); node.Text = Utils.RemoveHtmlTags(childAlbum.Title); node.DataId = childAlbum.Id.ToString(CultureInfo.InvariantCulture); if (!String.IsNullOrEmpty(_navigateUrl)) { node.NavigateUrl = Utils.AddQueryStringParameter(_navigateUrl, String.Concat("aid=", childAlbum.Id.ToString(CultureInfo.InvariantCulture))); } bool isUserAuthorized = true; if (SecurityActionEnumHelper.IsValidSecurityAction(this._securityAction)) { isUserAuthorized = Utils.IsUserAuthorized(_securityAction, RoleController.GetGalleryServerRolesForUser(), childAlbum.Id, childAlbum.GalleryId, childAlbum.IsPrivate, childAlbum.IsVirtualAlbum); } node.ShowCheckBox = isUserAuthorized && _showCheckbox; node.Selectable = isUserAuthorized; if (childAlbum.GetChildGalleryObjects(GalleryObjectType.Album, !Utils.IsAuthenticated).Any()) { node.HasChildren = true; } tv.Nodes.Add(node); } return(tv); }
/// <summary> /// Finds the first album within the heirarchy of the specified <paramref name="album"/> whose ID is in /// <paramref name="albumIds"/>. Acts recursively in an across-first, then-down search pattern, resulting /// in the highest level matching album to be returned. Returns null if there are no matching albums. /// </summary> /// <param name="album">The album to be searched to see if it, or any of its children, matches one of the IDs /// in <paramref name="albumIds"/>.</param> /// <param name="albumIds">Contains the IDs of the albums to search for.</param> /// <returns>Returns the first album within the heirarchy of the specified <paramref name="album"/> whose ID is in /// <paramref name="albumIds"/>.</returns> private static IAlbum FindFirstMatchingAlbumRecursive(IAlbum album, ICollection <int> albumIds) { // Is the current album in the list? if (albumIds.Contains(album.Id)) { return(album); } // Nope, so look at the child albums of this album. IAlbum albumToSelect = null; IGalleryObjectCollection childAlbums = album.GetChildGalleryObjects(GalleryObjectType.Album, true); foreach (IGalleryObject childAlbum in childAlbums) { if (albumIds.Contains(childAlbum.Id)) { albumToSelect = (IAlbum)childAlbum; break; } } // Not the child albums either, so iterate through the children of the child albums. Act recursively. if (albumToSelect == null) { foreach (IGalleryObject childAlbum in childAlbums) { albumToSelect = (IAlbum)FindFirstMatchingAlbumRecursive((IAlbum)childAlbum, albumIds); if (albumToSelect != null) { break; } } } return(albumToSelect); // Returns null if no matching album is found }
private static int GetIdOfFirstMediaObject(IAlbum album) { int firstMediaObjectId = 0; foreach (IGalleryObject mediaObject in album.GetChildGalleryObjects(GalleryObjectType.MediaObject, true)) { if (!mediaObject.IsNew) // We might encounter new, unsaved objects while synchronizing. Need to skip these since their ID=int.MinValue { firstMediaObjectId = mediaObject.Id; break; } } if (firstMediaObjectId == 0) { foreach (IGalleryObject childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album, true)) { firstMediaObjectId = GetIdOfFirstMediaObject((IAlbum)childAlbum); if (firstMediaObjectId > 0) break; } } return firstMediaObjectId; }
/// <summary> /// Find, or create if necessary, the album corresponding to the specified directory and set it as the /// child of the parentAlbum parameter. /// </summary> /// <param name="directory">The directory for which to obtain a matching album object.</param> /// <param name="parentAlbum">The album that contains the album at the specified directory.</param> /// <returns>Returns an album object corresponding to the specified directory and having the specified /// parent album.</returns> /// <exception cref="ArgumentNullException">Thrown when <paramref name="directory" /> or <paramref name="parentAlbum" /> is null.</exception> /// <exception cref="ArgumentException">Thrown when </exception> /// <exception cref="ArgumentException">Thrown when the full directory path of the parent of <paramref name="directory" /> does not match the /// directory path of <paramref name="parentAlbum" />.</exception> private IAlbum SynchronizeDirectory(DirectoryInfo directory, IAlbum parentAlbum) { #region Parameter validation if (directory == null) throw new ArgumentNullException("directory"); if (parentAlbum == null) throw new ArgumentNullException("parentAlbum"); if (!directory.Parent.FullName.Equals(parentAlbum.FullPhysicalPathOnDisk.TrimEnd(new char[] { Path.DirectorySeparatorChar }), StringComparison.InvariantCultureIgnoreCase)) throw new ArgumentException(String.Format("Error in SynchronizeDirectory(). directory.Parent.FullName='{0}'; parentAlbum.FullPhysicalPathOnDisk='{1}'", directory.Parent.FullName, parentAlbum.FullPhysicalPathOnDisk.TrimEnd(new char[] { Path.DirectorySeparatorChar }))); #endregion var childAlbum = (IAlbum)parentAlbum.GetChildGalleryObjects(GalleryObjectType.Album) .FirstOrDefault(a => a.FullPhysicalPathOnDisk == directory.FullName); if (childAlbum != null) { // Found the album. Update properties. childAlbum.IsPrivate = (parentAlbum.IsPrivate ? true : childAlbum.IsPrivate); // Only set to private if parent is private childAlbum.RegenerateThumbnailOnSave = RebuildThumbnail; } else { // No album exists for this directory. Create a new one. childAlbum = Factory.CreateEmptyAlbumInstance(parentAlbum.GalleryId); childAlbum.Parent = parentAlbum; string directoryName = directory.Name; childAlbum.Title = directoryName; //childAlbum.ThumbnailMediaObjectId = 0; // not needed childAlbum.DirectoryName = directoryName; childAlbum.FullPhysicalPathOnDisk = Path.Combine(parentAlbum.FullPhysicalPathOnDisk, directoryName); childAlbum.IsPrivate = parentAlbum.IsPrivate; } childAlbum.IsSynchronized = true; if (childAlbum.IsNew || childAlbum.HasChanges) { HelperFunctions.UpdateAuditFields(childAlbum, UserName); childAlbum.Save(); } // Commit the transaction to the database for every 100 media objects that are processed. if ((_synchStatus.CurrentFileIndex - _lastTransactionCommitFileIndex) >= 100) { HelperFunctions.CommitTransaction(); HelperFunctions.BeginTransaction(); _lastTransactionCommitFileIndex = _synchStatus.CurrentFileIndex; } return childAlbum; }
/// <summary> /// Assign a thumbnail image to the album. Use the thumbnail image of the first media object in the album or, /// if no objects exist in the album, the first image in any child albums, searching recursively. If no images /// can be found, set <see cref="ThumbnailMediaObjectId" /> = 0. /// </summary> /// <param name="album">The album whose thumbnail image is to be assigned.</param> /// <param name="recursivelyAssignParentAlbums">Specifies whether to recursively iterate through the /// parent, grandparent, and so on until the root album, assigning a thumbnail, if necessary, to each /// album along the way.</param> /// <param name="recursivelyAssignChildrenAlbums">Specifies whether to recursively iterate through /// all children albums of this album, assigning a thumbnail to each child album, if necessary, along /// the way.</param> /// <param name="userName">The user name for the logged on user. This is used for the audit fields.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="album" /> is null.</exception> public static void AssignAlbumThumbnail(IAlbum album, bool recursivelyAssignParentAlbums, bool recursivelyAssignChildrenAlbums, string userName) { if (album == null) throw new ArgumentNullException("album"); if (!album.IsWritable) { album = Factory.LoadAlbumInstance(album.Id, false, true); } if ((!album.IsRootAlbum) && (!System.IO.File.Exists(album.Thumbnail.FileNamePhysicalPath))) { album.ThumbnailMediaObjectId = GetIdOfFirstMediaObject(album); HelperFunctions.UpdateAuditFields(album, userName); album.Save(); } if (recursivelyAssignChildrenAlbums) { foreach (IAlbum childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album)) { AssignAlbumThumbnail(childAlbum, false, recursivelyAssignChildrenAlbums, userName); } } if (recursivelyAssignParentAlbums) { while (!(album.Parent is NullObjects.NullGalleryObject)) { Album.AssignAlbumThumbnail((IAlbum)album.Parent, recursivelyAssignParentAlbums, false, userName); album = (IAlbum)album.Parent; } } }
private static void DeleteOriginalFilesFromAlbum(IAlbum album) { // Delete the original file for each item in the album. Then recursively do the same thing to all child albums. foreach (IGalleryObject mediaObject in album.GetChildGalleryObjects(GalleryObjectType.MediaObject)) { mediaObject.DeleteOriginalFile(); GalleryObjectController.SaveGalleryObject(mediaObject); } foreach (IAlbum childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album)) { DeleteOriginalFilesFromAlbum(childAlbum); } }
private string getAlbumStats(IAlbum album) { //Create a string like: (12 objects, created 3/24/04) int numObjects = album.GetChildGalleryObjects(false, GalleryPage.IsAnonymousUser).Count; if (album.IsVirtualAlbum) return string.Format(CultureInfo.CurrentCulture, Resources.GalleryServerPro.UC_Album_Header_Stats_Without_Date_Text, numObjects); else return string.Format(CultureInfo.CurrentCulture, Resources.GalleryServerPro.UC_Album_Header_Stats_Text, numObjects, album.DateAdded); }
private void SynchronizeMediaObjectFiles(DirectoryInfo directory, IAlbum album) { #region Parameter validation if (album == null) { throw new ArgumentNullException("album"); } if (directory.FullName != album.FullPhysicalPath) { throw new ArgumentException("Error in SynchronizeMediaObjectFiles()."); } #endregion //Update the media object table in the database with the file attributes of all //files in the directory passed to this function. Skip any hidden files. FileInfo[] files = directory.GetFiles(); // First sort by the filename. Array.Sort <FileInfo>(files, delegate(FileInfo a, FileInfo b) { return(a.Name.CompareTo(b.Name)); }); foreach (FileInfo file in files) { if ((file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) { this._synchStatus.SkippedMediaObjects.Add(new KeyValuePair <string, string>(file.FullName.Remove(0, _mediaObjectPhysicalPathLength + 1), Resources.SynchronizationStatus_Hidden_File_Msg)); continue; } #region Process thumbnail or optimized image if (file.Name.StartsWith(_thumbnailPrefix, StringComparison.OrdinalIgnoreCase)) { // We have a thumbnail image. If we are storing thumbnails in a different directory, delete the file. The user may have just // specified a new thumbnail path, and we need to delete all the previous thumbnails from their original location. if (_thumbnailRootPath != AppSetting.Instance.MediaObjectPhysicalPath) { File.Delete(file.FullName); } continue; } if (file.Name.StartsWith(_optimizedPrefix, StringComparison.OrdinalIgnoreCase)) { // We have an optimized image. If we are storing optimized images in a different directory, delete the file. The user may have // just specified a new optimized path, and we need to delete all the previous optimized images from their original location. if (_optimizedRootPath != AppSetting.Instance.MediaObjectPhysicalPath) { File.Delete(file.FullName); } continue; } #endregion IGalleryObject mediaObject = null; // See if this file is an existing media object. First look in the album's children. If not there, search the hash // keys - maybe it was moved from another directory. foreach (IGalleryObject existingMO in album.GetChildGalleryObjects(GalleryObjectType.MediaObject)) { if (existingMO.Original.FileNamePhysicalPath == file.FullName) { mediaObject = existingMO; break; } } if ((mediaObject != null) || ((mediaObject == null) && this._mediaObjectsFromDataStore.TryGetValue(HelperFunctions.GetHashKey(file), out mediaObject))) { // Found an existing media object matching the file on disk. Update properties, but only if its file extension // is enabled. (If this is a media object that had been added to Gallery Server but its file type was // subsequently disabled, we do not want to synchronize it - we want its info in the data store to be deleted.) if (HelperFunctions.IsFileAuthorizedForAddingToGallery(file.Name)) { UpdateExistingMediaObject(album, mediaObject); } } else { // No media object exists for this file. Create a new one. CreateNewMediaObject(album, file); } int newFileIndex = this._synchStatus.CurrentFileIndex + 1; if (newFileIndex < this._synchStatus.TotalFileCount) { UpdateStatus(newFileIndex, file.DirectoryName, file.Name); } if (this._synchStatus.ShouldTerminate) { this._synchStatus.ShouldTerminate = false; throw new GalleryServerPro.ErrorHandler.CustomExceptions.SynchronizationTerminationRequestedException(); } } }
/// <summary> /// Delete any thumbnail and optimized images that do not have matching media objects. /// This can occur when a user manually transfers (e.g. uses Windows Explorer) /// original images to a new directory and leaves the thumbnail and optimized /// images in the original directory or when a user deletes the original media file in /// Explorer. This function *only* deletes files that begin the the thumbnail and optimized /// prefix (e.g. zThumb_, zOpt_). /// </summary> /// <param name="album">The album whose directory is to be processed for orphaned image files.</param> private void DeleteOrphanedImages(IAlbum album) { if (album == null) { throw new ArgumentNullException("album"); } // STEP 1: Get list of directories that may contain thumbnail or optimized images for the current album string originalPath = album.FullPhysicalPathOnDisk; string thumbnailPath = HelperFunctions.MapAlbumDirectoryStructureToAlternateDirectory(album.FullPhysicalPathOnDisk, AppSetting.Instance.ThumbnailPath); string optimizedPath = HelperFunctions.MapAlbumDirectoryStructureToAlternateDirectory(album.FullPhysicalPathOnDisk, AppSetting.Instance.OptimizedPath); List <string> albumPaths = new List <string>(3); // The original path may contain thumbnails or optimized images when the thumbnail/optimized path is the same as the original path if ((AppSetting.Instance.ThumbnailPath == AppSetting.Instance.MediaObjectPhysicalPath) || (AppSetting.Instance.OptimizedPath == AppSetting.Instance.MediaObjectPhysicalPath)) { albumPaths.Add(originalPath); } if (!albumPaths.Contains(thumbnailPath)) { albumPaths.Add(thumbnailPath); } if (!albumPaths.Contains(optimizedPath)) { albumPaths.Add(optimizedPath); } string thumbnailPrefix = ConfigManager.GetGalleryServerProConfigSection().Core.ThumbnailFileNamePrefix; string optimizedPrefix = ConfigManager.GetGalleryServerProConfigSection().Core.OptimizedFileNamePrefix; IGalleryObjectCollection mediaObjects = album.GetChildGalleryObjects(GalleryObjectType.MediaObject); // STEP 2: Loop through each path and make sure all thumbnail and optimized files in each directory have // matching media objects. Delete any files that do not. foreach (string albumPath in albumPaths) { if (!Directory.Exists(albumPath)) { return; } DirectoryInfo directory = new DirectoryInfo(albumPath); // Loop through each file in the directory. foreach (FileInfo file in directory.GetFiles()) { if ((file.Name.StartsWith(thumbnailPrefix, StringComparison.OrdinalIgnoreCase)) || (file.Name.StartsWith(optimizedPrefix, StringComparison.OrdinalIgnoreCase))) { // This file is a thumbnail or optimized file. Check to see if any media object in this album // refers to it. bool foundMediaObject = false; foreach (IGalleryObject mediaObject in mediaObjects) { if ((mediaObject.Optimized.FileName == file.Name) || (mediaObject.Thumbnail.FileName == file.Name)) { foundMediaObject = true; break; } } if (!foundMediaObject) { // No media object in this album refers to this thumbnail or optimized image. Smoke it! try { file.Delete(); } catch (IOException ex) { // An exception occurred, probably because the account ASP.NET is running under does not // have permission to delete the file. Let's record the error, but otherwise ignore it. Error.Record(ex); } catch (System.Security.SecurityException ex) { // An exception occurred, probably because the account ASP.NET is running under does not // have permission to delete the file. Let's record the error, but otherwise ignore it. Error.Record(ex); } catch (UnauthorizedAccessException ex) { // An exception occurred, probably because the account ASP.NET is running under does not // have permission to delete the file. Let's record the error, but otherwise ignore it. Error.Record(ex); } } } } } // Now recursively loop through any child albums. IGalleryObjectCollection childAlbums = album.GetChildGalleryObjects(GalleryObjectType.Album); if (this.IsRecursive) { foreach (IAlbum childAlbum in childAlbums) { DeleteOrphanedImages(childAlbum); } } }
/// <summary> /// Delete any thumbnail and optimized images that do not have matching media objects. /// This can occur when a user manually transfers (e.g. uses Windows Explorer) /// original images to a new directory and leaves the thumbnail and optimized /// images in the original directory or when a user deletes the original media file in /// Explorer. This function *only* deletes files that begin the the thumbnail and optimized /// prefix (e.g. zThumb_, zOpt_). /// </summary> /// <param name="album">The album whose directory is to be processed for orphaned image files.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="album" /> is null.</exception> private void DeleteOrphanedImages(IAlbum album) { if (album == null) throw new ArgumentNullException("album"); // STEP 1: Get list of directories that may contain thumbnail or optimized images for the current album string originalPath = album.FullPhysicalPathOnDisk; string thumbnailPath = HelperFunctions.MapAlbumDirectoryStructureToAlternateDirectory(album.FullPhysicalPathOnDisk, GallerySettings.FullThumbnailPath, GallerySettings.FullMediaObjectPath); string optimizedPath = HelperFunctions.MapAlbumDirectoryStructureToAlternateDirectory(album.FullPhysicalPathOnDisk, GallerySettings.FullOptimizedPath, GallerySettings.FullMediaObjectPath); List<string> albumPaths = new List<string>(3); // The original path may contain thumbnails or optimized images when the thumbnail/optimized path is the same as the original path if ((GallerySettings.FullThumbnailPath.Equals(GallerySettings.FullMediaObjectPath, StringComparison.OrdinalIgnoreCase)) || (GallerySettings.FullOptimizedPath.Equals(GallerySettings.FullMediaObjectPath, StringComparison.OrdinalIgnoreCase))) { albumPaths.Add(originalPath); } if (!albumPaths.Contains(thumbnailPath)) albumPaths.Add(thumbnailPath); if (!albumPaths.Contains(optimizedPath)) albumPaths.Add(optimizedPath); string thumbnailPrefix = GallerySettings.ThumbnailFileNamePrefix; string optimizedPrefix = GallerySettings.OptimizedFileNamePrefix; IGalleryObjectCollection mediaObjects = album.GetChildGalleryObjects(GalleryObjectType.MediaObject); // STEP 2: Loop through each path and make sure all thumbnail and optimized files in each directory have // matching media objects. Delete any files that do not. foreach (string albumPath in albumPaths) { if (!Directory.Exists(albumPath)) return; DirectoryInfo directory = new DirectoryInfo(albumPath); // Loop through each file in the directory. FileInfo[] files; try { files = directory.GetFiles(); } catch (UnauthorizedAccessException) { return; } foreach (FileInfo file in files) { if ((file.Name.StartsWith(thumbnailPrefix, StringComparison.OrdinalIgnoreCase)) || (file.Name.StartsWith(optimizedPrefix, StringComparison.OrdinalIgnoreCase))) { // This file is a thumbnail or optimized file. Check to see if any media object in this album // refers to it. bool foundMediaObject = false; foreach (IGalleryObject mediaObject in mediaObjects) { if ((mediaObject.Optimized.FileName.Equals(file.Name, StringComparison.OrdinalIgnoreCase)) || (mediaObject.Thumbnail.FileName.Equals(file.Name, StringComparison.OrdinalIgnoreCase))) { foundMediaObject = true; break; } } if (!foundMediaObject) { // No media object in this album refers to this thumbnail or optimized image. Smoke it! try { file.Delete(); } catch (IOException ex) { // An exception occurred, probably because the account ASP.NET is running under does not // have permission to delete the file. Let's record the error, but otherwise ignore it. Error.Record(ex, this._galleryId, Factory.LoadGallerySettings(), AppSetting.Instance); } catch (System.Security.SecurityException ex) { // An exception occurred, probably because the account ASP.NET is running under does not // have permission to delete the file. Let's record the error, but otherwise ignore it. Error.Record(ex, this._galleryId, Factory.LoadGallerySettings(), AppSetting.Instance); } catch (UnauthorizedAccessException ex) { // An exception occurred, probably because the account ASP.NET is running under does not // have permission to delete the file. Let's record the error, but otherwise ignore it. Error.Record(ex, this._galleryId, Factory.LoadGallerySettings(), AppSetting.Instance); } } } } } // Now recursively loop through any child albums. IGalleryObjectCollection childAlbums = album.GetChildGalleryObjects(GalleryObjectType.Album); if (this.IsRecursive) { foreach (IAlbum childAlbum in childAlbums) { DeleteOrphanedImages(childAlbum); } } }
private void SynchronizeExternalMediaObjects(IAlbum album) { foreach (IGalleryObject mediaObject in album.GetChildGalleryObjects(GalleryObjectType.External)) { // Check for existence of thumbnail. if (this.OverwriteThumbnail || !File.Exists(mediaObject.Thumbnail.FileNamePhysicalPath)) { mediaObject.RegenerateThumbnailOnSave = true; HelperFunctions.UpdateAuditFields(mediaObject, this._userName); mediaObject.Save(); mediaObject.IsSynchronized = true; } } }
/// <summary> /// Delete any thumbnail and optimized files that do not have matching media objects. /// This can occur when a user manually transfers (e.g. uses Windows Explorer) /// original files to a new directory and leaves the thumbnail and optimized /// files in the original directory or when a user deletes the original media file in /// Explorer. This function *only* deletes files that begin the the thumbnail and optimized /// prefix (e.g. zThumb_, zOpt_). /// </summary> /// <param name="album">The album whose directory is to be processed for orphaned image files.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="album" /> is null.</exception> private void DeleteOrphanedThumbnailAndOptimizedFiles(IAlbum album) { if (album == null) { throw new ArgumentNullException("album"); } // STEP 1: Get list of directories that may contain thumbnail or optimized images for the current album string originalPath = album.FullPhysicalPathOnDisk; string thumbnailPath = HelperFunctions.MapAlbumDirectoryStructureToAlternateDirectory(album.FullPhysicalPathOnDisk, GallerySettings.FullThumbnailPath, GallerySettings.FullMediaObjectPath); string optimizedPath = HelperFunctions.MapAlbumDirectoryStructureToAlternateDirectory(album.FullPhysicalPathOnDisk, GallerySettings.FullOptimizedPath, GallerySettings.FullMediaObjectPath); List <string> albumPaths = new List <string>(3); // The original path may contain thumbnails or optimized images when the thumbnail/optimized path is the same as the original path if ((GallerySettings.FullThumbnailPath.Equals(GallerySettings.FullMediaObjectPath, StringComparison.OrdinalIgnoreCase)) || (GallerySettings.FullOptimizedPath.Equals(GallerySettings.FullMediaObjectPath, StringComparison.OrdinalIgnoreCase))) { albumPaths.Add(originalPath); } if (!albumPaths.Contains(thumbnailPath)) { albumPaths.Add(thumbnailPath); } if (!albumPaths.Contains(optimizedPath)) { albumPaths.Add(optimizedPath); } string thumbnailPrefix = GallerySettings.ThumbnailFileNamePrefix; string optimizedPrefix = GallerySettings.OptimizedFileNamePrefix; IGalleryObjectCollection mediaObjects = album.GetChildGalleryObjects(GalleryObjectType.MediaObject); // STEP 2: Loop through each path and make sure all thumbnail and optimized files in each directory have // matching media objects. Delete any files that do not. foreach (string albumPath in albumPaths) { if (!Directory.Exists(albumPath)) { return; } DirectoryInfo directory = new DirectoryInfo(albumPath); // Loop through each file in the directory. FileInfo[] files; try { files = directory.GetFiles(); } catch (UnauthorizedAccessException) { return; } var queueItems = GetCurrentAndCompleteMediaQueueItems(); foreach (FileInfo file in files) { if ((file.Name.StartsWith(thumbnailPrefix, StringComparison.OrdinalIgnoreCase)) || (file.Name.StartsWith(optimizedPrefix, StringComparison.OrdinalIgnoreCase))) { // This file is a thumbnail or optimized file. // TEST 1: Check to see if any media object in this album refers to it. var foundMediaObject = false; foreach (IGalleryObject mediaObject in mediaObjects) { if ((mediaObject.Optimized.FileName.Equals(file.Name, StringComparison.OrdinalIgnoreCase)) || (mediaObject.Thumbnail.FileName.Equals(file.Name, StringComparison.OrdinalIgnoreCase))) { foundMediaObject = true; break; } } if (!foundMediaObject) { // TEST 2: Maybe the encoder engine is currently creating the file or just finished it. // First check to see if we started processing a new media item since we started this loop. // If so, add it to our list of queue items. var currentQueueItem = MediaConversionQueue.Instance.GetCurrentMediaQueueItem(); if (currentQueueItem != null && !queueItems.Any(mq => mq.MediaQueueId == currentQueueItem.MediaQueueId)) { queueItems = queueItems.Concat(new[] { currentQueueItem }); } // See if this file is mentioned in any of the media queue items foundMediaObject = queueItems.Any(mq => mq.StatusDetail.Contains(file.Name)); } if (!foundMediaObject) { // No media object in this album refers to this thumbnail or optimized image. Smoke it! try { file.Delete(); } catch (IOException ex) { // An exception occurred, probably because the account ASP.NET is running under does not // have permission to delete the file. Let's record the error, but otherwise ignore it. EventController.RecordError(ex, AppSetting.Instance, _galleryId, Factory.LoadGallerySettings()); } catch (SecurityException ex) { // An exception occurred, probably because the account ASP.NET is running under does not // have permission to delete the file. Let's record the error, but otherwise ignore it. EventController.RecordError(ex, AppSetting.Instance, _galleryId, Factory.LoadGallerySettings()); } catch (UnauthorizedAccessException ex) { // An exception occurred, probably because the account ASP.NET is running under does not // have permission to delete the file. Let's record the error, but otherwise ignore it. EventController.RecordError(ex, AppSetting.Instance, _galleryId, Factory.LoadGallerySettings()); } } } } } }
/// <summary> /// Adds the media objects in the <paramref name="album"/> to the ZIP archive. Only media objects associated with a /// physical file are added (that is, external media objects are excluded). /// </summary> /// <param name="zos">The ZipOutputStream (ZIP archive) the media object file is to be added to.</param> /// <param name="album">The album to be added to the ZIP archive.</param> /// <param name="imageSize">Size of the image to add to the ZIP archive. This parameter applies only to <see cref="Image"/> /// media objects.</param> /// <param name="basePath">The full path to the directory containing the highest-level media file to be added /// to the ZIP archive. Must include trailing slash. Ex: C:\Inetpub\wwwroot\galleryserverpro\mediaobjects\Summer 2005\sunsets\</param> /// <param name="applyWatermark">Indicates whether to apply a watermark to images as they are added to the archive. /// Applies only for media objects in the <see cref="album"/> that are an <see cref="Image"/>.</param> private void AddZipEntry(ZipOutputStream zos, IAlbum album, DisplayObjectType imageSize, string basePath, bool applyWatermark) { foreach (IAlbum childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album, false, !this._isAuthenticated)) { AddZipEntry(zos, childAlbum, imageSize, basePath, applyWatermark); } foreach (IGalleryObject mediaObject in album.GetChildGalleryObjects(GalleryObjectType.MediaObject, false, !this._isAuthenticated)) { AddFileZipEntry(zos, mediaObject, imageSize, basePath, applyWatermark); } }
/// <summary> /// Create a minimally populated <see cref="Video" /> instance from the specified parameters. /// </summary> /// <param name="videoFile">A <see cref="System.IO.FileInfo" /> object representing a supported video type. The file must already /// exist in the album's directory. If the file has a matching record in the data store, a reference to the existing /// object is returned; otherwise, a new instance is returned. However, if the forceNew parameter is specified and is /// set to true, then a new, unsaved media object with no assigned parent album is always returned, regardless of the existence of the file. /// Otherwise, a new instance is returned. For new instances, call <see cref="IGalleryObject.Save" /> to persist the object to the data store.</param> /// <param name="parentAlbum">The album in which the video exists (for media objects that already exist /// in the data store), or should be added to (for new media objects which need to be inserted into the /// data store).</param> /// <param name="forceNew">Indicates whether to initialize a new, unsaved media object even if the imageFile /// parameter refers to an existing file in the album's directory. Typically used when copying an existing media /// object where a subsequent operation will copy the existing file to the destination album, thus resulting in a /// new, independent media object.</param> /// <returns>Returns a <see cref="Video" /> instance corresponding to the specified parameters.</returns> /// <exception cref="UnsupportedMediaObjectTypeException">Thrown when /// <paramref name="videoFile"/> has a file extension that Gallery Server Pro is configured to reject, or it is /// associated with a non-video MIME type.</exception> /// <exception cref="InvalidMediaObjectException">Thrown when /// <paramref name="videoFile"/> refers to a file that is not in the same directory as the parent album's directory.</exception> public static IGalleryObject CreateVideoInstance(System.IO.FileInfo videoFile, IAlbum parentAlbum, bool forceNew) { #if DEBUG tt.Tools.StartingMethod(videoFile, parentAlbum, forceNew); #endif // Validation check: Make sure the configuration settings allow for this particular type of file to be added. if (!HelperFunctions.IsFileAuthorizedForAddingToGallery(videoFile.Name)) throw new UnsupportedMediaObjectTypeException(videoFile.FullName); // If the file belongs to an existing media object, return a reference to it. if (!forceNew) { foreach (IGalleryObject childMediaObject in parentAlbum.GetChildGalleryObjects(GalleryObjectType.Video)) { if (childMediaObject.Original.FileNamePhysicalPath == videoFile.FullName) return childMediaObject; } } if (forceNew) parentAlbum = null; // Create a new video object, which will cause a new record to be inserted in the data store when Save() is called. return new Video(videoFile, parentAlbum); }
private static void DeleteHiResImagesFromAlbum(IAlbum album) { // Delete the hi-res image for each image in the album. Then recursively do the same thing to all child albums. foreach (GalleryServerPro.Business.Image image in album.GetChildGalleryObjects(GalleryObjectType.Image)) { image.DeleteHiResImage(); GalleryObjectController.SaveGalleryObject(image); } foreach (IAlbum childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album)) { DeleteHiResImagesFromAlbum(childAlbum); } }
/// <summary> /// Synchronizes the media object files in the <paramref name="directory" /> associated with the <paramref name="album" />. /// Does not act recursively. /// </summary> /// <param name="directory">The directory.</param> /// <param name="album">The album.</param> /// <exception cref="UnauthorizedAccessException">Thrown when the IIS app pool identity cannot access the files in the directory.</exception> /// <exception cref="ArgumentNullException">Thrown when <paramref name="album" /> or <paramref name="directory" /> is null.</exception> /// <exception cref="ArgumentException">Thrown when the full directory path of <paramref name="directory" /> does not match the directory path of /// <paramref name="album" />.</exception> private void SynchronizeMediaObjectFiles(DirectoryInfo directory, IAlbum album) { #region Parameter validation if (directory == null) throw new ArgumentNullException("directory"); if (album == null) throw new ArgumentNullException("album"); if (!directory.FullName.Equals(album.FullPhysicalPath, StringComparison.InvariantCultureIgnoreCase)) throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Error in SynchronizeMediaObjectFiles(): The full directory path of the parameter 'directory' does not match the directory path of the parameter 'album'. directory.FullName='{0}'; album.FullPhysicalPath='{1}'", directory.FullName, album.FullPhysicalPath)); #endregion //Update the media object table in the database with the file attributes of all //files in the directory passed to this function. Skip any hidden files. FileInfo[] files; try { files = directory.GetFiles(); } catch (UnauthorizedAccessException) { _synchStatus.SkippedMediaObjects.Add(new KeyValuePair<string, string>(directory.Name, Resources.SynchronizationStatus_Restricted_Directory_Msg)); throw; } // First sort by the filename. Array.Sort(files, (a, b) => String.Compare(a.Name, b.Name, StringComparison.InvariantCultureIgnoreCase)); // Don't use Ordinal or OrdinalIgnoreCase, as it sorts unexpectedly (e.g. 100.pdf comes before _100.pdf) foreach (FileInfo file in files) { if ((file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) { _synchStatus.SkippedMediaObjects.Add(new KeyValuePair<string, string>(file.FullName.Remove(0, _fullMediaObjectPathLength + 1), Resources.SynchronizationStatus_Hidden_File_Msg)); continue; } #region Process thumbnail or optimized image if (file.Name.StartsWith(_thumbnailPrefix, StringComparison.OrdinalIgnoreCase)) { // We have a thumbnail image. If we are storing thumbnails in a different directory, delete the file, but only if the path // is writeable. The user may have just specified a new thumbnail path, and we need to delete all the previous thumbnails // from their original location. if (_thumbnailRootPath != GallerySettings.FullMediaObjectPath && !GallerySettings.MediaObjectPathIsReadOnly) { File.Delete(file.FullName); } continue; } if (file.Name.StartsWith(_optimizedPrefix, StringComparison.OrdinalIgnoreCase)) { // We have an optimized image. If we are storing optimized images in a different directory, delete the file, but only if the path // is writeable. The user may have just specified a new optimized path, and we need to delete all the previous optimized images // from their original location. if (_optimizedRootPath != GallerySettings.FullMediaObjectPath && !GallerySettings.MediaObjectPathIsReadOnly) { File.Delete(file.FullName); } continue; } #endregion // See if this file is an existing media object. var mediaObject = album .GetChildGalleryObjects(GalleryObjectType.MediaObject) .FirstOrDefault(mo => mo.Original.FileNamePhysicalPath.Equals(file.FullName, StringComparison.OrdinalIgnoreCase)); if (mediaObject != null) { // Found an existing media object matching the file on disk. Update properties, but only if its file extension // is enabled. (If this is a media object that had been added to Gallery Server but its file type was // subsequently disabled, we do not want to synchronize it - we want its info in the data store to be deleted.) if (HelperFunctions.IsFileAuthorizedForAddingToGallery(file.Name, album.GalleryId)) { UpdateExistingMediaObject(mediaObject); } } else { // No media object exists for this file. Create a new one. CreateNewMediaObject(album, file); } int newFileIndex = _synchStatus.CurrentFileIndex + 1; if (newFileIndex < _synchStatus.TotalFileCount) { var persistToDatabase = (_synchStatus.CurrentFileIndex % 100) == 0; // Save to DB every 100 files UpdateStatus(newFileIndex, file.DirectoryName, file.Name, persistToDatabase: persistToDatabase); } lock (_synchStatus) { if (_synchStatus.ShouldTerminate) { // Immediately set this property back to false so that we don't trigger this code again, then throw a special exception // that will be caught and used to cancel the synch. _synchStatus.Update(SynchronizationState.Aborted, null, String.Empty, null, String.Empty, false, true); throw new SynchronizationTerminationRequestedException(); } } } // Synchronize any external media objects previously added. No recursive action. SynchronizeExternalMediaObjects(album); DeleteOrphanedMediaObjectRecords(album); DeleteOrphanedThumbnailAndOptimizedFiles(album); }
private static void DeleteOrphanedMediaObjectRecords(IAlbum album) { // Delete media object records that weren't sync'd. var orphanMediaObjects = album.GetChildGalleryObjects(GalleryObjectType.MediaObject) .Where(mo => !mo.IsSynchronized && mo.GalleryObjectType != GalleryObjectType.External); foreach (var mediaObject in orphanMediaObjects) { mediaObject.DeleteFromGallery(); } }
/// <summary> /// Add the child albums and media objects as stored on disk to the specified dictionary objects. Set /// IsSynchronized = false for each album and media object. This will be set to true as each is processed. /// This method calls itself recursively if IsRecursive = true. /// </summary> /// <param name="albums">A Dictionary object containing relevant albums for this synchronization. The album specified /// in the parentAlbum parameter will be added to this object.</param> /// <param name="mediaObjects">A Dictionary object containing relevant media objects for this synchronization. /// Media objects within the parentAlbum parameter will be added to this object.</param> /// <param name="parentAlbum">The album used as the source for populating the albums and mediaObjects /// parameters.</param> private void AddChildAlbumsAndGalleryObjectsAndSetToUnsynchronized(Dictionary<string, IAlbum> albums, Dictionary<string, IGalleryObject> mediaObjects, IAlbum parentAlbum) { foreach (IAlbum childAlbum in parentAlbum.GetChildGalleryObjects(GalleryObjectType.Album)) { childAlbum.IsSynchronized = false; childAlbum.RegenerateThumbnailOnSave = this.OverwriteThumbnail; try { // There can be situations where the database becomes corrupt, and the same album has two records. When this happens, // the following line will fail. Instead of letting the exception cause the synch to fail, we swallow the exception. // This will cause the album that caused the exception to eventually be deleted, which is what we want. albums.Add(childAlbum.FullPhysicalPathOnDisk, childAlbum); } catch (System.ArgumentException) { } foreach (IGalleryObject mediaObject in childAlbum.GetChildGalleryObjects(GalleryObjectType.MediaObject)) { if (!String.IsNullOrEmpty(mediaObject.Hashkey)) { mediaObject.IsSynchronized = false; mediaObject.RegenerateOptimizedOnSave = this.OverwriteOptimized; mediaObject.RegenerateThumbnailOnSave = this.OverwriteThumbnail; mediaObject.RegenerateMetadataOnSave = this.RegenerateMetadata; try { // There may be situations where the database becomes corrupt, and the same media object has two records. When this happens, // the following line will fail. Instead of letting the exception cause the synch to fail, we swallow the exception. // This will cause the media object that caused the exception to eventually be deleted, which is what we want. mediaObjects.Add(mediaObject.Hashkey, mediaObject); } catch (System.ArgumentException) { } } } if (this._isRecursive) { AddChildAlbumsAndGalleryObjectsAndSetToUnsynchronized(albums, mediaObjects, childAlbum); } } }
private static void DeleteOrphanedAlbumRecords(IAlbum album) { // Delete album records that weren't sync'd. foreach (var childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album).Where(a => !a.IsSynchronized)) { childAlbum.DeleteFromGallery(); } }
/// <summary> /// Gets a data entity containing album information for the specified <paramref name="album" />. Returns an object with empty /// properties if the user does not have permission to view the specified album. The instance can be JSON-parsed and sent to the /// browser. /// </summary> /// <param name="album">The album to convert to an instance of <see cref="GalleryServerPro.Web.Entity.Album" />.</param> /// <param name="perms">The permissions the current user has for the album.</param> /// <param name="options">Specifies options for configuring the return data. To use default /// settings, specify an empty instance with properties left at default values.</param> /// <returns> /// Returns an <see cref="GalleryServerPro.Web.Entity.Album" /> object containing information about the requested album. /// </returns> /// <exception cref="ArgumentNullException">Thrown when <paramref name="album" /> is null.</exception> /// <exception cref="System.ArgumentNullException"></exception> public static Entity.Album ToAlbumEntity(IAlbum album, Entity.Permissions perms, Entity.GalleryDataLoadOptions options) { if (album == null) throw new ArgumentNullException("album"); var albumEntity = new Entity.Album(); albumEntity.Id = album.Id; albumEntity.GalleryId = album.GalleryId; albumEntity.Title = album.Title; albumEntity.Caption = album.Caption; albumEntity.Owner = (perms.AdministerGallery ? album.OwnerUserName : null); albumEntity.InheritedOwners = (perms.AdministerGallery ? String.Join(", ", album.InheritedOwners) : null); albumEntity.DateStart = album.DateStart; albumEntity.DateEnd = album.DateEnd; albumEntity.IsPrivate = album.IsPrivate; albumEntity.VirtualType = (int)album.VirtualAlbumType; albumEntity.RssUrl = GetRssUrl(album); albumEntity.Permissions = perms; albumEntity.MetaItems = GalleryObjectController.ToMetaItems(album.MetadataItems.GetVisibleItems(), album); albumEntity.NumAlbums = album.GetChildGalleryObjects(GalleryObjectType.Album, !Utils.IsAuthenticated).Count; // Optionally load gallery items if (options.LoadGalleryItems) { var albumSortDef = ProfileController.GetProfile().AlbumProfiles.Find(album.Id); IList<IGalleryObject> items; if (albumSortDef != null) { items = album .GetChildGalleryObjects(options.Filter, !Utils.IsAuthenticated) .ToSortedList(albumSortDef.SortByMetaName, albumSortDef.SortAscending, album.GalleryId); albumEntity.SortById = (int)albumSortDef.SortByMetaName; albumEntity.SortUp = albumSortDef.SortAscending; } else { if (album.IsVirtualAlbum) { items = album.GetChildGalleryObjects(options.Filter, !Utils.IsAuthenticated).ToSortedList(album.SortByMetaName, album.SortAscending, album.GalleryId); } else { // Real (non-virtual) albums are already sorted on their Seq property, so return items based on that. items = album.GetChildGalleryObjects(options.Filter, !Utils.IsAuthenticated).ToSortedList(); } albumEntity.SortById = (int)album.SortByMetaName; albumEntity.SortUp = album.SortAscending; } if (options.NumGalleryItemsToRetrieve > 0) items = items.Skip(options.NumGalleryItemsToSkip).Take(options.NumGalleryItemsToRetrieve).ToList(); albumEntity.GalleryItems = GalleryObjectController.ToGalleryItems(items); albumEntity.NumGalleryItems = albumEntity.GalleryItems.Length; } else { albumEntity.NumGalleryItems = album.GetChildGalleryObjects(options.Filter, !Utils.IsAuthenticated).Count; } // Optionally load media items if (options.LoadMediaItems) { IList<IGalleryObject> items; if (album.IsVirtualAlbum) { items = album.GetChildGalleryObjects(GalleryObjectType.MediaObject, !Utils.IsAuthenticated).ToSortedList(album.SortByMetaName, album.SortAscending, album.GalleryId); } else { // Real (non-virtual) albums are already sorted on their Seq property, so return items based on that. items = album.GetChildGalleryObjects(GalleryObjectType.MediaObject, !Utils.IsAuthenticated).ToSortedList(); } //IList<IGalleryObject> items = album.GetChildGalleryObjects(GalleryObjectType.MediaObject, !Utils.IsAuthenticated).ToSortedList(); albumEntity.NumMediaItems = items.Count; albumEntity.MediaItems = GalleryObjectController.ToMediaItems(items); } else { albumEntity.NumMediaItems = album.GetChildGalleryObjects(GalleryObjectType.MediaObject, !Utils.IsAuthenticated).Count; } return albumEntity; }
/// <summary> /// Gets the total file size, in KB, of all the original files in the <paramref name="album"/>, including all /// child albums. The total includes only those items where a web-optimized version also exists. /// </summary> /// <param name="album">The album for which to retrieve the file size of all original files.</param> /// <returns>Returns the total file size, in KB, of all the original files in the <paramref name="album"/>.</returns> private static long GetFileSizeKbAllOriginalFilesInAlbum(IAlbum album) { // Get the total file size, in KB, of all the high resolution images in the specified album long sumTotal = 0; foreach (IGalleryObject go in album.GetChildGalleryObjects(GalleryObjectType.MediaObject)) { if (DoesOriginalExist(go.Optimized.FileName, go.Original.FileName)) sumTotal += go.Original.FileSizeKB; } foreach (IAlbum childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album)) { sumTotal += GetFileSizeKbAllOriginalFilesInAlbum(childAlbum); } return sumTotal; }
/// <summary> /// Finds the first album within the heirarchy of the specified <paramref name="album"/> whose ID is in /// <paramref name="albumIds"/>. Acts recursively in an across-first, then-down search pattern, resulting /// in the highest level matching album to be returned. Returns null if there are no matching albums. /// </summary> /// <param name="album">The album to be searched to see if it, or any of its children, matches one of the IDs /// in <paramref name="albumIds"/>.</param> /// <param name="albumIds">Contains the IDs of the albums to search for.</param> /// <returns>Returns the first album within the heirarchy of the specified <paramref name="album"/> whose ID is in /// <paramref name="albumIds"/>.</returns> private static IAlbum FindFirstMatchingAlbumRecursive(IAlbum album, ICollection<int> albumIds) { // Is the current album in the list? if (albumIds.Contains(album.Id)) return album; // Nope, so look at the child albums of this album. IAlbum albumToSelect = null; var childAlbums = album.GetChildGalleryObjects(GalleryObjectType.Album).ToSortedList(); foreach (IGalleryObject childAlbum in childAlbums) { if (albumIds.Contains(childAlbum.Id)) { albumToSelect = (IAlbum)childAlbum; break; } } // Not the child albums either, so iterate through the children of the child albums. Act recursively. if (albumToSelect == null) { foreach (IGalleryObject childAlbum in childAlbums) { albumToSelect = FindFirstMatchingAlbumRecursive((IAlbum)childAlbum, albumIds); if (albumToSelect != null) break; } } return albumToSelect; // Returns null if no matching album is found }
/// <summary> /// Create a sample album and media object. This method is intended to be invoked once just after the application has been /// installed. /// </summary> /// <param name="galleryId">The ID for the gallery where the sample objects are to be created.</param> public static void CreateSampleObjects(int galleryId) { if (Factory.LoadGallerySetting(galleryId).MediaObjectPathIsReadOnly) { return; } DateTime currentTimestamp = DateTime.Now; IAlbum sampleAlbum = null; foreach (IAlbum album in Factory.LoadRootAlbumInstance(galleryId).GetChildGalleryObjects(GalleryObjectType.Album)) { if (album.DirectoryName == "Samples") { sampleAlbum = album; break; } } if (sampleAlbum == null) { // Create sample album. sampleAlbum = Factory.CreateEmptyAlbumInstance(galleryId); sampleAlbum.Parent = Factory.LoadRootAlbumInstance(galleryId); sampleAlbum.Title = "Samples"; sampleAlbum.DirectoryName = "Samples"; sampleAlbum.Summary = "Welcome to Gallery Server Pro!"; sampleAlbum.CreatedByUserName = "******"; sampleAlbum.DateAdded = currentTimestamp; sampleAlbum.LastModifiedByUserName = "******"; sampleAlbum.DateLastModified = currentTimestamp; sampleAlbum.Save(); } // Look for sample image in sample album. IGalleryObject sampleImage = null; foreach (IGalleryObject image in sampleAlbum.GetChildGalleryObjects(GalleryObjectType.Image)) { if (image.Original.FileName == Constants.SAMPLE_IMAGE_FILENAME) { sampleImage = image; break; } } if (sampleImage == null) { // Sample image not found. Pull image from assembly and save to disk (if needed), then create a media object from it. string sampleDirPath = Path.Combine(Factory.LoadGallerySetting(galleryId).FullMediaObjectPath, sampleAlbum.DirectoryName); string sampleImageFilepath = Path.Combine(sampleDirPath, Constants.SAMPLE_IMAGE_FILENAME); if (!File.Exists(sampleImageFilepath)) { Assembly asm = Assembly.GetExecutingAssembly(); using (Stream stream = asm.GetManifestResourceStream(String.Concat("GalleryServerPro.Web.gs.images.", Constants.SAMPLE_IMAGE_FILENAME))) { if (stream != null) { BinaryWriter bw = new BinaryWriter(File.Create(sampleImageFilepath)); byte[] buffer = new byte[stream.Length]; stream.Read(buffer, 0, (int)stream.Length); bw.Write(buffer); bw.Flush(); bw.Close(); } } } if (File.Exists(sampleImageFilepath)) { // Temporarily change a couple settings so that the thumbnail and compressed images are high quality. IGallerySettings gallerySettings = Factory.LoadGallerySetting(galleryId); int optTriggerSizeKb = gallerySettings.OptimizedImageTriggerSizeKb; int thumbImageJpegQuality = gallerySettings.ThumbnailImageJpegQuality; gallerySettings.ThumbnailImageJpegQuality = 95; gallerySettings.OptimizedImageTriggerSizeKb = 200; // Create the media object from the file. IGalleryObject image = Factory.CreateImageInstance(new FileInfo(sampleImageFilepath), sampleAlbum); image.Title = "Margaret, Skyler and Roger Martin (July 2010)"; image.CreatedByUserName = "******"; image.DateAdded = currentTimestamp; image.LastModifiedByUserName = "******"; image.DateLastModified = currentTimestamp; image.Save(); // Restore the default settings. gallerySettings.OptimizedImageTriggerSizeKb = optTriggerSizeKb; gallerySettings.ThumbnailImageJpegQuality = thumbImageJpegQuality; } } }
/// <summary> /// Performs any necessary actions that must occur before an album is deleted. Specifically, it deletes the owner role /// if one exists for the album, but only when this album is the only one assigned to the role. It also clears out /// <see cref="IGallerySettings.UserAlbumParentAlbumId" /> if the album's ID matches it. This function recursively calls /// itself to make sure all child albums are processed. /// </summary> /// <param name="album">The album to be deleted, or one of its child albums.</param> private static void OnBeforeAlbumDelete(IAlbum album) { // If there is an owner role associated with this album, and the role is not assigned to any other albums, delete it. if (!String.IsNullOrEmpty(album.OwnerRoleName)) { IGalleryServerRole role = RoleController.GetGalleryServerRoles().GetRole(album.OwnerRoleName); if ((role != null) && (role.AllAlbumIds.Count == 1) && role.AllAlbumIds.Contains(album.Id)) { RoleController.DeleteGalleryServerProRole(role.RoleName); } } // If the album is specified as the user album container, clear out the setting. The ValidateBeforeAlbumDelete() // function will throw an exception if user albums are enabled, so this should only happen when user albums // are disabled, so it is safe to clear it out. int userAlbumParentAlbumId = Factory.LoadGallerySetting(album.GalleryId).UserAlbumParentAlbumId; if (album.Id == userAlbumParentAlbumId) { IGallerySettings gallerySettingsWriteable = Factory.LoadGallerySetting(album.GalleryId, true); gallerySettingsWriteable.UserAlbumParentAlbumId = 0; gallerySettingsWriteable.Save(); } // Recursively validate child albums. foreach (IGalleryObject childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album)) { OnBeforeAlbumDelete((IAlbum)childAlbum); } }
/// <summary> /// Create a minimally populated <see cref="Audio" /> instance from the specified parameters. /// </summary> /// <param name="audioFile">A <see cref="System.IO.FileInfo" /> object representing a supported audio type. The file must already /// exist in the album's directory. If the file has a matching record in the data store, a reference to the existing /// object is returned; otherwise, a new instance is returned. Otherwise, a new instance is returned. For new instances, /// call <see cref="IGalleryObject.Save" /> to persist the object to the data store.</param> /// <param name="parentAlbum">The album in which the audio exists (for media objects that already exist /// in the data store), or should be added to (for new media objects which need to be inserted into the /// data store).</param> /// <returns>Returns an <see cref="Audio" /> instance corresponding to the specified parameters.</returns> /// <exception cref="InvalidMediaObjectException">Thrown when /// <paramref name = "audioFile" /> refers to a file that is not in the same directory as the parent album's directory.</exception> /// <exception cref="UnsupportedMediaObjectTypeException">Thrown when /// <paramref name = "audioFile" /> has a file extension that Gallery Server Pro is configured to reject, or it is /// associated with a non-audio MIME type.</exception> /// <exception cref="ArgumentNullException">Thrown when <paramref name = "audioFile" /> or <paramref name = "parentAlbum" /> is null.</exception> public static IGalleryObject CreateAudioInstance(FileInfo audioFile, IAlbum parentAlbum) { if (audioFile == null) throw new ArgumentNullException("audioFile"); if (parentAlbum == null) throw new ArgumentNullException("parentAlbum"); // Validation check: Make sure the configuration settings allow for this particular type of file to be added. if (!HelperFunctions.IsFileAuthorizedForAddingToGallery(audioFile.Name, parentAlbum.GalleryId)) throw new UnsupportedMediaObjectTypeException(audioFile.FullName); // If the file belongs to an existing media object, return a reference to it. foreach (IGalleryObject childMediaObject in parentAlbum.GetChildGalleryObjects(GalleryObjectType.Audio)) { if (childMediaObject.Original.FileNamePhysicalPath == audioFile.FullName) return childMediaObject; } // Create a new audio object, which will cause a new record to be inserted in the data store when Save() is called. return new Audio(audioFile, parentAlbum); }
/// <summary> /// Reverse the gallery objects in the <paramref name="album" /> if they are custom sorted and the user /// clicked the reverse sort button (i.e. changed the <paramref name="previousSortAscending" /> value). /// This can't be handled by the normal sort routine because we aren't actually sorting on any particular /// metadata value. /// </summary> /// <param name="album">The album whose items are to be sorted.</param> /// <param name="previousSortByMetaName">The name of the metadata property the album was previously sorted on.</param> /// <param name="previousSortAscending">Indicates whether the album was previously sorted in ascending order.</param> private static void ReverseCustomSortIfNeeded(IAlbum album, MetadataItemName previousSortByMetaName, bool previousSortAscending) { var albumIsCustomSortedAndUserIsChangingSortDirection = ((album.SortByMetaName == MetadataItemName.NotSpecified) && (album.SortByMetaName == previousSortByMetaName) && (album.SortAscending != previousSortAscending)); if (albumIsCustomSortedAndUserIsChangingSortDirection) { // Album is being manually sorted and user clicked the reverse button. var seq = 1; foreach (var galleryObject in album.GetChildGalleryObjects().ToSortedList().Reverse()) { galleryObject.Sequence = seq; seq++; } } }
private void SynchronizeMediaObjectFiles(DirectoryInfo directory, IAlbum album) { #region Parameter validation if (album == null) throw new ArgumentNullException("album"); if (directory.FullName != album.FullPhysicalPath) throw new ArgumentException("Error in SynchronizeMediaObjectFiles()."); #endregion //Update the media object table in the database with the file attributes of all //files in the directory passed to this function. Skip any hidden files. foreach (FileInfo file in directory.GetFiles()) { if ((file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) { this._synchStatus.SkippedMediaObjects.Add(new KeyValuePair<string, string>(file.FullName.Remove(0, _mediaObjectPhysicalPathLength + 1), Resources.SynchronizationStatus_Hidden_File_Msg)); continue; } #region Process thumbnail or optimized image if (file.Name.StartsWith(_thumbnailPrefix, StringComparison.OrdinalIgnoreCase)) { // We have a thumbnail image. If we are storing thumbnails in a different directory, delete the file. The user may have just // specified a new thumbnail path, and we need to delete all the previous thumbnails from their original location. if (_thumbnailRootPath != AppSetting.Instance.MediaObjectPhysicalPath) { File.Delete(file.FullName); } continue; } if (file.Name.StartsWith(_optimizedPrefix, StringComparison.OrdinalIgnoreCase)) { // We have an optimized image. If we are storing optimized images in a different directory, delete the file. The user may have // just specified a new optimized path, and we need to delete all the previous optimized images from their original location. if (_optimizedRootPath != AppSetting.Instance.MediaObjectPhysicalPath) { File.Delete(file.FullName); } continue; } #endregion IGalleryObject mediaObject = null; // See if this file is an existing media object. First look in the album's children. If not there, search the hash // keys - maybe it was moved from another directory. foreach (IGalleryObject existingMO in album.GetChildGalleryObjects(GalleryObjectType.MediaObject)) { if (existingMO.Original.FileNamePhysicalPath == file.FullName) { mediaObject = existingMO; break; } } if ((mediaObject != null) || ((mediaObject == null) && this._mediaObjectsFromDataStore.TryGetValue(HelperFunctions.GetHashKey(file), out mediaObject))) { // Found an existing media object matching the file on disk. Update properties, but only if its file extension // is enabled. (If this is a media object that had been added to Gallery Server but its file type was // subsequently disabled, we do not want to synchronize it - we want its info in the data store to be deleted.) if (HelperFunctions.IsFileAuthorizedForAddingToGallery(file.Name)) { UpdateExistingMediaObject(album, mediaObject); } } else { // No media object exists for this file. Create a new one. CreateNewMediaObject(album, file); } int newFileIndex = this._synchStatus.CurrentFileIndex + 1; if (newFileIndex < this._synchStatus.TotalFileCount) { UpdateStatus(newFileIndex, file.DirectoryName, file.Name); } if (this._synchStatus.ShouldTerminate) { this._synchStatus.ShouldTerminate = false; throw new GalleryServerPro.ErrorHandler.CustomExceptions.SynchronizationTerminationRequestedException(); } } }
/// <summary> /// Delete any thumbnail and optimized files that do not have matching media objects. /// This can occur when a user manually transfers (e.g. uses Windows Explorer) /// original files to a new directory and leaves the thumbnail and optimized /// files in the original directory or when a user deletes the original media file in /// Explorer. This function *only* deletes files that begin the the thumbnail and optimized /// prefix (e.g. zThumb_, zOpt_). /// </summary> /// <param name="album">The album whose directory is to be processed for orphaned image files.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="album" /> is null.</exception> private void DeleteOrphanedThumbnailAndOptimizedFiles(IAlbum album) { if (album == null) throw new ArgumentNullException("album"); // STEP 1: Get list of directories that may contain thumbnail or optimized images for the current album string originalPath = album.FullPhysicalPathOnDisk; string thumbnailPath = HelperFunctions.MapAlbumDirectoryStructureToAlternateDirectory(album.FullPhysicalPathOnDisk, GallerySettings.FullThumbnailPath, GallerySettings.FullMediaObjectPath); string optimizedPath = HelperFunctions.MapAlbumDirectoryStructureToAlternateDirectory(album.FullPhysicalPathOnDisk, GallerySettings.FullOptimizedPath, GallerySettings.FullMediaObjectPath); List<string> albumPaths = new List<string>(3); // The original path may contain thumbnails or optimized images when the thumbnail/optimized path is the same as the original path if ((GallerySettings.FullThumbnailPath.Equals(GallerySettings.FullMediaObjectPath, StringComparison.OrdinalIgnoreCase)) || (GallerySettings.FullOptimizedPath.Equals(GallerySettings.FullMediaObjectPath, StringComparison.OrdinalIgnoreCase))) { albumPaths.Add(originalPath); } if (!albumPaths.Contains(thumbnailPath)) albumPaths.Add(thumbnailPath); if (!albumPaths.Contains(optimizedPath)) albumPaths.Add(optimizedPath); string thumbnailPrefix = GallerySettings.ThumbnailFileNamePrefix; string optimizedPrefix = GallerySettings.OptimizedFileNamePrefix; IGalleryObjectCollection mediaObjects = album.GetChildGalleryObjects(GalleryObjectType.MediaObject); // STEP 2: Loop through each path and make sure all thumbnail and optimized files in each directory have // matching media objects. Delete any files that do not. foreach (string albumPath in albumPaths) { if (!Directory.Exists(albumPath)) return; DirectoryInfo directory = new DirectoryInfo(albumPath); // Loop through each file in the directory. FileInfo[] files; try { files = directory.GetFiles(); } catch (UnauthorizedAccessException) { return; } var queueItems = GetCurrentAndCompleteMediaQueueItems(); foreach (FileInfo file in files) { if ((file.Name.StartsWith(thumbnailPrefix, StringComparison.OrdinalIgnoreCase)) || (file.Name.StartsWith(optimizedPrefix, StringComparison.OrdinalIgnoreCase))) { // This file is a thumbnail or optimized file. // TEST 1: Check to see if any media object in this album refers to it. var foundMediaObject = false; foreach (IGalleryObject mediaObject in mediaObjects) { if ((mediaObject.Optimized.FileName.Equals(file.Name, StringComparison.OrdinalIgnoreCase)) || (mediaObject.Thumbnail.FileName.Equals(file.Name, StringComparison.OrdinalIgnoreCase))) { foundMediaObject = true; break; } } if (!foundMediaObject) { // TEST 2: Maybe the encoder engine is currently creating the file or just finished it. // First check to see if we started processing a new media item since we started this loop. // If so, add it to our list of queue items. var currentQueueItem = MediaConversionQueue.Instance.GetCurrentMediaQueueItem(); if (currentQueueItem != null && !queueItems.Any(mq => mq.MediaQueueId == currentQueueItem.MediaQueueId)) { queueItems = queueItems.Concat(new[] { currentQueueItem }); } // See if this file is mentioned in any of the media queue items foundMediaObject = queueItems.Any(mq => mq.StatusDetail.Contains(file.Name)); } if (!foundMediaObject) { // No media object in this album refers to this thumbnail or optimized image. Smoke it! try { file.Delete(); } catch (IOException ex) { // An exception occurred, probably because the account ASP.NET is running under does not // have permission to delete the file. Let's record the error, but otherwise ignore it. EventController.RecordError(ex, AppSetting.Instance, _galleryId, Factory.LoadGallerySettings()); } catch (SecurityException ex) { // An exception occurred, probably because the account ASP.NET is running under does not // have permission to delete the file. Let's record the error, but otherwise ignore it. EventController.RecordError(ex, AppSetting.Instance, _galleryId, Factory.LoadGallerySettings()); } catch (UnauthorizedAccessException ex) { // An exception occurred, probably because the account ASP.NET is running under does not // have permission to delete the file. Let's record the error, but otherwise ignore it. EventController.RecordError(ex, AppSetting.Instance, _galleryId, Factory.LoadGallerySettings()); } } } } } }
/// <summary> /// Add the child albums and media objects as stored on disk to the specified dictionary objects. Set /// IsSynchronized = false for each album and media object. This will be set to true as each is processed. /// This method calls itself recursively if IsRecursive = true. /// </summary> /// <param name="albums">A Dictionary object containing relevant albums for this synchronization. The album specified /// in the parentAlbum parameter will be added to this object.</param> /// <param name="mediaObjects">A Dictionary object containing relevant media objects for this synchronization. /// Media objects within the parentAlbum parameter will be added to this object.</param> /// <param name="parentAlbum">The album used as the source for populating the albums and mediaObjects /// parameters.</param> private void AddChildAlbumsAndGalleryObjectsAndSetToUnsynchronized(Dictionary<string, IAlbum> albums, Dictionary<string, IGalleryObject> mediaObjects, IAlbum parentAlbum) { foreach (IAlbum childAlbum in parentAlbum.GetChildGalleryObjects(GalleryObjectType.Album)) { if (!childAlbum.IsWritable) { throw new WebException(String.Format(CultureInfo.CurrentCulture, "The album is not writeable (ID {0}, Title='{1}')", childAlbum.Id, childAlbum.Title)); } childAlbum.IsSynchronized = false; childAlbum.RegenerateThumbnailOnSave = this.OverwriteThumbnail; try { // There can be situations where the database becomes corrupt, and the same album has two records. When this happens, // the following line will fail. Instead of letting the exception cause the synch to fail, we swallow the exception. // This will cause the album that caused the exception to eventually be deleted, which is what we want. albums.Add(childAlbum.FullPhysicalPathOnDisk, childAlbum); } catch (System.ArgumentException) { } foreach (IGalleryObject mediaObject in childAlbum.GetChildGalleryObjects(GalleryObjectType.MediaObject, false)) { if (!String.IsNullOrEmpty(mediaObject.Hashkey)) { if (!mediaObject.IsWritable) { throw new WebException(String.Format(CultureInfo.CurrentCulture, "The media object is not writeable (ID {0}, Title='{1}')", mediaObject.Id, mediaObject.Title)); } mediaObject.IsSynchronized = false; mediaObject.RegenerateOptimizedOnSave = this.OverwriteOptimized; mediaObject.RegenerateThumbnailOnSave = this.OverwriteThumbnail; mediaObject.ExtractMetadataOnSave = this.RegenerateMetadata; try { // There may be situations where the database becomes corrupt, and the same media object has two records. When this happens, // the following line will fail. Instead of letting the exception cause the synch to fail, we swallow the exception. // This will cause the media object that caused the exception to eventually be deleted, which is what we want. mediaObjects.Add(mediaObject.Hashkey, mediaObject); } catch (System.ArgumentException) { } } } string albumMsg = String.Format(CultureInfo.InvariantCulture, Resources.SynchronizationStatus_Loading_Album_Msg, childAlbum.Title); this._synchStatus.Update(SynchronizationState.NotSet, null, String.Empty, 0, albumMsg, null, false); if (this._isRecursive) { AddChildAlbumsAndGalleryObjectsAndSetToUnsynchronized(albums, mediaObjects, childAlbum); } } }
/// <summary> /// Gets the IDs of the child albums of the specified <paramref name="album" />, acting recursively. /// </summary> /// <param name="album">The album.</param> /// <returns>Returns an enumerable list of album ID values.</returns> private static IEnumerable<int> GetChildAlbumIds(IAlbum album) { List<int> albumIds = new List<int>(); foreach (IGalleryObject childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album)) { albumIds.Add(childAlbum.Id); albumIds.AddRange(GetChildAlbumIds((IAlbum)childAlbum)); } return albumIds; }
private void Initialize(string synchId, IAlbum album, string userName) { if (album == null) throw new ArgumentNullException("album"); if (String.IsNullOrEmpty(userName)) throw new ArgumentNullException("userName"); this._userName = userName; #region Set up the _synchStatus instance // Tell the status instance we are starting a new synchronization. It will throw // SynchronizationInProgressException if another is in progress. this._synchStatus = SynchronizationStatus.Start(synchId, album.GalleryId); this._synchStatus.Update(SynchronizationState.NotSet, CountFiles(album.FullPhysicalPathOnDisk), null, null, null, null, true); #endregion #region Populate the _albumsFromDataStore and _mediaObjectsFromDataStore dictionary objects and set each to IsSynchronized = false this._albumsFromDataStore = new Dictionary<String, IAlbum>(); this._mediaObjectsFromDataStore = new Dictionary<String, IGalleryObject>(this._synchStatus.TotalFileCount); // Fill _albums and _mediaObjects with the albums and media objects for this album as currently stored // in the data store. We'll be comparing these objects with those we find on the hard drive. Act recursively // if IsRecursive = true. Set IsSynchronized = false for each object. (We'll be setting it back to true // as we synchronize each object.) album.IsSynchronized = false; album.RegenerateThumbnailOnSave = this.OverwriteThumbnail; if (!album.IsWritable) { throw new WebException(String.Format(CultureInfo.CurrentCulture, "The album is not writeable (ID {0}, Title='{1}')", album.Id, album.Title)); } this._albumsFromDataStore.Add(album.FullPhysicalPathOnDisk, album); foreach (IGalleryObject mediaObject in album.GetChildGalleryObjects(GalleryObjectType.MediaObject)) { if (!mediaObject.IsWritable) { throw new WebException(String.Format(CultureInfo.CurrentCulture, "The media object is not writeable (ID {0}, Title='{1}')", mediaObject.Id, mediaObject.Title)); } mediaObject.IsSynchronized = false; mediaObject.RegenerateThumbnailOnSave = this.OverwriteThumbnail; mediaObject.RegenerateOptimizedOnSave = this.OverwriteOptimized; mediaObject.ExtractMetadataOnSave = this.RegenerateMetadata; if (!String.IsNullOrEmpty(mediaObject.Hashkey)) { this._mediaObjectsFromDataStore.Add(mediaObject.Hashkey, mediaObject); } } if (this._isRecursive) { AddChildAlbumsAndGalleryObjectsAndSetToUnsynchronized(this._albumsFromDataStore, this._mediaObjectsFromDataStore, album); } #endregion // Clear the list of hash keys so we're starting with a fresh load from the data store. MediaObjectHashKeys.Clear(); }
/// <summary> /// Set the IsPrivate property of all child albums and media objects of the specified album to have the same value /// as the specified album. /// </summary> /// <param name="album">The album whose child objects are to be updated to have the same IsPrivate value.</param> /// <param name="userName">Name of the current user.</param> private static void SynchIsPrivatePropertyOnChildGalleryObjectsRecursive(IAlbum album, string userName) { album.Inflate(true); foreach (IAlbum childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album)) { childAlbum.Inflate(true); // The above Inflate() does not inflate child albums, so we need to explicitly inflate it. childAlbum.IsPrivate = album.IsPrivate; GalleryObjectController.SaveGalleryObject(childAlbum, userName); SynchIsPrivatePropertyOnChildGalleryObjectsRecursive(childAlbum, userName); } foreach (IGalleryObject childGalleryObject in album.GetChildGalleryObjects(GalleryObjectType.MediaObject)) { childGalleryObject.IsPrivate = album.IsPrivate; GalleryObjectController.SaveGalleryObject(childGalleryObject, userName); } }
/// <summary> /// Synchronizes the media object files. /// </summary> /// <param name="directory">The directory.</param> /// <param name="album">The album.</param> /// <exception cref="UnauthorizedAccessException">Thrown when the IIS app pool identity cannot access the files in the directory.</exception> /// <exception cref="ArgumentNullException">Thrown when <paramref name="album" /> or <paramref name="directory" /> is null.</exception> /// <exception cref="ArgumentException">Thrown when the full directory path of <paramref name="directory" /> does not match the directory path of /// <paramref name="album" />.</exception> private void SynchronizeMediaObjectFiles(DirectoryInfo directory, IAlbum album) { #region Parameter validation if (directory == null) throw new ArgumentNullException("directory"); if (album == null) throw new ArgumentNullException("album"); if (!directory.FullName.Equals(album.FullPhysicalPath, StringComparison.OrdinalIgnoreCase)) throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Error in SynchronizeMediaObjectFiles(): The full directory path of the parameter 'directory' does not match the directory path of the parameter 'album'. directory.FullName='{0}'; album.FullPhysicalPath='{1}'", directory.FullName, album.FullPhysicalPath)); #endregion //Update the media object table in the database with the file attributes of all //files in the directory passed to this function. Skip any hidden files. FileInfo[] files; try { files = directory.GetFiles(); } catch (UnauthorizedAccessException) { _synchStatus.SkippedMediaObjects.Add(new KeyValuePair<string, string>(directory.Name, Resources.SynchronizationStatus_Restricted_Directory_Msg)); throw; } // First sort by the filename. Array.Sort(files, (a, b) => String.Compare(a.Name, b.Name, StringComparison.Ordinal)); foreach (FileInfo file in files) { if ((file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) { _synchStatus.SkippedMediaObjects.Add(new KeyValuePair<string, string>(file.FullName.Remove(0, _fullMediaObjectPathLength + 1), Resources.SynchronizationStatus_Hidden_File_Msg)); continue; } #region Process thumbnail or optimized image if (file.Name.StartsWith(_thumbnailPrefix, StringComparison.OrdinalIgnoreCase)) { // We have a thumbnail image. If we are storing thumbnails in a different directory, delete the file, but only if the path // is writeable. The user may have just specified a new thumbnail path, and we need to delete all the previous thumbnails // from their original location. if (_thumbnailRootPath != GallerySettings.FullMediaObjectPath && !GallerySettings.MediaObjectPathIsReadOnly) { File.Delete(file.FullName); } continue; } if (file.Name.StartsWith(_optimizedPrefix, StringComparison.OrdinalIgnoreCase)) { // We have an optimized image. If we are storing optimized images in a different directory, delete the file, but only if the path // is writeable. The user may have just specified a new optimized path, and we need to delete all the previous optimized images // from their original location. if (_optimizedRootPath != GallerySettings.FullMediaObjectPath && !GallerySettings.MediaObjectPathIsReadOnly) { File.Delete(file.FullName); } continue; } #endregion IGalleryObject mediaObject = null; // See if this file is an existing media object. First look in the album's children. If not there, search the hash // keys - maybe it was moved from another directory. foreach (IGalleryObject existingMediaObject in album.GetChildGalleryObjects(GalleryObjectType.MediaObject)) { if (existingMediaObject.Original.FileNamePhysicalPath.Equals(file.FullName, StringComparison.OrdinalIgnoreCase)) { mediaObject = existingMediaObject; break; } } if ((mediaObject != null) || (_mediaObjectsFromDataStore.TryGetValue(HelperFunctions.GetHashKey(file), out mediaObject))) { // Found an existing media object matching the file on disk. Update properties, but only if its file extension // is enabled. (If this is a media object that had been added to Gallery Server but its file type was // subsequently disabled, we do not want to synchronize it - we want its info in the data store to be deleted.) if (HelperFunctions.IsFileAuthorizedForAddingToGallery(file.Name, album.GalleryId)) { UpdateExistingMediaObject(album, mediaObject); } } else { // No media object exists for this file. Create a new one. CreateNewMediaObject(album, file); } int newFileIndex = this._synchStatus.CurrentFileIndex + 1; if (newFileIndex < this._synchStatus.TotalFileCount) { UpdateStatus(newFileIndex, file.DirectoryName, file.Name); } lock (this._synchStatus) { if (this._synchStatus.ShouldTerminate) { // Immediately set this property back to false so that we don't trigger this code again, then throw a special exception // that will be caught and used to cancel the synch. this._synchStatus.Update(SynchronizationState.NotSet, null, null, null, null, false, false); throw new SynchronizationTerminationRequestedException(); } } } }
/// <summary> /// Deletes the thumbnail and optimized images associated with this album and all its children, but do not delete the /// album's directory or the any other files it contains. /// </summary> /// <param name="album">The album.</param> private static void DeleteSupportFilesOnly(IAlbum album) { foreach (IGalleryObject childGalleryObject in album.GetChildGalleryObjects(GalleryObjectType.MediaObject)) { DeleteThumbnailAndOptimizedImagesFromFileSystem(childGalleryObject); } foreach (IAlbum childAlbum in album.GetChildGalleryObjects(GalleryObjectType.Album)) { DeleteSupportFilesOnly(childAlbum); } }
private IAlbum VerifyAlbumExistsAndReturnReference(ZipEntry zipContentFile, IAlbum rootParentAlbum) { // Get the directory path of the next file or directory within the zip file. // Ex: album1\album2\album3, album1 string zipDirectoryPath = Path.GetDirectoryName(zipContentFile.Name); string[] directoryNames = zipDirectoryPath.Split(new char[] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries); string albumFullPhysicalPath = rootParentAlbum.FullPhysicalPathOnDisk; IAlbum currentAlbum = rootParentAlbum; foreach (string directoryNameFromZip in directoryNames) { string shortenedDirName = GetPreviouslyCreatedTruncatedAlbumName(albumFullPhysicalPath, directoryNameFromZip); // Ex: c:\inetpub\wwwroot\galleryserver\mypics\2006\album1 albumFullPhysicalPath = System.IO.Path.Combine(albumFullPhysicalPath, shortenedDirName); IAlbum newAlbum = null; if (Directory.Exists(albumFullPhysicalPath)) { // Directory exists, so there is probably an album corresponding to it. Find it. IGalleryObjectCollection childGalleryObjects = currentAlbum.GetChildGalleryObjects(GalleryObjectType.Album); foreach (IGalleryObject childGalleryObject in childGalleryObjects) { if (childGalleryObject.FullPhysicalPathOnDisk.Equals(albumFullPhysicalPath, StringComparison.OrdinalIgnoreCase)) { newAlbum = childGalleryObject as Album; break; } } if (newAlbum == null) { // No album in the database matches that directory. Add it. // Before we add the album, we need to make sure the user has permission to add the album. Check if user // is authenticated and if the current album is the one passed into this method. It can be assumed that any // other album we encounter has been created by this method and we checked for permission when it was created. if (this._isAuthenticated && (currentAlbum.Id == rootParentAlbum.Id)) { SecurityManager.ThrowIfUserNotAuthorized(SecurityActions.AddChildAlbum, this._roles, currentAlbum.Id, currentAlbum.GalleryId, this._isAuthenticated, currentAlbum.IsPrivate); } newAlbum = Factory.CreateEmptyAlbumInstance(currentAlbum.GalleryId); newAlbum.Parent = currentAlbum; newAlbum.IsPrivate = currentAlbum.IsPrivate; newAlbum.DirectoryName = directoryNameFromZip; HelperFunctions.UpdateAuditFields(newAlbum, this._userName); newAlbum.Save(); } } else { // The directory doesn't exist. Create an album. // Before we add the album, we need to make sure the user has permission to add the album. Check if user // is authenticated and if the current album is the one passed into this method. It can be assumed that any // other album we encounter has been created by this method and we checked for permission when it was created. if (this._isAuthenticated && (currentAlbum.Id == rootParentAlbum.Id)) { SecurityManager.ThrowIfUserNotAuthorized(SecurityActions.AddChildAlbum, this._roles, currentAlbum.Id, currentAlbum.GalleryId, this._isAuthenticated, currentAlbum.IsPrivate); } newAlbum = Factory.CreateEmptyAlbumInstance(currentAlbum.GalleryId); newAlbum.IsPrivate = currentAlbum.IsPrivate; newAlbum.Parent = currentAlbum; newAlbum.Title = directoryNameFromZip; HelperFunctions.UpdateAuditFields(newAlbum, this._userName); newAlbum.Save(); // If the directory name written to disk is different than the name from the zip file, add it to // our hash table. if (!directoryNameFromZip.Equals(newAlbum.DirectoryName)) { this._albumAndDirectoryNamesLookupTable.Add(Path.Combine(currentAlbum.FullPhysicalPathOnDisk, directoryNameFromZip), Path.Combine(currentAlbum.FullPhysicalPathOnDisk, newAlbum.DirectoryName)); } } currentAlbum = newAlbum; } return(currentAlbum); }
/// <summary> /// Create a minimally populated <see cref="ExternalMediaObject" /> instance from the specified parameters. /// </summary> /// <param name="externalHtmlSource">The HTML that defines an externally stored media object, such as one hosted at /// YouTube or Silverlight.live.com.</param> /// <param name="mimeType">Specifies the category to which this mime type belongs. This usually corresponds to the first portion of /// the full mime type description. (e.g. "image" if the full mime type is "image/jpeg").</param> /// <param name="parentAlbum">The album in which the file exists (for media objects that already exist /// in the data store), or should be added to (for new media objects which need to be inserted into the /// data store).</param> /// <param name="forceNew">Indicates whether to initialize a new, unsaved media object even if the imageFile /// parameter refers to an existing file in the album's directory. Typically used when copying an existing media /// object where a subsequent operation will copy the existing file to the destination album, thus resulting in a /// new, independent media object.</param> /// <returns>Returns a minimally populated <see cref="ExternalMediaObject" /> instance from the specified parameters.</returns> public static IGalleryObject CreateExternalMediaObjectInstance(string externalHtmlSource, MimeTypeCategory mimeType, IAlbum parentAlbum, bool forceNew) { #if DEBUG Tools.StartingMethod(externalHtmlSource, mimeType, parentAlbum); #endif // If the file belongs to an existing media object, return a reference to it. if (!forceNew) { foreach (IGalleryObject childMediaObject in parentAlbum.GetChildGalleryObjects(GalleryObjectType.External)) { if (childMediaObject.Original.ExternalHtmlSource == externalHtmlSource) return childMediaObject; } } if (forceNew) parentAlbum = null; // Create a new generic media object, which will cause a new record to be inserted in the data store when Save() is called. return new ExternalMediaObject(externalHtmlSource, mimeType, parentAlbum); }