]> git.scottworley.com Git - gumdrone/blob - src/main.rs
Release 0.1.1
[gumdrone] / src / main.rs
1 // gumdrone: Order chewing gum from a website
2 //
3 // This program is free software: you can redistribute it and/or modify it
4 // under the terms of the GNU Affero General Public License as published
5 // by the Free Software Foundation, version 3.
6
7 use std::io::prelude::*;
8
9 const ORDERS_FILE: &str = "/var/lib/gumdrone/orders";
10
11 const ORDER_PAGE: &str = "<!DOCTYPE html>
12 <html>
13 <head>
14 <meta charset=\"utf-8\">
15 <title>Order!</title>
16 <style>
17 td input { width: 3em; }
18 </style>
19 </head>
20 <body>
21 <h1>Order Gum!</h1>
22 <form action='/' method='POST'>
23 <table>
24 <tr><th>Qty</th><th>Product</th></tr>
25 <tr><td><input name='br' value='0'></td><td>Wrigley's Big Red</td></tr>
26 <tr><td><input name='dm' value='0'></td><td>Wrigley's Doublemint</td></tr>
27 <tr><td><input name='ep' value='0'></td><td>Wrigley's Eclipse Peppermint</td></tr>
28 <tr><td><input name='es' value='0'></td><td>Wrigley's Eclipse Spearmint</td></tr>
29 <tr><td><input name='ew' value='0'></td><td>Wrigley's Eclipse Winterfrost</td></tr>
30 <tr><td><input name='xb' value='0'></td><td>Wrigley's Extra Classic Bubble</td></tr>
31 <tr><td><input name='xp' value='0'></td><td>Wrigley's Extra Peppermint</td></tr>
32 <tr><td><input name='xi' value='0'></td><td>Wrigley's Extra Polar Ice</td></tr>
33 <tr><td><input name='ri' value='0'></td><td>Wrigley's Extra Refreshers Polar Ice</td></tr>
34 <tr><td><input name='rs' value='0'></td><td>Wrigley's Extra Refreshers Spearmint</td></tr>
35 <tr><td><input name='xs' value='0'></td><td>Wrigley's Extra Spearmint</td></tr>
36 <tr><td><input name='xw' value='0'></td><td>Wrigley's Extra Sweet Watermellon</td></tr>
37 <tr><td><input name='xf' value='0'></td><td>Wrigley's Extra Winterfresh</td></tr>
38 <tr><td><input name='to' value='0'></td><td>Wrigley's Hubba Bubba Bubble Tape Original</td></tr>
39 <tr><td><input name='tr' value='0'></td><td>Wrigley's Hubba Bubba Bubble Tape Sour Blue Raspberry</td></tr>
40 <tr><td><input name='ho' value='0'></td><td>Wrigley's Hubba Bubba Max Original</td></tr>
41 <tr><td><input name='hr' value='0'></td><td>Wrigley's Hubba Bubba Max Sour Blue Raspberry</td></tr>
42 <tr><td><input name='hw' value='0'></td><td>Wrigley's Hubba Bubba Max Strawberry Watermellon</td></tr>
43 <tr><td><input name='jf' value='0'></td><td>Wrigley's Juicy Fruit</td></tr>
44 <tr><td><input name='sp' value='0'></td><td>Wrigley's Spearmint</td></tr>
45 <tr><td><input name='wf' value='0'></td><td>Wrigley's Winterfresh</td></tr>
46 </table>
47 <div>Address: <input name='address'></div>
48 <div><input type='submit' value='Order'></div>
49 </form>
50 </body>
51 </html>";
52
53 fn prompt_for_order(_: &cgi::Request) -> Result<cgi::Response, cgi::Response> {
54 Ok(cgi::html_response(200, ORDER_PAGE))
55 }
56
57 fn write_order(order: &[u8]) -> std::io::Result<()> {
58 let datum = [order, b"\n"].concat();
59 let ofile = std::fs::File::options()
60 .append(true)
61 .create(true)
62 .open(ORDERS_FILE)?;
63 let mut vlock = fd_lock::RwLock::new(ofile);
64 vlock.write()?.write_all(&datum)?;
65 Ok(())
66 }
67
68 fn record_order(request: &cgi::Request) -> Result<cgi::Response, cgi::Response> {
69 let body = request.body();
70 write_order(body).map_err(|_| cgi::text_response(503, "Couldn't record order"))?;
71 Ok(cgi::text_response(200, "Order recorded"))
72 }
73
74 fn strip_body(mut response: cgi::Response) -> cgi::Response {
75 response.body_mut().clear();
76 response
77 }
78
79 fn respond(request: &cgi::Request) -> Result<cgi::Response, cgi::Response> {
80 match *request.method() {
81 cgi::http::Method::HEAD => prompt_for_order(request).map(strip_body),
82 cgi::http::Method::GET => prompt_for_order(request),
83 cgi::http::Method::PUT => record_order(request),
84 _ => Err(cgi::text_response(405, "Huh?")),
85 }
86 }
87
88 fn respond_or_report_error(request: cgi::Request) -> cgi::Response {
89 match respond(&request) {
90 Ok(result) => result,
91 Err(error) => error,
92 }
93 }
94
95 cgi::cgi_main! { respond_or_report_error }