Merge pull request #1 from spikecodes/master

Merge upstream
This commit is contained in:
robrobinbin 2021-01-17 23:47:09 +01:00 committed by GitHub
commit 7a32ba087e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 75 additions and 64 deletions

View File

@ -1,5 +1,8 @@
// Import Crates // Import Crates
use actix_web::{App, HttpResponse, HttpServer, dev::{Service, ServiceResponse}, middleware, web}; use actix_web::{
dev::{Service, ServiceResponse},
middleware, web, App, HttpResponse, HttpServer,
};
use futures::future::FutureExt; use futures::future::FutureExt;
// Reference local files // Reference local files
@ -50,12 +53,10 @@ 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> = ServiceResponse::new( let redirect: ServiceResponse<actix_web::dev::Body> =
res.unwrap().request().clone(), ServiceResponse::new(res.unwrap().request().clone(), HttpResponse::Found().header("Location", https_url).finish());
HttpResponse::Found().header("Location", https_url).finish()
);
Ok(redirect) Ok(redirect)
} else { } else {
res res

View File

@ -72,7 +72,7 @@ async fn parse_post(json: &serde_json::Value) -> Post {
let ratio: f64 = post["data"]["upvote_ratio"].as_f64().unwrap_or(1.0) * 100.0; let ratio: f64 = post["data"]["upvote_ratio"].as_f64().unwrap_or(1.0) * 100.0;
// Determine the type of media along with the media URL // Determine the type of media along with the media URL
let (post_type, media, width, height) = media(&post["data"]).await; let (post_type, media) = media(&post["data"]).await;
// Build a post using data parsed from Reddit post API // Build a post using data parsed from Reddit post API
Post { Post {
@ -97,7 +97,12 @@ async fn parse_post(json: &serde_json::Value) -> Post {
score: format_num(score), score: format_num(score),
upvote_ratio: ratio as i64, upvote_ratio: ratio as i64,
post_type, post_type,
thumbnail: format_url(val(post, "thumbnail").as_str()), media,
thumbnail: Media {
url: format_url(val(post, "thumbnail").as_str()),
width: post["data"]["thumbnail_width"].as_i64().unwrap_or_default(),
height: post["data"]["thumbnail_height"].as_i64().unwrap_or_default(),
},
flair: Flair { flair: Flair {
flair_parts: parse_rich_flair( flair_parts: parse_rich_flair(
val(post, "link_flair_type"), val(post, "link_flair_type"),
@ -115,15 +120,10 @@ async fn parse_post(json: &serde_json::Value) -> Post {
nsfw: post["data"]["over_18"].as_bool().unwrap_or(false), nsfw: post["data"]["over_18"].as_bool().unwrap_or(false),
stickied: post["data"]["stickied"].as_bool().unwrap_or(false), stickied: post["data"]["stickied"].as_bool().unwrap_or(false),
}, },
media,
domain: val(post, "domain"), domain: val(post, "domain"),
rel_time, rel_time,
created, created,
comments: format_num(post["data"]["num_comments"].as_i64().unwrap_or_default()), comments: format_num(post["data"]["num_comments"].as_i64().unwrap_or_default()),
media_width: width,
media_height: height,
thumbnail_width: post["data"]["thumbnail_width"].as_i64().unwrap_or_default(),
thumbnail_height: post["data"]["thumbnail_height"].as_i64().unwrap_or_default(),
} }
} }

View File

@ -39,6 +39,12 @@ pub struct Flags {
pub stickied: bool, pub stickied: bool,
} }
pub struct Media {
pub url: String,
pub width: i64,
pub height: i64,
}
// Post containing content, metadata and media // Post containing content, metadata and media
pub struct Post { pub struct Post {
pub id: String, pub id: String,
@ -52,16 +58,12 @@ pub struct Post {
pub post_type: String, pub post_type: String,
pub flair: Flair, pub flair: Flair,
pub flags: Flags, pub flags: Flags,
pub thumbnail: String, pub thumbnail: Media,
pub media: String, pub media: Media,
pub domain: String, pub domain: String,
pub rel_time: String, pub rel_time: String,
pub created: String, pub created: String,
pub comments: String, pub comments: String,
pub media_width: i64,
pub media_height: i64,
pub thumbnail_width: i64,
pub thumbnail_height: i64,
} }
// Comment with content, post, score and data/time that it was posted // Comment with content, post, score and data/time that it was posted
@ -174,16 +176,16 @@ pub fn rewrite_url(text: &str) -> String {
// Append `m` and `k` for millions and thousands respectively // Append `m` and `k` for millions and thousands respectively
pub fn format_num(num: i64) -> String { pub fn format_num(num: i64) -> String {
if num > 1_000_000 { if num >= 1_000_000 {
format!("{}m", num / 1_000_000) format!("{}m", num / 1_000_000)
} else if num > 1000 { } else if num >= 1000 {
format!("{}k", num / 1_000) format!("{}k", num / 1_000)
} else { } else {
num.to_string() num.to_string()
} }
} }
pub async fn media(data: &Value) -> (String, String, i64, i64) { pub async fn media(data: &Value) -> (String, Media) {
let post_type: &str; let post_type: &str;
// If post is a video, return the video // If post is a video, return the video
let url = if data["preview"]["reddit_video_preview"]["fallback_url"].is_string() { let url = if data["preview"]["reddit_video_preview"]["fallback_url"].is_string() {
@ -215,13 +217,14 @@ pub async fn media(data: &Value) -> (String, String, i64, i64) {
data["url"].as_str().unwrap_or_default().to_string() data["url"].as_str().unwrap_or_default().to_string()
}; };
let (width, height) = if post_type == "image" { (
(data["preview"]["images"][0]["source"]["width"].as_i64().unwrap_or_default(), data["preview"]["images"][0]["source"]["height"].as_i64().unwrap_or_default()) post_type.to_string(),
} else { Media {
(0, 0) url,
}; width: data["preview"]["images"][0]["source"]["width"].as_i64().unwrap_or_default(),
height: data["preview"]["images"][0]["source"]["height"].as_i64().unwrap_or_default(),
(post_type.to_string(), url, width, height) },
)
} }
pub fn parse_rich_flair(flair_type: String, rich_flair: Option<&Vec<Value>>, text_flair: Option<&str>) -> Vec<FlairPart> { pub fn parse_rich_flair(flair_type: String, rich_flair: Option<&Vec<Value>>, text_flair: Option<&str>) -> Vec<FlairPart> {
@ -317,7 +320,7 @@ pub async fn fetch_posts(path: &str, fallback_title: String) -> Result<(Vec<Post
let title = val(post, "title"); let title = val(post, "title");
// Determine the type of media along with the media URL // Determine the type of media along with the media URL
let (post_type, media, width, height) = media(&post["data"]).await; let (post_type, media) = media(&post["data"]).await;
posts.push(Post { posts.push(Post {
id: val(post, "id"), id: val(post, "id"),
@ -340,7 +343,11 @@ pub async fn fetch_posts(path: &str, fallback_title: String) -> Result<(Vec<Post
score: format_num(score), score: format_num(score),
upvote_ratio: ratio as i64, upvote_ratio: ratio as i64,
post_type, post_type,
thumbnail: format_url(val(post, "thumbnail").as_str()), thumbnail: Media {
url: format_url(val(post, "thumbnail").as_str()),
width: post["data"]["thumbnail_width"].as_i64().unwrap_or_default(),
height: post["data"]["thumbnail_height"].as_i64().unwrap_or_default(),
},
media, media,
domain: val(post, "domain"), domain: val(post, "domain"),
flair: Flair { flair: Flair {
@ -364,10 +371,6 @@ pub async fn fetch_posts(path: &str, fallback_title: String) -> Result<(Vec<Post
rel_time, rel_time,
created, created,
comments: format_num(post["data"]["num_comments"].as_i64().unwrap_or_default()), comments: format_num(post["data"]["num_comments"].as_i64().unwrap_or_default()),
media_width: width,
media_height: height,
thumbnail_width: post["data"]["thumbnail_width"].as_i64().unwrap_or_default(),
thumbnail_height: post["data"]["thumbnail_height"].as_i64().unwrap_or_default(),
}); });
} }

View File

@ -32,23 +32,30 @@ body {
} }
nav { nav {
display: flex; display: grid;
grid-template-areas: "logo searchbox code";
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
color: var(--accent); color: var(--accent);
background: var(--outside); background: var(--outside);
padding: 5px 15px;
font-size: 20px;
min-height: 40px;
position: fixed;
width: calc(100% - 30px);
box-shadow: var(--shadow); box-shadow: var(--shadow);
top: 0;
font-size: 20px;
z-index: 1; z-index: 1;
top: 0;
padding: 5px 15px;
min-height: 40px;
width: calc(100% - 30px);
position: fixed;
} }
nav * { color: var(--text); } nav * { color: var(--text); }
nav #reddit { color: var(--accent); } nav #reddit, #code { color: var(--accent); }
nav #logo { grid-area: logo; }
nav #code { grid-area: code; }
nav #version { opacity: 25%; } nav #version { opacity: 25%; }
#settings_link { #settings_link {
@ -246,6 +253,7 @@ select, #search {
} }
#searchbox { #searchbox {
grid-area: searchbox;
display: flex; display: flex;
box-shadow: var(--shadow); box-shadow: var(--shadow);
border-radius: 5px; border-radius: 5px;
@ -939,7 +947,7 @@ td, th {
} }
nav { nav {
flex-direction: column; grid-template-areas: 'logo code' 'searchbox searchbox';
padding: 10px; padding: 10px;
width: calc(100% - 20px); width: calc(100% - 20px);
} }
@ -952,5 +960,4 @@ td, th {
#user, #sidebar { margin: 20px 0; } #user, #sidebar { margin: 20px 0; }
#logo { margin: 5px auto; } #logo { margin: 5px auto; }
#searchbox { width: 100%; } #searchbox { width: 100%; }
#github { display: none; }
} }

View File

@ -26,7 +26,7 @@
<a id="settings_link" href="/settings">settings</a> <a id="settings_link" href="/settings">settings</a>
</p> </p>
{% block search %}{% endblock %} {% block search %}{% endblock %}
<a id="github" href="https://github.com/spikecodes/libreddit">GITHUB</a> <a id="code" href="https://github.com/spikecodes/libreddit">code</a>
</nav> </nav>
<!-- MAIN CONTENT --> <!-- MAIN CONTENT -->

View File

@ -62,11 +62,11 @@
<!-- POST MEDIA --> <!-- POST MEDIA -->
{% if post.post_type == "image" %} {% if post.post_type == "image" %}
<img class="post_media" width="{{ post.media_width }}px" height="{{ post.media_height}}px" src="{{ post.media }}"/> <img class="post_media" width="{{ post.media.width }}px" height="{{ post.media.height}}px" src="{{ post.media.url }}"/>
{% else if post.post_type == "video" || post.post_type == "gif" %} {% else if post.post_type == "video" || post.post_type == "gif" %}
<video class="post_media" src="{{ post.media }}" controls autoplay loop></video> <video class="post_media" src="{{ post.media.url }}" controls autoplay loop></video>
{% else if post.post_type == "link" %} {% else if post.post_type == "link" %}
<a id="post_url" href="{{ post.media }}">{{ post.media }}</a> <a id="post_url" href="{{ post.media.url }}">{{ post.media.url }}</a>
{% endif %} {% endif %}
<!-- POST BODY --> <!-- POST BODY -->

View File

@ -53,16 +53,16 @@
<a href="{{ post.permalink }}">{{ post.title }}</a>{% if post.flags.nsfw %} <small class="nsfw">NSFW</small>{% endif %} <a href="{{ post.permalink }}">{{ post.title }}</a>{% if post.flags.nsfw %} <small class="nsfw">NSFW</small>{% endif %}
</p> </p>
<!-- POST MEDIA/THUMBNAIL --> <!-- POST MEDIA/THUMBNAIL -->
{% if (prefs.layout == "" || prefs.layout == "card") && post.post_type == "image" %} {% if (prefs.layout.is_empty() || prefs.layout == "card") && post.post_type == "image" %}
<img class="post_media" width="{{ post.media_width }}px" height="{{ post.media_height}}px" src="{{ post.media }}"/> <img class="post_media" width="{{ post.media.width }}px" height="{{ post.media.height}}px" src="{{ post.media.url }}"/>
{% else if post.post_type != "self" %} {% else if post.post_type != "self" %}
<a class="post_thumbnail {% if post.thumbnail == "" %}no_thumbnail{% endif %}" href="{% if post.post_type == "link" %}{{ post.media }}{% else %}{{ post.permalink }}{% endif %}"> <a class="post_thumbnail {% if post.thumbnail.url.is_empty() %}no_thumbnail{% endif %}" href="{% if post.post_type == "link" %}{{ post.media.url }}{% else %}{{ post.permalink }}{% endif %}">
{% if post.thumbnail == "" %} {% if post.thumbnail.url.is_empty() %}
<svg viewBox="0 0 100 106" width="140" height="53" xmlns="http://www.w3.org/2000/svg"> <svg viewBox="0 0 100 106" width="140" height="53" xmlns="http://www.w3.org/2000/svg">
<path d="M35,15h-15a10,10 0,0,0 0,20h25a10,10 0,0,0 10,-10m-12.5,0a10, 10 0,0,1 10, -10h25a10,10 0,0,1 0,20h-15" fill="none" stroke-width="5" stroke-linecap="round"/> <path d="M35,15h-15a10,10 0,0,0 0,20h25a10,10 0,0,0 10,-10m-12.5,0a10, 10 0,0,1 10, -10h25a10,10 0,0,1 0,20h-15" fill="none" stroke-width="5" stroke-linecap="round"/>
</svg> </svg>
{% else %} {% else %}
<img src="{{ post.thumbnail }}" width="{{ post.thumbnail_width }}px" height="{{ post.thumbnail_height }}px"> <img src="{{ post.thumbnail.url }}" width="{{ post.thumbnail.width }}px" height="{{ post.thumbnail.height }}px">
{% endif %} {% endif %}
<span>{% if post.post_type == "link" %}{{ post.domain }}{% else %}{{ post.post_type }}{% endif %}</span> <span>{% if post.post_type == "link" %}{{ post.domain }}{% else %}{{ post.post_type }}{% endif %}</span>
</a> </a>

View File

@ -47,16 +47,16 @@
<a href="{{ post.permalink }}">{{ post.title }}</a>{% if post.flags.nsfw %} <small class="nsfw">NSFW</small>{% endif %} <a href="{{ post.permalink }}">{{ post.title }}</a>{% if post.flags.nsfw %} <small class="nsfw">NSFW</small>{% endif %}
</p> </p>
<!-- POST MEDIA/THUMBNAIL --> <!-- POST MEDIA/THUMBNAIL -->
{% if (prefs.layout == "" || prefs.layout == "card") && post.post_type == "image" %} {% if (prefs.layout.is_empty() || prefs.layout == "card") && post.post_type == "image" %}
<img class="post_media" width="{{ post.media_width }}px" height="{{ post.media_height}}px" src="{{ post.media }}"/> <img class="post_media" width="{{ post.media.width }}px" height="{{ post.media.height }}px" src="{{ post.media.url }}"/>
{% else if post.post_type != "self" %} {% else if post.post_type != "self" %}
<a class="post_thumbnail {% if post.thumbnail == "" %}no_thumbnail{% endif %}" href="{% if post.post_type == "link" %}{{ post.media }}{% else %}{{ post.permalink }}{% endif %}"> <a class="post_thumbnail {% if post.thumbnail.url.is_empty() %}no_thumbnail{% endif %}" href="{% if post.post_type == "link" %}{{ post.media.url }}{% else %}{{ post.permalink }}{% endif %}">
{% if post.thumbnail == "" %} {% if post.thumbnail.url.is_empty() %}
<svg viewBox="0 0 100 106" width="140" height="53" xmlns="http://www.w3.org/2000/svg"> <svg viewBox="0 0 100 106" width="140" height="53" xmlns="http://www.w3.org/2000/svg">
<path d="M35,15h-15a10,10 0,0,0 0,20h25a10,10 0,0,0 10,-10m-12.5,0a10, 10 0,0,1 10, -10h25a10,10 0,0,1 0,20h-15" fill="none" stroke-width="5" stroke-linecap="round"/> <path d="M35,15h-15a10,10 0,0,0 0,20h25a10,10 0,0,0 10,-10m-12.5,0a10, 10 0,0,1 10, -10h25a10,10 0,0,1 0,20h-15" fill="none" stroke-width="5" stroke-linecap="round"/>
</svg> </svg>
{% else %} {% else %}
<img src="{{ post.thumbnail }}" width="{{ post.thumbnail_width }}px" height="{{ post.thumbnail_height }}px"> <img src="{{ post.thumbnail.url }}" width="{{ post.thumbnail.width }}px" height="{{ post.thumbnail.height }}px">
{% endif %} {% endif %}
<span>{% if post.post_type == "link" %}{{ post.domain }}{% else %}{{ post.post_type }}{% endif %}</span> <span>{% if post.post_type == "link" %}{{ post.domain }}{% else %}{{ post.post_type }}{% endif %}</span>
</a> </a>

View File

@ -38,16 +38,16 @@
<a href="{{ post.permalink }}">{{ post.title }}</a>{% if post.flags.nsfw %} <small class="nsfw">NSFW</small>{% endif %} <a href="{{ post.permalink }}">{{ post.title }}</a>{% if post.flags.nsfw %} <small class="nsfw">NSFW</small>{% endif %}
</p> </p>
<!-- POST MEDIA/THUMBNAIL --> <!-- POST MEDIA/THUMBNAIL -->
{% if (prefs.layout == "" || prefs.layout == "card") && post.post_type == "image" %} {% if (prefs.layout.is_empty() || prefs.layout == "card") && post.post_type == "image" %}
<img class="post_media" width="{{ post.media_width }}px" height="{{ post.media_height}}px" src="{{ post.media }}"/> <img class="post_media" width="{{ post.media.width }}px" height="{{ post.media.height }}px" src="{{ post.media.url }}"/>
{% else if post.post_type != "self" %} {% else if post.post_type != "self" %}
<a class="post_thumbnail {% if post.thumbnail == "" %}no_thumbnail{% endif %}" href="{% if post.post_type == "link" %}{{ post.media }}{% else %}{{ post.permalink }}{% endif %}"> <a class="post_thumbnail {% if post.thumbnail.url.is_empty() %}no_thumbnail{% endif %}" href="{% if post.post_type == "link" %}{{ post.media.url }}{% else %}{{ post.permalink }}{% endif %}">
{% if post.thumbnail == "" %} {% if post.thumbnail.url.is_empty() %}
<svg viewBox="0 0 100 106" width="140" height="53" xmlns="http://www.w3.org/2000/svg"> <svg viewBox="0 0 100 106" width="140" height="53" xmlns="http://www.w3.org/2000/svg">
<path d="M35,15h-15a10,10 0,0,0 0,20h25a10,10 0,0,0 10,-10m-12.5,0a10, 10 0,0,1 10, -10h25a10,10 0,0,1 0,20h-15" fill="none" stroke-width="5" stroke-linecap="round"/> <path d="M35,15h-15a10,10 0,0,0 0,20h25a10,10 0,0,0 10,-10m-12.5,0a10, 10 0,0,1 10, -10h25a10,10 0,0,1 0,20h-15" fill="none" stroke-width="5" stroke-linecap="round"/>
</svg> </svg>
{% else %} {% else %}
<img src="{{ post.thumbnail }}" width="{{ post.thumbnail_width }}px" height="{{ post.thumbnail_height }}px"> <img src="{{ post.thumbnail.url }}" width="{{ post.thumbnail.width }}px" height="{{ post.thumbnail.height }}px">
{% endif %} {% endif %}
<span>{% if post.post_type == "link" %}{{ post.domain }}{% else %}{{ post.post_type }}{% endif %}</span> <span>{% if post.post_type == "link" %}{{ post.domain }}{% else %}{{ post.post_type }}{% endif %}</span>
</a> </a>