public delegate EditingModel Factory();        //autofac uses this

        public EditingModel(BookSelection bookSelection, PageSelection pageSelection,
                            LanguageSettings languageSettings,
                            TemplateInsertionCommand templateInsertionCommand,
                            PageListChangedEvent pageListChangedEvent,
                            RelocatePageEvent relocatePageEvent,
                            BookRefreshEvent bookRefreshEvent,
                            DuplicatePageCommand duplicatePageCommand,
                            DeletePageCommand deletePageCommand,
                            SelectedTabChangedEvent selectedTabChangedEvent,
                            SelectedTabAboutToChangeEvent selectedTabAboutToChangeEvent,
                            LibraryClosing libraryClosingEvent,
                            LocalizationChangedEvent localizationChangedEvent,
                            CollectionSettings collectionSettings,
                            SendReceiver sendReceiver,
                            EnhancedImageServer server)
        {
            _bookSelection        = bookSelection;
            _pageSelection        = pageSelection;
            _languageSettings     = languageSettings;
            _duplicatePageCommand = duplicatePageCommand;
            _deletePageCommand    = deletePageCommand;
            _collectionSettings   = collectionSettings;
            _sendReceiver         = sendReceiver;
            _server = server;

            bookSelection.SelectionChanged      += new EventHandler(OnBookSelectionChanged);
            pageSelection.SelectionChanged      += new EventHandler(OnPageSelectionChanged);
            templateInsertionCommand.InsertPage += new EventHandler(OnInsertTemplatePage);

            bookRefreshEvent.Subscribe((book) => OnBookSelectionChanged(null, null));
            selectedTabChangedEvent.Subscribe(OnTabChanged);
            selectedTabAboutToChangeEvent.Subscribe(OnTabAboutToChange);
            duplicatePageCommand.Implementer = OnDuplicatePage;
            deletePageCommand.Implementer    = OnDeletePage;
            pageListChangedEvent.Subscribe(x => _view.UpdatePageList(false));
            relocatePageEvent.Subscribe(OnRelocatePage);
            libraryClosingEvent.Subscribe(o => SaveNow());
            localizationChangedEvent.Subscribe(o =>
            {
                //this is visible was added for https://jira.sil.org/browse/BL-267, where the edit tab has never been
                //shown so the view has never been full constructed, so we're not in a good state to do a refresh
                if (Visible)
                {
                    SaveNow();
                    _view.UpdateButtonLocalizations();
                    RefreshDisplayOfCurrentPage();
                    //_view.UpdateDisplay();
                    _view.UpdatePageList(false);
                    _view.UpdateTemplateList();
                }
                else if (_view != null)
                {
                    // otherwise changing UI language in Publish tab (for instance) won't update these localizations
                    _view.UpdateButtonLocalizations();
                }
            });
            _contentLanguages = new List <ContentLanguage>();
            _server.CurrentCollectionSettings = _collectionSettings;
            _server.CurrentBook = CurrentBook;
        }
        public void CanRetrieveContentOfFakeTempFile_ButOnlyUntilDisposed()
        {
            using (var server = CreateImageServer())
            {
                var html = @"<html ><head></head><body>here it is</body></html>";
                var dom  = new HtmlDom(html);
                dom.BaseForRelativePaths = _folder.Path.ToLocalhost();
                string url;
                using (var fakeTempFile = EnhancedImageServer.MakeSimulatedPageFileInBookFolder(dom))
                {
                    url = fakeTempFile.Key;
                    var transaction = new PretendRequestInfo(url);

                    // Execute
                    server.MakeReply(transaction);

                    // Verify
                    // Whitespace inserted by CreateHtml5StringFromXml seems to vary across versions and platforms.
                    // I would rather verify the actual output, but don't want this test to be fragile, and the
                    // main point is that we get a file with the DOM content.
                    Assert.That(transaction.ReplyContents,
                                Is.EqualTo(TempFileUtils.CreateHtml5StringFromXml(dom.RawDom)));
                }
                var transactionFail = new PretendRequestInfo(url);

                // Execute
                server.MakeReply(transactionFail);

                // Verify
                Assert.That(transactionFail.StatusCode, Is.EqualTo(404));
            }
        }
