Completely remove csv-db files and continued working on frontend. Created styles base

This commit is contained in:
Dmitriy Shishkov 2020-07-04 22:31:26 +05:00
parent cd874d6e28
commit 55f5ccfdf4
19 changed files with 153 additions and 571 deletions

View File

@ -1,26 +0,0 @@
#ifndef _ARTICLE_H
#define _ARTICLE_H
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "../../include/db_op/db.h"
#ifndef ARTICLE_T_TYPE
#define ARTICLE_T_TYPE
typedef struct {
unsigned int id;
char *header;
char *content;
char *author;
char *topic;
} article_t;
#endif
int expand_line_article(int n, char *buff, entry_s *rec);
char *serialize_article(entry_s *rec);
#endif

View File

@ -1,51 +0,0 @@
#ifndef _DB_H
#define _DB_H
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#ifndef ARTICLE_T_TYPE
#define ARTICLE_T_TYPE
typedef struct {
unsigned int id;
char *header;
char *content;
char *author;
char *topic;
} article_t;
#endif
typedef enum
{
BLOGPOST_T,
ARTICLE_T
} types;
typedef struct
{
types type;
union {
article_t a;
} data;
} entry_s;
#include "./article.h"
#define LINE_SIZE 512
int open_db(char *file_name, types type, FILE **file, char ***head, int *head_length);
int open_table(char *file_name, FILE **file);
int read_head(FILE *file, char ***head);
int get_entry(FILE *file, entry_s *rec, int n, int (*process_line)(int, char *, entry_s *));
int append_table(FILE *file, entry_s *rec, char *(*process_line)(entry_s *));
int remove_entry(FILE *file, int n);
int read_whole_table(FILE *file, entry_s **rec, int (*process_line)(int, char *, entry_s *));
int find_by(FILE *file, entry_s **entries, int (*check_line)(int, char *, entry_s), int (*process_line)(int, char *, entry_s));
#endif

View File

@ -1,8 +0,0 @@
#ifndef _DB_CLI_H
#define _DB_CLI_H
#include "../../include/db_op/db.h"
char *get_all_articles_list();
#endif

View File

@ -25,7 +25,7 @@ int gen_html_article(article_info article, char **out)
process_md(article, &content);
int line_length = snprintf(NULL, 0, template_str, article.title, content) + 1;
int line_length = snprintf(NULL, 0, template_str, article.title, article.title, content) + 1;
*out = malloc(line_length);
if (*out == NULL)
{
@ -33,7 +33,7 @@ int gen_html_article(article_info article, char **out)
return -1;
}
snprintf(*out, line_length, template_str, article.title, content);
snprintf(*out, line_length, template_str, article.title, article.title, content);
free(template_str);

View File

