Update 2024 #1
12 changed files with 164 additions and 235 deletions
20
README.md
20
README.md
|
@ -29,18 +29,18 @@ All configuration options are defined in .env which should be placed in the path
|
|||
|
||||
`.env`
|
||||
```
|
||||
USERNAME=yourusername
|
||||
EMAIL=me@mydomain.tld # optional
|
||||
BIND_PORT=8000 # optional
|
||||
SUBMIT_TOKEN=Submit!123 # required, token needed for submitting
|
||||
GITHUB_ACCOUNT=yourusername # optional
|
||||
TWITTER_ACCOUNT=yourusername # optional
|
||||
MASTODON_ACCOUNT=yourusername@mastodon.social # optional
|
||||
REDDIT_ACCOUNT=yourusername # optional
|
||||
DISCORD_ACCOUNT=yourusername # optional
|
||||
CL_USERNAME=yourusername
|
||||
CL_EMAIL=me@mydomain.tld # optional
|
||||
CL_BIND_PORT=8000 # optional
|
||||
CL_SUBMIT_TOKEN=Submit!123 # required, token needed for submitting
|
||||
CL_GITHUB_ACCOUNT=yourusername # optional
|
||||
CL_TWITTER_ACCOUNT=yourusername # optional
|
||||
CL_MASTODON_ACCOUNT=yourusername@mastodon.social # optional
|
||||
CL_REDDIT_ACCOUNT=yourusername # optional
|
||||
CL_DISCORD_ACCOUNT=yourusername # optional
|
||||
|
||||
# only needed when not using a docker container
|
||||
ROOT_PATH=/path/to/template/directory/and/sqliteDB
|
||||
CL_ROOT_PATH=/path/to/template/directory/and/sqliteDB
|
||||
```
|
||||
|
||||
## Routes
|
||||
|
|
|
@ -10,13 +10,18 @@ html {
|
|||
padding-left: 20%;
|
||||
}
|
||||
|
||||
img {
|
||||
.social-icon {
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
}
|
||||
|
||||
.post-img {
|
||||
width: 50%;
|
||||
padding: 20px 0px 20px 0px;
|
||||
}
|
||||
|
||||
article {
|
||||
padding-top: 2em;
|
||||
padding-top: 2rem;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
|
@ -29,20 +34,21 @@ article {
|
|||
}
|
||||
|
||||
.post-publish-date {
|
||||
font-size: 0.7em;
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
.post-body {
|
||||
padding-top: 1em;
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
#submit-form {
|
||||
padding-top: 2em;
|
||||
padding-top: 2rem;
|
||||
}
|
||||
|
||||
#submit-body, #submit-title {
|
||||
#submit-body,
|
||||
#submit-title {
|
||||
width: 100%;
|
||||
margin-bottom: 2em;
|
||||
margin-bottom: 2rem;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
padding: 20px;
|
||||
width: 60%;
|
||||
padding-left: 20%;
|
||||
}
|
||||
|
||||
.social-icon {
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
@media (max-width:1080px) {
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
padding: 20px;
|
||||
width: 90%;
|
||||
padding-left: 5%;
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
function setTokenCookie() {
|
||||
let token = document.getElementById('set-token').value;
|
||||
let tokenCookie = 'token=' + token + "; SameSite=None; secure";
|
||||
document.cookie = tokenCookie;
|
||||
setFormTokens(token);
|
||||
document.getElementById("cookie-block").hidden = true;
|
||||
}
|
||||
|
||||
function clearTokenCookie() {
|
||||
document.cookie = "token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; SameSite=None; secure";
|
||||
document.getElementById("cookie-block").hidden = false;
|
||||
}
|
||||
|
||||
function setFormTokens(token) {
|
||||
let tokenFields = document.querySelectorAll(".token");
|
||||
for (t of tokenFields) {
|
||||
t.value = token;
|
||||
}
|
||||
}
|
||||
|
||||
// if cookie is set, use it to pass the token
|
||||
let c_pairs = document.cookie.split(";");
|
||||
let cookie_set = false;
|
||||
for (c of c_pairs) {
|
||||
if (c.trim().split("=")[0].startsWith("token")){
|
||||
// stick token into all the form input fields
|
||||
let token = c.split("=")[1];
|
||||
setFormTokens(token);
|
||||
cookie_set = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cookie_set) {
|
||||
document.getElementById("cookie-block").hidden = false;
|
||||
}
|
|
@ -1,43 +1,55 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta property="og:title" content="{{ username }}' site'" />
|
||||
<meta property="og:image" content="/static/site-image.png" />
|
||||
|
||||
<title>{{ username }}' site</title>
|
||||
<link rel="stylesheet" href="/static/css/index.css">
|
||||
<link rel="shortcut icon" type="image/jpg" href="/static/favicon.ico"/>
|
||||
</head>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta property="og:title" content="{{ username }}' site'" />
|
||||
<meta property="og:image" content="/static/site-image.png" />
|
||||
|
||||
<title>{{ username }}' site</title>
|
||||
<link rel="stylesheet" href="/static/css/blog.css">
|
||||
<link rel="shortcut icon" type="image/jpg" href="/static/favicon.ico" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Hi, I'm {{ username }}</h1>
|
||||
<p style="text-align: right">
|
||||
<a href="/">Back to the blog</a>
|
||||
</p>
|
||||
<p>
|
||||
This is my blog.
|
||||
|
||||
{% if email %}
|
||||
If you have questions or input for me please send me an E-Mail to <img class="social-icon"
|
||||
src="/static/social-icons/mail.png" /> {{ email }}
|
||||
{% endif %}
|
||||
</p>
|
||||
<br>
|
||||
<p>
|
||||
<ul style="list-style: none;">
|
||||
{% if github_account %}
|
||||
<li><img class="social-icon" src="/static/social-icons/github.ico"><a
|
||||
href="https://github.com/{{ github_account }}"> {{ github_account }}</a></li>
|
||||
{% endif %}
|
||||
{% if twitter_account %}
|
||||
<li><img class="social-icon" src="/static/social-icons/twitter.ico"><a
|
||||
href="https://twitter.com/{{ twitter_account }}"> {{ twitter_account }}</a></li>
|
||||
{% endif %}
|
||||
{% if reddit_account %}
|
||||
<li><img class="social-icon" src="/static/social-icons/reddit.ico"><a
|
||||
href="https://reddit.com/u/{{ reddit_account }}"> {{ reddit_account }}</a></li>
|
||||
{% endif %}
|
||||
{% if mastodon_account %}
|
||||
<li><img class="social-icon" src="/static/social-icons/mastodon.ico"><a href="https://mastodon.social/"> {{
|
||||
mastodon_account }}</a></li>
|
||||
{% endif %}
|
||||
{% if discord_account %}
|
||||
<li><img class="social-icon" src="/static/social-icons/discord.ico"><a href="https://discord.com/"> {{
|
||||
discord_account }}</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
<body>
|
||||
<h1>Hi, I'm {{ username }}</h1>
|
||||
<p style="text-align: right">
|
||||
<a href="/">Back to the blog</a>
|
||||
</p>
|
||||
<p>
|
||||
This is my blog. If you have questions or input for me please send me an E-Mail to {{ email }}
|
||||
</p>
|
||||
<br>
|
||||
<p>
|
||||
<ul style="list-style: none;">
|
||||
{% if github_account %}
|
||||
<li><img class="social-icon" src="/static/social-icons/github.ico"><a href="https://github.com/{{ github_account }}"> {{ github_account }}</a></li>
|
||||
{% endif %}
|
||||
{% if twitter_account %}
|
||||
<li><img class="social-icon" src="/static/social-icons/twitter.ico"><a href="https://twitter.com/{{ twitter_account }}"> {{ twitter_account }}</a></li>
|
||||
{% endif %}
|
||||
{% if reddit_account %}
|
||||
<li><img class="social-icon" src="/static/social-icons/reddit.ico"><a href="https://reddit.com/u/{{ reddit_account }}"> {{ reddit_account }}</a></li>
|
||||
{% endif %}
|
||||
{% if mastodon_account %}
|
||||
<li><img class="social-icon" src="/static/social-icons/mastodon.ico"><a href="https://mastodon.social/"> {{ mastodon_account }}</a></li>
|
||||
{% endif %}
|
||||
{% if discord_account %}
|
||||
<li><img class="social-icon" src="/static/social-icons/discord.ico"><a href="https://discord.com/"> {{ discord_account }}</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
|
@ -1,42 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta property="og:title" content="Edit '{{ title }}'"/>
|
||||
<meta property="og:image" content="/static/site-image.png" />
|
||||
|
||||
<title>Edit '{{ title }}'</title>
|
||||
<link rel="stylesheet" href="/static/css/blog.css">
|
||||
<link rel="shortcut icon" type="image/jpg" href="/static/favicon.ico"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="cookie-block" hidden>
|
||||
<p>Please set your token cookie first.</p>
|
||||
<input id="set-token" type="text" name="set-token">
|
||||
<button onclick="setTokenCookie()">Set Token Cookie</button>
|
||||
</div>
|
||||
<button onclick="clearTokenCookie()">Clear Token Cookie</button>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta property="og:title" content="Edit '{{ title }}'" />
|
||||
<meta property="og:image" content="/static/site-image.png" />
|
||||
|
||||
<form id="submit-form" action="/api/blog/posts/edit/{{ id }}" method=POST>
|
||||
<input class="token" type="text" name="token" hidden>
|
||||
<label for="title">Title</label>
|
||||
<textarea id="submit-title" type="text" name="title">{{ title }}</textarea>
|
||||
<br>
|
||||
<label for="submit-body">Content</label>
|
||||
<textarea id="submit-body" type="text" name="body">{{ body }}</textarea>
|
||||
<br>
|
||||
<button id="submit-button" type="submit">Edit post</button>
|
||||
</form>
|
||||
<title>Edit '{{ title }}'</title>
|
||||
<link rel="stylesheet" href="/static/css/blog.css">
|
||||
<link rel="shortcut icon" type="image/jpg" href="/static/favicon.ico" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="cookie-block" hidden>
|
||||
<label for="token">Password</label>
|
||||
</br>
|
||||
<input id="token" type="password" name="token">
|
||||
</div>
|
||||
|
||||
<form id="submit-form" action="/api/blog/posts/edit/{{ id }}" method=POST>
|
||||
<input class="token" type="text" name="token" hidden>
|
||||
<label for="title">Title</label>
|
||||
<textarea id="submit-title" type="text" name="title">{{ title }}</textarea>
|
||||
<br>
|
||||
<label for="submit-body">Content</label>
|
||||
<textarea id="submit-body" type="text" name="body">{{ body }}</textarea>
|
||||
<br>
|
||||
<button id="submit-button" type="submit">Edit post</button>
|
||||
</form>
|
||||
|
||||
<form action="/api/blog/posts/hide/{{ id }}" method="POST">
|
||||
<input class="token" type="text" name="token" hidden>
|
||||
<button type="submit">Hide post</button>
|
||||
</form>
|
||||
<form action="/api/blog/posts/delete/{{ id }}" method="POST">
|
||||
<input class="token" type="text" name="token" hidden>
|
||||
<button type="submit">Delete post</button>
|
||||
</form>
|
||||
</body>
|
||||
|
||||
<form action="/api/blog/posts/hide/{{ id }}" method="POST">
|
||||
<input class="token" type="text" name="token" hidden>
|
||||
<button type="submit">Hide post</button>
|
||||
</form>
|
||||
<form action="/api/blog/posts/delete/{{ id }}" method="POST">
|
||||
<input class="token" type="text" name="token" hidden>
|
||||
<button type="submit">Delete post</button>
|
||||
</form>
|
||||
<script src="/static/js/blog.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,33 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta property="og:title" content="Submit post" />
|
||||
<meta property="og:image" content="/static/site-image.png" />
|
||||
|
||||
<title>Submit post</title>
|
||||
<link rel="stylesheet" href="/static/css/blog.css">
|
||||
<link rel="shortcut icon" type="image/jpg" href="/static/favicon.ico"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="cookie-block" hidden>
|
||||
<p>Please set your token cookie first.</p>
|
||||
<input id="set-token" type="text" name="set-token">
|
||||
<button onclick="setTokenCookie()">Set Token Cookie</button>
|
||||
</div>
|
||||
<button onclick="clearTokenCookie()">Clear Token Cookie</button>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta property="og:title" content="Submit post" />
|
||||
<meta property="og:image" content="/static/site-image.png" />
|
||||
|
||||
<title>Submit post</title>
|
||||
<link rel="stylesheet" href="/static/css/blog.css">
|
||||
<link rel="shortcut icon" type="image/jpg" href="/static/favicon.ico" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="cookie-block" hidden>
|
||||
<label for="token">Password</label>
|
||||
<br />
|
||||
<input id="token" type="password" name="token">
|
||||
</div>
|
||||
|
||||
<form id="submit-form" action="/api/blog/create" method=POST>
|
||||
<input class="token" type="text" name="token" hidden>
|
||||
<label for="title">Title</label>
|
||||
<textarea id="submit-title" type="text" name="title">{{ title }}</textarea>
|
||||
<br>
|
||||
<label for="submit-body">Content</label>
|
||||
<textarea id="submit-body" type="text" name="body">{{ body }}</textarea>
|
||||
<br>
|
||||
<button id="submit-button" type="submit">Submit</button>
|
||||
</form>
|
||||
</body>
|
||||
|
||||
<form id="submit-form" action="/api/blog/create" method=POST>
|
||||
<input class="token" type="text" name="token" hidden>
|
||||
<label for="title">Title</label>
|
||||
<textarea id="submit-title" type="text" name="title">{{ title }}</textarea>
|
||||
<br>
|
||||
<label for="submit-body">Content</label>
|
||||
<textarea id="submit-body" type="text" name="body">{{ body }}</textarea>
|
||||
<br>
|
||||
<button id="submit-button" type="submit">Submit</button>
|
||||
</form>
|
||||
<script src="/static/js/blog.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -31,10 +31,7 @@ async fn blog_create_post(form: Form<NewPostForm>) -> impl Responder {
|
|||
}
|
||||
|
||||
#[post("/api/blog/posts/edit/{post_id}")]
|
||||
async fn blog_edit_post(
|
||||
post_id: web::Path<String>,
|
||||
form: Form<NewPostForm>,
|
||||
) -> impl Responder {
|
||||
async fn blog_edit_post(post_id: web::Path<String>, form: Form<NewPostForm>) -> impl Responder {
|
||||
let (valid, id) = id_valid(post_id.into_inner());
|
||||
if valid && CONFIG.submit_token == form.token {
|
||||
edit_post_by_id(
|
||||
|
@ -73,10 +70,7 @@ async fn blog_delete_post(
|
|||
}
|
||||
|
||||
#[post("/api/blog/posts/hide/{post_id}")]
|
||||
async fn blog_hide_post(
|
||||
post_id: web::Path<String>,
|
||||
form: Form<BlogActionForm>,
|
||||
) -> impl Responder {
|
||||
async fn blog_hide_post(post_id: web::Path<String>, form: Form<BlogActionForm>) -> impl Responder {
|
||||
let (valid, id) = id_valid(post_id.into_inner());
|
||||
if valid && CONFIG.submit_token == form.token {
|
||||
println!("Hid post: {}", id);
|
||||
|
|
|
@ -7,12 +7,12 @@ pub struct Config {
|
|||
pub submit_token: String,
|
||||
pub root_path: String,
|
||||
pub username: String,
|
||||
pub email: String,
|
||||
pub bind_port: String,
|
||||
pub accounts: Accounts,
|
||||
}
|
||||
|
||||
pub struct Accounts {
|
||||
pub email: Option<String>,
|
||||
pub github: Option<String>,
|
||||
pub twitter: Option<String>,
|
||||
pub mastodon: Option<String>,
|
||||
|
@ -68,9 +68,9 @@ fn load_config() -> Config {
|
|||
submit_token: eval_conf_var("SUBMIT_TOKEN", true, None).unwrap(),
|
||||
root_path: eval_conf_var("ROOT_PATH", false, Some("./content")).unwrap(),
|
||||
username: eval_conf_var("USERNAME", true, None).unwrap(),
|
||||
email: eval_conf_var("EMAIL", false, None).unwrap(),
|
||||
bind_port: eval_conf_var("BIND_PORT", false, Some("8000")).unwrap(),
|
||||
accounts: Accounts {
|
||||
email: eval_conf_var("EMAIL", false, None),
|
||||
github: eval_conf_var("GITHUB_ACCOUNT", false, None),
|
||||
discord: eval_conf_var("DISCORD_ACCOUNT", false, None),
|
||||
twitter: eval_conf_var("TWITTER_ACCOUNT", false, None),
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
use diesel::prelude::*;
|
||||
use chrono;
|
||||
|
||||
#[derive(Queryable, Selectable)]
|
||||
#[diesel(table_name = crate::schema::posts)]
|
||||
#[diesel(check_for_backend(diesel::pg::Pg))]
|
||||
pub struct Post {
|
||||
pub id: i32,
|
||||
pub title: String,
|
||||
pub body: String,
|
||||
pub published: bool,
|
||||
pub publish_date: chrono::Timestamp
|
||||
}
|
|
@ -36,31 +36,30 @@ pub fn replace_br_tags(x: &str) -> String {
|
|||
#[get("/about")]
|
||||
async fn about(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {
|
||||
let mut context = Context::new();
|
||||
context.insert(
|
||||
"username",
|
||||
&CONFIG.username
|
||||
);
|
||||
context.insert("email", &CONFIG.email);
|
||||
|
||||
context.insert("username", &CONFIG.username);
|
||||
match &CONFIG.accounts.email {
|
||||
Some(acc) => context.insert("email", &acc.replace("@", " (at) ")),
|
||||
None => (),
|
||||
}
|
||||
match &CONFIG.accounts.github {
|
||||
Some(acc) => context.insert("github_account", &acc),
|
||||
None => ()
|
||||
None => (),
|
||||
};
|
||||
match &CONFIG.accounts.twitter {
|
||||
Some(acc) => context.insert("twitter_account", &acc),
|
||||
None => ()
|
||||
None => (),
|
||||
};
|
||||
match &CONFIG.accounts.mastodon {
|
||||
Some(acc) => context.insert("mastodon_account", &acc),
|
||||
None => ()
|
||||
None => (),
|
||||
};
|
||||
match &CONFIG.accounts.reddit {
|
||||
Some(acc) => context.insert("reddit_account", &acc),
|
||||
None => ()
|
||||
None => (),
|
||||
};
|
||||
match &CONFIG.accounts.discord {
|
||||
Some(acc) => context.insert("discord_account", &acc),
|
||||
None => ()
|
||||
None => (),
|
||||
};
|
||||
|
||||
let result = tmpl
|
||||
|
@ -103,8 +102,7 @@ async fn blog_all(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {
|
|||
#[get("/id/{post_id}")]
|
||||
async fn blog_by_id(
|
||||
tmpl: web::Data<tera::Tera>,
|
||||
post_id: web::Path<String>
|
||||
// web::Path(post_id): web::Path<String>,
|
||||
post_id: web::Path<String>, // web::Path(post_id): web::Path<String>,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let (valid, id) = id_valid(post_id.into_inner());
|
||||
if valid {
|
||||
|
@ -157,7 +155,7 @@ async fn blog_edit(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {
|
|||
#[get("/edit/{post_id}")]
|
||||
async fn blog_edit_by_id(
|
||||
tmpl: web::Data<tera::Tera>,
|
||||
post_id: web::Path<String>
|
||||
post_id: web::Path<String>,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let (valid, id) = id_valid(post_id.into_inner());
|
||||
if valid {
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
// @generated automatically by Diesel CLI.
|
||||
|
||||
diesel::table! {
|
||||
posts (id) {
|
||||
id -> Nullable<Integer>,
|
||||
title -> Text,
|
||||
body -> Text,
|
||||
published -> Bool,
|
||||
publish_date -> Timestamp,
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue