0
|
1 /* |
|
2 * page-new.c -- page /new |
|
3 * |
|
4 * Copyright (c) 2020 David Demelier <markand@malikania.fr> |
|
5 * |
|
6 * Permission to use, copy, modify, and/or distribute this software for any |
|
7 * purpose with or without fee is hereby granted, provided that the above |
|
8 * copyright notice and this permission notice appear in all copies. |
|
9 * |
|
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
|
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
|
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
17 */ |
|
18 |
|
19 #include <sys/types.h> |
|
20 #include <assert.h> |
|
21 #include <stdarg.h> |
|
22 #include <stdint.h> |
|
23 #include <string.h> |
|
24 |
|
25 #include <kcgi.h> |
|
26 |
|
27 #include "database.h" |
|
28 #include "fragment-duration.h" |
|
29 #include "image.h" |
|
30 #include "page-new.h" |
|
31 #include "page.h" |
|
32 #include "util.h" |
|
33 |
|
34 static const char *keywords[] = { |
|
35 "durations" |
|
36 }; |
|
37 |
|
38 static const struct { |
|
39 const char *title; |
|
40 long long int secs; |
|
41 } durations[] = { |
|
42 { "day", IMAGE_DURATION_DAY }, |
|
43 { "hour", IMAGE_DURATION_HOUR }, |
|
44 { "week", IMAGE_DURATION_WEEK }, |
|
45 { "month", IMAGE_DURATION_MONTH }, |
|
46 }; |
|
47 |
|
48 static int |
|
49 template(size_t keyword, void *arg) |
|
50 { |
|
51 struct kreq *r = arg; |
|
52 |
|
53 switch (keyword) { |
|
54 case 0: |
|
55 for (size_t i = 0; i < NELEM(durations); ++i) |
|
56 fragment_duration(r, durations[i].title); |
|
57 break; |
|
58 default: |
|
59 break; |
|
60 } |
|
61 |
|
62 return 1; |
|
63 } |
|
64 |
|
65 static long long int |
|
66 duration(const char *val) |
|
67 { |
|
68 for (size_t i = 0; i < NELEM(durations); ++i) |
|
69 if (strcmp(val, durations[i].title) == 0) |
|
70 return durations[i].secs; |
|
71 |
|
72 /* Default to month. */ |
|
73 return IMAGE_DURATION_MONTH; |
|
74 } |
|
75 |
|
76 static void |
|
77 get(struct kreq *r) |
|
78 { |
|
79 struct ktemplate kt = { |
|
80 .key = keywords, |
|
81 .keysz = NELEM(keywords), |
|
82 .cb = template, |
|
83 .arg = r |
|
84 }; |
|
85 |
|
86 page(r, &kt, KHTTP_200, "pages/new.html"); |
|
87 } |
|
88 |
|
89 static void |
|
90 post(struct kreq *r) |
|
91 { |
|
92 struct image image = { |
|
93 .author = estrdup("Anonymous"), |
|
94 .title = estrdup("Untitled"), |
|
95 .visible = true |
|
96 }; |
|
97 |
|
98 for (size_t i = 0; i < r->fieldsz; ++i) { |
|
99 const char *key = r->fields[i].key; |
|
100 const char *val = r->fields[i].val; |
|
101 |
|
102 if (strcmp(key, "title") == 0) |
|
103 replace(&image.title, val); |
|
104 else if (strcmp(key, "author") == 0) |
|
105 replace(&image.author, val); |
|
106 else if (strcmp(key, "duration") == 0) |
|
107 image.duration = duration(val); |
|
108 else if (strcmp(key, "filename") == 0) { |
|
109 if (r->fields[i].file) |
|
110 replace(&image.filename, r->fields[i].file); |
|
111 |
|
112 image.data = ememdup(r->fields[i].val, r->fields[i].valsz); |
|
113 image.datasz = r->fields[i].valsz; |
|
114 } else if (strcmp(key, "private") == 0) |
|
115 image.visible = strcmp(val, "on") != 0; |
|
116 } |
|
117 |
|
118 /* TODO: image_isvalid should check for all stuff. */ |
|
119 if (!image.data || !image_isvalid(image.data, image.datasz)) |
|
120 page(r, NULL, KHTTP_400, "pages/400.html"); |
|
121 else if (!database_insert(&image)) |
|
122 page(r, NULL, KHTTP_500, "pages/500.html"); |
|
123 else { |
|
124 /* Redirect to image details. */ |
|
125 khttp_head(r, kresps[KRESP_STATUS], "%s", khttps[KHTTP_302]); |
|
126 khttp_head(r, kresps[KRESP_LOCATION], "/image/%s", image.id); |
|
127 khttp_body(r); |
|
128 khttp_free(r); |
|
129 } |
|
130 |
|
131 image_finish(&image); |
|
132 } |
|
133 |
|
134 void |
|
135 page_new(struct kreq *r) |
|
136 { |
|
137 assert(r); |
|
138 |
|
139 switch (r->method) { |
|
140 case KMETHOD_GET: |
|
141 get(r); |
|
142 break; |
|
143 case KMETHOD_POST: |
|
144 post(r); |
|
145 break; |
|
146 default: |
|
147 break; |
|
148 } |
|
149 } |