Compare commits

...

3 commits

21 changed files with 505 additions and 202 deletions

View file

@ -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}}}

View file

@ -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;
}

View file

@ -3,11 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>{{title}}</title>
<link href="{{servlet-context}}/css/phone.css" media="only screen and (max-device-width: 480px)" rel="stylesheet" type="text/css" />
<link href="{{servlet-context}}/css/tablet.css" media="only screen and (min-device-width: 481px) and (max-device-width: 1024px)" rel="stylesheet" type="text/css" />
<link href="{{servlet-context}}/css/standard.css" media="screen and (min-device-width: 1025px)" rel="stylesheet" type="text/css" />
<link href="{{servlet-context}}/css/print.css" media="print" rel="stylesheet" type="text/css" />
<link href="{{servlet-context}}/css/states.css" rel="stylesheet" type="text/css" />
{% script "/lib/jquery-1.9.0.js" %}
{% script "/lib/jquery.validate.min.js" %}
{% script "/lib/script.js" %}
@ -45,7 +41,9 @@
{% endif %}
{% if error %}
<div id="error">
<p class="error">{{error}}</p>
<pre class="error">
{{error}}
</pre>
</div>
{% endif %}
@ -57,7 +55,8 @@
Built with <a href="http://www.luminusweb.net/">LuminusWeb</a> ||
<img height="16" width="16" align="top" src="img/clojure-icon.gif" alt="&lambda;"> Powered by <a href="http://clojure.org">Clojure</a> ||
Engineering and hosting by <a href="http://www.journeyman.cc">Journeyman</a> ||
World generated using <a href="http://git.journeyman.cc/?p=mw-engine;a=summary">MicroWorld Engine</a>
World generated using <a href="http://git.journeyman.cc/?p=mw-engine;a=summary">MicroWorld Engine</a> ||
Version {{version}}
</div>
</div>
</body>

View file

@ -4,6 +4,7 @@
{{content|safe}}
</div>
<form action="inspect" method="post">
{% csrf-field %}
<input type="hidden" name="x" value="{{x}}"/>
<input type="hidden" name="y" value="{{y}}"/>
<p class="widget">

View file

@ -1,6 +1,7 @@
{% extends "templates/base.html" %}
{% block content %}
<form action="{{servlet-context}}/params" method="POST">
{% csrf-field %}
<p class="widget">
<label for="ruleset">The rule set to use</label>
<select name="ruleset">
@ -34,4 +35,4 @@
</p>
</form>
{% endblock %}
{% endblock %}

View file

@ -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]

54
src/clj/mw_ui/layout.clj Normal file
View file

@ -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))

View file

@ -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))

View file

@ -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]

View file

@ -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))

View file

@ -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,

View file

@ -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.

View file

@ -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)}
)))))))

View file

@ -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)))

View file

@ -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"))

45
src/clj/mw_ui/util.clj Normal file
View file

@ -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)))))))

View file

@ -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))

View file

@ -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))

View file

@ -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)}
)))))))

View file

@ -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"))

View file

@ -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)))))))