@ -11,20 +11,6 @@ int process_md(article_info article, char **out)
while ((buff = strtok_r(rest, "\n", &rest)) != NULL)
{
if (strcmp(buff, "***") == 0)
{
char *tmp_out = realloc(*out, strlen(*out) + strlen("<hr>\n") + 1);
if (tmp_out == NULL)
{
perror("Couldn't allocate memory for new element");
continue;
}
*out = tmp_out;
strcat(*out, "<hr>\n");
continue;
}
if ((buff[0] == '*' && buff[1] == ' ') || (buff[0] == '-' && buff[1] == ' ') || (buff[0] == '+' && buff[1] == ' '))
{
char *begining = "";
@ -52,7 +38,7 @@ int process_md(article_info article, char **out)
free(append);
continue;
}
if (is_in_list)
{
char *tmp_out = realloc(*out, strlen(*out) + strlen("</ul>\n") + 1);
@ -66,6 +52,19 @@ int process_md(article_info article, char **out)
is_in_list = 0;
}
if (strcmp(buff, "***") == 0)
{
char *tmp_out = realloc(*out, strlen(*out) + strlen("<hr>\n") + 1);
if (tmp_out == NULL)
{
perror("Couldn't allocate memory for new element");
continue;
}
*out = tmp_out;
strcat(*out, "<hr>\n");
continue;
}
if (buff[0] == '#')
{
int n = 1;
@ -147,7 +146,7 @@ int process_md(article_info article, char **out)
memcpy(internal, buff + i + n, j);
internal[j] = '\0';
size_t append_line_length = snprintf(NULL, 0, "<%s>%s</%s> ", tag, internal, tag) + 1;
size_t append_line_length = snprintf(NULL, 0, "<%s>%s</%s>", tag, internal, tag) + 1;
char *append = malloc(append_line_length);
char *tmp_out = realloc(*out, strlen(*out) + append_line_length);
if (append == NULL || tmp_out == NULL)
@ -157,10 +156,10 @@ int process_md(article_info article, char **out)
}
*out = tmp_out;
snprintf(append, append_line_length, "<%s>%s</%s> ", tag, internal, tag);
snprintf(append, append_line_length, "<%s>%s</%s>", tag, internal, tag);
strcat(*out, append);
i += n * 2 + j;
i += n * 2 + j - 1;
free(append);
free(internal);
@ -189,7 +188,7 @@ int process_md(article_info article, char **out)
memcpy(src, buff + i + 2 + n + 2, k);
src[k] = '\0';
size_t append_line_length = snprintf(NULL, 0, "<img src=\"%s\" alt=\"%s\"> ", src, internal_text) + 1;
size_t append_line_length = snprintf(NULL, 0, "<a href=\"%s\"><img src=\"%s\" alt=\"%s\"></a>", src, src, internal_text) + 1;
char *append = malloc(append_line_length);
char *tmp_out = realloc(*out, strlen(*out) + append_line_length);
if (append == NULL || tmp_out == NULL)
@ -199,10 +198,10 @@ int process_md(article_info article, char **out)
}
*out = tmp_out;
snprintf(append, append_line_length, "<img src=\"%s\" alt=\"%s\"> ", src, internal_text);
snprintf(append, append_line_length, "<a href=\"%s\"><img src=\"%s\" alt=\"%s\"></a>", src, src, internal_text);
strcat(*out, append);
i += 2 + n + 2 + k + 1;
i += 2 + n + 2 + k;
free(append);
free(src);
@ -232,7 +231,7 @@ int process_md(article_info article, char **out)
memcpy(href, buff + i + 1 + n + 2, k);
href[k] = '\0';
size_t append_line_length = snprintf(NULL, 0, "<a href=\"%s\">%s</a> ", href, internal_text) + 1;
size_t append_line_length = snprintf(NULL, 0, "<a href=\"%s\">%s</a>", href, internal_text) + 1;
char *append = malloc(append_line_length);
char *tmp_out = realloc(*out, strlen(*out) + append_line_length);
if (append == NULL || tmp_out == NULL)
@ -242,10 +241,10 @@ int process_md(article_info article, char **out)
}
*out = tmp_out;
snprintf(append, append_line_length, "<a href=\"%s\">%s</a> ", href, internal_text);
snprintf(append, append_line_length, "<a href=\"%s\">%s</a>", href, internal_text);
strcat(*out, append);
i += 1 + n + 2 + k + 1;
i += 1 + n + 2 + k;
free(append);
free(href);

View File

