src/web: nitweb use popcorn
authorAlexandre Terrasa <alexandre@moz-code.org>
Fri, 20 May 2016 00:01:31 +0000 (20:01 -0400)
committerAlexandre Terrasa <alexandre@moz-code.org>
Fri, 20 May 2016 20:18:31 +0000 (16:18 -0400)
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>

src/nitweb.nit
src/web/web_actions.nit
src/web/web_base.nit

index b924ec2..c055ee9 100644 (file)
@@ -47,15 +47,15 @@ private class NitwebPhase
                var host = toolcontext.opt_host.value or else "localhost"
                var port = toolcontext.opt_port.value
 
-               var srv = new NitServer(host, port.to_i)
-               srv.routes.add new Route("/random", new RandomAction(srv, model))
-               srv.routes.add new Route("/doc/:namespace", new DocAction(srv, model, modelbuilder))
-               srv.routes.add new Route("/code/:namespace", new CodeAction(srv, model, modelbuilder))
-               srv.routes.add new Route("/search/:namespace", new SearchAction(srv, model))
-               srv.routes.add new Route("/uml/:namespace", new UMLDiagramAction(srv, model, mainmodule))
-               srv.routes.add new Route("/", new TreeAction(srv, model))
+               var app = new App
+               app.use("/random", new RandomAction(model))
+               app.use("/doc/:namespace", new DocAction(model, modelbuilder))
+               app.use("/code/:namespace", new CodeAction(model, modelbuilder))
+               app.use("/search/:namespace", new SearchAction(model))
+               app.use("/uml/:namespace", new UMLDiagramAction(model, mainmodule))
+               app.use("/", new TreeAction(model))
 
-               srv.listen
+               app.listen(host, port.to_i)
        end
 end
 
index 60d39c2..e9198ae 100644 (file)
@@ -22,10 +22,10 @@ import uml
 class TreeAction
        super ModelAction
 
-       redef fun answer(request, url) do
-               var model = init_model_view(request)
+       redef fun get(req, res) do
+               var model = init_model_view(req)
                var view = new HtmlHomePage(model.to_tree)
-               return render_view(view)
+               res.send_view(view)
        end
 end
 
@@ -34,18 +34,20 @@ class SearchAction
        super ModelAction
 
        # TODO handle more than full namespaces.
-       redef fun answer(request, url) do
-               var namespace = request.param("namespace")
-               var model = init_model_view(request)
+       redef fun get(req, res) do
+               var namespace = req.param("namespace")
+               var model = init_model_view(req)
                var mentity = find_mentity(model, namespace)
                if mentity == null then
-                       return render_error(404, "No mentity found")
+                       res.error(404)
+                       return
                end
-               if request.is_json_asked then
-                       return render_json(mentity.to_json)
+               if req.is_json_asked then
+                       res.json(mentity.to_json)
+                       return
                end
                var view = new HtmlResultPage(namespace or else "null", [mentity])
-               return render_view(view)
+               res.send_view(view)
        end
 end
 
@@ -56,15 +58,16 @@ class CodeAction
        # Modelbuilder used to access sources.
        var modelbuilder: ModelBuilder
 
-       redef fun answer(request, url) do
-               var namespace = request.param("namespace")
-               var model = init_model_view(request)
+       redef fun get(req, res) do
+               var namespace = req.param("namespace")
+               var model = init_model_view(req)
                var mentity = find_mentity(model, namespace)
                if mentity == null then
-                       return render_error(404, "No mentity found")
+                       res.error(404)
+                       return
                end
                var view = new HtmlSourcePage(modelbuilder, mentity)
-               return render_view(view)
+               res.send_view(view)
        end
 end
 
@@ -75,16 +78,21 @@ class DocAction
        # Modelbuilder used to access sources.
        var modelbuilder: ModelBuilder
 
-       # TODO handle more than full namespaces.
-       redef fun answer(request, url) do
-               var namespace = request.param("namespace")
-               var model = init_model_view(request)
+       redef fun get(req, res) do
+               var namespace = req.param("namespace")
+               var model = init_model_view(req)
                var mentity = find_mentity(model, namespace)
                if mentity == null then
-                       return render_error(404, "No mentity found")
+                       res.error(404)
+                       return
+               end
+               if req.is_json_asked then
+                       res.json(mentity.to_json)
+                       return
                end
+
                var view = new HtmlDocPage(modelbuilder, mentity)
-               return render_view(view)
+               res.send_view(view)
        end
 end
 
