From: Patrick Date: Mon, 28 Aug 2023 01:40:51 +0000 (+0200) Subject: likes, comments, write, read X-Git-Url: https://gitweb.ps.run/chirp/commitdiff_plain/e8417ccf8f4a902e362f7e76af318849d2695d18?ds=sidebyside likes, comments, write, read --- diff --git a/src/main.c b/src/main.c index dff0d17..4c994d9 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,4 @@ +#include #include #define STB_DS_IMPLEMENTATION #include @@ -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, - "

[%s] %s: %s

", +int +html_post(Post * post, char * buffer, int bufferLen) { + int result = 0; + int printed = 0; + + printed = snprintf(buffer, bufferLen, + "
[%s] %s: %s
", 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
", post->likes); + buffer += printed; bufferLen -= printed; result += printed; + } + + printed = snprintf(buffer, bufferLen, + "
" + "" + "
", + post->user->name, + (size_t)post); + buffer += printed; bufferLen -= printed; result += printed; + + if (arrlen(post->comments) > 0) { + printed = snprintf(buffer, bufferLen, + "Comments:
"); + 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, + "
" + "" + "" + "
" + "
", + post->user->name, + (size_t)post); + buffer += printed; bufferLen -= printed; result += printed; + + return result; } char * @@ -205,17 +257,26 @@ html_home(User * user) "" "" "
" - "
" + "
" "" "
", user->name); + snprintf(html+strlen(html), HTML_LEN-strlen(html), + "
" + "" + "
" + "
" + "" + "
", + 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), "" ""); + arrfree(posts); return html; } @@ -228,13 +289,21 @@ html_user(User * user) "" "" "
" - "
" + "
" "" "
", user->name); + snprintf(html+strlen(html), HTML_LEN-strlen(html), + "
" + "" + "
" + "
" + "" + "
", + 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), "" @@ -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)