2018-09-02 20:55:42 +00:00
|
|
|
use guid_create::GUID;
|
|
|
|
use multipart::server::{Multipart, save::{SavedData, SaveResult}};
|
2018-10-20 09:04:20 +00:00
|
|
|
use rocket::{Data, http::ContentType, response::{Redirect, status}};
|
2018-12-06 17:54:16 +00:00
|
|
|
use rocket_i18n::I18n;
|
2018-10-12 19:48:11 +00:00
|
|
|
use std::fs;
|
2018-09-02 20:55:42 +00:00
|
|
|
use plume_models::{db_conn::DbConn, medias::*, users::User};
|
2018-12-06 17:54:16 +00:00
|
|
|
use template_utils::Ructe;
|
2018-12-29 08:36:07 +00:00
|
|
|
use routes::errors::ErrorPage;
|
2018-09-02 20:55:42 +00:00
|
|
|
|
|
|
|
#[get("/medias")]
|
2018-12-29 08:36:07 +00:00
|
|
|
pub fn list(user: User, conn: DbConn, intl: I18n) -> Result<Ructe, ErrorPage> {
|
|
|
|
let medias = Media::for_user(&*conn, user.id)?;
|
|
|
|
Ok(render!(medias::index(
|
2018-12-06 17:54:16 +00:00
|
|
|
&(&*conn, &intl.catalog, Some(user)),
|
|
|
|
medias
|
2018-12-29 08:36:07 +00:00
|
|
|
)))
|
2018-09-02 20:55:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/medias/new")]
|
2018-12-06 17:54:16 +00:00
|
|
|
pub fn new(user: User, conn: DbConn, intl: I18n) -> Ructe {
|
|
|
|
render!(medias::new(
|
|
|
|
&(&*conn, &intl.catalog, Some(user))
|
|
|
|
))
|
2018-09-02 20:55:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[post("/medias/new", data = "<data>")]
|
2018-12-06 17:54:16 +00:00
|
|
|
pub fn upload(user: User, data: Data, ct: &ContentType, conn: DbConn) -> Result<Redirect, status::BadRequest<&'static str>> {
|
2018-09-02 20:55:42 +00:00
|
|
|
if ct.is_form_data() {
|
2018-10-20 09:04:20 +00:00
|
|
|
let (_, boundary) = ct.params().find(|&(k, _)| k == "boundary").ok_or_else(|| status::BadRequest(Some("No boundary")))?;
|
2018-09-02 20:55:42 +00:00
|
|
|
|
|
|
|
match Multipart::with_body(data.open(), boundary).save().temp() {
|
|
|
|
SaveResult::Full(entries) => {
|
|
|
|
let fields = entries.fields;
|
|
|
|
|
2018-10-20 09:04:20 +00:00
|
|
|
let filename = fields.get(&"file".to_string()).and_then(|v| v.into_iter().next())
|
|
|
|
.ok_or_else(|| status::BadRequest(Some("No file uploaded")))?.headers
|
|
|
|
.filename.clone();
|
|
|
|
let ext = filename.and_then(|f| f.rsplit('.').next().map(|ext| ext.to_owned()))
|
2018-11-26 09:21:52 +00:00
|
|
|
.unwrap_or_else(|| "png".to_owned());
|
2018-10-12 19:22:57 +00:00
|
|
|
let dest = format!("static/media/{}.{}", GUID::rand().to_string(), ext);
|
2018-09-02 20:55:42 +00:00
|
|
|
|
2018-10-20 09:04:20 +00:00
|
|
|
match fields[&"file".to_string()][0].data {
|
2018-12-29 08:36:07 +00:00
|
|
|
SavedData::Bytes(ref bytes) => fs::write(&dest, bytes).map_err(|_| status::BadRequest(Some("Couldn't save upload")))?,
|
|
|
|
SavedData::File(ref path, _) => {fs::copy(path, &dest).map_err(|_| status::BadRequest(Some("Couldn't copy upload")))?;},
|
2018-10-20 09:04:20 +00:00
|
|
|
_ => {
|
|
|
|
return Ok(Redirect::to(uri!(new)));
|
2018-09-02 20:55:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-29 08:36:07 +00:00
|
|
|
let has_cw = !read(&fields[&"cw".to_string()][0].data).map(|cw| cw.is_empty()).unwrap_or(false);
|
2018-09-02 20:55:42 +00:00
|
|
|
let media = Media::insert(&*conn, NewMedia {
|
|
|
|
file_path: dest,
|
2018-12-29 08:36:07 +00:00
|
|
|
alt_text: read(&fields[&"alt".to_string()][0].data)?,
|
2018-09-02 20:55:42 +00:00
|
|
|
is_remote: false,
|
|
|
|
remote_url: None,
|
|
|
|
sensitive: has_cw,
|
|
|
|
content_warning: if has_cw {
|
2018-12-29 08:36:07 +00:00
|
|
|
Some(read(&fields[&"cw".to_string()][0].data)?)
|
2018-09-02 20:55:42 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
},
|
|
|
|
owner_id: user.id
|
2018-12-29 08:36:07 +00:00
|
|
|
}).map_err(|_| status::BadRequest(Some("Error while saving media")))?;
|
2018-10-20 09:04:20 +00:00
|
|
|
Ok(Redirect::to(uri!(details: id = media.id)))
|
2018-09-02 20:55:42 +00:00
|
|
|
},
|
|
|
|
SaveResult::Partial(_, _) | SaveResult::Error(_) => {
|
2018-10-20 09:04:20 +00:00
|
|
|
Ok(Redirect::to(uri!(new)))
|
2018-09-02 20:55:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2018-10-20 09:04:20 +00:00
|
|
|
Ok(Redirect::to(uri!(new)))
|
2018-09-02 20:55:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-29 08:36:07 +00:00
|
|
|
fn read(data: &SavedData) -> Result<String, status::BadRequest<&'static str>> {
|
2018-09-02 20:55:42 +00:00
|
|
|
if let SavedData::Text(s) = data {
|
2018-12-29 08:36:07 +00:00
|
|
|
Ok(s.clone())
|
2018-09-02 20:55:42 +00:00
|
|
|
} else {
|
2018-12-29 08:36:07 +00:00
|
|
|
Err(status::BadRequest(Some("Error while reading data")))
|
2018-09-02 20:55:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/medias/<id>")]
|
2018-12-29 08:36:07 +00:00
|
|
|
pub fn details(id: i32, user: User, conn: DbConn, intl: I18n) -> Result<Ructe, ErrorPage> {
|
|
|
|
let media = Media::get(&*conn, id)?;
|
|
|
|
Ok(render!(medias::details(
|
2018-12-06 17:54:16 +00:00
|
|
|
&(&*conn, &intl.catalog, Some(user)),
|
|
|
|
media
|
2018-12-29 08:36:07 +00:00
|
|
|
)))
|
2018-09-02 20:55:42 +00:00
|
|
|
}
|
|
|
|
|
2018-09-19 17:13:07 +00:00
|
|
|
#[post("/medias/<id>/delete")]
|
2018-12-29 08:36:07 +00:00
|
|
|
pub fn delete(id: i32, _user: User, conn: DbConn) -> Result<Redirect, ErrorPage> {
|
2018-10-20 09:04:20 +00:00
|
|
|
let media = Media::get(&*conn, id)?;
|
2018-12-29 08:36:07 +00:00
|
|
|
media.delete(&*conn)?;
|
|
|
|
Ok(Redirect::to(uri!(list)))
|
2018-09-02 21:10:15 +00:00
|
|
|
}
|
|
|
|
|
2018-09-19 17:13:07 +00:00
|
|
|
#[post("/medias/<id>/avatar")]
|
2018-12-29 08:36:07 +00:00
|
|
|
pub fn set_avatar(id: i32, user: User, conn: DbConn) -> Result<Redirect, ErrorPage> {
|
2018-10-20 09:04:20 +00:00
|
|
|
let media = Media::get(&*conn, id)?;
|
2018-12-29 08:36:07 +00:00
|
|
|
user.set_avatar(&*conn, media.id)?;
|
|
|
|
Ok(Redirect::to(uri!(details: id = id)))
|
2018-09-03 12:04:17 +00:00
|
|
|
}
|