nitweb: use catalog_json
[nit.git] / src / web / api_catalog.nit
index 9bca8be..afad834 100644 (file)
@@ -14,8 +14,8 @@
 
 module api_catalog
 
-import web_base
-import catalog
+import api_model
+import catalog::catalog_json
 
 redef class NitwebConfig
 
@@ -35,11 +35,6 @@ redef class APIRouter
        redef init do
                super
                use("/catalog/packages/", new APICatalogPackages(config))
-
-               use("/catalog/highlighted", new APICatalogHighLighted(config))
-               use("/catalog/required", new APICatalogMostRequired(config))
-               use("/catalog/bytags", new APICatalogByTags(config))
-               use("/catalog/contributors", new APICatalogContributors(config))
                use("/catalog/stats", new APICatalogStats(config))
 
                use("/catalog/tags", new APICatalogTags(config))
@@ -58,30 +53,6 @@ abstract class APICatalogHandler
        #
        # Sorting is based on mpackage score.
        var mpackages_sorter = new CatalogScoreSorter(config.catalog) is lazy
-
-       # 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
 
 # Get all the packages from the catalog using pagination
@@ -100,45 +71,6 @@ class APICatalogPackages
        end
 end
 
-class APICatalogHighLighted
-       super APICatalogHandler
-
-       redef fun get(req, res) do res.json list_best(config.catalog.score)
-end
-
-class APICatalogMostRequired
-       super APICatalogHandler
-
-       redef fun get(req, res) do
-               if config.catalog.deps.not_empty then
-                       var reqs = new Counter[MPackage]
-                       for p in config.model.mpackages do
-                               reqs[p] = config.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(config.catalog.tag2proj)
-end
-
-class APICatalogContributors
-       super APICatalogHandler
-
-       redef fun get(req, res) do
-               var obj = new JsonObject
-               obj["maintainers"] = new JsonArray.from(config.catalog.maint2proj.keys)
-               obj["contributors"] = new JsonArray.from(config.catalog.contrib2proj.keys)
-               res.json obj
-       end
-end
-
 # Get the catalog statistics
 #
 # `GET /stats`: return the catalog statistics
@@ -274,6 +206,73 @@ class APICatalogContributing
        end
 end
 
+redef class APIEntity
+       redef fun get(req, res) do
+               var mentity = mentity_from_uri(req, res)
+               if mentity == null then return
+
+               # Special case for packages (catalog view)
+               if mentity isa MPackage then
+                       res.raw_json mentity.to_full_catalog_json(plain=true, config.mainmodule, config.catalog)
+               else
+                       res.raw_json mentity.to_full_json(config.mainmodule)
+               end
+       end
+end
+
+redef class APISearch
+       super APICatalogHandler
+
+       redef fun search(query, limit) do
+               var index = config.view.index
+
+               # lookup by name prefix
+               var matches = index.find_by_name_prefix(query).uniq.
+                       sort(lname_sorter, name_sorter, kind_sorter)
+               matches = matches.rerank.sort(vis_sorter, score_sorter)
+
+               # lookup by tags
+               var malus = matches.length
+               if config.catalog.tag2proj.has_key(query) then
+                       for mpackage in config.catalog.tag2proj[query] do
+                               matches.add new IndexMatch(mpackage, malus)
+                               malus += 1
+                       end
+                       matches = matches.uniq.rerank.sort(vis_sorter, score_sorter)
+               end
+
+               # lookup by full_name prefix
+               malus = matches.length
+               var full_matches = new IndexMatches
+               for match in index.find_by_full_name_prefix(query).
+                       sort(lfname_sorter, fname_sorter) do
+                       match.score += 1
+                       full_matches.add match
+               end
+               matches = matches.uniq
+
+               # lookup by similarity
+               malus = matches.length
+               var sim_matches = new IndexMatches
+               for match in index.find_by_similarity(query).sort(score_sorter, lname_sorter, name_sorter) do
+                       if match.score > query.length then break
+                       match.score += 1
+                       sim_matches.add match
+               end
+               matches.add_all sim_matches
+               matches = matches.uniq
+               return matches.rerank.sort(vis_sorter, score_sorter).mentities
+       end
+
+       private var score_sorter = new ScoreComparator
+       private var vis_sorter = new VisibilityComparator
+       private var name_sorter = new NameComparator
+       private var lname_sorter = new NameLengthComparator
+       private var fname_sorter = new FullNameComparator
+       private var lfname_sorter = new FullNameLengthComparator
+       private var kind_sorter = new MEntityComparator
+end
+
 redef class Catalog
 
        # Build the catalog from `mpackages`
@@ -302,80 +301,13 @@ redef class Catalog
        end
 end
 
-redef class MPackageMetadata
-       serialize
-
-       redef fun core_serialize_to(v) do
-               super
-               v.serialize_attribute("license", license)
-               v.serialize_attribute("maintainers", maintainers)
-               v.serialize_attribute("contributors", contributors)
-               v.serialize_attribute("tags", tags)
-               v.serialize_attribute("tryit", tryit)
-               v.serialize_attribute("apk", apk)
-               v.serialize_attribute("homepage", homepage)
-               v.serialize_attribute("browse", browse)
-               v.serialize_attribute("git", git)
-               v.serialize_attribute("issues", issues)
-               v.serialize_attribute("first_date", first_date)
-               v.serialize_attribute("last_date", last_date)
-       end
-end
-
-# Catalog statistics
-redef class CatalogStats
-       serialize
-
-       redef fun core_serialize_to(v) do
-               super
-               v.serialize_attribute("packages", packages)
-               v.serialize_attribute("maintainers", maintainers)
-               v.serialize_attribute("contributors", contributors)
-               v.serialize_attribute("tags", tags)
-               v.serialize_attribute("modules", modules)
-               v.serialize_attribute("classes", classes)
-               v.serialize_attribute("methods", methods)
-               v.serialize_attribute("loc", loc)
-       end
-end
-
-# MPackage statistics for the catalog
-redef class MPackageStats
-       serialize
-
-       redef fun core_serialize_to(v) do
-               super
-               v.serialize_attribute("mmodules", mmodules)
-               v.serialize_attribute("mclasses", mclasses)
-               v.serialize_attribute("mmethods", mmethods)
-               v.serialize_attribute("loc", loc)
-               v.serialize_attribute("errors", errors)
-               v.serialize_attribute("warnings", warnings)
-               v.serialize_attribute("warnings_per_kloc", warnings_per_kloc)
-               v.serialize_attribute("documentation_score", documentation_score)
-               v.serialize_attribute("commits", commits)
-               v.serialize_attribute("score", score)
-       end
-end
-
-redef class Person
-       serialize
-
-       redef fun core_serialize_to(v) do
-               super
-               v.serialize_attribute("name", name)
-               v.serialize_attribute("email", email)
-               v.serialize_attribute("gravatar", gravatar)
-       end
-end
-
 redef class MPackage
        # Serialize the full catalog version of `self` to JSON
        #
        # See: `FullCatalogSerializer`
-       fun to_full_catalog_json(catalog: Catalog, plain, pretty: nullable Bool): String do
+       fun to_full_catalog_json(mainmodule: MModule, catalog: Catalog, plain, pretty: nullable Bool): String do
                var stream = new StringWriter
-               var serializer = new FullCatalogSerializer(stream, catalog)
+               var serializer = new FullCatalogSerializer(stream, mainmodule, catalog)
                serializer.plain_json = plain or else false
                serializer.pretty_json = pretty or else false
                serializer.serialize self