Compare commits

..

12 commits

Author SHA1 Message Date
Leonard Lorenz
40b9a90bf9 updated docker-compose to use the docker hub image 2021-05-02 19:54:39 +02:00
Leonard Lorenz
16efbc7cb5 Merge branch 'master' of github.com:mtrx1337/crablog 2021-05-02 19:43:07 +02:00
Leonard Lorenz
4e0611d5c2 Updated all dependencies 2021-05-02 19:39:31 +02:00
mtrx
6b0072df97
Updated readme for the new docker hub image 2021-05-02 19:19:23 +02:00
Leonard Lorenz
fda295b8f8 more styling 2021-04-03 23:42:21 +02:00
Leonard Lorenz
e19663d4e6 styling readme 2021-04-03 23:41:04 +02:00
mtrx
59014b5f9c
Merge pull request #4 from SunRed/master
Add compile flag again and update readme/env file
2021-04-03 23:38:45 +02:00
mtrx
787d40fb6b
fixed <id> not showing in route description 2021-04-03 23:30:06 +02:00
Leonard Lorenz
accbdb6f7a Bumped to 0.3.0. Switched /blog routes to / prefix and moved preevious / route to /about. Changed some env var loading code. 2021-04-03 23:27:58 +02:00
mtrx
5c1c0de1b1
we only need sqlite for our diesel_cli 2021-04-02 23:16:07 +02:00
0ab9e12723
Use example from README.md as default crablog.env 2021-02-13 14:13:17 +01:00
015d36ef91
Add change to compile with all threads again
Accidentally removed this on the last commits
Adds change from commit ec86734ea1 again
2021-02-13 14:04:43 +01:00
13 changed files with 307 additions and 166 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 . RUN cargo install --path . -j $(nproc)
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.
## Build instructions using docker ## Run instructions using docker
1. Clone the repository 1. Clone the repository
```bash ```bash
git clone https://github.com/leonardlorenz/crablog git clone https://github.com/mtrx1337/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 cargo install diesel_cli --no-default-features --features "sqlite"
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. Build and run the docker container (Will compile from source and thus take a while) 4. Pull the image (or build from source) and run the docker container
```bash ```bash
docker-compose up -d docker-compose up -d
``` ```
## Configuration environment file ## Configuration environment file
All configuration options are defined in .env, to be created in the same directory as this readme. All configuration options are defined in crablog.env, an example configuration is provided.
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,13 +44,17 @@ ROOT_PATH=/path/to/template/directory/and/sqliteDB
## Routes ## Routes
- / site welcome | Route | Description |
- /blog shows the last 5 posts | ------------ | -------------------------------------------------- |
- /blog/id/<id> shows a single post by id | `/` | shows the last 5 posts |
- /blog/all shows all posts | `/id/<id>` | shows a single post by id |
- /blog/submit set your submit token and create posts | `/all` | shows all posts |
- /blog/edit/<id> edit, delete or hide posts | `/submit` | set your submit token and create posts |
| `/edit/<id>` | edit, delete or hide posts |
| `/about` | information about this blog, social media accounts |
**API Routes** **API Routes**
- /api/blog/posts returns all posts as json | Route | Description |
| ---------------- | ------------------------- |
| `api/blog/posts` | returns all posts as json |

View file

@ -13,9 +13,11 @@
<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>
I have a <a href="/blog">blog.</a><br> This is my blog. If you have questions or input for me please send me an E-Mail to {{ email }}
If you have questions or input for me please send me an E-Mail to {{ email }}
</p> </p>
<br> <br>
<p> <p>

View file

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

View file

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

View file

