Dylan Baker 3 лет назад
Родитель
Сommit
103579d74f
4 измененных файлов: 170 добавлений и 27 удалений
  1. 102
    22
      Cargo.lock
  2. 5
    1
      Cargo.toml
  3. 60
    3
      src/main.rs
  4. 3
    1
      templates/admin/index.html

+ 102
- 22
Cargo.lock Просмотреть файл

148
  "chrono",
148
  "chrono",
149
  "hmac",
149
  "hmac",
150
  "kv-log-macro",
150
  "kv-log-macro",
151
- "rand",
152
- "serde",
151
+ "rand 0.7.3",
152
+ "serde 1.0.115",
153
  "serde_json",
153
  "serde_json",
154
  "sha2",
154
  "sha2",
155
 ]
155
 ]
268
 checksum = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d"
268
 checksum = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d"
269
 dependencies = [
269
 dependencies = [
270
  "byteorder",
270
  "byteorder",
271
- "serde",
271
+ "serde 1.0.115",
272
 ]
272
 ]
273
 
273
 
274
 [[package]]
274
 [[package]]
408
 dependencies = [
408
 dependencies = [
409
  "num-integer",
409
  "num-integer",
410
  "num-traits",
410
  "num-traits",
411
- "serde",
411
+ "rustc-serialize",
412
+ "serde 1.0.115",
412
  "time 0.1.43",
413
  "time 0.1.43",
413
 ]
414
 ]
414
 
415
 
448
  "hkdf",
449
  "hkdf",
449
  "hmac",
450
  "hmac",
450
  "percent-encoding",
451
  "percent-encoding",
451
- "rand",
452
+ "rand 0.7.3",
452
  "sha2",
453
  "sha2",
453
  "time 0.2.16",
454
  "time 0.2.16",
454
  "version_check",
455
  "version_check",
577
  "cfg-if",
578
  "cfg-if",
578
  "js-sys",
579
  "js-sys",
579
  "log",
580
  "log",
580
- "serde",
581
+ "serde 1.0.115",
581
  "serde_derive",
582
  "serde_derive",
582
  "serde_json",
583
  "serde_json",
583
  "wasm-bindgen",
584
  "wasm-bindgen",
590
 source = "registry+https://github.com/rust-lang/crates.io-index"
591
 source = "registry+https://github.com/rust-lang/crates.io-index"
591
 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
592
 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
592
 
593
 
594
+[[package]]
595
+name = "fuchsia-cprng"
596
+version = "0.1.1"
597
+source = "registry+https://github.com/rust-lang/crates.io-index"
598
+checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
599
+
593
 [[package]]
600
 [[package]]
594
 name = "futures-channel"
601
 name = "futures-channel"
595
 version = "0.3.5"
602
 version = "0.3.5"
797
  "cookie",
804
  "cookie",
798
  "infer",
805
  "infer",
799
  "pin-project-lite",
806
  "pin-project-lite",
800
- "rand",
801
- "serde",
807
+ "rand 0.7.3",
808
+ "serde 1.0.115",
802
  "serde_json",
809
  "serde_json",
803
  "serde_qs",
810
  "serde_qs",
804
  "serde_urlencoded",
811
  "serde_urlencoded",
926
 version = "0.1.0"
933
 version = "0.1.0"
927
 dependencies = [
934
 dependencies = [
928
  "async-std",
935
  "async-std",
936
+ "chrono",
929
  "dotenv",
937
  "dotenv",
938
+ "serde 1.0.115",
939
+ "serde_json",
930
  "tera",
940
  "tera",
931
  "tide 0.13.0",
941
  "tide 0.13.0",
932
  "tide-tera",
942
  "tide-tera",
943
+ "uuid",
933
 ]
944
 ]
934
 
945
 
935
 [[package]]
946
 [[package]]
1136
  "proc-macro2",
1147
  "proc-macro2",
1137
 ]
1148
 ]
1138
 
1149
 
1150
+[[package]]
1151
+name = "rand"
1152
+version = "0.3.23"
1153
+source = "registry+https://github.com/rust-lang/crates.io-index"
1154
+checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c"
1155
+dependencies = [
1156
+ "libc",
1157
+ "rand 0.4.6",
1158
+]
1159
+
1160
+[[package]]
1161
+name = "rand"
1162
+version = "0.4.6"
1163
+source = "registry+https://github.com/rust-lang/crates.io-index"
1164
+checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
1165
+dependencies = [
1166
+ "fuchsia-cprng",
1167
+ "libc",
1168
+ "rand_core 0.3.1",
1169
+ "rdrand",
1170
+ "winapi",
1171
+]
1172
+
1139
 [[package]]
