Compare commits

...

33 Commits

Author SHA1 Message Date
bb7fb1313d Fix multireddit subscription redirect url 2022-05-15 13:50:17 -07:00
01bc729a80 ✏️ Fix link to Cloudflare in README.md (#506)
Added `.com` to `https://cloudflare` to fix the link in `README.md`.
2022-05-15 19:58:32 +00:00
39e6e6bf81 Add lr.vern.cc to instance list (#505) 2022-05-15 19:58:10 +00:00
8c94c0dd17 Let native elements use theme accent colour (#509) 2022-05-15 19:56:25 +00:00
1c50c8f30d Update instances
Closes #503, #495, #488, #484, #483, #454, and #507
2022-05-15 19:16:15 +00:00
3facaefb53 Add strongthany.cc instance (#478)
* Update to list of public instances

added strongthany.cc instance to the list of public instances

* fixed accidental removal

put the location status back for riverside.
2022-04-06 18:25:11 +00:00
aec45311cc ✍️fix: Tries to add better readability - ➡️ fix: Moves funding links to correct file (#477)
* ✍️ fix(readme): Adds better readability

* ➡️ fix(buymeacoffee): Moves custom link to correct FUNDING.yml

* ➡️ fix(buymeacoffee): Moves custom link to correct FUNDING.yml

* ✍️ fix(bugreport): Adds better readability

* ✍️ fix(featureparity): Adds better readability

* ✍️ fix(featurerequest): Adds better readability

* ✍️ fix(crypto): Removes broken linking, changed to codeblock
2022-04-06 18:24:10 +00:00
47ab857103 Scroll overflowing tables (fixes #469) 2022-04-02 21:24:20 -07:00
a9ef5bc08b Add lunar.icu instance. Closes #460 2022-03-27 00:50:19 +00:00
eb6c5e5e1e Fix backslash url rewriting and add tests for rewrite_urls. (#461)
* Fix backslash url rewriting.

Add test for rewrite_urls.

Fixes #281.

* Update to v0.22.5

Co-authored-by: spikecodes <19519553+spikecodes@users.noreply.github.com>
2022-03-26 20:26:30 +00:00
ed11135af8 Update to v0.22.4 2022-03-26 13:09:24 -07:00
3a1af78e26 Wrap long post urls. (#462) 2022-03-26 19:55:53 +00:00
345770c64d Update libreddit.privacy.com.de domain 2022-03-26 19:54:26 +00:00
9eb42932df Hide empty sidebar 2022-03-24 21:19:21 -07:00
f0a6bdc21b Fix sorting buttons on r/all and r/popular (#402)
* Fix sorting buttons on r/all and r/popular

* Bump version to v0.22.2

* Fix empty sidebar in r/all and r/popular

Co-authored-by: spikecodes <19519553+spikecodes@users.noreply.github.com>
2022-03-15 03:39:39 +00:00
3eef60d486 Add instances (#432, #433, #436, #438) 2022-03-14 01:01:09 +00:00
59043456ba Wrap long post titles (fixes #435) 2022-03-13 12:59:15 -07:00
90c7088da2 Link Privacy Redirect as well 2022-03-13 19:19:56 +00:00
9e65a65556 Promote LibRedirect in README 2022-03-13 19:15:47 +00:00
8cfbde2710 Add LiberaPay "Donate" button back 2022-03-13 19:11:39 +00:00
70ff150ab4 Add user listing buttons (#400)
* Add user listing buttons

* Update to v0.22

Co-authored-by: spikecodes <19519553+spikecodes@users.noreply.github.com>
2022-03-13 19:06:27 +00:00
388779c1f2 Update instances (#421)
close #411 
close #412 
close #417

Co-authored-by: Spike <19519553+spikecodes@users.noreply.github.com>
2022-03-13 18:38:35 +00:00
6b605d859f Add German leddit.xyz instance (#429)
* new DE instance

* new hidden service

Co-authored-by: Spike <19519553+spikecodes@users.noreply.github.com>
2022-03-13 18:37:01 +00:00
0ae48c400c Add kylrth instances (#446)
Co-authored-by: Spike <19519553+spikecodes@users.noreply.github.com>
2022-03-13 18:35:13 +00:00
a6ed18d674 Changed location of my VPS :) (#415)
* Changed location of my VPS :)

So my tor url changed too along side my VPS's country so yup!

* Update README.md
2022-03-13 18:32:26 +00:00
838cdd95d1 Update libreddit.drivet.xyz (#360)
* Remove Cloudflare Proxy from libreddit.drivet.xyz

I'm testing some stuff and as a result i have disabled proxy for libreddit.drivet.xyz. It exposes my public ip, but also gives more privacy i guess

* Move libreddit.drivet.xyz to Poland

Co-authored-by: Spike <19519553+spikecodes@users.noreply.github.com>
2022-03-13 18:32:10 +00:00
bc95b08ffd Update libreddit.datatunnel.xyz to Finland 2022-01-21 17:36:34 +00:00
e6190267e4 Add libreddit.datatunnel.xyz instance. Closes #401 2022-01-20 22:34:47 +00:00
3ceeac5fb0 Add lr.rfl890.cf instance. Closes #399 2022-01-19 18:14:51 +00:00
60eb0137c2 Add libreddit.bus-hit.me to instances (#398) 2022-01-19 18:13:46 +00:00
b6bca68d4e Add reddi.tk instance. Closes #397 2022-01-17 20:13:38 +00:00
91bff826f0 Fix and improve admin/mod distinguishers (#386)
* Fix regression with comments from deleted mods

Starting with https://github.com/spikecodes/libreddit/pull/367/files
comments from deleted moderators and admins(?) aren't highlighted.

* Highlight mod and admin usernames in posts

Works like on reddit + shows highlight for mods on the search page.
2022-01-09 02:50:53 +00:00
af6606a855 leddit.xyz instance location change (#387) 2022-01-09 01:14:05 +00:00
19 changed files with 452 additions and 308 deletions

1
.github/FUNDING.yml vendored
View File

@ -1 +1,2 @@
liberapay: spike
custom: ['https://www.buymeacoffee.com/spikecodes']

View File

@ -1,7 +1,7 @@
---
name: 🐛 Bug report
about: Create a report to help us improve
title: ''
title: '🐛 Bug Report: '
labels: bug
assignees: ''
@ -12,7 +12,7 @@ assignees: ''
A clear and concise description of what the bug is.
-->
## To reproduce
## Steps to reproduce the bug
<!--
Steps to reproduce the behavior:
@ -22,12 +22,12 @@ Steps to reproduce the behavior:
4. See error
-->
## Expected behavior
## What's the expected behavior?
<!--
A clear and concise description of what you expected to happen.
-->
## Additional context
## Additional context / screenshot
<!--
Add any other context about the problem here.
-->

View File

@ -1,7 +1,7 @@
---
name: ✨ Feature parity
about: Suggest implementing a feature into Libreddit that is found in Reddit.com
title: ''
title: '✨ Feature parity: '
labels: feature parity
assignees: ''
@ -12,7 +12,7 @@ assignees: ''
A clear and concise description of what the feature is.
-->
## Describe the implementation into Libreddit
## Describe how this could be implemented into Libreddit
<!--
A clear and concise description of what you want to happen.
-->
@ -22,7 +22,7 @@ assignees: ''
A clear and concise description of any alternative solutions or features you've considered.
-->
## Additional context
## Additional context / screenshot
<!--
Add any other context or screenshots about the feature parity request here.
-->

View File

@ -1,7 +1,7 @@
---
name: 💡 Feature request
about: Suggest a feature for Libreddit that is not found in Reddit
title: ''
title: '💡 Feature request: '
labels: enhancement
assignees: ''
@ -12,7 +12,7 @@ assignees: ''
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
-->
## Describe the solution you'd like
## Describe the feature you would like to be implemented
<!--
A clear and concise description of what you want to happen.
-->
@ -22,7 +22,7 @@ assignees: ''
A clear and concise description of any alternative solutions or features you've considered.
-->
## Additional context
## Additional context / screenshot
<!--
Add any other context or screenshots about the feature request here.
-->

539
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -3,23 +3,23 @@ name = "libreddit"
description = " Alternative private front-end to Reddit"
license = "AGPL-3.0"
repository = "https://github.com/spikecodes/libreddit"
version = "0.21.7"
version = "0.22.7"
authors = ["spikecodes <19519553+spikecodes@users.noreply.github.com>"]
edition = "2021"
[dependencies]
askama = { version = "0.11.0", default-features = false }
askama = { version = "0.11.1", default-features = false }
async-recursion = "1.0.0"
cached = "0.26.2"
clap = { version = "3.0.5", default-features = false, features = ["std"] }
regex = "1.5.4"
serde = { version = "1.0.133", features = ["derive"] }
cached = "0.34.0"
clap = { version = "3.1.18", default-features = false, features = ["std"] }
regex = "1.5.5"
serde = { version = "1.0.137", features = ["derive"] }
cookie = "0.16.0"
futures-lite = "1.12.0"
hyper = { version = "0.14.16", features = ["full"] }
hyper = { version = "0.14.18", features = ["full"] }
hyper-rustls = "0.23.0"
route-recognizer = "0.3.1"
serde_json = "1.0.74"
tokio = { version = "1.15.0", features = ["full"] }
time = "0.3.5"
serde_json = "1.0.81"
tokio = { version = "1.18.2", features = ["full"] }
time = "0.3.9"
url = "2.2.2"

View File

@ -1,12 +0,0 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: spike
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: ['https://www.buymeacoffee.com/spikecodes']

View File

@ -8,7 +8,7 @@
**10 second pitch:** Libreddit is a portmanteau of "libre" (meaning freedom) and "Reddit". It is a private front-end like [Invidious](https://github.com/iv-org/invidious) but for Reddit. Browse the coldest takes of [r/unpopularopinion](https://libreddit.spike.codes/r/unpopularopinion) without being [tracked](#reddit).
- 🚀 Fast: written in Rust for blazing fast speeds and memory safety
- 🚀 Fast: written in Rust for blazing-fast speeds and memory safety
- ☁️ Light: no JavaScript, no ads, no tracking, no bloat
- 🕵 Private: all requests are proxied through the server, including media
- 🔒 Secure: strong [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) prevents browser requests to Reddit
@ -17,11 +17,13 @@
I appreciate any donations! Your support allows me to continue developing Libreddit.
<a href="https://www.buymeacoffee.com/spikecodes" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 50px" ></a>
<a href="https://www.buymeacoffee.com/spikecodes" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 40px" ></a>
<a href="https://liberapay.com/spike/donate"><img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg" style="height: 40px"></a>
**Bitcoin:** [bc1qwyxjnafpu3gypcpgs025cw9wa7ryudtecmwa6y](bitcoin:bc1qwyxjnafpu3gypcpgs025cw9wa7ryudtecmwa6y)
**Monero:** [45FJrEuFPtG2o7QZz2Nps77TbHD4sPqxViwbdyV9A6ktfHiWs47UngG5zXPcLoDXAc8taeuBgeNjfeprwgeXYXhN3C9tVSR](monero:45FJrEuFPtG2o7QZz2Nps77TbHD4sPqxViwbdyV9A6ktfHiWs47UngG5zXPcLoDXAc8taeuBgeNjfeprwgeXYXhN3C9tVSR)
**Bitcoin:** `bc1qwyxjnafpu3gypcpgs025cw9wa7ryudtecmwa6y`
**Monero:** `45FJrEuFPtG2o7QZz2Nps77TbHD4sPqxViwbdyV9A6ktfHiWs47UngG5zXPcLoDXAc8taeuBgeNjfeprwgeXYXhN3C9tVSR`
---
@ -29,6 +31,8 @@ I appreciate any donations! Your support allows me to continue developing Libred
Feel free to [open an issue](https://github.com/spikecodes/libreddit/issues/new) to have your [selfhosted instance](#deployment) listed here!
🔗 **Want to automatically redirect Reddit links to Libreddit? Use [LibRedirect](https://github.com/libredirect/libredirect) or [Privacy Redirect](https://github.com/SimonBrazell/privacy-redirect)!**
| Website | Country | Cloudflare |
|-|-|-|
| [libredd.it](https://libredd.it) (official) | 🇺🇸 US | |
@ -40,8 +44,9 @@ Feel free to [open an issue](https://github.com/spikecodes/libreddit/issues/new)
| [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.exonip.de](https://libreddit.exonip.de) | 🇩🇪 DE | |
| [libreddit.privacy.com.de](https://libreddit.privacy.com.de) | 🇩🇪 DE | |
| [libreddit.domain.glass](https://libreddit.domain.glass) | 🇺🇸 US | ✅ |
| [libreddit.sugoma.tk](https://libreddit.sugoma.tk) | 🇺🇸 US | |
| [libreddit.jamiethalacker.dev](https://libreddit.jamiethalacker.dev) | 🇺🇸 US | ✅ |
@ -55,19 +60,38 @@ Feel free to [open an issue](https://github.com/spikecodes/libreddit/issues/new)
| [libreddit.igna.rocks](https://libreddit.igna.rocks) | 🇺🇸 US | |
| [libreddit.autarkic.org](https://libreddit.autarkic.org) | 🇺🇸 US | |
| [libreddit.flux.industries](https://libreddit.flux.industries) | 🇩🇪 DE | ✅ |
| [libreddit.drivet.xyz](https://libreddit.drivet.xyz) | 🇫🇮 FI | |
| [libreddit.drivet.xyz](https://libreddit.drivet.xyz) | 🇵🇱 PL | |
| [lr.oversold.host](https://lr.oversold.host) | 🇱🇺 LU | |
| [libreddit.de](https://libreddit.de) | 🇩🇪 DE | |
| [libreddit.pussthecat.org](https://libreddit.pussthecat.org) | 🇩🇪 DE | |
| [libreddit.mutahar.rocks](https://libreddit.mutahar.rocks) | 🇫🇷 FR | |
| [libreddit.northboot.xyz](https://libreddit.northboot.xyz) | 🇩🇪 DE | |
| [leddit.xyz](https://www.leddit.xyz) | 🇩🇪 DE | |
| [leddit.xyz](https://leddit.xyz) | 🇺🇸 US | |
| [de.leddit.xyz](https://de.leddit.xyz) | 🇩🇪 DE | |
| [lr.cowfee.moe](https://lr.cowfee.moe) | 🇺🇸 US | |
| [libreddit.hu](https://libreddit.hu) | 🇫🇮 FI | ✅ |
| [libreddit.totaldarkness.net](https://libreddit.totaldarkness.net) | 🇨🇦 CA | |
| [libreddit.esmailelbob.xyz](https://libreddit.esmailelbob.xyz) | 🇪🇬 EG | |
| [libreddit.esmailelbob.xyz](https://libreddit.esmailelbob.xyz) | 🇨🇦 CA | |
| [lr.vern.cc](https://lr.vern.cc) | 🇵🇱 PL | |
| [libreddit.nl](https://libreddit.nl) | 🇳🇱 NL | |
| [lr.stilic.ml](https://lr.stilic.ml) | 🇫🇷 FR | ✅ |
| [reddi.tk](https://reddi.tk) | 🇺🇸 US | ✅ |
| [libreddit.bus-hit.me](https://libreddit.bus-hit.me) | 🇨🇦 CA | |
| [libreddit.datatunnel.xyz](https://libreddit.datatunnel.xyz) | 🇫🇮 FI | |
| [libreddit.crewz.me](https://libreddit.crewz.me) | 🇳🇱 NL | ✅ |
| [r.walkx.org](https://r.walkx.org) | 🇳🇱 NL | ✅ |
| [libreddit.kylrth.com](https://libreddit.kylrth.com) | 🇨🇦 CA | |
| [libreddit.yonalee.eu](https://libreddit.yonalee.eu) | 🇱🇺 LU | ✅ |
| [libreddit.winscloud.net](https://libreddit.winscloud.net) | 🇹🇭 TH | ✅ |
| [libreddit.tiekoetter.com](https://libreddit.tiekoetter.com) | 🇩🇪 DE | |
| [reddit.rtrace.io](https://reddit.rtrace.io) | 🇩🇪 DE | |
| [libreddit.lunar.icu](https://libreddit.lunar.icu) | 🇩🇪 DE | ✅ |
| [libreddit.privacydev.net](https://libreddit.privacydev.net) | 🇺🇸 US | |
| [libreddit.notyourcomputer.net](https://libreddit.notyourcomputer.net) | 🇺🇸 US | |
| [r.ahwx.org](https://r.ahwx.org) | 🇳🇱 NL | ✅ |
| [bob.fr.to](https://bob.fr.to) | 🇺🇸 US | |
| [reddit.beparanoid.de](https://reddit.beparanoid.de) | 🇨🇭 CH | |
| [libreddit.dcs0.hu](https://libreddit.dcs0.hu) | 🇭🇺 HU | |
| [spjmllawtheisznfs7uryhxumin26ssv2draj7oope3ok3wuhy43eoyd.onion](http://spjmllawtheisznfs7uryhxumin26ssv2draj7oope3ok3wuhy43eoyd.onion) | 🇮🇳 IN | |
| [fwhhsbrbltmrct5hshrnqlqygqvcgmnek3cnka55zj4y7nuus5muwyyd.onion](http://fwhhsbrbltmrct5hshrnqlqygqvcgmnek3cnka55zj4y7nuus5muwyyd.onion) | 🇩🇪 DE | |
| [kphht2jcflojtqte4b4kyx7p2ahagv4debjj32nre67dxz7y57seqwyd.onion](http://kphht2jcflojtqte4b4kyx7p2ahagv4debjj32nre67dxz7y57seqwyd.onion) | 🇳🇱 NL | |
@ -78,9 +102,12 @@ Feel free to [open an issue](https://github.com/spikecodes/libreddit/issues/new)
| [ledditqo2mxfvlgobxnlhrkq4dh34jss6evfkdkb2thlvy6dn4f4gpyd.onion](http://ledditqo2mxfvlgobxnlhrkq4dh34jss6evfkdkb2thlvy6dn4f4gpyd.onion) | 🇺🇸 US | |
| [libredoxhxwnmsb6dvzzd35hmgzmawsq5i764es7witwhddvpc2razid.onion](http://libredoxhxwnmsb6dvzzd35hmgzmawsq5i764es7witwhddvpc2razid.onion) | 🇺🇸 US | |
| [libreddit.2syis2nnyytz6jnusnjurva4swlaizlnleiks5mjp46phuwjbdjqwgqd.onion](http://libreddit.2syis2nnyytz6jnusnjurva4swlaizlnleiks5mjp46phuwjbdjqwgqd.onion) | 🇪🇬 EG | |
| [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 | |
A checkmark in the "Cloudflare" category here refers to the use of the reverse proxy, [Cloudflare](https://cloudflare). The checkmark will not be listed for a site which uses Cloudflare DNS but rather the proxying service which grants Cloudflare the ability to monitor traffic to the website.
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.
---
@ -143,7 +170,7 @@ Results from Google Lighthouse ([Libreddit Report](https://lighthouse-dot-webdot
- The requested URL
- Search terms
**Location:** The same privacy policy goes on to describe location data may be collected through the use of:
**Location:** The same privacy policy goes on to describe that location data may be collected through the use of:
- GPS (consensual)
- Bluetooth (consensual)
- Content associated with a location (consensual)
@ -167,7 +194,7 @@ For transparency, I hope to describe all the ways Libreddit handles user privacy
**Cookies:** Libreddit uses optional cookies to store any configured settings in [the settings menu](https://libreddit.spike.codes/settings). These are not cross-site cookies and the cookies hold no personal data.
**Hosting:** The official instances are hosted on [Replit](https://replit.com/) which monitors usage to prevent abuse. I can understand if this invalidates certain users' threat models and therefore, selfhosting, using unofficial instances and browsing through Tor are welcomed.
**Hosting:** The official instances are hosted on [Replit](https://replit.com/) which monitors usage to prevent abuse. I can understand if this invalidates certain users' threat models and therefore, self-hosting, using unofficial instances, and browsing through Tor are welcomed.
---
@ -258,7 +285,7 @@ LIBREDDIT_DEFAULT_WIDE=on LIBREDDIT_DEFAULT_THEME=dark libreddit -r
## Proxying using NGINX
**NOTE** If you're [proxying Libreddit through a NGINX Reverse Proxy](https://github.com/spikecodes/libreddit/issues/122#issuecomment-782226853), add
**NOTE** If you're [proxying Libreddit through an NGINX Reverse Proxy](https://github.com/spikecodes/libreddit/issues/122#issuecomment-782226853), add
```nginx
proxy_http_version 1.1;
```

View File

@ -11,7 +11,7 @@ mod user;
mod utils;
// Import Crates
use clap::{App as cli, Arg};
use clap::{Command, Arg};
use futures_lite::FutureExt;
use hyper::{header::HeaderValue, Body, Request, Response};
@ -87,7 +87,7 @@ async fn resource(body: &str, content_type: &str, cache: bool) -> Result<Respons
#[tokio::main]
async fn main() {
let matches = cli::new("Libreddit")
let matches = Command::new("Libreddit")
.version(env!("CARGO_PKG_VERSION"))
.about("Private front-end for Reddit written in Rust ")
.arg(
@ -193,6 +193,7 @@ async fn main() {
app.at("/user/[deleted]").get(|req| error(req, "User has deleted their account".to_string()).boxed());
app.at("/user/:name").get(|r| user::profile(r).boxed());
app.at("/user/:name/:listing").get(|r| user::profile(r).boxed());
app.at("/user/:name/comments/:id").get(|r| post::item(r).boxed());
app.at("/user/:name/comments/:id/:title").get(|r| post::item(r).boxed());
app.at("/user/:name/comments/:id/:title/:comment_id").get(|r| post::item(r).boxed());

View File

@ -102,7 +102,7 @@ async fn parse_post(json: &serde_json::Value) -> Post {
let body = if val(post, "removed_by_category") == "moderator" {
format!("<div class=\"md\"><p>[removed] — <a href=\"https://www.reveddit.com{}\">view removed post</a></p></div>", permalink)
} else {
rewrite_urls(&val(post, "selftext_html")).replace("\\", "")
rewrite_urls(&val(post, "selftext_html"))
};
// Build a post using data parsed from Reddit post API
@ -201,7 +201,7 @@ fn parse_comments(json: &serde_json::Value, post_link: &str, post_author: &str,
let body = if val(&comment, "author") == "[deleted]" && val(&comment, "body") == "[removed]" {
format!("<div class=\"md\"><p>[removed] — <a href=\"https://www.reveddit.com{}{}\">view removed comment</a></p></div>", post_link, id)
} else {
rewrite_urls(&val(&comment, "body_html")).to_string()
rewrite_urls(&val(&comment, "body_html"))
};
let author = Author {

View File

@ -19,6 +19,7 @@ struct SubredditTemplate {
ends: (String, String),
prefs: Preferences,
url: String,
redirect_url: String,
/// Whether the subreddit itself is filtered.
is_filtered: bool,
/// Whether all fetched posts are filtered (to differentiate between no posts fetched in the first place,
@ -86,18 +87,17 @@ pub async fn community(req: Request<Body>) -> Result<Response<Body>, String> {
} else {
Subreddit::default()
}
} else if sub_name.contains('+') {
// Multireddit
} else {
// Multireddit, all, popular
Subreddit {
name: sub_name.clone(),
..Subreddit::default()
}
} else {
Subreddit::default()
};
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 filters = get_filters(&req);
// If all requested subs are filtered, we don't need to fetch posts.
@ -109,6 +109,7 @@ pub async fn community(req: Request<Body>) -> Result<Response<Body>, String> {
ends: (param(&path, "after").unwrap_or_default(), "".to_string()),
prefs: Preferences::new(req),
url,
redirect_url,
is_filtered: true,
all_posts_filtered: false,
})
@ -124,6 +125,7 @@ pub async fn community(req: Request<Body>) -> Result<Response<Body>, String> {
ends: (param(&path, "after").unwrap_or_default(), after),
prefs: Preferences::new(req),
url,
redirect_url,
is_filtered: false,
all_posts_filtered,
})
@ -253,7 +255,7 @@ pub async fn subscriptions_filters(req: Request<Body>) -> Result<Response<Body>,
// Redirect back to subreddit
// check for redirect parameter if unsubscribing/unfiltering from outside sidebar
let path = if let Some(redirect_path) = param(&format!("?{}", query), "redirect") {
format!("/{}/", redirect_path)
format!("/{}", redirect_path)
} else {
format!("/r/{}", sub)
};
@ -334,10 +336,10 @@ pub async fn sidebar(req: Request<Body>) -> Result<Response<Body>, String> {
match json(path, quarantined).await {
// If success, receive JSON in response
Ok(response) => template(WikiTemplate {
wiki: rewrite_urls(&val(&response, "description_html").replace("\\", "")),
wiki: rewrite_urls(&val(&response, "description_html")),
// wiki: format!(
// "{}<hr><h1>Moderators</h1><br><ul>{}</ul>",
// rewrite_urls(&val(&response, "description_html").replace("\\", "")),
// rewrite_urls(&val(&response, "description_html"),
// moderators(&sub, quarantined).await.unwrap_or(vec!["Could not fetch moderators".to_string()]).join(""),
// ),
sub,
@ -409,7 +411,7 @@ async fn subreddit(sub: &str, quarantined: bool) -> Result<Subreddit, String> {
name: esc!(&res, "display_name"),
title: esc!(&res, "title"),
description: esc!(&res, "public_description"),
info: rewrite_urls(&val(&res, "description_html").replace("\\", "")),
info: rewrite_urls(&val(&res, "description_html")),
// moderators: moderators_list(sub, quarantined).await.unwrap_or_default(),
icon: format_url(&icon),
members: format_num(members),

View File

@ -15,8 +15,11 @@ struct UserTemplate {
posts: Vec<Post>,
sort: (String, String),
ends: (String, String),
/// "overview", "comments", or "submitted"
listing: String,
prefs: Preferences,
url: String,
redirect_url: String,
/// Whether the user themself is filtered.
is_filtered: bool,
/// Whether all fetched posts are filtered (to differentiate between no posts fetched in the first place,
@ -26,13 +29,17 @@ struct UserTemplate {
// FUNCTIONS
pub async fn profile(req: Request<Body>) -> Result<Response<Body>, String> {
let listing = req.param("listing").unwrap_or_else(|| "overview".to_string());
// Build the Reddit JSON API path
let path = format!(
"/user/{}.json?{}&raw_json=1",
"/user/{}/{}.json?{}&raw_json=1",
req.param("name").unwrap_or_else(|| "reddit".to_string()),
req.uri().query().unwrap_or_default()
listing,
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");
// Retrieve other variables from Libreddit request
let sort = param(&path, "sort").unwrap_or_default();
@ -46,8 +53,10 @@ pub async fn profile(req: Request<Body>) -> Result<Response<Body>, String> {
posts: Vec::new(),
sort: (sort, param(&path, "t").unwrap_or_default()),
ends: (param(&path, "after").unwrap_or_default(), "".to_string()),
listing,
prefs: Preferences::new(req),
url,
redirect_url,
is_filtered: true,
all_posts_filtered: false,
})
@ -62,8 +71,10 @@ pub async fn profile(req: Request<Body>) -> Result<Response<Body>, String> {
posts,
sort: (sort, param(&path, "t").unwrap_or_default()),
ends: (param(&path, "after").unwrap_or_default(), after),
listing,
prefs: Preferences::new(req),
url,
redirect_url,
is_filtered: false,
all_posts_filtered,
})

View File

@ -607,8 +607,12 @@ 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());
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"\", "");
// Rewrite external media previews to Libreddit
Regex::new(r"https://external-preview\.redd\.it(.*)[^?]").map_or(String::new(), |re| {
@ -710,6 +714,7 @@ pub async fn error(req: Request<Body>, msg: String) -> Result<Response<Body>, St
#[cfg(test)]
mod tests {
use super::format_num;
use super::rewrite_urls;
#[test]
fn format_num_works() {
@ -719,4 +724,13 @@ mod tests {
assert_eq!(format_num(1001), ("1.0k".to_string(), "1001".to_string()));
assert_eq!(format_num(1_999_999), ("2.0m".to_string(), "1999999".to_string()));
}
#[test]
fn rewrite_urls_removes_backslashes() {
let comment_body_html = r#"<a href=\"https://www.reddit.com/r/linux%5C_gaming/comments/x/just%5C_a%5C_test%5C/\">https://www.reddit.com/r/linux\\_gaming/comments/x/just\\_a\\_test/</a>"#;
assert_eq!(
rewrite_urls(comment_body_html),
r#"<a href="https://www.reddit.com/r/linux_gaming/comments/x/just_a_test/">https://www.reddit.com/r/linux_gaming/comments/x/just_a_test/</a>"#
)
}
}

View File

@ -177,6 +177,7 @@
html, body, div, h1, h2, h3, h4, h5, h6, ul, ol, dl, li, dt, dd, p, blockquote,
pre, form, fieldset, table, th, td, select, input {
accent-color: var(--accent);
margin: 0;
color: var(--text);
font-family: "Inter", sans-serif;
@ -487,7 +488,7 @@ aside {
/* Sorting and Search */
select, #search, #sort_options, #inside, #searchbox > *, #sort_submit {
select, #search, #sort_options, #listing_options, #inside, #searchbox > *, #sort_submit {
height: 38px;
}
@ -563,6 +564,11 @@ button.submit:hover > svg { stroke: var(--accent); }
border-radius: 5px 0px 0px 5px;
}
#listing_options + #sort_select {
margin-left: 10px;
border-radius: 5px 0px 0px 5px;
}
#search_sort {
background: var(--highlighted);
border-radius: 5px;
@ -591,7 +597,7 @@ button.submit:hover > svg { stroke: var(--accent); }
margin-bottom: 20px;
}
#sort_options, footer > a {
#sort_options, #listing_options, footer > a {
border-radius: 5px;
align-items: center;
box-shadow: var(--shadow);
@ -600,7 +606,7 @@ button.submit:hover > svg { stroke: var(--accent); }
overflow: hidden;
}
#sort_options > a, footer > a {
#sort_options > a, #listing_options > a, footer > a {
color: var(--text);
padding: 10px 20px;
text-align: center;
@ -608,12 +614,12 @@ button.submit:hover > svg { stroke: var(--accent); }
transition: 0.2s background;
}
#sort_options > a.selected {
#sort_options > a.selected, #listing_options > a.selected {
background: var(--accent);
color: var(--foreground);
}
#sort_options > a:not(.selected):hover {
#sort_options > a:not(.selected):hover, #listing_options > a:not(.selected):hover {
background: var(--foreground);
}
@ -749,6 +755,7 @@ a.search_subreddit:hover {
font-size: 16px;
font-weight: 500;
line-height: 1.5;
overflow-wrap: anywhere;
margin: 5px 15px 5px 12px;
grid-area: post_title;
}
@ -878,6 +885,7 @@ a.search_subreddit:hover {
color: var(--accent);
margin: 5px 12px;
grid-area: post_media;
overflow-wrap: anywhere;
}
.post_body {
@ -1311,6 +1319,8 @@ input[type="submit"] {
.md table {
margin: 5px;
overflow-x: auto;
display: block;
max-width: fit-content;
}
.md code {

View File

@ -13,7 +13,7 @@
{% if author.name != "[deleted]" %}
<a class="comment_author {{ author.distinguished }} {% if author.name == post_author %}op{% endif %}" href="/user/{{ author.name }}">u/{{ author.name }}</a>
{% else %}
<span class="comment_author">u/[deleted]</span>
<span class="comment_author {{ author.distinguished }}">u/[deleted]</span>
{% endif %}
{% if author.flair.flair_parts.len() > 0 %}
<small class="author_flair">{% call utils::render_flair(author.flair.flair_parts) %}</small>

View File

@ -37,7 +37,7 @@
<p class="post_header">
<a class="post_subreddit" href="/r/{{ post.community }}">r/{{ post.community }}</a>
<span class="dot">&bull;</span>
<a class="post_author" href="/user/{{ post.author.name }}">u/{{ post.author.name }}</a>
<a class="post_author {{ post.author.distinguished }}" href="/user/{{ post.author.name }}">u/{{ post.author.name }}</a>
{% if post.author.flair.flair_parts.len() > 0 %}
<small class="author_flair">{% call utils::render_flair(post.author.flair.flair_parts) %}</small>
{% endif %}

View File

@ -41,7 +41,7 @@
</form>
{% if sub.name.contains("+") %}
<form action="/r/{{ sub.name }}/subscribe" method="POST">
<form action="/r/{{ sub.name }}/subscribe?redirect={{ redirect_url }}" method="POST">
<button id="multisub" class="subscribe" title="Subscribe to each sub in this multireddit">Subscribe to Multireddit</button>
</form>
{% endif %}
@ -74,12 +74,12 @@
</footer>
</div>
{% endif %}
{% if is_filtered || (!sub.name.is_empty() && !sub.name.contains("+")) %}
{% if is_filtered || (!sub.name.is_empty() && sub.name != "all" && sub.name != "popular" && !sub.name.contains("+")) %}
<aside>
{% if is_filtered %}
<center>(Content from r/{{ sub.name }} has been filtered)</center>
{% endif %}
{% if !sub.name.is_empty() && !sub.name.contains("+") %}
{% if !sub.name.is_empty() && sub.name != "all" && sub.name != "popular" && !sub.name.contains("+") %}
<div class="panel" id="subreddit">
{% if sub.wiki %}
<div id="top">
@ -101,22 +101,22 @@
<div id="sub_actions">
<div id="sub_subscription">
{% if prefs.subscriptions.contains(sub.name) %}
<form action="/r/{{ sub.name }}/unsubscribe" method="POST">
<form action="/r/{{ sub.name }}/unsubscribe?redirect={{ redirect_url }}" method="POST">
<button class="unsubscribe">Unsubscribe</button>
</form>
{% else %}
<form action="/r/{{ sub.name }}/subscribe" method="POST">
<form action="/r/{{ sub.name }}/subscribe?redirect={{ redirect_url }}" method="POST">
<button class="subscribe">Subscribe</button>
</form>
{% endif %}
</div>
<div id="sub_filter">
{% if prefs.filters.contains(sub.name) %}
<form action="/r/{{ sub.name }}/unfilter" method="POST">
<form action="/r/{{ sub.name }}/unfilter?redirect={{ redirect_url }}" method="POST">
<button class="unfilter">Unfilter</button>
</form>
{% else %}
<form action="/r/{{ sub.name }}/filter" method="POST">
<form action="/r/{{ sub.name }}/filter?redirect={{ redirect_url }}" method="POST">
<button class="filter">Filter</button>
</form>
{% endif %}

View File

@ -16,9 +16,12 @@
{% if !is_filtered %}
<div id="column_one">
<form id="sort">
<select name="sort">
{% call utils::options(sort.0, ["hot", "new", "top"], "") %}
</select>{% if sort.0 == "top" %}<select id="timeframe" name="t">
<div id="listing_options">
{% call utils::sort(["/user/", user.name.as_str()].concat(), ["overview", "comments", "submitted"], listing) %}
</div>
<select id="sort_select" name="sort">
{% call utils::options(sort.0, ["hot", "new", "top", "controversial"], "") %}
</select>{% if sort.0 == "top" || sort.0 == "controversial" %}<select id="timeframe" name="t">
{% call utils::options(sort.1, ["hour", "day", "week", "month", "year", "all"], "all") %}
</select>{% endif %}<button id="sort_submit" class="submit">
<svg width="15" viewBox="0 0 110 100" fill="none" stroke-width="10" stroke-linecap="round">
@ -91,22 +94,22 @@
{% let name = ["u_", user.name.as_str()].join("") %}
<div id="user_subscription">
{% if prefs.subscriptions.contains(name) %}
<form action="/r/{{ name }}/unsubscribe" method="POST">
<form action="/r/{{ name }}/unsubscribe?redirect={{ redirect_url }}" method="POST">
<button class="unsubscribe">Unfollow</button>
</form>
{% else %}
<form action="/r/{{ name }}/subscribe" method="POST">
<form action="/r/{{ name }}/subscribe?redirect={{ redirect_url }}" method="POST">
<button class="subscribe">Follow</button>
</form>
{% endif %}
</div>
<div id="user_filter">
{% if prefs.filters.contains(name) %}
<form action="/r/{{ name }}/unfilter" method="POST">
<form action="/r/{{ name }}/unfilter?redirect={{ redirect_url }}" method="POST">
<button class="unfilter">Unfilter</button>
</form>
{% else %}
<form action="/r/{{ name }}/filter" method="POST">
<form action="/r/{{ name }}/filter?redirect={{ redirect_url }}" method="POST">
<button class="filter">Filter</button>
</form>
{% endif %}

View File

@ -72,7 +72,7 @@
{% endif -%}
<a class="post_subreddit" href="/{{ community }}">{{ community }}</a>
<span class="dot">&bull;</span>
<a class="post_author" href="/u/{{ post.author.name }}">u/{{ post.author.name }}</a>
<a class="post_author {{ post.author.distinguished }}" href="/u/{{ post.author.name }}">u/{{ post.author.name }}</a>
<span class="dot">&bull;</span>
<span class="created" title="{{ post.created }}">{{ post.rel_time }}</span>
{% if !post.awards.is_empty() %}