[Racket] Ferti hydroponic nutrient solver, redux.
raco fmt.
Changed files
db/conn.rkt
@@ -15,7 +15,7 @@
15
15
[(connection? (current-conn)) (printf "Database connection already exists: ~e\n" (current-conn))]
16
16
[else
17
17
(current-conn (sqlite3-connect #:database path #:mode 'create))
18
Removed:
(printf "Created database connection at path: ~a\n" path)]))
18
Added:
(printf "Connected to database: ~a\n" path)]))
19
19
20
20
(define (disconnect!)
21
21
(disconnect (current-conn))
handlers.rkt
@@ -17,16 +17,16 @@
17
17
(define (wrap-basic-auth handler)
18
18
(lambda (req)
19
19
(match (request->basic-credentials req)
20
Removed:
[(cons user pass)
21
Removed:
;; credentials found → continue to dispatcher
22
Removed:
(handler req)]
20
Added:
;; credentials found → continue to dispatcher
21
Added:
[(cons user pass) (handler req)]
23
22
[else
24
23
;; no credentials → trigger auth challenge
25
Removed:
(response
26
Removed:
401 #"Unauthorized" (current-seconds) TEXT/HTML-MIME-TYPE
27
Removed:
(list
28
Removed:
(make-basic-auth-header "Ferti Private Area"))
29
Removed:
void)])))
24
Added:
(response 401
25
Added:
#"Unauthorized"
26
Added:
(current-seconds)
27
Added:
TEXT/HTML-MIME-TYPE
28
Added:
(list (make-basic-auth-header "Ferti Private Area"))
29
Added:
void)])))
30
30
31
31
(define-values (app-dispatch _)
32
32
(dispatch-rules [("ferti") #:method "get" ferti]
main.rkt
@@ -9,10 +9,9 @@
9
9
10
10
(define-runtime-path development-db-path "storage/development.sqlite3")
11
11
(module+ main
12
Removed:
(with-handlers ([exn:fail?
13
Removed:
(λ (e)
14
Removed:
(printf "Startup error: ~a\n" (exn-message e))
15
Removed:
(exit 1))])
12
Added:
(with-handlers ([exn:fail? (λ (e)
13
Added:
(printf "Startup error: ~a\n" (exn-message e))
14
Added:
(exit 1))])
16
15
(connect! #:path development-db-path)
17
16
(if (file-exists? development-db-path)
18
17
(printf "Database already exists: ~a" development-db-path)
views.rkt
@@ -68,33 +68,31 @@
68
68
;; Pages
69
69
70
70
(define (ferti-page fertilizer-recipe latest-measurement-hash latest-target-hash measurements)
71
Removed:
(page-template
72
Removed:
"Ferti"
73
Removed:
`((h1 ((class "display-1 mb-3")) "Ferti")
74
Removed:
,ferti-actions
75
Removed:
,@(ferti-recipe fertilizer-recipe)
76
Removed:
,@(ferti-targets latest-measurement-hash latest-target-hash)
77
Removed:
,@(ferti-measurements measurements)
78
Removed:
,@(ferti-fertilizers))))
71
Added:
(page-template "Ferti"
72
Added:
`((h1 ((class "display-1 mb-3")) "Ferti") ,ferti-actions
73
Added:
,@(ferti-recipe fertilizer-recipe)
74
Added:
,@(ferti-targets latest-measurement-hash
75
Added:
latest-target-hash)
76
Added:
,@(ferti-measurements measurements)
77
Added:
,@(ferti-fertilizers))))
79
78
80
79
(define ferti-actions
81
80
`(div ((class "btn-group mb-3"))
82
81
(a ((class "btn btn-outline-primary") [href "/target/new"]) "Créer une cible")
83
82
(a ((class "btn btn-outline-primary") [href "/measurement/new"]) "Ajouter un relevé")
84
83
(a ((class "btn btn-outline-primary") [href "/fertilizer/new"]) "Ajouter un intrant")))
85
Removed:
86
84
87
85
(define (ferti-recipe ferti-recipe)
88
Removed:
`((h2 () "Recette")
89
Removed:
,(if (ormap (λ (pair) (not (zero? (cdr pair)))) ferti-recipe)
90
Removed:
`(table ((class "table"))
91
Removed:
(tr (th "Intrant") (th ((class "text-end")) "Quantité (g/L)"))
92
Removed:
,@(for/list ([fertilizer-amount ferti-recipe]
93
Removed:
#:when (not (zero? (cdr fertilizer-amount))))
94
Removed:
(match-define (cons fertilizer amount) fertilizer-amount)
95
Removed:
`(tr (td () ,(fertilizer-name fertilizer))
96
Removed:
(td ((class "text-end font-monospace")) ,(round 2 amount)))))
97
Removed:
`(p "La recette Ferti requiert au moins un relevé et une cible."))))
86
Added:
`((h2 () "Recette") ,(if (ormap (λ (pair) (not (zero? (cdr pair)))) ferti-recipe)
87
Added:
`(table ((class "table"))
88
Added:
(tr (th "Intrant") (th ((class "text-end")) "Quantité (g/L)"))
89
Added:
,@(for/list ([fertilizer-amount ferti-recipe]
90
Added:
#:when (not (zero? (cdr fertilizer-amount))))
91
Added:
(match-define (cons fertilizer amount) fertilizer-amount)
92
Added:
`(tr (td () ,(fertilizer-name fertilizer))
93
Added:
(td ((class "text-end font-monospace"))
94
Added:
,(round 2 amount)))))
95
Added:
`(p "La recette Ferti requiert au moins un relevé et une cible."))))
98
96
99
97
(define (ferti-targets latest-measurement-hash latest-target-hash)
100
98
`((h2 () "Dernière Cible")
@@ -128,35 +126,35 @@
128
126
"—")))))))
129
127
130
128
(define (ferti-measurements measurements)
131
Removed:
`((h2 () "Relevés")
132
Removed:
(table ((class "table table-striped"))
133
Removed:
(tr (th "Date")
134
Removed:
(th ((class "text-end")) "N")
135
Removed:
(th ((class "text-end")) "P")
136
Removed:
(th ((class "text-end")) "K"))
137
Removed:
,@(for/list ([m measurements])
138
Removed:
(define measured-on (nutrient-measurement-date m))
139
Removed:
(define-values (n p k)
140
Removed:
(apply values
141
Removed:
(for/list ([nutrient '("Nitrate Nitrogen" "Phosphorus" "Potassium")])
142
Removed:
(define n (get-nutrient #:name nutrient))
143
Removed:
(define mnv (get-nutrient-measurement-value m n))
144
Removed:
(if (real? mnv)
145
Removed:
(round 2 mnv)
146
Removed:
"—"))))
147
Removed:
`(tr (td ,measured-on)
148
Removed:
(td ((class "text-end font-monospace")) ,n)
149
Removed:
(td ((class "text-end font-monospace")) ,p)
150
Removed:
(td ((class "text-end font-monospace")) ,k))))))
129
Added:
`((h2 () "Relevés") (table ((class "table table-striped"))
130
Added:
(tr (th "Date")
131
Added:
(th ((class "text-end")) "N")
132
Added:
(th ((class "text-end")) "P")
133
Added:
(th ((class "text-end")) "K"))
134
Added:
,@(for/list ([m measurements])
135
Added:
(define measured-on (nutrient-measurement-date m))
136
Added:
;; TODO: use new nutrient-value hash, available
137
Added:
;; immediately in this context.
138
Added:
(define-values (n p k)
139
Added:
(apply values
140
Added:
(for/list ([nutrient '("Nitrate Nitrogen" "Phosphorus"
141
Added:
"Potassium")])
142
Added:
(define n (get-nutrient #:name nutrient))
143
Added:
(define mnv (get-nutrient-measurement-value m n))
144
Added:
(if (real? mnv)
145
Added:
(round 2 mnv)
146
Added:
"—"))))
147
Added:
`(tr (td ,measured-on)
148
Added:
(td ((class "text-end font-monospace")) ,n)
149
Added:
(td ((class "text-end font-monospace")) ,p)
150
Added:
(td ((class "text-end font-monospace")) ,k))))))
151
151
152
152
(define (ferti-fertilizers)
153
Removed:
`((h2 () "Intrants")
154
Removed:
(table ((class "table table-striped"))
155
Removed:
(tr (th () "Nom de référence")
156
Removed:
(th () "Nom de marque"))
157
Removed:
,@(for/list ([fertilizer (get-fertilizer-products)])
158
Removed:
`(tr (td ,(fertilizer-name fertilizer))
159
Removed:
(td ,(or (fertilizer-brand-name fertilizer) "—")))))))
153
Added:
`((h2 () "Intrants") (table ((class "table table-striped"))
154
Added:
(tr (th () "Nom de référence") (th () "Nom de marque"))
155
Added:
,@(for/list ([fertilizer (get-fertilizer-products)])
156
Added:
`(tr (td ,(fertilizer-name fertilizer))
157
Added:
(td ,(or (fertilizer-brand-name fertilizer) "—")))))))
160
158
161
159
(define (new-measurement-page)
162
160
(page-template "Nouveau relevé"