Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor to move to darksky.net weather data; requiring a full-stack setup including a proxy #13

Merged
merged 21 commits into from Jul 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
725d0be
initial project dep setup for proxy server
chadhs Jun 12, 2018
5b7b806
add dev/user setup for server start stop
chadhs Jun 15, 2018
e6affbf
dev/user tooling update and version fixes
chadhs Jun 15, 2018
a8d47b5
restructured to run backend proxy and frontend independently from fig…
chadhs Jun 26, 2018
505a765
readme update
chadhs Jun 26, 2018
7731b69
first pass of setup proxy access to darksky + profile refactor
chadhs Jun 27, 2018
8c99945
updated db, event, sub, view to use darksky weather data
chadhs Jun 28, 2018
9be8b44
update sub, view, css for darksky weather data display
chadhs Jun 28, 2018
3d48547
added cors headers to proxy, sample secrets, removed old secerts hand…
chadhs Jun 29, 2018
e144328
parameterize lat-lon and proxy-port (default to 8000)
chadhs Jun 29, 2018
8f50c44
fix 2 digit hour bug, but casting to string
chadhs Jun 30, 2018
260888d
updated response map spacing while troubleshooting
chadhs Jun 30, 2018
0c28a29
revert icon size change
chadhs Jun 30, 2018
957b1bd
add special fixed with class to first weather icon to prevent new line
chadhs Jul 1, 2018
f692ef0
project.clj minor refactor
chadhs Jul 1, 2018
a0ff866
added notes to readme about raspberry pi deploy
chadhs Jul 1, 2018
85e3c7c
updated screenshot to reflect changes
chadhs Jul 1, 2018
35000db
ensure fixed width icons; set new icon size
chadhs Jul 1, 2018
a01f675
screenshot update
chadhs Jul 1, 2018
4545052
broke out clojure backend into core, route, handler namespaces
chadhs Jul 1, 2018
baa0e96
update README to be clear about the darksky.net free account requirement
chadhs Jul 1, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
@@ -1,8 +1,11 @@
.nrepl-port
.lein*
.rebel_readline_history
/*.log
/target
/*-init.clj
/resources/public/js/compiled
/resources/public/css
out
environ.cljs
profiles.clj
57 changes: 37 additions & 20 deletions README.md
Expand Up @@ -4,23 +4,27 @@ ccclock — cord cutters clock — is a clock for "cord cutters" who miss the al

ccclock is built with [re-frame](https://github.com/Day8/re-frame) and intended to run locally on a raspberry pi with attached lcd; but can run in any browser anywhere.

This current iteration as powered by darksky.net and requires a free account and api key.

![ccclock demo](ccclock-demo.png)

## Development Mode

**Note:** When doing full stack development, start the ring server first and start figwheel last (via emacs or terminal).

### Set Environment Variables & Secrets

Copy the example file, and update the values; this file is ignored by git for safety.
Copy the example file, and update the values. A darksky.net free account and api key is required for the `weather-apikey` value. This file is ignored by git for safety.

```
cp src/cljs/ccclock/environ.cljs.example src/cljs/ccclock/environ.cljs
```sh
cp profiles-example.clj profiles.clj
```

### Start Cider from Emacs:
### Start Cider + Figwheel from Emacs

Put this in your Emacs config file:

```
```emacs-lisp
(setq cider-cljs-lein-repl
"(do (require 'figwheel-sidecar.repl-api)
(figwheel-sidecar.repl-api/start-figwheel!)
Expand All @@ -29,36 +33,49 @@ Put this in your Emacs config file:

Navigate to a clojurescript file and start a figwheel REPL with `cider-jack-in-clojurescript` or (`C-c M-J`)

### Compile css:

Compile css file once.
### Start Fighweel from Terminal:

```
lein garden once
```sh
lein do clean, garden once, figwheel dev
```

Automatically recompile css file on change.
### Start Ring Backend from Terminal

```
lein garden auto
```sh
lein ring server
```

### Run application:
### Automatically Recompile CSS File on Changes

```sh
lein garden auto
```
lein clean
lein figwheel dev
```

### See Changes Live in Your Browser

Figwheel will automatically push cljs changes to the browser.

Wait a bit, then browse to [http://localhost:3449](http://localhost:3449).

## Production Build

To compile clojurescript to javascript, compile css, and build jar file which serves the api-proxy and index.html:

To compile clojurescript to javascript:

```sh
lein with-profile prod uberjar
```
lein do clean, cljsbuild once, garden once

To run in production set the `WEATHER_APIKEY` environment variable and then run

```sh
java -jar target/ccclock.jar
```

## Notes

To deploy to a raspberry pi, I recommend the following:

- have rc.local launch your production jar
- set to boot to desktop and launch chromium in kiosk mode launching http://localhost:8000/index.html

Your browser may sit with a "cannot load page" or other such error for a couple minutes if it opens before the jvm launches your jar.
Binary file modified ccclock-demo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions profiles-example.clj
@@ -0,0 +1,10 @@
{:profiles/dev
{:env
{:weather-apikey "00000000000000000000000000000000"
:lat-lon "43.038902,-87.906471"
:proxy-port "8000"}}
:profiles/test
{:env
{:weather-apikey "00000000000000000000000000000000"
:lat-lon "43.038902,-87.906471"
:proxy-port "8000"}}}
74 changes: 48 additions & 26 deletions project.clj
@@ -1,41 +1,59 @@
(defproject ccclock "0.5.1-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.8.0"]
[org.clojure/clojurescript "1.9.908"]
(defproject ccclock "0.6.1-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.9.0"]
[org.clojure/clojurescript "1.10.312"]
[reagent "0.7.0"]
[re-frame "0.10.5"]
[garden "1.3.2"]
[ns-tracker "0.3.0"]
[cljs-ajax "0.7.3"]]
[garden "1.3.5"]
[ns-tracker "0.3.1"]
[cljs-ajax "0.7.3"]
;; server side libraries
[ring "1.6.3"]
[compojure "1.6.1"]
[environ "1.1.0"]
[ring/ring-defaults "0.3.2"]
[clj-http "3.9.0"]
[cheshire "5.8.0"]]

:plugins [[lein-cljsbuild "1.1.5"]
[lein-garden "0.2.8"]]
:plugins [[lein-cljsbuild "1.1.7"]
[lein-garden "0.3.0"]
;; server side plugins
[lein-ring "0.12.4"]
[lein-environ "1.1.0"]]

:min-lein-version "2.5.3"

:source-paths ["src/clj"]
:source-paths ["src/clj" "src/cljs"]

:clean-targets ^{:protect false} ["resources/public/js/compiled" "target"
:clean-targets ^{:protect false} ["resources/public/js/compiled"
"resources/public/css"]

:figwheel {:css-dirs ["resources/public/css"]}
:ring {:handler ccclock.core/app
:port 8000}

:garden {:builds [{:id "screen"
:source-paths ["src/clj"]
:stylesheet ccclock.css/screen
:compiler {:output-to "resources/public/css/screen.css"
:pretty-print? true}}]}

:repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}
:repl-options {:nrepl-middleware [cider.piggieback/wrap-cljs-repl]}

:profiles
{:dev
{:dependencies [[binaryage/devtools "0.9.4"]
[figwheel-sidecar "0.5.13"]
[com.cemerick/piggieback "0.2.2"]
[day8.re-frame/re-frame-10x "0.3.3"]]

:plugins [[lein-figwheel "0.5.13"]]}
:prod { }}
;; composite profiles are being used
;; all lein configuration should be in :project/<profile> sections below
;; DO NOT edit :profiles/<profile> below, to add profile config edit profiles.clj
{:dev [:project/dev :profiles/dev]
:test [:project/test :profiles/test]
:profiles/dev {}
:profiles/test {}
:project/dev {:dependencies [[binaryage/devtools "0.9.10"]
[day8.re-frame/re-frame-10x "0.3.3"]
[figwheel-sidecar "0.5.16"]
[cider/piggieback "0.3.6"]]
:plugins [[lein-figwheel "0.5.16"]]
:figwheel {:css-dirs ["resources/public/css"]}}
:project/test {}
:prod {}}

:cljsbuild
{:builds
Expand All @@ -47,20 +65,24 @@
:output-dir "resources/public/js/compiled/out"
:asset-path "js/compiled/out"
:source-map-timestamp true
:preloads [devtools.preload
day8.re-frame-10x.preload]
:closure-defines {"re_frame.trace.trace_enabled_QMARK_" true}
:preloads [devtools.preload day8.re-frame-10x.preload]
:external-config {:devtools/config {:features-to-install :all}}
}}
:external-config {:devtools/config {:features-to-install :all}}}}

{:id "min"
:source-paths ["src/cljs"]
:compiler {:main ccclock.core
:output-to "resources/public/js/compiled/app.js"
:optimizations :advanced
:closure-defines {goog.DEBUG false}
:pretty-print false}}
:pretty-print false}}]}

;; server side settings
:main ccclock.core

:aot [ccclock.core]

]}
:uberjar-name "ccclock.jar"

)
:prep-tasks ["clean" ["cljsbuild" "once" "min"]["garden" "once"] "compile"])
24 changes: 23 additions & 1 deletion src/clj/ccclock/core.clj
@@ -1 +1,23 @@
(ns ccclock.core)
(ns ccclock.core
(:require [ccclock.route :as route])
(:require [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
[ring.middleware.reload :refer [wrap-reload]]
[environ.core :as environ]
[ring.adapter.jetty :refer [run-jetty]])
(:gen-class))


(def dev-app
(-> #'route/app-routes
(wrap-defaults site-defaults)
wrap-reload))


(def app
(-> route/app-routes
(wrap-defaults site-defaults)))


(defn -main [& args]
(let [port (Integer/parseInt (or (environ/env :proxy-port) "8000"))]
(run-jetty app {:port port :join? false})))
4 changes: 3 additions & 1 deletion src/clj/ccclock/css.clj
@@ -1,10 +1,12 @@
(ns ccclock.css
(:require [garden.def :refer [defstyles]]))


(def colors
{:default-text "#6A5ACD"
:default-background "#000"})


(defstyles screen
[:*
{:margin "0"
Expand Down Expand Up @@ -44,7 +46,7 @@
{:font-size "7vw"}]

[:.cond-display
{:font-size "19vw"
{:font-size "17vw"
:text-align "center"
:letter-spacing "1vw"
:padding-top "6vw"
Expand Down
25 changes: 25 additions & 0 deletions src/clj/ccclock/handler.clj
@@ -0,0 +1,25 @@
(ns ccclock.handler
(:require [ring.util.response :as response]
[environ.core :as environ]
[clj-http.client :as client]))


(defn handle-index [req]
;; NOTE: this will deliver your index.html
(-> (response/resource-response "index.html" {:root "public"})
(response/content-type "text/html")))


(defn handle-proxy [req]
(let [weather-url "https://api.darksky.net/forecast"
weather-apikey (environ/env :weather-apikey)
lat-lon (environ/env :lat-lon)
result (client/get
(str weather-url "/"
weather-apikey "/"
lat-lon))]
{:status 200
:headers {"Access-Control-Allow-Origin" "*"
"Access-Control-Allow-Headers" "Content-Type"
"Content-Type" "application/json"}
:body (get result :body)}))
13 changes: 13 additions & 0 deletions src/clj/ccclock/route.clj
@@ -0,0 +1,13 @@
(ns ccclock.route
(:require [ccclock.handler :as handler])
(:require [compojure.core :refer [defroutes GET]]
[compojure.route :as route]))


(defroutes app-routes
;; NOTE: this will deliver all of your assets from the public directory
;; of resources i.e. resources/public
(route/resources "/" {:root "public"})
(GET "/" [] handler/handle-index)
(GET "/weather" [] handler/handle-proxy)
(route/not-found "Page not found"))
7 changes: 1 addition & 6 deletions src/cljs/ccclock/config.cljs
@@ -1,10 +1,5 @@
(ns ccclock.config
(:require [ccclock.environ :as environ]))
(ns ccclock.config)


(def debug?
^boolean goog.DEBUG)


(def secrets
environ/secrets)
5 changes: 2 additions & 3 deletions src/cljs/ccclock/db.cljs
Expand Up @@ -2,6 +2,5 @@


(def default-db
{:time (js/Date.)
:weather {}
:forecast {}})
{:time (js/Date.)
:weather {}})
7 changes: 0 additions & 7 deletions src/cljs/ccclock/environ.cljs.example

This file was deleted.