Compare commits

...

3 Commits

Author SHA1 Message Date
66ac72beab Fix clippy errors 2021-03-26 20:00:47 -07:00
14f9ac4ca7 Automatically draft a release on push 2021-03-26 21:48:00 +00:00
6a7f725c12 Default subreddit post sorting. Closes #166 2021-03-25 21:41:58 -07:00
12 changed files with 60 additions and 54 deletions

View File

@ -21,9 +21,29 @@ jobs:
- name: Build
run: cargo build --release
- uses: actions/upload-artifact@v2.2.1
name: Upload a Build Artifact
with:
name: libreddit
path: target/release/libreddit
- name: Versions
id: version
run: |
echo "::set-output name=version::$(cargo metadata --format-version 1 --no-deps | jq .packages[0].version -r | sed 's/^/v/')"
echo "::set-output name=tag::${GITHUB_REF#refs/*/}"
- name: Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ steps.version.outputs.version }}
name: ${{ steps.version.outputs.version }} - NAME
draft: true
files: target/release/libreddit
body: |
- CHANGES
See full list of changes [here](https://github.com/spikecodes/libreddit/compare/${{ steps.version.outputs.tag }}...${{ steps.version.outputs.version }}).
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}

View File

@ -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.7.0"
version = "0.8.1"
authors = ["spikecodes <19519553+spikecodes@users.noreply.github.com>"]
edition = "2018"
@ -13,10 +13,10 @@ async-recursion = "0.3.2"
cached = "0.23.0"
clap = { version = "2.33.3", default-features = false }
regex = "1.4.5"
serde = { version = "1.0.124", features = ["derive"] }
serde = { version = "1.0.125", features = ["derive"] }
cookie = "0.15.0"
futures-lite = "1.11.3"
hyper = { version = "0.14.4", features = ["full"] }
hyper = { version = "0.14.5", features = ["full"] }
hyper-rustls = "0.22.1"
route-recognizer = "0.3.0"
serde_json = "1.0.64"

View File

