diff --git a/README.md b/README.md
index 2e99c39..68bca8d 100644
--- a/README.md
+++ b/README.md
@@ -1,18 +1,13 @@
-## Part of the overall MicroWorld system
+## Part of the overall Microworld system
*mw-ui* is not a stand-alone project. To use it you also need at least
[mw-parser](https://github.com/simon-brooke/mw-parser) and
[mw-engine](https://github.com/simon-brooke/mw-engine). There will be other
modules in due course.
-You can see MicroWorld in action [here](http://www.journeyman.cc/microworld/) -
-but please don't be mean to my poor little server. If you want to run big maps
-or complex rule-sets, please run it on your own machines.
-
## What this is about
-
+
MicroWorld is a rule driven cellular automaton. What does that mean? Well, it's
a two dimensional world made up of squares called **cells**. The world develops
in steps, and at each step, each cell is modified by applying the rules.
diff --git a/project.clj b/project.clj
index e280238..cee94af 100644
--- a/project.clj
+++ b/project.clj
@@ -8,18 +8,21 @@
"build-signature-timestamp" "unset"
"Implementation-Version" "unset"
}
- :dependencies [[org.clojure/clojure "1.6.0"]
- [mw-engine "0.1.5-SNAPSHOT"]
- [mw-parser "0.1.5-SNAPSHOT"]
- [lib-noir "0.8.4"]
- [ring-server "0.3.1"]
- [selmer "0.6.8"]
+ :dependencies [[org.clojure/clojure "1.8.0"]
+ [mw-engine "3.0.0-SNAPSHOT"]
+ [mw-parser "3.0.0-SNAPSHOT"]
+ [lib-noir "0.9.9"]
+ [ring-server "0.4.0"]
+ [selmer "1.0.9"]
[com.taoensso/timbre "3.2.1"]
- [com.taoensso/tower "2.0.2"]
- [markdown-clj "0.9.44"]
- [environ "0.5.0"]
- [noir-exception "0.2.2"]]
+ [com.taoensso/tower "3.0.2"]
+ [markdown-clj "0.9.89"]
+ [environ "1.1.0"]
+ [noir-exception "0.2.5"]]
+ :source-paths ["src/clj" "src/cljc"]
+ :license {:name "GNU General Public License v2"
+ :url "http://www.gnu.org/licenses/gpl-2.0.html"}
:repl-options {:init-ns mw-ui.repl}
:plugins [[lein-ring "0.8.11"]
[lein-environ "0.5.0"]
@@ -37,8 +40,8 @@
:stacktraces? false
:auto-reload? false}}
:dev {:dependencies [[ring-mock "0.1.5"]
- [ring/ring-devel "1.3.0"]
- [pjstadig/humane-test-output "0.6.0"]]
+ [ring/ring-devel "1.5.0"]
+ [pjstadig/humane-test-output "0.8.1"]]
:injections [(require 'pjstadig.humane-test-output)
(pjstadig.humane-test-output/activate!)]
:env {:dev true}}}
diff --git a/resources/public/css/standard.css b/resources/public/css/standard.css
index 131a881..62f3189 100644
--- a/resources/public/css/standard.css
+++ b/resources/public/css/standard.css
@@ -6,7 +6,7 @@ body {
/* Overall container div, holds all content of page. Yes, I know it shouldn't have fixed width */
#main-container{
clear: both;
-/* width:100%; */
+ width:100%;
}
/* footer of the document */
@@ -145,4 +145,3 @@ th, td {
text-align: left;
padding: 0 0.25em;
}
-
diff --git a/resources/templates/base.html b/resources/templates/base.html
index 35c830b..46fe376 100644
--- a/resources/templates/base.html
+++ b/resources/templates/base.html
@@ -3,11 +3,7 @@
{% endif %}
@@ -57,7 +55,8 @@
Built with LuminusWeb ||
Powered by Clojure ||
Engineering and hosting by Journeyman ||
- World generated using MicroWorld Engine
+ World generated using MicroWorld Engine ||
+ Version {{version}}
diff --git a/resources/templates/inspector.html b/resources/templates/inspector.html
index 7ba60b3..35441df 100644
--- a/resources/templates/inspector.html
+++ b/resources/templates/inspector.html
@@ -4,6 +4,7 @@
{{content|safe}}
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/src/mw_ui/handler.clj b/src/clj/mw_ui/handler.clj
similarity index 62%
rename from src/mw_ui/handler.clj
rename to src/clj/mw_ui/handler.clj
index 7e614d1..66d7fe7 100644
--- a/src/mw_ui/handler.clj
+++ b/src/clj/mw_ui/handler.clj
@@ -1,4 +1,6 @@
-(ns mw-ui.handler
+(ns ^{:doc "Set up and tear down the request handler."
+ :author "Simon Brooke"}
+ mw-ui.handler
(:require [compojure.core :refer [defroutes]]
[mw-ui.routes.home :refer [home-routes]]
[mw-ui.middleware :refer [load-middleware]]
@@ -10,10 +12,34 @@
[selmer.parser :as parser]
[environ.core :refer [env]]))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;
+;;;; mw-ui: a servlet user/visualisation interface for MicroWorld.
+;;;;
+;;;; This program is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU General Public License
+;;;; as published by the Free Software Foundation; either version 2
+;;;; of the License, or (at your option) any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;;; USA.
+;;;;
+;;;; Copyright (C) 2014 Simon Brooke
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
(defroutes app-routes
(route/resources "/")
(route/not-found "Not Found"))
+
(defn init
"init will be called once when
app is deployed as a servlet on
@@ -27,14 +53,15 @@
:async? false ; should be always false for rotor
:max-message-per-msecs nil
:fn rotor/appender-fn})
-
(timbre/set-config!
[:shared-appender-config :rotor]
{:path "mw_ui.log" :max-size (* 512 1024) :backlog 10})
+
(if (env :dev) (parser/cache-off!))
(timbre/info "mw-ui started successfully"))
+
(defn destroy
"destroy will be called when your application
shuts down, put any clean up code here"
@@ -42,7 +69,6 @@
(timbre/info "mw-ui is shutting down..."))
-
(def app (app-handler
;; add your application routes here
[home-routes app-routes]
diff --git a/src/clj/mw_ui/layout.clj b/src/clj/mw_ui/layout.clj
new file mode 100644
index 0000000..3754943
--- /dev/null
+++ b/src/clj/mw_ui/layout.clj
@@ -0,0 +1,54 @@
+(ns ^{:doc "Layout content as HTML."
+ :author "Simon Brooke"}
+ mw-ui.layout
+ (:require [selmer.parser :as parser]
+ [clojure.string :as s]
+ [ring.util.response :refer [content-type response]]
+ [ring.util.anti-forgery :refer [anti-forgery-field]]
+ [compojure.response :refer [Renderable]]))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;
+;;;; mw-ui: a servlet user/visualisation interface for MicroWorld.
+;;;;
+;;;; This program is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU General Public License
+;;;; as published by the Free Software Foundation; either version 2
+;;;; of the License, or (at your option) any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;;; USA.
+;;;;
+;;;; Copyright (C) 2014 Simon Brooke
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+(def template-path "templates/")
+
+(parser/add-tag! :csrf-field (fn [_ _] (anti-forgery-field)))
+
+(deftype RenderableTemplate [template params]
+ Renderable
+ (render [this request]
+ (content-type
+ (->> (assoc (merge params {:version (System/getProperty "mw-ui.version")})
+ (keyword (s/replace template #".html" "-selected")) "active"
+ :servlet-context
+ (if-let [context (:servlet-context request)]
+ (.getContextPath context)))
+ (parser/render-file (str template-path template))
+ response)
+ "text/html; charset=utf-8")))
+
+
+(defn render [template & [params]]
+ (RenderableTemplate. template params))
+
diff --git a/src/clj/mw_ui/middleware.clj b/src/clj/mw_ui/middleware.clj
new file mode 100644
index 0000000..99c1a34
--- /dev/null
+++ b/src/clj/mw_ui/middleware.clj
@@ -0,0 +1,53 @@
+(ns ^{:doc "In truth, boilerplate from Luminus."
+ :author "Simon Brooke"}
+ mw-ui.middleware
+ (:require [taoensso.timbre :as timbre]
+ [selmer.parser :as parser]
+ [environ.core :refer [env]]
+ [selmer.middleware :refer [wrap-error-page]]
+ [noir-exception.core
+ :refer [wrap-internal-error wrap-exceptions]]))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;
+;;;; mw-ui: a servlet user/visualisation interface for MicroWorld.
+;;;;
+;;;; This program is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU General Public License
+;;;; as published by the Free Software Foundation; either version 2
+;;;; of the License, or (at your option) any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;;; USA.
+;;;;
+;;;; Copyright (C) 2014 Simon Brooke
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+(defn log-request [handler]
+ (fn [req]
+ (timbre/debug req)
+ (handler req)))
+
+
+(def development-middleware
+ [log-request
+ wrap-error-page
+ wrap-exceptions])
+
+
+(def production-middleware
+ [#(wrap-internal-error % :log (fn [e] (timbre/error e)))])
+
+
+(defn load-middleware []
+ (concat (when (env :dev) development-middleware)
+ production-middleware))
diff --git a/src/mw_ui/render_world.clj b/src/clj/mw_ui/render_world.clj
similarity index 58%
rename from src/mw_ui/render_world.clj
rename to src/clj/mw_ui/render_world.clj
index 9d103d5..df7eb2b 100644
--- a/src/mw_ui/render_world.clj
+++ b/src/clj/mw_ui/render_world.clj
@@ -1,28 +1,56 @@
-(ns mw-ui.render-world
+(ns ^{:doc "Render the state of the world as an HTML table."
+ :author "Simon Brooke"}
+ mw-ui.render-world
(:require [clojure.java.io :as jio]
- [mw-engine.core :as engine]
- [mw-engine.world :as world]
- [mw-engine.heightmap :as heightmap]
- [mw-parser.bulk :as compiler]
+ [microworld.engine.core :as engine]
+ [microworld.engine.world :as world]
+ [microworld.engine.heightmap :as heightmap]
+ [microworld.parser.bulk :as compiler]
[hiccup.core :refer [html]]
[noir.io :as io]
[noir.session :as session]))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;
+;;;; mw-ui: a servlet user/visualisation interface for MicroWorld.
+;;;;
+;;;; This program is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU General Public License
+;;;; as published by the Free Software Foundation; either version 2
+;;;; of the License, or (at your option) any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;;; USA.
+;;;;
+;;;; Copyright (C) 2014 Simon Brooke
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
(defn format-css-class [statekey]
"Format this statekey, assumed to be a keyword indicating a state in the
world, into a CSS class"
(subs (str statekey) 1))
+
(defn format-image-path
"Render this statekey, assumed to be a keyword indicating a state in the
world, into a path which should recover the corresponding image file."
[statekey]
(format "img/tiles/%s.png" (format-css-class statekey)))
+
(defn format-mouseover [cell]
(str cell))
+
(defn render-cell
"Render this world cell as a Hiccup table cell."
[cell]
@@ -31,21 +59,22 @@
[:a {:href (format "inspect?x=%d&y=%d" (:x cell) (:y cell))}
[:img {:alt (:state cell) :src (format-image-path state)}]]]))
+
(defn render-world-row
"Render this world row as a Hiccup table row."
[row]
(apply vector (cons :tr (map render-cell row))))
+
(defn render-world-table
"Render the world implied by the current session as a complete HTML table in a DIV."
[]
(let [world (or (session/get :world)
- (heightmap/apply-heightmap
- (io/get-resource "/img/heightmaps/small_hill.png")))
+ (heightmap/apply-heightmap "public/img/heightmaps/small_hill.png"))
rules (or (session/get :rules)
(do (session/put! :rules
(compiler/compile-file
- (io/get-resource "/rulesets/basic.txt")))
+ (jio/resource "public/rulesets/basic.txt")))
(session/get :rules)))
generation (inc (or (session/get :generation) 0))
w2 (engine/transform-world world rules)
@@ -59,6 +88,7 @@
[:p
(str "Generation " generation)]]))
+
(defn render-inspector
"Render in Hiccup format the HTML content of an inspector on this cell."
[cell table]
diff --git a/src/mw_ui/repl.clj b/src/clj/mw_ui/repl.clj
similarity index 50%
rename from src/mw_ui/repl.clj
rename to src/clj/mw_ui/repl.clj
index 3563fac..e034f28 100644
--- a/src/mw_ui/repl.clj
+++ b/src/clj/mw_ui/repl.clj
@@ -1,9 +1,34 @@
-(ns mw-ui.repl
+(ns ^{:doc "In truth, boilerplate from Luminus."
+ :author "Simon Brooke"}
+ mw-ui.repl
(:use mw-ui.handler
ring.server.standalone
[ring.middleware file-info file])
- (:gen-class)
-)
+ (:gen-class))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;
+;;;; mw-ui: a servlet user/visualisation interface for MicroWorld.
+;;;;
+;;;; This program is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU General Public License
+;;;; as published by the Free Software Foundation; either version 2
+;;;; of the License, or (at your option) any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;;; USA.
+;;;;
+;;;; Copyright (C) 2014 Simon Brooke
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
(defonce server (atom nil))
diff --git a/src/mw_ui/routes/home.clj b/src/clj/mw_ui/routes/home.clj
similarity index 59%
rename from src/mw_ui/routes/home.clj
rename to src/clj/mw_ui/routes/home.clj
index ac779aa..4c40b4a 100644
--- a/src/mw_ui/routes/home.clj
+++ b/src/clj/mw_ui/routes/home.clj
@@ -1,9 +1,12 @@
-(ns mw-ui.routes.home
+(ns ^{:doc "Routes which serve the main pages of the application."
+ :author "Simon Brooke"}
+ mw-ui.routes.home
(:use clojure.walk
compojure.core)
- (:require [clojure.pprint :only [pprint]]
+ (:require [clojure.java.io :refer [file resource]]
+ [clojure.pprint :only [pprint]]
[hiccup.core :refer [html]]
- [mw-engine.utils :as engine-utils]
+ [microworld.engine.utils :as engine-utils]
[mw-ui.layout :as layout]
[mw-ui.render-world :as world]
[mw-ui.routes.load :as load]
@@ -15,31 +18,57 @@
[noir.session :as session]
[ring.util.response :as response]))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;
+;;;; mw-ui: a servlet user/visualisation interface for MicroWorld.
+;;;;
+;;;; This program is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU General Public License
+;;;; as published by the Free Software Foundation; either version 2
+;;;; of the License, or (at your option) any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;;; USA.
+;;;;
+;;;; Copyright (C) 2014 Simon Brooke
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
(defn list-states []
(sort
(filter #(not (nil? %))
(map #(first (rest (re-matches #"([0-9a-z-]+).png" (.getName %))))
- (file-seq (clojure.java.io/file "resources/public/img/tiles"))))))
+ (file-seq (resource "public/img/tiles"))))))
(defn about-page []
(layout/render "trusted-content.html"
{:title "About MicroWorld"
:about-selected "active"
- :content (util/md->html "/md/about.md")}))
+ :content (util/md->html "public/md/about.md")
+ :version (System/getProperty "mw-ui.version")}))
(defn docs-page []
(layout/render "docs.html" {:title "Documentation"
- :parser (util/md->html "/md/mw-parser.md" )
- :states (util/list-resources "/img/tiles" #"([0-9a-z-_]+).png")
- :lessons (util/list-resources "/md/lesson-plans" #"([0-9a-z-_]+).md")
- :components ["mw-engine" "mw-parser" "mw-ui"]}))
+ :parser (util/md->html "public/md/microworld.parser.md" )
+ :states (util/list-resources "public/img/tiles" #"([0-9a-z-_]+).png")
+ :lessons (util/list-resources "public/md/lesson-plans" #"([0-9a-z-_]+).md")
+ :components ["microworld.engine" "microworld.parser" "mw-ui"]
+ :version (System/getProperty "mw-ui.version")}))
(defn home-page []
"Render the home page."
(layout/render "trusted-content.html" {:title "Welcome to MicroWorld"
- :content (util/md->html "/md/mw-ui.md")}))
+ :content (util/md->html "public/md/mw-ui.md")
+ :version (System/getProperty "mw-ui.version")}))
(defn inspect-page [request]
"Open an inspector on the cell at the co-ordinates specified in this request"
@@ -63,7 +92,7 @@
:x (:x cell)
:y (:y cell)
:states (util/list-resources
- "/img/tiles" #"([0-9a-z-_]+).png")}))))
+ "public/img/tiles" #"([0-9a-z-_]+).png")}))))
(defn md-page
"Render the markdown page specified in this request, if any. Probably undesirable,
diff --git a/src/mw_ui/routes/load.clj b/src/clj/mw_ui/routes/load.clj
similarity index 53%
rename from src/mw_ui/routes/load.clj
rename to src/clj/mw_ui/routes/load.clj
index ce33831..0636ccf 100644
--- a/src/mw_ui/routes/load.clj
+++ b/src/clj/mw_ui/routes/load.clj
@@ -1,4 +1,6 @@
-(ns mw-ui.routes.load
+(ns ^{:doc "Route which handles the upload of worlds/rules from the client."
+ :author "Simon Brooke"}
+ mw-ui.routes.load
(:use clojure.walk
compojure.core)
(:require [hiccup.core :refer [html]]
@@ -8,6 +10,29 @@
[mw-ui.layout :as layout]
))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;
+;;;; mw-ui: a servlet user/visualisation interface for MicroWorld.
+;;;;
+;;;; This program is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU General Public License
+;;;; as published by the Free Software Foundation; either version 2
+;;;; of the License, or (at your option) any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;;; USA.
+;;;;
+;;;; Copyright (C) 2014 Simon Brooke
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
(defn- upload [file]
(io/upload-file "/tmp/" file)
@@ -16,6 +41,7 @@
(with-open [eddi (java.io.FileReader. (:tempfile file))] (read)))
(str "Successfully loaded your world from " (:filename file))))
+
(defn load-page
"If no args, show the load form; with args, load a world file from the client.
diff --git a/src/clj/mw_ui/routes/params.clj b/src/clj/mw_ui/routes/params.clj
new file mode 100644
index 0000000..19416d7
--- /dev/null
+++ b/src/clj/mw_ui/routes/params.clj
@@ -0,0 +1,85 @@
+(ns ^{:doc "Route which serves and handles the parameters page."
+ :author "Simon Brooke"}
+ mw-ui.routes.params
+ (:use clojure.walk
+ clojure.java.io
+ compojure.core)
+ (:require [clojure.java.io :refer [resource]]
+ [hiccup.core :refer [html]]
+ [microworld.engine.heightmap :as heightmap]
+ [microworld.parser.bulk :as compiler]
+ [mw-ui.layout :as layout]
+ [mw-ui.util :as util]
+ [mw-ui.render-world :as world]
+ [noir.io :as io]
+ [noir.session :as session]))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;
+;;;; mw-ui: a servlet user/visualisation interface for MicroWorld.
+;;;;
+;;;; This program is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU General Public License
+;;;; as published by the Free Software Foundation; either version 2
+;;;; of the License, or (at your option) any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;;; USA.
+;;;;
+;;;; Copyright (C) 2014 Simon Brooke
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+(defn- send-params []
+ {:title "Choose your world"
+ :heightmaps (util/list-resources "public/img/heightmaps" #"([0-9a-z-_]+).png")
+ :pause (or (session/get :pause) 5)
+ :rulesets (util/list-resources "public/rulesets" #"([0-9a-z-_]+).txt")
+ })
+
+
+(defn params-page
+ "Handler for params request. If no `request` passed, show empty params form.
+ If `request` is passed, put parameters from request into session and show
+ the world page."
+ ([]
+ (layout/render "params.html" (send-params)))
+ ([request]
+ (try
+ (let [params (keywordize-keys (:form-params request))
+ map (:heightmap params)
+ pause (:pause params)
+ rulefile (:ruleset params)
+ rulepath (str "public/rulesets/" rulefile ".txt")]
+ (if (not= map "")
+ (session/put! :world
+ (heightmap/apply-heightmap
+ (resource (str "public/img/heightmaps/" map ".png")))))
+ (when (not= rulefile "")
+ (session/put! :rule-text (io/slurp-resource rulepath))
+ (session/put! :rules (compiler/compile-file (resource rulepath))))
+ (if (not= pause "")
+ (session/put! :pause pause))
+ (layout/render "params.html"
+ (merge (send-params)
+ {:r rulefile
+ :h map
+ :message "Your parameters are saved, now look at your world"})))
+ (catch Exception e
+ (let [params (keywordize-keys (:form-params request))]
+ (layout/render "params.html"
+ (merge (send-params)
+ {:title "Choose your world"
+ :r (:ruleset params)
+ :h (:heightmap params)
+ :message "Your paramters are not saved"
+ :error (str (.getName (.getClass e)) ": " (.getMessage e) "; " params)}
+ )))))))
diff --git a/src/mw_ui/routes/rules.clj b/src/clj/mw_ui/routes/rules.clj
similarity index 50%
rename from src/mw_ui/routes/rules.clj
rename to src/clj/mw_ui/routes/rules.clj
index 7512605..8f128aa 100644
--- a/src/mw_ui/routes/rules.clj
+++ b/src/clj/mw_ui/routes/rules.clj
@@ -1,8 +1,10 @@
-(ns mw-ui.routes.rules
+(ns ^{:doc "Route which serves and handles the rules page."
+ :author "Simon Brooke"}
+ mw-ui.routes.rules
(:use clojure.walk
compojure.core)
(:require [hiccup.core :refer [html]]
- [mw-parser.bulk :as compiler]
+ [microworld.parser.bulk :as compiler]
[mw-ui.layout :as layout]
[mw-ui.util :as util]
[mw-ui.render-world :as world]
@@ -10,31 +12,56 @@
[noir.session :as session]
[ring.util.response :as response]))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;
+;;;; mw-ui: a servlet user/visualisation interface for MicroWorld.
+;;;;
+;;;; This program is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU General Public License
+;;;; as published by the Free Software Foundation; either version 2
+;;;; of the License, or (at your option) any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;;; USA.
+;;;;
+;;;; Copyright (C) 2014 Simon Brooke
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
(defn process-rules-request
[request]
(let [src (:src (keywordize-keys (:form-params request)))]
- (try
- (cond src
+ (try
+ (cond src
(let [rules (compiler/compile-string src)]
{:rule-text src
:rules rules
- :message (str "Successfully compiled "
- (count rules)
+ :message (str "Successfully compiled "
+ (count rules)
" rules") })
- true {:rule-text (or
- (session/get :rule-text)
+ true {:rule-text (or
+ (session/get :rule-text)
(io/slurp-resource "/rulesets/basic.txt"))
:message "No rules found in request; loading defaults"})
- (catch Exception e
+ (catch Exception e
{:rule-text src
:message "An error occurred during compilation"
:error (str (.getName (.getClass e)) ": " (.getMessage e))}))))
-(defn rules-page
+
+(defn rules-page
"Request handler for the `rules` request. If the `request` contains a value
- for `:src`, treat that as rule source and try to compile it. If compilation
- succeeds, stash the compiled rules and the rule text on the session, and
- provide feedback; if not, provide feedback.
+ for `:src`, treat that as rule source and try to compile it. If compilation
+ succeeds, stash the compiled rules and the rule text on the session, and
+ provide feedback; if not, provide feedback.
If `request` doesn't contain a value for `:src`, load basic rule source from
the session or from `resources/rulesets/basic.txt` and pass that back."
@@ -44,7 +71,7 @@
(session/put! :rules (:rules processed)))
(if (:rule-text processed)
(session/put! :rule-text (:rule-text processed)))
- (layout/render "rules.html"
+ (layout/render "rules.html"
(merge {:title "Edit Rules"} processed))))
([]
(rules-page nil)))
diff --git a/src/clj/mw_ui/routes/save.clj b/src/clj/mw_ui/routes/save.clj
new file mode 100644
index 0000000..41a29db
--- /dev/null
+++ b/src/clj/mw_ui/routes/save.clj
@@ -0,0 +1,41 @@
+(ns ^{:doc "Route which handles the saving of world state the client."
+ :author "Simon Brooke"}
+ mw-ui.routes.save
+ (:require [clojure.pprint :refer [pprint]]
+ [noir.session :as session]
+ [ring.util.response :as response]))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;
+;;;; mw-ui: a servlet user/visualisation interface for MicroWorld.
+;;;;
+;;;; This program is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU General Public License
+;;;; as published by the Free Software Foundation; either version 2
+;;;; of the License, or (at your option) any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;;; USA.
+;;;;
+;;;; Copyright (C) 2014 Simon Brooke
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+(defn save-page []
+ "Save the current world to the browser, using our own custom mime-type in
+ an attempt to prevent the browser trying to do anything clever with it.
+ Note that it is saved as a raw Clojure data structure, not as XML or
+ any proprietary format."
+ (response/header
+ (response/response
+ (with-out-str (pprint (session/get :world))))
+ "Content-Type" "application/journeyman-mwm; charset=utf-8"))
+
diff --git a/src/clj/mw_ui/util.clj b/src/clj/mw_ui/util.clj
new file mode 100644
index 0000000..c52aaa9
--- /dev/null
+++ b/src/clj/mw_ui/util.clj
@@ -0,0 +1,45 @@
+(ns ^{:doc "Utility functions used by other namespaces in this package."
+ :author "Simon Brooke"}
+ mw-ui.util
+ (:require [clojure.java.io :refer [resource file]]
+ [noir.session :as session]
+ [markdown.core :refer [md-to-html-string]]))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;
+;;;; mw-ui: a servlet user/visualisation interface for MicroWorld.
+;;;;
+;;;; This program is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU General Public License
+;;;; as published by the Free Software Foundation; either version 2
+;;;; of the License, or (at your option) any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;;;; USA.
+;;;;
+;;;; Copyright (C) 2014 Simon Brooke
+;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+(defn md->html
+ "reads a markdown file from public/md and returns an HTML string"
+ [filename]
+ (->>
+ (slurp (resource filename))
+ (md-to-html-string)))
+
+
+(defn list-resources [directory pattern]
+ "List resource files matching `pattern` in `directory`."
+ (sort
+ (remove nil?
+ (map #(first (rest (re-matches pattern (.getName %))))
+ (file-seq (file (resource directory)))))))
diff --git a/src/mw_ui/layout.clj b/src/mw_ui/layout.clj
deleted file mode 100644
index 6a6c224..0000000
--- a/src/mw_ui/layout.clj
+++ /dev/null
@@ -1,24 +0,0 @@
-(ns mw-ui.layout
- (:require [selmer.parser :as parser]
- [clojure.string :as s]
- [ring.util.response :refer [content-type response]]
- [compojure.response :refer [Renderable]]))
-
-(def template-path "templates/")
-
-(deftype RenderableTemplate [template params]
- Renderable
- (render [this request]
- (content-type
- (->> (assoc params
- (keyword (s/replace template #".html" "-selected")) "active"
- :servlet-context
- (if-let [context (:servlet-context request)]
- (.getContextPath context)))
- (parser/render-file (str template-path template))
- response)
- "text/html; charset=utf-8")))
-
-(defn render [template & [params]]
- (RenderableTemplate. template params))
-
diff --git a/src/mw_ui/middleware.clj b/src/mw_ui/middleware.clj
deleted file mode 100644
index 3440b32..0000000
--- a/src/mw_ui/middleware.clj
+++ /dev/null
@@ -1,24 +0,0 @@
-(ns mw-ui.middleware
- (:require [taoensso.timbre :as timbre]
- [selmer.parser :as parser]
- [environ.core :refer [env]]
- [selmer.middleware :refer [wrap-error-page]]
- [noir-exception.core
- :refer [wrap-internal-error wrap-exceptions]]))
-
-(defn log-request [handler]
- (fn [req]
- (timbre/debug req)
- (handler req)))
-
-(def development-middleware
- [log-request
- wrap-error-page
- wrap-exceptions])
-
-(def production-middleware
- [#(wrap-internal-error % :log (fn [e] (timbre/error e)))])
-
-(defn load-middleware []
- (concat (when (env :dev) development-middleware)
- production-middleware))
diff --git a/src/mw_ui/routes/params.clj b/src/mw_ui/routes/params.clj
deleted file mode 100644
index fe05161..0000000
--- a/src/mw_ui/routes/params.clj
+++ /dev/null
@@ -1,57 +0,0 @@
-(ns mw-ui.routes.params
- (:use clojure.walk
- clojure.java.io
- compojure.core)
- (:require [hiccup.core :refer [html]]
- [mw-engine.heightmap :as heightmap]
- [mw-parser.bulk :as compiler]
- [mw-ui.layout :as layout]
- [mw-ui.util :as util]
- [mw-ui.render-world :as world]
- [noir.io :as io]
- [noir.session :as session]))
-
-(defn- send-params []
- {:title "Choose your world"
- :heightmaps (util/list-resources "/img/heightmaps" #"([0-9a-z-_]+).png")
- :pause (or (session/get :pause) 5)
- :rulesets (util/list-resources "/rulesets" #"([0-9a-z-_]+).txt")
- })
-
-(defn params-page
- "Handler for params request. If no `request` passed, show empty params form.
- If `request` is passed, put parameters from request into session and show
- the world page."
- ([]
- (layout/render "params.html" (send-params)))
- ([request]
- (try
- (let [params (keywordize-keys (:form-params request))
- map (:heightmap params)
- pause (:pause params)
- rulefile (:ruleset params)
- rulepath (str "/rulesets/" rulefile ".txt")]
- (if (not= map "")
- (session/put! :world
- (heightmap/apply-heightmap
- (io/get-resource (str "/img/heightmaps/" map ".png")))))
- (when (not= rulefile "")
- (session/put! :rule-text (io/slurp-resource rulepath))
- (session/put! :rules (compiler/compile-file (io/get-resource rulepath))))
- (if (not= pause "")
- (session/put! :pause pause))
- (layout/render "params.html"
- (merge (send-params)
- {:r rulefile
- :h map
- :message "Your parameters are saved, now look at your world"})))
- (catch Exception e
- (let [params (keywordize-keys (:form-params request))]
- (layout/render "params.html"
- (merge (send-params)
- {:title "Choose your world"
- :r (:ruleset params)
- :h (:heightmap params)
- :message "Your paramters are not saved"
- :error (str (.getName (.getClass e)) ": " (.getMessage e) "; " params)}
- )))))))
diff --git a/src/mw_ui/routes/save.clj b/src/mw_ui/routes/save.clj
deleted file mode 100644
index 26f3688..0000000
--- a/src/mw_ui/routes/save.clj
+++ /dev/null
@@ -1,15 +0,0 @@
-(ns mw-ui.routes.save
- (:require [clojure.pprint :as pretty :only [pprint]]
- [noir.session :as session]
- [ring.util.response :as response]))
-
-(defn save-page []
- "Save the current world to the browser, using our own custom mime-type in
- an attempt to prevent the browser trying to do anything clever with it.
- Note that it is saved as a raw Clojure data structure, not as XML or
- any proprietary format."
- (response/header
- (response/response
- (with-out-str (pretty/pprint (session/get :world))))
- "Content-Type" "application/journeyman-mwm; charset=utf-8"))
-
diff --git a/src/mw_ui/util.clj b/src/mw_ui/util.clj
deleted file mode 100644
index 46def67..0000000
--- a/src/mw_ui/util.clj
+++ /dev/null
@@ -1,21 +0,0 @@
-(ns mw-ui.util
- (:require [noir.io :as io]
- [noir.session :as session]
- [markdown.core :as md]))
-
-(defn md->html
- "reads a markdown file from public/md and returns an HTML string"
- [filename]
- (->>
- (io/slurp-resource filename)
- (md/md-to-html-string)))
-
-(defn list-resources [directory pattern]
- "List resource files matching `pattern` in `directory`."
- (let
- [path (str (io/resource-path) directory)]
- (session/put! :list-resources-path path)
- (sort
- (remove nil?
- (map #(first (rest (re-matches pattern (.getName %))))
- (file-seq (clojure.java.io/file path)))))))