Merge: Nitsmell : Adding new code smells and print console updated
[nit.git] / src / web / api_catalog.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 module api_catalog
16
17 import web_base
18 import catalog
19
20 redef class NitwebConfig
21
22 # Catalog to pass to handlers.
23 var catalog: Catalog is noinit
24
25 # Build the catalog
26 #
27 # This method should be called at nitweb startup.
28 fun build_catalog do
29 var catalog = new Catalog(modelbuilder)
30 for mpackage in model.mpackages do
31 catalog.deps.add_node(mpackage)
32 for mgroup in mpackage.mgroups do
33 for mmodule in mgroup.mmodules do
34 for imported in mmodule.in_importation.direct_greaters do
35 var ip = imported.mpackage
36 if ip == null or ip == mpackage then continue
37 catalog.deps.add_edge(mpackage, ip)
38 end
39 end
40 end
41 catalog.git_info(mpackage)
42 catalog.package_page(mpackage)
43 end
44 self.catalog = catalog
45 end
46 end
47
48 redef class APIRouter
49 redef init do
50 super
51 use("/catalog/highlighted", new APICatalogHighLighted(config))
52 use("/catalog/required", new APICatalogMostRequired(config))
53 use("/catalog/bytags", new APICatalogByTags(config))
54 use("/catalog/contributors", new APICatalogContributors(config))
55 use("/catalog/stats", new APICatalogStats(config))
56 end
57 end
58
59 abstract class APICatalogHandler
60 super APIHandler
61
62 # List the 10 best packages from `cpt`
63 fun list_best(cpt: Counter[MPackage]): JsonArray do
64 var res = new JsonArray
65 var best = cpt.sort
66 for i in [1..10] do
67 if i > best.length then break
68 res.add best[best.length-i]
69 end
70 return res
71 end
72
73 # List packages by group.
74 fun list_by(map: MultiHashMap[Object, MPackage]): JsonObject do
75 var res = new JsonObject
76 var keys = map.keys.to_a
77 alpha_comparator.sort(keys)
78 for k in keys do
79 var projs = map[k].to_a
80 alpha_comparator.sort(projs)
81 res[k.to_s.html_escape] = new JsonArray.from(projs)
82 end
83 return res
84 end
85 end
86
87 class APICatalogStats
88 super APICatalogHandler
89
90 redef fun get(req, res) do
91 var obj = new JsonObject
92 obj["packages"] = config.model.mpackages.length
93 obj["maintainers"] = config.catalog.maint2proj.length
94 obj["contributors"] = config.catalog.contrib2proj.length
95 obj["modules"] = config.catalog.mmodules.sum
96 obj["classes"] = config.catalog.mclasses.sum
97 obj["methods"] = config.catalog.mmethods.sum
98 obj["loc"] = config.catalog.loc.sum
99 res.json obj
100 end
101 end
102
103 class APICatalogHighLighted
104 super APICatalogHandler
105
106 redef fun get(req, res) do res.json list_best(config.catalog.score)
107 end
108
109 class APICatalogMostRequired
110 super APICatalogHandler
111
112 redef fun get(req, res) do
113 if config.catalog.deps.not_empty then
114 var reqs = new Counter[MPackage]
115 for p in config.model.mpackages do
116 reqs[p] = config.catalog.deps[p].smallers.length - 1
117 end
118 res.json list_best(reqs)
119 return
120 end
121 res.json new JsonArray
122 end
123 end
124
125 class APICatalogByTags
126 super APICatalogHandler
127
128 redef fun get(req, res) do res.json list_by(config.catalog.tag2proj)
129 end
130
131 class APICatalogContributors
132 super APICatalogHandler
133
134 redef fun get(req, res) do
135 var obj = new JsonObject
136 obj["maintainers"] = new JsonArray.from(config.catalog.maint2proj.keys)
137 obj["contributors"] = new JsonArray.from(config.catalog.contrib2proj.keys)
138 res.json obj
139 end
140 end
141
142 redef class Person
143 super Serializable
144
145 redef fun core_serialize_to(v) do
146 v.serialize_attribute("name", name)
147 v.serialize_attribute("email", email)
148 v.serialize_attribute("page", page)
149 v.serialize_attribute("hash", (email or else "").md5.to_lower)
150 end
151 end