示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        /// <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);
            }
        }
示例#4
0
 // 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;
 }
示例#5
0
 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;
 }
示例#6
0
 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;
 }
示例#7
0
 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;
 }
示例#8
0
        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;
            }
        }
示例#9
0
        /// <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);
            }
        }