Exemple #3
0
        public static string GetString(EnhancedImageServer server, string endPoint, string query = "",
                                       ContentType returnType = ContentType.Text, EndpointHandler handler = null, string endOfUrlForTest = null)
        {
            if (handler != null)
            {
                server.RegisterEndpointHandler(endPoint, handler, true);
            }
            server.StartListening();
            var client = new WebClientWithTimeout
            {
                Timeout = 3000,
            };

            client.Headers[HttpRequestHeader.ContentType] = returnType == ContentType.Text ? "text/plain" : "application/json";

            if (endOfUrlForTest != null)
            {
                return(client.DownloadString(ServerBase.ServerUrlWithBloomPrefixEndingInSlash + "api/" + endOfUrlForTest));
            }
            else
            {
                if (!string.IsNullOrEmpty(query))
                {
                    query = "?" + query;
                }
                return(client.DownloadString(ServerBase.ServerUrlWithBloomPrefixEndingInSlash + "api/" + endPoint + query));
            }
        }
 public void Setup()
 {
     // as long as we're only using one, fixed port number, we need to prevent unit test runner
     // from running these tests in parallel.
     Monitor.Enter(_portMonitor);
     _server = new EnhancedImageServer(new BookSelection());
 }
 public void RegisterWithServer(EnhancedImageServer server)
 {
     // We could probably get away with using the server thread here, but the code interacts quite a bit with the
     // current book and other state.
     server.RegisterEndpointHandler("pageTemplates", HandleTemplatesRequest, true);
     // Being on the UI thread causes a deadlock on Linux/Mono.  See https://silbloom.myjetbrains.com/youtrack/issue/BL-3818.
     server.RegisterEndpointHandler("pageTemplateThumbnail", HandleThumbnailRequest, false);
 }
 private static string AdjustPossibleLocalHostPathToFilePath(string path)
 {
     if (!path.StartsWith("localhost/", StringComparison.InvariantCulture))
     {
         return(path);
     }
     return(EnhancedImageServer.LocalHostPathToFilePath(path));
 }
 public static void RegisterWithServer(EnhancedImageServer server)
 {
     server.RegisterEndpointHandler("help/.*", (request) =>
     {
         var topic = request.LocalPath().ToLowerInvariant().Replace("api/help", "");
         Show(Application.OpenForms.Cast <Form>().Last(), topic);
         //if this is called from a simple html anchor, we don't want the browser to do anything
         request.SucceededDoNotNavigate();
     });
 }
Exemple #8
0
 public static void RegisterWithServer(EnhancedImageServer server)
 {
     server.RegisterEndpointHandler("help/.*", (request) =>
     {
         var topic = request.LocalPath().Replace("api/help", "");
         Show(Application.OpenForms.Cast <Form>().Last(), topic);
         //if this is called from a simple html anchor, we don't want the browser to do anything
         request.ExternalLinkSucceeded();
     }, true);             // opening a form, definitely UI thread
 }
Exemple #9
0
        /// ------------------------------------------------------------------------------------
        public void Dispose()
        {
            _scope.Dispose();
            _scope = null;

            if (_httpServer != null)
            {
                _httpServer.Dispose();
            }
            _httpServer = null;
        }
        public void RegisterWithServer(EnhancedImageServer server)
        {
            server.RegisterEndpointHandler("audio/startRecord", HandleStartRecording);
            server.RegisterEndpointHandler("audio/endRecord", HandleEndRecord);
            server.RegisterEndpointHandler("audio/enableListenButton", HandleEnableListenButton);
            server.RegisterEndpointHandler("audio/deleteSegment", HandleDeleteSegment);
            server.RegisterEndpointHandler("audio/currentRecordingDevice", HandleCurrentRecordingDevice);
            server.RegisterEndpointHandler("audio/checkForSegment", HandleCheckForSegment);
            server.RegisterEndpointHandler("audio/devices", HandleAudioDevices);

            Debug.Assert(ServerBase.portForHttp > 0, "Need the server to be listening before this can be registered (BL-3337).");
        }
        public void RegisterWithServer(EnhancedImageServer server)
        {
            // I don't know for sure that these need to be on the UI thread, but that was the old default so keeping it for safety.
            server.RegisterEndpointHandler("audio/startRecord", HandleStartRecording, true);
            server.RegisterEndpointHandler("audio/endRecord", HandleEndRecord, true);
            server.RegisterEndpointHandler("audio/enableListenButton", HandleEnableListenButton, true);
            server.RegisterEndpointHandler("audio/deleteSegment", HandleDeleteSegment, true);
            server.RegisterEndpointHandler("audio/currentRecordingDevice", HandleCurrentRecordingDevice, true);
            server.RegisterEndpointHandler("audio/checkForSegment", HandleCheckForSegment, true);
            server.RegisterEndpointHandler("audio/devices", HandleAudioDevices, true);

            Debug.Assert(ServerBase.portForHttp > 0, "Need the server to be listening before this can be registered (BL-3337).");
        }
        public void Setup()
        {
            var bookSelection = new BookSelection();

            bookSelection.SelectBook(new Bloom.Book.Book());
            _server = new EnhancedImageServer(bookSelection);

            //needed to avoid a check in the server
            _server.CurrentCollectionSettings = new CollectionSettings();
            var controller = new ReadersApi(bookSelection);

            controller.RegisterWithServer(_server);
        }