@ -1,7 +1,8 @@
version: "3.8" version: "3.0"
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.1.0" version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "404df68c297f73b8d36c9c9056404913d25905a8f80127b0e5fe147c9c4b9f02" checksum = "452299e87817ae5673910e53c243484ca38be3828db819b6011736fc6982e874"
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", "rand 0.7.3",
"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.48", "syn 1.0.71",
] ]
[[package]] [[package]]
@ -233,9 +233,9 @@ dependencies = [
[[package]] [[package]]
name = "actix-web" name = "actix-web"
version = "3.2.0" version = "3.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88344b7a5ef27e5e09e73565379f69273dd3e2d29e82afc381b84d170d0a5631" checksum = "e641d4a172e7faa0862241a20ff4f1f5ab0ab7c279f00c2d4587b77483477b86"
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.48", "syn 1.0.71",
] ]
[[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.48", "syn 1.0.71",
] ]
[[package]] [[package]]
@ -335,9 +335,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]] [[package]]
name = "awc" name = "awc"
version = "2.0.1" version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "425980a1e58e5030a3e4b065a3d577c8f0e16142ea9d81f30614eae810c98577" checksum = "b381e490e7b0cfc37ebc54079b0413d8093ef43d14a4e4747083f7fa47a9e691"
dependencies = [ dependencies = [
"actix-codec", "actix-codec",
"actix-http", "actix-http",
@ -351,7 +351,7 @@ dependencies = [
"log", "log",
"mime", "mime",
"percent-encoding", "percent-encoding",
"rand", "rand 0.7.3",
"serde", "serde",
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
@ -572,12 +572,12 @@ checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
[[package]] [[package]]
name = "crablog" name = "crablog"
version = "0.2.3" version = "0.3.1"
dependencies = [ dependencies = [
"actix-files", "actix-files",
"actix-web", "actix-web",
"chrono", "chrono",
"diesel 1.4.5", "diesel 1.4.6",
"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.48", "syn 1.0.71",
] ]
[[package]] [[package]]
@ -636,9 +636,9 @@ dependencies = [
[[package]] [[package]]
name = "diesel" name = "diesel"
version = "1.4.5" version = "1.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e2de9deab977a153492a1468d1b1c0662c1cf39e5ea87d0c060ecd59ef18d8c" checksum = "047bfc4d5c3bd2ef6ca6f981941046113524b9a9f9a7cbdfdd7ff40f58e6f542"
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.48", "syn 1.0.71",
] ]
[[package]] [[package]]
@ -694,12 +694,6 @@ 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"
@ -724,14 +718,14 @@ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.48", "syn 1.0.71",
] ]
[[package]] [[package]]
name = "env_logger" name = "env_logger"
version = "0.8.2" version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26ecb66b4bdca6c1409b40fb255eefc2bd4f6d135dab3c3124f80ffa2a9661e" checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f"
dependencies = [ dependencies = [
"atty", "atty",
"humantime", "humantime",
@ -835,7 +829,7 @@ dependencies = [
"proc-macro-hack", "proc-macro-hack",
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.48", "syn 1.0.71",
] ]
[[package]] [[package]]
@ -912,6 +906,17 @@ 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"
@ -933,9 +938,9 @@ dependencies = [
[[package]] [[package]]
name = "globwalk" name = "globwalk"
version = "0.8.0" 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 = "178270263374052c40502e9f607134947de75302c1348d1a0e31db67c1691446" checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"ignore", "ignore",
@ -1322,9 +1327,9 @@ checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.5.2" version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
[[package]] [[package]]
name = "opaque-debug" name = "opaque-debug"
@ -1408,7 +1413,7 @@ dependencies = [
"pest_meta", "pest_meta",
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.48", "syn 1.0.71",
] ]
[[package]] [[package]]
@ -1448,7 +1453,7 @@ checksum = "65ad2ae56b6abe3a1ee25f15ee605bacadb9a764edaba9c2bf4103800d4a1895"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.48", "syn 1.0.71",
] ]
[[package]] [[package]]
@ -1459,7 +1464,7 @@ checksum = "81a4ffa594b66bff340084d4081df649a7dc049ac8d7fc458d8e628bfbbb2f86"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.48", "syn 1.0.71",
] ]
[[package]] [[package]]
@ -1500,9 +1505,9 @@ checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.24" version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
dependencies = [ dependencies = [
"unicode-xid 0.2.1", "unicode-xid 0.2.1",
] ]
@ -1534,11 +1539,23 @@ 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", "getrandom 0.1.15",
"libc", "libc",
"rand_chacha", "rand_chacha 0.2.2",
"rand_core", "rand_core 0.5.1",
"rand_hc", "rand_hc 0.2.0",
]
[[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]]
@ -1548,7 +1565,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [ dependencies = [
"ppv-lite86", "ppv-lite86",
"rand_core", "rand_core 0.5.1",
]
[[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]]
@ -1557,7 +1584,16 @@ 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", "getrandom 0.1.15",
]
[[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]]
@ -1566,7 +1602,16 @@ 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", "rand_core 0.5.1",
]
[[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]]
@ -1656,22 +1701,22 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.117" version = "1.0.125"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.117" version = "1.0.125"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.48", "syn 1.0.71",
] ]
[[package]] [[package]]
@ -1687,14 +1732,14 @@ dependencies = [
[[package]] [[package]]
name = "serde_urlencoded" name = "serde_urlencoded"
version = "0.6.1" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9"
dependencies = [ dependencies = [
"dtoa", "form_urlencoded",
"itoa", "itoa",
"ryu",
"serde", "serde",
"url",
] ]
[[package]] [[package]]
@ -1803,7 +1848,7 @@ dependencies = [
"quote 1.0.7", "quote 1.0.7",
"serde", "serde",
"serde_derive", "serde_derive",
"syn 1.0.48", "syn 1.0.71",
] ]
[[package]] [[package]]
@ -1819,7 +1864,7 @@ dependencies = [
"serde_derive", "serde_derive",
"serde_json", "serde_json",
"sha1", "sha1",
"syn 1.0.48", "syn 1.0.71",
] ]
[[package]] [[package]]
@ -1841,9 +1886,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.48" version = "1.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac" checksum = "ad184cc9470f9117b2ac6817bfe297307418819ba40552f9b3846f05c33d5373"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
@ -1861,9 +1906,9 @@ dependencies = [
[[package]] [[package]]
name = "tera" name = "tera"
version = "1.5.0" version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1381c83828bedd5ce4e59473110afa5381ffe523406d9ade4b77c9f7be70ff9a" checksum = "b64b021b8d3ab1f59ceae9e6cd1c26c8e7ce0322a9ebfff6c0e22b3b66938935"
dependencies = [ dependencies = [
"chrono", "chrono",
"chrono-tz", "chrono-tz",
@ -1873,7 +1918,7 @@ dependencies = [
"percent-encoding", "percent-encoding",
"pest", "pest",
"pest_derive", "pest_derive",
"rand", "rand 0.8.3",
"regex", "regex",
"serde", "serde",
"serde_json", "serde_json",
@ -1907,7 +1952,7 @@ checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.48", "syn 1.0.71",
] ]
[[package]] [[package]]
@ -1974,7 +2019,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"standback", "standback",
"syn 1.0.48", "syn 1.0.71",
] ]
[[package]] [[package]]
@ -2070,7 +2115,7 @@ dependencies = [
"idna", "idna",
"lazy_static", "lazy_static",
"log", "log",
"rand", "rand 0.7.3",
"smallvec", "smallvec",
"thiserror", "thiserror",
"tokio", "tokio",
@ -2218,9 +2263,9 @@ dependencies = [
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "0.8.1" 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 = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
dependencies = [ dependencies = [
"serde", "serde",
"sha1", "sha1",
@ -2245,7 +2290,7 @@ dependencies = [
"nom", "nom",
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.48", "syn 1.0.71",
] ]
[[package]] [[package]]
@ -2320,7 +2365,7 @@ dependencies = [
"log", "log",
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.48", "syn 1.0.71",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -2342,7 +2387,7 @@ checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.7", "quote 1.0.7",
"syn 1.0.48", "syn 1.0.71",
"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.2.3" version = "0.3.1"
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.2.0" actix-web = "3.3.2"
actix-files = "0.4.0" actix-files = "0.4.0"
serde = { version = "1.0.117", features = ["derive"] } serde = { version = "1.0.125", features = ["derive"] }
serde_json = "1.0.59" serde_json = "*"
serde_derive = "1.0.117" serde_derive = "*"
diesel = { version = "1.4.5", default-features = false, features = ["sqlite", "chrono"] } diesel = { version = "1.4.6", 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.1", features = ["serde", "v5"] } uuid = { version = "0.8.2", features = ["serde", "v5"] }
tera = "1.5.0" tera = "1.8.0"
once_cell = "1.5.2" once_cell = "1.7.2"
env_logger = "0.8.2" env_logger = "0.8.3"

View file

@ -9,50 +9,89 @@ extern crate serde_derive;
extern crate tera; extern crate tera;
use actix_files as fs; use actix_files as fs;
use actix_web::{App, HttpServer, middleware::Logger}; use actix_web::{middleware::Logger, App, HttpServer};
use env_logger::Env; use env_logger::Env;
use tera::Tera;
use std::{env, sync::RwLock, collections::HashMap};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::{collections::HashMap, env, sync::RwLock};
use tera::Tera;
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."));
config.insert(String::from("ROOT_PATH"), env::var("ROOT_PATH").expect("ROOT_PATH variable not set.")); let required_env_vars = [
config.insert(String::from("USERNAME"), env::var("USERNAME").expect("USERNAME variable not set.")); "SUBMIT_TOKEN",
config.insert(String::from("EMAIL"), env::var("EMAIL").expect("EMAIL variable not set.")); "ROOT_PATH",
config.insert(String::from("BIND_PORT"), env::var("BIND_PORT").expect("BIND_PORT variable not set.")); "USERNAME",
if let Ok(acc) = env::var("GITHUB_ACCOUNT") { "EMAIL",
config.insert(String::from("GITHUB_ACCOUNT"), acc.clone()); "BIND_PORT",
];
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") {
config.insert(String::from("TWITTER_ACCOUNT"), acc.clone()); // Test if variable is set. If it is insert into config.
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() {
if let Ok(acc) = env::var("DISCORD_ACCOUNT") { insert_optional_env(var);
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(
let mut tera = Tera::new(format!("{}{}", CONFIG_MAP.read().unwrap().get("ROOT_PATH").unwrap(), "/templates/*").as_str()).unwrap(); format!(
"{}{}",
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::root) .service(routes::about)
.service(routes::blog) .service(routes::blog)
.service(routes::blog_all) .service(routes::blog_all)
.service(routes::blog_by_id) .service(routes::blog_by_id)
@ -64,10 +103,20 @@ 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("/static", format!("{}{}", CONFIG_MAP.read().unwrap().get("ROOT_PATH").unwrap(), "/static"))) .service(fs::Files::new(
"/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!("0.0.0.0:{}", CONFIG_MAP.read().unwrap().get("BIND_PORT").unwrap()))? .bind(format!(
"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 actix_web::{get, http::StatusCode, web, HttpResponse, Error, error};
use tera::Context;
use super::CONFIG_MAP; use super::CONFIG_MAP;
use actix_web::{error, get, http::StatusCode, web, Error, HttpResponse};
use tera::Context;
/// 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,10 +33,13 @@ pub fn replace_br_tags(x: &str) -> String {
x.replace("<br>", "\n") x.replace("<br>", "\n")
} }
#[get("/")] #[get("/about")]
async fn root(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> { async fn about(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {
let mut context = Context::new(); let mut context = Context::new();
context.insert("username", CONFIG_MAP.read().unwrap().get("USERNAME").unwrap()); context.insert(
"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);
@ -54,89 +57,113 @@ async fn root(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {
context.insert("reddit_account", acc); context.insert("reddit_account", acc);
} }
let result = tmpl.render("index.html", &context) let result = tmpl
.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("/blog")] #[get("/")]
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("username", CONFIG_MAP.read().unwrap().get("USERNAME").unwrap()); context.insert(
"username",
CONFIG_MAP.read().unwrap().get("USERNAME").unwrap(),
);
let result = tmpl.render("blog.html", &context) let result = tmpl
.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("/blog/all")] #[get("/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("username", CONFIG_MAP.read().unwrap().get("USERNAME").unwrap()); context.insert(
"username",
CONFIG_MAP.read().unwrap().get("USERNAME").unwrap(),
);
let result = tmpl.render("blog-all-posts.html", &context) let result = tmpl
.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("/blog/id/{post_id}")] #[get("/id/{post_id}")]
async fn blog_by_id(tmpl: web::Data<tera::Tera>, web::Path(post_id): web::Path<std::string::String>) -> Result<HttpResponse, Error> { async fn blog_by_id(
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("username", CONFIG_MAP.read().unwrap().get("USERNAME").unwrap()); context.insert(
"username",
CONFIG_MAP.read().unwrap().get("USERNAME").unwrap(),
);
let result = tmpl.render("blog-by-id.html", &context) let result = tmpl
.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("/blog/submit")] #[get("/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.render("submit.html", &context) let result = tmpl
.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("/blog/edit")] #[get("/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("username", CONFIG_MAP.read().unwrap().get("USERNAME").unwrap()); context.insert(
"username",
CONFIG_MAP.read().unwrap().get("USERNAME").unwrap(),
);
let result = tmpl.render("edit.html", &context) let result = tmpl
.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("/blog/edit/{post_id}")] #[get("/edit/{post_id}")]
async fn blog_edit_by_id(tmpl: web::Data<tera::Tera>, web::Path(post_id): web::Path<std::string::String>) -> Result<HttpResponse, Error> { async fn blog_edit_by_id(
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);
@ -149,7 +176,8 @@ async fn blog_edit_by_id(tmpl: web::Data<tera::Tera>, web::Path(post_id): web::P
context.insert("body", &post.body); context.insert("body", &post.body);
context.insert("id", &id); context.insert("id", &id);
let result = tmpl.render("edit-form.html", &context) let result = tmpl
.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))