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:
|
||||
Data _dataBuffer;
|
||||
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 "utility.hpp"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
using namespace Etheryo;
|
||||
|
||||
|
@ -34,12 +37,13 @@ std::string JsonHandler::to_str()
|
|||
std::string str = "[";
|
||||
size_t map_size(0), map_index(0), vec_index(0);
|
||||
|
||||
for (const auto& map_data : _buffer) {
|
||||
for (auto& map_data : _buffer) {
|
||||
vec_index++;
|
||||
str.push_back('{');
|
||||
map_size = map_data.size();
|
||||
for (auto it = map_data.begin(); it != map_data.end(); it++) {
|
||||
map_index++;
|
||||
sanitarize(it->second);
|
||||
str += ("\"" + it->first + "\": \"" + it->second + (map_index >= map_size ? "\"" : "\","));
|
||||
}
|
||||
map_index = 0;
|
||||
|
@ -49,4 +53,11 @@ std::string JsonHandler::to_str()
|
|||
}
|
||||
str.push_back(']');
|
||||
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 <pqxx/pqxx>
|
||||
|
||||
#include "crow/app.h"
|
||||
#include "crow/http_response.h"
|
||||
#include "dotenv.hpp"
|
||||
#include "json.hpp"
|
||||
|
@ -10,16 +11,19 @@
|
|||
pqxx::connection* globalConnection(nullptr);
|
||||
crow::response test(void);
|
||||
crow::response getSimplePosts(int limit);
|
||||
crow::response getPost(std::string slug);
|
||||
|
||||
// Json Handler with a precise data type
|
||||
Etheryo::JsonHandler category;
|
||||
Etheryo::JsonHandler post_info;
|
||||
Etheryo::JsonHandler post;
|
||||
|
||||
int main()
|
||||
{
|
||||
// Init Json Objects
|
||||
category.add({ "id", "slug", "icon", "type_icon" });
|
||||
post_info.add({"slug","author","title", "date", "picture"});
|
||||
post.add({"name","title","date","picture","body","views","likes","dislikes"});
|
||||
|
||||
// Init Postgresql + DotEnv
|
||||
Etheryo::DotEnv dotenvParser;
|
||||
|
@ -31,7 +35,7 @@ int main()
|
|||
crow::SimpleApp app;
|
||||
CROW_ROUTE(app, "/")(test);
|
||||
CROW_ROUTE(app, "/get_simple_posts/<int>")(getSimplePosts);
|
||||
|
||||
CROW_ROUTE(app, "/get_post/<string>")(getPost);
|
||||
app.port(8000).multithreaded().run();
|
||||
globalConnection->close();
|
||||
}
|
||||
|
@ -72,4 +76,28 @@ crow::response getSimplePosts(int limit)
|
|||
response.add_header("Access-Control-Allow-Origin", "*");
|
||||
response.add_header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
|
||||
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"
|
||||
tabindex="0"
|
||||
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>
|
||||
<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} />
|
||||
</div>
|
||||
<div class="flex align-center margin-horizontal-05">
|
||||
|
@ -54,9 +54,9 @@
|
|||
role="button"
|
||||
tabindex="0"
|
||||
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} />
|
||||
<div class="flex-col align justify-center">
|
||||
|
|
|
@ -59,7 +59,7 @@ h1 {
|
|||
height: 100%;
|
||||
}
|
||||
|
||||
.h-60 {
|
||||
.h-70 {
|
||||
height: 60%;
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,10 @@ h1 {
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
.margin-bottom {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.margin-horizontal-05 {
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
width: 90%;
|
||||
height: auto;
|
||||
object-fit: cover;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.carousel-v-minpost-container {
|
||||
|
@ -71,11 +70,12 @@
|
|||
transition: all .1s ease 0s;
|
||||
margin-right: 1rem;
|
||||
margin-left: 1rem;
|
||||
background-color: var(--color-background);
|
||||
}
|
||||
|
||||
.carousel-v-minpost img {
|
||||
min-width: 50%;
|
||||
max-width: 50%;
|
||||
min-width: 40%;
|
||||
max-width: 40%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
margin: 0;
|
||||
|
@ -88,5 +88,6 @@
|
|||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-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