Exemple #13
0
        private SimulatedPageFile MakeFinalHtmlForPdfMaker()
        {
            PdfFilePath = GetPdfPath(Path.GetFileName(_currentlyLoadedBook.FolderPath));

            var dom = BookSelection.CurrentSelection.GetDomForPrinting(BookletPortion, _currentBookCollectionSelection.CurrentSelection, _bookServer);

            AddStylesheetClasses(dom.RawDom);

            //we do this now becuase the publish ui allows the user to select a different layout for the pdf than what is in the book file
            SizeAndOrientation.UpdatePageSizeAndOrientationClasses(dom.RawDom, PageLayout);
            PageLayout.UpdatePageSplitMode(dom.RawDom);

            XmlHtmlConverter.MakeXmlishTagsSafeForInterpretationAsHtml(dom.RawDom);
            dom.UseOriginalImages = true;             // don't want low-res images or transparency in PDF.
            return(EnhancedImageServer.MakeSimulatedPageFileInBookFolder(dom));
        }
Exemple #14
0
        public static string PostString(EnhancedImageServer server, string endPoint, string data, ContentType returnType,
                                        EndpointHandler handler = null)
        {
            if (handler != null)
            {
                server.RegisterEndpointHandler(endPoint, handler, true);
            }
            server.StartListening();
            var client = new WebClientWithTimeout
            {
                Timeout = 3000
            };

            client.Headers[HttpRequestHeader.ContentType] = returnType == ContentType.Text ? "text/plain" : "application/json";

            return(client.UploadString(ServerBase.ServerUrlWithBloomPrefixEndingInSlash + "api/" + endPoint, "POST", data));
        }
        private PretendRequestInfo CreateServerMakeSimPageMakeReply(HtmlDom dom, bool simulateCallingFromJavascript = false)
        {
            PretendRequestInfo transaction;

            using (var server = CreateImageServer())
            {
                using (var fakeTempFile = EnhancedImageServer.MakeSimulatedPageFileInBookFolder(dom, simulateCallingFromJavascript))
                {
                    var url = fakeTempFile.Key;
                    transaction = new PretendRequestInfo(url, forPrinting: false, forSrcAttr: simulateCallingFromJavascript);

                    // Execute
                    server.MakeReply(transaction);
                }
            }
            return(transaction);
        }
Exemple #16
0
 public void RegisterWithServer(EnhancedImageServer server)
 {
     server.RegisterEndpointHandler("keyboarding/useLongpress", (ApiRequest request) =>
     {
         try
         {
             //detect if some keyboarding system is active, e.g. KeyMan. If it is, don't enable LongPress
             var form = Application.OpenForms.Cast <Form>().Last();
             request.ReplyWithText(SIL.Windows.Forms.Keyboarding.KeyboardController.IsFormUsingInputProcessor(form)
                                         ? "false"
                                         : "true");
         }
         catch (Exception error)
         {
             request.ReplyWithText("true");                     // This is arbitrary. I don't know if it's better to assume keyman, or not.
             NonFatalProblem.Report(ModalIf.None, PassiveIf.All, "Error checking for keyman", "", error);
         }
     }, handleOnUiThread: false);
 }
Exemple #17
0
        private SimulatedPageFile MakeFinalHtmlForPdfMaker()
        {
            PdfFilePath = GetPdfPath(Path.GetFileName(_currentlyLoadedBook.FolderPath));

            var dom = BookSelection.CurrentSelection.GetDomForPrinting(BookletPortion, _currentBookCollectionSelection.CurrentSelection, _bookServer);

            AddStylesheetClasses(dom.RawDom);

            //we do this now becuase the publish ui allows the user to select a different layout for the pdf than what is in the book file
            SizeAndOrientation.UpdatePageSizeAndOrientationClasses(dom.RawDom, PageLayout);

            if (BookSelection.CurrentSelection.GetLayout().SizeAndOrientation.IsLandScape !=
                PageLayout.SizeAndOrientation.IsLandScape)
            {
                // Need to update the xmatter in the print dom...it may use different images.
                // Make sure we do this AFTER setting PageOrientation in Dom.
                BookSelection.CurrentSelection.UpdateBrandingForCurrentOrientation(dom);
            }
            PageLayout.UpdatePageSplitMode(dom.RawDom);

            XmlHtmlConverter.MakeXmlishTagsSafeForInterpretationAsHtml(dom.RawDom);
            dom.UseOriginalImages = true;             // don't want low-res images or transparency in PDF.
            return(EnhancedImageServer.MakeSimulatedPageFileInBookFolder(dom, source: "pub"));
        }
