From c3dade257d9446ae4d507ef7234bb10f68614978 Mon Sep 17 00:00:00 2001
From: Nick Lowery
Date: Mon, 16 May 2022 21:11:01 -0600
Subject: [PATCH 01/22] Restore post sorting preference by link (#406)
---
templates/settings.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/templates/settings.html b/templates/settings.html
index 8a70912..3669d88 100644
--- a/templates/settings.html
+++ b/templates/settings.html
@@ -110,7 +110,7 @@
Note: settings and subscriptions are saved in browser cookies. Clearing your cookies will reset them.
-
You can restore your current settings and subscriptions after clearing your cookies using this link.
+
You can restore your current settings and subscriptions after clearing your cookies using this link.
From 3bdc21f90a6aefd3759227006efb0e320729d51b Mon Sep 17 00:00:00 2001
From: Spike <19519553+spikecodes@users.noreply.github.com>
Date: Tue, 17 May 2022 03:12:03 +0000
Subject: [PATCH 02/22] Remove silkky.cloud instance. Closes #510
---
README.md | 1 -
1 file changed, 1 deletion(-)
diff --git a/README.md b/README.md
index adfd157..8d20782 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,6 @@ Feel free to [open an issue](https://github.com/spikecodes/libreddit/issues/new)
| [reddit.invak.id](https://reddit.invak.id) | 🇧🇬 BG | |
| [reddit.phii.me](https://reddit.phii.me) | 🇺🇸 US | |
| [lr.riverside.rocks](https://lr.riverside.rocks) | 🇺🇸 US | |
-| [libreddit.silkky.cloud](https://libreddit.silkky.cloud) | 🇫🇮 FI | ✅ |
| [libreddit.strongthany.cc](https://libreddit.strongthany.cc) | 🇺🇸 US | |
| [libreddit.database.red](https://libreddit.database.red) | 🇺🇸 US | ✅ |
| [libreddit.privacy.com.de](https://libreddit.privacy.com.de) | 🇩🇪 DE | |
From 1c8bcf33c16e5d6467091074c2d2545d41aca7e3 Mon Sep 17 00:00:00 2001
From: BobIsMyManager
Date: Wed, 18 May 2022 04:30:51 +0000
Subject: [PATCH 03/22] Made .onion instance url consistant (#511)
Without `http://`, it may have caused problems for libredirect
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 8d20782..48dea6b 100644
--- a/README.md
+++ b/README.md
@@ -105,7 +105,7 @@ Feel free to [open an issue](https://github.com/spikecodes/libreddit/issues/new)
| [ol5begilptoou34emq2sshf3may3hlblvipdjtybbovpb7c7zodxmtqd.onion](http://ol5begilptoou34emq2sshf3may3hlblvipdjtybbovpb7c7zodxmtqd.onion) | 🇩🇪 DE | |
| [lbrdtjaj7567ptdd4rv74lv27qhxfkraabnyphgcvptl64ijx2tijwid.onion](http://lbrdtjaj7567ptdd4rv74lv27qhxfkraabnyphgcvptl64ijx2tijwid.onion) | 🇨🇦 CA | |
| [libreddit.lqs5fjmajyp7rvp4qvyubwofzi6d4imua7vs237rkc4m5qogitqwrgyd.onion](http://libreddit.lqs5fjmajyp7rvp4qvyubwofzi6d4imua7vs237rkc4m5qogitqwrgyd.onion) | 🇨🇦 CA | |
-| [reddit.prnoid54e44a4bduq5due64jkk7wcnkxcp5kv3juncm7veptjcqudgyd.onion](reddit.prnoid54e44a4bduq5due64jkk7wcnkxcp5kv3juncm7veptjcqudgyd.onion) | 🇨🇠CH | |
+| [reddit.prnoid54e44a4bduq5due64jkk7wcnkxcp5kv3juncm7veptjcqudgyd.onion](http://reddit.prnoid54e44a4bduq5due64jkk7wcnkxcp5kv3juncm7veptjcqudgyd.onion) | 🇨🇠CH | |
A checkmark in the "Cloudflare" category here refers to the use of the reverse proxy, [Cloudflare](https://cloudflare.com). The checkmark will not be listed for a site that uses Cloudflare DNS but rather the proxying service which grants Cloudflare the ability to monitor traffic to the website.
From 60c7b6b23fcbbe77f36d12040195e4a04e40a606 Mon Sep 17 00:00:00 2001
From: mikupls <93015331+mikupls@users.noreply.github.com>
Date: Sat, 21 May 2022 03:41:31 +0200
Subject: [PATCH 04/22] Embed css themes to simplify adding and testing new
themes (#489)
---
Cargo.lock | 126 ++++++++++++++++++++++++++++++++++++
Cargo.toml | 1 +
src/main.rs | 21 +++++-
src/utils.rs | 15 +++++
static/style.css | 119 +---------------------------------
static/themes/black.css | 14 ++++
static/themes/dracula.css | 14 ++++
static/themes/gold.css | 14 ++++
static/themes/laserwave.css | 14 ++++
static/themes/light.css | 14 ++++
static/themes/nord.css | 14 ++++
static/themes/rosebox.css | 13 ++++
static/themes/violet.css | 14 ++++
templates/settings.html | 2 +-
14 files changed, 274 insertions(+), 121 deletions(-)
create mode 100644 static/themes/black.css
create mode 100644 static/themes/dracula.css
create mode 100644 static/themes/gold.css
create mode 100644 static/themes/laserwave.css
create mode 100644 static/themes/light.css
create mode 100644 static/themes/nord.css
create mode 100644 static/themes/rosebox.css
create mode 100644 static/themes/violet.css
diff --git a/Cargo.lock b/Cargo.lock
index 58439fa..dea7b0c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -100,6 +100,15 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+[[package]]
+name = "block-buffer"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
+dependencies = [
+ "generic-array",
+]
+
[[package]]
name = "bumpalo"
version = "3.9.1"
@@ -207,6 +216,15 @@ version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
+[[package]]
+name = "cpufeatures"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "darling"
version = "0.13.4"
@@ -242,6 +260,15 @@ dependencies = [
"syn",
]
+[[package]]
+name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array",
+]
+
[[package]]
name = "fastrand"
version = "1.7.0"
@@ -371,6 +398,16 @@ dependencies = [
"slab",
]
+[[package]]
+name = "generic-array"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
[[package]]
name = "h2"
version = "0.3.13"
@@ -561,6 +598,7 @@ dependencies = [
"hyper-rustls",
"regex",
"route-recognizer",
+ "rust-embed",
"serde",
"serde_json",
"time",
@@ -668,6 +706,12 @@ version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
+[[package]]
+name = "opaque-debug"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+
[[package]]
name = "openssl-probe"
version = "0.1.5"
@@ -792,6 +836,40 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746"
+[[package]]
+name = "rust-embed"
+version = "6.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a17e5ac65b318f397182ae94e532da0ba56b88dd1200b774715d36c4943b1c3"
+dependencies = [
+ "rust-embed-impl",
+ "rust-embed-utils",
+ "walkdir",
+]
+
+[[package]]
+name = "rust-embed-impl"
+version = "6.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94e763e24ba2bf0c72bc6be883f967f794a019fafd1b86ba1daff9c91a7edd30"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "rust-embed-utils",
+ "syn",
+ "walkdir",
+]
+
+[[package]]
+name = "rust-embed-utils"
+version = "7.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "756feca3afcbb1487a1d01f4ecd94cf8ec98ea074c55a69e7136d29fb6166029"
+dependencies = [
+ "sha2",
+ "walkdir",
+]
+
[[package]]
name = "rustls"
version = "0.20.5"
@@ -831,6 +909,15 @@ version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
[[package]]
name = "schannel"
version = "0.1.19"
@@ -911,6 +998,19 @@ dependencies = [
"serde",
]
+[[package]]
+name = "sha2"
+version = "0.9.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
+dependencies = [
+ "block-buffer",
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+ "opaque-debug",
+]
+
[[package]]
name = "signal-hook-registry"
version = "1.4.0"
@@ -1124,6 +1224,12 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
+[[package]]
+name = "typenum"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
+
[[package]]
name = "unicase"
version = "2.6.0"
@@ -1184,6 +1290,17 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
+[[package]]
+name = "walkdir"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
+dependencies = [
+ "same-file",
+ "winapi",
+ "winapi-util",
+]
+
[[package]]
name = "want"
version = "0.3.0"
@@ -1290,6 +1407,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
diff --git a/Cargo.toml b/Cargo.toml
index b55c1d1..0745fb4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -23,3 +23,4 @@ serde_json = "1.0.81"
tokio = { version = "1.18.2", features = ["full"] }
time = "0.3.9"
url = "2.2.2"
+rust-embed="6.4.0"
diff --git a/src/main.rs b/src/main.rs
index 7efa558..dc78a0b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -19,7 +19,7 @@ use hyper::{header::HeaderValue, Body, Request, Response};
mod client;
use client::proxy;
use server::RequestExt;
-use utils::{error, redirect};
+use utils::{error, redirect, ThemeAssets};
mod server;
@@ -85,6 +85,23 @@ async fn resource(body: &str, content_type: &str, cache: bool) -> Result Result, String> {
+ let mut res = include_str!("../static/style.css").to_string();
+ for file in ThemeAssets::iter() {
+ res.push_str("\n");
+ let theme = ThemeAssets::get(file.as_ref()).unwrap();
+ res.push_str(std::str::from_utf8(theme.data.as_ref()).unwrap());
+ }
+ Ok(
+ Response::builder()
+ .status(200)
+ .header("content-type", "text/css")
+ .header("Cache-Control", "public, max-age=1209600, s-maxage=86400")
+ .body(res.to_string().into())
+ .unwrap_or_default(),
+ )
+}
+
#[tokio::main]
async fn main() {
let matches = Command::new("Libreddit")
@@ -152,7 +169,7 @@ async fn main() {
}
// Read static files
- app.at("/style.css").get(|_| resource(include_str!("../static/style.css"), "text/css", false).boxed());
+ app.at("/style.css").get(|_| style().boxed());
app
.at("/manifest.json")
.get(|_| resource(include_str!("../static/manifest.json"), "application/json", false).boxed());
diff --git a/src/utils.rs b/src/utils.rs
index 56a7de7..419e384 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -11,6 +11,7 @@ use std::collections::{HashMap, HashSet};
use std::str::FromStr;
use time::{Duration, OffsetDateTime, macros::format_description};
use url::Url;
+use rust_embed::RustEmbed;
// Post flair with content, background color and foreground color
pub struct Flair {
@@ -445,6 +446,7 @@ pub struct Params {
#[derive(Default)]
pub struct Preferences {
+ pub available_themes: Vec,
pub theme: String,
pub front_page: String,
pub layout: String,
@@ -459,10 +461,23 @@ pub struct Preferences {
pub filters: Vec,
}
+#[derive(RustEmbed)]
+#[folder = "static/themes/"]
+#[include = "*.css"]
+pub struct ThemeAssets;
+
impl Preferences {
// Build preferences from cookies
pub fn new(req: Request) -> Self {
+ // Read available theme names from embedded css files.
+ // Always make the default "system" theme available.
+ let mut themes = vec!["system".to_string()];
+ for file in ThemeAssets::iter() {
+ let chunks: Vec<&str> = file.as_ref().split(".css").collect();
+ themes.push(chunks[0].to_owned())
+ }
Self {
+ available_themes: themes,
theme: setting(&req, "theme"),
front_page: setting(&req, "front_page"),
layout: setting(&req, "layout"),
diff --git a/static/style.css b/static/style.css
index dc2a6de..664caee 100644
--- a/static/style.css
+++ b/static/style.css
@@ -45,124 +45,7 @@
}
}
-/* Light theme setting */
-.light {
- --accent: #009a9a;
- --green: #00a229;
- --text: black;
- --foreground: #f5f5f5;
- --background: #ddd;
- --outside: #ececec;
- --post: #eee;
- --panel-border: 1px solid #ccc;
- --highlighted: white;
- --visited: #555;
- --shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
-}
-
-/* Black theme setting */
-.black {
- --accent: #009a9a;
- --green: #00a229;
- --text: white;
- --foreground: #0f0f0f;
- --background: black;
- --outside: black;
- --post: black;
- --panel-border: 2px solid #0f0f0f;
- --highlighted: #0f0f0f;
- --visited: #aaa;
- --shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
-}
-
-/* Dracula theme setting */
-.dracula {
- --accent: #bd93f9;
- --green: #50fa7b;
- --text: #f8f8f2;
- --foreground: #3d4051;
- --background: #282a36;
- --outside: #393c4d;
- --post: #333544;
- --panel-border: 2px solid #44475a;
- --highlighted: #4e5267;
- --visited: #969692;
- --shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
-}
-
-/* Nord theme setting */
-.nord {
- --accent: #8fbcbb;
- --green: #a3be8c;
- --text: #eceff4;
- --foreground: #3b4252;
- --background: #2e3440;
- --outside: #434c5e;
- --post: #434c5e;
- --panel-border: 2px solid #4c566a;
- --highlighted: #3b4252;
- --visited: #a3a5aa;
- --shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
-}
-
-/* Laserwave theme setting */
-.laserwave {
- --accent: #eb64b9;
- --green: #74dfc4;
- --text: #e0dfe1;
- --foreground: #302a36;
- --background: #27212e;
- --outside: #3e3647;
- --post: #3e3647;
- --panel-border: 2px solid #2f2738;
- --highlighted: #302a36;
- --visited: #91889b;
- --shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
-}
-
-/* Violet theme setting */
-.violet {
- --accent: #7c71dd;
- --green: #5cff85;
- --text: white;
- --foreground: #1F2347;
- --background: #12152b;
- --outside: #181c3a;
- --post: #181c3a;
- --panel-border: 1px solid #1F2347;
- --highlighted: #1F2347;
- --visited: #aaa;
- --shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
-}
-
-/* Gold theme setting */
-.gold {
- --accent: #f2aa4c;
- --green: #5cff85;
- --text: white;
- --foreground: #234;
- --background: #101820;
- --outside: #1b2936;
- --post: #1b2936;
- --panel-border: 0px solid black;
- --highlighted: #234;
- --visited: #aaa;
- --shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
-}
-
-/* Rosebox theme setting */
-.rosebox {
- --accent: #a57562;
- --green: #a3be8c;
- --text: white;
- --foreground: #222;
- --background: #262626;
- --outside: #222;
- --post: #222;
- --panel-border: 1px solid #222;
- --highlighted: #262626;
- --shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
-}
+/* Other themes are located in the "themes" folder */
/* General */
diff --git a/static/themes/black.css b/static/themes/black.css
new file mode 100644
index 0000000..5906b5b
--- /dev/null
+++ b/static/themes/black.css
@@ -0,0 +1,14 @@
+/* Black theme setting */
+.black {
+ --accent: #009a9a;
+ --green: #00a229;
+ --text: white;
+ --foreground: #0f0f0f;
+ --background: black;
+ --outside: black;
+ --post: black;
+ --panel-border: 2px solid #0f0f0f;
+ --highlighted: #0f0f0f;
+ --visited: #aaa;
+ --shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+}
\ No newline at end of file
diff --git a/static/themes/dracula.css b/static/themes/dracula.css
new file mode 100644
index 0000000..0e36e2b
--- /dev/null
+++ b/static/themes/dracula.css
@@ -0,0 +1,14 @@
+/* Dracula theme setting */
+.dracula {
+ --accent: #bd93f9;
+ --green: #50fa7b;
+ --text: #f8f8f2;
+ --foreground: #3d4051;
+ --background: #282a36;
+ --outside: #393c4d;
+ --post: #333544;
+ --panel-border: 2px solid #44475a;
+ --highlighted: #4e5267;
+ --visited: #969692;
+ --shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+}
\ No newline at end of file
diff --git a/static/themes/gold.css b/static/themes/gold.css
new file mode 100644
index 0000000..4ff7d6e
--- /dev/null
+++ b/static/themes/gold.css
@@ -0,0 +1,14 @@
+/* Gold theme setting */
+.gold {
+ --accent: #f2aa4c;
+ --green: #5cff85;
+ --text: white;
+ --foreground: #234;
+ --background: #101820;
+ --outside: #1b2936;
+ --post: #1b2936;
+ --panel-border: 0px solid black;
+ --highlighted: #234;
+ --visited: #aaa;
+ --shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
+}
\ No newline at end of file
diff --git a/static/themes/laserwave.css b/static/themes/laserwave.css
new file mode 100644
index 0000000..dde21f3
--- /dev/null
+++ b/static/themes/laserwave.css
@@ -0,0 +1,14 @@
+/* Laserwave theme setting */
+.laserwave {
+ --accent: #eb64b9;
+ --green: #74dfc4;
+ --text: #e0dfe1;
+ --foreground: #302a36;
+ --background: #27212e;
+ --outside: #3e3647;
+ --post: #3e3647;
+ --panel-border: 2px solid #2f2738;
+ --highlighted: #302a36;
+ --visited: #91889b;
+ --shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+}
\ No newline at end of file
diff --git a/static/themes/light.css b/static/themes/light.css
new file mode 100644
index 0000000..1fe0387
--- /dev/null
+++ b/static/themes/light.css
@@ -0,0 +1,14 @@
+/* Light theme setting */
+.light {
+ --accent: #009a9a;
+ --green: #00a229;
+ --text: black;
+ --foreground: #f5f5f5;
+ --background: #ddd;
+ --outside: #ececec;
+ --post: #eee;
+ --panel-border: 1px solid #ccc;
+ --highlighted: white;
+ --visited: #555;
+ --shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+}
\ No newline at end of file
diff --git a/static/themes/nord.css b/static/themes/nord.css
new file mode 100644
index 0000000..d75fd11
--- /dev/null
+++ b/static/themes/nord.css
@@ -0,0 +1,14 @@
+/* Nord theme setting */
+.nord {
+ --accent: #8fbcbb;
+ --green: #a3be8c;
+ --text: #eceff4;
+ --foreground: #3b4252;
+ --background: #2e3440;
+ --outside: #434c5e;
+ --post: #434c5e;
+ --panel-border: 2px solid #4c566a;
+ --highlighted: #3b4252;
+ --visited: #a3a5aa;
+ --shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+}
diff --git a/static/themes/rosebox.css b/static/themes/rosebox.css
new file mode 100644
index 0000000..903931d
--- /dev/null
+++ b/static/themes/rosebox.css
@@ -0,0 +1,13 @@
+/* Rosebox theme setting */
+.rosebox {
+ --accent: #a57562;
+ --green: #a3be8c;
+ --text: white;
+ --foreground: #222;
+ --background: #262626;
+ --outside: #222;
+ --post: #222;
+ --panel-border: 1px solid #222;
+ --highlighted: #262626;
+ --shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
+}
\ No newline at end of file
diff --git a/static/themes/violet.css b/static/themes/violet.css
new file mode 100644
index 0000000..0d836ee
--- /dev/null
+++ b/static/themes/violet.css
@@ -0,0 +1,14 @@
+/* Violet theme setting */
+.violet {
+ --accent: #7c71dd;
+ --green: #5cff85;
+ --text: white;
+ --foreground: #1F2347;
+ --background: #12152b;
+ --outside: #181c3a;
+ --post: #181c3a;
+ --panel-border: 1px solid #1F2347;
+ --highlighted: #1F2347;
+ --visited: #aaa;
+ --shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
+}
\ No newline at end of file
diff --git a/templates/settings.html b/templates/settings.html
index 3669d88..60ee109 100644
--- a/templates/settings.html
+++ b/templates/settings.html
@@ -15,7 +15,7 @@
From 0ec8e4e9a22d9a5e2586b740c06e7fa490b1e688 Mon Sep 17 00:00:00 2001
From: erdnaxe
Date: Sat, 21 May 2022 03:48:32 +0200
Subject: [PATCH 05/22] Harden Systemd configuration (#453)
---
contrib/libreddit.service | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/contrib/libreddit.service b/contrib/libreddit.service
index b6e6fef..8ed5da7 100644
--- a/contrib/libreddit.service
+++ b/contrib/libreddit.service
@@ -11,5 +11,27 @@ Environment=PORT=8080
EnvironmentFile=-/etc/libreddit.conf
ExecStart=/usr/bin/libreddit -a ${ADDRESS} -p ${PORT}
+# Hardening
+DeviceAllow=
+LockPersonality=yes
+MemoryDenyWriteExecute=yes
+PrivateDevices=yes
+ProcSubset=pid
+ProtectClock=yes
+ProtectControlGroups=yes
+ProtectHome=yes
+ProtectHostname=yes
+ProtectKernelLogs=yes
+ProtectKernelModules=yes
+ProtectKernelTunables=yes
+ProtectProc=invisible
+RestrictAddressFamilies=AF_INET AF_INET6
+RestrictNamespaces=yes
+RestrictRealtime=yes
+RestrictSUIDSGID=yes
+SystemCallArchitectures=native
+SystemCallFilter=@system-service ~@privileged ~@resources
+UMask=0077
+
[Install]
WantedBy=default.target
From 428dc58e3c233575b03884ace6003e3c0bfca1c9 Mon Sep 17 00:00:00 2001
From: spikecodes <19519553+spikecodes@users.noreply.github.com>
Date: Fri, 20 May 2022 19:20:44 -0700
Subject: [PATCH 06/22] Update to v0.22.8
---
Cargo.lock | 64 ++++++++++++++++++++++++------------------------
Cargo.toml | 6 ++---
src/main.rs | 4 +--
src/post.rs | 10 ++++++--
src/subreddit.rs | 2 +-
src/user.rs | 2 +-
src/utils.rs | 42 +++++++++++++++----------------
7 files changed, 68 insertions(+), 62 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index dea7b0c..dbef214 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -461,9 +461,9 @@ dependencies = [
[[package]]
name = "http-body"
-version = "0.4.4"
+version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6"
+checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
dependencies = [
"bytes",
"http",
@@ -559,9 +559,9 @@ dependencies = [
[[package]]
name = "itoa"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
+checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
[[package]]
name = "js-sys"
@@ -580,13 +580,13 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
-version = "0.2.125"
+version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
+checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]]
name = "libreddit"
-version = "0.22.7"
+version = "0.22.8"
dependencies = [
"askama",
"async-recursion",
@@ -702,9 +702,9 @@ dependencies = [
[[package]]
name = "once_cell"
-version = "1.10.0"
+version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
+checksum = "7b10983b38c53aebdf33f542c6275b0f58a238129d00c4ae0e6fb59738d783ca"
[[package]]
name = "opaque-debug"
@@ -773,11 +773,11 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "proc-macro2"
-version = "1.0.38"
+version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa"
+checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
dependencies = [
- "unicode-xid",
+ "unicode-ident",
]
[[package]]
@@ -800,9 +800,9 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.5.5"
+version = "1.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
+checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
dependencies = [
"aho-corasick",
"memchr",
@@ -811,9 +811,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
-version = "0.6.25"
+version = "0.6.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
+checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
[[package]]
name = "ring"
@@ -872,9 +872,9 @@ dependencies = [
[[package]]
name = "rustls"
-version = "0.20.5"
+version = "0.20.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a024a432ae760ab3bff924ad91ce1cfa52cb57ed16e1ef32d0d249cfee1a6c13"
+checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033"
dependencies = [
"log",
"ring",
@@ -905,9 +905,9 @@ dependencies = [
[[package]]
name = "ryu"
-version = "1.0.9"
+version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
+checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
[[package]]
name = "same-file"
@@ -920,12 +920,12 @@ dependencies = [
[[package]]
name = "schannel"
-version = "0.1.19"
+version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
+checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2"
dependencies = [
"lazy_static",
- "winapi",
+ "windows-sys",
]
[[package]]
@@ -1056,13 +1056,13 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
-version = "1.0.94"
+version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a07e33e919ebcd69113d5be0e4d70c5707004ff45188910106854f38b960df4a"
+checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942"
dependencies = [
"proc-macro2",
"quote",
- "unicode-xid",
+ "unicode-ident",
]
[[package]]
@@ -1245,6 +1245,12 @@ version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
+[[package]]
+name = "unicode-ident"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
+
[[package]]
name = "unicode-normalization"
version = "0.1.19"
@@ -1254,12 +1260,6 @@ dependencies = [
"tinyvec",
]
-[[package]]
-name = "unicode-xid"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
-
[[package]]
name = "untrusted"
version = "0.7.1"
diff --git a/Cargo.toml b/Cargo.toml
index 0745fb4..d7033de 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,7 +3,7 @@ name = "libreddit"
description = " Alternative private front-end to Reddit"
license = "AGPL-3.0"
repository = "https://github.com/spikecodes/libreddit"
-version = "0.22.7"
+version = "0.22.8"
authors = ["spikecodes <19519553+spikecodes@users.noreply.github.com>"]
edition = "2021"
@@ -12,7 +12,7 @@ askama = { version = "0.11.1", default-features = false }
async-recursion = "1.0.0"
cached = "0.34.0"
clap = { version = "3.1.18", default-features = false, features = ["std"] }
-regex = "1.5.5"
+regex = "1.5.6"
serde = { version = "1.0.137", features = ["derive"] }
cookie = "0.16.0"
futures-lite = "1.12.0"
@@ -23,4 +23,4 @@ serde_json = "1.0.81"
tokio = { version = "1.18.2", features = ["full"] }
time = "0.3.9"
url = "2.2.2"
-rust-embed="6.4.0"
+rust-embed = "6.4.0"
diff --git a/src/main.rs b/src/main.rs
index dc78a0b..b6f7889 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -11,7 +11,7 @@ mod user;
mod utils;
// Import Crates
-use clap::{Command, Arg};
+use clap::{Arg, Command};
use futures_lite::FutureExt;
use hyper::{header::HeaderValue, Body, Request, Response};
@@ -88,7 +88,7 @@ async fn resource(body: &str, content_type: &str, cache: bool) -> Result Result, String> {
let mut res = include_str!("../static/style.css").to_string();
for file in ThemeAssets::iter() {
- res.push_str("\n");
+ res.push('\n');
let theme = ThemeAssets::get(file.as_ref()).unwrap();
res.push_str(std::str::from_utf8(theme.data.as_ref()).unwrap());
}
diff --git a/src/post.rs b/src/post.rs
index 2ebc313..f9d6e74 100644
--- a/src/post.rs
+++ b/src/post.rs
@@ -100,7 +100,10 @@ async fn parse_post(json: &serde_json::Value) -> Post {
let permalink = val(post, "permalink");
let body = if val(post, "removed_by_category") == "moderator" {
- format!("", permalink)
+ format!(
+ "",
+ permalink
+ )
} else {
rewrite_urls(&val(post, "selftext_html"))
};
@@ -199,7 +202,10 @@ fn parse_comments(json: &serde_json::Value, post_link: &str, post_author: &str,
let highlighted = id == highlighted_comment;
let body = if val(&comment, "author") == "[deleted]" && val(&comment, "body") == "[removed]" {
- format!("", post_link, id)
+ format!(
+ "",
+ post_link, id
+ )
} else {
rewrite_urls(&val(&comment, "body_html"))
};
diff --git a/src/subreddit.rs b/src/subreddit.rs
index ca519b9..fcd0d2a 100644
--- a/src/subreddit.rs
+++ b/src/subreddit.rs
@@ -97,7 +97,7 @@ pub async fn community(req: Request) -> Result, String> {
let path = format!("/r/{}/{}.json?{}&raw_json=1", sub_name.clone(), sort, req.uri().query().unwrap_or_default());
let url = String::from(req.uri().path_and_query().map_or("", |val| val.as_str()));
- let redirect_url = url[1..].replace('?', "%3F").replace('&', "%26").replace('+',"%2B");
+ let redirect_url = url[1..].replace('?', "%3F").replace('&', "%26").replace('+', "%2B");
let filters = get_filters(&req);
// If all requested subs are filtered, we don't need to fetch posts.
diff --git a/src/user.rs b/src/user.rs
index a5a11d0..f83ee98 100644
--- a/src/user.rs
+++ b/src/user.rs
@@ -5,7 +5,7 @@ use crate::server::RequestExt;
use crate::utils::{error, filter_posts, format_url, get_filters, param, template, Post, Preferences, User};
use askama::Template;
use hyper::{Body, Request, Response};
-use time::{OffsetDateTime, macros::format_description};
+use time::{macros::format_description, OffsetDateTime};
// STRUCTS
#[derive(Template)]
diff --git a/src/utils.rs b/src/utils.rs
index 419e384..60afc6f 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -6,12 +6,12 @@ use askama::Template;
use cookie::Cookie;
use hyper::{Body, Request, Response};
use regex::Regex;
+use rust_embed::RustEmbed;
use serde_json::Value;
use std::collections::{HashMap, HashSet};
use std::str::FromStr;
-use time::{Duration, OffsetDateTime, macros::format_description};
+use time::{macros::format_description, Duration, OffsetDateTime};
use url::Url;
-use rust_embed::RustEmbed;
// Post flair with content, background color and foreground color
pub struct Flair {
@@ -218,24 +218,19 @@ pub struct Post {
impl Post {
// Fetch posts of a user or subreddit and return a vector of posts and the "after" value
pub async fn fetch(path: &str, quarantine: bool) -> Result<(Vec, String), String> {
- let res;
- let post_list;
-
// Send a request to the url
- match json(path.to_string(), quarantine).await {
+ let res = match json(path.to_string(), quarantine).await {
// If success, receive JSON in response
- Ok(response) => {
- res = response;
- }
+ Ok(response) => response,
// If the Reddit API returns an error, exit this function
Err(msg) => return Err(msg),
- }
+ };
// Fetch the list of posts from the JSON response
- match res["data"]["children"].as_array() {
- Some(list) => post_list = list,
+ let post_list = match res["data"]["children"].as_array() {
+ Some(list) => list,
None => return Err("No posts found".to_string()),
- }
+ };
let mut posts: Vec = Vec::new();
@@ -622,12 +617,11 @@ pub fn format_url(url: &str) -> String {
// Rewrite Reddit links to Libreddit in body of text
pub fn rewrite_urls(input_text: &str) -> String {
-
- let text1 =
- Regex::new(r#"href="(https|http|)://(www\.|old\.|np\.|amp\.|)(reddit\.com|redd\.it)/"#)
- .map_or(String::new(), |re| re.replace_all(input_text, r#"href="/"#).to_string())
- // Remove (html-encoded) "\" from URLs.
- .replace("%5C", "").replace(r"\", "");
+ let text1 = Regex::new(r#"href="(https|http|)://(www\.|old\.|np\.|amp\.|)(reddit\.com|redd\.it)/"#)
+ .map_or(String::new(), |re| re.replace_all(input_text, r#"href="/"#).to_string())
+ // Remove (html-encoded) "\" from URLs.
+ .replace("%5C", "")
+ .replace('\\', "");
// Rewrite external media previews to Libreddit
Regex::new(r"https://external-preview\.redd\.it(.*)[^?]").map_or(String::new(), |re| {
@@ -671,7 +665,12 @@ pub fn time(created: f64) -> (String, String) {
format!("{}m ago", time_delta.whole_minutes())
};
- (rel_time, time.format(format_description!("[month repr:short] [day] [year], [hour]:[minute]:[second] UTC")).unwrap_or_default())
+ (
+ rel_time,
+ time
+ .format(format_description!("[month repr:short] [day] [year], [hour]:[minute]:[second] UTC"))
+ .unwrap_or_default(),
+ )
}
// val() function used to parse JSON from Reddit APIs
@@ -742,7 +741,8 @@ mod tests {
#[test]
fn rewrite_urls_removes_backslashes() {
- let comment_body_html = r#"https://www.reddit.com/r/linux\\_gaming/comments/x/just\\_a\\_test/"#;
+ let comment_body_html =
+ r#"https://www.reddit.com/r/linux\\_gaming/comments/x/just\\_a\\_test/"#;
assert_eq!(
rewrite_urls(comment_body_html),
r#"https://www.reddit.com/r/linux_gaming/comments/x/just_a_test/"#
From 7e07ca3df1b5ce5d4ca26c7929cffe0724b54570 Mon Sep 17 00:00:00 2001
From: spikecodes <19519553+spikecodes@users.noreply.github.com>
Date: Fri, 20 May 2022 21:26:53 -0700
Subject: [PATCH 07/22] Fix #480
---
static/style.css | 1 +
1 file changed, 1 insertion(+)
diff --git a/static/style.css b/static/style.css
index 664caee..3e0d64d 100644
--- a/static/style.css
+++ b/static/style.css
@@ -777,6 +777,7 @@ a.search_subreddit:hover {
padding: 5px 15px 5px 12px;
grid-area: post_body;
width: calc(100% - 30px);
+ overflow-wrap: anywhere;
}
/* Used only for text post preview */
From 322aa97a1813fd550bf4d3f91997055b45615fd8 Mon Sep 17 00:00:00 2001
From: Nick Lowery
Date: Fri, 20 May 2022 23:28:31 -0600
Subject: [PATCH 08/22] Fix HTML encoding in templating (#404)
---
src/post.rs | 11 +++++------
src/search.rs | 2 +-
src/subreddit.rs | 13 ++++++-------
src/user.rs | 7 +++----
src/utils.rs | 27 ++++++++-------------------
templates/comment.html | 4 ++--
templates/post.html | 4 ++--
templates/search.html | 2 +-
templates/subreddit.html | 2 +-
templates/user.html | 2 +-
templates/utils.html | 2 +-
templates/wiki.html | 4 ++--
12 files changed, 33 insertions(+), 47 deletions(-)
diff --git a/src/post.rs b/src/post.rs
index f9d6e74..02ca380 100644
--- a/src/post.rs
+++ b/src/post.rs
@@ -1,6 +1,5 @@
// CRATES
use crate::client::json;
-use crate::esc;
use crate::server::RequestExt;
use crate::subreddit::{can_access_quarantine, quarantine};
use crate::utils::{
@@ -13,7 +12,7 @@ use std::collections::HashSet;
// STRUCTS
#[derive(Template)]
-#[template(path = "post.html", escape = "none")]
+#[template(path = "post.html")]
struct PostTemplate {
comments: Vec,
post: Post,
@@ -111,7 +110,7 @@ async fn parse_post(json: &serde_json::Value) -> Post {
// Build a post using data parsed from Reddit post API
Post {
id: val(post, "id"),
- title: esc!(post, "title"),
+ title: val(post, "title"),
community: val(post, "subreddit"),
body,
author: Author {
@@ -122,7 +121,7 @@ async fn parse_post(json: &serde_json::Value) -> Post {
post["data"]["author_flair_richtext"].as_array(),
post["data"]["author_flair_text"].as_str(),
),
- text: esc!(post, "link_flair_text"),
+ text: val(post, "link_flair_text"),
background_color: val(post, "author_flair_background_color"),
foreground_color: val(post, "author_flair_text_color"),
},
@@ -146,7 +145,7 @@ async fn parse_post(json: &serde_json::Value) -> Post {
post["data"]["link_flair_richtext"].as_array(),
post["data"]["link_flair_text"].as_str(),
),
- text: esc!(post, "link_flair_text"),
+ text: val(post, "link_flair_text"),
background_color: val(post, "link_flair_background_color"),
foreground_color: if val(post, "link_flair_text_color") == "dark" {
"black".to_string()
@@ -218,7 +217,7 @@ fn parse_comments(json: &serde_json::Value, post_link: &str, post_author: &str,
data["author_flair_richtext"].as_array(),
data["author_flair_text"].as_str(),
),
- text: esc!(&comment, "link_flair_text"),
+ text: val(&comment, "link_flair_text"),
background_color: val(&comment, "author_flair_background_color"),
foreground_color: val(&comment, "author_flair_text_color"),
},
diff --git a/src/search.rs b/src/search.rs
index 3547679..4dd3b5f 100644
--- a/src/search.rs
+++ b/src/search.rs
@@ -29,7 +29,7 @@ struct Subreddit {
}
#[derive(Template)]
-#[template(path = "search.html", escape = "none")]
+#[template(path = "search.html")]
struct SearchTemplate {
posts: Vec,
subreddits: Vec,
diff --git a/src/subreddit.rs b/src/subreddit.rs
index fcd0d2a..b03e7e9 100644
--- a/src/subreddit.rs
+++ b/src/subreddit.rs
@@ -1,5 +1,4 @@
// CRATES
-use crate::esc;
use crate::utils::{
catch_random, error, filter_posts, format_num, format_url, get_filters, param, redirect, rewrite_urls, setting, template, val, Post, Preferences, Subreddit,
};
@@ -11,7 +10,7 @@ use time::{Duration, OffsetDateTime};
// STRUCTS
#[derive(Template)]
-#[template(path = "subreddit.html", escape = "none")]
+#[template(path = "subreddit.html")]
struct SubredditTemplate {
sub: Subreddit,
posts: Vec,
@@ -28,7 +27,7 @@ struct SubredditTemplate {
}
#[derive(Template)]
-#[template(path = "wiki.html", escape = "none")]
+#[template(path = "wiki.html")]
struct WikiTemplate {
sub: String,
wiki: String,
@@ -38,7 +37,7 @@ struct WikiTemplate {
}
#[derive(Template)]
-#[template(path = "wall.html", escape = "none")]
+#[template(path = "wall.html")]
struct WallTemplate {
title: String,
sub: String,
@@ -408,9 +407,9 @@ async fn subreddit(sub: &str, quarantined: bool) -> Result {
let icon = if community_icon.is_empty() { val(&res, "icon_img") } else { community_icon.to_string() };
Ok(Subreddit {
- name: esc!(&res, "display_name"),
- title: esc!(&res, "title"),
- description: esc!(&res, "public_description"),
+ name: val(&res, "display_name"),
+ title: val(&res, "title"),
+ description: val(&res, "public_description"),
info: rewrite_urls(&val(&res, "description_html")),
// moderators: moderators_list(sub, quarantined).await.unwrap_or_default(),
icon: format_url(&icon),
diff --git a/src/user.rs b/src/user.rs
index f83ee98..69c4ae9 100644
--- a/src/user.rs
+++ b/src/user.rs
@@ -1,6 +1,5 @@
// CRATES
use crate::client::json;
-use crate::esc;
use crate::server::RequestExt;
use crate::utils::{error, filter_posts, format_url, get_filters, param, template, Post, Preferences, User};
use askama::Template;
@@ -9,7 +8,7 @@ use time::{macros::format_description, OffsetDateTime};
// STRUCTS
#[derive(Template)]
-#[template(path = "user.html", escape = "none")]
+#[template(path = "user.html")]
struct UserTemplate {
user: User,
posts: Vec,
@@ -102,11 +101,11 @@ async fn user(name: &str) -> Result {
// Parse the JSON output into a User struct
User {
name: res["data"]["name"].as_str().unwrap_or(name).to_owned(),
- title: esc!(about("title")),
+ title: about("title"),
icon: format_url(&about("icon_img")),
karma: res["data"]["total_karma"].as_i64().unwrap_or(0),
created: created.format(format_description!("[month repr:short] [day] '[year repr:last_two]")).unwrap_or_default(),
- banner: esc!(about("banner_img")),
+ banner: about("banner_img"),
description: about("public_description"),
}
})
diff --git a/src/utils.rs b/src/utils.rs
index 60afc6f..2691d16 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -1,7 +1,7 @@
//
// CRATES
//
-use crate::{client::json, esc, server::RequestExt};
+use crate::{client::json, server::RequestExt};
use askama::Template;
use cookie::Cookie;
use hyper::{Body, Request, Response};
@@ -42,7 +42,7 @@ impl FlairPart {
Self {
flair_part_type: value("e").to_string(),
value: match value("e") {
- "text" => esc!(value("t")),
+ "text" => value("t").to_string(),
"emoji" => format_url(value("u")),
_ => String::new(),
},
@@ -55,7 +55,7 @@ impl FlairPart {
"text" => match text_flair {
Some(text) => vec![Self {
flair_part_type: "text".to_string(),
- value: esc!(text),
+ value: text.to_string(),
}],
None => Vec::new(),
},
@@ -241,7 +241,7 @@ impl Post {
let (rel_time, created) = time(data["created_utc"].as_f64().unwrap_or_default());
let score = data["score"].as_i64().unwrap_or_default();
let ratio: f64 = data["upvote_ratio"].as_f64().unwrap_or(1.0) * 100.0;
- let title = esc!(post, "title");
+ let title = val(post, "title");
// Determine the type of media along with the media URL
let (post_type, media, gallery) = Media::parse(data).await;
@@ -266,7 +266,7 @@ impl Post {
data["author_flair_richtext"].as_array(),
data["author_flair_text"].as_str(),
),
- text: esc!(post, "link_flair_text"),
+ text: val(post, "link_flair_text"),
background_color: val(post, "author_flair_background_color"),
foreground_color: val(post, "author_flair_text_color"),
},
@@ -294,7 +294,7 @@ impl Post {
data["link_flair_richtext"].as_array(),
data["link_flair_text"].as_str(),
),
- text: esc!(post, "link_flair_text"),
+ text: val(post, "link_flair_text"),
background_color: val(post, "link_flair_background_color"),
foreground_color: if val(post, "link_flair_text_color") == "dark" {
"black".to_string()
@@ -320,7 +320,7 @@ impl Post {
}
#[derive(Template)]
-#[template(path = "comment.html", escape = "none")]
+#[template(path = "comment.html")]
// Comment with content, post, score and data/time that it was posted
pub struct Comment {
pub id: String,
@@ -396,7 +396,7 @@ impl Awards {
}
#[derive(Template)]
-#[template(path = "error.html", escape = "none")]
+#[template(path = "error.html")]
pub struct ErrorTemplate {
pub msg: String,
pub prefs: Preferences,
@@ -678,17 +678,6 @@ pub fn val(j: &Value, k: &str) -> String {
j["data"][k].as_str().unwrap_or_default().to_string()
}
-// Escape < and > to accurately render HTML
-#[macro_export]
-macro_rules! esc {
- ($f:expr) => {
- $f.replace('&', "&").replace('<', "<").replace('>', ">")
- };
- ($j:expr, $k:expr) => {
- $j["data"][$k].as_str().unwrap_or_default().to_string().replace('<', "<").replace('>', ">")
- };
-}
-
//
// NETWORKING
//
diff --git a/templates/comment.html b/templates/comment.html
index 3014192..61c44f5 100644
--- a/templates/comment.html
+++ b/templates/comment.html
@@ -32,9 +32,9 @@
{% if is_filtered %}
(Filtered content)
{% else %}
- {{ body }}
+ {{ body|safe }}
{% endif %}
- {% for c in replies -%}{{ c.render().unwrap() }}{%- endfor %}
+ {% for c in replies -%}{{ c.render().unwrap()|safe }}{%- endfor %}
diff --git a/templates/post.html b/templates/post.html
index add5881..97715ec 100644
--- a/templates/post.html
+++ b/templates/post.html
@@ -110,7 +110,7 @@
{% endif %}
- {{ post.body }}
+ {{ post.body|safe }}
{{ post.score.0 }} Upvotes
{%- endfor %}
diff --git a/templates/search.html b/templates/search.html
index 0218c35..c5cff86 100644
--- a/templates/search.html
+++ b/templates/search.html
@@ -39,7 +39,7 @@
{% endif %}
{% for subreddit in subreddits %}
- {% if subreddit.icon != "" %}
{% endif %}
+ {% if subreddit.icon != "" %}
{% endif %}
-{% endblock %}
\ No newline at end of file
+{% endblock %}
From 7f5bfc04b30e8c3ca690660f8cfad37242769ea7 Mon Sep 17 00:00:00 2001
From: spikecodes <19519553+spikecodes@users.noreply.github.com>
Date: Fri, 20 May 2022 22:42:05 -0700
Subject: [PATCH 09/22] Always show Feeds dropdown (Fixes #408)
---
templates/utils.html | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/templates/utils.html b/templates/utils.html
index 0e22900..e4c6f75 100644
--- a/templates/utils.html
+++ b/templates/utils.html
@@ -38,7 +38,6 @@
{%- endmacro %}
{% macro sub_list(current) -%}
-{% if prefs.subscriptions.len() > 0 %}
Feeds
@@ -46,13 +45,14 @@
Home
Popular
All
-
REDDIT FEEDS
- {% for sub in prefs.subscriptions %}
-
{{ sub }}
- {% endfor %}
+ {% if prefs.subscriptions.len() > 0 %}
+
REDDIT FEEDS
+ {% for sub in prefs.subscriptions %}
+
{{ sub }}
+ {% endfor %}
+ {% endif %}
-{% endif %}
{%- endmacro %}
{% macro render_hls_notification(redirect_url) -%}
From 90828cc71c968a3ee92f637253cb6da11d4a20c7 Mon Sep 17 00:00:00 2001
From: Mario A <10923513+Midblyte@users.noreply.github.com>
Date: Sat, 21 May 2022 05:48:59 +0000
Subject: [PATCH 10/22] Fix "Post url contains non-ASCII characters" error
(#479)
---
Cargo.lock | 1 +
Cargo.toml | 1 +
src/client.rs | 3 ++-
3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/Cargo.lock b/Cargo.lock
index dbef214..f138b37 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -596,6 +596,7 @@ dependencies = [
"futures-lite",
"hyper",
"hyper-rustls",
+ "percent-encoding",
"regex",
"route-recognizer",
"rust-embed",
diff --git a/Cargo.toml b/Cargo.toml
index d7033de..5c856cf 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,6 +18,7 @@ cookie = "0.16.0"
futures-lite = "1.12.0"
hyper = { version = "0.14.18", features = ["full"] }
hyper-rustls = "0.23.0"
+percent-encoding = "2.1.0"
route-recognizer = "0.3.1"
serde_json = "1.0.81"
tokio = { version = "1.18.2", features = ["full"] }
diff --git a/src/client.rs b/src/client.rs
index 864a6c6..da271dd 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -1,6 +1,7 @@
use cached::proc_macro::cached;
use futures_lite::{future::Boxed, FutureExt};
use hyper::{body::Buf, client, Body, Request, Response, Uri};
+use percent_encoding::{percent_encode, CONTROLS};
use serde_json::Value;
use std::result::Result;
@@ -90,7 +91,7 @@ fn request(url: String, quarantine: bool) -> Boxed, String
.headers()
.get("Location")
.map(|val| {
- let new_url = val.to_str().unwrap_or_default();
+ let new_url = percent_encode(val.as_bytes(), CONTROLS).to_string();
format!("{}{}raw_json=1", new_url, if new_url.contains('?') { "&" } else { "?" })
})
.unwrap_or_default()
From 0c757023f9223dd87b0d109e09537ee490eca2e1 Mon Sep 17 00:00:00 2001
From: Arya K <73596856+gi-yt@users.noreply.github.com>
Date: Sat, 21 May 2022 05:53:48 +0000
Subject: [PATCH 11/22] Correct localhost to 0.0.0.0 in SystemD conf (#498)
---
contrib/libreddit.conf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contrib/libreddit.conf b/contrib/libreddit.conf
index 18b8193..dd91e3b 100644
--- a/contrib/libreddit.conf
+++ b/contrib/libreddit.conf
@@ -1,2 +1,2 @@
-ADDRESS=localhost
+ADDRESS=0.0.0.0
PORT=12345
From d558127306017646dc72e0a4b8c6a9b837dc6842 Mon Sep 17 00:00:00 2001
From: spikecodes <19519553+spikecodes@users.noreply.github.com>
Date: Fri, 20 May 2022 23:10:11 -0700
Subject: [PATCH 12/22] Add keyboard shortcuts to nav buttons (closes #466)
---
templates/search.html | 4 ++--
templates/subreddit.html | 4 ++--
templates/user.html | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/templates/search.html b/templates/search.html
index c5cff86..9386f35 100644
--- a/templates/search.html
+++ b/templates/search.html
@@ -92,13 +92,13 @@
{% if params.before != "" %}
PREV
+ &before={{ params.before }}" accesskey="P">PREV
{% endif %}
{% if params.after != "" %}
NEXT
+ &after={{ params.after }}" accesskey="N">NEXT
{% endif %}
{% endif %}
diff --git a/templates/subreddit.html b/templates/subreddit.html
index 3ef318e..7559e3c 100644
--- a/templates/subreddit.html
+++ b/templates/subreddit.html
@@ -65,11 +65,11 @@
diff --git a/templates/user.html b/templates/user.html
index 2e6278d..43c907c 100644
--- a/templates/user.html
+++ b/templates/user.html
@@ -66,11 +66,11 @@
From 50665bbeb362c3bebc39a10a6c497efb09984515 Mon Sep 17 00:00:00 2001
From: spikecodes <19519553+spikecodes@users.noreply.github.com>
Date: Sat, 21 May 2022 15:47:58 -0700
Subject: [PATCH 13/22] Switch titles to s (Fixes #444)
---
templates/post.html | 4 ++--
templates/subreddit.html | 2 +-
templates/user.html | 2 +-
templates/utils.html | 4 ++--
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/templates/post.html b/templates/post.html
index 97715ec..227d7fc 100644
--- a/templates/post.html
+++ b/templates/post.html
@@ -55,7 +55,7 @@
{% endif %}
-
+
{{ post.title }}
{% if post.flair.flair_parts.len() > 0 %}
{% call utils::render_flair(post.flair.flair_parts) %}
{% endif %}
{% if post.flags.nsfw %} NSFW{% endif %}
-
+
diff --git a/templates/subreddit.html b/templates/subreddit.html
index 7559e3c..e5e8fa1 100644
--- a/templates/subreddit.html
+++ b/templates/subreddit.html
@@ -89,7 +89,7 @@
{% endif %}