Compare commits

..

No commits in common. "40b9a90bf9780bc1267b9930339c33871241d9fe" and "243bc6397be63ed17e0fccd97b2c78e9af4308cb" have entirely different histories.

13 changed files with 166 additions and 307 deletions

View file

@ -5,7 +5,7 @@ ENV RUSTFLAGS='-C target-feature=-crt-static'
WORKDIR /app WORKDIR /app
COPY ./site . COPY ./site .
RUN apk add --no-cache musl-dev sqlite-dev RUN apk add --no-cache musl-dev sqlite-dev
RUN cargo install --path . -j $(nproc) RUN cargo install --path .
FROM alpine:latest FROM alpine:latest

View file

@ -2,31 +2,31 @@
Pure rust. Built with actix, diesel, tera, serde and sqlite3. Pure rust. Built with actix, diesel, tera, serde and sqlite3.
## Run instructions using docker ## Build instructions using docker
1. Clone the repository 1. Clone the repository
```bash ```bash
git clone https://github.com/mtrx1337/crablog git clone https://github.com/leonardlorenz/crablog
cd crablog/site cd crablog/site
``` ```
2. Install diesel and create a database 2. Install diesel and create a database
```bash ```bash
cargo install diesel_cli --no-default-features --features "sqlite" cargo install diesel_cli
diesel setup --database-url ../content/db.sqlite3 diesel setup --database-url ../content/db.sqlite3
diesel migration run --database-url ../content/db.sqlite3 diesel migration run --database-url ../content/db.sqlite3
``` ```
3. Set up your configuration file (see below) 3. Set up your configuration file (see below)
4. Pull the image (or build from source) and run the docker container 4. Build and run the docker container (Will compile from source and thus take a while)
```bash ```bash
docker-compose up -d docker-compose up -d
``` ```
## Configuration environment file ## Configuration environment file
All configuration options are defined in crablog.env, an example configuration is provided. All configuration options are defined in .env, to be created in the same directory as this readme.
When not using Docker you may have to add crablog.env to your startup script or define the variables there.
An example configuration:
`crablog.env`
``` ```
USERNAME=yourusername USERNAME=yourusername
EMAIL=me@mydomain.tld EMAIL=me@mydomain.tld
@ -44,17 +44,13 @@ ROOT_PATH=/path/to/template/directory/and/sqliteDB
## Routes ## Routes
| Route | Description | - / site welcome
| ------------ | -------------------------------------------------- | - /blog shows the last 5 posts
| `/` | shows the last 5 posts | - /blog/id/<id> shows a single post by id
| `/id/<id>` | shows a single post by id | - /blog/all shows all posts
| `/all` | shows all posts | - /blog/submit set your submit token and create posts
| `/submit` | set your submit token and create posts | - /blog/edit/<id> edit, delete or hide posts
| `/edit/<id>` | edit, delete or hide posts |
| `/about` | information about this blog, social media accounts |
**API Routes** **API Routes**
| Route | Description | - /api/blog/posts returns all posts as json
| ---------------- | ------------------------- |
| `api/blog/posts` | returns all posts as json |

View file

@ -13,16 +13,13 @@
</head> </head>
<body> <body>
<h1><a href="/" class="post-link" style="text-decoration:none;color:black;">{{ username }}' blog</a></h1> <h1><a href="/blog" class="post-link" style="text-decoration:none;color:black;">{{ username }}' blog</a></h1>
<p style="text-align: right"> <p style="text-align: right"><a href="/">Home</a> <a href="/blog">Last 5 posts</a></p>
<a href="/about">About</a>
<a href="/">Last 5 posts</a>
</p>
<ul> <ul>
{% for post in posts %} {% for post in posts %}
<article> <article>
<div> <div>
<a href="/id/{{ post.id }}" class="post-link">[link]</a> <a href="/blog/id/{{ post.id }}" class="post-link">[link]</a>
</div> </div>
<div class="post-content"> <div class="post-content">
<h2 class="post-title">{{ post.title }}</h2> <h2 class="post-title">{{ post.title }}</h2>

View file

