/// <summary> /// Common routine used in normal upload and bulk upload. /// </summary> /// <param name="book"></param> /// <param name="progressBox"></param> /// <param name="publishView"></param> /// <param name="parseId"></param> /// <param name="invokeTarget"></param> /// <returns></returns> internal string FullUpload(Book.Book book, LogBox progressBox, PublishView publishView, out string parseId, Form invokeTarget = null) { var bookFolder = book.FolderPath; // Set this in the metadata so it gets uploaded. Do this in the background task as it can take some time. // These bits of data can't easily be set while saving the book because we save one page at a time // and they apply to the book as a whole. book.BookInfo.LanguageTableReferences = _parseClient.GetLanguagePointers(book.CollectionSettings.MakeLanguageUploadData(book.AllLanguages.ToArray())); book.BookInfo.PageCount = book.GetPages().Count(); book.BookInfo.Save(); progressBox.WriteStatus(LocalizationManager.GetString("PublishTab.Upload.MakingThumbnail", "Making thumbnail image...")); MakeThumbnail(book, 70, invokeTarget); MakeThumbnail(book, 256, invokeTarget); //the largest thumbnail I found on Amazon was 300px high. Prathambooks.org about the same. var uploadPdfPath = Path.Combine(bookFolder, Path.ChangeExtension(Path.GetFileName(bookFolder), ".pdf")); // If there is not already a locked preview in the book folder // (which we take to mean the user has created a customized one that he prefers), // make sure we have a current correct preview and then copy it to the book folder so it gets uploaded. if (!FileUtils.IsFileLocked(uploadPdfPath)) { progressBox.WriteStatus(LocalizationManager.GetString("PublishTab.Upload.MakingPdf", "Making PDF Preview...")); publishView.MakePublishPreview(); if (File.Exists(publishView.PdfPreviewPath)) { File.Copy(publishView.PdfPreviewPath, uploadPdfPath, true); } } string result = UploadBook(bookFolder, progressBox, out parseId); return(result); }
private MenuItem GenerateMenuItem() { var item = new MenuItem(); item.Header = Resources.DynamoViewMenuItemPublishTitle; var isEnabled = loadedParams.CurrentWorkspaceModel is HomeWorkspaceModel && startupParams.AuthProvider != null; item.IsEnabled = isEnabled; item.Click += (sender, args) => { var model = new PublishModel(startupParams.AuthProvider, startupParams.CustomNodeManager); model.MessageLogged += this.OnMessageLogged; var viewModel = new PublishViewModel(model) { CurrentWorkspaceModel = loadedParams.CurrentWorkspaceModel, Cameras = ConvertCameraData(loadedParams.BackgroundPreviewViewModel.GetCameraInformation()) }; var window = new PublishView(viewModel) { Owner = loadedParams.DynamoWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner }; window.ShowDialog(); model.MessageLogged -= this.OnMessageLogged; }; return(item); }
/// <summary> /// Handles the recursion through directories: if a folder looks like a Bloom book upload it; otherwise, try its children. /// Invisible folders like .hg are ignored. /// </summary> /// <param name="folder"></param> /// <param name="dlg"></param> /// <param name="container"></param> /// <param name="context"></param> private void UploadInternal(string folder, BulkUploadProgressDlg dlg, ApplicationContainer container, ref ProjectContext context) { if (Path.GetFileName(folder).StartsWith(".")) { return; // secret folder, probably .hg } if (Directory.GetFiles(folder, "*.htm").Count() == 1) { // Exactly one htm file, assume this is a bloom book folder. dlg.Progress.WriteMessage("Starting to upload " + folder); // Make sure the files we want to upload are up to date. // Unfortunately this requires making a book object, which requires making a ProjectContext, which must be created with the // proper parent book collection if possible. var parent = Path.GetDirectoryName(folder); var collectionPath = Directory.GetFiles(parent, "*.bloomCollection").FirstOrDefault(); if (collectionPath == null && context == null) { collectionPath = Settings.Default.MruProjects.Latest; } if (context == null || context.SettingsPath != collectionPath) { if (context != null) { context.Dispose(); } // optimise: creating a context seems to be quite expensive. Probably the only thing we need to change is // the collection. If we could update that in place...despite autofac being told it has lifetime scope...we would save some time. // Note however that it's not good enough to just store it in the project context. The one that is actually in // the autofac object (_scope in the ProjectContext) is used by autofac to create various objects, in particular, books. context = container.CreateProjectContext(collectionPath); } var server = context.BookServer; var book = server.GetBookFromBookInfo(new BookInfo(folder, true)); book.BringBookUpToDate(new NullProgress()); // Assemble the various arguments needed to make the objects normally involved in an upload. // We leave some constructor arguments not actually needed for this purpose null. var bookSelection = new BookSelection(); bookSelection.SelectBook(book); var currentEditableCollectionSelection = new CurrentEditableCollectionSelection(); if (collectionPath != null) { var collection = new BookCollection(collectionPath, BookCollection.CollectionType.SourceCollection, bookSelection); currentEditableCollectionSelection.SelectCollection(collection); } var publishModel = new PublishModel(bookSelection, new PdfMaker(), currentEditableCollectionSelection, null, server, _htmlThumbnailer); publishModel.PageLayout = book.GetLayout(); var view = new PublishView(publishModel, new SelectedTabChangedEvent(), new LocalizationChangedEvent(), this, null); string dummy; FullUpload(book, dlg.Progress, view, out dummy, dlg); return; } foreach (var sub in Directory.GetDirectories(folder)) { UploadInternal(sub, dlg, container, ref context); } }
internal string UploadOneBook(BookInstance book, LogBox progressBox, PublishView publishView, string[] languages, bool excludeNarrationAudio, bool excludeMusic, out string parseId) { using (var tempFolder = new TemporaryFolder(Path.Combine("BloomUpload", Path.GetFileName(book.FolderPath)))) { BookTransfer.PrepareBookForUpload(ref book, _publishModel.BookServer, tempFolder.FolderPath, progressBox); return(_transferrer.FullUpload(book, progressBox, publishView, languages, excludeNarrationAudio, excludeMusic, false, out parseId)); } }
/// <summary> /// Common routine used in normal upload and bulk upload. /// </summary> /// <param name="book"></param> /// <param name="progressBox"></param> /// <param name="publishView"></param> /// <param name="languages"></param> /// <param name="parseId"></param> /// <param name="excludeAudio"></param> /// <returns></returns> internal string FullUpload(Book.Book book, LogBox progressBox, PublishView publishView, string[] languages, out string parseId, bool excludeAudio = true) { var bookFolder = book.FolderPath; parseId = ""; // in case of early return // Set this in the metadata so it gets uploaded. Do this in the background task as it can take some time. // These bits of data can't easily be set while saving the book because we save one page at a time // and they apply to the book as a whole. book.BookInfo.LanguageTableReferences = _parseClient.GetLanguagePointers(book.CollectionSettings.MakeLanguageUploadData(languages)); book.BookInfo.PageCount = book.GetPages().Count(); book.BookInfo.Save(); progressBox.WriteStatus(LocalizationManager.GetString("PublishTab.Upload.MakingThumbnail", "Making thumbnail image...")); //the largest thumbnail I found on Amazon was 300px high. Prathambooks.org about the same. _thumbnailer.MakeThumbnailOfCover(book, 70); // this is a sacrificial one to prime the pump, to fix BL-2673 _thumbnailer.MakeThumbnailOfCover(book, 70); if (progressBox.CancelRequested) { return(""); } _thumbnailer.MakeThumbnailOfCover(book, 256); if (progressBox.CancelRequested) { return(""); } // It is possible the user never went back to the Collection tab after creating/updating the book, in which case // the 'normal' thumbnail never got created/updating. See http://issues.bloomlibrary.org/youtrack/issue/BL-3469. _thumbnailer.MakeThumbnailOfCover(book); if (progressBox.CancelRequested) { return(""); } var uploadPdfPath = UploadPdfPath(bookFolder); // If there is not already a locked preview in the book folder // (which we take to mean the user has created a customized one that he prefers), // make sure we have a current correct preview and then copy it to the book folder so it gets uploaded. if (!FileUtils.IsFileLocked(uploadPdfPath)) { progressBox.WriteStatus(LocalizationManager.GetString("PublishTab.Upload.MakingPdf", "Making PDF Preview...")); publishView.MakePublishPreview(); if (RobustFile.Exists(publishView.PdfPreviewPath)) { RobustFile.Copy(publishView.PdfPreviewPath, uploadPdfPath, true); } } if (progressBox.CancelRequested) { return(""); } return(UploadBook(bookFolder, progressBox, out parseId, Path.GetFileName(uploadPdfPath), excludeAudio)); }
internal string UploadOneBook(BookInstance book, LogBox progressBox, PublishView publishView, bool excludeMusic, out string parseId) { using (var tempFolder = new TemporaryFolder(Path.Combine("BloomUpload", Path.GetFileName(book.FolderPath)))) { BookUpload.PrepareBookForUpload(ref book, _publishModel.BookServer, tempFolder.FolderPath, progressBox); var bookParams = new BookUploadParameters { ExcludeMusic = excludeMusic, PreserveThumbnails = false, }; return(_uploader.FullUpload(book, progressBox, publishView, bookParams, out parseId)); } }
private MenuItem GenerateMenuItem() { MenuItem item = new MenuItem(); item.Header = Resources.DynamoViewMenuItemPublishTitle; var isEnabled = publishViewModel.CurrentWorkspaceModel is HomeWorkspaceModel && publishModel.HasAuthProvider; item.IsEnabled = isEnabled; item.Click += (sender, args) => { PublishView publishWindow = new PublishView(publishViewModel); publishWindow.ShowDialog(); }; return(item); }
internal void Show() { View = new PublishView(); View.Presenter = this; View.ShowDialog(); }
private void UploadBookInternal(IProgress progress, ApplicationContainer container, BookUploadParameters uploadParams, ref ProjectContext context) { progress.WriteMessageWithColor("Cyan", "Starting to upload " + uploadParams.Folder); // Make sure the files we want to upload are up to date. // Unfortunately this requires making a book object, which requires making a ProjectContext, which must be created with the // proper parent book collection if possible. var parent = Path.GetDirectoryName(uploadParams.Folder); var collectionPath = Directory.GetFiles(parent, "*.bloomCollection").FirstOrDefault(); if (collectionPath == null || !RobustFile.Exists(collectionPath)) { progress.WriteError("Skipping book because no collection file was found in its parent directory."); return; } _collectionFoldersUploaded.Add(collectionPath); // Compute the book hash file and compare it to the existing one for bulk upload. var currentHashes = BookUpload.HashBookFolder(uploadParams.Folder); progress.WriteMessage(currentHashes); var pathToLocalHashInfoFromLastUpload = Path.Combine(uploadParams.Folder, HashInfoFromLastUpload); if (!uploadParams.ForceUpload) { var canSkip = false; if (Program.RunningUnitTests) { canSkip = _singleBookUploader.CheckAgainstLocalHashfile(currentHashes, pathToLocalHashInfoFromLastUpload); } else { canSkip = _singleBookUploader.CheckAgainstHashFileOnS3(currentHashes, uploadParams.Folder, progress); RobustFile.WriteAllText(pathToLocalHashInfoFromLastUpload, currentHashes); // ensure local copy is saved } if (canSkip) { // local copy of hashes file is identical or has been saved progress.WriteMessageWithColor("green", $"Skipping '{Path.GetFileName(uploadParams.Folder)}' because it has not changed since being uploaded."); ++_booksSkipped; return; // skip this one; we already uploaded it earlier. } } // save local copy of hashes file: it will be uploaded with the other book files RobustFile.WriteAllText(pathToLocalHashInfoFromLastUpload, currentHashes); if (context == null || context.SettingsPath != collectionPath) { context?.Dispose(); // optimise: creating a context seems to be quite expensive. Probably the only thing we need to change is // the collection. If we could update that in place...despite autofac being told it has lifetime scope...we would save some time. // Note however that it's not good enough to just store it in the project context. The one that is actually in // the autofac object (_scope in the ProjectContext) is used by autofac to create various objects, in particular, books. context = container.CreateProjectContext(collectionPath); Program.SetProjectContext(context); } var server = context.BookServer; var bookInfo = new BookInfo(uploadParams.Folder, true); var book = server.GetBookFromBookInfo(bookInfo); book.BringBookUpToDate(new NullProgress()); bookInfo.Bookshelf = book.CollectionSettings.DefaultBookshelf; var bookshelfName = String.IsNullOrWhiteSpace(book.CollectionSettings.DefaultBookshelf) ? "(none)" : book.CollectionSettings.DefaultBookshelf; progress.WriteMessage($"Bookshelf is '{bookshelfName}'"); // Assemble the various arguments needed to make the objects normally involved in an upload. // We leave some constructor arguments not actually needed for this purpose null. var bookSelection = new BookSelection(); bookSelection.SelectBook(book); var currentEditableCollectionSelection = new CurrentEditableCollectionSelection(); var collection = new BookCollection(collectionPath, BookCollection.CollectionType.SourceCollection, bookSelection); currentEditableCollectionSelection.SelectCollection(collection); var publishModel = new PublishModel(bookSelection, new PdfMaker(), currentEditableCollectionSelection, context.Settings, server, _thumbnailer); publishModel.PageLayout = book.GetLayout(); var view = new PublishView(publishModel, new SelectedTabChangedEvent(), new LocalizationChangedEvent(), _singleBookUploader, null, null, null, null); var blPublishModel = new BloomLibraryPublishModel(_singleBookUploader, book, publishModel); string dummy; // Normally we let the user choose which languages to upload. Here, just the ones that have complete information. var langDict = book.AllPublishableLanguages(); var languagesToUpload = langDict.Keys.Where(l => langDict[l]).ToList(); if (!string.IsNullOrEmpty(book.CollectionSettings.SignLanguageIso639Code) && BookUpload.GetVideoFilesToInclude(book).Any()) { languagesToUpload.Insert(0, book.CollectionSettings.SignLanguageIso639Code); } if (blPublishModel.MetadataIsReadyToPublish && (languagesToUpload.Any() || blPublishModel.OkToUploadWithNoLanguages)) { if (blPublishModel.BookIsAlreadyOnServer) { var msg = $"Overwriting the copy of {uploadParams.Folder} on the server..."; progress.WriteWarning(msg); } using (var tempFolder = new TemporaryFolder(Path.Combine("BloomUpload", Path.GetFileName(book.FolderPath)))) { BookUpload.PrepareBookForUpload(ref book, server, tempFolder.FolderPath, progress); uploadParams.LanguagesToUpload = languagesToUpload.ToArray(); _singleBookUploader.FullUpload(book, progress, view, uploadParams, out dummy); } progress.WriteMessageWithColor("Green", "{0} has been uploaded", uploadParams.Folder); if (blPublishModel.BookIsAlreadyOnServer) { ++_booksUpdated; } else { ++_newBooksUploaded; } } else { // report to the user why we are not uploading their book var reason = blPublishModel.GetReasonForNotUploadingBook(); progress.WriteError("{0} was not uploaded. {1}", uploadParams.Folder, reason); ++_booksWithErrors; } }
internal string UploadOneBook(BookInstance book, LogBox progressBox, PublishView publishView, string[] languages, out string parseId) { return(_transferrer.FullUpload(book, progressBox, publishView, languages, out parseId)); }
/// <summary> /// Handles the recursion through directories: if a folder looks like a Bloom book upload it; otherwise, try its children. /// Invisible folders like .hg are ignored. /// </summary> /// <param name="folder"></param> /// <param name="dlg"></param> /// <param name="container"></param> /// <param name="excludeAudio"></param> /// <param name="alreadyUploaded"></param> /// <param name="context"></param> private void UploadInternal(string folder, BulkUploadProgressDlg dlg, ApplicationContainer container, bool excludeAudio, string[] alreadyUploaded, ref ProjectContext context) { var lastFolderPart = Path.GetFileName(folder); if (lastFolderPart != null && lastFolderPart.StartsWith(".")) { return; // secret folder, probably .hg } if (Directory.GetFiles(folder, "*.htm").Length == 1) { if (alreadyUploaded.Contains(folder)) { return; // skip this one; we already successfully uploaded it at some point } // Exactly one htm file, assume this is a bloom book folder. dlg.Progress.WriteMessage("Starting to upload " + folder); // Make sure the files we want to upload are up to date. // Unfortunately this requires making a book object, which requires making a ProjectContext, which must be created with the // proper parent book collection if possible. var parent = Path.GetDirectoryName(folder); var collectionPath = Directory.GetFiles(parent, "*.bloomCollection").FirstOrDefault(); if (collectionPath == null) { collectionPath = Settings.Default.MruProjects.Latest; } if (collectionPath == null) { throw new ApplicationException("Collection not found in this or parent directory."); } if (context == null || context.SettingsPath != collectionPath) { context?.Dispose(); // optimise: creating a context seems to be quite expensive. Probably the only thing we need to change is // the collection. If we could update that in place...despite autofac being told it has lifetime scope...we would save some time. // Note however that it's not good enough to just store it in the project context. The one that is actually in // the autofac object (_scope in the ProjectContext) is used by autofac to create various objects, in particular, books. context = container.CreateProjectContext(collectionPath); Program.SetProjectContext(context); } var server = context.BookServer; var bookInfo = new BookInfo(folder, true); bookInfo.BookshelfList = GetBookshelfName(folder); var book = server.GetBookFromBookInfo(bookInfo); book.BringBookUpToDate(new NullProgress()); // Assemble the various arguments needed to make the objects normally involved in an upload. // We leave some constructor arguments not actually needed for this purpose null. var bookSelection = new BookSelection(); bookSelection.SelectBook(book); var currentEditableCollectionSelection = new CurrentEditableCollectionSelection(); var collection = new BookCollection(collectionPath, BookCollection.CollectionType.SourceCollection, bookSelection); currentEditableCollectionSelection.SelectCollection(collection); var publishModel = new PublishModel(bookSelection, new PdfMaker(), currentEditableCollectionSelection, context.Settings, server, _thumbnailer, null); publishModel.PageLayout = book.GetLayout(); var view = new PublishView(publishModel, new SelectedTabChangedEvent(), new LocalizationChangedEvent(), this, null, null, null); var blPublishModel = new BloomLibraryPublishModel(this, book); string dummy; // Normally we let the user choose which languages to upload. Here, just the ones that have complete information. var langDict = book.AllLanguages; var languagesToUpload = langDict.Keys.Where(l => langDict[l]).ToArray(); if (blPublishModel.MetadataIsReadyToPublish && (languagesToUpload.Any() || blPublishModel.OkToUploadWithNoLanguages)) { if (blPublishModel.BookIsAlreadyOnServer) { var msg = "Apparently this book is already on the server. Overwriting..."; ReportToLogBoxAndLogger(dlg.Progress, folder, msg); } FullUpload(book, dlg.Progress, view, languagesToUpload, out dummy, excludeAudio); AppendBookToUploadLogFile(folder); } else { // report to the user why we are not uploading their book ReportToLogBoxAndLogger(dlg.Progress, folder, blPublishModel.GetReasonForNotUploadingBook()); } return; } foreach (var sub in Directory.GetDirectories(folder)) { UploadInternal(sub, dlg, container, excludeAudio, alreadyUploaded, ref context); } }
//autofac uses this public WorkspaceView(WorkspaceModel model, Control libraryView, EditingView.Factory editingViewFactory, PublishView.Factory pdfViewFactory, CollectionSettingsDialog.Factory settingsDialogFactory, EditBookCommand editBookCommand, SendReceiveCommand sendReceiveCommand, SelectedTabAboutToChangeEvent selectedTabAboutToChangeEvent, SelectedTabChangedEvent selectedTabChangedEvent, LocalizationChangedEvent localizationChangedEvent, FeedbackDialog.Factory feedbackDialogFactory, ProblemReporterDialog.Factory problemReportDialogFactory, //ChorusSystem chorusSystem, LocalizationManager localizationManager ) { _model = model; _settingsDialogFactory = settingsDialogFactory; _selectedTabAboutToChangeEvent = selectedTabAboutToChangeEvent; _selectedTabChangedEvent = selectedTabChangedEvent; _localizationChangedEvent = localizationChangedEvent; _feedbackDialogFactory = feedbackDialogFactory; _problemReportDialogFactory = problemReportDialogFactory; //_chorusSystem = chorusSystem; _localizationManager = localizationManager; _model.UpdateDisplay += new System.EventHandler(OnUpdateDisplay); InitializeComponent(); _checkForNewVersionMenuItem.Visible = SIL.PlatformUtilities.Platform.IsWindows; _toolStrip.Renderer = new NoBorderToolStripRenderer(); //we have a number of buttons which don't make sense for the remote (therefore vulnerable) low-end user //_settingsLauncherHelper.CustomSettingsControl = _toolStrip; _settingsLauncherHelper.ManageComponent(_settingsButton); //NB: the rest of these aren't really settings, but we're using that feature to simplify this menu down to what makes sense for the easily-confused user _settingsLauncherHelper.ManageComponent(_openCreateCollectionButton); _settingsLauncherHelper.ManageComponent(_keyBloomConceptsMenuItem); _settingsLauncherHelper.ManageComponent(_makeASuggestionMenuItem); _settingsLauncherHelper.ManageComponent(_webSiteMenuItem); _settingsLauncherHelper.ManageComponent(_showLogMenuItem); _settingsLauncherHelper.ManageComponent(_releaseNotesMenuItem); _settingsLauncherHelper.ManageComponent(_divider2); _settingsLauncherHelper.ManageComponent(_divider3); _settingsLauncherHelper.ManageComponent(_divider4); OnSettingsProtectionChanged(this, null); //initial setup SettingsProtectionSettings.Default.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(OnSettingsProtectionChanged); _uiLanguageMenu.Visible = true; _settingsLauncherHelper.ManageComponent(_uiLanguageMenu); editBookCommand.Subscribe(OnEditBook); sendReceiveCommand.Subscribe(OnSendReceive); //Cursor = Cursors.AppStarting; Application.Idle += new EventHandler(Application_Idle); Text = _model.ProjectName; //SetupTabIcons(); // // _collectionView // this._collectionView = (LibraryView)libraryView; this._collectionView.Dock = System.Windows.Forms.DockStyle.Fill; // // _editingView // this._editingView = editingViewFactory(); this._editingView.Dock = System.Windows.Forms.DockStyle.Fill; // // _pdfView // this._publishView = pdfViewFactory(); this._publishView.Dock = System.Windows.Forms.DockStyle.Fill; _collectionTab.Tag = _collectionView; _publishTab.Tag = _publishView; _editTab.Tag = _editingView; this._collectionTab.Text = _collectionView.CollectionTabLabel; SetTabVisibility(_publishTab, false); SetTabVisibility(_editTab, false); // if (Program.StartUpWithFirstOrNewVersionBehavior) // { // _tabStrip.SelectedTab = _infoTab; // SelectPage(_infoView); // } // else // { _tabStrip.SelectedTab = _collectionTab; SelectPage(_collectionView); // } if (SIL.PlatformUtilities.Platform.IsMono) { // Without this adjustment, we lose some controls on smaller resolutions. AdjustToolPanelLocation(true); // in mono auto-size causes the height of the tab strip to be too short _tabStrip.AutoSize = false; } SetupUiLanguageMenu(); _viewInitialized = false; }
/// <summary> /// Common routine used in normal upload and bulk upload. /// </summary> internal string FullUpload(Book.Book book, IProgress progress, PublishView publishView, BookUploadParameters bookParams, out string parseId) { book.Storage.CleanupUnusedSupportFiles(isForPublish: false); // we are publishing, but this is the real folder not a copy, so play safe. var bookFolder = book.FolderPath; parseId = ""; // in case of early return // Set this in the metadata so it gets uploaded. Do this in the background task as it can take some time. // These bits of data can't easily be set while saving the book because we save one page at a time // and they apply to the book as a whole. book.BookInfo.LanguageTableReferences = ParseClient.GetLanguagePointers(book.BookData.MakeLanguageUploadData(bookParams.LanguagesToUpload)); book.BookInfo.PageCount = book.GetPages().Count(); book.BookInfo.Save(); // If the caller wants to preserve existing thumbnails, recreate them only if one or more of them do not exist. var thumbnailsExist = File.Exists(Path.Combine(bookFolder, "thumbnail-70.png")) && File.Exists(Path.Combine(bookFolder, "thumbnail-256.png")) && File.Exists(Path.Combine(bookFolder, "thumbnail.png")); if (!bookParams.PreserveThumbnails || !thumbnailsExist) { var thumbnailMsg = LocalizationManager.GetString("PublishTab.Upload.MakingThumbnail", "Making thumbnail image..."); progress.WriteStatus(thumbnailMsg); //the largest thumbnail I found on Amazon was 300px high. Prathambooks.org about the same. _thumbnailer.MakeThumbnailOfCover(book, 70); // this is a sacrificial one to prime the pump, to fix BL-2673 _thumbnailer.MakeThumbnailOfCover(book, 70); if (progress.CancelRequested) { return(""); } _thumbnailer.MakeThumbnailOfCover(book, 256); if (progress.CancelRequested) { return(""); } // It is possible the user never went back to the Collection tab after creating/updating the book, in which case // the 'normal' thumbnail never got created/updating. See http://issues.bloomlibrary.org/youtrack/issue/BL-3469. _thumbnailer.MakeThumbnailOfCover(book); if (progress.CancelRequested) { return(""); } } var uploadPdfPath = UploadPdfPath(bookFolder); // If there is not already a locked preview in the book folder // (which we take to mean the user has created a customized one that he prefers), // make sure we have a current correct preview and then copy it to the book folder so it gets uploaded. if (!FileHelper.IsLocked(uploadPdfPath)) { var pdfMsg = LocalizationManager.GetString("PublishTab.Upload.MakingPdf", "Making PDF Preview..."); progress.WriteStatus(pdfMsg); publishView.MakePDFForUpload(progress); if (RobustFile.Exists(publishView.PdfPreviewPath)) { RobustFile.Copy(publishView.PdfPreviewPath, uploadPdfPath, true); } else { return(""); // no PDF, no upload (See BL-6719) } } if (progress.CancelRequested) { return(""); } return(UploadBook(bookFolder, progress, out parseId, Path.GetFileName(uploadPdfPath), GetAudioFilesToInclude(book, bookParams.ExcludeNarrationAudio, bookParams.ExcludeMusic), GetVideoFilesToInclude(book), bookParams.LanguagesToUpload, book.CollectionSettings)); }
public BloomLibraryUploadControl(PublishView parentView, BloomLibraryPublishModel model, IBloomWebSocketServer webSocketServer) { _model = model; _parentView = parentView; _webSocketServer = webSocketServer; InitializeComponent(); _originalLoginText = _loginLink.Text; // Before anything might modify it (but after InitializeComponent creates it). _titleLabel.Text = _model.Title; _uploadSource.SelectedIndex = 0; _progressBox.ShowDetailsMenuItem = true; _progressBox.ShowCopyToClipboardMenuItem = true; _progressBox.LinkClicked += _progressBox_LinkClicked; _okToUpload = _model.MetadataIsReadyToPublish; // See if saved credentials work. try { _model.LogIn(); } catch (Exception e) { LogAndInformButDontReportFailureToConnectToServer(e); } CommonApi.NotifyLogin(() => { this.Invoke((Action)(UpdateDisplay)); ; }); switch (_model.LicenseType) { case LicenseState.CreativeCommons: _creativeCommonsLink.Text = _model.LicenseToken; _usingNotesSuggestion = false; if (string.IsNullOrWhiteSpace(_model.LicenseRights)) { _licenseNotesLabel.Hide(); } else { _licenseNotesLabel.Text = LocalizationManager.GetString("PublishTab.Upload.AdditionalRequests", "Additional Requests: ") + _model.LicenseRights; } break; case LicenseState.Null: _usingCcControls = false; _licenseNotesLabel.Text = LocalizationManager.GetString("PublishTab.Upload.AllReserved", "All rights reserved (Contact the Copyright holder for any permissions.)"); if (!string.IsNullOrWhiteSpace(_model.LicenseRights)) { _licenseNotesLabel.Text += Environment.NewLine + _model.LicenseRights; } _licenseSuggestion.Text = LocalizationManager.GetString("PublishTab.Upload.SuggestAssignCC", "Suggestion: Assigning a Creative Commons License makes it easy for you to clearly grant certain permissions to everyone."); break; case LicenseState.Custom: // This must be custom a license (with non-blank rights...actually, // currently, the palaso dialog will not allow a custom license with no rights statement). _usingCcControls = false; _licenseNotesLabel.Text = _model.LicenseRights; _licenseSuggestion.Text = LocalizationManager.GetString("PublishTab.Upload.SuggestChangeCC", "Suggestion: Creative Commons Licenses make it much easier for others to use your book, even if they aren't fluent in the language of your custom license."); break; default: throw new ApplicationException("Unknown License state."); } _copyrightLabel.Text = _model.Copyright; _creditsLabel.Text = _model.Credits; _summaryBox.Text = _model.Summary; if (!TeamCollectionApi.TheOneInstance.CanEditBook()) { _summaryBox.Enabled = false; _summaryOptionalLabel.Text = LocalizationManager.GetString("TeamCollection.OptionalCheckOutEdit", "optional--check out to edit"); } UpdateFeaturesCheckBoxesDisplay(); var allLanguages = _model.AllLanguages; foreach (var lang in allLanguages.Keys) { var checkBox = new CheckBox(); checkBox.UseMnemonic = false; checkBox.Text = _model.PrettyLanguageName(lang); if (allLanguages[lang]) { checkBox.Checked = true; } else { checkBox.Text += @" " + LocalizationManager.GetString("PublishTab.Upload.IncompleteTranslation", "(incomplete translation)", "This is added after the language name, in order to indicate that some parts of the book have not been translated into this language yet."); } // Disable clicking on languages that have been selected for display in this book. // See https://issues.bloomlibrary.org/youtrack/issue/BL-7166. if (lang == _model.Book.BookData.Language1.Iso639Code || lang == _model.Book.Language2IsoCode || lang == _model.Book.Language3IsoCode) { checkBox.Checked = true; // even if partial checkBox.AutoCheck = false; } checkBox.Margin = _checkBoxMargin; checkBox.AutoSize = true; checkBox.Tag = lang; checkBox.CheckStateChanged += delegate(object sender, EventArgs args) { _langsLabel.ForeColor = LanguagesOkToUpload ? Color.Black : Color.Red; if (_okToUploadDependsOnLangsChecked) { _okToUpload = LanguagesOkToUpload; UpdateDisplay(); } }; _languagesFlow.Controls.Add(checkBox); } UpdateAudioCheckBoxDisplay(); _summaryOptionalLabel.Left = _summaryBox.Right - _summaryOptionalLabel.Width; // right-align these (even if localization changes their width) // Copyright info is not required if the book has been put in the public domain // or if we are publishing from a source collection and we have original copyright info if (!_model.IsBookPublicDomain && !_model.HasOriginalCopyrightInfoInSourceCollection) { RequireValue(_copyrightLabel); } RequireValue(_titleLabel); if (BookUpload.UseSandbox) { var oldTextWidth = TextRenderer.MeasureText(_uploadButton.Text, _uploadButton.Font).Width; // Do not localize the following string (https://issues.bloomlibrary.org/youtrack/issue/BL-7383). _uploadButton.Text = "Upload (to dev.bloomlibrary.org)"; var neededWidth = TextRenderer.MeasureText(_uploadButton.Text, _uploadButton.Font).Width; _uploadButton.Width += neededWidth - oldTextWidth; } // After considering all the factors except whether any languages are selected, // if we can upload at this point, whether we can from here on depends on whether one is checked. // This test needs to come after evaluating everything else uploading depends on (except login) _okToUploadDependsOnLangsChecked = _okToUpload; if (allLanguages.Keys.Any()) { return; } // No languages in the book have complete data const string space = " "; _langsLabel.Text += space + LocalizationManager.GetString("PublishTab.Upload.NoLangsFound", "(None found)"); if (!_model.OkToUploadWithNoLanguages) { _langsLabel.ForeColor = Color.Red; _okToUpload = false; } }
/// <summary> /// Common routine used in normal upload and bulk upload. /// </summary> internal string FullUpload(Book.Book book, IProgress progress, PublishView publishView, BookUploadParameters bookParams, out string parseId) { // this (isForPublish:true) is dangerous and the product of much discussion. // See "finally" block later to see that we put branding files back book.Storage.CleanupUnusedSupportFiles(isForPublish: true); try { var bookFolder = book.FolderPath; parseId = ""; // in case of early return var languagesToUpload = book.BookInfo.PublishSettings.BloomLibrary.TextLangs.IncludedLanguages().ToArray(); // When initializing, we may set the collection's sign language to IncludeByDefault so the checkbox on the publish screen // gets set by default. Also, videos could have been removed since the user last visited the publish screen (e.g. bulk upload). // So we need to make sure we have videos before including the sign language. if (book.HasSignLanguageVideos()) { languagesToUpload = languagesToUpload.Union(book.BookInfo.PublishSettings.BloomLibrary.SignLangs.IncludedLanguages()).ToArray(); } // Set this in the metadata so it gets uploaded. Do this in the background task as it can take some time. // These bits of data can't easily be set while saving the book because we save one page at a time // and they apply to the book as a whole. book.BookInfo.LanguageTableReferences = ParseClient.GetLanguagePointers(book.BookData.MakeLanguageUploadData(languagesToUpload)); book.BookInfo.PageCount = book.GetPages().Count(); book.BookInfo.Save(); // If the caller wants to preserve existing thumbnails, recreate them only if one or more of them do not exist. var thumbnailsExist = File.Exists(Path.Combine(bookFolder, "thumbnail-70.png")) && File.Exists(Path.Combine(bookFolder, "thumbnail-256.png")) && File.Exists(Path.Combine(bookFolder, "thumbnail.png")); if (!bookParams.PreserveThumbnails || !thumbnailsExist) { var thumbnailMsg = LocalizationManager.GetString("PublishTab.Upload.MakingThumbnail", "Making thumbnail image..."); progress.WriteStatus(thumbnailMsg); //the largest thumbnail I found on Amazon was 300px high. Prathambooks.org about the same. _thumbnailer.MakeThumbnailOfCover(book, 70); // this is a sacrificial one to prime the pump, to fix BL-2673 _thumbnailer.MakeThumbnailOfCover(book, 70); if (progress.CancelRequested) { return(""); } _thumbnailer.MakeThumbnailOfCover(book, 256); if (progress.CancelRequested) { return(""); } // It is possible the user never went back to the Collection tab after creating/updating the book, in which case // the 'normal' thumbnail never got created/updating. See http://issues.bloomlibrary.org/youtrack/issue/BL-3469. _thumbnailer.MakeThumbnailOfCover(book); if (progress.CancelRequested) { return(""); } } var uploadPdfPath = UploadPdfPath(bookFolder); var videoFiles = GetVideoFilesToInclude(book); bool hasVideo = videoFiles.Any(); if (hasVideo) { var skipPdfMsg = LocalizationManager.GetString("PublishTab.Upload.SkipMakingPdf", "Skipping PDF because this book has video"); progress.WriteStatus(skipPdfMsg); } else { // If there is not already a locked preview in the book folder // (which we take to mean the user has created a customized one that he prefers), // make sure we have a current correct preview and then copy it to the book folder so it gets uploaded. if (!FileHelper.IsLocked(uploadPdfPath)) { var pdfMsg = LocalizationManager.GetString("PublishTab.Upload.MakingPdf", "Making PDF Preview..."); progress.WriteStatus(pdfMsg); publishView.MakePDFForUpload(progress); if (RobustFile.Exists(publishView.PdfPreviewPath)) { RobustFile.Copy(publishView.PdfPreviewPath, uploadPdfPath, true); } else { return(""); // no PDF, no upload (See BL-6719) } } } if (progress.CancelRequested) { return(""); } return(UploadBook(bookFolder, progress, out parseId, hasVideo ? null : Path.GetFileName(uploadPdfPath), GetAudioFilesToInclude(book, bookParams.ExcludeMusic), videoFiles, languagesToUpload, book.CollectionSettings)); } finally { // Put back all the branding files which we removed above in the call to CleanupUnusedSupportFiles() book.UpdateSupportFiles(); // NB: alternatively, we considered refactoring CleanupUnusedSupportFiles() to give us a list of files // to not upload. } }
//autofac uses this public WorkspaceView(WorkspaceModel model, Control libraryView, EditingView.Factory editingViewFactory, PublishView.Factory pdfViewFactory, CollectionSettingsDialog.Factory settingsDialogFactory, EditBookCommand editBookCommand, SendReceiveCommand sendReceiveCommand, SelectedTabAboutToChangeEvent selectedTabAboutToChangeEvent, SelectedTabChangedEvent selectedTabChangedEvent, FeedbackDialog.Factory feedbackDialogFactory, ChorusSystem chorusSystem, Sparkle sparkleApplicationUpdater, LocalizationManager localizationManager ) { _model = model; _settingsDialogFactory = settingsDialogFactory; _selectedTabAboutToChangeEvent = selectedTabAboutToChangeEvent; _selectedTabChangedEvent = selectedTabChangedEvent; _feedbackDialogFactory = feedbackDialogFactory; _chorusSystem = chorusSystem; _sparkleApplicationUpdater = sparkleApplicationUpdater; _localizationManager = localizationManager; _model.UpdateDisplay += new System.EventHandler(OnUpdateDisplay); InitializeComponent(); #if !DEBUG _sparkleApplicationUpdater.CheckOnFirstApplicationIdle(); #endif _toolStrip.Renderer = new NoBorderToolStripRenderer(); //we have a number of buttons which don't make sense for the remote (therefore vulnerable) low-end user //_settingsLauncherHelper.CustomSettingsControl = _toolStrip; _settingsLauncherHelper.ManageComponent(_settingsButton); //NB: the rest of these aren't really settings, but we're using that feature to simplify this menu down to what makes sense for the easily-confused user _settingsLauncherHelper.ManageComponent(_openCreateCollectionButton); _settingsLauncherHelper.ManageComponent(deepBloomPaperToolStripMenuItem); _settingsLauncherHelper.ManageComponent(_makeASuggestionMenuItem); _settingsLauncherHelper.ManageComponent(_webSiteMenuItem); _settingsLauncherHelper.ManageComponent(_showLogMenuItem); _settingsLauncherHelper.ManageComponent(_releaseNotesMenuItem); _settingsLauncherHelper.ManageComponent(_divider2); _settingsLauncherHelper.ManageComponent(_divider3); _settingsLauncherHelper.ManageComponent(_divider4); OnSettingsProtectionChanged(this, null); //initial setup SettingsProtectionSettings.Default.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(OnSettingsProtectionChanged); _uiLanguageMenu.Visible = true; _settingsLauncherHelper.ManageComponent(_uiLanguageMenu); editBookCommand.Subscribe(OnEditBook); sendReceiveCommand.Subscribe(OnSendReceive); //Cursor = Cursors.AppStarting; Application.Idle += new EventHandler(Application_Idle); Text = _model.ProjectName; //SetupTabIcons(); // // _collectionView // this._collectionView = (LibraryView)libraryView; this._collectionView.Dock = System.Windows.Forms.DockStyle.Fill; // // _editingView // this._editingView = editingViewFactory(); this._editingView.Dock = System.Windows.Forms.DockStyle.Fill; // // _pdfView // this._publishView = pdfViewFactory(); this._publishView.Dock = System.Windows.Forms.DockStyle.Fill; _collectionTab.Tag = _collectionView; _publishTab.Tag = _publishView; _editTab.Tag = _editingView; this._collectionTab.Text = _collectionView.CollectionTabLabel; SetTabVisibility(_publishTab, false); SetTabVisibility(_editTab, false); // if (Program.StartUpWithFirstOrNewVersionBehavior) // { // _tabStrip.SelectedTab = _infoTab; // SelectPage(_infoView); // } // else // { _tabStrip.SelectedTab = _collectionTab; SelectPage(_collectionView); // } SetupUILanguageMenu(); }