1173
 [[package]]
1140
 name = "rand"
1174
 name = "rand"
1141
 version = "0.7.3"
1175
 version = "0.7.3"
1145
  "getrandom",
1179
  "getrandom",
1146
  "libc",
1180
  "libc",
1147
  "rand_chacha",
1181
  "rand_chacha",
1148
- "rand_core",
1182
+ "rand_core 0.5.1",
1149
  "rand_hc",
1183
  "rand_hc",
1150
 ]
1184
 ]
1151
 
1185
 
1156
 checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
1190
 checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
1157
 dependencies = [
1191
 dependencies = [
1158
  "ppv-lite86",
1192
  "ppv-lite86",
1159
- "rand_core",
1193
+ "rand_core 0.5.1",
1160
 ]
1194
 ]
1161
 
1195
 
1196
+[[package]]
1197
+name = "rand_core"
1198
+version = "0.3.1"
1199
+source = "registry+https://github.com/rust-lang/crates.io-index"
1200
+checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
1201
+dependencies = [
1202
+ "rand_core 0.4.2",
1203
+]
1204
+
1205
+[[package]]
1206
+name = "rand_core"
1207
+version = "0.4.2"
1208
+source = "registry+https://github.com/rust-lang/crates.io-index"
1209
+checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
1210
+
1162
 [[package]]
1211
 [[package]]
1163
 name = "rand_core"
1212
 name = "rand_core"
1164
 version = "0.5.1"
1213
 version = "0.5.1"
1174
 source = "registry+https://github.com/rust-lang/crates.io-index"
1223
 source = "registry+https://github.com/rust-lang/crates.io-index"
1175
 checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
1224
 checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
1176
 dependencies = [
1225
 dependencies = [
1177
- "rand_core",
1226
+ "rand_core 0.5.1",
1227
+]
1228
+
1229
+[[package]]
1230
+name = "rdrand"
1231
+version = "0.4.0"
1232
+source = "registry+https://github.com/rust-lang/crates.io-index"
1233
+checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
1234
+dependencies = [
1235
+ "rand_core 0.3.1",
1178
 ]
1236
 ]
1179
 
1237
 
1180
 [[package]]
1238
 [[package]]
1219
 source = "registry+https://github.com/rust-lang/crates.io-index"
1277
 source = "registry+https://github.com/rust-lang/crates.io-index"
1220
 checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
1278
 checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
1221
 
1279
 
1280
+[[package]]
1281
+name = "rustc-serialize"
1282
+version = "0.3.24"
1283
+source = "registry+https://github.com/rust-lang/crates.io-index"
1284
+checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
1285
+
1222
 [[package]]
1286
 [[package]]
1223
 name = "rustc_version"
1287
 name = "rustc_version"
1224
 version = "0.2.3"
1288
 version = "0.2.3"
1270
 source = "registry+https://github.com/rust-lang/crates.io-index"
1334
 source = "registry+https://github.com/rust-lang/crates.io-index"
1271
 checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0"
1335
 checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0"
1272
 
1336
 
1337
+[[package]]
1338
+name = "serde"
1339
+version = "0.9.15"
1340
+source = "registry+https://github.com/rust-lang/crates.io-index"
1341
+checksum = "34b623917345a631dc9608d5194cc206b3fe6c3554cd1c75b937e55e285254af"
1342
+
1273
 [[package]]
1343
 [[package]]
1274
 name = "serde"
1344
 name = "serde"
1275
 version = "1.0.115"
1345
 version = "1.0.115"
1298
 dependencies = [
1368
 dependencies = [
1299
  "itoa",
1369
  "itoa",
1300
  "ryu",
1370
  "ryu",
1301
- "serde",
1371
+ "serde 1.0.115",
1302
 ]
1372
 ]
1303
 
1373
 
1304
 [[package]]
1374
 [[package]]
1310
  "data-encoding",
1380
  "data-encoding",
1311
  "error-chain",
1381
  "error-chain",
1312
  "percent-encoding",
1382
  "percent-encoding",
1313
- "serde",
1383
+ "serde 1.0.115",
1314
 ]
1384
 ]
1315
 
1385
 
1316
 [[package]]
1386
 [[package]]
1321
 dependencies = [
1391
 dependencies = [
1322
  "dtoa",
1392
  "dtoa",
1323
  "itoa",
1393
  "itoa",
1324
- "serde",
1394
+ "serde 1.0.115",
1325
  "url",
1395
  "url",
1326
 ]
1396
 ]
