A local http server that can serve (low-res) images plus other files.
geckofx makes concurrent requests of URLs which this class handles. This means that the methods of this class get called on different threads, so it has to be thread-safe.
상속: Bloom.ImageProcessing.ImageServer
예제 #1
0
        public void RegisterWithServer(EnhancedImageServer server)
        {
            server.RegisterEndpointHandler(kBrandingImageUrlPart, request =>
            {
#if DEBUG
                // The book templates are allowed to use the branding api.  All real books
                // should not use this facility.
                if (request.CurrentBook == null || request.CurrentBook.FolderPath == null ||
                    !Book.BookStorage.IsStaticContent(request.CurrentBook.FolderPath))
                {
                    //Debug.Fail("Books should no longer have branding api urls");
                }
#endif
                var fileName = request.RequiredFileNameOrPath("id");
                var path     = FindBrandingImageFileIfPossible(_collectionSettings.BrandingProjectKey, fileName.NotEncoded, request.CurrentBook.GetLayout());

                // And this is perfectly normal, to not have a branding image at all, for a particular page:
                if (string.IsNullOrEmpty(path))
                {
                    request.Failed("");
                    // the HTML will need to be able to handle this invisibly... see http://stackoverflow.com/questions/22051573/how-to-hide-image-broken-icon-using-only-css-html-without-js
                    return;
                }
                request.ReplyWithImage(path);
            }, false);
        }
예제 #2
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);
            }
            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);
            }
        }
예제 #3
0
 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();
     });
 }
예제 #4
0
        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);
        }
예제 #5
0
        public void RegisterWithServer(EnhancedImageServer server)
        {
            server.RegisterEndpointHandler(kBrandingImageUrlPart, request =>
            {
                var fileName = request.RequiredFileNameOrPath("id");

                var path = BloomFileLocator.GetOptionalBrandingFile(_collectionSettings.BrandingProjectName, fileName.NotEncoded);
                if(string.IsNullOrEmpty(path))
                {
                    request.Failed("");
                    // the HTML will need to be able to handle this invisibly... see http://stackoverflow.com/questions/22051573/how-to-hide-image-broken-icon-using-only-css-html-without-js
                    return;
                }
                request.ReplyWithImage(path);
            });
        }
예제 #6
0
        public static string PostString(EnhancedImageServer server, string endPoint, string data, ContentType returnType,
			EndpointHandler handler = null)
        {
            if(handler != null)
            {
                server.RegisterEndpointHandler(endPoint, handler);
            }
            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);
        }
예제 #7
0
        public void RegisterWithServer(EnhancedImageServer server)
        {
            server.RegisterEndpointHandler(kBrandingImageUrlPart, request =>
            {
                var fileName = request.RequiredFileNameOrPath("id");
                var path     = FindBrandingImageFileIfPossible(_collectionSettings.BrandingProjectName, fileName.NotEncoded);

                // And this is perfectly normal, to not have a branding image at all, for a particular page:
                if (string.IsNullOrEmpty(path))
                {
                    request.Failed("");
                    // the HTML will need to be able to handle this invisibly... see http://stackoverflow.com/questions/22051573/how-to-hide-image-broken-icon-using-only-css-html-without-js
                    return;
                }
                request.ReplyWithImage(path);
            });
        }
예제 #8
0
        public void RegisterWithServer(EnhancedImageServer server)
        {
            server.RegisterEndpointHandler("collection/defaultFont", request =>
            {
                var bookFontName = request.CurrentCollectionSettings.DefaultLanguage1FontName;
                if (String.IsNullOrEmpty(bookFontName))
                {
                    bookFontName = "sans-serif";
                }
                request.ReplyWithText(bookFontName);
            });

            server.RegisterEndpointHandler("readers/ui/.*", HandleRequest, true);
            server.RegisterEndpointHandler("readers/io/.*", HandleRequest, false);

            //we could do them all like this:
            //server.RegisterEndpointHandler("readers/loadReaderToolSettings", r=> r.ReplyWithJson(GetDefaultReaderSettings(r.CurrentCollectionSettings)));
        }
 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);
 }
예제 #10
0
        public PretendRequestInfo(string url, HttpMethods httpMethod = HttpMethods.Get, bool forPrinting = false, bool forSrcAttr = false)
        {
            HttpMethod = httpMethod;
            if (forPrinting)
            {
                url = url.Replace("/bloom/", "/bloom/OriginalImages/");
            }

            // In the real request, RawUrl does not include this prefix
            RawUrl = url.Replace(ServerBase.ServerUrl, "");

            // When JavaScript inserts a real path into the html it replaces the three magic html characters with these substitutes.
            // For this PretendRequestInfo we simulate that by doing the replace here in the url.
            if (forSrcAttr)
            {
                url = EnhancedImageServer.SimulateJavaScriptHandlingOfHtml(url);
            }

            // Reducing the /// emulates a behavior of the real HttpListener
            LocalPathWithoutQuery = url.Replace(ServerBase.ServerUrl, "").Replace("/bloom/OriginalImages///", "/bloom/OriginalImages/").Replace("/bloom///", "/bloom/").UnescapeCharsForHttp();
        }
