diff --git a/.gitignore b/.gitignore index cf11b31..7e819cf 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ resources/public/docs/mw-*/uberdoc.html # Artefacts: mw_ui.log pom.xml + +buildall.tmp.*/ diff --git a/docs/uberdoc.html b/docs/uberdoc.html new file mode 100644 index 0000000..4d7c64b --- /dev/null +++ b/docs/uberdoc.html @@ -0,0 +1,3690 @@ + +mw-ui -- Marginalia

mw-ui

0.1.5


Web-based user interface for MicroWorld

+

dependencies

org.clojure/clojure
1.6.0
mw-engine
0.1.5
mw-parser
0.1.5
lib-noir
0.8.4
ring-server
0.3.1
selmer
0.6.8
hiccup
1.0.5
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



(this space intentionally left almost blank)
 

Set up and tear down the request handler.

+
(ns ^{:doc 
+      :author "Simon Brooke"}
+  mw-ui.handler
+  (:require [compojure.core :refer [defroutes]]
+            [mw-ui.routes.home :refer [home-routes]]
+            [mw-ui.middleware :refer [load-middleware]]
+            [noir.response :refer [redirect]]
+            [noir.util.middleware :refer [app-handler]]
+            [compojure.route :as route]
+            [taoensso.timbre :as timbre]
+            [taoensso.timbre.appenders.rotor :as rotor]
+            [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"))

init will be called once when + app is deployed as a servlet on + an app server such as Tomcat + put any initialization code here

+
(defn init
+  []
+  (timbre/set-config!
+    [:appenders :rotor]
+    {:min-level :info
+     :enabled? true
+     :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"))

destroy will be called when your application + shuts down, put any clean up code here

+
(defn destroy
+  []
+  (timbre/info "mw-ui is shutting down..."))
+
(def app (app-handler
+           ;; add your application routes here
+           [home-routes app-routes]
+           ;; add custom middleware here
+           :middleware (load-middleware)
+           ;; timeout sessions after 30 minutes
+           :session-options {:timeout (* 60 30)
+                             :timeout-response (redirect "/")}
+           ;; add access rules here
+           :access-rules []
+           ;; serialize/deserialize the following data formats
+           ;; available formats:
+           ;; :json :json-kw :yaml :yaml-kw :edn :yaml-in-html
+           :formats [:json-kw :edn]))
 

Layout content as HTML.

+
(ns ^{:doc 
+      :author "Simon Brooke"}
+  mw-ui.layout
+  (:require [selmer.parser :as parser]
+            [clojure.string :as s]
+            [ring.util.response :refer [content-type response]]
+            [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/")
+
(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))
 

In truth, boilerplate from Luminus.

+
(ns ^{:doc 
+      :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))
 

Render the state of the world as an HTML table.

+
(ns ^{:doc 
+      :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]
+            [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))

Render this statekey, assumed to be a keyword indicating a state in the + world, into a path which should recover the corresponding image file.

+
(defn format-image-path
+  [statekey]
+  (format "img/tiles/%s.png" (format-css-class statekey)))
+
(defn format-mouseover [cell]
+  (str cell))

Render this world cell as a Hiccup table cell.

+
(defn render-cell
+  [cell]
+  (let [state (:state cell)]
+    [:td {:class (format-css-class state) :title (format-mouseover cell)}
+     [:a {:href (format "inspect?x=%d&y=%d" (:x cell) (:y cell))}
+      [:img {:alt (:state cell) :src (format-image-path state)}]]]))

Render this world row as a Hiccup table row.

+
(defn render-world-row
+  [row]
+  (apply vector (cons :tr (map render-cell row))))

Render the world implied by the current session as a complete HTML table in a DIV.

+
(defn render-world-table
+  []
+  (let [world (or (session/get :world)
+                  (heightmap/apply-heightmap
+                      (io/get-resource "/img/heightmaps/small_hill.png")))
+        rules (or (session/get :rules)
+                  (do (session/put! :rules
+                                    (compiler/compile-file
+                                      (io/get-resource "/rulesets/basic.txt")))
+                    (session/get :rules)))
+        generation (inc (or (session/get :generation) 0))
+        w2 (engine/transform-world world rules)
+        ]
+    (session/put! :world w2)
+    (session/put! :generation generation)
+    [:div {:class "world"}
+      (apply vector
+                 (cons :table
+                       (map render-world-row w2)))
+      [:p
+       (str "Generation " generation)]]))

Render in Hiccup format the HTML content of an inspector on this cell.

+
(defn render-inspector
+  [cell table]
+  [:table {:class "music-ruled"}
+   [:tr
+    [:td {:colspan 2 :style "text-align: center;"}
+     [:img {:src (str "img/tiles/" (name (:state cell)) ".png")
+            :width 64
+            :height 64}]]]
+   [:tr [:th "Key"][:th "Value"]]
+   (map #(vector :tr (vector :th %)(vector :td (cell %))) (keys cell))])
 

In truth, boilerplate from Luminus.

+
(ns ^{:doc 
+      :author "Simon Brooke"}
+  mw-ui.repl
+  (:use mw-ui.handler
+        ring.server.standalone
+        [ring.middleware file-info file])
+  (: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))
+
(defn get-handler []
+  ;; #'app expands to (var app) so that when we reload our code,
+  ;; the server is forced to re-resolve the symbol in the var
+  ;; rather than having its own copy. When the root binding
+  ;; changes, the server picks it up without having to restart.
+  (-> #'app
+      ; Makes static assets in $PROJECT_DIR/resources/public/ available.
+      (wrap-file "resources")
+      ; Content-Type, Content-Length, and Last Modified headers for files in body
+      (wrap-file-info)))

used for starting the server in development mode from REPL

+
(defn start-server
+  [& [port]]
+  (let [port (if port (Integer/parseInt port) 3000)]
+    (reset! server
+            (serve (get-handler)
+                   {:port port
+                    :init init
+                    :auto-reload? true
+                    :destroy destroy
+                    :join? false}))
+    (println (str "You can view the site at http://localhost:" port))))
+
(defn stop-server []
+  (.stop @server)
+  (reset! server nil))
+
(defn -main []
+  (start-server))
 

Routes which serve the main pages of the application.

+
(ns ^{:doc 
+      :author "Simon Brooke"}
+  mw-ui.routes.home
+  (:use clojure.walk
+        compojure.core)
+  (:require [clojure.pprint :only [pprint]]
+            [hiccup.core :refer [html]]
+            [mw-engine.utils :as engine-utils]
+            [mw-ui.layout :as layout]
+            [mw-ui.render-world :as world]
+            [mw-ui.routes.load :as load]
+            [mw-ui.routes.rules :as rules]
+            [mw-ui.routes.params :as params]
+            [mw-ui.routes.save :as save]
+            [mw-ui.util :as util]
+            [noir.io :as io]
+            [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"))))))
+
(defn about-page []
+  (layout/render "trusted-content.html"
+                 {:title "About MicroWorld"
+                  :about-selected "active"
+                  :content (util/md->html "/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"]
+                              :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")
+                              :version (System/getProperty "mw-ui.version")}))
+
(defn inspect-page [request]
+  "Open an inspector on the cell at the co-ordinates specified in this request"
+  (let [params (keywordize-keys (:params request))
+        xs (:x params)
+        ys (:y params)
+        x (if (seq xs) (read-string xs) 0)
+        y (if (seq ys) (read-string ys) 0)
+        world (session/get :world)
+        cell (engine-utils/get-cell world x y)
+        state (:state params)]
+    (cond state
+      (do
+        (session/put! :world (engine-utils/set-property world cell :state (keyword state)))
+        (response/redirect "world"))
+      true
+      (layout/render "inspector.html"
+                     {:title (format "Inspect cell at %d, %d" x y)
+                      :content (html (world/render-inspector cell world))
+                      :cell cell
+                      :x (:x cell)
+                      :y (:y cell)
+                      :states (util/list-resources
+                                "/img/tiles" #"([0-9a-z-_]+).png")}))))

Render the markdown page specified in this request, if any. Probably undesirable, + should be removed.

+
(defn md-page
+  [request]
+  (let [params (keywordize-keys (:params request))
+        content (or (:content params) "missing.md")]
+    (layout/render "trusted-content.html"
+                   {:title "Welcome to MicroWorld"
+                    :content (util/md->html (str "/md/" content))})))
+
(defn world-page []
+  "Render the world in the current session (or a default one if none)."
+  (layout/render "trusted-content.html"
+                 {:title "Watch your world grow"
+                 :world-selected "active"
+                 :content (html (world/render-world-table))
+                 :pause (or (session/get :pause) 5)
+                 :maybe-refresh "refresh"}))
+
(defroutes home-routes
+  (GET  "/" [] (home-page))
+  (GET  "/about" [] (about-page))
+  (GET  "/docs"  [] (docs-page))
+  (GET  "/inspect" request (inspect-page request))
+  (POST "/inspect" request (inspect-page request))
+  (GET  "/load" [] (load/load-page))
+  (POST "/load" request (load/load-page request))
+  (GET  "/md" request (md-page request))
+  (GET  "/params" [] (params/params-page))
+  (POST "/params" request (params/params-page request))
+  (GET  "/rules" request (rules/rules-page request))
+  (POST "/rules" request (rules/rules-page request))
+  (GET  "/saved-map.mwm" [] (save/save-page))
+  (GET  "/world"  [] (world-page)))
 

Route which handles the upload of worlds/rules from the client.

+
(ns ^{:doc 
+      :author "Simon Brooke"}
+  mw-ui.routes.load
+  (:use clojure.walk
+        compojure.core)
+  (:require [hiccup.core :refer [html]]
+            [noir.io :as io]
+            [noir.session :as session]
+            [ring.util.response :as response]
+            [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)
+  (cond
+   (session/put! :world
+                (with-open [eddi (java.io.FileReader. (:tempfile file))] (read)))
+    (str "Successfully loaded your world from " (:filename file))))

If no args, show the load form; with args, load a world file from the client.

+ +

NOTE that this reads a Clojure form from an untrusted client and should almost + certainly NOT be enabled on a public-facing site, especially not on the Internet.

+ +

TODO doesn't work yet.

+
(defn load-page
+  ([]
+   (load-page nil))
+  ([request]
+     (let [params (keywordize-keys (:params request))
+           file (:file request)]
+       (try
+         (layout/render "load.html"
+                        {:title "Load World"
+                         :message (upload file)})
+         (catch Exception any
+               (layout/render "load.html"
+                            {:title "Load World"
+                             :message "Failed to load your world"
+                             :error (str (.getName (.getClass any)) ": " (.getMessage any))}))))))
 

Route which serves and handles the parameters page.

+
(ns ^{:doc 
+      :author "Simon Brooke"}
+  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]))

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 "/img/heightmaps" #"([0-9a-z-_]+).png")
+   :pause (or (session/get :pause) 5)
+   :rulesets (util/list-resources "/rulesets" #"([0-9a-z-_]+).txt")
+   })

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.

+
(defn params-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)})))))))
 

Route which serves and handles the rules page.

+
(ns ^{:doc 
+      :author "Simon Brooke"}
+  mw-ui.routes.rules
+  (:use clojure.walk
+        compojure.core)
+  (:require [hiccup.core :refer [html]]
+            [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]
+            [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
+          (let [rules (compiler/compile-string src)]
+            {:rule-text src
+             :rules rules
+             :message (str "Successfully compiled "
+                           (count rules)
+                           " rules")           })
+          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
+          {:rule-text src
+           :message "An error occurred during compilation"
+           :error (str (.getName (.getClass e)) ": " (.getMessage e))}))))

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.

+ +

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.

+
(defn rules-page
+  ([request]
+    (let [processed (process-rules-request request)]
+      (if (:rules processed)
+        (session/put! :rules (:rules processed)))
+      (if (:rule-text processed)
+        (session/put! :rule-text (:rule-text processed)))
+      (layout/render "rules.html"
+                     (merge {:title "Edit Rules"} processed))))
+  ([]
+    (rules-page nil)))
 

Route which handles the saving of world state the client.

+
(ns ^{:doc 
+      :author "Simon Brooke"}
+  mw-ui.routes.save
+  (:require [clojure.pprint :as pretty :only [pprint]]
+            [noir.session :as session]
+            [noir.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/content-type
+    "application/journeyman-mwm; charset=utf-8"
+    (with-out-str (pretty/pprint  (session/get :world)))))
 

Utility functions used by other namespaces in this package.

+
(ns ^{:doc 
+      :author "Simon Brooke"}
+  mw-ui.util
+  (:require [noir.io :as io]
+            [noir.session :as session]
+            [markdown.core :as md]))

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

+

reads a markdown file from public/md and returns an HTML string

+
(defn md->html
+  [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)))))))
 
\ No newline at end of file diff --git a/project.clj b/project.clj index a3a3dfe..2fee3f8 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject mw-ui "0.1.5-SNAPSHOT" +(defproject mw-ui "0.1.6-SNAPSHOT" :description "Web-based user interface for MicroWorld" :url "http://www.journeyman.cc/microworld" :manifest { @@ -8,17 +8,18 @@ "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"] - [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"]] + :dependencies [[org.clojure/clojure "1.8.0"] + [mw-engine "0.1.6-SNAPSHOT"] + [mw-parser "0.1.6-SNAPSHOT"] + [lib-noir "0.9.9"] + [ring-server "0.5.0"] + [selmer "1.12.25"] + [hiccup "1.0.5"] + [com.taoensso/timbre "4.10.0"] + [com.taoensso/tower "3.0.2"] + [markdown-clj "1.10.4"] + [environ "1.2.0"] + [noir-exception "0.2.5"]] :repl-options {:init-ns mw-ui.repl} :plugins [[lein-ring "0.8.11"] @@ -40,8 +41,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.8.1"] + [pjstadig/humane-test-output "0.10.0"]] :injections [(require 'pjstadig.humane-test-output) (pjstadig.humane-test-output/activate!)] :env {:dev true}}} diff --git a/resources/public/docs/mw-engine b/resources/public/docs/mw-engine new file mode 120000 index 0000000..09eca7a --- /dev/null +++ b/resources/public/docs/mw-engine @@ -0,0 +1 @@ +../../../../mw-engine/docs \ No newline at end of file diff --git a/resources/public/docs/mw-parser b/resources/public/docs/mw-parser new file mode 120000 index 0000000..5ed9c16 --- /dev/null +++ b/resources/public/docs/mw-parser @@ -0,0 +1 @@ +../../../../mw-parser/docs \ No newline at end of file diff --git a/resources/public/docs/mw-ui b/resources/public/docs/mw-ui new file mode 120000 index 0000000..a2968b0 --- /dev/null +++ b/resources/public/docs/mw-ui @@ -0,0 +1 @@ +../../../../mw-ui/docs \ No newline at end of file diff --git a/resources/public/img/heightmaps/mgi_med.png b/resources/public/img/heightmaps/mgi_med.png new file mode 100644 index 0000000..cb4e875 Binary files /dev/null and b/resources/public/img/heightmaps/mgi_med.png differ