From 744b322b8ceb4277568dfadfab3151f743c2e267 Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Mon, 8 Aug 2016 21:49:55 -0400 Subject: [PATCH] nitweb: use config file Signed-off-by: Alexandre Terrasa --- src/nitweb.nit | 76 +++++++++++++++++++++++++--------------------- src/web/api_catalog.nit | 14 ++++----- src/web/api_docdown.nit | 5 +-- src/web/api_feedback.nit | 38 +++++++++++++++++------ src/web/api_graph.nit | 2 +- src/web/api_metrics.nit | 12 +++----- src/web/api_model.nit | 9 ++---- src/web/web_base.nit | 29 ++++++++++++------ 8 files changed, 105 insertions(+), 80 deletions(-) diff --git a/src/nitweb.nit b/src/nitweb.nit index 3f3b7f5..9376172 100644 --- a/src/nitweb.nit +++ b/src/nitweb.nit @@ -15,23 +15,27 @@ # Runs a webserver based on nitcorn that render things from model. module nitweb +import popcorn::pop_config import frontend import web 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 @@ -39,6 +43,22 @@ end 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) @@ -63,25 +83,17 @@ private class NitwebPhase do var model = mainmodule.model var modelbuilder = toolcontext.modelbuilder + var config = build_config(toolcontext, mainmodule) var catalog = build_catalog(model, modelbuilder) - # Prepare mongo connection - var mongo = new MongoClient("mongodb://localhost:27017/") - var db = mongo.database("nitweb") - var collection = db.collection("stars") - - # Run the server - var host = toolcontext.opt_host.value or else "localhost" - var port = toolcontext.opt_port.value - var app = new App app.use_before("/*", new RequestClock) - app.use("/api", new NitwebAPIRouter(model, mainmodule, modelbuilder, catalog, stars)) + app.use("/api", new NitwebAPIRouter(config, catalog)) 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 @@ -89,30 +101,24 @@ end class NitwebAPIRouter super APIRouter - # ModelBuilder to pass to handlers. - var modelbuilder: ModelBuilder - # Catalog to pass to handlers. var catalog: Catalog - # Mongo collection used to store ratings. - var collection: MongoCollection - init do - use("/catalog", new APICatalogRouter(model, mainmodule, catalog)) - use("/list", new APIList(model, mainmodule)) - use("/search", new APISearch(model, mainmodule)) - use("/random", new APIRandom(model, mainmodule)) - use("/entity/:id", new APIEntity(model, mainmodule)) - use("/code/:id", new APIEntityCode(model, mainmodule, modelbuilder)) - use("/uml/:id", new APIEntityUML(model, mainmodule)) - use("/linearization/:id", new APIEntityLinearization(model, mainmodule)) - use("/defs/:id", new APIEntityDefs(model, mainmodule)) - use("/feedback/", new APIFeedbackRouter(model, mainmodule, collection)) - use("/inheritance/:id", new APIEntityInheritance(model, mainmodule)) - use("/graph/", new APIGraphRouter(model, mainmodule)) - use("/docdown/", new APIDocdown(model, mainmodule, modelbuilder)) - use("/metrics/", new APIMetricsRouter(model, mainmodule)) + 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)) end end diff --git a/src/web/api_catalog.nit b/src/web/api_catalog.nit index 2535898..f0c70c6 100644 --- a/src/web/api_catalog.nit +++ b/src/web/api_catalog.nit @@ -25,11 +25,11 @@ class APICatalogRouter var catalog: Catalog init do - use("/highlighted", new APICatalogHighLighted(model, mainmodule, catalog)) - use("/required", new APICatalogMostRequired(model, mainmodule, catalog)) - use("/bytags", new APICatalogByTags(model, mainmodule, catalog)) - use("/contributors", new APICatalogContributors(model, mainmodule, catalog)) - use("/stats", new APICatalogStats(model, mainmodule, catalog)) + use("/highlighted", new APICatalogHighLighted(config, catalog)) + use("/required", new APICatalogMostRequired(config, catalog)) + use("/bytags", new APICatalogByTags(config, catalog)) + use("/contributors", new APICatalogContributors(config, catalog)) + use("/stats", new APICatalogStats(config, catalog)) end end @@ -68,7 +68,7 @@ class APICatalogStats redef fun get(req, res) do var obj = new JsonObject - obj["packages"] = model.mpackages.length + obj["packages"] = config.model.mpackages.length obj["maintainers"] = catalog.maint2proj.length obj["contributors"] = catalog.contrib2proj.length obj["modules"] = catalog.mmodules.sum @@ -91,7 +91,7 @@ class APICatalogMostRequired redef fun get(req, res) do if catalog.deps.not_empty then var reqs = new Counter[MPackage] - for p in model.mpackages do + for p in config.model.mpackages do reqs[p] = catalog.deps[p].smallers.length - 1 end res.json list_best(reqs) diff --git a/src/web/api_docdown.nit b/src/web/api_docdown.nit index 3510b64..bf4c80f 100644 --- a/src/web/api_docdown.nit +++ b/src/web/api_docdown.nit @@ -24,13 +24,10 @@ import doc_commands class APIDocdown super APIHandler - # Modelbuilder used by the commands - var modelbuilder: ModelBuilder - # Specific Markdown processor to use within Nitweb var md_processor: MarkdownProcessor is lazy do var proc = new MarkdownProcessor - proc.emitter.decorator = new NitwebDecorator(view, modelbuilder) + proc.emitter.decorator = new NitwebDecorator(view, config.modelbuilder) return proc end diff --git a/src/web/api_feedback.nit b/src/web/api_feedback.nit index e994bf6..76e9d67 100644 --- a/src/web/api_feedback.nit +++ b/src/web/api_feedback.nit @@ -18,15 +18,38 @@ module api_feedback import web_base import mongodb +redef class NitwebConfig + + # MongoDB uri used for data persistence. + # + # * key: `mongo.uri` + # * default: `mongodb://localhost:27017/` + var mongo_uri: String is lazy do + return value_or_default("mongo.uri", "mongodb://localhost:27017/") + end + + # MongoDB DB used for data persistence. + # + # * key: `mongo.db` + # * default: `nitweb` + var mongo_db: String is lazy do return value_or_default("mongo.db", "nitweb") + + # Mongo instance + var mongo: MongoClient is lazy do return new MongoClient(mongo_uri) + + # Database instance + var db: MongoDb is lazy do return mongo.database(mongo_db) + + # MongoDB collection used to store stars. + var stars: MongoCollection is lazy do return db.collection("stars") +end + # Group all api handlers in one router class APIFeedbackRouter super APIRouter - # Mongo collection used to store ratings - var collection: MongoCollection - init do - use("/stars/:id", new APIStars(model, mainmodule, collection)) + use("/stars/:id", new APIStars(config)) end end @@ -34,9 +57,6 @@ end class APIStars super APIHandler - # Collection used to store ratings - var collection: MongoCollection - redef fun get(req, res) do var mentity = mentity_from_uri(req, res) if mentity == null then @@ -65,7 +85,7 @@ class APIStars end var val = new MEntityRating(mentity.full_name, rating, get_time) - collection.insert(val.json) + config.stars.insert(val.json) res.json mentity_ratings(mentity) end @@ -76,7 +96,7 @@ class APIStars var req = new JsonObject req["mentity"] = mentity.full_name - var rs = collection.find_all(req) + var rs = config.stars.find_all(req) for r in rs do ratings.ratings.add new MEntityRating.from_json(r) return ratings end diff --git a/src/web/api_graph.nit b/src/web/api_graph.nit index 06e6bf2..d58031d 100644 --- a/src/web/api_graph.nit +++ b/src/web/api_graph.nit @@ -24,7 +24,7 @@ class APIGraphRouter super APIRouter init do - use("/inheritance/:id", new APIInheritanceGraph(model, mainmodule)) + use("/inheritance/:id", new APIInheritanceGraph(config)) end end diff --git a/src/web/api_metrics.nit b/src/web/api_metrics.nit index 30a53f1..8d64c04 100644 --- a/src/web/api_metrics.nit +++ b/src/web/api_metrics.nit @@ -19,16 +19,10 @@ import metrics # Group all api handlers in one router. class APIMetricsRouter - super Router - - # Model to pass to handlers. - var model: Model - - # Mainmodule to pass to handlers. - var mainmodule: MModule + super APIRouter init do - use("/structural/:id", new APIStructuralMetrics(model, mainmodule)) + use("/structural/:id", new APIStructuralMetrics(config)) end end @@ -36,6 +30,7 @@ class APIStructuralMetrics super APIHandler private fun mclasses_metrics: MetricSet do + var mainmodule = config.mainmodule var metrics = new MetricSet metrics.register(new CNOA(mainmodule, view)) metrics.register(new CNOP(mainmodule, view)) @@ -58,6 +53,7 @@ class APIStructuralMetrics end private fun mmodules_metrics: MetricSet do + var mainmodule = config.mainmodule var metrics = new MetricSet metrics.register(new MNOA(mainmodule, view)) metrics.register(new MNOP(mainmodule, view)) diff --git a/src/web/api_model.nit b/src/web/api_model.nit index f8c6eeb..63fd636 100644 --- a/src/web/api_model.nit +++ b/src/web/api_model.nit @@ -148,7 +148,7 @@ class APIEntityLinearization res.error 404 return end - var lin = mentity.collect_linearization(mainmodule) + var lin = mentity.collect_linearization(config.mainmodule) if lin == null then res.error 404 return @@ -206,7 +206,7 @@ class APIEntityUML var dot if mentity isa MClassDef then mentity = mentity.mclass if mentity isa MClass then - var uml = new UMLModel(view, mainmodule) + var uml = new UMLModel(view, config.mainmodule) dot = uml.generate_class_uml.write_to_string else if mentity isa MModule then var uml = new UMLModel(view, mentity) @@ -225,9 +225,6 @@ end class APIEntityCode super APIHandler - # Modelbuilder used to access sources. - var modelbuilder: ModelBuilder - redef fun get(req, res) do var mentity = mentity_from_uri(req, res) if mentity == null then return @@ -241,7 +238,7 @@ class APIEntityCode # Highlight `mentity` source code. private fun render_source(mentity: MEntity): nullable HTMLTag do - var node = modelbuilder.mentity2node(mentity) + var node = config.modelbuilder.mentity2node(mentity) if node == null then return null var hl = new HighlightVisitor hl.enter_visit node diff --git a/src/web/web_base.nit b/src/web/web_base.nit index f48da04..c535936 100644 --- a/src/web/web_base.nit +++ b/src/web/web_base.nit @@ -19,10 +19,11 @@ import model::model_views import model::model_json import doc_down import popcorn +import popcorn::pop_config -# Specific nitcorn Action that uses a Model -class ModelHandler - super Handler +# Nitweb config file. +class NitwebConfig + super AppConfig # Model to use. var model: Model @@ -30,6 +31,17 @@ class ModelHandler # MModule used to flatten model. var mainmodule: MModule + # Modelbuilder used to access sources. + var modelbuilder: ModelBuilder +end + +# Specific nitcorn Action that uses a Model +class ModelHandler + super Handler + + # App config. + var config: NitwebConfig + # Find the MEntity ` with `full_name`. fun find_mentity(model: ModelView, full_name: nullable String): nullable MEntity do if full_name == null then return null @@ -38,7 +50,7 @@ class ModelHandler # Init the model view from the `req` uri parameters. fun init_model_view(req: HttpRequest): ModelView do - var view = new ModelView(model) + var view = new ModelView(config.model) var show_private = req.bool_arg("private") or else false if not show_private then view.min_visibility = protected_visibility @@ -59,7 +71,7 @@ abstract class APIHandler # # So we can cache the model view. var view: ModelView is lazy do - var view = new ModelView(model) + var view = new ModelView(config.model) view.min_visibility = private_visibility view.include_fictive = true view.include_empty_doc = true @@ -91,11 +103,8 @@ end class APIRouter super Router - # Model to use. - var model: Model - - # MModule used to flatten model. - var mainmodule: MModule + # App config. + var config: NitwebConfig end redef class MEntity -- 1.7.9.5