/// <summary>
        /// Synchronize the media object library, starting with the root album. Optionally specify that only the
        /// specified album is synchronized. If <see cref="IsRecursive" /> = true, then child albums are recursively synchronized;
        /// otherwise, only the root album (or the specified album if that overload is used) is synchronized.
        /// </summary>
        /// <param name="synchId">A GUID that uniquely identifies the synchronization. If another synchronization is in
        /// progress, a <see cref="GalleryServerPro.Events.CustomExceptions.SynchronizationInProgressException" /> exception is thrown.</param>
        /// <param name="userName">The user name for the logged on user. This is used for the audit fields in the album
        /// and media objects.</param>
        /// <param name="album">The album to synchronize.</param>
        /// <exception cref="GalleryServerPro.Events.CustomExceptions.SynchronizationInProgressException">
        /// Thrown if another synchronization is in progress.</exception>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="album" /> is null.</exception>
        public void Synchronize(string synchId, IAlbum album, string userName)
        {
            if (album == null)
            {
                throw new ArgumentNullException("album");
            }

            try
            {
                Initialize(synchId, album, userName);                 // Will throw SynchronizationInProgressException if another is in progress. Will be caught be upstream code.

                var albumDirectory = new DirectoryInfo(album.FullPhysicalPathOnDisk);

                // Synchronize the files in this album. No recursive action.
                SynchronizeMediaObjectFiles(albumDirectory, album);

                if (IsRecursive)
                {
                    // Synchronize the child directories and their files. Acts recursively.
                    SynchronizeChildDirectories(albumDirectory, album);
                }

                Album.AssignAlbumThumbnail(album, false, true, UserName);

                album.SortAsync(true, UserName, true);

                if (_synchStatus != null)
                {
                    _synchStatus.Finish();
                }
            }
            catch (SynchronizationTerminationRequestedException)
            {
                // The user has canceled the synchronization. Swallow the exception and return.
                return;
            }
            catch (SynchronizationInProgressException)
            {
                // Another sync is in progress. We don't want the generic catch below to change the sync state, so we intercept it here.
                throw;
            }
            catch
            {
                if (_synchStatus != null)
                {
                    UpdateStatus(0, syncState: SynchronizationState.Error, persistToDatabase: true);
                }

                throw;
            }
            finally
            {
                HelperFunctions.PurgeCache();
            }
        }
        /// <summary>
        /// Synchronize the media object library, starting with the root album. Optionally specify that only the 
        /// specified album is synchronized. If <see cref="IsRecursive" /> = true, then child albums are recursively synchronized;
        /// otherwise, only the root album (or the specified album if that overload is used) is synchronized.
        /// </summary>
        /// <param name="synchId">A GUID that uniquely identifies the synchronization. If another synchronization is in 
        /// progress, a <see cref="GalleryServerPro.Events.CustomExceptions.SynchronizationInProgressException" /> exception is thrown.</param>
        /// <param name="userName">The user name for the logged on user. This is used for the audit fields in the album 
        /// and media objects.</param>
        /// <param name="album">The album to synchronize.</param>
        /// <exception cref="GalleryServerPro.Events.CustomExceptions.SynchronizationInProgressException">
        /// Thrown if another synchronization is in progress.</exception>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="album" /> is null.</exception>
        public void Synchronize(string synchId, IAlbum album, string userName)
        {
            if (album == null)
                throw new ArgumentNullException("album");

            try
            {
                Initialize(synchId, album, userName); // Will throw SynchronizationInProgressException if another is in progress. Will be caught be upstream code.

                var albumDirectory = new DirectoryInfo(album.FullPhysicalPathOnDisk);

                // Synchronize the files in this album. No recursive action.
                SynchronizeMediaObjectFiles(albumDirectory, album);

                if (IsRecursive)
                {
                    // Synchronize the child directories and their files. Acts recursively.
                    SynchronizeChildDirectories(albumDirectory, album);
                }

                Album.AssignAlbumThumbnail(album, false, true, UserName);

                album.SortAsync(true, UserName, true);

                if (_synchStatus != null)
                    _synchStatus.Finish();
            }
            catch (SynchronizationTerminationRequestedException)
            {
                // The user has canceled the synchronization. Swallow the exception and return.
                return;
            }
            catch (SynchronizationInProgressException)
            {
                // Another sync is in progress. We don't want the generic catch below to change the sync state, so we intercept it here.
                throw;
            }
            catch
            {
                if (_synchStatus != null)
                    UpdateStatus(0, syncState: SynchronizationState.Error, persistToDatabase: true);

                throw;
            }
            finally
            {
                HelperFunctions.PurgeCache();
            }
        }