1327
 
1397
 
1441
 dependencies = [
1511
 dependencies = [
1442
  "proc-macro2",
1512
  "proc-macro2",
1443
  "quote",
1513
  "quote",
1444
- "serde",
1514
+ "serde 1.0.115",
1445
  "serde_derive",
1515
  "serde_derive",
1446
  "syn",
1516
  "syn",
1447
 ]
1517
 ]
1455
  "base-x",
1525
  "base-x",
1456
  "proc-macro2",
1526
  "proc-macro2",
1457
  "quote",
1527
  "quote",
1458
- "serde",
1528
+ "serde 1.0.115",
1459
  "serde_derive",
1529
  "serde_derive",
1460
  "serde_json",
1530
  "serde_json",
1461
  "sha1",
1531
  "sha1",
1499
  "percent-encoding",
1569
  "percent-encoding",
1500
  "pest",
1570
  "pest",
1501
  "pest_derive",
1571
  "pest_derive",
1502
- "rand",
1572
+ "rand 0.7.3",
1503
  "regex",
1573
  "regex",
1504
- "serde",
1574
+ "serde 1.0.115",
1505
  "serde_json",
1575
  "serde_json",
1506
  "slug",
1576
  "slug",
1507
  "unic-segment",
1577
  "unic-segment",
1529
  "http-types",
1599
  "http-types",
1530
  "kv-log-macro",
1600
  "kv-log-macro",
1531
  "route-recognizer 0.1.13",
1601
  "route-recognizer 0.1.13",
1532
- "serde",
1602
+ "serde 1.0.115",
1533
  "serde_json",
1603
  "serde_json",
1534
 ]
1604
 ]
1535
 
1605
 
1550
  "kv-log-macro",
1620
  "kv-log-macro",
1551
  "pin-project-lite",
1621
  "pin-project-lite",
1552
  "route-recognizer 0.2.0",
1622
  "route-recognizer 0.2.0",
1553
- "serde",
1623
+ "serde 1.0.115",
1554
  "serde_json",
1624
  "serde_json",
1555
 ]
1625
 ]
1556
 
1626
 
1723
  "idna",
1793
  "idna",
1724
  "matches",
1794
  "matches",
1725
  "percent-encoding",
1795
  "percent-encoding",
1726
- "serde",
1796
+ "serde 1.0.115",
1797
+]
1798
+
1799
+[[package]]
1800
+name = "uuid"
1801
+version = "0.4.0"
1802
+source = "registry+https://github.com/rust-lang/crates.io-index"
1803
+checksum = "7cfec50b0842181ba6e713151b72f4ec84a6a7e2c9c8a8a3ffc37bb1cd16b231"
1804
+dependencies = [
1805
+ "rand 0.3.23",
1806
+ "serde 0.9.15",
1727
 ]
1807
 ]
1728
 
1808
 
1729
 [[package]]
1809
 [[package]]
1762
 checksum = "f0563a9a4b071746dd5aedbc3a28c6fe9be4586fb3fbadb67c400d4f53c6b16c"
1842
 checksum = "f0563a9a4b071746dd5aedbc3a28c6fe9be4586fb3fbadb67c400d4f53c6b16c"
1763
 dependencies = [
1843
 dependencies = [
1764
  "cfg-if",
1844
  "cfg-if",
1765
- "serde",
1845
+ "serde 1.0.115",
1766
  "serde_json",
1846
  "serde_json",
1767
  "wasm-bindgen-macro",
1847
  "wasm-bindgen-macro",
1768
 ]
1848
 ]

+ 5
- 1
Cargo.toml Просмотреть файл

8
 
8
 
9
 [dependencies]
9
 [dependencies]
10
 async-std = { version = "1.6.0", features = ["attributes"] }
10
 async-std = { version = "1.6.0", features = ["attributes"] }
11
+chrono = { version = "0.4", features = ["serde", "rustc-serialize"] }
11
 dotenv = "0.15.0"
12
 dotenv = "0.15.0"
12
-tide = "0.13.0"
13
+serde = "1.0.115"
13
 tera = "1.5.0"
14
 tera = "1.5.0"
15
+tide = "0.13.0"
14
 tide-tera = "0.1.1"
16
 tide-tera = "0.1.1"
17
+uuid = { version = "0.4", features = ["serde", "v4"] }
18
+serde_json = "1.0.57"

+ 60
- 3
src/main.rs Просмотреть файл

