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
COPY ./site .
RUN apk add --no-cache musl-dev sqlite-dev
RUN cargo install --path .
RUN cargo install --path . -j $(nproc)
FROM alpine:latest

View file

@ -2,31 +2,31 @@
Pure rust. Built with actix, diesel, tera, serde and sqlite3.
## Build instructions using docker
## Run instructions using docker
1. Clone the repository
```bash
git clone https://github.com/leonardlorenz/crablog
git clone https://github.com/mtrx1337/crablog
cd crablog/site
```
2. Install diesel and create a database
```bash
cargo install diesel_cli
cargo install diesel_cli --no-default-features --features "sqlite"
diesel setup --database-url ../content/db.sqlite3
diesel migration run --database-url ../content/db.sqlite3
```
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
docker-compose up -d
```
## Configuration environment file
All configuration options are defined in .env, to be created in the same directory as this readme.
An example configuration:
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.
`crablog.env`
```
USERNAME=yourusername
EMAIL=me@mydomain.tld
@ -44,13 +44,17 @@ ROOT_PATH=/path/to/template/directory/and/sqliteDB
## Routes
- / site welcome
- /blog shows the last 5 posts
- /blog/id/<id> shows a single post by id
- /blog/all shows all posts
- /blog/submit set your submit token and create posts
- /blog/edit/<id> edit, delete or hide posts
| Route | Description |
| ------------ | -------------------------------------------------- |
| `/` | shows the last 5 posts |
| `/id/<id>` | shows a single post by id |
| `/all` | shows all 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/blog/posts returns all posts as json
| Route | Description |
| ---------------- | ------------------------- |
| `api/blog/posts` | returns all posts as json |

View file

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

View file

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

View file

@ -13,12 +13,16 @@
</head>
<body>
<h1><a href="/blog" 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>
<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="/about">About</a>
<a href="/all">All Posts</a>
</p>
<ul>
<article>
<div>
<a href="/blog/id/{{ post.id }}" class="post-link">[link]</a>
<a href="/id/{{ post.id }}" class="post-link">[link]</a>
</div>
<div class="post-content">
<h2 class="post-title">{{ post.title }}</h2>

View file

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

View file

@ -11,11 +11,11 @@
<link rel="shortcut icon" type="image/jpg" href="/static/favicon.ico"/>
</head>
<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>
<ul style="list-style: none;">
{% 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 %}
</ul>
</body>

View file

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

View file

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

179
site/Cargo.lock generated
View file

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

View file

@ -1,6 +1,6 @@
[package]
name = "crablog"
version = "0.2.3"
version = "0.3.1"
authors = ["Leonard Lorenz <dev@leonardlorenz.de>"]
edition = "2018"
@ -8,20 +8,20 @@ edition = "2018"
[dependencies]
chrono = { version = "*", features = ["serde"] }
actix-web = "3.2.0"
actix-web = "3.3.2"
actix-files = "0.4.0"
serde = { version = "1.0.117", features = ["derive"] }
serde_json = "1.0.59"
serde_derive = "1.0.117"
serde = { version = "1.0.125", features = ["derive"] }
serde_json = "*"
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 }
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;
use actix_files as fs;
use actix_web::{App, HttpServer, middleware::Logger};
use actix_web::{middleware::Logger, App, HttpServer};
use env_logger::Env;
use tera::Tera;
use std::{env, sync::RwLock, collections::HashMap};
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(|| {
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."));
config.insert(String::from("USERNAME"), env::var("USERNAME").expect("USERNAME variable not set."));
config.insert(String::from("EMAIL"), env::var("EMAIL").expect("EMAIL variable not set."));
config.insert(String::from("BIND_PORT"), env::var("BIND_PORT").expect("BIND_PORT variable not set."));
if let Ok(acc) = env::var("GITHUB_ACCOUNT") {
config.insert(String::from("GITHUB_ACCOUNT"), acc.clone());
let required_env_vars = [
"SUBMIT_TOKEN",
"ROOT_PATH",
"USERNAME",
"EMAIL",
"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());
}
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());
};
for var in optional_env_vars.iter() {
insert_optional_env(var);
}
// 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)
});
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
let mut tera = Tera::new(format!("{}{}", CONFIG_MAP.read().unwrap().get("ROOT_PATH").unwrap(), "/templates/*").as_str()).unwrap();
let mut tera = Tera::new(
format!(
"{}{}",
CONFIG_MAP.read().unwrap().get("ROOT_PATH").unwrap(),
"/templates/*"
)
.as_str(),
)
.unwrap();
tera.autoescape_on(vec![".sql"]);
env_logger::Builder::from_env(Env::default().default_filter_or("info"));
App::new()
.data(tera)
.service(routes::root)
.service(routes::about)
.service(routes::blog)
.service(routes::blog_all)
.service(routes::blog_by_id)
@ -64,10 +103,20 @@ async fn main() -> std::io::Result<()> {
.service(api::blog_edit_post)
.service(api::blog_hide_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"))
})
.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()
.await
}

View file

@ -1,8 +1,8 @@
use crate::db;
use actix_web::{get, http::StatusCode, web, HttpResponse, Error, error};
use tera::Context;
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
/// assert(!(id_valid("2147483648").0))
@ -33,10 +33,13 @@ pub fn replace_br_tags(x: &str) -> String {
x.replace("<br>", "\n")
}
#[get("/")]
async fn root(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {
#[get("/about")]
async fn about(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {
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());
if let Some(acc) = CONFIG_MAP.read().unwrap().get("GITHUB_ACCOUNT") {
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);
}
let result = tmpl.render("index.html", &context)
let result = tmpl
.render("about.html", &context)
.map_err(|e| error::ErrorInternalServerError(format!("Template error\n{}", e)))?;
Ok(HttpResponse::Ok().content_type("text/html").body(result))
}
#[get("/blog")]
#[get("/")]
async fn blog(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {
let posts = db::get_last_five_posts();
let mut context = Context::new();
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"))?;
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> {
let posts = db::get_all_posts();
let mut context = Context::new();
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"))?;
Ok(HttpResponse::Ok().content_type("text/html").body(result))
}
#[get("/blog/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> {
#[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> {
let (valid, id) = id_valid(post_id);
if valid {
let post = db::get_post_by_id(id as i32);
if !post.published {
return Ok(HttpResponse::new(StatusCode::UNAUTHORIZED))
return Ok(HttpResponse::new(StatusCode::UNAUTHORIZED));
}
let mut context = Context::new();
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"))?;
return Ok(HttpResponse::Ok().content_type("text/html").body(result))
return Ok(HttpResponse::Ok().content_type("text/html").body(result));
} 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> {
let mut context = Context::new();
context.insert("title", "");
context.insert("body", "");
let result = tmpl.render("submit.html", &context)
let result = tmpl
.render("submit.html", &context)
.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> {
let mut context = Context::new();
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"))?;
Ok(HttpResponse::Ok().content_type("text/html").body(result))
}
#[get("/blog/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> {
#[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> {
let (valid, id) = id_valid(post_id);
if valid {
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("id", &id);
let result = tmpl.render("edit-form.html", &context)
let result = tmpl
.render("edit-form.html", &context)
.map_err(|_| error::ErrorInternalServerError("Template error"))?;
Ok(HttpResponse::Ok().content_type("text/html").body(result))