Skip to content

Moved all templates that use Release or CrateDetails to Tera #849

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jul 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ mime_guess = "2"
dotenv = "0.15"
zstd = "0.5"
git2 = { version = "0.13.6", default-features = false }
once_cell = "1.2.0"
once_cell = "1.4.0"
path-slash = "0.1.3"

# Data serialization and deserialization
serde = { version = "1.0", features = ["derive"] }
Expand Down Expand Up @@ -77,9 +78,6 @@ features = ["with-chrono", "with-serde_json"]
# Process information
procfs = "0.7"

[target.'cfg(windows)'.dependencies]
path-slash = "0.1.1"

[dev-dependencies]
criterion = "0.3"
rand = "0.7.3"
Expand Down
21 changes: 9 additions & 12 deletions src/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ pub(crate) use self::database::DatabaseBackend;
pub(crate) use self::s3::S3Backend;
use chrono::{DateTime, Utc};
use failure::{err_msg, Error};
use path_slash::PathExt;
use postgres::{transaction::Transaction, Connection};
use std::collections::{HashMap, HashSet};
use std::ffi::OsStr;
use std::fmt;
use std::fs;
use std::io::Read;
use std::path::{Path, PathBuf};
use std::{
collections::{HashMap, HashSet},
ffi::OsStr,
fmt, fs,
io::Read,
path::{Path, PathBuf},
};

