From 45cd5914ffba8d18a0a2311e954a50a57e117345 Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Mon, 6 Jun 2016 09:00:49 -0400 Subject: [PATCH] nitweb: introduce API catalog route Signed-off-by: Alexandre Terrasa --- src/nitweb.nit | 20 ++++++- src/web/api_catalog.nit | 138 +++++++++++++++++++++++++++++++++++++++++++++++ src/web/web.nit | 1 + 3 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 src/web/api_catalog.nit diff --git a/src/nitweb.nit b/src/nitweb.nit index 452179f..7eba23d 100644 --- a/src/nitweb.nit +++ b/src/nitweb.nit @@ -43,13 +43,30 @@ private class NitwebPhase var model = mainmodule.model var modelbuilder = toolcontext.modelbuilder + # Build catalog + 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 + # Run the server var host = toolcontext.opt_host.value or else "localhost" var port = toolcontext.opt_port.value var app = new App - app.use("/api", new APIRouter(model, modelbuilder, mainmodule)) + app.use("/api", new APIRouter(model, modelbuilder, mainmodule, catalog)) app.use("/doc/:namespace", new DocAction(model, mainmodule, modelbuilder)) app.use("/*", new StaticHandler(toolcontext.share_dir / "nitweb", "index.html")) @@ -74,6 +91,7 @@ class APIRouter var catalog: Catalog 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)) diff --git a/src/web/api_catalog.nit b/src/web/api_catalog.nit new file mode 100644 index 0000000..72d207f --- /dev/null +++ b/src/web/api_catalog.nit @@ -0,0 +1,138 @@ +# This file is part of NIT ( http://www.nitlanguage.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. + +module api_catalog + +import web_base +import catalog + +# Group all api handlers in one router. +class APICatalogRouter + super Router + + # Model to pass to handlers. + var model: Model + + # Mainmodule to pass to handlers. + var mainmodule: MModule + + # Catalog to pass to handlers. + 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)) + end +end + +abstract class APICatalogHandler + super APIHandler + + var catalog: Catalog + + # List the 10 best packages from `cpt` + fun list_best(cpt: Counter[MPackage]): JsonArray do + var res = new JsonArray + var best = cpt.sort + for i in [1..10] do + if i > best.length then break + res.add best[best.length-i] + end + return res + end + + # List packages by group. + fun list_by(map: MultiHashMap[Object, MPackage]): JsonObject do + var res = new JsonObject + var keys = map.keys.to_a + alpha_comparator.sort(keys) + for k in keys do + var projs = map[k].to_a + alpha_comparator.sort(projs) + res[k.to_s.html_escape] = new JsonArray.from(projs) + end + return res + end +end + +class APICatalogStats + super APICatalogHandler + + redef fun get(req, res) do + var obj = new JsonObject + obj["packages"] = model.mpackages.length + obj["maintainers"] = catalog.maint2proj.length + obj["contributors"] = catalog.contrib2proj.length + obj["modules"] = catalog.mmodules.sum + obj["classes"] = catalog.mclasses.sum + obj["methods"] = catalog.mmethods.sum + obj["loc"] = catalog.loc.sum + res.json obj + end +end + +class APICatalogHighLighted + super APICatalogHandler + + redef fun get(req, res) do res.json list_best(catalog.score) +end + +class APICatalogMostRequired + super APICatalogHandler + + redef fun get(req, res) do + if catalog.deps.not_empty then + var reqs = new Counter[MPackage] + for p in model.mpackages do + reqs[p] = catalog.deps[p].smallers.length - 1 + end + res.json list_best(reqs) + return + end + res.json new JsonArray + end +end + +class APICatalogByTags + super APICatalogHandler + + redef fun get(req, res) do res.json list_by(catalog.tag2proj) +end + +class APICatalogContributors + super APICatalogHandler + + redef fun get(req, res) do + var obj = new JsonObject + obj["maintainers"] = new JsonArray.from(catalog.maint2proj.keys) + obj["contributors"] = new JsonArray.from(catalog.contrib2proj.keys) + res.json obj + end +end + +redef class Person + super Jsonable + + redef fun to_json do + var obj = new JsonObject + obj["name"] = name + obj["email"] = email + obj["page"] = page + obj["hash"] = (email or else "").md5.to_lower + return obj.to_json + end +end diff --git a/src/web/web.nit b/src/web/web.nit index c6a12f0..2a22001 100644 --- a/src/web/web.nit +++ b/src/web/web.nit @@ -17,3 +17,4 @@ module web import web_actions import model_api +import api_catalog -- 1.7.9.5