--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2014-2015 Alexandre Terrasa <alexandre@moz-code.org>
+#
+# 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 <host> <port> <root_url>"
+ 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