private void RefreshPreview(EpubPublishUiSettings newSettings)
        {
            // We have seen some exceptions thrown during refresh that cause a pretty yellow
            // dialog box pop up informing the user, e.g., that the program couldn't find
            // "api/publish/epub/updatePreview".  Rather than confuse the user, we catch such
            // exceptions here and retry a limited number of times.
            // See https://issues.bloomlibrary.org/youtrack/issue/BL-6763.
            Exception exception = null;

            for (int i = 0; i < 3; ++i)
            {
                try
                {
                    if (UpdatePreview(newSettings, true))
                    {
                        _webSocketServer.SendString(kWebsocketContext, kWebsocketEventId_epubReady, _previewSrc);
                    }
                    return;
                }
                catch (Exception e)
                {
                    exception = e;                      // the original stack trace is rather important for post mortem debugging!
                }
            }
            // Notify the user gently that updating the ePUB preview failed.
            NonFatalProblem.Report(ModalIf.None, PassiveIf.All, "Something went wrong while making the ePUB preview.",
                                   "Updating the ePUB preview failed: " + exception.Message, exception);
        }
        public void GetEpubSettingsForCurrentBook(EpubPublishUiSettings epubPublishUiSettings)
        {
            var info = _bookSelection.CurrentSelection.BookInfo;

            epubPublishUiSettings.howToPublishImageDescriptions = info.MetaData.Epub_HowToPublishImageDescriptions;
            epubPublishUiSettings.removeFontSizes = info.MetaData.Epub_RemoveFontSizes;
        }
        public void UpdateAndSave(EpubPublishUiSettings newSettings, string path, bool force, WebSocketProgress progress = null)
        {
            bool succeeded;

            do
            {
                lock (this)
                {
                    succeeded = UpdatePreview(newSettings, force, progress);
                    if (succeeded)
                    {
                        EpubMaker.SaveEpub(path, _progress);
                        _webSocketServer.SendString(kWebsocketContext, kWebsocketEventId_epubReady, _previewSrc);
                    }
                }
            } while (!succeeded && !EpubMaker.AbortRequested);             // try until we get a complete epub, not interrupted by user changing something.
        }
        public bool UpdatePreview(EpubPublishUiSettings newSettings, bool force, WebSocketProgress progress = null)
        {
            _progress = progress ?? _standardProgress.WithL10NPrefix("PublishTab.Epub.");
            if (Program.RunningOnUiThread)
            {
                // There's some stuff inside this lock that has to run on the UI thread.
                // If we lock the UI thread here, we can deadlock the whole program.
                throw new ApplicationException(@"Must not attempt to make epubs on UI thread...will produce deadlocks");
            }

            lock (_epubMakerLock)
            {
                if (EpubMaker != null)
                {
                    EpubMaker.AbortRequested = false;
                }
                _stagingEpub = true;
            }

            // For some unknown reason, if the accessibility window is showing, some of the browser navigation
            // that is needed to accurately determine which content is visible simply doesn't happen.
            // It would be disconcerting if it popped to the top after we close it and reopen it.
            // So, we just close the window if it is showing when we do this. See BL-7807.
            // Except that opening the Ace Checker tab invokes this code path in a way that works without the
            // deadlock (or whatever causes the failure).  This call can be detected by the progress argument not
            // being null.  The Refresh button on the AccessibilityCheckWindow also uses this code path in the
            // same way, so the next two lines also allow that Refresh button to work.  See BL-9341 for why
            // the original fix is inadequate.
            if (progress == null)
            {
                AccessibilityChecker.AccessibilityCheckWindow.StaticClose();
            }

            try
            {
                _webSocketServer.SendString(kWebsocketContext, "startingEbookCreation", _previewSrc);

                var  htmlPath   = _bookSelection.CurrentSelection.GetPathHtmlFile();
                var  newVersion = Book.Book.ComputeHashForAllBookRelatedFiles(htmlPath);
                bool previewIsAlreadyCurrent;
                lock (_epubMakerLock)
                {
                    previewIsAlreadyCurrent = _desiredEpubSettings == newSettings && EpubMaker != null && newVersion == _bookVersion &&
                                              !EpubMaker.AbortRequested && !force;
                }

                if (previewIsAlreadyCurrent)
                {
                    SaveAsEpub();                    // just in case there's a race condition where we haven't already saved it.
                    return(true);                    // preview is already up to date.
                }

                _desiredEpubSettings = newSettings;

                // clear the obsolete preview, if any; this also ensures that when the new one gets done,
                // we will really be changing the src attr in the preview iframe so the display will update.
                _webSocketServer.SendEvent(kWebsocketContext, kWebsocketEventId_epubReady);
                _bookVersion = newVersion;
                ReportProgress(LocalizationManager.GetString("PublishTab.Epub.PreparingPreview", "Preparing Preview"));

                // This three-tries loop is an attempt to recover from a weird state the system sometimes gets into
                // where a browser won't navigate to a temporary page that the EpubMaker uses. I'm not sure it actually
                // helps, once the system gets into this state even a brand new browser seems to have the same problem.
                // Usually there will be no exception, and the loop breaks at the end of the first iteration.
                for (int i = 0; i < 3; i++)
                {
                    try
                    {
                        if (!PublishHelper.InPublishTab)
                        {
                            return(false);
                        }
                        _previewSrc = UpdateEpubControlContent();
                    }
                    catch (ApplicationException ex)
                    {
                        if (i >= 2)
                        {
                            throw;
                        }
                        ReportProgress("Something went wrong, trying again");
                        continue;
                    }

                    break;                     // normal case, no exception
                }

                lock (_epubMakerLock)
                {
                    if (EpubMaker.AbortRequested)
                    {
                        return(false);                        // the code that set the abort flag will request a new preview.
                    }
                }
            }
            finally
            {
                lock (_epubMakerLock)
                {
                    _stagingEpub = false;
                }
            }

            // Do pending save if the user requested it while the preview was still in progress.
            SaveAsEpub();
            ReportProgress(LocalizationManager.GetString("PublishTab.Epub.Done", "Done"));
            return(true);
        }
