]>
Commit | Line | Data |
---|---|---|
9f986275 SW |
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 } |