Commit 7089ef83 authored by Aljaž Srebrnič's avatar Aljaž Srebrnič

move to spaceapi-server-rs with custom modifier

parent f10a29de
This diff is collapsed.
......@@ -5,8 +5,8 @@ authors = ["Aljaž \"g5pw\" Srebrnič <a2piratesoft@gmail.com>"]
edition = "2018"
[dependencies]
spaceapi = "^0.5"
serde_json = "*"
json-patch = "*"
iron = "0.6.*"
r2d2_redis = "*"
spaceapi-server = "*"
env_logger = "*"
r2d2 = "0.8"
r2d2_redis = "0.9.0"
redis = "0.10"
{
"api": "0.13",
"space": "Mittelab",
"logo": "https://www.mittelab.org/images/logo.svg",
"url": "https://www.mittelab.org",
"location": {
"address": "Piazza Liberà 5/B, 34132 Trieste (TS), Italy",
"lon": 13.7733872,
"lat": 45.6566526
},
"contact": {
"email": "info@mittelab.org",
"irc": "irc://irc.freenode.net/#mittelab",
"twitter": "@mittelab",
"facebook": "https://facebook.com/mittelab",
"phone": "+390409776431",
"issue_mail": "sysadmin@mittelab.org"
},
"issue_report_channels": [
"email"
],
"state": {
"open": null
},
"projects": [
"https://git.mittelab.org",
"https://github.com/mittelab",
"https://wiki.mittelab.org/progetti/"
]
}
use spaceapi::Status;
use serde_json::{to_value, to_string, from_value, from_str};
use json_patch::merge;
use iron::prelude::*;
use iron::{status, headers, middleware};
use iron::modifiers::Header;
use r2d2_redis::{r2d2, redis, RedisConnectionManager};
pub struct ReadHandler {
status: Status,
redis_pool: r2d2::Pool<RedisConnectionManager>,
}
impl ReadHandler {
pub fn new(status: Status,
redis_pool: r2d2::Pool<RedisConnectionManager>)
-> ReadHandler {
ReadHandler {
status,
redis_pool,
}
}
fn build_response_json(&self) -> String {
// Create a mutable copy of the status struct
let mut status = to_value(self.status.clone()).unwrap();
let conn = self.redis_pool.get().unwrap();
let data: String = redis::cmd("JSON.GET").arg("spaceapi").query(&*conn).unwrap_or("".to_string());
let update = from_str(&data).unwrap();
merge(&mut status, &update);
let status: Status = from_value(status).expect("Cannot construct Status object");
// Serialize to JSON
to_string(&status)
.expect("Status object could not be serialized to JSON. \
Please open an issue at https://github.com/spaceapi-community/spaceapi-server-rs/issues")
}
}
impl middleware::Handler for ReadHandler {
/// Return the current status JSON.
fn handle(&self, _req: &mut Request) -> IronResult<Response> {
// info!("{} /{} from {}", req.method, req.url.path()[0], req.remote_addr);
// Get response body
let body = self.build_response_json();
// Create response
let response = Response::with((status::Ok, body))
// Set headers
.set(Header(headers::ContentType("application/json; charset=utf-8".parse().unwrap())))
.set(Header(headers::CacheControl(vec![headers::CacheDirective::NoCache])))
.set(Header(headers::AccessControlAllowOrigin::Any));
Ok(response)
}
}
\ No newline at end of file
use std::error::Error;
use std::fs::File;
use std::io::BufReader;
use std::path::Path;
use spaceapi::Status;
use serde_json::from_reader;
use iron::prelude::*;
use iron::status;
use r2d2_redis::{r2d2, RedisConnectionManager};
use crate::handlers::ReadHandler;
mod handlers;
fn read_spaceapi_from_file<P: AsRef<Path>>(path: P) -> Result<Status, Box<Error>> {
// Open the file in read-only mode with buffer.
let file = File::open(path)?;
let reader = BufReader::new(file);
let status = from_reader(reader)?;
Ok(status)
extern crate spaceapi_server;
extern crate env_logger;
extern crate r2d2_redis;
use spaceapi_server::SpaceapiServerBuilder;
use spaceapi_server::api;
use spaceapi_server::modifiers::StatusModifier;
use r2d2;
use r2d2_redis::RedisConnectionManager;
use redis;
use redis::{Commands, RedisResult};
type RedisPool = r2d2::Pool<RedisConnectionManager>;
struct OpenStatusFromRedisModifier {
pool: RedisPool
}
impl OpenStatusFromRedisModifier {
fn new(pool: RedisPool) -> OpenStatusFromRedisModifier {
OpenStatusFromRedisModifier{pool}
}
}
impl StatusModifier for OpenStatusFromRedisModifier {
fn modify(&self, status: &mut api::Status) {
let conn = self.pool.get().unwrap();
let state : RedisResult<String> = conn.get("state_open");
status.state.open = match state {
Ok(v) => Some(v == "open"),
Err(_) => None
};
status.state.lastchange = conn.get("state_lastchange").ok();
status.state.trigger_person = conn.get("state_triggerperson").ok();
}
}
fn main() {
env_logger::init();
// Create new minimal Status instance
let status = api::StatusBuilder::new("Mittelab")
.logo("https://www.mittelab.org/images/logo.svg")
.url("https://www.mittelab.org")
.location(api::Location {
address: Some("Piazza Liberà 5/B, 34132 Trieste (TS), Italy".into()),
lat: 45.6566526,
lon: 13.7733872,
})
.contact(api::Contact {
email: Some("info@mittelab.org".into()),
irc: Some("irc://irc.freenode.net/#mittelab".into()),
twitter: Some("@mittelab".into()),
facebook: Some("https://facebook.com/mittelab".into()),
phone: Some("+390409776431".into()),
issue_mail: Some("sysadmin@mittelab.org".into()),
..Default::default()
})
.add_issue_report_channel("email")
.add_project("https://git.mittelab.org")
.add_project("https://github.com/mittelab")
.add_project("https://wiki.mittelab.org/progetti/")
.build()
.expect("Creating status failed");
let manager = RedisConnectionManager::new("redis://localhost").unwrap();
let pool = r2d2::Pool::builder()
let pool = RedisPool::builder()
.build(manager)
.unwrap();
let base = read_spaceapi_from_file("base.json").expect("Cannot read file!");
// Set up server
let server = SpaceapiServerBuilder::new(status)
// .add_redis_pool(pool) waiting for
.redis_connection_info("redis://localhost")
.add_status_modifier(OpenStatusFromRedisModifier::new(pool))
.build()
.expect("Could not initialize server");
let _server = Iron::new( ReadHandler::new(base, pool)).http("localhost:3000").unwrap();
// Serve!
server.serve("127.0.0.1:8000").expect("Could not start the server");
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment