Merge: Model index
[nit.git] / src / nitweb.nit
index 1df4153..9484425 100644 (file)
 # Runs a webserver based on nitcorn that render things from model.
 module nitweb
 
+import popcorn::pop_config
+import popcorn::pop_auth
 import frontend
 import web
 
+redef class NitwebConfig
+
+       # Github client id used for Github OAuth login.
+       #
+       # * key: `github.client_id`
+       # * default: ``
+       var github_client_id: String is lazy do return value_or_default("github.client.id", "")
+
+       # Github client secret used for Github OAuth login.
+       #
+       # * key: `github.client_secret`
+       # * default: ``
+       var github_client_secret: String is lazy do
+               return value_or_default("github.client.secret", "")
+       end
+end
+
 redef class ToolContext
 
-       # Host name to bind on.
+       # Path to app config file.
+       var opt_config = new OptionString("Path to app config file", "--config")
+
+       # Host name to bind on (will overwrite the config one).
        var opt_host = new OptionString("Host to bind the server on", "--host")
 
-       # Port number to bind on.
-       var opt_port = new OptionInt("Port number to use", 3000, "--port")
+       # Port number to bind on (will overwrite the config one).
+       var opt_port = new OptionInt("Port number to use", -1, "--port")
 
        # Web rendering phase.
        var webphase: Phase = new NitwebPhase(self, null)
 
        init do
                super
-               option_context.add_option(opt_host, opt_port)
+               option_context.add_option(opt_config, opt_host, opt_port)
        end
 end
 
 # Phase that builds the model and wait for http request to serve pages.
 private class NitwebPhase
        super Phase
+
+       # Build the nitweb config from `toolcontext` options.
+       fun build_config(toolcontext: ToolContext, mainmodule: MModule): NitwebConfig do
+               var config_file = toolcontext.opt_config.value
+               if config_file == null then config_file = "nitweb.ini"
+               var config = new NitwebConfig(
+                       config_file,
+                       toolcontext.modelbuilder.model,
+                       mainmodule,
+                       toolcontext.modelbuilder)
+               var opt_host = toolcontext.opt_host.value
+               if opt_host != null then config["app.host"] = opt_host
+               var opt_port = toolcontext.opt_port.value
+               if opt_port >= 0 then config["app.port"] = opt_port.to_s
+               return config
+       end
+
+       # Build the nit catalog used in homepage.
+       fun build_catalog(model: Model, modelbuilder: ModelBuilder): Catalog do
+               var catalog = new Catalog(modelbuilder)
+               for mpackage in model.mpackages do
+                       catalog.deps.add_node(mpackage)
+                       for mgroup in mpackage.mgroups do
+                               for mmodule in mgroup.mmodules do
+                                       for imported in mmodule.in_importation.direct_greaters do
+                                               var ip = imported.mpackage
+                                               if ip == null or ip == mpackage then continue
+                                               catalog.deps.add_edge(mpackage, ip)
+                                       end
+                               end
+                       end
+                       catalog.git_info(mpackage)
+                       catalog.package_page(mpackage)
+               end
+               return catalog
+       end
+
        redef fun process_mainmodule(mainmodule, mmodules)
        do
                var model = mainmodule.model
                var modelbuilder = toolcontext.modelbuilder
-
-               # Run the server
-               var host = toolcontext.opt_host.value or else "localhost"
-               var port = toolcontext.opt_port.value
+               var config = build_config(toolcontext, mainmodule)
+               var catalog = build_catalog(model, modelbuilder)
 
                var app = new App
 
-               app.use("/api", new APIRouter(model, modelbuilder, mainmodule))
-               app.use("/doc/:namespace", new DocAction(model, mainmodule, modelbuilder))
-               app.use("/", new TreeAction(model, mainmodule))
+               app.use_before("/*", new SessionInit)
+               app.use_before("/*", new RequestClock)
+               app.use("/api", new NitwebAPIRouter(config, catalog))
+               app.use("/login", new GithubLogin(config.github_client_id))
+               app.use("/oauth", new GithubOAuthCallBack(config.github_client_id, config.github_client_secret))
+               app.use("/logout", new GithubLogout)
+               app.use("/*", new StaticHandler(toolcontext.share_dir / "nitweb", "index.html"))
+               app.use_after("/*", new ConsoleLog)
 
-               app.listen(host, port.to_i)
+               app.listen(config.app_host, config.app_port)
+       end
+end
+
+# Group all api handlers in one router.
+class NitwebAPIRouter
+       super APIRouter
+
+       # Catalog to pass to handlers.
+       var catalog: Catalog
+
+       init do
+               use("/catalog", new APICatalogRouter(config, catalog))
+               use("/list", new APIList(config))
+               use("/search", new APISearch(config))
+               use("/random", new APIRandom(config))
+               use("/entity/:id", new APIEntity(config))
+               use("/code/:id", new APIEntityCode(config))
+               use("/uml/:id", new APIEntityUML(config))
+               use("/linearization/:id", new APIEntityLinearization(config))
+               use("/defs/:id", new APIEntityDefs(config))
+               use("/feedback/", new APIFeedbackRouter(config))
+               use("/inheritance/:id", new APIEntityInheritance(config))
+               use("/graph/", new APIGraphRouter(config))
+               use("/docdown/", new APIDocdown(config))
+               use("/metrics/", new APIMetricsRouter(config))
+               use("/user", new GithubUser)
        end
 end
 
@@ -61,7 +149,7 @@ end
 var toolcontext = new ToolContext
 var tpl = new Template
 tpl.add "Usage: nitweb [OPTION]... <file.nit>...\n"
-tpl.add "Run a webserver based on nitcorn that serve pages about model."
+tpl.add "Run a webserver based on nitcorn that serves pages about model."
 toolcontext.tooldescription = tpl.write_to_string
 
 # process options