commit
18fe7ff8cf
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -1485,18 +1485,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.119"
|
version = "1.0.120"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9bdd36f49e35b61d49efd8aa7fc068fd295961fd2286d0b2ee9a4c7a14e99cc3"
|
checksum = "166b2349061381baf54a58e4b13c89369feb0ef2eaa57198899e2312aac30aab"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.119"
|
version = "1.0.120"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "552954ce79a059ddd5fd68c271592374bd15cab2274970380c000118aeffe1cd"
|
checksum = "0ca2a8cb5805ce9e3b95435e3765b7b553cecc762d938d409434338386cb5775"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
18
Cargo.toml
18
Cargo.toml
@ -8,14 +8,14 @@ authors = ["spikecodes <19519553+spikecodes@users.noreply.github.com>"]
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base64 = "0.13.0"
|
base64 = "0.13"
|
||||||
actix-web = { version = "3.3.2", features = ["rustls"] }
|
actix-web = { version = "3.3", features = ["rustls"] }
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
askama = "0.10.5"
|
askama = "0.10"
|
||||||
ureq = "2.0.1"
|
ureq = "2.0"
|
||||||
serde = { version = "1.0.118", default_features = false, features = ["derive"] }
|
serde = { version = "1.0", default_features = false, features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
async-recursion = "0.3.1"
|
async-recursion = "0.3"
|
||||||
url = "2.2.0"
|
url = "2.2"
|
||||||
regex = "1.4.2"
|
regex = "1.4"
|
||||||
time = "0.2.23"
|
time = "0.2"
|
37
src/main.rs
37
src/main.rs
@ -53,15 +53,16 @@ async fn main() -> std::io::Result<()> {
|
|||||||
.wrap_fn(move |req, srv| {
|
.wrap_fn(move |req, srv| {
|
||||||
let secure = req.connection_info().scheme() == "https";
|
let secure = req.connection_info().scheme() == "https";
|
||||||
let https_url = format!("https://{}{}", req.connection_info().host(), req.uri().to_string());
|
let https_url = format!("https://{}{}", req.connection_info().host(), req.uri().to_string());
|
||||||
srv.call(req).map(move |res: Result<ServiceResponse, _>| {
|
srv.call(req).map(move |res: Result<ServiceResponse, _>|
|
||||||
if force_https && !secure {
|
if force_https && !secure {
|
||||||
let redirect: ServiceResponse<actix_web::dev::Body> =
|
Ok(ServiceResponse::new(
|
||||||
ServiceResponse::new(res.unwrap().request().clone(), HttpResponse::Found().header("Location", https_url).finish());
|
res.unwrap().request().to_owned(),
|
||||||
Ok(redirect)
|
HttpResponse::Found().header("Location", https_url).finish(),
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
})
|
})
|
||||||
// Append trailing slash and remove double slashes
|
// Append trailing slash and remove double slashes
|
||||||
.wrap(middleware::NormalizePath::default())
|
.wrap(middleware::NormalizePath::default())
|
||||||
@ -106,23 +107,19 @@ async fn main() -> std::io::Result<()> {
|
|||||||
.route("/{page}/", web::get().to(subreddit::wiki)),
|
.route("/{page}/", web::get().to(subreddit::wiki)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
// Universal services
|
// Front page
|
||||||
|
.route("/", web::get().to(subreddit::page))
|
||||||
|
.route("/{sort:best|hot|new|top|rising|controversial}/", web::get().to(subreddit::page))
|
||||||
|
// View Reddit wiki
|
||||||
.service(
|
.service(
|
||||||
web::scope("")
|
web::scope("/wiki")
|
||||||
// Front page
|
.route("/", web::get().to(subreddit::wiki))
|
||||||
.route("/", web::get().to(subreddit::page))
|
.route("/{page}/", web::get().to(subreddit::wiki)),
|
||||||
.route("/{sort:best|hot|new|top|rising|controversial}/", web::get().to(subreddit::page))
|
|
||||||
// View Reddit wiki
|
|
||||||
.service(
|
|
||||||
web::scope("/wiki")
|
|
||||||
.route("/", web::get().to(subreddit::wiki))
|
|
||||||
.route("/{page}/", web::get().to(subreddit::wiki)),
|
|
||||||
)
|
|
||||||
// Search all of Reddit
|
|
||||||
.route("/search/", web::get().to(search::find))
|
|
||||||
// Short link for post
|
|
||||||
.route("/{id:.{5,6}}/", web::get().to(post::item)),
|
|
||||||
)
|
)
|
||||||
|
// Search all of Reddit
|
||||||
|
.route("/search/", web::get().to(search::find))
|
||||||
|
// Short link for post
|
||||||
|
.route("/{id:.{5,6}}/", web::get().to(post::item))
|
||||||
})
|
})
|
||||||
.bind(&address)
|
.bind(&address)
|
||||||
.unwrap_or_else(|e| panic!("Cannot bind to the address {}: {}", address, e))
|
.unwrap_or_else(|e| panic!("Cannot bind to the address {}: {}", address, e))
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// CRATES
|
// CRATES
|
||||||
use crate::utils::{error, fetch_posts, param, prefs, request, val, Post, Preferences};
|
use crate::utils::{cookie, error, fetch_posts, param, prefs, request, val, Post, Preferences};
|
||||||
use actix_web::{HttpRequest, HttpResponse};
|
use actix_web::{HttpRequest, HttpResponse};
|
||||||
use askama::Template;
|
use askama::Template;
|
||||||
|
|
||||||
@ -33,7 +33,8 @@ struct SearchTemplate {
|
|||||||
|
|
||||||
// SERVICES
|
// SERVICES
|
||||||
pub async fn find(req: HttpRequest) -> HttpResponse {
|
pub async fn find(req: HttpRequest) -> HttpResponse {
|
||||||
let path = format!("{}.json?{}", req.path(), req.query_string());
|
let nsfw_results = if cookie(&req, "hide_nsfw") != "on" { "&include_over_18=on" } else { "" };
|
||||||
|
let path = format!("{}.json?{}{}", req.path(), req.query_string(), nsfw_results);
|
||||||
let sub = req.match_info().get("sub").unwrap_or("").to_string();
|
let sub = req.match_info().get("sub").unwrap_or("").to_string();
|
||||||
|
|
||||||
let sort = if param(&path, "sort").is_empty() {
|
let sort = if param(&path, "sort").is_empty() {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// CRATES
|
// CRATES
|
||||||
use crate::utils::{prefs, Preferences};
|
use crate::utils::{prefs, Preferences};
|
||||||
use actix_web::{cookie::Cookie, web::Form, HttpMessage, HttpRequest, HttpResponse};
|
use actix_web::{cookie::Cookie, web::Form, HttpRequest, HttpResponse};
|
||||||
use askama::Template;
|
use askama::Template;
|
||||||
use time::{Duration, OffsetDateTime};
|
use time::{Duration, OffsetDateTime};
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ pub async fn get(req: HttpRequest) -> HttpResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set cookies using response "Set-Cookie" header
|
// Set cookies using response "Set-Cookie" header
|
||||||
pub async fn set(req: HttpRequest, form: Form<SettingsForm>) -> HttpResponse {
|
pub async fn set(_req: HttpRequest, form: Form<SettingsForm>) -> HttpResponse {
|
||||||
let mut res = HttpResponse::Found();
|
let mut res = HttpResponse::Found();
|
||||||
|
|
||||||
let names = vec!["theme", "front_page", "layout", "wide", "comment_sort", "hide_nsfw"];
|
let names = vec!["theme", "front_page", "layout", "wide", "comment_sort", "hide_nsfw"];
|
||||||
@ -45,10 +45,7 @@ pub async fn set(req: HttpRequest, form: Form<SettingsForm>) -> HttpResponse {
|
|||||||
.expires(OffsetDateTime::now_utc() + Duration::weeks(52))
|
.expires(OffsetDateTime::now_utc() + Duration::weeks(52))
|
||||||
.finish(),
|
.finish(),
|
||||||
),
|
),
|
||||||
None => match HttpMessage::cookie(&req, name.to_owned()) {
|
None => res.del_cookie(&Cookie::named(name.to_owned())),
|
||||||
Some(cookie) => res.del_cookie(&cookie),
|
|
||||||
None => &mut res,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ async fn subreddit(sub: &str) -> Result<Subreddit, String> {
|
|||||||
let active: i64 = res["data"]["accounts_active"].as_u64().unwrap_or_default() as i64;
|
let active: i64 = res["data"]["accounts_active"].as_u64().unwrap_or_default() as i64;
|
||||||
|
|
||||||
// Fetch subreddit icon either from the community_icon or icon_img value
|
// Fetch subreddit icon either from the community_icon or icon_img value
|
||||||
let community_icon: &str = res["data"]["community_icon"].as_str().unwrap_or("").split('?').collect::<Vec<&str>>()[0];
|
let community_icon: &str = res["data"]["community_icon"].as_str().map_or("", |s| s.split('?').collect::<Vec<&str>>()[0]);
|
||||||
let icon = if community_icon.is_empty() { val(&res, "icon_img") } else { community_icon.to_string() };
|
let icon = if community_icon.is_empty() { val(&res, "icon_img") } else { community_icon.to_string() };
|
||||||
|
|
||||||
let sub = Subreddit {
|
let sub = Subreddit {
|
||||||
|
@ -286,7 +286,7 @@ pub fn time(created: f64) -> (String, String) {
|
|||||||
|
|
||||||
// val() function used to parse JSON from Reddit APIs
|
// val() function used to parse JSON from Reddit APIs
|
||||||
pub fn val(j: &Value, k: &str) -> String {
|
pub fn val(j: &Value, k: &str) -> String {
|
||||||
String::from(j["data"][k].as_str().unwrap_or_default())
|
j["data"][k].as_str().unwrap_or_default().to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch posts of a user or subreddit and return a vector of posts and the "after" value
|
// Fetch posts of a user or subreddit and return a vector of posts and the "after" value
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
User-agent: *
|
|
||||||
Allow: /
|
|
@ -460,7 +460,7 @@ a.search_subreddit:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.post_score {
|
.post_score {
|
||||||
padding-top: 20px;
|
padding-top: 16px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-align: end;
|
text-align: end;
|
||||||
@ -476,7 +476,7 @@ a.search_subreddit:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.post_header {
|
.post_header {
|
||||||
margin: 20px 20px 5px 20px;
|
margin: 15px 20px 5px 15px;
|
||||||
grid-area: post_header;
|
grid-area: post_header;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,7 +487,7 @@ a.search_subreddit:hover {
|
|||||||
.post_title {
|
.post_title {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
margin: 5px 20px;
|
margin: 5px 15px;
|
||||||
grid-area: post_title;
|
grid-area: post_title;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -548,7 +548,7 @@ a.search_subreddit:hover {
|
|||||||
.post_body {
|
.post_body {
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
margin: 5px 20px;
|
margin: 5px 15px;
|
||||||
grid-area: post_body;
|
grid-area: post_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,7 +558,7 @@ a.search_subreddit:hover {
|
|||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
grid-area: post_footer;
|
grid-area: post_footer;
|
||||||
margin: 5px 20px 20px 20px;
|
margin: 5px 20px 15px 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post_comments {
|
.post_comments {
|
||||||
@ -675,6 +675,7 @@ a.search_subreddit:hover {
|
|||||||
padding: 10px 0 10px 5px;
|
padding: 10px 0 10px 5px;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
flex-shrink: 1;
|
flex-shrink: 1;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment_data > * {
|
.comment_data > * {
|
||||||
@ -924,20 +925,13 @@ td, th {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.post_score {
|
.post_score {
|
||||||
background-color: unset;
|
margin: 5px 0px 20px 15px;
|
||||||
margin: 5px 0px 20px 20px;
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.compact .post_score {
|
.compact .post_score { padding: 0; }
|
||||||
background-color: unset;
|
|
||||||
margin: 2.5px 0px 15px 15px;
|
|
||||||
padding: 0;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.post_score::before { content: "↑" }
|
.post_score::before { content: "↑" }
|
||||||
.post:hover > .post_score { background: unset; }
|
|
||||||
|
|
||||||
.post_header { font-size: 14px; }
|
.post_header { font-size: 14px; }
|
||||||
.post_footer { margin-left: 15px; }
|
.post_footer { margin-left: 15px; }
|
||||||
|
Loading…
Reference in New Issue
Block a user