@ -1,49 +0,0 @@
#include "../../include/db_op/db.h"
int expand_line_article(int n, char *buff, entry_s *rec)
{
#define entry rec->data.a
entry.id = n;
char *tmp = strtok(buff, ";");
if (tmp == NULL)
return -1;
entry.header = malloc(strlen(tmp) + 1);
entry.header = tmp;
tmp = strtok(NULL, ";");
if (tmp == NULL)
return -2;
entry.content = malloc(strlen(tmp) + 1);
entry.content = tmp;
tmp = strtok(NULL, ";");
if (tmp == NULL)
return -3;
entry.author = malloc(strlen(tmp) + 1);
entry.author = tmp;
tmp = strtok(NULL, "\n");
if (tmp == NULL)
return -4;
entry.topic = malloc(strlen(tmp) + 1);
entry.topic = tmp;
return 0;
}
char *serialize_article(entry_s *rec)
{
int line_length = snprintf(NULL, 0, "%s;%s;%s;%s\n", entry.header, entry.content, entry.author, entry.topic) + 1;
char *line = malloc(line_length);
if (line == NULL)
return "";
snprintf(line, line_length, "%s;%s;%s;%s\n", entry.header, entry.content, entry.author, entry.topic);
return line;
}

View File

@ -1,282 +0,0 @@
#include "../../include/db_op/db.h"
#include "../../include/utils_op/utils.h"
#include "../../include/utils_op/arr.h"
/**
* @brief Opens a table of specified type. If no such table, creates one and returns 1
*
* @param file_name
* @param type
* @param file
* @param head
* @param head_length
* @return int
*/
int open_db(char *file_name, types type, FILE **file, char ***head, int *head_length)
{
char *type_string;
switch (type)
{
case BLOGPOST_T:
type_string = "blogpost";
break;
case ARTICLE_T:
type_string = "article";
break;
default:
err_msg("This type is not supported");
return -1;
}
FILE *root_file;
if ((root_file = fopen(file_name, "a+")) == NULL)
{
err_msg("can't open database file");
return -1;
}
char *buff = NULL;
size_t size = LINE_SIZE;
while (getline(&buff, &size, root_file) >= 0)
if (strcmp(type_string, strtok(buff, " ")) == 0)
{
int ret = open_table(strtok(NULL, "\n"), file);
*head_length = read_head(*file, head);
fclose(root_file);
return ret;
}
free(buff);
struct stat st = {0};
if (stat("./db", &st) == -1)
mkdir("./db", 0700);
int table_file_name_size = snprintf(NULL, 0, "./db/%s.csv", type_string) + 1;
char *table_file_name = malloc(table_file_name_size);
snprintf(table_file_name, table_file_name_size, "./db/%s.csv", type_string);
fseek(root_file, 0, SEEK_SET);
fprintf(root_file, "%s %s\n", type_string, table_file_name);
fclose(root_file);
int ret = open_table(table_file_name, file);
free(table_file_name);
return 1;
}
/**
* @brief Open table file
*
* @param file_name
* @param file
* @return int -1 if couldn't open file
*/
int open_table(char *file_name, FILE **file)
{
if ((*file = fopen(file_name, "a+")) == NULL)
{
err_msg("can't open table file");
return -1;
}
return 0;
}
/**
* @brief Read table head
*
* @param file
* @param head
* @return int
*/
int read_head(FILE *file, char ***head)
{
fseek(file, 0, SEEK_SET);
int length = 0;
*head = malloc(length * sizeof(char *));
char buff[LINE_SIZE];
fscanf(file, "%[^\n]", buff);
char *tok;
int i = 0;
for (tok = strtok(buff, ";"); tok && *tok; tok = strtok(NULL, ";"))
insert_to_arr(head, length++, tok);
return length;
}
/**
* @brief Get the entry on line n
*
* @param file
* @param rec
* @param n
* @param process_line
* @return int
*/
int get_entry(FILE *file, entry_s *rec, int n, int (*process_line)(int, char *, entry_s *))
{
char *buff = NULL;
int i = 0;
size_t size = LINE_SIZE;
fseek(file, 0, SEEK_SET);
while (getline(&buff, &size, file) >= 0)
{
if (i == n)
{
int res = (*process_line)(n, buff, rec);
return res;
}
else
i++;
}
free(buff);
return -1;
}
/**
* @brief Insert entry to the end of table
*
* @param file
* @param rec
* @param process_line
* @return int
*/
int append_table(FILE *file, entry_s *rec, char *(*process_line)(entry_s *))
{
fseek(file, 0, SEEK_END);
char *buff = (*process_line)(rec);
if (fprintf(file, "%s", buff) < 0)
return -1;
free(buff);
return 0;
}
/**
* @brief Remove entry located at line n
*
* @param file
* @param n
* @return int
*/
int remove_entry(FILE *file, int n)
{
if (n == 0)
{
err_msg("you shouldn't remove table head. Aborting");
return -1;
}
int tmp_file_name_length = snprintf(NULL, 0, "./db/tmp%d.csv", n) + 1;
char *tmp_file_name = malloc(tmp_file_name_length);
snprintf(tmp_file_name, tmp_file_name_length, "./db/tmp%d.csv", n);
FILE *tmp_file = fopen(tmp_file_name, "w");
char *buff = NULL;
size_t size = LINE_SIZE;
int i = 0;
fseek(file, 0, SEEK_SET);
while (getline(&buff, &size, file) >= 0)
{
if (i != n)
fprintf(tmp_file, "%s", buff);
i++;
}
fclose(tmp_file);
free(buff);
int fd = fileno(file);
char file_path[1024];
int path_length = snprintf(NULL, 0, "/proc/self/fd/%d", fd) + 1;
char *path = malloc(path_length);
snprintf(path, path_length, "/proc/self/fd/%d", fd);
memset(file_path, 0, sizeof(file_path));
ssize_t l = readlink(path, file_path, sizeof(file_path) - 1);
free(path);
if (l < 0)
{
err_msg("couldn't get table path");
return -1;
}
file_path[l] = '\0';
if (remove(file_path) != 0)
{
err_msg("couldn't remove original file");
return -1;
}
if (rename(tmp_file_name, file_path) != 0)
{
err_msg("couldn't rename tmp file");
return -1;
}
free(tmp_file_name);
return i;
}
int read_whole_table(FILE *file, entry_s **entries, int (*process_line)(int ,char *, entry_s *))
{
char *buff;
int i = 0;
size_t size = LINE_SIZE;
fseek(file, 0, SEEK_SET);
printf("Begining line-by-line reading\n");
while (getline(&buff, &size, file) >= 0)
{
if (i == 0)
{
i++;
continue;
}
printf("Read line [%d]: %s\n", i, buff);
int res = (*process_line)(i, buff, &((*entries)[i]));
if (res < 0)
return res;
i++;
printf("---%lu---\n", sizeof(entry_s));
*entries = (entry_s *)realloc(*entries, sizeof(entry_s) * i);
}
if (i == 1)
return -1;
free(buff);
return ++i;
}

