/// <summary>
        /// Adds a media file to an album. Prior to calling this method, the file should exist in the 
        /// temporary upload directory (<see cref="GlobalConstants.TempUploadDirectory" />) in the 
        /// App_Data directory with the name <see cref="AddMediaObjectSettings.FileNameOnServer" />. The
        /// file is copied to the destination album and given the name of 
        /// <see cref="AddMediaObjectSettings.FileName" /> (instead of whatever name it currently has, which 
        /// may contain a GUID).
        /// </summary>
        /// <param name="settings">The settings that contain data and configuration options for the media file.</param>
        public static List<ActionResult> AddMediaObject(AddMediaObjectSettings settings)
        {
            List<ActionResult> results = CreateMediaObjectFromFile(settings);

            Utils.AddResultToSession(results);

            return results;
        }
        /// <summary>
        /// Adds a media file to an album. Prior to calling this method, the file should exist in the 
        /// temporary upload directory (<see cref="GlobalConstants.TempUploadDirectory" />) in the 
        /// App_Data directory with the name <see cref="AddMediaObjectSettings.FileNameOnServer" />. The
        /// file is copied to the destination album and given the name of 
        /// <see cref="AddMediaObjectSettings.FileName" /> (instead of whatever name it currently has, which 
        /// may contain a GUID).
        /// </summary>
        /// <param name="settings">The settings that contain data and configuration options for the media file.</param>
        /// <exception cref="Events.CustomExceptions.GallerySecurityException">Thrown when user is not authorized to add a media object to the album.</exception>
        public static List<ActionResult> AddMediaObject(AddMediaObjectSettings settings)
        {
            List<ActionResult> results = CreateMediaObjectFromFile(settings);

            HelperFunctions.PurgeCache();

            return results;
        }
        /// <summary>
        /// Adds a media file to an album. Prior to calling this method, the file should exist in the
        /// temporary upload directory (<see cref="GlobalConstants.TempUploadDirectory" />) in the
        /// App_Data directory with the name <see cref="AddMediaObjectSettings.FileNameOnServer" />. The
        /// file is copied to the destination album and given the name of
        /// <see cref="AddMediaObjectSettings.FileName" /> (instead of whatever name it currently has, which
        /// may contain a GUID).
        /// </summary>
        /// <param name="settings">The settings that contain data and configuration options for the media file.</param>
        /// <returns>List{ActionResult}.</returns>
        /// <exception cref="System.Web.Http.HttpResponseException">Thrown when the user does not have permission to add media
        /// objects or some other error occurs.</exception>
        public List<ActionResult> CreateFromFile(AddMediaObjectSettings settings)
        {
            try
            {
                settings.CurrentUserName = Utils.UserName;

                var fileExt = Path.GetExtension(settings.FileName);

                if (fileExt != null && fileExt.Equals(".zip", StringComparison.OrdinalIgnoreCase))
                {
                    Task.Factory.StartNew(() =>
                                              {
                                                  var results = GalleryObjectController.AddMediaObject(settings);

                                                  // Since we don't have access to the user's session here, let's create a log entry.
                                                  LogUploadZipFileResults(results, settings);
                                              });

                    return new List<ActionResult>
                               {
                                   new ActionResult
                                       {
                                           Title = settings.FileName,
                                           Status = ActionResultStatus.Async.ToString()
                                       }
                               };
                }
                else
                {
                    var results = GalleryObjectController.AddMediaObject(settings);

                    Utils.AddResultToSession(results);

                    return results;
                }
            }
            catch (GallerySecurityException)
            {
                AppEventController.LogEvent(String.Format(CultureInfo.InvariantCulture, "Unauthorized access detected. The security system prevented a user from adding a media object."), null, EventType.Warning);

                throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Forbidden));
            }
            catch (Exception ex)
            {
                AppEventController.LogError(ex);

                throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
                                                    {
                                                        Content = Utils.GetExStringContent(ex),
                                                        ReasonPhrase = "Server Error"
                                                    });
            }
        }
 public List<ActionResult> AddMediaObject(AddMediaObjectSettings settings)
 {
     try
     {
         return GalleryObjectController.AddMediaObject(settings);
     }
     catch (Exception ex)
     {
         AppErrorController.LogError(ex);
         throw;
     }
 }
        private static void LogUploadZipFileResults(List<ActionResult> results, AddMediaObjectSettings settings)
        {
            var isSuccessful = results.All(r => r.Status == ActionResultStatus.Success.ToString());
            int? galleryId = null;
            IAlbum album = null;
            try
            {
                album = Factory.LoadAlbumInstance(settings.AlbumId, false);
                galleryId = album.GalleryId;
            }
            catch (InvalidAlbumException) { }

            if (isSuccessful)
            {
                AppEventController.LogEvent(String.Format(CultureInfo.InvariantCulture, "{0} files were successfully extracted from the file '{1}' and added to album '{2}'.", results.Count, settings.FileName, album != null ? album.Title : "<Unknown>"), galleryId);

                return;
            }

            // If we get here at least one of the results was an info, warning, error, etc.
            var succesfulResults = results.Where(m => m.Status == ActionResultStatus.Success.ToString());
            var unsuccesfulResults = results.Where(m => m.Status != ActionResultStatus.Success.ToString());
            var msg = String.Format(CultureInfo.InvariantCulture, "{0} items in the uploaded file '{1}' were added to the gallery, but {2} files were skipped. Review the details for additional information. The file was uploaded by user {3}.", succesfulResults.Count(), settings.FileName, unsuccesfulResults.Count(), settings.CurrentUserName);
            var ex = new UnsupportedMediaObjectTypeException(msg, null);

            var i = 1;
            foreach (var result in unsuccesfulResults)
            {
                ex.Data.Add("File " + i++, String.Format(CultureInfo.InvariantCulture, "{0}: {1}", result.Title, result.Message));
            }

            AppEventController.LogError(ex, galleryId);
        }
        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);

                if ((Path.GetExtension(options.FileName).Equals(".zip", StringComparison.OrdinalIgnoreCase)) && (options.ExtractZipFile))
                {
                    // Extract the files from the zipped file.
                    using (ZipUtility zip = new ZipUtility(Utils.UserName, RoleController.GetGalleryServerRolesForUser()))
                    {
                        using (FileStream fs = new FileStream(sourceFilePath, FileMode.Open, FileAccess.Read))
                        {
                            return zip.ExtractZipFile(fs, album, options.DiscardOriginalFile);
                        }
                    }
                }
                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);
                    return new List<ActionResult>() { result };
                }
            }
            catch (Exception ex)
            {
                AppErrorController.LogError(ex);
                return new List<ActionResult>()
                       	{
                       		new ActionResult()
                       			{
                       				Title = options.FileName,
                       				Status = ActionResultStatus.Error,
                       				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
            }
        }
        private static ActionResult CreateMediaObject(string filePath, IAlbum album, AddMediaObjectSettings options)
        {
            var result = new ActionResult()
            {
                Title = Path.GetFileName(filePath)
            };

            try
            {
                using (IGalleryObject go = Factory.CreateMediaObjectInstance(filePath, album))
                {
                    SaveGalleryObject(go);

                    if (options.DiscardOriginalFile)
                    {
                        go.DeleteOriginalFile();
                        GalleryObjectController.SaveGalleryObject(go);
                    }

                    result.Status = ActionResultStatus.Success;
                }
            }
            catch (UnsupportedMediaObjectTypeException ex)
            {
                try
                {
                    File.Delete(filePath);
                }
                catch (UnauthorizedAccessException) { } // Ignore an error; the file will continue to exist in the destination album directory

                result.Status = ActionResultStatus.Error;
                result.Message = ex.Message;
            }

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