@ -21,20 +21,6 @@
---
## Jump to...
- [About](#about)
- [Teddit Comparison](#how-does-it-compare-to-teddit)
- [Comparison](#comparison)
- [Installation](#installation)
- [Cargo](#1-cargo)
- [Docker](#2-docker)
- [AUR](#3-aur)
- [GitHub Releases](#4-github-releases)
- [Replit](#5-replit)
- [Deployment](#deployment)
---
# Instances
Feel free to [open an issue](https://github.com/spikecodes/libreddit/issues/new) to have your [selfhosted instance](#deployment) listed here!

View File

@ -134,6 +134,6 @@ pub async fn json(path: String) -> Result<Value, String> {
Err(e) => err("Failed receiving body from Reddit", e.to_string()),
}
}
Err(e) => err("Couldn't send request to Reddit", e.to_string()),
Err(e) => err("Couldn't send request to Reddit", e),
}
}

View File

@ -6,7 +6,8 @@
clippy::match_wildcard_for_single_variants,
clippy::cast_possible_truncation,
clippy::similar_names,
clippy::cast_possible_wrap
clippy::cast_possible_wrap,
clippy::find_map
)]
// Reference local files

View File

@ -40,7 +40,7 @@ pub async fn item(req: Request<Body>) -> Result<Response<Body>, String> {
#[cfg(debug_assertions)]
dbg!(req.param("id").unwrap_or_default());
let single_thread = &req.param("comment_id").is_some();
let single_thread = req.param("comment_id").is_some();
let highlighted_comment = &req.param("comment_id").unwrap_or_default();
// Send a request to the url, receive JSON in response
@ -57,7 +57,7 @@ pub async fn item(req: Request<Body>) -> Result<Response<Body>, String> {
post,
sort,
prefs: Preferences::new(req),
single_thread: *single_thread,
single_thread,
})
}
// If the Reddit API returns an error, exit and send error page to user

View File

@ -61,7 +61,7 @@ impl RequestExt for Request<Body> {
}
fn param(&self, name: &str) -> Option<String> {
self.params().find(name).map(|s| s.to_owned())
self.params().find(name).map(std::borrow::ToOwned::to_owned)
}
fn set_params(&mut self, params: Params) -> Option<Params> {
@ -72,14 +72,14 @@ impl RequestExt for Request<Body> {
let mut cookies = Vec::new();
if let Some(header) = self.headers().get("Cookie") {
for cookie in header.to_str().unwrap_or_default().split("; ") {
cookies.push(Cookie::parse(cookie).unwrap_or(Cookie::named("")));
cookies.push(Cookie::parse(cookie).unwrap_or_else(|_| Cookie::named("")));
}
}
cookies
}
fn cookie(&self, name: &str) -> Option<Cookie> {
self.cookies().iter().find(|c| c.name() == name).map(|c| c.to_owned())
self.cookies().iter().find(|c| c.name() == name).map(std::borrow::ToOwned::to_owned)
}
}

View File

@ -16,19 +16,6 @@ struct SettingsTemplate {
prefs: Preferences,
}
#[derive(serde::Deserialize, Default, Debug)]
#[serde(default)]
pub struct Form {
theme: Option<String>,
front_page: Option<String>,
layout: Option<String>,
wide: Option<String>,
comment_sort: Option<String>,
show_nsfw: Option<String>,
redirect: Option<String>,
subscriptions: Option<String>,
}
// FUNCTIONS
// Retrieve cookies from request "Cookie" header
@ -63,7 +50,7 @@ pub async fn set(req: Request<Body>) -> Result<Response<Body>, String> {
let mut res = redirect("/settings".to_string());
let names = vec!["theme", "front_page", "layout", "wide", "comment_sort", "show_nsfw", "subscriptions"];
let names = vec!["theme", "front_page", "layout", "wide", "comment_sort", "post_sort", "show_nsfw", "subscriptions"];
for name in names {
match form.get(name) {
@ -98,7 +85,7 @@ pub async fn restore(req: Request<Body>) -> Result<Response<Body>, String> {
let form = url::form_urlencoded::parse(query).collect::<HashMap<_, _>>();
let names = vec!["theme", "front_page", "layout", "wide", "comment_sort", "show_nsfw", "subscriptions"];
let names = vec!["theme", "front_page", "layout", "wide", "comment_sort", "post_sort", "show_nsfw", "subscriptions"];
let path = match form.get("redirect") {
Some(value) => format!("/{}/", value),

View File

@ -32,17 +32,21 @@ pub async fn community(req: Request<Body>) -> Result<Response<Body>, String> {
// Build Reddit API path
let subscribed = cookie(&req, "subscriptions");
let front_page = cookie(&req, "front_page");
let sort = req.param("sort").unwrap_or_else(|| req.param("id").unwrap_or("hot".to_string()));
let post_sort = req.cookie("post_sort").map_or_else(|| "hot".to_string(), |c| c.value().to_string());
let sort = req.param("sort").unwrap_or_else(|| req.param("id").unwrap_or(post_sort));
let sub = req.param("sub").map(String::from).unwrap_or(if front_page == "default" || front_page.is_empty() {
if subscribed.is_empty() {
"popular".to_string()
let sub = req.param("sub").map_or(
if front_page == "default" || front_page.is_empty() {
if subscribed.is_empty() {
"popular".to_string()
} else {
subscribed.to_owned()
}
} else {
subscribed.to_owned()
}
} else {
front_page.to_owned()
});
front_page.to_owned()
},
String::from,
);
let path = format!("/r/{}/{}.json?{}&raw_json=1", sub, sort, req.uri().query().unwrap_or_default());
@ -88,7 +92,7 @@ pub async fn community(req: Request<Body>) -> Result<Response<Body>, String> {
// Sub or unsub by setting subscription cookie using response "Set-Cookie" header
pub async fn subscriptions(req: Request<Body>) -> Result<Response<Body>, String> {
let sub = req.param("sub").unwrap_or_default().to_string();
let sub = req.param("sub").unwrap_or_default();
let query = req.uri().query().unwrap_or_default().to_string();
let action: Vec<String> = req.uri().path().split('/').map(String::from).collect();
@ -136,8 +140,8 @@ pub async fn subscriptions(req: Request<Body>) -> Result<Response<Body>, String>
}
pub async fn wiki(req: Request<Body>) -> Result<Response<Body>, String> {
let sub = req.param("sub").unwrap_or("reddit.com".to_string());
let page = req.param("page").unwrap_or("index".to_string());
let sub = req.param("sub").unwrap_or_else(|| "reddit.com".to_string());
let page = req.param("page").unwrap_or_else(|| "index".to_string());
let path: String = format!("/r/{}/wiki/{}.json?raw_json=1", sub, page);
match json(path).await {
@ -152,7 +156,7 @@ pub async fn wiki(req: Request<Body>) -> Result<Response<Body>, String> {
}
pub async fn sidebar(req: Request<Body>) -> Result<Response<Body>, String> {
let sub = req.param("sub").unwrap_or("reddit.com".to_string());
let sub = req.param("sub").unwrap_or_else(|| "reddit.com".to_string());
// Build the Reddit JSON API url
let path: String = format!("/r/{}/about.json?raw_json=1", sub);

View File

@ -23,7 +23,7 @@ pub async fn profile(req: Request<Body>) -> Result<Response<Body>, String> {
// Build the Reddit JSON API path
let path = format!(
"/user/{}.json?{}&raw_json=1",
req.param("name").unwrap_or("reddit".to_string()),
req.param("name").unwrap_or_else(|| "reddit".to_string()),
req.uri().query().unwrap_or_default()
);

View File

@ -365,6 +365,7 @@ pub struct Preferences {
pub wide: String,
pub show_nsfw: String,
pub comment_sort: String,
pub post_sort: String,
pub subscriptions: Vec<String>,
}
@ -378,6 +379,7 @@ impl Preferences {
wide: cookie(&req, "wide"),
show_nsfw: cookie(&req, "show_nsfw"),
comment_sort: cookie(&req, "comment_sort"),
post_sort: cookie(&req, "post_sort"),
subscriptions: cookie(&req, "subscriptions").split('+').map(String::from).filter(|s| !s.is_empty()).collect(),
}
}

View File

@ -36,6 +36,12 @@
<input type="checkbox" name="wide" {% if prefs.wide == "on" %}checked{% endif %}>
</div>
<p>Content</p>
<div id="post_sort">
<label for="post_sort" title="Applies only to subreddit feeds">Default subreddit post sort:</label>
<select name="post_sort">
{% call utils::options(prefs.post_sort, ["hot", "new", "top", "rising", "controversial"], "hot") %}
</select>
</div>
<div id="comment_sort">
<label for="comment_sort">Default comment sort:</label>
<select name="comment_sort">