Example #1
0
        /// <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));
        }
Example #2
0
        /// <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();
        }
Example #7
0
        /// <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);
            }
        }
Example #8
0
        /// <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);
            }
        }
Example #9
0
        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();
     }
 }
Example #11
0
        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);
        }
Example #12
0
        /// <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();
            }
        }
Example #14
0
        /// <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);
        }
Example #15
0
        /// <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);
        }
Example #16
0
        /// <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);
        }
Example #17
0
		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));
            }
        }
Example #20
0
 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;
         }
     }
 }
Example #21
0
        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);
        }
Example #22
0
        /// <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);
            }
        }
Example #23
0
        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);
        }
Example #24
0
        /// <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);
                }
            }
        }
Example #25
0
        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);
        }
Example #26
0
        /// <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
        }
Example #27
0
        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;
        }
Example #29
0
        /// <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);
            }
        }
Example #31
0
		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);
		}
Example #32
0
        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();
                }
            }
        }
Example #33
0
        /// <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());
                            }
                        }
                    }
                }
            }
        }
Example #37
0
		/// <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);
			}
		}
Example #38
0
		/// <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();
     }
 }
Example #44
0
        /// <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;
        }
Example #46
0
        /// <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
        }
Example #47
0
        /// <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;
                }
            }
        }
Example #48
0
        /// <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);
            }
        }
Example #49
0
        /// <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);
        }
Example #50
0
        /// <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();
        }
Example #56
0
        /// <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);
            }
        }
Example #59
0
        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);
        }
Example #60
0
		/// <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);
		}