mirror of
https://github.com/tiffany352/rink-rs
synced 2024-11-10 13:44:15 +00:00
web: Add config file + opensearch support
This commit is contained in:
parent
914f3a8dc2
commit
37925d59c3
5 changed files with 68 additions and 7 deletions
|
@ -33,3 +33,4 @@ serde = "0.8"
|
||||||
limiter = "0.2"
|
limiter = "0.2"
|
||||||
logger = "0.1.0"
|
logger = "0.1.0"
|
||||||
url = "1.2.0"
|
url = "1.2.0"
|
||||||
|
toml = { version = "0.2", features = ["serde"] }
|
||||||
|
|
6
web/rink-web.toml.sample
Normal file
6
web/rink-web.toml.sample
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# The absolute URL of the place this instance will be hosted. It may
|
||||||
|
# have an explicit protocol, but usually you'll want the // prefix
|
||||||
|
# instead. It should not have a trailing slash. Note that rink-web
|
||||||
|
# does not currently support being placed under a directory, it must
|
||||||
|
# have a subdomain to itself.
|
||||||
|
baseurl = "//rink.tiffnix.com"
|
|
@ -20,6 +20,7 @@ extern crate serde_json;
|
||||||
extern crate limiter;
|
extern crate limiter;
|
||||||
extern crate logger;
|
extern crate logger;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
extern crate toml;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
@ -41,10 +42,15 @@ use std::env;
|
||||||
use worker::{eval_text, eval_json};
|
use worker::{eval_text, eval_json};
|
||||||
use limiter::RequestLimit;
|
use limiter::RequestLimit;
|
||||||
use logger::Logger;
|
use logger::Logger;
|
||||||
use rustc_serialize::json::ToJson;
|
use rustc_serialize::json::{ToJson, Json};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::fs::File;
|
||||||
|
|
||||||
fn root(req: &mut Request) -> IronResult<Response> {
|
struct Rink {
|
||||||
|
config: Json,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn root(rink: &Rink, req: &mut Request) -> IronResult<Response> {
|
||||||
let mut data = BTreeMap::new();
|
let mut data = BTreeMap::new();
|
||||||
|
|
||||||
let map = req.get_ref::<Params>().unwrap();
|
let map = req.get_ref::<Params>().unwrap();
|
||||||
|
@ -64,10 +70,12 @@ fn root(req: &mut Request) -> IronResult<Response> {
|
||||||
data.insert("main-page".to_owned(), true.to_json());
|
data.insert("main-page".to_owned(), true.to_json());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data.insert("config".to_owned(), rink.config.to_json());
|
||||||
|
|
||||||
Ok(Response::with((status::Ok, Template::new("index", data))))
|
Ok(Response::with((status::Ok, Template::new("index", data))))
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ErrorMiddleware;
|
struct ErrorMiddleware(Arc<Rink>);
|
||||||
|
|
||||||
impl AfterMiddleware for ErrorMiddleware {
|
impl AfterMiddleware for ErrorMiddleware {
|
||||||
fn catch(&self, _req: &mut Request, err: IronError) -> IronResult<Response> {
|
fn catch(&self, _req: &mut Request, err: IronError) -> IronResult<Response> {
|
||||||
|
@ -79,12 +87,13 @@ impl AfterMiddleware for ErrorMiddleware {
|
||||||
}
|
}
|
||||||
error.insert("message".to_owned(), format!("{}", err.error));
|
error.insert("message".to_owned(), format!("{}", err.error));
|
||||||
data.insert("error".to_owned(), error.to_json());
|
data.insert("error".to_owned(), error.to_json());
|
||||||
|
data.insert("config".to_owned(), self.0.config.to_json());
|
||||||
println!("{:#?}", data);
|
println!("{:#?}", data);
|
||||||
Ok(err.response.set(Template::new("index", data)))
|
Ok(err.response.set(Template::new("index", data)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn api(req: &mut Request) -> IronResult<Response> {
|
fn api(_rink: &Rink, req: &mut Request) -> IronResult<Response> {
|
||||||
let acao = Header(headers::AccessControlAllowOrigin::Any);
|
let acao = Header(headers::AccessControlAllowOrigin::Any);
|
||||||
|
|
||||||
let map = req.get_ref::<Params>().unwrap();
|
let map = req.get_ref::<Params>().unwrap();
|
||||||
|
@ -98,6 +107,13 @@ fn api(req: &mut Request) -> IronResult<Response> {
|
||||||
Ok(Response::with((acao, status::Ok, reply)))
|
Ok(Response::with((acao, status::Ok, reply)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn opensearch(rink: &Rink, _req: &mut Request) -> IronResult<Response> {
|
||||||
|
let mut data = BTreeMap::new();
|
||||||
|
data.insert("config".to_owned(), rink.config.to_json());
|
||||||
|
|
||||||
|
Ok(Response::with((status::Ok, Template::new("opensearch", data))))
|
||||||
|
}
|
||||||
|
|
||||||
fn ifnot1helper(
|
fn ifnot1helper(
|
||||||
c: &handlebars::Context,
|
c: &handlebars::Context,
|
||||||
h: &handlebars::Helper,
|
h: &handlebars::Helper,
|
||||||
|
@ -175,13 +191,35 @@ fn main() {
|
||||||
worker::worker(&server, &query);
|
worker::worker(&server, &query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let config = {
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
|
let mut file = File::open("rink-web.toml").expect(
|
||||||
|
"Config file rink-web.toml does not exist. You \
|
||||||
|
must create it with the keys specified in the \
|
||||||
|
sample."
|
||||||
|
);
|
||||||
|
let mut buf = String::new();
|
||||||
|
file.read_to_string(&mut buf).unwrap();
|
||||||
|
let res = toml::Parser::new(&buf).parse().unwrap();
|
||||||
|
rustc_serialize::json::Json::from_str(
|
||||||
|
&serde_json::ser::to_string(&res).unwrap()
|
||||||
|
).unwrap()
|
||||||
|
};
|
||||||
|
let rink = Arc::new(Rink {
|
||||||
|
config: config,
|
||||||
|
});
|
||||||
let (logger_before, logger_after) = Logger::new(None);
|
let (logger_before, logger_after) = Logger::new(None);
|
||||||
|
|
||||||
let mut mount = Mount::new();
|
let mut mount = Mount::new();
|
||||||
|
|
||||||
let mut router = Router::new();
|
let mut router = Router::new();
|
||||||
router.get("/", root, "root");
|
let rink2 = rink.clone();
|
||||||
router.get("/api", api, "api");
|
router.get("/", move |req: &mut Request| root(&rink2, req), "root");
|
||||||
|
let rink2 = rink.clone();
|
||||||
|
router.get("/api", move |req: &mut Request| api(&rink2, req), "api");
|
||||||
|
let rink2 = rink.clone();
|
||||||
|
router.get("/opensearch.xml", move |req: &mut Request| opensearch(&rink2, req), "opensearch.xml");
|
||||||
mount.mount("/", router);
|
mount.mount("/", router);
|
||||||
|
|
||||||
mount.mount("/static", Static::new("./static/"));
|
mount.mount("/static", Static::new("./static/"));
|
||||||
|
@ -204,7 +242,7 @@ fn main() {
|
||||||
|
|
||||||
chain.link_before(logger_before);
|
chain.link_before(logger_before);
|
||||||
chain.link_before(limiter);
|
chain.link_before(limiter);
|
||||||
chain.link_after(ErrorMiddleware);
|
chain.link_after(ErrorMiddleware(rink.clone()));
|
||||||
chain.link_after(hbse);
|
chain.link_after(hbse);
|
||||||
chain.link_after(logger_after);
|
chain.link_after(logger_after);
|
||||||
let addr = first.as_ref().map(|x| &**x).unwrap_or("localhost:8000");
|
let addr = first.as_ref().map(|x| &**x).unwrap_or("localhost:8000");
|
||||||
|
|
|
@ -17,6 +17,10 @@
|
||||||
rel="stylesheet" />
|
rel="stylesheet" />
|
||||||
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap-theme.css"
|
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap-theme.css"
|
||||||
rel="stylesheet" />
|
rel="stylesheet" />
|
||||||
|
<link rel="search"
|
||||||
|
type="application/opensearchdescription+xml"
|
||||||
|
href="{{config.baseurl}}/opensearch.xml"
|
||||||
|
title="Rink Search" />
|
||||||
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
|
||||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
|
||||||
|
|
12
web/templates/opensearch.hbs
Normal file
12
web/templates/opensearch.hbs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
|
||||||
|
xmlns:moz="http://www.mozilla.org/2006/browser/search/">
|
||||||
|
<ShortName>Rink</ShortName>
|
||||||
|
<Description>Perform a Rink calculation</Description>
|
||||||
|
<Url type="text/html" method="get" template="{{config.baseurl}}/?q={searchTerms}"/>
|
||||||
|
<moz:SearchForm>{{config.baseurl}}/</moz:SearchForm>
|
||||||
|
<InputEncoding>UTF-8</InputEncoding>
|
||||||
|
<Url type="application/opensearchdescription+xml"
|
||||||
|
rel="self"
|
||||||
|
template="{{config.baseurl}}/opensearch.xml"/>
|
||||||
|
</OpenSearchDescription>
|
Loading…
Reference in a new issue