/// <summary> /// Perform a synchronization according to the specified <paramref name="syncOptions" />. Any exceptions that occur during the /// sync are caught and logged to the event log. For auto-run syncs, the property <see cref="IGallerySettings.LastAutoSync" /> /// is set to the current date/time and persisted to the data store. /// NOTE: This method does not perform any security checks; the calling code must ensure the requesting user is authorized to run the sync. /// </summary> /// <param name="syncOptions">An object specifying the parameters for the synchronization operation.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="syncOptions" /> is null.</exception> public static void BeginSync(SyncOptions syncOptions) { if (syncOptions == null) throw new ArgumentNullException("syncOptions"); IAlbum album = null; try { album = AlbumController.LoadAlbumInstance(syncOptions.AlbumIdToSynchronize, true, true, true); AppEventController.LogEvent(String.Format(CultureInfo.InvariantCulture, "{0} synchronization of album '{1}' (ID {2}) has started.", syncOptions.UserName, album.Title, album.Id), album.GalleryId); var synchMgr = new SynchronizationManager(album.GalleryId); synchMgr.IsRecursive = syncOptions.IsRecursive; synchMgr.RebuildThumbnail = syncOptions.RebuildThumbnails; synchMgr.RebuildOptimized = syncOptions.RebuildOptimized; synchMgr.Synchronize(syncOptions.SyncId, album, syncOptions.UserName); if (syncOptions.SyncInitiator == SyncInitiator.AutoSync) { // Update the date/time of this auto-sync and save to data store. IGallerySettings gallerySettings = Factory.LoadGallerySetting(album.GalleryId, true); gallerySettings.LastAutoSync = DateTime.Now; gallerySettings.Save(false); // The above Save() only updated the database; now we need to update the in-memory copy of the settings. // We have to do this instead of simply calling gallerySettings.Save(true) because that overload causes the // gallery settings to be cleared and reloaded, and the reloading portion done by the AddMembershipDataToGallerySettings // function fails in DotNetNuke because there isn't a HttpContext.Current instance at this moment (because this code is // run on a separate thread). IGallerySettings gallerySettingsReadOnly = Factory.LoadGallerySetting(album.GalleryId, false); gallerySettingsReadOnly.LastAutoSync = gallerySettings.LastAutoSync; } AppEventController.LogEvent(String.Format(CultureInfo.InvariantCulture, "{0} synchronization of album '{1}' (ID {2}) has finished.", syncOptions.UserName, album.Title, album.Id), album.GalleryId); } catch (SynchronizationInProgressException) { var message = String.Format(CultureInfo.InvariantCulture, "{0} synchronization of album '{1}' (ID {2}) could not be started because another one is in progress.", syncOptions.UserName, album != null ? album.Title : "N/A", album != null ? album.Id.ToString(CultureInfo.InvariantCulture) : "N/A"); AppEventController.LogEvent(message, album != null ? album.GalleryId : (int?)null); } catch (Exception ex) { if (album != null) { AppEventController.LogError(ex, album.GalleryId); } else { AppEventController.LogError(ex); } var msg = String.Format(CultureInfo.InvariantCulture, "{0} synchronization of album '{1}' (ID {2}) has encountered an error and could not be completed.", syncOptions.UserName, album != null ? album.Title : "N/A", album != null ? album.Id.ToString(CultureInfo.InvariantCulture) : "N/A"); AppEventController.LogEvent(msg, album != null ? album.GalleryId : (int?)null); } }
/// <summary> /// Starts a synchronization on a background thread for all galleries. /// </summary> /// <param name="syncOptions">The synchronization options.</param> /// <param name="password">The password that allows remote access to the synchronization API.</param> private static void StartRemoteSyncForAllGalleries(SyncOptions syncOptions, string password) { // User is requesting that all galleries be synchronized. foreach (var gallery in Factory.LoadGalleries()) { var rootAlbum = Factory.LoadRootAlbumInstance(gallery.GalleryId, false, false); if (!ValidateRemoteSync(rootAlbum, password)) continue; var copiedSyncOptions = CopySyncOptions(syncOptions); copiedSyncOptions.AlbumIdToSynchronize = rootAlbum.Id; Task.Factory.StartNew(() => GalleryController.BeginSync(copiedSyncOptions), TaskCreationOptions.LongRunning); } }
/// <summary> /// Starts a synchronization on a background thread for the album specified in <paramref name="syncOptions" />. /// </summary> /// <param name="syncOptions">The synchronization options.</param> /// <param name="password">The password that allows remote access to the synchronization API.</param> private static void StartRemoteSync(SyncOptions syncOptions, string password) { IAlbum album = AlbumController.LoadAlbumInstance(syncOptions.AlbumIdToSynchronize, true, true, true); if (!ValidateRemoteSync(album, password)) { throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Forbidden)); } Task.Factory.StartNew(() => GalleryController.BeginSync(syncOptions), TaskCreationOptions.LongRunning); }
/// <summary> /// Generate a new instance of <see cref="SyncOptions" /> having the same properties as <paramref name="syncOptions" />, /// with the exception of <see cref="SyncOptions.SyncId" />, which is set to a new value. /// </summary> /// <param name="syncOptions">The synchronization options to copy.</param> /// <returns>An instance of <see cref="SyncOptions" />.</returns> private static SyncOptions CopySyncOptions(SyncOptions syncOptions) { return new SyncOptions { AlbumIdToSynchronize = syncOptions.AlbumIdToSynchronize, IsRecursive = syncOptions.IsRecursive, RebuildThumbnails = syncOptions.RebuildThumbnails, RebuildOptimized = syncOptions.RebuildOptimized, SyncId = Guid.NewGuid().ToString(), SyncInitiator = syncOptions.SyncInitiator, UserName = syncOptions.UserName }; }
/// <overloads> /// Synchronize the files in the media objects directory with the data store. /// </overloads> /// <summary> /// Invoke a synchronization having the specified options. It is initiated on a background thread and the current thread /// is immediately returned. /// </summary> /// <param name="syncOptions">An object containing settings for the synchronization.</param> /// <returns>An instance of <see cref="HttpResponseMessage" />.</returns> /// <exception cref="System.Web.Http.HttpResponseException">Thrown when the caller does not have permission to start a /// synchronization.</exception> public HttpResponseMessage StartSync(SyncOptions syncOptions) { try { #region Check user authorization if (!Utils.IsAuthenticated) throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Forbidden)); IAlbum album = AlbumController.LoadAlbumInstance(syncOptions.AlbumIdToSynchronize, true, true, false); if (!Utils.IsUserAuthorized(SecurityActions.Synchronize, RoleController.GetGalleryServerRolesForUser(), syncOptions.AlbumIdToSynchronize, album.GalleryId, false, album.IsVirtualAlbum)) throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Forbidden)); #endregion syncOptions.SyncId = GetSyncId(); syncOptions.UserName = Utils.UserName; Task.Factory.StartNew(() => GalleryController.BeginSync(syncOptions), TaskCreationOptions.LongRunning); return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("Synchronization started...") }; } catch (Exception ex) { AppEventController.LogError(ex); throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError) { Content = Utils.GetExStringContent(ex), ReasonPhrase = "Server Error" }); } }