Added Percent Encoding Support
This commit is contained in:
parent
8f157c0b40
commit
9a6430656d
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -1394,11 +1394,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libreddit"
|
||||
version = "0.1.7"
|
||||
version = "0.1.8"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"askama",
|
||||
"chrono",
|
||||
"percent-encoding",
|
||||
"pulldown-cmark",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -3,15 +3,16 @@ name = "libreddit"
|
||||
description = " Alternative private front-end to Reddit"
|
||||
license = "AGPL-3.0"
|
||||
repository = "https://github.com/spikecodes/libreddit"
|
||||
version = "0.1.7"
|
||||
version = "0.1.8"
|
||||
authors = ["spikecodes <19519553+spikecodes@users.noreply.github.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[features]
|
||||
default = ["proxy"]
|
||||
proxy = ["actix-web/rustls"]
|
||||
proxy = ["actix-web/rustls", "percent-encoding"]
|
||||
|
||||
[dependencies]
|
||||
percent-encoding = { version = "2.1.0", optional = true }
|
||||
actix-web = "3.2.0"
|
||||
surf = "2.1.0"
|
||||
askama = "0.8.0"
|
||||
|
16534
cargo-timing.html
16534
cargo-timing.html
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
edition = "2018"
|
||||
tab_spaces = 2
|
||||
hard_tabs = true
|
||||
max_width = 200
|
||||
max_width = 175
|
@ -4,9 +4,9 @@ use actix_web::{get, App, HttpResponse, HttpServer};
|
||||
// Reference local files
|
||||
mod popular;
|
||||
mod post;
|
||||
mod proxy;
|
||||
mod subreddit;
|
||||
mod user;
|
||||
mod proxy;
|
||||
mod utils;
|
||||
|
||||
// Create Services
|
||||
|
@ -1,7 +1,7 @@
|
||||
// CRATES
|
||||
use actix_web::{get, web, HttpResponse, Result, http::StatusCode};
|
||||
use askama::Template;
|
||||
use crate::utils::{fetch_posts, ErrorTemplate, Params, Post};
|
||||
use actix_web::{get, http::StatusCode, web, HttpResponse, Result};
|
||||
use askama::Template;
|
||||
|
||||
// STRUCTS
|
||||
#[derive(Template)]
|
||||
|
26
src/post.rs
26
src/post.rs
@ -1,9 +1,12 @@
|
||||
// CRATES
|
||||
use actix_web::{get, web, HttpResponse, Result, http::StatusCode};
|
||||
use crate::utils::{request, val, Comment, ErrorTemplate, Flair, Params, Post};
|
||||
use actix_web::{get, http::StatusCode, web, HttpResponse, Result};
|
||||
use askama::Template;
|
||||
use chrono::{TimeZone, Utc};
|
||||
use pulldown_cmark::{html, Options, Parser};
|
||||
use crate::utils::{request, val, Comment, ErrorTemplate, Flair, Params, Post};
|
||||
|
||||
#[cfg(feature = "proxy")]
|
||||
use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
|
||||
|
||||
// STRUCTS
|
||||
#[derive(Template)]
|
||||
@ -66,6 +69,14 @@ async fn page(web::Path((_sub, id)): web::Path<(String, String)>, params: web::Q
|
||||
}
|
||||
}
|
||||
|
||||
async fn format_url(url: &str) -> String {
|
||||
#[cfg(feature = "proxy")]
|
||||
return utf8_percent_encode(url, NON_ALPHANUMERIC).to_string();
|
||||
|
||||
#[cfg(not(feature = "proxy"))]
|
||||
return url.to_string();
|
||||
}
|
||||
|
||||
// UTILITIES
|
||||
async fn media(data: &serde_json::Value) -> String {
|
||||
let post_hint: &str = data["data"]["post_hint"].as_str().unwrap_or("");
|
||||
@ -76,15 +87,20 @@ async fn media(data: &serde_json::Value) -> String {
|
||||
let media: String = if !has_media {
|
||||
format!(r#"<h4 class="post_body"><a href="{u}">{u}</a></h4>"#, u = data["data"]["url"].as_str().unwrap())
|
||||
} else {
|
||||
format!(r#"<img class="post_image" src="{}{}.png"/>"#, prefix, data["data"]["url"].as_str().unwrap())
|
||||
format!(
|
||||
r#"<img class="post_image" src="{}{}.png"/>"#,
|
||||
prefix,
|
||||
format_url(data["data"]["url"].as_str().unwrap()).await
|
||||
)
|
||||
};
|
||||
|
||||
match post_hint {
|
||||
"hosted:video" => format!(
|
||||
r#"<video class="post_image" src="{}{}" controls/>"#,
|
||||
prefix, data["data"]["media"]["reddit_video"]["fallback_url"].as_str().unwrap()
|
||||
prefix,
|
||||
format_url(data["data"]["media"]["reddit_video"]["fallback_url"].as_str().unwrap()).await
|
||||
),
|
||||
"image" => format!(r#"<img class="post_image" src="{}{}"/>"#, prefix, data["data"]["url"].as_str().unwrap()),
|
||||
"image" => format!(r#"<img class="post_image" src="{}{}"/>"#, prefix, format_url(data["data"]["url"].as_str().unwrap()).await),
|
||||
"self" => String::from(""),
|
||||
_ => media,
|
||||
}
|
||||
|
23
src/proxy.rs
23
src/proxy.rs
@ -1,18 +1,27 @@
|
||||
use actix_web::{get, web, HttpResponse, Result, client::Client, Error};
|
||||
use actix_web::{client::Client, get, web, Error, HttpResponse, Result};
|
||||
|
||||
#[cfg(feature = "proxy")]
|
||||
use percent_encoding::percent_decode_str;
|
||||
|
||||
#[get("/imageproxy/{url:.*}")]
|
||||
async fn handler(web::Path(url): web::Path<String>) -> Result<HttpResponse> {
|
||||
if cfg!(feature = "proxy") {
|
||||
dbg!(&url);
|
||||
#[cfg(feature = "proxy")]
|
||||
let media: String = percent_decode_str(url.as_str()).decode_utf8()?.to_string();
|
||||
|
||||
#[cfg(not(feature = "proxy"))]
|
||||
let media: String = url;
|
||||
|
||||
dbg!(&media);
|
||||
|
||||
let client = Client::default();
|
||||
client.get(url)
|
||||
client
|
||||
.get(media)
|
||||
.send()
|
||||
.await
|
||||
.map_err(Error::from)
|
||||
.and_then(|res| {
|
||||
Ok(HttpResponse::build(res.status()).streaming(res))
|
||||
})
|
||||
.and_then(|res| Ok(HttpResponse::build(res.status()).streaming(res)))
|
||||
} else {
|
||||
Ok(HttpResponse::Ok().body(""))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// CRATES
|
||||
use actix_web::{get, web, HttpResponse, Result, http::StatusCode};
|
||||
use crate::utils::{fetch_posts, request, val, ErrorTemplate, Params, Post, Subreddit};
|
||||
use actix_web::{get, http::StatusCode, web, HttpResponse, Result};
|
||||
use askama::Template;
|
||||
use crate::utils::{request, val, fetch_posts, ErrorTemplate, Params, Post, Subreddit};
|
||||
|
||||
// STRUCTS
|
||||
#[derive(Template)]
|
||||
@ -10,7 +10,7 @@ struct SubredditTemplate {
|
||||
sub: Subreddit,
|
||||
posts: Vec<Post>,
|
||||
sort: String,
|
||||
ends: (String, String)
|
||||
ends: (String, String),
|
||||
}
|
||||
|
||||
// SERVICES
|
||||
@ -57,7 +57,7 @@ pub async fn render(sub_name: String, sort: Option<String>, ends: (Option<String
|
||||
sub: sub,
|
||||
posts: items.0,
|
||||
sort: sorting,
|
||||
ends: (before, items.1)
|
||||
ends: (before, items.1),
|
||||
}
|
||||
.render()
|
||||
.unwrap();
|
||||
@ -82,7 +82,7 @@ async fn subreddit(sub: &String) -> Result<Subreddit, &'static str> {
|
||||
let res = req.unwrap();
|
||||
|
||||
let members = res["data"]["subscribers"].as_u64().unwrap_or(0);
|
||||
let active = res["data"]["accounts_active"].as_u64().unwrap_or(0);
|
||||
let active = res["data"]["accounts_active"].as_u64().unwrap_or(0);
|
||||
|
||||
let sub = Subreddit {
|
||||
name: val(&res, "display_name").await,
|
||||
@ -94,4 +94,4 @@ async fn subreddit(sub: &String) -> Result<Subreddit, &'static str> {
|
||||
};
|
||||
|
||||
Ok(sub)
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// CRATES
|
||||
use actix_web::{get, web, HttpResponse, Result, http::StatusCode};
|
||||
use crate::utils::{fetch_posts, nested_val, request, ErrorTemplate, Params, Post, User};
|
||||
use actix_web::{get, http::StatusCode, web, HttpResponse, Result};
|
||||
use askama::Template;
|
||||
use crate::utils::{nested_val, request, fetch_posts, ErrorTemplate, Params, Post, User};
|
||||
|
||||
// STRUCTS
|
||||
#[derive(Template)]
|
||||
@ -71,4 +71,4 @@ async fn user(name: &String) -> Result<User, &'static str> {
|
||||
banner: nested_val(&res, "subreddit", "banner_img").await,
|
||||
description: nested_val(&res, "subreddit", "public_description").await,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
16
src/utils.rs
16
src/utils.rs
@ -2,8 +2,8 @@
|
||||
// CRATES
|
||||
//
|
||||
use chrono::{TimeZone, Utc};
|
||||
use surf::{get, client, middleware::Redirect};
|
||||
use serde_json::{Value, from_str};
|
||||
use serde_json::{from_str, Value};
|
||||
use surf::{client, get, middleware::Redirect};
|
||||
|
||||
//
|
||||
// STRUCTS
|
||||
@ -23,7 +23,7 @@ pub struct Post {
|
||||
pub score: String,
|
||||
pub media: String,
|
||||
pub time: String,
|
||||
pub flair: Flair
|
||||
pub flair: Flair,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -32,7 +32,7 @@ pub struct Comment {
|
||||
pub body: String,
|
||||
pub author: String,
|
||||
pub score: String,
|
||||
pub time: String
|
||||
pub time: String,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -42,7 +42,7 @@ pub struct User {
|
||||
pub icon: String,
|
||||
pub karma: i64,
|
||||
pub banner: String,
|
||||
pub description: String
|
||||
pub description: String,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -53,7 +53,7 @@ pub struct Subreddit {
|
||||
pub description: String,
|
||||
pub icon: String,
|
||||
pub members: String,
|
||||
pub active: String
|
||||
pub active: String,
|
||||
}
|
||||
|
||||
// Parser for query params, used in sorting (eg. /r/rust/?sort=hot)
|
||||
@ -61,14 +61,14 @@ pub struct Subreddit {
|
||||
pub struct Params {
|
||||
pub sort: Option<String>,
|
||||
pub after: Option<String>,
|
||||
pub before: Option<String>
|
||||
pub before: Option<String>,
|
||||
}
|
||||
|
||||
// Error template
|
||||
#[derive(askama::Template)]
|
||||
#[template(path = "error.html", escape = "none")]
|
||||
pub struct ErrorTemplate {
|
||||
pub message: String
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user