Exemple #5
0
        public bool UpdatePreview(EpubPublishUiSettings newSettings, bool force, WebSocketProgress progress = null)
        {
            _progress = progress ?? _standardProgress.WithL10NPrefix("PublishTab.Epub.");
            if (Program.RunningOnUiThread)
            {
                // There's some stuff inside this lock that has to run on the UI thread.
                // If we lock the UI thread here, we can deadlock the whole program.
                throw new ApplicationException(@"Must not attempt to make epubs on UI thread...will produce deadlocks");
            }

            lock (_epubMakerLock)
            {
                if (EpubMaker != null)
                {
                    EpubMaker.AbortRequested = false;
                }
                _stagingEpub = true;
            }

            try
            {
                _webSocketServer.SendString(kWebsocketContext, "startingEbookCreation", _previewSrc);

                var  htmlPath   = _bookSelection.CurrentSelection.GetPathHtmlFile();
                var  newVersion = Book.Book.MakeVersionCode(File.ReadAllText(htmlPath), htmlPath);
                bool previewIsAlreadyCurrent;
                lock (_epubMakerLock)
                {
                    previewIsAlreadyCurrent = _desiredEpubSettings == newSettings && EpubMaker != null && newVersion == _bookVersion &&
                                              !EpubMaker.AbortRequested && !force;
                }

                if (previewIsAlreadyCurrent)
                {
                    SaveAsEpub();                    // just in case there's a race condition where we haven't already saved it.
                    return(true);                    // preview is already up to date.
                }

                _desiredEpubSettings = newSettings;

                // clear the obsolete preview, if any; this also ensures that when the new one gets done,
                // we will really be changing the src attr in the preview iframe so the display will update.
                _webSocketServer.SendEvent(kWebsocketContext, kWebsocketEventId_epubReady);
                _bookVersion = newVersion;
                ReportProgress(LocalizationManager.GetString("PublishTab.Epub.PreparingPreview", "Preparing Preview"));

                // This three-tries loop is an attempt to recover from a weird state the system sometimes gets into
                // where a browser won't navigate to a temporary page that the EpubMaker uses. I'm not sure it actually
                // helps, once the system gets into this state even a brand new browser seems to have the same problem.
                // Usually there will be no exception, and the loop breaks at the end of the first iteration.
                for (int i = 0; i < 3; i++)
                {
                    try
                    {
                        if (!PublishHelper.InPublishTab)
                        {
                            return(false);
                        }
                        _previewSrc = UpdateEpubControlContent();
                    }
                    catch (ApplicationException ex)
                    {
                        if (i >= 2)
                        {
                            throw;
                        }
                        ReportProgress("Something went wrong, trying again");
                        continue;
                    }

                    break;                     // normal case, no exception
                }

                lock (_epubMakerLock)
                {
                    if (EpubMaker.AbortRequested)
                    {
                        return(false);                        // the code that set the abort flag will request a new preview.
                    }
                }
            }
            finally
            {
                lock (_epubMakerLock)
                {
                    _stagingEpub = false;
                }
            }

            // Do pending save if the user requested it while the preview was still in progress.
            SaveAsEpub();
            ReportProgress(LocalizationManager.GetString("PublishTab.Epub.Done", "Done"));
            return(true);
        }