Plume/src/routes/mod.rs

173 lines
4.5 KiB
Rust
Raw Normal View History

#![warn(clippy::too_many_arguments)]
2018-09-01 22:08:26 +02:00
use atom_syndication::{ContentBuilder, Entry, EntryBuilder, LinkBuilder, Person, PersonBuilder};
use rocket::{
http::{
2019-03-20 17:56:17 +01:00
hyper::header::{CacheControl, CacheDirective},
uri::{FromUriParam, Query},
RawStr, Status,
},
request::{self, FromFormValue, FromRequest, Request},
response::NamedFile,
2019-03-20 17:56:17 +01:00
Outcome,
};
use rocket_i18n::I18n;
use std::path::{Path, PathBuf};
2018-05-10 20:01:16 +02:00
2019-03-20 17:56:17 +01:00
use plume_models::{db_conn::DbConn, posts::Post, users::User, Connection};
use Searcher;
2019-03-20 17:56:17 +01:00
use Worker;
pub struct PlumeRocket<'a> {
conn: DbConn,
intl: I18n,
user: Option<User>,
searcher: Searcher<'a>,
worker: Worker<'a>,
}
impl<'a, 'r> FromRequest<'a, 'r> for PlumeRocket<'a> {
type Error = ();
fn from_request(request: &'a Request<'r>) -> request::Outcome<PlumeRocket<'a>, ()> {
let conn = request.guard::<DbConn>()?;
let intl = request.guard::<I18n>()?;
let user = request.guard::<User>().succeeded();
let worker = request.guard::<Worker>()?;
let searcher = request.guard::<Searcher>()?;
rocket::Outcome::Success(PlumeRocket {
conn,
intl,
user,
worker,
searcher,
})
}
}
2018-09-01 22:08:26 +02:00
const ITEMS_PER_PAGE: i32 = 12;
#[derive(Copy, Clone, UriDisplayQuery)]
pub struct Page(i32);
impl<'v> FromFormValue<'v> for Page {
type Error = &'v RawStr;
fn from_form_value(form_value: &'v RawStr) -> Result<Page, &'v RawStr> {
match form_value.parse::<i32>() {
Ok(page) => Ok(Page(page)),
_ => Err(form_value),
}
}
}
impl FromUriParam<Query, Option<Page>> for Page {
type Target = Page;
fn from_uri_param(val: Option<Page>) -> Page {
val.unwrap_or_default()
}
}
impl Page {
2018-07-25 14:29:34 +02:00
/// Computes the total number of pages needed to display n_items
pub fn total(n_items: i32) -> i32 {
if n_items % ITEMS_PER_PAGE == 0 {
n_items / ITEMS_PER_PAGE
} else {
(n_items / ITEMS_PER_PAGE) + 1
}
}
pub fn limits(self) -> (i32, i32) {
((self.0 - 1) * ITEMS_PER_PAGE, self.0 * ITEMS_PER_PAGE)
}
}
pub struct ContentLen(pub u64);
impl<'a, 'r> FromRequest<'a, 'r> for ContentLen {
type Error = ();
fn from_request(r: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
match r.limits().get("forms") {
Some(l) => Outcome::Success(ContentLen(l)),
None => Outcome::Failure((Status::InternalServerError, ())),
}
}
}
impl Default for Page {
fn default() -> Self {
Page(1)
}
}
2018-09-27 23:06:40 +02:00
pub fn post_to_atom(post: Post, conn: &Connection) -> Entry {
2018-09-01 22:08:26 +02:00
EntryBuilder::default()
2018-11-06 10:49:46 +01:00
.title(format!("<![CDATA[{}]]>", post.title))
2019-03-20 17:56:17 +01:00
.content(
ContentBuilder::default()
.value(format!("<![CDATA[{}]]>", *post.content.get()))
.src(post.ap_url.clone())
.content_type("html".to_string())
.build()
.expect("Atom feed: content error"),
)
.authors(
post.get_authors(&*conn)
.expect("Atom feed: author error")
.into_iter()
.map(|a| {
PersonBuilder::default()
.name(a.display_name)
.uri(a.ap_url)
.build()
.expect("Atom feed: author error")
})
.collect::<Vec<Person>>(),
)
.links(vec![LinkBuilder::default()
.href(post.ap_url)
.build()
.expect("Atom feed: link error")])
.build()
.expect("Atom feed: entry error")
2018-09-01 22:08:26 +02:00
}
2018-04-23 12:54:37 +02:00
pub mod blogs;
2018-05-10 11:44:57 +02:00
pub mod comments;
2018-06-18 17:59:49 +02:00
pub mod errors;
pub mod instance;
2018-05-10 18:38:03 +02:00
pub mod likes;
2018-09-02 22:55:42 +02:00
pub mod medias;
2018-05-13 15:35:55 +02:00
pub mod notifications;
2018-04-23 16:25:39 +02:00
pub mod posts;
2018-05-19 11:51:10 +02:00
pub mod reshares;
2019-03-20 17:56:17 +01:00
pub mod search;
2018-04-24 11:21:39 +02:00
pub mod session;
2018-09-06 14:06:04 +02:00
pub mod tags;
2018-04-22 20:13:12 +02:00
pub mod user;
2018-04-24 10:35:45 +02:00
pub mod well_known;
2018-05-10 20:01:16 +02:00
#[derive(Responder)]
#[response()]
pub struct CachedFile {
inner: NamedFile,
2019-03-20 17:56:17 +01:00
cache_control: CacheControl,
}
#[get("/static/cached/<_build_id>/<file..>", rank = 2)]
pub fn plume_static_files(file: PathBuf, _build_id: &RawStr) -> Option<CachedFile> {
static_files(file)
}
#[get("/static/<file..>", rank = 3)]
pub fn static_files(file: PathBuf) -> Option<CachedFile> {
2019-03-20 17:56:17 +01:00
NamedFile::open(Path::new("static/").join(file))
.ok()
.map(|f| CachedFile {
inner: f,
cache_control: CacheControl(vec![CacheDirective::MaxAge(60 * 60 * 24 * 30)]),
})
2018-05-10 20:01:16 +02:00
}