From d5a6f80df10cd6a752bbe9e959a9cd9a1e3b82fb Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Tue, 3 Feb 2015 22:40:07 +0100 Subject: [PATCH] contrib/nitrpg: introduce the tool that run the website Signed-off-by: Alexandre Terrasa --- contrib/nitrpg/src/web.nit | 168 ++++++++++++++++++++++++++++++++++++ contrib/nitrpg/www/styles/main.css | 74 ++++++++++++++++ 2 files changed, 242 insertions(+) create mode 100644 contrib/nitrpg/src/web.nit create mode 100644 contrib/nitrpg/www/styles/main.css diff --git a/contrib/nitrpg/src/web.nit b/contrib/nitrpg/src/web.nit new file mode 100644 index 0000000..80f7821 --- /dev/null +++ b/contrib/nitrpg/src/web.nit @@ -0,0 +1,168 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2014-2015 Alexandre Terrasa +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Display `nitrpg` data as a website. +module web + +import nitcorn +import templates + +# A custom action forn `nitrpg`. +class RpgAction + super Action + + # Root URL is used as a prefix for all URL generated by the actions. + var root_url: String + + # Github oauth token used for GithubAPI. + var auth: String is lazy do return get_github_oauth + + # API client used to import data from Github. + var api: GithubAPI is lazy do + var api = new GithubAPI(auth) + return api + end + + init do + super + if auth.is_empty then + print "Error: Invalid Github oauth token!" + exit 1 + end + end + + # Return an Error reponse page. + fun bad_request(msg: String): HttpResponse do + var rsp = new HttpResponse(400) + var page = new NitRpgPage(root_url) + var error = new ErrorPanel(msg) + page.flow_panels.add error + rsp.body = page.write_to_string + return rsp + end +end + +# An action that require a game. +class GameAction + super RpgAction + + # Response page stub. + var page: NitRpgPage is noinit + + # Target game. + var game: Game is noinit + + redef fun answer(request, url) is abstract + + # Check errors and prepare response. + private fun prepare_response(request: HttpRequest, url: String): HttpResponse do + var owner = request.param("owner") + var repo_name = request.param("repo") + if owner == null or repo_name == null then + var msg = "Bad request: should look like /repos/:owner/:repo." + return bad_request(msg) + end + var repo = new Repo(api, "{owner}/{repo_name}") + game = new Game(api, repo) + game.root_url = root_url + if api.was_error then + var msg = api.last_error.message + return bad_request("Repo Error: {msg}") + end + var response = new HttpResponse(200) + page = new NitRpgPage(root_url) + page.side_panels.add new GameStatusPanel(game) + page.breadcrumbs = new Breadcrumbs + page.breadcrumbs.add_link(game.url, game.name) + return response + end +end + +# Repo overview page. +class RepoHome + super GameAction + + redef fun answer(request, url) do + var rsp = prepare_response(request, url) + page.side_panels.add new ShortListPlayersPanel(game) + page.flow_panels.add new PodiumPanel(game) + rsp.body = page.write_to_string + return rsp + end +end + +# Repo players list. +class ListPlayers + super GameAction + + redef fun answer(request, url) do + var rsp = prepare_response(request, url) + page.breadcrumbs.add_link(game.url / "players", "players") + page.flow_panels.add new ListPlayersPanel(game) + rsp.body = page.write_to_string + return rsp + end +end + +# Player details page. +class PlayerHome + super GameAction + + redef fun answer(request, url) do + var rsp = prepare_response(request, url) + var name = request.param("player") + if name == null then + var msg = "Bad request: should look like /:owner/:repo/:players/:name." + return bad_request(msg) + end + var player = game.load_player(name) + if player == null then + return bad_request("Request Error: unknown player {name}.") + end + page.breadcrumbs.add_link(game.url / "players", "players") + page.breadcrumbs.add_link(player.url, name) + page.side_panels.clear + page.side_panels.add new PlayerStatusPanel(game, player) + page.flow_panels.add new PlayerReviewsPanel(game, player) + rsp.body = page.write_to_string + return rsp + end +end + +if args.length != 3 then + print "Error: missing argument" + print "" + print "Usage:" + print "web " + exit 1 +end + +var host = args[0] +var port = args[1] +var root = args[2] + +var iface = "{host}:{port}" +var vh = new VirtualHost(iface) +vh.routes.add new Route("/styles/", new FileServer("www/styles")) +vh.routes.add new Route("/games/:owner/:repo/players/:player", new PlayerHome(root)) +vh.routes.add new Route("/games/:owner/:repo/players", new ListPlayers(root)) +vh.routes.add new Route("/games/:owner/:repo", new RepoHome(root)) + +var fac = new HttpFactory.and_libevent +fac.config.virtual_hosts.add vh + +print "Launching server on http://{iface}/" +fac.run diff --git a/contrib/nitrpg/www/styles/main.css b/contrib/nitrpg/www/styles/main.css new file mode 100644 index 0000000..865123e --- /dev/null +++ b/contrib/nitrpg/www/styles/main.css @@ -0,0 +1,74 @@ +body { padding-top: 70px; } + +.navbar .breadcrumb { + background-color: transparent; + margin-bottom: 0; + margin-top: 0.5em; +} + +/* columns of same height styles */ +.container-xs-height { + display:table; + padding-left:0px; + padding-right:0px; +} +.row-xs-height { + display:table-row; +} +.col-xs-height { + display:table-cell; + float:none; +} +@media (min-width: 768px) { + .container-sm-height { + display:table; + padding-left:0px; + padding-right:0px; + } + .row-sm-height { + display:table-row; + } + .col-sm-height { + display:table-cell; + float:none; + } +} +@media (min-width: 992px) { + .container-md-height { + display:table; + padding-left:0px; + padding-right:0px; + } + .row-md-height { + display:table-row; + } + .col-md-height { + display:table-cell; + float:none; + } +} +@media (min-width: 1200px) { + .container-lg-height { + display:table; + padding-left:0px; + padding-right:0px; + } + .row-lg-height { + display:table-row; + } + .col-lg-height { + display:table-cell; + float:none; + } +} + +/* vertical alignment styles */ +.col-top { + vertical-align:top; +} +.col-middle { + vertical-align:middle; +} +.col-bottom { + vertical-align:bottom; +} -- 1.7.9.5