From c17ded75afcc91d8b9304e94d308446da54cf794 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alexis=20Laferri=C3=A8re?= Date: Tue, 5 Apr 2016 16:29:28 -0400 Subject: [PATCH] contrib/benitlux: intro the admin server interface with daily notification MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexis Laferrière --- contrib/benitlux/src/benitlux_controller.nit | 51 ++++++++++++++++++++++++++ contrib/benitlux/src/benitlux_model.nit | 8 ++++ contrib/benitlux/src/benitlux_web.nit | 9 ++++- 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/contrib/benitlux/src/benitlux_controller.nit b/contrib/benitlux/src/benitlux_controller.nit index 5f5513a..c65ac37 100644 --- a/contrib/benitlux/src/benitlux_controller.nit +++ b/contrib/benitlux/src/benitlux_controller.nit @@ -322,6 +322,57 @@ redef class Sys end # --- +# Administration + +# Path to the secret used to authenticate admin requests +fun secret_path: String do return "benitlux.secret" + +# Services reserved to administrators +class BenitluxAdminAction + super BenitluxAction + super RestfulAction + + private fun server_secret: String do return secret_path.to_path.read_all + + # Trigger sending daily menu to connected clients + # + # This should usually be called by an external cron program. + # send_daily_updates?secret=shared_secret -> true | BenitluxError + fun send_daily_updates(secret: nullable String): HttpResponse + is restful do + # Check secrets + var server_secret = server_secret + if server_secret.is_empty then + print_error "The admin interface needs a secret at '{secret_path}'" + return new HttpResponse.server_error + end + + if server_secret != secret then + return new HttpResponse.invalid_token + end + + # Load beer menu + var list = db.list_beers_and_rating + if list == null then return new HttpResponse.server_error + + var msg = new DailyNotification(list) + + # Broadcast updates + for conn in push_connections.values.to_a do + if not conn.closed then + conn.respond new HttpResponse.ok(msg) + conn.close + end + end + push_connections.clear + + return new HttpResponse.ok(true) + end + + redef fun answer(request, turi) do return new HttpResponse.bad_request +end + +# --- # Misc services redef class Text diff --git a/contrib/benitlux/src/benitlux_model.nit b/contrib/benitlux/src/benitlux_model.nit index 987047f..48a807a 100644 --- a/contrib/benitlux/src/benitlux_model.nit +++ b/contrib/benitlux/src/benitlux_model.nit @@ -234,6 +234,14 @@ class CheckinReport var users = new Array[User] end +# Daily menu notifications +class DailyNotification + serialize + + # All beers on the menu today + var beers: Array[BeerAndRatings] +end + # Server or API usage error class BenitluxError super Error diff --git a/contrib/benitlux/src/benitlux_web.nit b/contrib/benitlux/src/benitlux_web.nit index d5bab54..3b2743b 100644 --- a/contrib/benitlux/src/benitlux_web.nit +++ b/contrib/benitlux/src/benitlux_web.nit @@ -25,6 +25,9 @@ import benitlux_restful # Listening interface fun iface: String do return "localhost:8080" +# Listening interface for admin commands +fun iface_admin: String do return "localhost:8081" + # Sqlite3 database var db_path = "benitlux_sherbrooke.db" var db = new BenitluxDB.open(db_path) @@ -40,10 +43,14 @@ vh.routes.add new Route("/rest/", new BenitluxRESTAction(db)) vh.routes.add new Route("/push/", new BenitluxPushAction(db)) vh.routes.add new Route(null, new BenitluxSubscriptionAction(db)) +var vh_admin = new VirtualHost(iface_admin) +vh_admin.routes.add new Route(null, new BenitluxAdminAction(db)) + var factory = new HttpFactory.and_libevent factory.config.virtual_hosts.add vh +factory.config.virtual_hosts.add vh_admin -print "Launching server on http://{iface}/" +print "Launching server on http://{iface}/ and http://{iface_admin}/" factory.run db.close -- 1.7.9.5