codigocomentado/src/main.rs

154 lines
3.9 KiB
Rust
Raw Normal View History

2019-11-13 07:17:38 +00:00
#![feature(proc_macro_hygiene, decl_macro)]
2019-11-14 02:10:42 +00:00
pub mod models;
pub mod schema;
2019-11-13 07:17:38 +00:00
#[macro_use]
extern crate rocket;
2019-11-14 02:10:42 +00:00
#[macro_use]
extern crate diesel;
extern crate comrak;
2019-11-14 02:10:42 +00:00
extern crate dotenv;
2019-11-13 07:17:38 +00:00
extern crate rand;
extern crate rocket_contrib;
2019-11-14 02:10:42 +00:00
extern crate tera;
2019-11-13 07:17:38 +00:00
2019-11-14 02:10:42 +00:00
use self::diesel::prelude::*;
use self::models::*;
use comrak::{markdown_to_html, ComrakOptions};
2019-11-14 02:10:42 +00:00
use diesel::pg::PgConnection;
use diesel::result::Error;
2019-11-14 02:10:42 +00:00
use dotenv::dotenv;
2019-11-13 07:17:38 +00:00
use rand::Rng;
2019-11-23 19:05:41 +00:00
use rocket::Request;
2019-11-13 07:17:38 +00:00
use rocket_contrib::serve::StaticFiles;
use rocket_contrib::templates::Template;
2019-11-14 02:10:42 +00:00
use std::env;
use std::vec::Vec;
use tera::Context;
2019-11-13 07:17:38 +00:00
2019-11-21 20:35:56 +00:00
const TITLES: [&str; 9] = [
"/* {} */",
"# {}",
"// {}",
"<!-- {} -->",
"{# {} #}",
"-- {}",
"--[[ {} --]]",
"; {}",
"% {}",
];
2019-11-17 05:10:06 +00:00
const MAX_POSTS_PER_PAGE: i64 = 20;
2019-11-13 07:17:38 +00:00
2019-11-14 02:10:42 +00:00
fn establish_connection() -> PgConnection {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL not setted");
PgConnection::establish(&database_url).expect(&format!("Error connecting to {}", database_url))
}
2019-11-17 05:10:06 +00:00
fn get_posts(page: i64) -> (Vec<Post>, i64) {
2019-11-14 02:10:42 +00:00
use schema::posts::dsl::*;
let connection = establish_connection();
2019-11-17 05:10:06 +00:00
let visible_posts = posts
2019-11-14 02:10:42 +00:00
.filter(published.eq(true))
2019-11-17 05:10:06 +00:00
.limit(MAX_POSTS_PER_PAGE)
.offset(MAX_POSTS_PER_PAGE * (page - 1))
2019-11-14 02:10:42 +00:00
.load::<Post>(&connection)
2019-11-17 05:10:06 +00:00
.expect("Error loading posts");
let number_of_posts: i64 = posts
.filter(published.eq(true))
.count()
.get_result(&connection)
.expect("Error counting the posts");
(visible_posts, number_of_posts)
2019-11-14 02:10:42 +00:00
}
#[get("/?<page>")]
fn index(page: Option<i8>) -> Template {
2019-11-17 05:10:06 +00:00
let page = page.unwrap_or_else(|| 1);
2019-11-14 02:10:42 +00:00
let mut context = Context::new();
2019-11-13 07:17:38 +00:00
let mut rng = rand::thread_rng();
let title_fmt = TITLES[rng.gen_range(0, TITLES.len())];
let title = str::replace(title_fmt, "{}", "CódigoComentado");
2019-11-14 02:10:42 +00:00
2019-11-17 05:10:06 +00:00
let (posts, n_posts) = get_posts(page as i64);
let total_pages = (n_posts as f64 / MAX_POSTS_PER_PAGE as f64).ceil() as i64;
2019-11-14 02:10:42 +00:00
context.insert("title", &title);
2019-11-17 05:10:06 +00:00
context.insert("posts", &posts);
context.insert("total_pages", &total_pages);
context.insert("actual_page", &page);
2019-11-13 07:17:38 +00:00
Template::render("index", context)
}
fn get_post(id_number: i32) -> Result<Post, Error> {
2019-11-17 22:09:36 +00:00
use schema::posts::dsl::*;
let connection = establish_connection();
let post = posts.find(id_number).first(&connection);
post
2019-11-17 22:09:36 +00:00
}
2019-11-18 08:16:16 +00:00
#[get("/post/<title>")]
2019-11-17 22:09:36 +00:00
fn show_post(title: String) -> Template {
let mut context = Context::new();
let title_splited: Vec<&str> = title.split('-').collect();
let id = title_splited.last().unwrap().parse().unwrap();
let mut rng = rand::thread_rng();
let title_fmt = TITLES[rng.gen_range(0, TITLES.len())];
let title = str::replace(title_fmt, "{}", "CódigoComentado");
let post = get_post(id);
2019-11-17 22:09:36 +00:00
context.insert("title", &title);
match post {
Ok(mut p) => {
let content = markdown_to_html(&p.content, &ComrakOptions::default());
p.content = content;
context.insert("post", &p);
Template::render("post", context)
}
Err(_e) => {
let uri = format!("/post/{}", title_splited.join("-"));
context.insert("url", &uri);
Template::render("404", context)
}
}
2019-11-17 22:09:36 +00:00
}
2019-11-23 19:05:41 +00:00
#[catch(404)]
fn not_found_404(req: &Request) -> Template {
let mut context = Context::new();
let mut rng = rand::thread_rng();
let title_fmt = TITLES[rng.gen_range(0, TITLES.len())];
let title = str::replace(title_fmt, "{}", "CódigoComentado");
let uri = format!("{}", req.uri());
context.insert("title", &title);
context.insert("url", &uri);
Template::render("404", context)
}
2019-11-13 01:57:32 +00:00
fn main() {
2019-11-13 07:17:38 +00:00
rocket::ignite()
.attach(Template::fairing())
2019-11-17 22:09:36 +00:00
.mount("/", routes![index, show_post])
2019-11-13 07:17:38 +00:00
.mount("/static", StaticFiles::from("static"))
2019-11-23 19:05:41 +00:00
.register(catchers![not_found_404])
2019-11-13 07:17:38 +00:00
.launch();
2019-11-13 01:57:32 +00:00
}