diff options
| author | Patrick | 2023-08-28 03:40:51 +0200 |
|---|---|---|
| committer | Patrick | 2023-08-28 03:40:51 +0200 |
| commit | e8417ccf8f4a902e362f7e76af318849d2695d18 (patch) | |
| tree | fede9808d05370a0ed1fea8e5d49aba062fe1f14 | |
| parent | 189f7bdd03406eeb29c46a36a2bfbdb110bed645 (diff) | |
| download | chirp-e8417ccf8f4a902e362f7e76af318849d2695d18.tar.gz chirp-e8417ccf8f4a902e362f7e76af318849d2695d18.zip | |
likes, comments, write, read
| -rw-r--r-- | src/main.c | 239 |
1 files changed, 177 insertions, 62 deletions
@@ -1,3 +1,4 @@ +#include <stdint.h>
#include <mongoose.h>
#define STB_DS_IMPLEMENTATION
#include <stb_ds.h>
@@ -7,83 +8,99 @@ #define CONTENT_LEN 1024
#define HTML_LEN 1024*8
-typedef struct post Post;
-typedef struct user User;
+typedef struct Post Post;
+typedef struct User User;
User * UsersFind(struct mg_str name);
-// Post
+// Post / User
-struct post {
+struct Post {
time_t timestamp;
User * user;
char content[CONTENT_LEN];
+ int likes;
+ Post * comments;
+ Post * parent;
};
-
-
-// User
-
-struct user {
+struct User {
char name[NAME_LEN];
Post * posts;
User ** following;
};
+Post
+PostNew() {
+ Post result;
+ memset(&result, 0, sizeof(result));
+ return result;
+}
+
+void
+PostWrite(Post * post, FILE * f) {
+ fwrite(&post->timestamp, 8, 1, f);
+ fwrite(post->user->name, 1, sizeof(post->user->name), f);
+ fwrite(post->content, 1, sizeof(post->content), f);
+}
+
+void
+PostRead(Post * post, FILE * f) {
+ fread(&post->timestamp, 8, 1, f);
+ char name[NAME_LEN];
+ fread(name, 1, sizeof(name), f);
+ post->user = UsersFind(mg_str(name));
+ fread(post->content, 1, sizeof(post->content), f);
+}
+
User
UserNew(const char * name) {
User result;
+ memset(&result, 0, sizeof(result));
strcpy(result.name, name);
- result.posts = NULL;
- result.following = NULL;
return result;
}
void
-UserWrite(User * user) {
- char filename[128];
- snprintf(filename, 128, "data/users/%s", user->name);
- FILE * f = fopen(filename, "w");
-
- int numFollowing = arrlen(user->following);
- int numPosts = arrlen(user->posts);
- fwrite(&numFollowing, sizeof(int), 1, f);
- fwrite(&numPosts, sizeof(int), 1, f);
+UserWrite(User * user, FILE * f) {
+ fwrite(user->name, 1, sizeof(user->name), f);
+
+ uint32_t numFollowing = arrlen(user->following);
+ uint32_t numPosts = arrlen(user->posts);
+ fwrite(&numFollowing, 4, 1, f);
+ fwrite(&numPosts, 4, 1, f);
+
for (int i = 0; i < numFollowing; i++) {
fwrite(user->following[i]->name, 1, sizeof(user->following[i]->name), f);
}
+
for (int i = 0; i < numPosts; i++) {
- fwrite(&user->posts[i].timestamp, sizeof(user->posts[i].timestamp), 1, f);
- fwrite(user->posts[i].user->name, 1, sizeof(user->posts[i].user->name), f);
- fwrite(user->posts[i].content, 1, sizeof(user->posts[i].content), f);
+ PostWrite(&user->posts[i], f);
}
- fclose(f);
}
void
-UserRead(User * user) {
- char filename[128];
- snprintf(filename, 128, "data/users/%s", user->name);
- FILE * f = fopen(filename, "r");
-
- int numFollowing;
- int numPosts;
- fread(&numFollowing, sizeof(int), 1, f);
- fread(&numPosts, sizeof(int), 1, f);
+UserRead(User * user, FILE * f) {
+ fread(user->name, 1, sizeof(user->name), f);
+
+ uint32_t numFollowing;
+ uint32_t numPosts;
+ fread(&numFollowing, 1, 4, f);
+ fread(&numPosts, 1, 4, f);
+
+ user->following = NULL;
for (int i = 0; i < numFollowing; i++) {
char name[NAME_LEN];
fread(name, 1, sizeof(name), f);
arrput(user->following, UsersFind(mg_str(name)));
}
+
+ user->posts = NULL;
for (int i = 0; i < numPosts; i++) {
- char name[NAME_LEN];
- Post post;
- fread(&post.timestamp, sizeof(post.timestamp), 1, f);
- fread(name, 1, sizeof(name), f);
- post.user = UsersFind(mg_str(name));
- fread(post.content, 1, sizeof(post.content), f);
+ Post post = PostNew();
+ PostRead(&post, f);
+ arrput(user->posts, post);
}
- fclose(f);
}
@@ -99,10 +116,6 @@ UsersSetup() { yas = UserNew("yas");
tof = UserNew("tof");
- // UserRead(&pat);
- // UserRead(&yas);
- // UserRead(&tof);
-
arrput(pat.following, &yas);
arrput(yas.following, &pat);
arrput(tof.following, &yas);
@@ -128,7 +141,7 @@ UsersFind(struct mg_str name) { // HTML
void
-http_redirect_home(struct mg_connection * c, struct mg_http_message * hm, User * user) {
+http_redirect(struct mg_connection * c, struct mg_http_message * hm) {
struct mg_str *referer = mg_http_get_header(hm, "Referer");
static char redirectHeaders[128];
@@ -166,16 +179,55 @@ html_user_not_found() return html;
}
-char *
-html_post(Post * post) {
- static char html[2048];
- snprintf(html, 2048,
- "<p>[%s] <a href=\"/user/%s\">%s</a>: %s</p>",
+int
+html_post(Post * post, char * buffer, int bufferLen) {
+ int result = 0;
+ int printed = 0;
+
+ printed = snprintf(buffer, bufferLen,
+ "<div style=\"border: 2px solid black; margin: 2px; padding: 2px;\">[%s] <a href=\"/user/%s\">%s</a>: %s <br />",
ctime(&post->timestamp),
post->user->name,
post->user->name,
post->content);
- return html;
+ buffer += printed; bufferLen -= printed; result += printed;
+
+ if (post->likes > 0) {
+ printed = snprintf(buffer, bufferLen,
+ "Likes: %d<br />", post->likes);
+ buffer += printed; bufferLen -= printed; result += printed;
+ }
+
+ printed = snprintf(buffer, bufferLen,
+ "<form action=\"/api/like/%s/%llu\" method=\"post\">"
+ "<input type=\"submit\" value=\"Like!\">"
+ "</form>",
+ post->user->name,
+ (size_t)post);
+ buffer += printed; bufferLen -= printed; result += printed;
+
+ if (arrlen(post->comments) > 0) {
+ printed = snprintf(buffer, bufferLen,
+ "Comments:<br />");
+ buffer += printed; bufferLen -= printed; result += printed;
+
+ for (int i = 0; i < arrlen(post->comments); i++) {
+ printed = html_post(&post->comments[i], buffer, bufferLen);
+ buffer += printed; bufferLen -= printed; result += printed;
+ }
+ }
+
+ printed = snprintf(buffer, bufferLen,
+ "<form action=\"/api/comment/%s/%llu\" method=\"post\">"
+ "<input type=\"text\" name=\"content\" autofocus>"
+ "<input type=\"submit\" value=\"Comment!\">"
+ "</form>"
+ "</div>",
+ post->user->name,
+ (size_t)post);
+ buffer += printed; bufferLen -= printed; result += printed;
+
+ return result;
}
char *
@@ -205,17 +257,26 @@ html_home(User * user) "<html>"
"<body>"
"<form action=\"/api/post/%s\" method=\"post\">"
- "<input type=\"text\" name=\"content\"><br>"
+ "<input type=\"text\" name=\"content\" autofocus><br>"
"<input type=\"submit\" value=\"Chirp!\">"
"</form>",
user->name);
+ snprintf(html+strlen(html), HTML_LEN-strlen(html),
+ "<form action=\"/api/write/%s\" method=\"post\">"
+ "<input type=\"submit\" value=\"Write!\">"
+ "</form>"
+ "<form action=\"/api/read/%s\" method=\"post\">"
+ "<input type=\"submit\" value=\"Read!\">"
+ "</form>",
+ user->name,
+ user->name);
for (int i = 0; i < arrlen(posts); i++) {
- snprintf(html+strlen(html), HTML_LEN-strlen(html),
- html_post(posts[i]));
+ html_post(posts[i], html+strlen(html), HTML_LEN-strlen(html));
}
snprintf(html+strlen(html), HTML_LEN-strlen(html),
"</body>"
"</html>");
+ arrfree(posts);
return html;
}
@@ -228,13 +289,21 @@ html_user(User * user) "<html>"
"<body>"
"<form action=\"/api/post/%s\" method=\"post\">"
- "<input type=\"text\" name=\"content\"><br>"
+ "<input type=\"text\" name=\"content\" autofocus><br>"
"<input type=\"submit\" value=\"Chirp!\">"
"</form>",
user->name);
+ snprintf(html+strlen(html), HTML_LEN-strlen(html),
+ "<form action=\"/api/write/%s\" method=\"post\">"
+ "<input type=\"submit\" value=\"Write!\">"
+ "</form>"
+ "<form action=\"/api/read/%s\" method=\"post\">"
+ "<input type=\"submit\" value=\"Read!\">"
+ "</form>",
+ user->name,
+ user->name);
for (int i = arrlen(user->posts) - 1; i >= 0; i--) {
- snprintf(html+strlen(html), HTML_LEN-strlen(html),
- html_post(&user->posts[i]));
+ html_post(&user->posts[i], html+strlen(html), HTML_LEN-strlen(html));
}
snprintf(html+strlen(html), HTML_LEN-strlen(html),
"</body>"
@@ -260,23 +329,69 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) // hm->message.len, hm->message.ptr);
- struct mg_str caps[2];
+ // TODO: make sure this diesnt error. shhhhhh!
+ struct mg_str caps[10];
if (mg_match(hm->uri, mg_str("/api/post/*"), caps)) {
User * user = UsersFind(caps[0]);
if (user != NULL) {
Post newPost;
+ newPost.likes = 0;
+ newPost.comments = NULL;
+ newPost.parent = NULL;
newPost.timestamp = time(NULL);
newPost.user = user;
mg_http_get_var(&hm->body, "content", newPost.content, sizeof(newPost.content)-1);
arrput(user->posts, newPost);
-
- // UserWrite(user);
-
- http_redirect_home(c, hm, user);
}
}
+ else if (mg_match(hm->uri, mg_str("/api/comment/*/*"), caps)) {
+ User * user = UsersFind(caps[0]);
+
+ if (user != NULL) {
+ Post * parent = (Post *)atoll(caps[1].ptr);
+ if (parent != NULL) {
+ Post newComment;
+ newComment.likes = 0;
+ newComment.comments = NULL;
+ newComment.parent = parent;
+ newComment.timestamp = time(NULL);
+ newComment.user = user;
+ mg_http_get_var(&hm->body, "content", newComment.content, sizeof(newComment.content)-1);
+ arrput(parent->comments, newComment);
+ }
+ }
+ }
+ else if (mg_match(hm->uri, mg_str("/api/like/*/*"), caps)) {
+ User * user = UsersFind(caps[0]);
+ if (user != NULL) {
+ Post * post = (Post *)atoll(caps[1].ptr);
+ if (post != NULL)
+ post->likes++;
+ }
+ }
+ else if (mg_match(hm->uri, mg_str("/api/write/*"), caps)) {
+ User * user = UsersFind(caps[0]);
+ if (user != NULL) {
+ char filename[128];
+ snprintf(filename, 128, "data/users/%s", user->name);
+ FILE * f = fopen(filename, "w");
+ UserWrite(user, f);
+ fclose(f);
+ }
+ }
+ else if (mg_match(hm->uri, mg_str("/api/read/*"), caps)) {
+ User * user = UsersFind(caps[0]);
+ if (user != NULL) {
+ char filename[128];
+ snprintf(filename, 128, "data/users/%s", user->name);
+ FILE * f = fopen(filename, "r");
+ UserRead(user, f);
+ fclose(f);
+ }
+ }
+ http_redirect(c, hm);
}
// GET
else if (mg_strcmp(hm->method, mg_str("GET")) == 0)
|