View File

@ -1,103 +0,0 @@
#include "../../include/db_op/db_cli.h"
#include "../../include/utils_op/arr.h"
char *get_all_articles_list()
{
FILE *db_file;
char **db_head;
int length = -1;
int ret = open_db("root.db", ARTICLE_T, &db_file, &db_head, &length);
if (ret == 1)
{
perror("No such database\n");
}
entry_s *articles_table = (entry_s *)malloc(sizeof(entry_s));
if (articles_table == NULL)
return "";
size_t entries_amount = read_whole_table(db_file, &articles_table, expand_line_article);
printf("\nStarting processing table\n");
size_t topics_amount = 0;
char **articles_by_topics_lists = malloc(topics_amount * sizeof(char *));
char **topics_list = malloc(topics_amount * sizeof(char));
if (articles_by_topics_lists == NULL || topics_list == NULL)
return "";
printf("Initialized lists arrays\n");
size_t topics_list_size = 1;
for (int i = 0; i < entries_amount; i++)
{
printf("Processing entry [%d]\n", i);
article_t rec = articles_table[i].data.a;
int pos = check_if_contains(topics_list, topics_amount, rec.topic);
if (pos == 0)
{
topics_amount++;
char **tmp_topics_list = realloc(topics_list, topics_list_size + strlen(rec.topic));
if (tmp_topics_list == NULL)
continue;
else
topics_list = tmp_topics_list;
topics_list_size += strlen(rec.topic);
pos = topics_amount - 1;
topics_list[pos] = rec.topic;
char **tmp_articles_by_topics_lists = realloc(articles_by_topics_lists, topics_amount * sizeof(char *));
if (tmp_articles_by_topics_lists == NULL)
continue;
else
articles_by_topics_lists = tmp_articles_by_topics_lists;
}
int line_length = snprintf(NULL, 0, "<li>%s</li>\n", rec.header) + 1;
char *tmp_line = malloc(line_length);
if (tmp_line == NULL)
return "";
snprintf(tmp_line, line_length, "<li>%s</li>\n", rec.header);
char *tmp_articles_by_topics_lists_line = realloc(articles_by_topics_lists[pos], strlen(articles_by_topics_lists[pos]) + line_length + 1);
if (tmp_articles_by_topics_lists_line == NULL)
continue;
else
articles_by_topics_lists[pos] = tmp_articles_by_topics_lists_line;
strncat(articles_by_topics_lists[pos], tmp_line, line_length);
}
char *articles_table_list_str = malloc(topics_amount * strlen("<h1></h1>\n<ul></ul>\n"));
if (articles_table_list_str == NULL)
return "";
for (int i = 0; i < topics_amount; i++)
{
int add_len = snprintf(NULL, 0, "<h1>%s</h1>\n<ul>%s</ul>\n", topics_list[i], articles_by_topics_lists[i]);
char *tmp_line = malloc(add_len);
if (tmp_line == NULL)
continue;
snprintf(tmp_line, add_len, "<h1>%s</h1>\n<ul>%s</ul>\n", topics_list[i], articles_by_topics_lists[i]);
char *tmp_articles_table_list_str = realloc(articles_table_list_str, strlen(articles_table_list_str) + add_len + 1);
if (tmp_articles_table_list_str == NULL)
continue;
else
articles_table_list_str = tmp_articles_table_list_str;
strcat(articles_table_list_str, tmp_line);
}
return articles_table_list_str;
}