예제 #3
0
        /// <summary>
        /// Creates the media object from the file specified in <paramref name="options" />.
        /// </summary>
        /// <param name="options">The options.</param>
        /// <returns>List{ActionResult}.</returns>
        /// <exception cref="Events.CustomExceptions.GallerySecurityException">Thrown when user is not authorized to add a media object to the album.</exception>
        /// <remarks>This function can be invoked from a thread that does not have access to the current HTTP context (for example, when
        /// uploading ZIP files). Therefore, be sure nothing in this body (or the functions it calls) uses HttpContext.Current, or at
        /// least check it for null first.</remarks>
        private static List <ActionResult> CreateMediaObjectFromFile(AddMediaObjectSettings options)
        {
            string sourceFilePath = Path.Combine(AppSetting.Instance.PhysicalApplicationPath, GlobalConstants.TempUploadDirectory, options.FileNameOnServer);

            try
            {
                IAlbum album = AlbumController.LoadAlbumInstance(options.AlbumId, true, true);

                if (HttpContext.Current != null)
                {
                    SecurityManager.ThrowIfUserNotAuthorized(SecurityActions.AddMediaObject, RoleController.GetGalleryServerRolesForUser(), album.Id, album.GalleryId, Utils.IsAuthenticated, album.IsPrivate, album.IsVirtualAlbum);
                }
                else
                {
                    // We are extracting files from a zip archive (we know this because this is the only scenario that happens on a background
                    // thread where HttpContext.Current is null). Tweak the security check slightly to ensure the HTTP context isn't used.
                    // The changes are still secure because options.CurrentUserName is assigned in the server's API method.
                    SecurityManager.ThrowIfUserNotAuthorized(SecurityActions.AddMediaObject, RoleController.GetGalleryServerRolesForUser(options.CurrentUserName), album.Id, album.GalleryId, !String.IsNullOrWhiteSpace(options.CurrentUserName), album.IsPrivate, album.IsVirtualAlbum);
                }

                var extension = Path.GetExtension(options.FileName);
                if (extension != null && ((extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)) && (options.ExtractZipFile)))
                {
                    List <ActionResult> result;

                    // Extract the files from the zipped file.
                    using (var zip = new ZipUtility(options.CurrentUserName, RoleController.GetGalleryServerRolesForUser(options.CurrentUserName)))
                    {
                        using (var fs = new FileStream(sourceFilePath, FileMode.Open, FileAccess.Read))
                        {
                            result = zip.ExtractZipFile(fs, album, options.DiscardOriginalFile);
                        }
                    }

                    album.SortAsync(true, options.CurrentUserName, true);

                    return(result);
                }
                else
                {
                    string albumPhysicalPath = album.FullPhysicalPathOnDisk;
                    string filename          = HelperFunctions.ValidateFileName(albumPhysicalPath, options.FileName);
                    string filepath          = Path.Combine(albumPhysicalPath, filename);

                    MoveFile(filepath, sourceFilePath);

                    ActionResult result = CreateMediaObject(filepath, album, options);

                    album.Sort(true, options.CurrentUserName);

                    return(new List <ActionResult> {
                        result
                    });
                }
            }
            catch (Exception ex)
            {
                AppEventController.LogError(ex);
                return(new List <ActionResult>
                {
                    new ActionResult
                    {
                        Title = options.FileName,
                        Status = ActionResultStatus.Error.ToString(),
                        Message = "The event log may have additional details."
                    }
                });
            }
            finally
            {
                try
                {
                    // If the file still exists in the temp directory, delete it. Typically this happens when we've
                    // extracted the contents of a zip file (since other files will have already been moved to the dest album.)
                    if (File.Exists(sourceFilePath))
                    {
                        File.Delete(sourceFilePath);
                    }
                }
                catch (IOException) { }                 // Ignore an error; not a big deal if it continues to exist in the temp directory
                catch (UnauthorizedAccessException) { } // Ignore an error; not a big deal if it continues to exist in the temp directory
            }
        }