Added load and save. Save works, load doesn't (yet).

This commit is contained in:
simon 2014-08-16 21:34:26 +01:00
parent 34d3745ecb
commit ab01606c5c
8 changed files with 139 additions and 56 deletions

View file

@ -37,7 +37,7 @@ body {
#nav:hover #nav-menu {
display: inline;
}
#nav-icon {
padding: 0.25em;
}
@ -52,7 +52,7 @@ body {
display: inline;
}
#nav ul li a {
#nav ul li a {
color: white;
text-decoration: none;
font-weight: bold;
@ -68,6 +68,12 @@ li.nav-item a:active { background: gray; color: white; }
color: white;
}
/* there isn't enough room on a phone display for optional elements, and
load/save isn't going to work on a phone anyway */
.nav-optional {
display: none;
}
.widget {
margin: 0;
padding: 0.25em 1em;

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 */
@ -54,7 +54,7 @@ body {
display: inline;
}
#nav ul li a {
#nav ul li a {
color: white;
text-decoration: none;
font-weight: bold;

View file

@ -53,7 +53,7 @@ body {
#nav:hover #nav-menu {
display: inline;
}
#nav-icon {
padding: 0.25em;
}
@ -68,7 +68,7 @@ body {
display: inline;
}
#nav ul li a {
#nav ul li a {
color: white;
text-decoration: none;
font-weight: bold;
@ -84,6 +84,12 @@ li.nav-item a:active { background: gray; color: white; }
color: white;
}
/* there isn't enough room on a tablet display for optional elements, and
load/save isn't going to work on a tablet anyway */
.nav-optional {
display: none;
}
.widget {
margin: 0;
padding: 0.25em 1em;

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

View file

@ -23,9 +23,11 @@
<img id="nav-icon" src="{{servlet-context}}/img/threelines.png" alt="Menu"/>
<ul id="nav-menu" class="nav">
<li class="{{home-selected}}"><a href="{{servlet-context}}/">Home</a></li>
<li class="{{world-selected}}"><a href="{{servlet-context}}/world">World</a></li>
<li class="{{params-selected}}"><a href="{{servlet-context}}/params">Parameters</a></li>
<li class="{{rules-selected}}"><a href="{{servlet-context}}/rules">Rules</a></li>
<li class="{{world-selected}}"><a href="{{servlet-context}}/world">World</a></li>
<li class="{{save-selected}} nav-optional"><a href="{{servlet-context}}/saved-map.mwm">Save</a></li>
<li class="{{load-selected}} nav-optional"><a href="{{servlet-context}}/load">Load</a></li>
<li class="{{about-selected}}"><a href="{{servlet-context}}/about">About</a></li>
<li class="{{docs-selected}}"><a href="{{servlet-context}}/docs">Documentation</a></li>
</ul>
@ -37,12 +39,12 @@
<div id="main-container" class="container">
{% if message %}
<div id="announcement">
<div id="message">
<p class="message">{{message}}</p>
</div>
{% endif %}
{% if error %}
<div id="announcement">
<div id="error">
<p class="error">{{error}}</p>
</div>
{% endif %}

View file

@ -1,21 +1,48 @@
(ns mw-ui.routes.home
(:use clojure.walk
compojure.core
[mw-engine.utils :as engine-utils]
[mw-ui.routes.rules :as rules]
[mw-ui.routes.params :as params])
(:require [hiccup.core :refer [html]]
compojure.core)
(:require [clojure.pprint :only [pprint]]
[hiccup.core :refer [html]]
[mw-engine.utils :as engine-utils]
[mw-ui.layout :as layout]
[mw-ui.util :as util]
[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]))
(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")}))
(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"]}))
(defn home-page []
(layout/render "trusted-content.html" {:title "Welcome to MicroWorld"
"Render the home page."
(layout/render "trusted-content.html" {:title "Welcome to MicroWorld"
:content (util/md->html "/md/mw-ui.md")}))
(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)
@ -35,53 +62,41 @@
:cell cell
:x (:x cell)
:y (:y cell)
:states (util/list-resources
:states (util/list-resources
"/img/tiles" #"([0-9a-z-_]+).png")}))))
(defn world-page []
(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"}))
(defn about-page []
(layout/render "trusted-content.html"
{:title "About MicroWorld"
:about-selected "active"
:content (util/md->html "/md/about.md")}))
(defn md-page [request]
(defn md-page
"Render the markdown page specified in this request, if any. Probably undesirable,
should be removed."
[request]
(let [params (keywordize-keys (:params request))
content (or (:content params) "missing.md")]
(layout/render "trusted-content.html"
{:title "Welcome to MicroWorld"
(layout/render "trusted-content.html"
{:title "Welcome to MicroWorld"
:content (util/md->html (str "/md/" content))})))
(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 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"]}))
(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 "/world" [] (world-page))
(GET "/params" [] (params/params-page))
(GET "/md" request (md-page request))
(POST "/params" request (params/params-page request))
(GET "/rules" request (rules/rules-page request))
(POST "/rules" request (rules/rules-page request))
(GET "/inspect" request (inspect-page request))
(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))
)

39
src/mw_ui/routes/load.clj Normal file
View file

@ -0,0 +1,39 @@
(ns 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]))
(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))))
(defn load-page
"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."
([]
(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))}))))))

15
src/mw_ui/routes/save.clj Normal file
View file

@ -0,0 +1,15 @@
(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"))