1
-use std::io::ErrorKind;
1
+use std::env;
2
+use std::fs::File;
3
+use std::io::prelude::*;
4
+use std::io::{Error, ErrorKind};
5
+use std::path::PathBuf;
2
 
6
 
7
+use chrono::prelude::{Local, NaiveDate};
8
+use dotenv;
9
+use serde::{Deserialize, Serialize};
10
+use serde_json;
3
 use tera::{Context, Tera};
11
 use tera::{Context, Tera};
4
 use tide::utils::After;
12
 use tide::utils::After;
5
-use tide::{Body, Response, Result, StatusCode};
13
+use tide::{Body, Response, StatusCode};
14
+use uuid::Uuid;
15
+
16
+#[derive(Debug, Serialize, Deserialize)]
17
+struct Post {
18
+    id: String,
19
+    title: String,
20
+    body: String,
21
+    date: String,
22
+}
23
+
24
+impl Post {
25
+    fn save(&mut self) -> std::io::Result<()> {
26
+        let mut path: PathBuf = get_posts_directory()?;
27
+        let filename = format!("{}.json", self.id);
28
+        path = path.join(&filename);
29
+        let mut file = match File::create(&path) {
30
+            Err(why) => panic!("couldn't create {}: {}", self.id, why),
31
+            Ok(file) => file,
32
+        };
33
+        match file.write_all(serde_json::to_string(&self)?.as_bytes()) {
34
+            Err(why) => Err(Error::new(
35
+                ErrorKind::Other,
36
+                format!("couldn't write to {}.json: {}", self.id, why),
37
+            )),
38
+            Ok(_) => Ok(()),
39
+        }
40
+    }
41
+}
42
+
43
+fn get_posts_directory() -> Result<PathBuf, std::io::Error> {
44
+    match env::var("POSTS_DIR") {
45
+        Ok(dir) => Ok(dir.into()),
46
+        Err(_) => Err(Error::new(
47
+            ErrorKind::Other,
48
+            "Posts directory environment variable not set",
49
+        )),
50
+    }
51
+}
6
 
52
 
7
 #[async_std::main]
53
 #[async_std::main]
8
-async fn main() -> Result<()> {
54
+async fn main() -> std::io::Result<()> {
55
+    dotenv::dotenv().ok();
9
     tide::log::start();
56
     tide::log::start();
10
     let mut app = tide::new();
57
     let mut app = tide::new();
11
 
58
 
12
     app.with(After(|mut res: Response| async {
59
     app.with(After(|mut res: Response| async {
13
         if let Some(err) = res.downcast_error::<async_std::io::Error>() {
60
         if let Some(err) = res.downcast_error::<async_std::io::Error>() {
61
+            println!("{:?}", res);
14
             if let ErrorKind::NotFound = err.kind() {
62
             if let ErrorKind::NotFound = err.kind() {
15
                 res.set_status(StatusCode::NotFound);
63
                 res.set_status(StatusCode::NotFound);
16
             }
64
             }
30
         Ok(Body::from_string(html))
78
         Ok(Body::from_string(html))
31
     });
79
     });
32
 
80
 
81
+    app.at("/admin/posts")
82
+        .post(|mut req: tide::Request<()>| async move {
83
+            let mut post: Post = req.body_form().await?;
84
+            post.id = Uuid::new_v4().to_string();
85
+            post.date = Local::now().date().naive_local().to_string();
86
+            post.save()?;
87
+            Ok(tide::Redirect::new("/admin"))
88
+        });
89
+
33
     app.listen("127.0.0.1:8080").await?;
90
     app.listen("127.0.0.1:8080").await?;
34
 
91
 
35
     Ok(())
92
     Ok(())

+ 3
- 1
templates/admin/index.html Просмотреть файл

1
 {% extends "admin/layout.html" %} {% block content %}
1
 {% extends "admin/layout.html" %} {% block content %}
2
 <h1 class="heading">Admin</h1>
2
 <h1 class="heading">Admin</h1>
3
-<form class="form" method="POST" action="/posts">
3
+<form class="form" method="POST" action="/admin/posts">
4
+  <input type="hidden" name="id" />
5
+  <input type="hidden" name="date" />
4
   <div class="form__field">
6
   <div class="form__field">
5
     <label for="title" class="form__label">Title</label>
7
     <label for="title" class="form__label">Title</label>
6
     <input class="form__text-field" type="text" name="title" />
8
     <input class="form__text-field" type="text" name="title" />

Загрузка…
Отмена
Сохранить