From 1db79541ffcf730b9a3988b9d8571fd36d5287ac Mon Sep 17 00:00:00 2001 From: 0xboobface <0xboobface@gmail.com> Date: Sun, 21 Jul 2019 10:39:00 +0200 Subject: [PATCH] Add web interface for the server --- client/pom.xml | 2 - .../src/main/java/ctbrec/docs/DocServer.java | 4 +- common/pom.xml | 6 + .../ctbrec/servlet}/StaticFileServlet.java | 13 +- master/pom.xml | 16 +- server/pom.xml | 2 - .../ctbrec/recorder/server/HttpServer.java | 7 + .../main/resources/html/static/button-red.png | Bin 0 -> 6338 bytes .../src/main/resources/html/static/custom.css | 37 + .../main/resources/html/static/favicon.png | Bin 0 -> 1262 bytes .../main/resources/html/static/freelancer.css | 393 + .../resources/html/static/freelancer.min.js | 1 + .../src/main/resources/html/static/icon64.png | Bin 0 -> 2729 bytes .../src/main/resources/html/static/index.html | 558 + .../src/main/resources/html/static/modal.js | 16 + .../vendor/bootstrap/css/bootstrap-grid.css | 1567 ++ .../bootstrap/css/bootstrap-grid.min.css | 7 + .../vendor/bootstrap/css/bootstrap-reboot.css | 342 + .../bootstrap/css/bootstrap-reboot.min.css | 8 + .../static/vendor/bootstrap/css/bootstrap.css | 8981 ++++++++ .../vendor/bootstrap/css/bootstrap.css.map | 1 + .../vendor/bootstrap/css/bootstrap.min.css | 7 + .../bootstrap/css/bootstrap.min.css.map | 1 + .../vendor/bootstrap/js/bootstrap.bundle.js | 6444 ++++++ .../bootstrap/js/bootstrap.bundle.js.map | 1 + .../bootstrap/js/bootstrap.bundle.min.js | 7 + .../bootstrap/js/bootstrap.bundle.min.js.map | 1 + .../static/vendor/bootstrap/js/bootstrap.js | 3927 ++++ .../vendor/bootstrap/js/bootstrap.js.map | 1 + .../vendor/bootstrap/js/bootstrap.min.js | 7 + .../vendor/bootstrap/js/bootstrap.min.js.map | 1 + .../html/static/vendor/flowplayer/LICENSE.md | 715 + .../static/vendor/flowplayer/flowplayer.js | 10518 +++++++++ .../vendor/flowplayer/flowplayer.min.js | 6 + .../static/vendor/flowplayer/flowplayer.swf | Bin 0 -> 8541 bytes .../vendor/flowplayer/flowplayerhls.swf | Bin 0 -> 61773 bytes .../html/static/vendor/flowplayer/index.html | 32 + .../flowplayer/skin/icons/flowplayer.eot | Bin 0 -> 17896 bytes .../flowplayer/skin/icons/flowplayer.svg | 98 + .../flowplayer/skin/icons/flowplayer.ttf | Bin 0 -> 17732 bytes .../flowplayer/skin/icons/flowplayer.woff | Bin 0 -> 17808 bytes .../flowplayer/skin/icons/flowplayer.woff2 | Bin 0 -> 7908 bytes .../static/vendor/flowplayer/skin/skin.css | 1034 + .../vendor/font-awesome/css/font-awesome.css | 2337 ++ .../font-awesome/css/font-awesome.css.map | 7 + .../font-awesome/css/font-awesome.min.css | 4 + .../vendor/font-awesome/fonts/FontAwesome.otf | Bin 0 -> 134808 bytes .../fonts/fontawesome-webfont.eot | Bin 0 -> 165742 bytes .../fonts/fontawesome-webfont.svg | 2671 +++ .../fonts/fontawesome-webfont.ttf | Bin 0 -> 165548 bytes .../fonts/fontawesome-webfont.woff | Bin 0 -> 98024 bytes .../fonts/fontawesome-webfont.woff2 | Bin 0 -> 77160 bytes .../vendor/font-awesome/less/animated.less | 34 + .../font-awesome/less/bordered-pulled.less | 25 + .../static/vendor/font-awesome/less/core.less | 12 + .../vendor/font-awesome/less/fixed-width.less | 6 + .../font-awesome/less/font-awesome.less | 18 + .../vendor/font-awesome/less/icons.less | 789 + .../vendor/font-awesome/less/larger.less | 13 + .../static/vendor/font-awesome/less/list.less | 19 + .../vendor/font-awesome/less/mixins.less | 60 + .../static/vendor/font-awesome/less/path.less | 15 + .../font-awesome/less/rotated-flipped.less | 20 + .../font-awesome/less/screen-reader.less | 5 + .../vendor/font-awesome/less/stacked.less | 20 + .../vendor/font-awesome/less/variables.less | 800 + .../vendor/font-awesome/scss/_animated.scss | 34 + .../font-awesome/scss/_bordered-pulled.scss | 25 + .../vendor/font-awesome/scss/_core.scss | 12 + .../font-awesome/scss/_fixed-width.scss | 6 + .../vendor/font-awesome/scss/_icons.scss | 789 + .../vendor/font-awesome/scss/_larger.scss | 13 + .../vendor/font-awesome/scss/_list.scss | 19 + .../vendor/font-awesome/scss/_mixins.scss | 60 + .../vendor/font-awesome/scss/_path.scss | 15 + .../font-awesome/scss/_rotated-flipped.scss | 20 + .../font-awesome/scss/_screen-reader.scss | 5 + .../vendor/font-awesome/scss/_stacked.scss | 20 + .../vendor/font-awesome/scss/_variables.scss | 800 + .../font-awesome/scss/font-awesome.scss | 18 + .../html/static/vendor/hls.js/hls.js | 18209 +++++++++++++++ .../jquery.easing.compatibility.js | 59 + .../vendor/jquery-easing/jquery.easing.js | 166 + .../vendor/jquery-easing/jquery.easing.min.js | 1 + .../vendor/jquery-ui/jquery-ui-1.12.1.css | 1311 ++ .../vendor/jquery-ui/jquery-ui-1.12.1.js | 18706 ++++++++++++++++ .../html/static/vendor/jquery/jquery.js | 10364 +++++++++ .../html/static/vendor/jquery/jquery.min.js | 2 + .../html/static/vendor/jquery/jquery.min.map | 1 + .../html/static/vendor/jquery/jquery.slim.js | 8269 +++++++ .../static/vendor/jquery/jquery.slim.min.js | 2 + .../static/vendor/jquery/jquery.slim.min.map | 1 + .../static/vendor/knockout/knockout-3.5.0.js | 138 + .../magnific-popup/jquery.magnific-popup.js | 1860 ++ .../jquery.magnific-popup.min.js | 4 + .../vendor/magnific-popup/magnific-popup.css | 351 + .../static/vendor/notify.js/notify.min.js | 1 + 97 files changed, 102887 insertions(+), 10 deletions(-) rename {client/src/main/java/ctbrec/docs => common/src/main/java/ctbrec/servlet}/StaticFileServlet.java (77%) create mode 100644 server/src/main/resources/html/static/button-red.png create mode 100644 server/src/main/resources/html/static/custom.css create mode 100644 server/src/main/resources/html/static/favicon.png create mode 100644 server/src/main/resources/html/static/freelancer.css create mode 100644 server/src/main/resources/html/static/freelancer.min.js create mode 100644 server/src/main/resources/html/static/icon64.png create mode 100644 server/src/main/resources/html/static/index.html create mode 100644 server/src/main/resources/html/static/modal.js create mode 100644 server/src/main/resources/html/static/vendor/bootstrap/css/bootstrap-grid.css create mode 100644 server/src/main/resources/html/static/vendor/bootstrap/css/bootstrap-grid.min.css create mode 100644 server/src/main/resources/html/static/vendor/bootstrap/css/bootstrap-reboot.css create mode 100644 server/src/main/resources/html/static/vendor/bootstrap/css/bootstrap-reboot.min.css create mode 100644 server/src/main/resources/html/static/vendor/bootstrap/css/bootstrap.css create mode 100644 server/src/main/resources/html/static/vendor/bootstrap/css/bootstrap.css.map create mode 100644 server/src/main/resources/html/static/vendor/bootstrap/css/bootstrap.min.css create mode 100644 server/src/main/resources/html/static/vendor/bootstrap/css/bootstrap.min.css.map create mode 100644 server/src/main/resources/html/static/vendor/bootstrap/js/bootstrap.bundle.js create mode 100644 server/src/main/resources/html/static/vendor/bootstrap/js/bootstrap.bundle.js.map create mode 100644 server/src/main/resources/html/static/vendor/bootstrap/js/bootstrap.bundle.min.js create mode 100644 server/src/main/resources/html/static/vendor/bootstrap/js/bootstrap.bundle.min.js.map create mode 100644 server/src/main/resources/html/static/vendor/bootstrap/js/bootstrap.js create mode 100644 server/src/main/resources/html/static/vendor/bootstrap/js/bootstrap.js.map create mode 100644 server/src/main/resources/html/static/vendor/bootstrap/js/bootstrap.min.js create mode 100644 server/src/main/resources/html/static/vendor/bootstrap/js/bootstrap.min.js.map create mode 100644 server/src/main/resources/html/static/vendor/flowplayer/LICENSE.md create mode 100644 server/src/main/resources/html/static/vendor/flowplayer/flowplayer.js create mode 100644 server/src/main/resources/html/static/vendor/flowplayer/flowplayer.min.js create mode 100644 server/src/main/resources/html/static/vendor/flowplayer/flowplayer.swf create mode 100644 server/src/main/resources/html/static/vendor/flowplayer/flowplayerhls.swf create mode 100644 server/src/main/resources/html/static/vendor/flowplayer/index.html create mode 100755 server/src/main/resources/html/static/vendor/flowplayer/skin/icons/flowplayer.eot create mode 100755 server/src/main/resources/html/static/vendor/flowplayer/skin/icons/flowplayer.svg create mode 100755 server/src/main/resources/html/static/vendor/flowplayer/skin/icons/flowplayer.ttf create mode 100755 server/src/main/resources/html/static/vendor/flowplayer/skin/icons/flowplayer.woff create mode 100644 server/src/main/resources/html/static/vendor/flowplayer/skin/icons/flowplayer.woff2 create mode 100644 server/src/main/resources/html/static/vendor/flowplayer/skin/skin.css create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/css/font-awesome.css create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/css/font-awesome.css.map create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/css/font-awesome.min.css create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/fonts/FontAwesome.otf create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/fonts/fontawesome-webfont.eot create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/fonts/fontawesome-webfont.svg create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/fonts/fontawesome-webfont.ttf create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/fonts/fontawesome-webfont.woff create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/fonts/fontawesome-webfont.woff2 create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/less/animated.less create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/less/bordered-pulled.less create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/less/core.less create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/less/fixed-width.less create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/less/font-awesome.less create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/less/icons.less create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/less/larger.less create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/less/list.less create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/less/mixins.less create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/less/path.less create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/less/rotated-flipped.less create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/less/screen-reader.less create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/less/stacked.less create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/less/variables.less create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/scss/_animated.scss create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/scss/_bordered-pulled.scss create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/scss/_core.scss create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/scss/_fixed-width.scss create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/scss/_icons.scss create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/scss/_larger.scss create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/scss/_list.scss create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/scss/_mixins.scss create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/scss/_path.scss create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/scss/_rotated-flipped.scss create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/scss/_screen-reader.scss create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/scss/_stacked.scss create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/scss/_variables.scss create mode 100644 server/src/main/resources/html/static/vendor/font-awesome/scss/font-awesome.scss create mode 100644 server/src/main/resources/html/static/vendor/hls.js/hls.js create mode 100755 server/src/main/resources/html/static/vendor/jquery-easing/jquery.easing.compatibility.js create mode 100755 server/src/main/resources/html/static/vendor/jquery-easing/jquery.easing.js create mode 100755 server/src/main/resources/html/static/vendor/jquery-easing/jquery.easing.min.js create mode 100644 server/src/main/resources/html/static/vendor/jquery-ui/jquery-ui-1.12.1.css create mode 100644 server/src/main/resources/html/static/vendor/jquery-ui/jquery-ui-1.12.1.js create mode 100644 server/src/main/resources/html/static/vendor/jquery/jquery.js create mode 100644 server/src/main/resources/html/static/vendor/jquery/jquery.min.js create mode 100644 server/src/main/resources/html/static/vendor/jquery/jquery.min.map create mode 100644 server/src/main/resources/html/static/vendor/jquery/jquery.slim.js create mode 100644 server/src/main/resources/html/static/vendor/jquery/jquery.slim.min.js create mode 100644 server/src/main/resources/html/static/vendor/jquery/jquery.slim.min.map create mode 100644 server/src/main/resources/html/static/vendor/knockout/knockout-3.5.0.js create mode 100644 server/src/main/resources/html/static/vendor/magnific-popup/jquery.magnific-popup.js create mode 100644 server/src/main/resources/html/static/vendor/magnific-popup/jquery.magnific-popup.min.js create mode 100644 server/src/main/resources/html/static/vendor/magnific-popup/magnific-popup.css create mode 100644 server/src/main/resources/html/static/vendor/notify.js/notify.min.js diff --git a/client/pom.xml b/client/pom.xml index c42664ee..1646238e 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -85,12 +85,10 @@ org.eclipse.jetty jetty-server - [9.3.24.v20180605,) org.eclipse.jetty jetty-servlet - [9.3.24.v20180605,) com.vladsch.flexmark diff --git a/client/src/main/java/ctbrec/docs/DocServer.java b/client/src/main/java/ctbrec/docs/DocServer.java index 141e6bb6..95ede4ee 100644 --- a/client/src/main/java/ctbrec/docs/DocServer.java +++ b/client/src/main/java/ctbrec/docs/DocServer.java @@ -13,6 +13,8 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import ctbrec.servlet.StaticFileServlet; + public class DocServer { private static final transient Logger LOG = LoggerFactory.getLogger(DocServer.class); @@ -46,7 +48,7 @@ public class DocServer { holder = new ServletHolder(searchServlet); handler.addServletWithMapping(holder, "/search/*"); - StaticFileServlet staticFileServlet = new StaticFileServlet(); + StaticFileServlet staticFileServlet = new StaticFileServlet("/html"); holder = new ServletHolder(staticFileServlet); handler.addServletWithMapping(holder, "/static/*"); diff --git a/common/pom.xml b/common/pom.xml index a9ef1c99..369f0fb0 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -60,6 +60,12 @@ javafx-media provided + + javax.servlet + javax.servlet-api + 3.1.0 + provided + junit junit diff --git a/client/src/main/java/ctbrec/docs/StaticFileServlet.java b/common/src/main/java/ctbrec/servlet/StaticFileServlet.java similarity index 77% rename from client/src/main/java/ctbrec/docs/StaticFileServlet.java rename to common/src/main/java/ctbrec/servlet/StaticFileServlet.java index b195a3db..5d47fc54 100644 --- a/client/src/main/java/ctbrec/docs/StaticFileServlet.java +++ b/common/src/main/java/ctbrec/servlet/StaticFileServlet.java @@ -1,8 +1,9 @@ -package ctbrec.docs; +package ctbrec.servlet; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.URLConnection; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -11,6 +12,12 @@ import javax.servlet.http.HttpServletResponse; public class StaticFileServlet extends HttpServlet { + private String classPathRoot; + + public StaticFileServlet(String classPathRoot) { + this.classPathRoot = classPathRoot; + } + @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String request = req.getRequestURI(); @@ -23,10 +30,12 @@ public class StaticFileServlet extends HttpServlet { } private void serveFile(String resource, HttpServletResponse resp) throws IOException { - InputStream resourceAsStream = getClass().getResourceAsStream("/html" + resource); + InputStream resourceAsStream = getClass().getResourceAsStream(classPathRoot + resource); if(resourceAsStream == null) { throw new FileNotFoundException(); } + resp.setContentType(URLConnection.guessContentTypeFromName(resource)); + resp.setStatus(HttpServletResponse.SC_OK); OutputStream out = resp.getOutputStream(); int length = 0; byte[] buffer = new byte[1024]; diff --git a/master/pom.xml b/master/pom.xml index af91e73c..d0129d40 100644 --- a/master/pom.xml +++ b/master/pom.xml @@ -5,9 +5,9 @@ 4.0.0 ctbrec master - pom + pom 2.0.1 - + ../common ../client @@ -17,7 +17,7 @@ UTF-8 - + @@ -101,6 +101,16 @@ 4.12 test + + org.eclipse.jetty + jetty-server + [9.4.19.v20190610,9.99.99) + + + org.eclipse.jetty + jetty-servlet + [9.4.19.v20190610,9.99.99) + diff --git a/server/pom.xml b/server/pom.xml index b7bddc1e..b41e5edb 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -81,12 +81,10 @@ org.eclipse.jetty jetty-server - [9.3.24.v20180605,) org.eclipse.jetty jetty-servlet - [9.3.24.v20180605,) junit diff --git a/server/src/main/java/ctbrec/recorder/server/HttpServer.java b/server/src/main/java/ctbrec/recorder/server/HttpServer.java index ff270d1b..56d1f14a 100644 --- a/server/src/main/java/ctbrec/recorder/server/HttpServer.java +++ b/server/src/main/java/ctbrec/recorder/server/HttpServer.java @@ -27,6 +27,7 @@ import ctbrec.event.EventHandlerConfiguration; import ctbrec.recorder.NextGenLocalRecorder; import ctbrec.recorder.OnlineMonitor; import ctbrec.recorder.Recorder; +import ctbrec.servlet.StaticFileServlet; import ctbrec.sites.Site; import ctbrec.sites.bonga.BongaCams; import ctbrec.sites.cam4.Cam4; @@ -142,6 +143,12 @@ public class HttpServer { holder = new ServletHolder(hlsServlet); handler.addServletWithMapping(holder, "/hls/*"); + String staticContext = "/static/*"; + LOG.info("Register static file servlet under {}", staticContext); + StaticFileServlet staticFileServlet = new StaticFileServlet("/html"); + holder = new ServletHolder(staticFileServlet); + handler.addServletWithMapping(holder, staticContext); + try { server.start(); server.join(); diff --git a/server/src/main/resources/html/static/button-red.png b/server/src/main/resources/html/static/button-red.png new file mode 100644 index 0000000000000000000000000000000000000000..cbf846bc6d7ceb1d6a31f619c5127c1ca1640527 GIT binary patch literal 6338 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