Exemple #18
0
 public static void RegisterWithServer(EnhancedImageServer server)
 {
     server.RegisterEndpointHandler("toolbox/settings", HandleSettings, false);
 }
Exemple #19
0
 public void RegisterWithServer(EnhancedImageServer server)
 {
     // These are both just retrieving information about files, apart from using _bookSelection.CurrentSelection.FolderPath.
     server.RegisterEndpointHandler("image/info", HandleImageInfo, false);
     server.RegisterEndpointHandler("image/imageCreditsForWholeBook", HandleCopyImageCreditsForWholeBook, false);
 }
Exemple #20
0
 public void RegisterWithServer(EnhancedImageServer server)
 {
     server.RegisterEndpointHandler("image/info", HandleImageInfo);
     server.RegisterEndpointHandler("image/imageCreditsForWholeBook", HandleCopyImageCreditsForWholeBook);
 }
Exemple #21
0
 public void RegisterWithServer(EnhancedImageServer server)
 {
     server.RegisterEndpointHandler("music/ui/chooseFile", HandleRequest, true);
 }
        public void RegisterWithServer(EnhancedImageServer server)
        {
            server.RegisterEndpointHandler(kApiUrlPart + "requestState", request =>
            {
                if (request.HttpMethod == HttpMethods.Get)
                {
                    request.ReplyWithJson(CurrentStateString);
                }
                else                 // post
                {
                    Debug.Fail("We shouldn't ever be using the 'post' version.");
                    request.PostSucceeded();
                }
            }, true);

            server.RegisterEndpointHandler(kApiUrlPart + "addPage", request =>
            {
                AddPageButton_Click();
                request.PostSucceeded();
            }, true);

            server.RegisterEndpointHandler(kApiUrlPart + "duplicatePage", request =>
            {
                _editingModel.OnDuplicatePage();
                request.PostSucceeded();
            }, true);

            server.RegisterEndpointHandler(kApiUrlPart + "deletePage", request =>
            {
                if (ConfirmRemovePageDialog.Confirm())
                {
                    _editingModel.OnDeletePage();
                }
                request.PostSucceeded();
            }, true);

            server.RegisterEndpointHandler(kApiUrlPart + "lockBook", request =>
            {
                _editingModel.SaveNow();                 // BL-5421 lock and unlock lose typing
                _editingModel.CurrentBook.TemporarilyUnlocked = false;
                request.PostSucceeded();
                UpdateState();                 // because we aren't selecting a new page
                _editingModel.RefreshDisplayOfCurrentPage();
            }, true);

            server.RegisterEndpointHandler(kApiUrlPart + "unlockBook", request =>
            {
                _editingModel.SaveNow();                 // BL-5421 lock and unlock lose typing
                _editingModel.CurrentBook.TemporarilyUnlocked = true;
                request.PostSucceeded();
                UpdateState();                 // because we aren't selecting a new page
                _editingModel.RefreshDisplayOfCurrentPage();
            }, true);

            server.RegisterEndpointHandler(kApiUrlPart + "cleanup", request =>
            {
                SendCleanupState();
                request.PostSucceeded();
            }, true);

            server.RegisterEndpointHandler(kApiUrlPart + "zoomMinus", request =>
            {
                _editingModel.AdjustPageZoom(-10);
                request.PostSucceeded();
            }, true);

            server.RegisterEndpointHandler(kApiUrlPart + "zoomPlus", request =>
            {
                _editingModel.AdjustPageZoom(10);
                request.PostSucceeded();
            }, true);

            server.RegisterEndpointHandler(kApiUrlPart + "requestVideoPlaceHolder", request =>
            {
                _editingModel.RequestVideoPlaceHolder();
                request.PostSucceeded();
            }, true);
        }