View File

@ -211,8 +211,9 @@ void handle_get_request(int fd, char *request)
char *id_str = (char *)malloc(strlen(path) - strlen("/article/") + 1);
memmove(id_str, path + strlen("/article/"), strlen(path) - strlen("/article/") + 1);
int id = strtol(id_str, NULL, 10);
if (id < 0)
char *remaining;
int id = strtol(id_str, &remaining, 10);
if (id < 0 || strcmp(id_str, remaining) == 0)
{
res_404(fd, path);
return;

View File

@ -6,7 +6,7 @@
</head>
<body>
<h1>Not Found</h1>
<h1>404 Not Found</h1>
<p>The requested URL: <a href="%s">%s</a> was not found on this server.</p>
<p>Return <a href="/">home</a></p>
</body>

View File

@ -4,16 +4,19 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
<title>About</title>
<link rel="stylesheet" href="../style.css">
<link rel="stylesheet" href="/style.css">
</head>
<body>
<header>
<a href="/" id="logo"><img src="./logo.png" alt="logo" /></a>
<a href="/" id="logo"><img src="/logo.png" alt="logo" /></a>
<a id="modern" href="/modern"
title="If you have modern browser, you can visit more fancy version of my site">Modernize</a>
</header>
<p>Me</p>
<img src="/about/me.jpg" alt="the pig" style="max-height: 200px;" />
<h1>About me</h1>
</body>
</html>

View File

@ -0,0 +1,15 @@
# My first article on this site
This is my own site written in pure C with templates in html and some css styles. All articles are stored in markdown format and are processed by server to convert them to html and send to client. Links list on the homepage is also generated dynamically to show all the articles, currntly avaliable on disk.
![Data flow](https://c.imge.to/2020/07/03/P5RIaj.png)
*Data flow*
As for all the pages of this site are pure html, it can be read from really old computers or text-based browsers. Server Side Rendered (SSR) webpages are also good for search engines.
Anyway, I just like such oldschool sites with minimal styles but still featuring pretty enougth design.
As for me, I'm *Shishkov Dmitriy*. High school student from Russia. I started doing programming about two years ago. As most self-taught coders I began with basic HTML. Then I switched to PHP-based templating programm generator DevelStudio. Some time later I started learning JS, React, NodeJS and similar web technologies. So I studied full-stack web.
But I wanted to try more low-level programming. In school I studied C++, but my friend recommended to start with C to better understand memory-management.
So, since then I'm studying C programming, working on some projects. Some of them avaliable on my [Github](https://github.com/Dm1tr1y147).

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -4,16 +4,20 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
<title>%s</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="/style.css">
</head>
<body>
<header>
<a href="/" id="logo"><img src="/logo.png" alt="logo" /></a>
<a id="modern" href="/modern"
title="If you have modern browser, you can visit more fancy version of my site">Modernize</a>
</header>
<main>
<h1 id="header">%s</h1>
%s
</main>
</body>

View File

@ -0,0 +1 @@
1593768639 First article

View File

@ -1,15 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
<title>Gallery</title>
<link rel="stylesheet" href="../style.css">
<link rel="stylesheet" href="/style.css">
</head>
<body>
<header>
<a href="/" id="logo"><img src="./logo.png" alt="logo" /></a>
<a id="modern" href="/modern"
title="If you have modern browser, you can visit more fancy version of my site">Modernize</a>
</header>
%s
<h1>Work in porgress</h1>
</body>
</html>

View File

@ -4,6 +4,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
<title>Test</title>
<link rel="stylesheet" href="style.css">
@ -12,6 +13,8 @@
<body>
<header>
<a href="/" id="logo"><img src="/logo.png" alt="logo" /></a>
<a id="modern" href="/modern"
title="If you have modern browser, you can visit more fancy version of my site">Modernize</a>
</header>
<main>
<h1>Home</h1>
@ -24,6 +27,29 @@
<h1>Articles</h1>
%s
</main>
<style>
main h1 {
margin: 20px 0;
}
main ul {
padding-left: 0;
}
main li {
list-style-type: none;
}
main li,
main li a {
font-size: initial;
line-height: initial;
}
li:hover a {
text-decoration: none;
}
</style>
</body>
</html>

View File

@ -2,8 +2,7 @@
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "alte_haas_grotesk_bold", "Helvetica Neue", Helvetica, Arial;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
::selection {
@ -11,8 +10,8 @@
color: #ffffff;
}
html {
min-height: 100vh;
html, body {
height: 100%;
}
body {
@ -21,28 +20,74 @@ body {
padding: 45px;
}
a {
font-family: monospace;
color: #000000;
}
header {
height: 65px;
margin-bottom: 20px;
margin-bottom: 30px;
}
header img {
height: 100%;
}
main h1 {
margin: 20px 0;
}
main li {
list-style-type: none;
}
li a {
header #modern {
line-height: 65px;
text-align: center;
vertical-align: top;
margin-left: 30px;
font-size: 18px;
color: #000000;
font-family: monospace;
}
li:hover a {
header #modern:hover
{
text-decoration: none;
}
main {
max-width: 800px;
}
main>* {
margin-bottom: 30px;
}
main img {
max-width: 100%;
}
main>ul {
padding-left: 30px;
}
main p, main blockquote, main li {
font-size: 20px;
line-height: 30px;
}
main a:hover {
text-decoration: none;
}
main blockquote {
margin-left: 20px;
padding-left: 10px;
border-left: #000000 solid 5px;
}
main>#header {
font-size: 45px;
}
@media (max-width: 800px) {
body {
padding: 30px;
}
header #modern {
margin-left: 25px;
}
}