const MAX_CONCURRENT_UPLOADS: usize = 1000;
const DEFAULT_COMPRESSION: CompressionAlgorithm = CompressionAlgorithm::Zstd;
Expand Down Expand Up @@ -171,12 +173,7 @@ impl<'a> Storage<'a> {
.map(|(file_path, file)| -> Result<_, Error> {
let alg = DEFAULT_COMPRESSION;
let content = compress(file, alg)?;
let bucket_path = Path::new(prefix).join(&file_path);

#[cfg(windows)] // On windows, we need to normalize \\ to / so the route logic works
let bucket_path = path_slash::PathBufExt::to_slash(&bucket_path).unwrap();
#[cfg(not(windows))]
let bucket_path = bucket_path.into_os_string().into_string().unwrap();
let bucket_path = Path::new(prefix).join(&file_path).to_slash().unwrap();

let mime = detect_mime(&file_path)?;
file_paths_and_mimes.insert(file_path, mime.to_string());
Expand Down
5 changes: 5 additions & 0 deletions src/test/fakes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ impl<'a> FakeRelease<'a> {
self
}

pub fn author(mut self, author: &str) -> Self {
self.package.authors = vec![author.into()];
self
}

pub(crate) fn repo(mut self, repo: impl Into<String>) -> Self {
self.package.repository = Some(repo.into());
self
Expand Down
4 changes: 2 additions & 2 deletions src/web/crate_details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use serde_json::Value;

// TODO: Add target name and versions

#[derive(Debug)]
#[derive(Debug, Clone, PartialEq)]
pub struct CrateDetails {
name: String,
version: String,
Expand Down Expand Up @@ -106,7 +106,7 @@ impl Serialize for CrateDetails {
}
}

#[derive(Debug, Eq, PartialEq, Serialize)]
#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
pub struct Release {
pub version: String,
pub build_status: bool,
Expand Down
46 changes: 28 additions & 18 deletions src/web/error.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use crate::db::PoolError;
use crate::web::page::Page;
use crate::{
db::PoolError,
web::{
page::{Page, WebPage},
releases::Search,
},
};
use failure::Fail;
use iron::prelude::*;
use iron::status;
use iron::Handler;
use std::error::Error;
use std::fmt;
use iron::{status, Handler, IronError, IronResult, Plugin, Request, Response};
use params::{Params, Value};
use std::{error::Error, fmt};

#[derive(Debug, Copy, Clone)]
pub enum Nope {
Expand Down Expand Up @@ -38,31 +41,38 @@ impl Handler for Nope {
.title("The requested resource does not exist")
.to_resp("error")
}

Nope::CrateNotFound => {
// user tried to navigate to a crate that doesn't exist
Page::new("no such crate".to_owned())
.set_status(status::NotFound)
.title("The requested crate does not exist")
.to_resp("error")
}

Nope::NoResults => {
use params::{Params, Value};
let params = req.get::<Params>().unwrap();
if let Some(&Value::String(ref query)) = params.find(&["query"]) {

if let Some(Value::String(ref query)) = params.find(&["query"]) {
// this used to be a search
Page::new(Vec::<super::releases::Release>::new())
.set_status(status::NotFound)
.set("search_query", &query)
.title(&format!("No crates found matching '{}'", query))
.to_resp("releases")
Search {
title: format!("No crates found matching '{}'", query),
search_query: Some(query.to_owned()),
status: status::NotFound,
..Default::default()
}
.into_response(req)
} else {
// user did a search with no search terms
Page::new(Vec::<super::releases::Release>::new())
.set_status(status::NotFound)
.title("No results given for empty search query")
.to_resp("releases")
Search {
title: "No results given for empty search query".to_owned(),
status: status::NotFound,
..Default::default()
}
.into_response(req)
}
}

Nope::InternalServerError => {
// something went wrong, details should have been logged
Page::new("internal server error".to_owned())
Expand Down
4 changes: 1 addition & 3 deletions src/web/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,7 @@ use postgres::Connection;
use router::NoRoute;
use semver::{Version, VersionReq};
use staticfile::Static;
use std::net::SocketAddr;
use std::sync::Arc;
use std::{env, fmt, path::PathBuf, time::Duration};
use std::{env, fmt, net::SocketAddr, path::PathBuf, sync::Arc, time::Duration};

/// Duration of static files for staticfile and DatabaseFileHandler (in seconds)
const STATIC_FILE_CACHE_DURATION: u64 = 60 * 60 * 24 * 30 * 12; // 12 months
Expand Down
59 changes: 1 addition & 58 deletions src/web/page/handlebars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,6 @@ impl<T: Serialize> Page<T> {
self
}

/// Sets an integer variable
pub fn set_int(mut self, var: &str, val: i64) -> Page<T> {
self.varsi.insert(var.to_owned(), val);
self
}

/// Sets title of page
pub fn title(mut self, title: &str) -> Page<T> {
self.title = Some(title.to_owned());
Expand Down Expand Up @@ -158,59 +152,8 @@ fn build_version_safe(version: &str) -> String {
#[cfg(test)]
mod tests {
use super::*;
use crate::web::releases::{self, Release};
use chrono::Utc;
use crate::web::releases;
use iron::Url;
use serde_json::json;

#[test]
fn serialize_page() {
let time = Utc::now();

let mut release = Release::default();
release.name = "lasso".into();
release.version = "0.1.0".into();
release.release_time = time.clone();

let mut varss = BTreeMap::new();
varss.insert("test".into(), "works".into());
let mut varsb = BTreeMap::new();
varsb.insert("test2".into(), true);
let mut varsi = BTreeMap::new();
varsi.insert("test3".into(), 1337);

let page = Page {
title: None,
content: vec![release.clone()],
status: status::Status::Ok,
varss,
varsb,
varsi,
rustc_resource_suffix: &*RUSTC_RESOURCE_SUFFIX,
};

let correct_json = json!({
"content": [{
"name": "lasso",
"version": "0.1.0",
"description": null,
"target_name": null,
"rustdoc_status": false,
"release_time": super::super::super::duration_to_str(time),
"release_time_rfc3339": time.format("%+").to_string(),
"stars": 0
}],
"varss": { "test": "works" },
"varsb": { "test2": true },
"varsi": { "test3": 1337 },
"rustc_resource_suffix": &*RUSTC_RESOURCE_SUFFIX,
"cratesfyi_version": crate::BUILD_VERSION,
"cratesfyi_version_safe": build_version_safe(crate::BUILD_VERSION),
"has_global_alert": crate::GLOBAL_ALERT.is_some()
});

assert_eq!(correct_json, serde_json::to_value(&page).unwrap());
}

#[test]
fn load_page_from_releases() {
Expand Down
24 changes: 12 additions & 12 deletions src/web/page/templates.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
use crate::db::Pool;
use crate::error::Result;
use crate::{db::Pool, error::Result};
use arc_swap::ArcSwap;
use chrono::{DateTime, Utc};
use failure::ResultExt;
use notify::{watcher, RecursiveMode, Watcher};
use path_slash::PathExt;
use postgres::Connection;
use serde_json::Value;
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::{mpsc::channel, Arc};
use std::thread;
use std::time::Duration;
use std::{
collections::HashMap,
path::PathBuf,
sync::{mpsc::channel, Arc},
thread,
time::Duration,
};
use tera::{Result as TeraResult, Tera};
use walkdir::WalkDir;

Expand Down Expand Up @@ -152,10 +154,8 @@ fn find_templates_in_filesystem(base: &str) -> Result<Vec<(PathBuf, Option<Strin
let name = path
.strip_prefix(&root)
.with_context(|_| format!("{} is not a child of {}", path.display(), root.display()))?
.to_str()
.ok_or_else(|| failure::format_err!("path {} is not UTF-8", path.display()))?
.to_string();

.to_slash()
.ok_or_else(|| failure::format_err!("failed to normalize {}", path.display()))?;
files.push((path.to_path_buf(), Some(name)));
}

Expand Down Expand Up @@ -185,7 +185,7 @@ impl tera::Function for ReturnValue {
// TODO: This can be replaced by chrono
fn timeformat(value: &Value, args: &HashMap<String, Value>) -> TeraResult<Value> {
let fmt = if let Some(Value::Bool(true)) = args.get("relative") {
let value = DateTime::parse_from_str(value.as_str().unwrap(), "%Y-%m-%dT%H:%M:%S%z")
let value = DateTime::parse_from_rfc3339(value.as_str().unwrap())
.unwrap()
.with_timezone(&Utc);

Expand Down
4 changes: 3 additions & 1 deletion src/web/page/web_page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use iron::{headers::ContentType, response::Response, status::Status, IronResult,
use serde::Serialize;
use tera::Context;

/// When making using a custom status, use a closure that coerces to a `fn(&Self) -> Status`
#[macro_export]
macro_rules! impl_webpage {
($page:ty = $template:expr $(, status = $status:expr)? $(, content_type = $content_type:expr)? $(,)?) => {
Expand All @@ -11,7 +12,8 @@ macro_rules! impl_webpage {

$(
fn get_status(&self) -> ::iron::status::Status {
$status
let status: fn(&Self) -> ::iron::status::Status = $status;
(status)(self)
}
)?

Expand Down
Loading