From f8fe873bd426ffae935214627b78e0a1f03b4ee0 Mon Sep 17 00:00:00 2001 From: simon Date: Thu, 24 Nov 2016 16:05:59 +0000 Subject: [PATCH] OK, this now works, more or less. The REST API is not yet used, and the on-screen representation of the machine isn't nearly as pretty as I intend. --- src/vending/routes/home.clj | 44 ++++++++++- src/vending/routes/json.clj | 74 +++--------------- src/vending/views/templates/home.html | 106 +++++++++++++++++--------- 3 files changed, 120 insertions(+), 104 deletions(-) diff --git a/src/vending/routes/home.clj b/src/vending/routes/home.clj index adc562d..4313460 100644 --- a/src/vending/routes/home.clj +++ b/src/vending/routes/home.clj @@ -1,15 +1,53 @@ (ns vending.routes.home (:use compojure.core) (:require [vending.views.layout :as layout] + [noir.session :as session] + [vending.core :as machine] [vending.util :as util])) -(defn home-page [] + +(def button-actions + {"Coin return" machine/coin-return + "Add Merk" machine/add-merk + "Add Bawbee" machine/add-bawbee + "Add Plack" machine/add-plack + "Add Bodle" machine/add-bodle + "Request Caramel Wafer" machine/get-caramel-wafer + "Request Teacake" machine/get-teacake + "Request Snowball" machine/get-snowball + }) + + +(defn- perform-action! + "Apply this function to the machine in the session, if there is one, or else to a new default + machine; cache the result in the session; and return a rendered page representation of the + state of the machine." + [function] + (let [machine (apply function (list (or (session/get :machine) (machine/make-default-machine))))] + (session/put! :machine machine) + (layout/render + "home.html" {:content (util/md->html "/md/docs.md") + :machine machine + :buttons (keys button-actions)}))) + + +(defn home-page + "Render the home page with the default machine; in so doing, reset the machine in the session." + [] + (let [machine (machine/make-default-machine)] + (session/put! :machine machine) (layout/render - "home.html" {:content (util/md->html "/md/docs.md")})) + "home.html" {:content (util/md->html "/md/docs.md") + :machine machine + :buttons (keys button-actions)}))) + (defn about-page [] (layout/render "about.html")) + (defroutes home-routes (GET "/" [] (home-page)) - (GET "/about" [] (about-page))) + (GET "/about" [] (about-page)) + (POST "/update" [action] (perform-action! (button-actions action))) + ) diff --git a/src/vending/routes/json.clj b/src/vending/routes/json.clj index ffbd4de..21d8b87 100644 --- a/src/vending/routes/json.clj +++ b/src/vending/routes/json.clj @@ -8,75 +8,23 @@ [vending.util :as util])) -(defn- perform-action +(defn- perform-action! "Apply this function to the machine in the session, if there is one, or else to a new default - machine; cache the result in the session; and return a JSON formatted representation of the result." + machine; cache the result in the session; and return a JSON formatted representation of the state + of the machine." [function] (let [machine (apply function (list (or (session/get :machine) (machine/make-default-machine))))] (session/put! :machine machine) (json/write-str machine))) -;;; Each of these action functions perform an action on the machine in the session, if there is one, -;;; or on a new default machine if there is no machine in the session. They return (and cache in the -;;; session) the new state of the machine after the action; the machine returned is returned as a -;;; JSON string. - -(defn coin-return-action - "Return all the coins that have been tendered since the last sale." - [] - (perform-action machine/coin-return)) - - -(defn add-merk-action - "Insert one merk into the coin slot of the machine in the session." - [] - (perform-action machine/add-merk)) - - -(defn add-bawbee-action - "Insert one bawbee into the coin slot of the machine in the session." - [] - (perform-action machine/add-bawbee)) - - -(defn add-plack-action - "Insert one plack into the coin slot of the machine in the session." - [] - (perform-action machine/add-plack)) - - -(defn add-bodle-action - "Insert one bodle into the coin slot of the machine in the session." - [] - (perform-action machine/add-bodle)) - - -(defn select-caramel-wafer-action - "Request one caramel wafer from the machine in the session." - [] - (perform-action machine/get-caramel-wafer)) - - -(defn select-teacake-action - "Request one teacake from the machine in the session." - [] - (perform-action machine/get-teacake)) - - -(defn select-snowball-action - "Request one snowball from the machine in the session." - [] - (perform-action machine/get-snowball)) - - (defroutes json-routes - (GET "/coin-return" [] (coin-return-action)) - (GET "/add-merk" [] (add-merk-action)) - (GET "/add-bawbee" [] (add-bawbee-action)) - (GET "/add-plack" [] (add-plack-action)) - (GET "/add-bodle" [] (add-bodle-action)) - (GET "/select-caramel-wafer" [] (select-caramel-wafer-action)) - (GET "/select-teacake" [] (select-teacake-action)) - (GET "/select-snowball" [] (select-snowball-action)) + (GET "/json/coin-return" [] (perform-action! machine/coin-return)) + (GET "/json/add-merk" [] (perform-action! machine/add-merk)) + (GET "/json/add-bawbee" [] (perform-action! machine/add-bawbee)) + (GET "/json/add-plack" [] (perform-action! machine/add-plack)) + (GET "/json/add-bodle" [] (perform-action! machine/add-bodle)) + (GET "/json/select-caramel-wafer" [] (perform-action! machine/get-caramel-wafer)) + (GET "/json/select-teacake" [] (perform-action! machine/get-teacake)) + (GET "/json/select-snowball" [] (perform-action! machine/get-snowball)) ) diff --git a/src/vending/views/templates/home.html b/src/vending/views/templates/home.html index 66d452b..aaa9f02 100644 --- a/src/vending/views/templates/home.html +++ b/src/vending/views/templates/home.html @@ -1,56 +1,86 @@ {% extends "vending/views/templates/base.html" %} {% block content %} -
-

