/// <summary>
 /// Upload bloom books in the specified folder to the bloom library.
 /// Folders that contain exactly one .htm file are interpreted as books and uploaded.
 /// Other folders are searched recursively for children that appear to be bloom books.
 /// The parent folder of a bloom book is searched for a .bloomContainer file and, if one is found,
 /// the book is treated as part of that collection (e.g., for determining vernacular language).
 /// If no collection is found there it uses whatever collection was last open, or the current default.
 /// N.B. The bulk upload process will go ahead and upload templates and books that are already on the server
 /// (over-writing the existing book) without informing the user.
 /// </summary>
 /// <param name="folder"></param>
 /// <param name="container"></param>
 /// <param name="excludeAudio"></param>
 /// <remarks>This method is triggered by starting Bloom with "upload" on the cmd line.</remarks>
 public void UploadFolder(string folder, ApplicationContainer container, bool excludeAudio = false)
 {
     if (!IsThisVersionAllowedToUpload())
     {
         var oldVersionMsg = LocalizationManager.GetString("PublishTab.Upload.OldVersion",
                                                           "Sorry, this version of Bloom Desktop is not compatible with the current version of BloomLibrary.org. Please upgrade to a newer version.");
         Console.WriteLine(oldVersionMsg);
     }
     if (!LogIn(Settings.Default.WebUserId, Settings.Default.WebPassword))
     {
         SIL.Reporting.ErrorReport.NotifyUserOfProblem("Could not log you in using user='******' and pwd='" + Settings.Default.WebPassword + "'." + System.Environment.NewLine +
                                                       "For some reason, from the command line, we cannot get these credentials out of Settings.Default. However if you place your command line arguments in the properties of the project in visual studio and run from there, it works. If you are already doing that and get this message, then try running Bloom normally (gui), go to publish, and make sure you are logged in. Then quit and try this again.");
         Console.WriteLine("\nFailed to login.");
         return;
     }
     using (var dlg = new BulkUploadProgressDlg())
     {
         var worker = new BackgroundWorker();
         worker.WorkerReportsProgress = true;
         worker.DoWork             += BackgroundUpload;
         worker.RunWorkerCompleted += (sender, args) =>
         {
             if (args.Error != null)
             {
                 throw args.Error;
             }
             dlg.Close();
         };
         worker.RunWorkerAsync(new object[] { folder, dlg, container, excludeAudio });
         dlg.ShowDialog();                 // waits until worker completed closes it.
     }
 }
Exemple #2
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);
            }
        }
Exemple #3
0
 /// <summary>
 /// Upload bloom books in the specified folder to the bloom library.
 /// Folders that contain exactly one .htm file are interpreted as books and uploaded.
 /// Other folders are searched recursively for children that appear to be bloom books.
 /// The parent folder of a bloom book is searched for a .bloomContainer file and, if one is found,
 /// the book is treated as part of that collection (e.g., for determining vernacular language).
 /// If no collection is found there it uses whatever collection was last open, or the current default.
 /// </summary>
 /// <param name="folder"></param>
 public void UploadFolder(string folder, ApplicationContainer container)
 {
     if (!LogIn(Settings.Default.WebUserId, Settings.Default.WebPassword))
     {
         Palaso.Reporting.ErrorReport.NotifyUserOfProblem("Could not log you in using user='******' and pwd='" + Settings.Default.WebPassword + "'." + System.Environment.NewLine +
                                                          "For some reason, from the command line, we cannot get these credentials out of Settings.Default. However if you place your command line arguments in the properties of the project in visual studio and run from there, it works. If you are already doing that and get this message, then try running Bloom normally (gui), go to publish, and make sure you are logged in. Then quit and try this again.");
         return;
     }
     using (var dlg = new BulkUploadProgressDlg())
     {
         var worker = new BackgroundWorker();
         worker.DoWork             += BackgroundUpload;
         worker.RunWorkerCompleted += (sender, args) =>
         {
             dlg.Close();
         };
         worker.RunWorkerAsync(new object[] { folder, dlg, container });
         dlg.ShowDialog();                 // waits until worker completed closes it.
     }
 }
        /// <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);
            }
        }