예제 #11
0
 public void RegisterWithServer(EnhancedImageServer server)
 {
     server.RegisterEndpointHandler("bookSettings", HandleBookSettings);
     server.RegisterEndpointHandler("imageInfo", HandleImageInfo);
 }
 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 static void RegisterWithServer(EnhancedImageServer server)
 {
     server.RegisterEndpointHandler(kPrefix+"/.*", ExternalLinkController.HandleRequest);
 }
예제 #14
0
 private static EnhancedImageServer GetTestServer()
 {
     var server = new EnhancedImageServer(new RuntimeImageProcessor(new BookRenamedEvent()), null, new BookSelection(), GetTestFileLocator());
     server.StartListening();
     return server;
 }
예제 #15
0
 public static void RegisterWithServer(EnhancedImageServer server)
 {
     server.RegisterEndpointHandler("toolbox/settings", HandleSettings);
 }
 public void Teardown()
 {
     _server.Dispose();
     _server = null;
     Monitor.Exit(_portMonitor);
 }
예제 #17
0
 public void Dispose()
 {
     EnhancedImageServer.RemoveSimulatedPageFile(Key);
 }
예제 #18
0
 public void RegisterWithServer(EnhancedImageServer server)
 {
     server.RegisterEndpointHandler("addPage", HandleAddPage);
     server.RegisterEndpointHandler("changeLayout", HandleChangeLayout);
 }
예제 #19
0
 public void TearDown()
 {
     _server.Dispose();
     _server = null;
 }
예제 #20
0
 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);
 }
예제 #21
0
 public void RegisterWithServer(EnhancedImageServer server)
 {
     // Not sure this needs UI thread, but it can result in saving the page, which seems
     // safest to do that way.
     server.RegisterEndpointHandler("book/settings", HandleBookSettings, true);
 }
예제 #22
0
 public void RegisterWithServer(EnhancedImageServer server)
 {
     server.RegisterEndpointHandler("image/info", HandleImageInfo);
 }
예제 #23
0
        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).");
        }
예제 #24
0
 public void RegisterWithServer(EnhancedImageServer server)
 {
     server.RegisterEndpointHandler("bookSettings", HandleBookSettings);
     server.RegisterEndpointHandler("imageInfo", HandleImageInfo);
 }
예제 #25
0
        //autofac uses this
        public EditingModel(BookSelection bookSelection, PageSelection pageSelection,
			TemplateInsertionCommand templateInsertionCommand,
			PageListChangedEvent pageListChangedEvent,
			RelocatePageEvent relocatePageEvent,
			BookRefreshEvent bookRefreshEvent,
			PageRefreshEvent pageRefreshEvent,
			DuplicatePageCommand duplicatePageCommand,
			DeletePageCommand deletePageCommand,
			SelectedTabChangedEvent selectedTabChangedEvent,
			SelectedTabAboutToChangeEvent selectedTabAboutToChangeEvent,
			LibraryClosing libraryClosingEvent,
			LocalizationChangedEvent localizationChangedEvent,
			CollectionSettings collectionSettings,
			//SendReceiver sendReceiver,
			EnhancedImageServer server,
			BloomWebSocketServer webSocketServer)
        {
            _bookSelection = bookSelection;
            _pageSelection = pageSelection;
            _duplicatePageCommand = duplicatePageCommand;
            _deletePageCommand = deletePageCommand;
            _collectionSettings = collectionSettings;
            //_sendReceiver = sendReceiver;
            _server = server;
            _webSocketServer = webSocketServer;
            _templatePagesDict = null;

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

            bookRefreshEvent.Subscribe((book) => OnBookSelectionChanged(null, null));
            pageRefreshEvent.Subscribe((PageRefreshEvent.SaveBehavior behavior) =>
            {
                switch (behavior)
                {
                    case PageRefreshEvent.SaveBehavior.SaveBeforeRefresh:
                        RethinkPageAndReloadIt(null);
                        break;

                    case PageRefreshEvent.SaveBehavior.JustRedisplay:
                        RefreshDisplayOfCurrentPage();
                        break;
                }
            });

            selectedTabChangedEvent.Subscribe(OnTabChanged);
            selectedTabAboutToChangeEvent.Subscribe(OnTabAboutToChange);
            duplicatePageCommand.Implementer = OnDuplicatePage;
            deletePageCommand.Implementer = OnDeletePage;
            pageListChangedEvent.Subscribe(x => _view.UpdatePageList(false));
            relocatePageEvent.Subscribe(OnRelocatePage);
            libraryClosingEvent.Subscribe(o =>
            {
                if (Visible)
                    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);
                }
                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;
        }