Welcome to vending

-

Time to start building your site!

-

Learn more »

-
+
+

Welcome to vending

+
-
-
- {{content|safe}} -
-
-
-

OK, the Vending machine plan

+
+

What this project is about is the - Vending Machine code kata. - Just at this point, I've added the whole of a luminusweb - default template to it, but I haven't done much with it. In due course this page will be replaced - with a graphical representation of a heath-robinson - vending machine, with buttons allowing coins to be inserted, and items to be selected.

+ Vending Machine code kata. + Just at this point, I've added the whole of a luminusweb + default template to it, but I haven't done much with it. In due course this page will be replaced + with a graphical representation of a heath-robinson + vending machine, with buttons allowing coins to be inserted, and items to be selected.

I intend that the page should be interactive, with the vending machine responding graphically to - what the user does on the buttons. The logic will almost certainly be server-side at first, - but possibly later I'll move it client-side using ClojureScript.

+ what the user does on the buttons. The logic will almost certainly be server-side at first, + but possibly later I'll move it client-side using ClojureScript.

At this stage in the project this page uses the Selmer - templating system; later I intend that it should use Enlive.

- + templating system; later I intend that it should use Enlive.

+ +
- + + - - - - - - - - + + + - + + + + + + + - - + + + + + + + - {% for button in buttons %} - + + + + + + + + + + + + -
Tendered coinsTendered coins{{machine.tendered}}
TeacakesCaramel wafersSnowballsMerksPlacksBawbeesBodlesStockCoin stacks
Last MessageTeacakesCaramel wafersSnowballsMerksBawbeesPlacksBodles
OutputChange + {{machine.stock.caramel-wafer}} + + {{machine.stock.teacake}} + + {{machine.stock.snowball}} + {{machine.coins.merk}}{{machine.coins.bawbee}}{{machine.coins.plack}}{{machine.coins.bodle}}
- - Last Message
{{machine.message}}
OutputChange
+ {{machine.output}} + + {% for coin in machine.change %} + {{coin}} {% endfor %} +
+ + {% for button in buttons %} + + + + {% endfor %} + + + +
+
{% endblock %}