@ -13,16 +13,12 @@
</head> </head>
<body> <body>
<h1><a href="/" class="post-link" style="text-decoration:none;color:black;">{{ username }}' blog</a></h1> <h1><a href="/blog" class="post-link" style="text-decoration:none;color:black;">{{ username }}' blog</a></h1>
<p style="text-align: right"> <p style="text-align: right"><a href="/">Home</a> <a href="/blog">Last 5 Posts</a> <a href="/blog/all">All Posts</a></p>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/all">All Posts</a>
</p>
<ul> <ul>
<article> <article>
<div> <div>
<a href="/id/{{ post.id }}" class="post-link">[link]</a> <a href="/blog/id/{{ post.id }}" class="post-link">[link]</a>
</div> </div>
<div class="post-content"> <div class="post-content">
<h2 class="post-title">{{ post.title }}</h2> <h2 class="post-title">{{ post.title }}</h2>

View file

@ -13,15 +13,13 @@
</head> </head>
<body> <body>
<h1><a href="/" class="post-link" style="text-decoration:none;color:black;">{{ username }}' blog</a></h1> <h1><a href="/blog" class="post-link" style="text-decoration:none;color:black;">{{ username }}' blog</a></h1>
<p style="text-align: right"> <p style="text-align: right"><a href="/">Home</a> <a href="/blog/all">All Posts</a></p>
<a href="/about">About</a>
<a href="/all">All Posts</a></p>
<ul> <ul>
{% for post in posts %} {% for post in posts %}
<article> <article>
<div> <div>
<a href="/id/{{ post.id }}" class="post-link">[link]</a> <a href="/blog/id/{{ post.id }}" class="post-link">[link]</a>
</div> </div>
<div class="post-content"> <div class="post-content">
<h2 class="post-title">{{ post.title }}</h2> <h2 class="post-title">{{ post.title }}</h2>

View file

@ -11,11 +11,11 @@
<link rel="shortcut icon" type="image/jpg" href="/static/favicon.ico"/> <link rel="shortcut icon" type="image/jpg" href="/static/favicon.ico"/>
</head> </head>
<body> <body>
<h1><a href="/" class="post-link" style="text-decoration:none;color:black;">{{ username }}' blog</a></h1> <h1><a href="/blog" class="post-link" style="text-decoration:none;color:black;">{{ username }}' blog</a></h1>
<h2>Edit posts</h2> <h2>Edit posts</h2>
<ul style="list-style: none;"> <ul style="list-style: none;">
{% for post in posts %} {% for post in posts %}
<li><a href="/edit/{{ post.id }}">{{ post.title }}</a></li> <li><a href="/blog/edit/{{ post.id }}">{{ post.title }}</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
</body> </body>

View file

@ -13,11 +13,9 @@
<body> <body>
<h1>Hi, I'm {{ username }}</h1> <h1>Hi, I'm {{ username }}</h1>
<p style="text-align: right">
<a href="/">Back to the blog</a>
</p>
<p> <p>
This is my blog. If you have questions or input for me please send me an E-Mail to {{ email }} I have a <a href="/blog">blog.</a><br>
If you have questions or input for me please send me an E-Mail to {{ email }}
</p> </p>
<br> <br>
<p> <p>

View file

@ -1,9 +1,6 @@
USERNAME=yourusername SUBMIT_TOKEN=mysupersecretpw
EMAIL=me@mydomain.tld
BIND_PORT=8000 BIND_PORT=8000
SUBMIT_TOKEN=Submit!123 # token needed for submitting USERNAME=
GITHUB_ACCOUNT=usernam3 EMAIL=
TWITTER_ACCOUNT=usernam3 TWITTER_ACCOUNT=
MASTODON_ACCOUNT=usernam3@mastodon.social GITHUB_ACCOUNT=
REDDIT_ACCOUNT=usernam3
DISCORD_ACCOUNT=usernam3

View file

@ -1,8 +1,7 @@
version: "3.0" version: "3.8"
services: services:
crablog: crablog:
build: . build: .
image: mtrx1337/crablog
ports: ports:
- 8000:8000 - 8000:8000
hostname: crablog hostname: crablog

179
site/Cargo.lock generated
View file

