aboutsummaryrefslogtreecommitdiffstats
path: root/src/bin/mt-webface.rs
blob: b35deec10568125df99064d1b8b0a256fe96b631 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

extern crate getopts;
extern crate pencil;
extern crate modelthing;
extern crate env_logger;
extern crate markdown;

#[macro_use]
extern crate log;

use std::env;
use std::collections::BTreeMap;
use std::path::Path;
use getopts::Options;
use pencil::Pencil;
use pencil::{Request, PencilResult, Response, HTTPError, PencilError};


fn home(r: &mut Request) -> PencilResult {
    let context: BTreeMap<String,String> = BTreeMap::new();
    return r.app.render_template("home.html", &context);
}

fn readme(r: &mut Request) -> PencilResult {
    let mut context = BTreeMap::new();
    let raw_text = include_str!("../../README.txt");
    context.insert("raw_text".to_string(), raw_text.to_string());
    return r.app.render_template("raw.html", &context);
}

fn model_list(r: &mut Request) -> PencilResult {
    let paths = modelthing::search_models(Path::new("examples"));
    let l: Vec<String> = paths.iter().map(|x| Path::new(x).strip_prefix("examples").unwrap().to_string_lossy().to_string()).collect();
    let mut context = BTreeMap::new();
    context.insert("model_slug_list".to_string(), l);
    return r.app.render_template("model_list.html", &context);
}

fn model_view(r: &mut Request) -> PencilResult {
    let model_slug = r.view_args.get("model_slug").unwrap();
    let model_path = Path::new("examples").join(model_slug);
    match modelthing::load_model_entry(model_path.as_path()) {
        Ok(me) => {
            let mut context = BTreeMap::new();
            context.insert("model_slug".to_string(), model_slug.to_string());
            context.insert("model_name".to_string(), me.ast.name.clone());
            context.insert("model_description".to_string(), me.ast.description.clone().unwrap_or("".to_string()));
            context.insert("markdown_html".to_string(), markdown::to_html(&me.markdown));
            context.insert("markdown".to_string(), me.markdown);
            context.insert("modelica".to_string(), format!("{:?}", me.ast));
            r.app.render_template("model_view.html", &context)
        },
        Err(_) => Err(PencilError::PenHTTPError(pencil::HTTPError::NotFound)),
    }
}

fn page_not_found(_: HTTPError) -> PencilResult {
    let mut response = Response::from("404: Not Found");
    response.status_code = 404;
    Ok(response)
}

fn server_error(_: HTTPError) -> PencilResult {
    let mut response = Response::from("500: Server Error");
    response.status_code = 500;
    Ok(response)
}

fn print_usage(opts: Options) {
    let brief = "usage:\tmt-webface [options]";
    println!("");
    print!("{}", opts.usage(&brief));
}

fn main() {

    let args: Vec<String> = env::args().collect();

    let mut opts = Options::new();
    opts.optflag("h", "help", "print this help menu");
    opts.optflag("b", "bind", "local IP:port to bind to");
    opts.optflag("", "version", "print the version");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => {
            println!("{}\n", f.to_string());
            print_usage(opts);
            ::std::process::exit(-1);
        }
    };

    if matches.opt_present("help") {
        print_usage(opts);
        return;
    }

    if matches.opt_present("version") {
        println!("modelthing {}", env!("CARGO_PKG_VERSION"));
        return;
    }

    env_logger::init().unwrap();

    let mut app = Pencil::new("webface");
    app.name = "modelthing-webface".to_string();
    app.set_debug(true);
    app.set_log_level();
    app.httperrorhandler(404, page_not_found);
    app.httperrorhandler(500, server_error);
    app.enable_static_file_handling();
    debug!("root_path: {}", app.root_path);

    app.register_template("base.html");
    app.register_template("home.html");
    app.register_template("raw.html");
    app.get("/", "home", home);
    app.get("/readme/", "readme", readme);
    app.register_template("model_list.html");
    app.get("/model_list/", "model_list", model_list);
    app.register_template("model_view.html");
    app.get("/model/<model_slug:string>/", "model", model_view);

    let bind = matches.opt_str("bind").unwrap_or("127.0.0.1:5000".to_string());
    let bind_str: &str = &bind;
    info!("Running on {}", bind);
    app.run(bind_str);
}