Backend: Sanitarized json parser (quotes, \n, \r...) Added a get_post route. Frontend: Basic article management.
This commit is contained in:
parent
36af469f8f
commit
42c487006c
9 changed files with 89 additions and 12 deletions
|
@ -22,6 +22,8 @@ public:
|
||||||
private:
|
private:
|
||||||
Data _dataBuffer;
|
Data _dataBuffer;
|
||||||
Json _buffer;
|
Json _buffer;
|
||||||
|
|
||||||
|
void sanitarize(std::string& str);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
16
backend/include/utility.hpp
Normal file
16
backend/include/utility.hpp
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef _HEADER_ETHERYOBLOG_UTILITY
|
||||||
|
#define _HEADER_ETHERYOBLOG_UTILITY
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
inline void str_replace(std::string& str, const std::string& from, const std::string& to) {
|
||||||
|
if(from.empty())
|
||||||
|
return;
|
||||||
|
size_t start_pos = 0;
|
||||||
|
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
|
||||||
|
str.replace(start_pos, from.length(), to);
|
||||||
|
start_pos += to.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //_HEADER_ETHERYOBLOG_UTILITY
|
|
@ -1,4 +1,7 @@
|
||||||
#include "json.hpp"
|
#include "json.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
using namespace Etheryo;
|
using namespace Etheryo;
|
||||||
|
|
||||||
|
@ -34,12 +37,13 @@ std::string JsonHandler::to_str()
|
||||||
std::string str = "[";
|
std::string str = "[";
|
||||||
size_t map_size(0), map_index(0), vec_index(0);
|
size_t map_size(0), map_index(0), vec_index(0);
|
||||||
|
|
||||||
for (const auto& map_data : _buffer) {
|
for (auto& map_data : _buffer) {
|
||||||
vec_index++;
|
vec_index++;
|
||||||
str.push_back('{');
|
str.push_back('{');
|
||||||
map_size = map_data.size();
|
map_size = map_data.size();
|
||||||
for (auto it = map_data.begin(); it != map_data.end(); it++) {
|
for (auto it = map_data.begin(); it != map_data.end(); it++) {
|
||||||
map_index++;
|
map_index++;
|
||||||
|
sanitarize(it->second);
|
||||||
str += ("\"" + it->first + "\": \"" + it->second + (map_index >= map_size ? "\"" : "\","));
|
str += ("\"" + it->first + "\": \"" + it->second + (map_index >= map_size ? "\"" : "\","));
|
||||||
}
|
}
|
||||||
map_index = 0;
|
map_index = 0;
|
||||||
|
@ -49,4 +53,11 @@ std::string JsonHandler::to_str()
|
||||||
}
|
}
|
||||||
str.push_back(']');
|
str.push_back(']');
|
||||||
return str;
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsonHandler::sanitarize(std::string& str)
|
||||||
|
{
|
||||||
|
str_replace(str, "\"", "\\\"");
|
||||||
|
str_replace(str, "\r", "\\r");
|
||||||
|
str_replace(str, "\n", "\\n");
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
#include "crow.h"
|
#include "crow.h"
|
||||||
#include <pqxx/pqxx>
|
#include <pqxx/pqxx>
|
||||||
|
|
||||||
|
#include "crow/app.h"
|
||||||
#include "crow/http_response.h"
|
#include "crow/http_response.h"
|
||||||
#include "dotenv.hpp"
|
#include "dotenv.hpp"
|
||||||
#include "json.hpp"
|
#include "json.hpp"
|
||||||
|
@ -10,16 +11,19 @@
|
||||||
pqxx::connection* globalConnection(nullptr);
|
pqxx::connection* globalConnection(nullptr);
|
||||||
crow::response test(void);
|
crow::response test(void);
|
||||||
crow::response getSimplePosts(int limit);
|
crow::response getSimplePosts(int limit);
|
||||||
|
crow::response getPost(std::string slug);
|
||||||
|
|
||||||
// Json Handler with a precise data type
|
// Json Handler with a precise data type
|
||||||
Etheryo::JsonHandler category;
|
Etheryo::JsonHandler category;
|
||||||
Etheryo::JsonHandler post_info;
|
Etheryo::JsonHandler post_info;
|
||||||
|
Etheryo::JsonHandler post;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// Init Json Objects
|
// Init Json Objects
|
||||||
category.add({ "id", "slug", "icon", "type_icon" });
|
category.add({ "id", "slug", "icon", "type_icon" });
|
||||||
post_info.add({"slug","author","title", "date", "picture"});
|
post_info.add({"slug","author","title", "date", "picture"});
|
||||||
|
post.add({"name","title","date","picture","body","views","likes","dislikes"});
|
||||||
|
|
||||||
// Init Postgresql + DotEnv
|
// Init Postgresql + DotEnv
|
||||||
Etheryo::DotEnv dotenvParser;
|
Etheryo::DotEnv dotenvParser;
|
||||||
|
@ -31,7 +35,7 @@ int main()
|
||||||
crow::SimpleApp app;
|
crow::SimpleApp app;
|
||||||
CROW_ROUTE(app, "/")(test);
|
CROW_ROUTE(app, "/")(test);
|
||||||
CROW_ROUTE(app, "/get_simple_posts/<int>")(getSimplePosts);
|
CROW_ROUTE(app, "/get_simple_posts/<int>")(getSimplePosts);
|
||||||
|
CROW_ROUTE(app, "/get_post/<string>")(getPost);
|
||||||
app.port(8000).multithreaded().run();
|
app.port(8000).multithreaded().run();
|
||||||
globalConnection->close();
|
globalConnection->close();
|
||||||
}
|
}
|
||||||
|
@ -72,4 +76,28 @@ crow::response getSimplePosts(int limit)
|
||||||
response.add_header("Access-Control-Allow-Origin", "*");
|
response.add_header("Access-Control-Allow-Origin", "*");
|
||||||
response.add_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
|
response.add_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
|
||||||
return response;
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
crow::response getPost(std::string slug)
|
||||||
|
{
|
||||||
|
post.clear();
|
||||||
|
pqxx::work worker { *globalConnection };
|
||||||
|
auto result = worker.query<int, std::string, std::string, std::string, std::string, std::string, int, int, int>
|
||||||
|
("select p.author_id, a.name, p.title, p.date, p.picture, p.body, p.views, p.likes, p.dislikes from post p join authors a on p.author_id = a.id where p.slug = '"+slug+"';");
|
||||||
|
for(auto [author_id, name, title, date, picture, body, views, likes, dislikes] : result)
|
||||||
|
{
|
||||||
|
post["name"] = name; //"title","date","picture","body","views","likes","dislikes"
|
||||||
|
post["title"] = title;
|
||||||
|
post["date"] = date;
|
||||||
|
post["picture"] = picture;
|
||||||
|
post["body"] = body;
|
||||||
|
post["views"] = std::to_string(views);
|
||||||
|
post["likes"] = std::to_string(likes);
|
||||||
|
post["dislikes"] = std::to_string(dislikes);
|
||||||
|
post.push();
|
||||||
|
}
|
||||||
|
auto response = crow::response { "application/json", post.to_str() };
|
||||||
|
response.add_header("Access-Control-Allow-Origin", "*");
|
||||||
|
response.add_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
|
||||||
|
return response;
|
||||||
}
|
}
|
|
@ -26,13 +26,13 @@
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
redirectTo(`/article/${mainpost.slug}`);
|
redirectTo(`/articles/${mainpost.slug}`);
|
||||||
}}
|
}}
|
||||||
on:keydown={(event) => handleKeyDown(event, `/article/${mainpost.slug}`)}
|
on:keydown={(event) => handleKeyDown(event, `/articles/${mainpost.slug}`)}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<h2>{mainpost.title}</h2>
|
<h2>{mainpost.title}</h2>
|
||||||
<div class="center flex justify-center h-60">
|
<div class="center flex justify-center h-70 margin-bottom ">
|
||||||
<img class="carousel-picture" alt="mainpicture" src={mainpost.picture} />
|
<img class="carousel-picture" alt="mainpicture" src={mainpost.picture} />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex align-center margin-horizontal-05">
|
<div class="flex align-center margin-horizontal-05">
|
||||||
|
@ -54,9 +54,9 @@
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
redirectTo(`/article/${p.slug}`);
|
redirectTo(`/articles/${p.slug}`);
|
||||||
}}
|
}}
|
||||||
on:keydown={(event) => handleKeyDown(event, `/article/${p.slug}`)}
|
on:keydown={(event) => handleKeyDown(event, `/articles/${p.slug}`)}
|
||||||
>
|
>
|
||||||
<img class="carousel-picture" alt="mainpicture" src={p.picture} />
|
<img class="carousel-picture" alt="mainpicture" src={p.picture} />
|
||||||
<div class="flex-col align justify-center">
|
<div class="flex-col align justify-center">
|
||||||
|
|
|
@ -59,7 +59,7 @@ h1 {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.h-60 {
|
.h-70 {
|
||||||
height: 60%;
|
height: 60%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +84,10 @@ h1 {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.margin-bottom {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.margin-horizontal-05 {
|
.margin-horizontal-05 {
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
width: 90%;
|
width: 90%;
|
||||||
height: auto;
|
height: auto;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel-v-minpost-container {
|
.carousel-v-minpost-container {
|
||||||
|
@ -71,11 +70,12 @@
|
||||||
transition: all .1s ease 0s;
|
transition: all .1s ease 0s;
|
||||||
margin-right: 1rem;
|
margin-right: 1rem;
|
||||||
margin-left: 1rem;
|
margin-left: 1rem;
|
||||||
|
background-color: var(--color-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel-v-minpost img {
|
.carousel-v-minpost img {
|
||||||
min-width: 50%;
|
min-width: 40%;
|
||||||
max-width: 50%;
|
max-width: 40%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -88,5 +88,6 @@
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
-webkit-line-clamp: 1;
|
-webkit-line-clamp: 2;
|
||||||
|
font-size: 1.4rem;
|
||||||
}
|
}
|
10
frontend/src/routes/articles/[slug]/+page.server.js
Normal file
10
frontend/src/routes/articles/[slug]/+page.server.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { error } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
export function load({ params }) {
|
||||||
|
const slug = params.slug;
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: 0,
|
||||||
|
slug: slug
|
||||||
|
};
|
||||||
|
}
|
5
frontend/src/routes/articles/[slug]/+page.svelte
Normal file
5
frontend/src/routes/articles/[slug]/+page.svelte
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<script>
|
||||||
|
export let data;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p>{data.slug}</p>
|
Loading…
Add table
Reference in a new issue