public LibraryModel(string pathToLibrary, CollectionSettings collectionSettings, //SendReceiver sendReceiver, BookSelection bookSelection, SourceCollectionsList sourceCollectionsList, BookCollection.Factory bookCollectionFactory, EditBookCommand editBookCommand, CreateFromSourceBookCommand createFromSourceBookCommand, BookServer bookServer, CurrentEditableCollectionSelection currentEditableCollectionSelection, BookThumbNailer thumbNailer, TeamCollectionManager tcManager) { _bookSelection = bookSelection; _pathToLibrary = pathToLibrary; _collectionSettings = collectionSettings; //_sendReceiver = sendReceiver; _sourceCollectionsList = sourceCollectionsList; _bookCollectionFactory = bookCollectionFactory; _editBookCommand = editBookCommand; _bookServer = bookServer; _currentEditableCollectionSelection = currentEditableCollectionSelection; _thumbNailer = thumbNailer; _tcManager = tcManager; createFromSourceBookCommand.Subscribe(CreateFromSourceBook); }
public CollectionModel(string pathToCollection, CollectionSettings collectionSettings, BookSelection bookSelection, SourceCollectionsList sourceCollectionsList, BookCollection.Factory bookCollectionFactory, EditBookCommand editBookCommand, CreateFromSourceBookCommand createFromSourceBookCommand, BookServer bookServer, CurrentEditableCollectionSelection currentEditableCollectionSelection, BookThumbNailer thumbNailer, TeamCollectionManager tcManager, BloomWebSocketServer webSocketServer, BookCollectionHolder bookCollectionHolder, LocalizationChangedEvent localizationChangedEvent) { _bookSelection = bookSelection; _pathToCollection = pathToCollection; _collectionSettings = collectionSettings; _sourceCollectionsList = sourceCollectionsList; _bookCollectionFactory = bookCollectionFactory; _editBookCommand = editBookCommand; _bookServer = bookServer; _currentEditableCollectionSelection = currentEditableCollectionSelection; _thumbNailer = thumbNailer; _tcManager = tcManager; _webSocketServer = webSocketServer; _bookCollectionHolder = bookCollectionHolder; _localizationChangedEvent = localizationChangedEvent; createFromSourceBookCommand.Subscribe(CreateFromSourceBook); }
/// <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); } }
// Called by autofac, which creates the one instance and registers it with the server. public TeamCollectionApi(CurrentEditableCollectionSelection currentBookCollectionSelection, CollectionSettings settings, BookSelection bookSelection, ITeamCollectionManager tcManager, BookServer bookServer, BloomWebSocketServer socketServer) { _currentBookCollectionSelection = currentBookCollectionSelection; _settings = settings; _tcManager = tcManager; _tcManager.CurrentCollection?.SetupMonitoringBehavior(); _bookSelection = bookSelection; _socketServer = socketServer; _bookServer = bookServer; TheOneInstance = this; }
public PublishModel(BookSelection bookSelection, PdfMaker pdfMaker, CurrentEditableCollectionSelection currentBookCollectionSelection, CollectionSettings collectionSettings, BookServer bookServer) { BookSelection = bookSelection; _pdfMaker = pdfMaker; //_pdfMaker.EngineChoice = collectionSettings.PdfEngineChoice; _currentBookCollectionSelection = currentBookCollectionSelection; ShowCropMarks = false; _collectionSettings = collectionSettings; _bookServer = bookServer; bookSelection.SelectionChanged += new EventHandler(OnBookSelectionChanged); BookletPortion = BookletPortions.BookletPages; }
public PublishModel(BookSelection bookSelection, PdfMaker pdfMaker, CurrentEditableCollectionSelection currentBookCollectionSelection, CollectionSettings collectionSettings, BookServer bookServer, BookThumbNailer thumbNailer) { BookSelection = bookSelection; _pdfMaker = pdfMaker; _pdfMaker.CompressPdf = true; // See http://issues.bloomlibrary.org/youtrack/issue/BL-3721. //_pdfMaker.EngineChoice = collectionSettings.PdfEngineChoice; _currentBookCollectionSelection = currentBookCollectionSelection; ShowCropMarks = false; _collectionSettings = collectionSettings; _bookServer = bookServer; _thumbNailer = thumbNailer; bookSelection.SelectionChanged += OnBookSelectionChanged; //we don't want to default anymore: BookletPortion = BookletPortions.BookletPages; }
public PublishModel(BookSelection bookSelection, PdfMaker pdfMaker, CurrentEditableCollectionSelection currentBookCollectionSelection, CollectionSettings collectionSettings, BookServer bookServer, BookThumbNailer thumbNailer, NavigationIsolator isolator) { BookSelection = bookSelection; _pdfMaker = pdfMaker; //_pdfMaker.EngineChoice = collectionSettings.PdfEngineChoice; _currentBookCollectionSelection = currentBookCollectionSelection; ShowCropMarks = false; _collectionSettings = collectionSettings; _bookServer = bookServer; _thumbNailer = thumbNailer; bookSelection.SelectionChanged += new EventHandler(OnBookSelectionChanged); _isoloator = isolator; //we don't want to default anymore: BookletPortion = BookletPortions.BookletPages; }
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; } }
/// <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); } }