Exemple #23
0
        /// ------------------------------------------------------------------------------------
        protected void BuildSubContainerForThisProject(string projectSettingsPath, IContainer parentContainer)
        {
            var editableCollectionDirectory = Path.GetDirectoryName(projectSettingsPath);

            _scope = parentContainer.BeginLifetimeScope(builder =>
            {
                //BloomEvents are by nature, singletons (InstancePerLifetimeScope)
                builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
                .InstancePerLifetimeScope()
                // Didn't work .Where(t => t.GetInterfaces().Contains(typeof(Bloom.Event<>)));
                .Where(t => t is IEvent);

                //Other classes which are also  singletons
                builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
                .InstancePerLifetimeScope()
                .Where(t => new[] {
                    typeof(TemplateInsertionCommand),
                    typeof(DuplicatePageCommand),
                    typeof(DeletePageCommand),
                    typeof(EditBookCommand),
                    typeof(SendReceiveCommand),
                    typeof(SelectedTabAboutToChangeEvent),
                    typeof(SelectedTabChangedEvent),
                    typeof(LibraryClosing),
                    typeof(PageListChangedEvent),                      // REMOVE+++++++++++++++++++++++++++
                    typeof(BookRefreshEvent),
                    typeof(BookDownloadStartingEvent),
                    typeof(BookSelection),
                    typeof(CurrentEditableCollectionSelection),
                    typeof(RelocatePageEvent),
                    typeof(QueueRenameOfCollection),
                    typeof(PageSelection),
                    typeof(LocalizationChangedEvent),
                    typeof(EditingModel)
                }.Contains(t));

                var bookRenameEvent = new BookRenamedEvent();
                builder.Register(c => bookRenameEvent).AsSelf().InstancePerLifetimeScope();

                try
                {
                    //nb: we split out the ChorusSystem.Init() so that this won't ever fail, so we have something registered even if we aren't
                    //going to be able to do HG for some reason.
                    var chorusSystem = new ChorusSystem(Path.GetDirectoryName(projectSettingsPath));
                    builder.Register <ChorusSystem>(c => chorusSystem).InstancePerLifetimeScope();
                    builder.Register <SendReceiver>(c => new SendReceiver(chorusSystem, () => ProjectWindow)).InstancePerLifetimeScope();
#if USING_CHORUS
                    chorusSystem.Init(string.Empty /*user name*/);
#endif
                }
                catch (Exception error)
                {
#if USING_CHORUS
#if !DEBUG
                    Palaso.Reporting.ErrorReport.NotifyUserOfProblem(error,
                                                                     "There was a problem loading the Chorus Send/Receive system for this collection. Bloom will try to limp along, but you'll need technical help to resolve this. If you have no other choice, find this folder: {0}, move it somewhere safe, and restart Bloom.", Path.GetDirectoryName(projectSettingsPath).CombineForPath(".hg"));
#endif
                    //swallow for develoeprs, because this happens if you don't have the Mercurial and "Mercurial Extensions" folders in the root, and our
                    //getdependencies doesn't yet do that.
#endif
                }


                //This deserves some explanation:
                //*every* collection has a "*.BloomCollection" settings file. But the one we make the most use of is the one editable collection
                //That's why we're registering it... it gets used all over. At the moment (May 2012), we don't ever read the
                //settings file of the collections we're using for sources.
                try
                {
                    builder.Register <CollectionSettings>(c => new CollectionSettings(projectSettingsPath)).InstancePerLifetimeScope();
                }
                catch (Exception)
                {
                    return;
                }


                builder.Register <LibraryModel>(c => new LibraryModel(editableCollectionDirectory, c.Resolve <CollectionSettings>(), c.Resolve <SendReceiver>(), c.Resolve <BookSelection>(), c.Resolve <SourceCollectionsList>(), c.Resolve <BookCollection.Factory>(), c.Resolve <EditBookCommand>(), c.Resolve <CreateFromSourceBookCommand>(), c.Resolve <BookServer>(), c.Resolve <CurrentEditableCollectionSelection>())).InstancePerLifetimeScope();

                builder.Register <IChangeableFileLocator>(c => new BloomFileLocator(c.Resolve <CollectionSettings>(), c.Resolve <XMatterPackFinder>(), GetFactoryFileLocations(), GetFoundFileLocations())).InstancePerLifetimeScope();

                builder.Register <LanguageSettings>(c =>
                {
                    var librarySettings = c.Resolve <CollectionSettings>();
                    var preferredSourceLanguagesInOrder = new List <string>();
                    preferredSourceLanguagesInOrder.Add(librarySettings.Language2Iso639Code);
                    if (!string.IsNullOrEmpty(librarySettings.Language3Iso639Code) &&
                        librarySettings.Language3Iso639Code != librarySettings.Language2Iso639Code)
                    {
                        preferredSourceLanguagesInOrder.Add(librarySettings.Language3Iso639Code);
                    }

                    return(new LanguageSettings(librarySettings.Language1Iso639Code, preferredSourceLanguagesInOrder));
                });
                builder.Register <XMatterPackFinder>(c =>
                {
                    var locations = new List <string>();
                    locations.Add(FileLocator.GetDirectoryDistributedWithApplication("xMatter"));
                    locations.Add(XMatterAppDataFolder);
                    locations.Add(XMatterCommonDataFolder);
                    return(new XMatterPackFinder(locations));
                });

                builder.Register <SourceCollectionsList>(c =>
                {
                    var l = new SourceCollectionsList(c.Resolve <Book.Book.Factory>(), c.Resolve <BookStorage.Factory>(), c.Resolve <BookCollection.Factory>(), editableCollectionDirectory);
                    l.RepositoryFolders = new string[] { FactoryCollectionsDirectory, GetInstalledCollectionsDirectory() };
                    return(l);
                }).InstancePerLifetimeScope();

                builder.Register <ITemplateFinder>(c =>
                {
                    return(c.Resolve <SourceCollectionsList>());
                }).InstancePerLifetimeScope();

                builder.RegisterType <BloomParseClient>().AsSelf().SingleInstance();

                // Enhance: may need some way to test a release build in the sandbox.
                builder.Register(c => CreateBloomS3Client()).AsSelf().SingleInstance();
                builder.RegisterType <BookTransfer>().AsSelf().SingleInstance();
                builder.RegisterType <LoginDialog>().AsSelf();

                //TODO: this gave a stackoverflow exception
//				builder.Register<WorkspaceModel>(c => c.Resolve<WorkspaceModel.Factory>()(rootDirectoryPath)).InstancePerLifetimeScope();
                //so we're doing this
                builder.Register(c => editableCollectionDirectory).InstancePerLifetimeScope();

                builder.RegisterType <CreateFromSourceBookCommand>().InstancePerLifetimeScope();

                string collectionDirectory = Path.GetDirectoryName(projectSettingsPath);
                if (Path.GetFileNameWithoutExtension(projectSettingsPath).ToLower().Contains("web"))
                {
                    // REVIEW: This seems to be used only for testing purposes
                    BookCollection editableCollection = _scope.Resolve <BookCollection.Factory>()(collectionDirectory, BookCollection.CollectionType.TheOneEditableCollection);
                    var sourceCollectionsList         = _scope.Resolve <SourceCollectionsList>();
                    _httpServer = new BloomServer(_scope.Resolve <CollectionSettings>(), editableCollection, sourceCollectionsList, parentContainer.Resolve <HtmlThumbNailer>());
                }
                else
                {
                    _httpServer = new EnhancedImageServer(new LowResImageCache(bookRenameEvent));
                }
                builder.Register((c => _httpServer)).AsSelf().SingleInstance();

                builder.Register <Func <WorkspaceView> >(c => () =>
                {
                    var factory = c.Resolve <WorkspaceView.Factory>();
                    if (projectSettingsPath.ToLower().Contains("web"))
                    {
                        return(factory(c.Resolve <WebLibraryView>()));
                    }
                    else
                    {
                        return(factory(c.Resolve <LibraryView>()));
                    }
                });
            });
        }
        public void RegisterWithServer(EnhancedImageServer server)
        {
            // This is just for storing the user preference of method
            // If we had a couple of these, we could just have a generic preferences api
            // that browser-side code could use.
            server.RegisterEndpointHandler(kApiUrlPart + "method", request =>
            {
                if (request.HttpMethod == HttpMethods.Get)
                {
                    var method = Settings.Default.PublishAndroidMethod;
                    if (!new string[] { "wifi", "usb", "file" }.Contains(method))
                    {
                        method = "wifi";
                    }
                    request.ReplyWithText(method);
                }
                else                 // post
                {
                    Settings.Default.PublishAndroidMethod = request.RequiredPostString();
#if __MonoCS__
                    if (Settings.Default.PublishAndroidMethod == "usb")
                    {
                        _progress.MessageWithoutLocalizing("Sorry, this method is not available on Linux yet.");
                    }
#endif
                    request.PostSucceeded();
                }
            }, true);

            server.RegisterEndpointHandler(kApiUrlPart + "backColor", request =>
            {
                if (request.HttpMethod == HttpMethods.Get)
                {
                    if (request.CurrentBook != _coverColorSourceBook)
                    {
                        _coverColorSourceBook = request.CurrentBook;
                        TryCssColorFromString(request.CurrentBook?.GetCoverColor() ?? "", out _thumbnailBackgroundColor);
                    }
                    request.ReplyWithText(ToCssColorString(_thumbnailBackgroundColor));
                }
                else                 // post
                {
                    // ignore invalid colors (very common while user is editing hex)
                    Color newColor;
                    var newColorAsString = request.RequiredPostString();
                    if (TryCssColorFromString(newColorAsString, out newColor))
                    {
                        _thumbnailBackgroundColor = newColor;
                        request.CurrentBook.SetCoverColor(newColorAsString);
                    }
                    request.PostSucceeded();
                }
            }, true);


            server.RegisterEndpointHandler(kApiUrlPart + "photoStoryMode", request =>
            {
                if (request.HttpMethod == HttpMethods.Get)
                {
                    // this is temporary, just trying to get support for full screen pan & zoom out quickly in 4.2
                    request.ReplyWithText(request.CurrentBook.UsePhotoStoryModeInBloomReader.ToString()
                                          .ToLowerInvariant()); // "false", not "False"
                }
                else                                            // post
                {
                    request.CurrentBook.UsePhotoStoryModeInBloomReader = bool.Parse(request.RequiredPostString());
                    request.PostSucceeded();
                }
            }, true);


            server.RegisterEndpointHandler(kApiUrlPart + "thumbnail", request =>
            {
                var coverImage = request.CurrentBook.GetCoverImagePath();
                if (coverImage == null)
                {
                    request.Failed("no cover image");
                }
                else
                {
                    // We don't care as much about making it resized as making its background transparent.
                    using (var thumbnail = TempFile.CreateAndGetPathButDontMakeTheFile())
                    {
                        if (_thumbnailBackgroundColor == Color.Transparent)
                        {
                            TryCssColorFromString(request.CurrentBook?.GetCoverColor(), out _thumbnailBackgroundColor);
                        }
                        RuntimeImageProcessor.GenerateEBookThumbnail(coverImage, thumbnail.Path, 256, 256, _thumbnailBackgroundColor);
                        request.ReplyWithImage(thumbnail.Path);
                    }
                }
            }, true);

            server.RegisterEndpointHandler(kApiUrlPart + "usb/start", request =>
            {
#if !__MonoCS__
                SetState("UsbStarted");
                _usbPublisher.Connect(request.CurrentBook, _thumbnailBackgroundColor);
#endif
                request.PostSucceeded();
            }, true);

            server.RegisterEndpointHandler(kApiUrlPart + "usb/stop", request =>
            {
#if !__MonoCS__
                _usbPublisher.Stop();
                SetState("stopped");
#endif
                request.PostSucceeded();
            }, true);
            server.RegisterEndpointHandler(kApiUrlPart + "wifi/start", request =>
            {
                _wifiPublisher.Start(request.CurrentBook, request.CurrentCollectionSettings, _thumbnailBackgroundColor);
                SetState("ServingOnWifi");
                request.PostSucceeded();
            }, true);

            server.RegisterEndpointHandler(kApiUrlPart + "wifi/stop", request =>
            {
                _wifiPublisher.Stop();
                SetState("stopped");
                request.PostSucceeded();
            }, true);

            server.RegisterEndpointHandler(kApiUrlPart + "file/save", request =>
            {
                FilePublisher.Save(request.CurrentBook, _bookServer, _thumbnailBackgroundColor, _progress);
                SetState("stopped");
                request.PostSucceeded();
            }, true);

            server.RegisterEndpointHandler(kApiUrlPart + "cleanup", request =>
            {
                Stop();
                request.PostSucceeded();
            }, true);

            server.RegisterEndpointHandler(kApiUrlPart + "textToClipboard", request =>
            {
                PortableClipboard.SetText(request.RequiredPostString());
                request.PostSucceeded();
            }, true);
        }