@@ -95,12 +103,13 @@ class UMLDiagramAction
        # Mainmodule used for hierarchy flattening.
        var mainmodule: MModule
 
-       redef fun answer(request, url) do
-               var namespace = request.param("namespace")
-               var model = init_model_view(request)
+       redef fun get(req, res) do
+               var namespace = req.param("namespace")
+               var model = init_model_view(req)
                var mentity = find_mentity(model, namespace)
                if mentity == null then
-                       return render_error(404, "No mentity found")
+                       res.error(404)
+                       return
                end
 
                var dot
@@ -112,10 +121,11 @@ class UMLDiagramAction
                        var uml = new UMLModel(model, mentity)
                        dot = uml.generate_package_uml.write_to_string
                else
-                       return render_error(404, "No diagram matching this namespace.")
+                       res.error(404)
+                       return
                end
                var view = new HtmlDotPage(dot, mentity.as(not null).html_name)
-               return render_view(view)
+               res.send_view(view)
        end
 end
 
@@ -123,11 +133,10 @@ end
 class RandomAction
        super ModelAction
 
-       # TODO handle more than full namespaces.
-       redef fun answer(request, url) do
-               var n = request.int_arg("n") or else 10
-               var k = request.string_arg("k") or else "modules"
-               var model = init_model_view(request)
+       redef fun get(req, res) do
+               var n = req.int_arg("n") or else 10
+               var k = req.string_arg("k") or else "modules"
+               var model = init_model_view(req)
                var mentities: Array[MEntity]
                if k == "modules" then
                        mentities = model.mmodules.to_a
@@ -138,14 +147,15 @@ class RandomAction
                end
                mentities.shuffle
                mentities = mentities.sub(0, n)
-               if request.is_json_asked then
+               if req.is_json_asked then
                        var json = new JsonArray
                        for mentity in mentities do
                                json.add mentity.to_json
                        end
-                       return render_json(json)
+                       res.json(json)
+                       return
                end
                var view = new HtmlResultPage("random", mentities)
-               return render_view(view)
+               res.send_view(view)
        end
 end
index 5d7dbde..258ec60 100644 (file)
@@ -17,77 +17,11 @@ module web_base
 
 import model::model_views
 import model::model_json
-import nitcorn
-
-# Nitcorn server runned by `nitweb`.
-#
-# Usage:
-#
-# ~~~nitish
-# var srv = new NitServer("localhost", 3000)
-# srv.routes.add new Route("/", new MyAction)
-# src.listen
-# ~~~
-class NitServer
-
-       # Host to bind.
-       var host: String
-
-       # Port to use.
-       var port: Int
-
-       # Routes knwon by the server.
-       var routes = new Array[Route]
-
-       # Start listen on `host:port`.
-       fun listen do
-               var iface = "{host}:{port}"
-               print "Launching server on http://{iface}/"
-
-               var vh = new VirtualHost(iface)
-               for route in routes do vh.routes.add route
-
-               var fac = new HttpFactory.and_libevent
-               fac.config.virtual_hosts.add vh
-               fac.run
-       end
-end
-
-# Specific nitcorn Action for nitweb.
-class NitAction
-       super Action
-
-       # Link to the NitServer that runs this action.
-       var srv: NitServer
-
-       # Build a custom http response for errors.
-       fun render_error(code: Int, message: String): HttpResponse do
-               var response = new HttpResponse(code)
-               var tpl = new Template
-               tpl.add "<h1>Error {code}</h1>"
-               tpl.add "<pre><code>{message.html_escape}</code></pre>"
-               response.body = tpl.write_to_string
-               return response
-       end
-
-       # Render a view as a HttpResponse 200.
-       fun render_view(view: NitView): HttpResponse do
-               var response = new HttpResponse(200)
-               response.body = view.render.write_to_string
-               return response
-       end
-
-       # Return a HttpResponse containing `json`.
-       fun render_json(json: Jsonable): HttpResponse do
-               var response = new HttpResponse(200)
-               response.body = json.to_json
-               return response
-       end
-end
+import popcorn
 
 # Specific nitcorn Action that uses a Model
 class ModelAction
-       super NitAction
+       super Handler
 
        # Model to use.
        var model: Model
@@ -119,6 +53,11 @@ interface NitView
        fun render: Writable is abstract
 end
 
+redef class HttpResponse
+       # Render a NitView as response.
+       fun send_view(view: NitView, status: nullable Int) do send(view.render, status)
+end
+
 redef class HttpRequest
        # Does the client asked for a json formatted response?
        #