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;
|
2019-11-18 08:14:29 +00:00
|
|
|
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::*;
|
2019-11-18 08:14:29 +00:00
|
|
|
use comrak::{markdown_to_html, ComrakOptions};
|
2019-11-14 02:10:42 +00:00
|
|
|
use diesel::pg::PgConnection;
|
|
|
|
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-21 20:31:04 +00:00
|
|
|
"/* {} */",
|
|
|
|
"# {}",
|
|
|
|
"// {}",
|
|
|
|
"<!-- {} -->",
|
|
|
|
"{# {} #}",
|
|
|
|
"-- {}",
|
|
|
|
"--[[ {} --]]",
|
2019-11-21 20:34:48 +00:00
|
|
|
"; {}",
|
|
|
|
"% {}",
|
2019-11-21 20:31:04 +00:00
|
|
|
];
|
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)
|
|
|
|
}
|
|
|
|
|
2019-11-17 22:09:36 +00:00
|
|
|
fn get_post(id_number: i32) -> Post {
|
|
|
|
use schema::posts::dsl::*;
|
|
|
|
|
|
|
|
let connection = establish_connection();
|
|
|
|
let post = posts.find(id_number).first(&connection);
|
|
|
|
|
|
|
|
post.unwrap()
|
|
|
|
}
|
|
|
|
|
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");
|
|
|
|
|
2019-11-18 08:14:29 +00:00
|
|
|
let mut post = get_post(id);
|
|
|
|
let content = markdown_to_html(&post.content, &ComrakOptions::default());
|
|
|
|
post.content = content;
|
2019-11-17 22:09:36 +00:00
|
|
|
|
|
|
|
context.insert("title", &title);
|
|
|
|
context.insert("post", &post);
|
2019-11-18 08:15:46 +00:00
|
|
|
Template::render("post", 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
|
|
|
}
|