diff --git a/.idea/libraries/Ceylon__org_takes_takes_1_16.xml b/.idea/libraries/Ceylon__org_takes_takes_1_16.xml
new file mode 100644
index 0000000000..0db8efd94b
--- /dev/null
+++ b/.idea/libraries/Ceylon__org_takes_takes_1_16.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/resource/strategicprimer/drivers/gui/common/about.html b/resource/strategicprimer/drivers/gui/common/about.html
index a1f0e2e9d5..9be7673fb0 100644
--- a/resource/strategicprimer/drivers/gui/common/about.html
+++ b/resource/strategicprimer/drivers/gui/common/about.html
@@ -41,6 +41,8 @@
App Name Here
The Window menu is managed by a library by Jeremy Wood from his Pumpernickel
project on GitHub.)
+ The embedded Web server in the report generator and tabular report generator is
+ the Takes library.
Code snippets originally taken (though subsequently modified) from
diff --git a/source/strategicprimer/viewer/drivers/report.ceylon b/source/strategicprimer/viewer/drivers/report.ceylon
index 6918a4a70d..edac7a289c 100644
--- a/source/strategicprimer/viewer/drivers/report.ceylon
+++ b/source/strategicprimer/viewer/drivers/report.ceylon
@@ -60,26 +60,6 @@ import ceylon.collection {
MutableSet,
HashSet
}
-import ceylon.io {
- SocketAddress
-}
-import ceylon.http.server {
- newServer,
- AsynchronousEndpoint,
- Endpoint,
- Request,
- Response,
- startsWith,
- matchEquals=equals,
- isRoot
-}
-import ceylon.http.server.endpoints {
- redirect
-}
-import ceylon.http.common {
- get,
- Header
-}
import lovelace.util.common {
matchingValue,
silentListener,
@@ -89,6 +69,24 @@ import lovelace.util.common {
import lovelace.util.jvm {
FileChooser
}
+import org.takes.facets.fork {
+ Fork,
+ FkRegex,
+ TkFork
+}
+import org.takes.rs {
+ RsHtml,
+ RsWithType,
+ RsWithHeader,
+ RsText
+}
+import org.takes.tk {
+ TkRedirect
+}
+import org.takes.http {
+ FtBasic,
+ Exit
+}
"An object to help us present files with only as much of their paths as
necessary to uniquely identify them, without their shared prefix."
@@ -139,7 +137,7 @@ shared class ReportCLIFactory() satisfies ModelDriverFactory {
shared actual IDriverUsage usage = DriverUsage {
graphical = false;
invocations = ["create-report"];
- paramsWanted = ParamCount.one;
+ paramsWanted = ParamCount.atLeastOne;
shortDescription = "Report Generator";
longDescription = "Produce HTML report of the contents of a map";
includeInCLIList = true;
@@ -187,48 +185,36 @@ class ReportServingCLI(SPOptions options, model) satisfies ReadOnlyDriver {
value localCache = cache.map(
(file->report) => suffixHelper.shortestSuffix(cache.keys,
file.absolutePath)->report);
- {Endpoint*} endpoints = localCache.map((file->report) =>
- Endpoint {
- path = startsWith("/``file``");
- service(Request request, Response response) =>
- response.writeString(report);
- });
- Endpoint|AsynchronousEndpoint rootHandler;
+ {Fork*} endpoints = localCache.map((file->report) => FkRegex("/``file``",
+ RsHtml(report)));
+ Fork rootHandler;
if (localCache.size == 1) {
assert (exists soleFile = localCache.first?.key);
- rootHandler = AsynchronousEndpoint {
- path = isRoot();
- acceptMethod = [ get ];
- service = redirect("/" + soleFile);
- };
+ rootHandler = FkRegex("/", TkRedirect("/" + soleFile));
} else {
- rootHandler = Endpoint {
- path = isRoot();
- void service(Request request, Response response) {
- response.writeString(
- "
-
-
- Strategic Primer Reports
-
-
- Strategic Primer Reports
-
- ");
- for (file->report in localCache) {
- response.writeString(
- " - ``file``
");
- }
- response.writeString("
-
- ");
- }
- };
+ StringBuilder builder = StringBuilder();
+ builder.append(
+ """
+
+
+ Strategic Primer Reports
+
+
+ Strategic Primer Reports
+
+ """);
+ for (file->report in localCache) {
+ builder.appendAll([" - ", file,
+ "
"]);
+ builder.appendNewline();
+ }
+ builder.append("""
+
+ """);
+ rootHandler = FkRegex("/", RsHtml(builder.string));
}
log.info("About to start serving on port ``port``");
- newServer {
- rootHandler, *endpoints
- }.start(SocketAddress("127.0.0.1", port));
+ FtBasic(TkFork(rootHandler, *endpoints), port).start(Exit.never);
}
}
@@ -465,72 +451,66 @@ class TabularReportServingCLI(SPOptions options, model) satisfies ReadOnlyDriver
parsePath(model.mapFile?.filename else "unknown.xml"));
}
- {Endpoint*} endpoints = builders.map(([file, table]->builder) =>
- Endpoint {
- path = matchEquals("/``file``.``table``.csv");
- void service(Request request, Response response) {
- response.addHeader(Header("Content-Disposition",
- "attachment; filename=\"``table``.csv\""));
- response.writeString(builder.string);
- }
- });
-
- {Endpoint*} tocs = mapping.keys
- .map(curry(suffixHelper.shortestSuffix)(mapping.keys)).map(
- (path) => Endpoint {
- path = matchEquals("/``path``").or(matchEquals("/``path``/"));
- void service(Request request, Response response) {
- response.writeString(
- "
-
-
- Tabular reports for ``path``
-
-
- Tabular reports for ``path``
-
- ");
- for ([mapFile, table] in builders.keys
- .filter(matchingValue(path,
- Tuple.first))) {
- response.writeString(" - ``table``.csv
\n");
- }
- response.writeString("
-
- ");
- }
- });
-
- Endpoint rootHandler = Endpoint {
- path = isRoot();
- void service(Request request, Response response) {
- response.writeString(
- "
-
-
- Strategic Primer Tabular Reports
-
-
- Strategic Primer Tabular Reports
-
- ");
- for (file in mapping.keys
- .map(curry(suffixHelper.shortestSuffix)(mapping.keys))) {
- response.writeString(
- " - ``file``
");
- }
- response.writeString(
- "
-
- ");
+ {Fork*} endpoints = builders
+ .map(([file, table]->builder) => FkRegex("/``file``.``table``.csv",
+ RsWithType(RsWithHeader(RsText(builder.string),
+ "Content-Disposition", "attachment; filename=\"``table``.csv\""),
+ "text/csv")));
+ String tocHtml(String path) {
+ StringBuilder builder = StringBuilder();
+ builder.append(
+ "
+
+
+ Tabular reports for ``path``
+
+
+ Tabular reports for ``path``
+
+ ");
+ for ([mapFile, table] in builders.keys.filter(matchingValue(path,
+ Tuple.first))) {
+ builder.appendAll([" - ", table, ".csv
"]);
+ builder.appendNewline();
}
- };
+ builder.append(
+ """
+
+ """);
+ return builder.string;
+ }
+ {Fork*} tocs = mapping.keys.map(curry(suffixHelper.shortestSuffix)(mapping.keys))
+ .flatMap(
+ (path) => [FkRegex("/``path``", RsHtml(tocHtml(path))),
+ FkRegex("/``path``/", RsHtml(tocHtml(path)))]);
+
+ StringBuilder rootDocument = StringBuilder();
+ rootDocument.append(
+ """
+
+
+ Strategic Primer Tabular Reports
+
+
+ Strategic Primer Tabular Reports
+
+ """);
+ for (file in mapping.keys.map(curry(suffixHelper.shortestSuffix)(mapping.keys))) {
+ rootDocument.appendAll([" - ", file,
+ "
"]);
+ rootDocument.appendNewline();
+ }
+ rootDocument.append(
+ """
+
+ """);
log.info("About to start serving on port ``port``");
- newServer {
- rootHandler, *endpoints.chain(tocs)
- }.start(SocketAddress("127.0.0.1", port));
+ FtBasic(
+ TkFork(FkRegex("/", RsHtml(rootDocument.string)), FkRegex("/index.html",
+ RsHtml(rootDocument.string)), *tocs.chain(endpoints).sequence()), port)
+ .start(Exit.never);
}
shared actual void startDriver() {
diff --git a/source/strategicprimer/viewer/module.ceylon b/source/strategicprimer/viewer/module.ceylon
index d41d8196b7..77824dc34b 100644
--- a/source/strategicprimer/viewer/module.ceylon
+++ b/source/strategicprimer/viewer/module.ceylon
@@ -34,7 +34,8 @@ module strategicprimer.viewer "0.4.9018" {
import strategicprimer.drivers.generators spVersion;
shared import strategicprimer.drivers.gui.common spVersion;
import strategicprimer.drivers.utility spVersion;
- import ceylon.http.server ceylonVersion;
+// import ceylon.http.server ceylonVersion;
+ import maven:"org.takes:takes" "1.16";
import com.vasileff.ceylon.structures "1.1.3";
import strategicprimer.mining spVersion;
import strategicprimer.drivers.query spVersion;
diff --git a/viewer-ceylon.iml b/viewer-ceylon.iml
index d8b63eb2ae..dd9b561fd0 100644
--- a/viewer-ceylon.iml
+++ b/viewer-ceylon.iml
@@ -29,10 +29,7 @@
-
-
-
@@ -42,12 +39,9 @@
-
-
-
-
+
\ No newline at end of file