@ -57,9 +57,9 @@ dependencies = [
[[package]] [[package]]
name = "actix-http" name = "actix-http"
version = "2.2.0" version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "452299e87817ae5673910e53c243484ca38be3828db819b6011736fc6982e874" checksum = "404df68c297f73b8d36c9c9056404913d25905a8f80127b0e5fe147c9c4b9f02"
dependencies = [ dependencies = [
"actix-codec", "actix-codec",
"actix-connect", "actix-connect",
@ -92,7 +92,7 @@ dependencies = [
"mime", "mime",
"percent-encoding", "percent-encoding",
"pin-project 1.0.1", "pin-project 1.0.1",
"rand 0.7.3", "rand",
"regex", "regex",
"serde", "serde",
"serde_json", "serde_json",
@ -109,7 +109,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a60f9ba7c4e6df97f3aacb14bb5c0cd7d98a49dcbaed0d7f292912ad9a6a3ed2" checksum = "a60f9ba7c4e6df97f3aacb14bb5c0cd7d98a49dcbaed0d7f292912ad9a6a3ed2"
dependencies = [ dependencies = [
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.71", "syn 1.0.48",
] ]
[[package]] [[package]]
@ -233,9 +233,9 @@ dependencies = [
[[package]] [[package]]
name = "actix-web" name = "actix-web"
version = "3.3.2" version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e641d4a172e7faa0862241a20ff4f1f5ab0ab7c279f00c2d4587b77483477b86" checksum = "88344b7a5ef27e5e09e73565379f69273dd3e2d29e82afc381b84d170d0a5631"
dependencies = [ dependencies = [
"actix-codec", "actix-codec",
"actix-http", "actix-http",
@ -278,7 +278,7 @@ checksum = "ad26f77093333e0e7c6ffe54ebe3582d908a104e448723eec6d43d08b07143fb"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.71", "syn 1.0.48",
] ]
[[package]] [[package]]
@ -313,7 +313,7 @@ checksum = "b246867b8b3b6ae56035f1eb1ed557c1d8eae97f0d53696138a50fa0e3a3b8c0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.71", "syn 1.0.48",
] ]
[[package]] [[package]]
@ -335,9 +335,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]] [[package]]
name = "awc" name = "awc"
version = "2.0.3" version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b381e490e7b0cfc37ebc54079b0413d8093ef43d14a4e4747083f7fa47a9e691" checksum = "425980a1e58e5030a3e4b065a3d577c8f0e16142ea9d81f30614eae810c98577"
dependencies = [ dependencies = [
"actix-codec", "actix-codec",
"actix-http", "actix-http",
@ -351,7 +351,7 @@ dependencies = [
"log", "log",
"mime", "mime",
"percent-encoding", "percent-encoding",
"rand 0.7.3", "rand",
"serde", "serde",
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
@ -572,12 +572,12 @@ checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
[[package]] [[package]]
name = "crablog" name = "crablog"
version = "0.3.1" version = "0.2.3"
dependencies = [ dependencies = [
"actix-files", "actix-files",
"actix-web", "actix-web",
"chrono", "chrono",
"diesel 1.4.6", "diesel 1.4.5",
"diesel_codegen", "diesel_codegen",
"env_logger", "env_logger",
"once_cell", "once_cell",
@ -616,7 +616,7 @@ checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.71", "syn 1.0.48",
] ]
[[package]] [[package]]
@ -636,9 +636,9 @@ dependencies = [
[[package]] [[package]]
name = "diesel" name = "diesel"
version = "1.4.6" version = "1.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "047bfc4d5c3bd2ef6ca6f981941046113524b9a9f9a7cbdfdd7ff40f58e6f542" checksum = "3e2de9deab977a153492a1468d1b1c0662c1cf39e5ea87d0c060ecd59ef18d8c"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"chrono", "chrono",
@ -667,7 +667,7 @@ checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.71", "syn 1.0.48",
] ]
[[package]] [[package]]
@ -694,6 +694,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
[[package]]
name = "dtoa"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
[[package]] [[package]]
name = "either" name = "either"
version = "1.6.1" version = "1.6.1"
@ -718,14 +724,14 @@ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.71", "syn 1.0.48",
] ]
[[package]] [[package]]
name = "env_logger" name = "env_logger"
version = "0.8.3" version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f" checksum = "f26ecb66b4bdca6c1409b40fb255eefc2bd4f6d135dab3c3124f80ffa2a9661e"
dependencies = [ dependencies = [
"atty", "atty",
"humantime", "humantime",
@ -829,7 +835,7 @@ dependencies = [
"proc-macro-hack", "proc-macro-hack",
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.71", "syn 1.0.48",
] ]
[[package]] [[package]]
@ -906,17 +912,6 @@ dependencies = [
"wasi 0.9.0+wasi-snapshot-preview1", "wasi 0.9.0+wasi-snapshot-preview1",
] ]
[[package]]
name = "getrandom"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
dependencies = [
"cfg-if 1.0.0",
"libc",
"wasi 0.10.0+wasi-snapshot-preview1",
]
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.23.0" version = "0.23.0"
@ -938,9 +933,9 @@ dependencies = [
[[package]] [[package]]
name = "globwalk" name = "globwalk"
version = "0.8.1" version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" checksum = "178270263374052c40502e9f607134947de75302c1348d1a0e31db67c1691446"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"ignore", "ignore",
@ -1327,9 +1322,9 @@ checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.7.2" version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
[[package]] [[package]]
name = "opaque-debug" name = "opaque-debug"
@ -1413,7 +1408,7 @@ dependencies = [
"pest_meta", "pest_meta",
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.71", "syn 1.0.48",
] ]
[[package]] [[package]]
@ -1453,7 +1448,7 @@ checksum = "65ad2ae56b6abe3a1ee25f15ee605bacadb9a764edaba9c2bf4103800d4a1895"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.71", "syn 1.0.48",
] ]
[[package]] [[package]]
@ -1464,7 +1459,7 @@ checksum = "81a4ffa594b66bff340084d4081df649a7dc049ac8d7fc458d8e628bfbbb2f86"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.71", "syn 1.0.48",
] ]
[[package]] [[package]]
@ -1505,9 +1500,9 @@ checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.26" version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [ dependencies = [
"unicode-xid 0.2.1", "unicode-xid 0.2.1",
] ]
@ -1539,23 +1534,11 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [ dependencies = [
"getrandom 0.1.15", "getrandom",
"libc", "libc",
"rand_chacha 0.2.2", "rand_chacha",
"rand_core 0.5.1", "rand_core",
"rand_hc 0.2.0", "rand_hc",
]
[[package]]
name = "rand"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
dependencies = [
"libc",
"rand_chacha 0.3.0",
"rand_core 0.6.2",
"rand_hc 0.3.0",
] ]
[[package]] [[package]]
@ -1565,17 +1548,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [ dependencies = [
"ppv-lite86", "ppv-lite86",
"rand_core 0.5.1", "rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
dependencies = [
"ppv-lite86",
"rand_core 0.6.2",
] ]
[[package]] [[package]]
@ -1584,16 +1557,7 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [ dependencies = [
"getrandom 0.1.15", "getrandom",
]
[[package]]
name = "rand_core"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
dependencies = [
"getrandom 0.2.2",
] ]
[[package]] [[package]]
@ -1602,16 +1566,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [ dependencies = [
"rand_core 0.5.1", "rand_core",
]
[[package]]
name = "rand_hc"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
dependencies = [
"rand_core 0.6.2",
] ]
[[package]] [[package]]
@ -1701,22 +1656,22 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.125" version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.125" version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.71", "syn 1.0.48",
] ]
[[package]] [[package]]
@ -1732,14 +1687,14 @@ dependencies = [
[[package]] [[package]]
name = "serde_urlencoded" name = "serde_urlencoded"
version = "0.7.0" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"
dependencies = [ dependencies = [
"form_urlencoded", "dtoa",
"itoa", "itoa",
"ryu",
"serde", "serde",
"url",
] ]
[[package]] [[package]]
@ -1848,7 +1803,7 @@ dependencies = [
"quote 1.0.7", "quote 1.0.7",
"serde", "serde",
"serde_derive", "serde_derive",
"syn 1.0.71", "syn 1.0.48",
] ]
[[package]] [[package]]
@ -1864,7 +1819,7 @@ dependencies = [
"serde_derive", "serde_derive",
"serde_json", "serde_json",
"sha1", "sha1",
"syn 1.0.71", "syn 1.0.48",
] ]
[[package]] [[package]]
@ -1886,9 +1841,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.71" version = "1.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad184cc9470f9117b2ac6817bfe297307418819ba40552f9b3846f05c33d5373" checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
@ -1906,9 +1861,9 @@ dependencies = [
[[package]] [[package]]
name = "tera" name = "tera"
version = "1.8.0" version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b64b021b8d3ab1f59ceae9e6cd1c26c8e7ce0322a9ebfff6c0e22b3b66938935" checksum = "1381c83828bedd5ce4e59473110afa5381ffe523406d9ade4b77c9f7be70ff9a"
dependencies = [ dependencies = [
"chrono", "chrono",
"chrono-tz", "chrono-tz",
@ -1918,7 +1873,7 @@ dependencies = [
"percent-encoding", "percent-encoding",
"pest", "pest",
"pest_derive", "pest_derive",
"rand 0.8.3", "rand",
"regex", "regex",
"serde", "serde",
"serde_json", "serde_json",
@ -1952,7 +1907,7 @@ checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.71", "syn 1.0.48",
] ]
[[package]] [[package]]
@ -2019,7 +1974,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"standback", "standback",
"syn 1.0.71", "syn 1.0.48",
] ]
[[package]] [[package]]
@ -2115,7 +2070,7 @@ dependencies = [
"idna", "idna",
"lazy_static", "lazy_static",
"log", "log",
"rand 0.7.3", "rand",
"smallvec", "smallvec",
"thiserror", "thiserror",
"tokio", "tokio",
@ -2263,9 +2218,9 @@ dependencies = [
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "0.8.2" version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
dependencies = [ dependencies = [
"serde", "serde",
"sha1", "sha1",
@ -2290,7 +2245,7 @@ dependencies = [
"nom", "nom",
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.71", "syn 1.0.48",
] ]
[[package]] [[package]]
@ -2365,7 +2320,7 @@ dependencies = [
"log", "log",
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.71", "syn 1.0.48",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -2387,7 +2342,7 @@ checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.71", "syn 1.0.48",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]

View file

@ -1,6 +1,6 @@
[package] [package]
name = "crablog" name = "crablog"
version = "0.3.1" version = "0.2.3"
authors = ["Leonard Lorenz <dev@leonardlorenz.de>"] authors = ["Leonard Lorenz <dev@leonardlorenz.de>"]
edition = "2018" edition = "2018"
@ -8,20 +8,20 @@ edition = "2018"
[dependencies] [dependencies]
chrono = { version = "*", features = ["serde"] } chrono = { version = "*", features = ["serde"] }
actix-web = "3.3.2" actix-web = "3.2.0"
actix-files = "0.4.0" actix-files = "0.4.0"
serde = { version = "1.0.125", features = ["derive"] } serde = { version = "1.0.117", features = ["derive"] }
serde_json = "*" serde_json = "1.0.59"
serde_derive = "*" serde_derive = "1.0.117"
diesel = { version = "1.4.6", default-features = false, features = ["sqlite", "chrono"] } diesel = { version = "1.4.5", default-features = false, features = ["sqlite", "chrono"] }
diesel_codegen = { version = "0.16.1", default-features = false } diesel_codegen = { version = "0.16.1", default-features = false }
uuid = { version = "0.8.2", features = ["serde", "v5"] } uuid = { version = "0.8.1", features = ["serde", "v5"] }
tera = "1.8.0" tera = "1.5.0"
once_cell = "1.7.2" once_cell = "1.5.2"
env_logger = "0.8.3" env_logger = "0.8.2"

View file

@ -9,89 +9,50 @@ extern crate serde_derive;
extern crate tera; extern crate tera;
use actix_files as fs; use actix_files as fs;
use actix_web::{middleware::Logger, App, HttpServer}; use actix_web::{App, HttpServer, middleware::Logger};
use env_logger::Env; use env_logger::Env;
use once_cell::sync::Lazy;
use std::{collections::HashMap, env, sync::RwLock};
use tera::Tera; use tera::Tera;
use std::{env, sync::RwLock, collections::HashMap};
use once_cell::sync::Lazy;
pub static CONFIG_MAP: Lazy<RwLock<HashMap<String, String>>> = Lazy::new(|| { pub static CONFIG_MAP: Lazy<RwLock<HashMap<String, String>>> = Lazy::new(|| {
let mut config: HashMap<String, String> = HashMap::new(); let mut config: HashMap<String, String> = HashMap::new();
config.insert(String::from("SUBMIT_TOKEN"), env::var("SUBMIT_TOKEN").expect("SUBMIT_TOKEN variable not set."));
let required_env_vars = [ config.insert(String::from("ROOT_PATH"), env::var("ROOT_PATH").expect("ROOT_PATH variable not set."));
"SUBMIT_TOKEN", config.insert(String::from("USERNAME"), env::var("USERNAME").expect("USERNAME variable not set."));
"ROOT_PATH", config.insert(String::from("EMAIL"), env::var("EMAIL").expect("EMAIL variable not set."));
"USERNAME", config.insert(String::from("BIND_PORT"), env::var("BIND_PORT").expect("BIND_PORT variable not set."));
"EMAIL", if let Ok(acc) = env::var("GITHUB_ACCOUNT") {
"BIND_PORT", config.insert(String::from("GITHUB_ACCOUNT"), acc.clone());
];
let optional_env_vars = [
"GITHUB_ACCOUNT",
"TWITTER_ACCOUNT",
"MASTODON_ACCOUNT",
"DISCORD_ACCOUNT",
"REDDIT_ACCOUNT",
];
// Test if variable is set. If not, panic.
let mut insert_required_env = |env: &str| {
let env_string = String::from(env);
config.insert(
env_string.clone(), // env var name
env::var(env_string).expect(format!("`{}` variable not set.", env).as_str()), // env var content
)
};
for var in required_env_vars.iter() {
insert_required_env(var);
} }
if let Ok(acc) = env::var("TWITTER_ACCOUNT") {
// Test if variable is set. If it is insert into config. config.insert(String::from("TWITTER_ACCOUNT"), acc.clone());
let mut insert_optional_env = |env: &str| {
if let Ok(var_content) = env::var(String::from(env)) {
config.insert(String::from(env), var_content.clone());
} }
}; if let Ok(acc) = env::var("MASTODON_ACCOUNT") {
config.insert(String::from("MASTODON_ACCOUNT"), acc.clone());
for var in optional_env_vars.iter() { }
insert_optional_env(var); if let Ok(acc) = env::var("DISCORD_ACCOUNT") {
config.insert(String::from("DISCORD_ACCOUNT"), acc.clone());
}
if let Ok(acc) = env::var("REDDIT_ACCOUNT") {
config.insert(String::from("REDDIT_ACCOUNT"), acc.clone());
} }
// Print some info about the current configuration
println!("Submit token = `{}`", config.get("SUBMIT_TOKEN").unwrap());
println!(
"Current working directory = `{}`",
env::current_dir().unwrap().to_str().unwrap()
);
println!("Root path = `{}`", config.get("ROOT_PATH").unwrap());
println!(
"Template path = `{}/templates/*`",
config.get("ROOT_PATH").unwrap()
);
println!("Launching on 0.0.0.0:{}", config.get("BIND_PORT").unwrap());
RwLock::new(config) RwLock::new(config)
}); });
#[actix_web::main] #[actix_web::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
HttpServer::new(|| { HttpServer::new(|| {
let mut tera = Tera::new(
format!( let mut tera = Tera::new(format!("{}{}", CONFIG_MAP.read().unwrap().get("ROOT_PATH").unwrap(), "/templates/*").as_str()).unwrap();
"{}{}",
CONFIG_MAP.read().unwrap().get("ROOT_PATH").unwrap(),
"/templates/*"
)
.as_str(),
)
.unwrap();
tera.autoescape_on(vec![".sql"]); tera.autoescape_on(vec![".sql"]);
env_logger::Builder::from_env(Env::default().default_filter_or("info")); env_logger::Builder::from_env(Env::default().default_filter_or("info"));
App::new() App::new()
.data(tera) .data(tera)
.service(routes::about) .service(routes::root)
.service(routes::blog) .service(routes::blog)
.service(routes::blog_all) .service(routes::blog_all)
.service(routes::blog_by_id) .service(routes::blog_by_id)
@ -103,20 +64,10 @@ async fn main() -> std::io::Result<()> {
.service(api::blog_edit_post) .service(api::blog_edit_post)
.service(api::blog_hide_post) .service(api::blog_hide_post)
.service(api::blog_delete_post) .service(api::blog_delete_post)
.service(fs::Files::new( .service(fs::Files::new("/static", format!("{}{}", CONFIG_MAP.read().unwrap().get("ROOT_PATH").unwrap(), "/static")))
"/static",
format!(
"{}{}",
CONFIG_MAP.read().unwrap().get("ROOT_PATH").unwrap(),
"/static"
),
))
.wrap(Logger::new("%a %r %t")) .wrap(Logger::new("%a %r %t"))
}) })
.bind(format!( .bind(format!("0.0.0.0:{}", CONFIG_MAP.read().unwrap().get("BIND_PORT").unwrap()))?
"0.0.0.0:{}",
CONFIG_MAP.read().unwrap().get("BIND_PORT").unwrap()
))?
.run() .run()
.await .await
} }

View file

@ -1,8 +1,8 @@
use crate::db; use crate::db;
use super::CONFIG_MAP; use actix_web::{get, http::StatusCode, web, HttpResponse, Error, error};
use actix_web::{error, get, http::StatusCode, web, Error, HttpResponse};
use tera::Context; use tera::Context;
use super::CONFIG_MAP;
/// tests if the post id is a valid i32 integer bigger than zero /// tests if the post id is a valid i32 integer bigger than zero
/// assert(!(id_valid("2147483648").0)) /// assert(!(id_valid("2147483648").0))
@ -33,13 +33,10 @@ pub fn replace_br_tags(x: &str) -> String {
x.replace("<br>", "\n") x.replace("<br>", "\n")
} }
#[get("/about")] #[get("/")]
async fn about(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> { async fn root(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {
let mut context = Context::new(); let mut context = Context::new();
context.insert( context.insert("username", CONFIG_MAP.read().unwrap().get("USERNAME").unwrap());
"username",
CONFIG_MAP.read().unwrap().get("USERNAME").unwrap(),
);
context.insert("email", CONFIG_MAP.read().unwrap().get("EMAIL").unwrap()); context.insert("email", CONFIG_MAP.read().unwrap().get("EMAIL").unwrap());
if let Some(acc) = CONFIG_MAP.read().unwrap().get("GITHUB_ACCOUNT") { if let Some(acc) = CONFIG_MAP.read().unwrap().get("GITHUB_ACCOUNT") {
context.insert("github_account", acc); context.insert("github_account", acc);
@ -57,113 +54,89 @@ async fn about(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {
context.insert("reddit_account", acc); context.insert("reddit_account", acc);
} }
let result = tmpl let result = tmpl.render("index.html", &context)
.render("about.html", &context)
.map_err(|e| error::ErrorInternalServerError(format!("Template error\n{}", e)))?; .map_err(|e| error::ErrorInternalServerError(format!("Template error\n{}", e)))?;
Ok(HttpResponse::Ok().content_type("text/html").body(result)) Ok(HttpResponse::Ok().content_type("text/html").body(result))
} }
#[get("/")] #[get("/blog")]
async fn blog(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> { async fn blog(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {
let posts = db::get_last_five_posts(); let posts = db::get_last_five_posts();
let mut context = Context::new(); let mut context = Context::new();
context.insert("posts", &posts); context.insert("posts", &posts);
context.insert( context.insert("username", CONFIG_MAP.read().unwrap().get("USERNAME").unwrap());
"username",
CONFIG_MAP.read().unwrap().get("USERNAME").unwrap(),
);
let result = tmpl let result = tmpl.render("blog.html", &context)
.render("blog.html", &context)
.map_err(|_| error::ErrorInternalServerError("Template error"))?; .map_err(|_| error::ErrorInternalServerError("Template error"))?;
Ok(HttpResponse::Ok().content_type("text/html").body(result)) Ok(HttpResponse::Ok().content_type("text/html").body(result))
} }
#[get("/all")] #[get("/blog/all")]
async fn blog_all(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> { async fn blog_all(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {
let posts = db::get_all_posts(); let posts = db::get_all_posts();
let mut context = Context::new(); let mut context = Context::new();
context.insert("posts", &posts); context.insert("posts", &posts);
context.insert( context.insert("username", CONFIG_MAP.read().unwrap().get("USERNAME").unwrap());
"username",
CONFIG_MAP.read().unwrap().get("USERNAME").unwrap(),
);
let result = tmpl let result = tmpl.render("blog-all-posts.html", &context)
.render("blog-all-posts.html", &context)
.map_err(|_| error::ErrorInternalServerError("Template error"))?; .map_err(|_| error::ErrorInternalServerError("Template error"))?;
Ok(HttpResponse::Ok().content_type("text/html").body(result)) Ok(HttpResponse::Ok().content_type("text/html").body(result))
} }
#[get("/id/{post_id}")] #[get("/blog/id/{post_id}")]
async fn blog_by_id( async fn blog_by_id(tmpl: web::Data<tera::Tera>, web::Path(post_id): web::Path<std::string::String>) -> Result<HttpResponse, Error> {
tmpl: web::Data<tera::Tera>,
web::Path(post_id): web::Path<std::string::String>,
) -> Result<HttpResponse, Error> {
let (valid, id) = id_valid(post_id); let (valid, id) = id_valid(post_id);
if valid { if valid {
let post = db::get_post_by_id(id as i32); let post = db::get_post_by_id(id as i32);
if !post.published { if !post.published {
return Ok(HttpResponse::new(StatusCode::UNAUTHORIZED)); return Ok(HttpResponse::new(StatusCode::UNAUTHORIZED))
} }
let mut context = Context::new(); let mut context = Context::new();
context.insert("post", &post); context.insert("post", &post);
context.insert( context.insert("username", CONFIG_MAP.read().unwrap().get("USERNAME").unwrap());
"username",
CONFIG_MAP.read().unwrap().get("USERNAME").unwrap(),
);
let result = tmpl let result = tmpl.render("blog-by-id.html", &context)
.render("blog-by-id.html", &context)
.map_err(|_| error::ErrorInternalServerError("Template error"))?; .map_err(|_| error::ErrorInternalServerError("Template error"))?;
return Ok(HttpResponse::Ok().content_type("text/html").body(result)); return Ok(HttpResponse::Ok().content_type("text/html").body(result))
} else { } else {
return Ok(HttpResponse::new(StatusCode::NOT_FOUND)); return Ok(HttpResponse::new(StatusCode::NOT_FOUND))
} }
} }
#[get("/submit")] #[get("/blog/submit")]
async fn blog_submit(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> { async fn blog_submit(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {
let mut context = Context::new(); let mut context = Context::new();
context.insert("title", ""); context.insert("title", "");
context.insert("body", ""); context.insert("body", "");
let result = tmpl let result = tmpl.render("submit.html", &context)
.render("submit.html", &context)
.map_err(|_| error::ErrorInternalServerError("Template error"))?; .map_err(|_| error::ErrorInternalServerError("Template error"))?;
return Ok(HttpResponse::Ok().content_type("text/html").body(result)); return Ok(HttpResponse::Ok().content_type("text/html").body(result))
} }
#[get("/edit")] #[get("/blog/edit")]
async fn blog_edit(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> { async fn blog_edit(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {
let mut context = Context::new(); let mut context = Context::new();
context.insert("posts", &db::get_all_posts()); context.insert("posts", &db::get_all_posts());
context.insert( context.insert("username", CONFIG_MAP.read().unwrap().get("USERNAME").unwrap());
"username",
CONFIG_MAP.read().unwrap().get("USERNAME").unwrap(),
);
let result = tmpl let result = tmpl.render("edit.html", &context)
.render("edit.html", &context)
.map_err(|_| error::ErrorInternalServerError("Template error"))?; .map_err(|_| error::ErrorInternalServerError("Template error"))?;
Ok(HttpResponse::Ok().content_type("text/html").body(result)) Ok(HttpResponse::Ok().content_type("text/html").body(result))
} }
#[get("/edit/{post_id}")] #[get("/blog/edit/{post_id}")]
async fn blog_edit_by_id( async fn blog_edit_by_id(tmpl: web::Data<tera::Tera>, web::Path(post_id): web::Path<std::string::String>) -> Result<HttpResponse, Error> {
tmpl: web::Data<tera::Tera>,
web::Path(post_id): web::Path<std::string::String>,
) -> Result<HttpResponse, Error> {
let (valid, id) = id_valid(post_id); let (valid, id) = id_valid(post_id);
if valid { if valid {
let mut post = db::get_post_by_id(id as i32); let mut post = db::get_post_by_id(id as i32);
@ -176,8 +149,7 @@ async fn blog_edit_by_id(
context.insert("body", &post.body); context.insert("body", &post.body);
context.insert("id", &id); context.insert("id", &id);
let result = tmpl let result = tmpl.render("edit-form.html", &context)
.render("edit-form.html", &context)
.map_err(|_| error::ErrorInternalServerError("Template error"))?; .map_err(|_| error::ErrorInternalServerError("Template error"))?;
Ok(HttpResponse::Ok().content_type("text/html").body(result)) Ok(HttpResponse::Ok().content_type("text/html").body(result))