Exemple #25
0
        /// <summary>
        /// Returns true if it make some attempt at an image, false if navigation is currently suppressed.
        /// </summary>
        /// <param name="order"></param>
        /// <param name="browser"></param>
        /// <param name="thumbnail"></param>
        /// <returns></returns>
        private bool CreateThumbNail(ThumbnailOrder order, GeckoWebBrowser browser, out Image thumbnail)
        {
            // runs on threadpool thread
            thumbnail = null;
            using (var temp = EnhancedImageServer.MakeSimulatedPageFileInBookFolder(order.Document))
            {
                order.Done  = false;
                browser.Tag = order;
                if (!OpenTempFileInBrowser(browser, temp.Key))
                {
                    return(false);
                }

                var browserSize = SetWidthAndHeight(browser);
                if (browserSize.Height == 0)          //happens when we run into the as-yet-unreproduced-or-fixed bl-254
                {
                    return(false);                    // will try again later
                }
                try
                {
                    Logger.WriteMinorEvent("HtmlThumNailer ({2}): browser.GetBitmap({0},{1})", browserSize.Width,
                                           (uint)browserSize.Height,
                                           Thread.CurrentThread.ManagedThreadId);
                    // This short sleep was added to fix BL-4170, a problem where thumbnails were often generated without
                    // images. We're not sure what changed or why it became necessary. Possibly there was a change in GeckoFx 45
                    // which caused it report document-complete before background images are sufficiently loaded to show up
                    // in a captured image. Testing indicated that our image server did finish returning the background
                    // images before the document-complete notification, but that doesn't prove they were fully rendered.
                    // Also casting doubt on this hypothesis, we tried delays (some much longer) in several seemingly
                    // more logical places where they didn't help, at least not without being unreasonably long.
                    // The length of the delay is of course problematic. Experiments on my fast desktop indicate that 10ms
                    // does not help; 20ms is enough for AOR images; 40ms for a 6mp/4M jpg photo; but somewhere between
                    // 100 and 200ms can be needed by a really large (24mp/14M) image. 200ms is based on hoping that
                    // most computers are no worse than five times slower than mine and accepting that the slower ones
                    // might have problems with huge images.
                    Thread.Sleep(200);
                    //BUG (April 2013) found that the initial call to GetBitMap always had a zero width, leading to an exception which
                    //the user doesn't see and then all is well. So at the moment, we avoid the exception, and just leave with
                    //the placeholder thumbnail.
                    if (browserSize.Width == 0 || browserSize.Height == 0)
                    {
                        var paperSizeName = GetPaperSizeName(order.Document.RawDom);
                        throw new ApplicationException("Problem getting thumbnail browser for document with Paper Size: " + paperSizeName);
                    }
                    using (Image fullsizeImage = CreateImage(browser))
                    {
                        if (_disposed)
                        {
                            return(false);
                        }
                        thumbnail = MakeThumbNail(fullsizeImage, order.Options);
                        return(true);
                    }
                }
                catch (Exception error)
                {
                    Logger.WriteEvent("HtmlThumbNailer ({0}) got {1}", Thread.CurrentThread.ManagedThreadId, error.Message);
                    Logger.WriteEvent("Disposing of all browsers in hopes of getting a fresh start on life");
                    foreach (var browserCacheForDifferentPaperSize in _browserCacheForDifferentPaperSizes)
                    {
                        try
                        {
                            Logger.WriteEvent("Disposing of browser {0}", browserCacheForDifferentPaperSize.Key);
                            browserCacheForDifferentPaperSize.Value.Dispose();
                        }
                        catch (Exception e2)
                        {
                            Logger.WriteEvent(
                                "While trying to dispose of thumbnailer browsers as a result of an exception, go another: " + e2.Message);
                        }
                    }
                    _browserCacheForDifferentPaperSizes.Clear();
#if DEBUG
                    _syncControl.Invoke((Action)(() => Debug.Fail(error.Message)));
#endif
                }
            }
            return(false);
        }
 public void RegisterWithServer(EnhancedImageServer server)
 {
     // Both of these display UI, expect to require UI thread.
     server.RegisterEndpointHandler("addPage", HandleAddPage, true);
     server.RegisterEndpointHandler("changeLayout", HandleChangeLayout, true);
 }
 public void Teardown()
 {
     _server.Dispose();
     _server = null;
     Monitor.Exit(_portMonitor);
 }
Exemple #28
0
 public void RegisterWithServer(EnhancedImageServer server)
 {
     server.RegisterEndpointHandler("addPage", HandleAddPage);
     server.RegisterEndpointHandler("changeLayout", HandleChangeLayout);
 }
 public void RegisterWithServer(EnhancedImageServer server)
 {
     server.RegisterEndpointHandler("pageTemplates", HandleTemplatesRequest);
     // Being on the UI thread causes a deadlock on Linux/Mono.  See https://silbloom.myjetbrains.com/youtrack/issue/BL-3818.
     server.RegisterEndpointHandler("pageTemplateThumbnail", HandleThumbnailRequest, false);
 }
Exemple #30
0
 public void RegisterWithServer(EnhancedImageServer server)
 {
     server.RegisterEndpointHandler("toolbox/enabledTools", HandleEnabledToolsRequest, true);
 }