From f7555ada4db3589fd581299fe7a977a23c5ec271 Mon Sep 17 00:00:00 2001 From: Jean Privat Date: Sun, 17 Apr 2016 20:53:14 -0400 Subject: [PATCH] nitcatalog: add a new class Person Signed-off-by: Jean Privat --- src/catalog.nit | 156 ++++++++++++++++++++++++++++++++++++++++++++++------ src/nitcatalog.nit | 66 +++------------------- 2 files changed, 145 insertions(+), 77 deletions(-) diff --git a/src/catalog.nit b/src/catalog.nit index 1d6bb2a..3ebc01e 100644 --- a/src/catalog.nit +++ b/src/catalog.nit @@ -30,7 +30,7 @@ # * [ ] gather git information from the repository # * [ ] gather package information from github # * [ ] gather people information from github -# * [ ] reify people +# * [X] reify people # * [X] separate information gathering from rendering # * [ ] move up information gathering in (existing or new) service modules # * [X] add command line options @@ -65,10 +65,10 @@ redef class MPackage var tags = new Array[String] # The list of maintainers - var maintainers = new Array[String] + var maintainers = new Array[Person] # The list of contributors - var contributors = new Array[String] + var contributors = new Array[Person] # The date of the most recent commit var last_date: nullable String = null @@ -82,6 +82,119 @@ redef class Int fun score: Float do return (self+1).to_f.log end +# A contributor/author/etc. +# +# It comes from git or the metadata +# +# TODO get more things from github by using the email as a key +# "https://api.github.com/search/users?q={email}+in:email" +class Person + # The name. Eg "John Doe" + var name: String is writable + + # The email, Eg "john.doe@example.com" + var email: nullable String is writable + + # Some homepage. Eg "http://example.com/~jdoe" + var page: nullable String is writable + + # Return a full-featured link to a person + fun to_html: String + do + var res = "" + var e = name.html_escape + var page = self.page + if page != null then + res += "" + end + var email = self.email + if email != null then + var md5 = email.md5.to_lower + res += " " + end + res += e + if page != null then res += "" + return res + end + + # The standard representation of a person. + # + # ~~~ + # var jd = new Person("John Doe", "john.doe@example.com", "http://example.com/~jdoe") + # assert jd.to_s == "John Doe (http://example.com/~jdoe)" + # ~~~ + # + # It can be used as the input of `parse`. + # + # ~~~ + # var jd2 = new Person.parse(jd.to_s) + # assert jd2.to_s == jd.to_s + # ~~~ + redef fun to_s + do + var res = name + var email = self.email + if email != null then res += " <{email}>" + var page = self.page + if page != null then res += " ({page})" + return res + end + + # Crete a new person from its standard textual representation. + # + # ~~~ + # var jd = new Person.parse("John Doe (http://example.com/~jdoe)") + # assert jd.name == "John Doe" + # assert jd.email == "john.doe@example.com" + # assert jd.page == "http://example.com/~jdoe" + # ~~~ + # + # Emails and page are optional. + # + # ~~~ + # var jd2 = new Person.parse("John Doe") + # assert jd2.name == "John Doe" + # assert jd2.email == null + # assert jd2.page == null + # ~~~ + init parse(person: String) + do + var name = person + var email = null + var page = null + # Regular expressions are broken, need to investigate. + # So split manually. + # + #var re = "([^<(]*?)(<([^>]*?)>)?(\\((.*)\\))?".to_re + #var m = (person+" ").search(re) + #print "{person}: `{m or else "?"}` `{m[1] or else "?"}` `{m[3] or else "?"}` `{m[5] or else "?"}`" + do + var sp1 = person.split_once_on("<") + if sp1.length < 2 then + break + end + var sp2 = sp1.last.split_once_on(">") + if sp2.length < 2 then + break + end + name = sp1.first.trim + email = sp2.first.trim + var sp3 = sp2.last.split_once_on("(") + if sp3.length < 2 then + break + end + var sp4 = sp3.last.split_once_on(")") + if sp4.length < 2 then + break + end + page = sp4.first.trim + end + + init(name, email, page) + end +end + + # The main class of the calatog generator that has the knowledge class Catalog @@ -96,10 +209,10 @@ class Catalog var cat2proj = new MultiHashMap[String, MPackage] # Packages by maintainer - var maint2proj = new MultiHashMap[String, MPackage] + var maint2proj = new MultiHashMap[Person, MPackage] # Packages by contributors - var contrib2proj = new MultiHashMap[String, MPackage] + var contrib2proj = new MultiHashMap[Person, MPackage] # Dependency between packages var deps = new POSet[MPackage] @@ -124,11 +237,23 @@ class Catalog # The score is loosely computed using other metrics var score = new Counter[MPackage] + # List of known people + var persons = new HashMap[String, Person] + # Scan, register and add a contributor to a package - fun register_contrib(person: String, mpackage: MPackage) + fun register_contrib(person: String, mpackage: MPackage): Person do - var projs = contrib2proj[person] - if not projs.has(mpackage) then projs.add mpackage + var p = persons.get_or_null(person) + if p == null then + p = new Person.parse(person) + persons[person] = p + end + var projs = contrib2proj[p] + if not projs.has(mpackage) then + projs.add mpackage + mpackage.contributors.add p + end + return p end # Compute information for a package @@ -159,9 +284,9 @@ class Catalog var maintainer = mpackage.metadata("package.maintainer") if maintainer != null then score += 5.0 - register_contrib(maintainer, mpackage) - mpackage.maintainers.add maintainer - var projs = maint2proj[maintainer] + var person = register_contrib(maintainer, mpackage) + mpackage.maintainers.add person + var projs = maint2proj[person] if not projs.has(mpackage) then projs.add mpackage end var license = mpackage.metadata("package.license") @@ -204,12 +329,7 @@ class Catalog var more_contributors = mpackage.metadata("package.more_contributors") if more_contributors != null then for c in more_contributors.split(",") do - contributors.add c.trim - end - end - if not contributors.is_empty then - for c in contributors do - register_contrib(c, mpackage) + register_contrib(c.trim, mpackage) end end score += contributors.length.to_f @@ -282,7 +402,7 @@ class Catalog contributors.inc(s.last) end for c in contributors.sort.reverse_iterator do - mpackage.contributors.add c + register_contrib(c, mpackage) end end diff --git a/src/nitcatalog.nit b/src/nitcatalog.nit index d2aff2d..29477c1 100644 --- a/src/nitcatalog.nit +++ b/src/nitcatalog.nit @@ -138,57 +138,6 @@ redef class Catalog return new CatalogPage(self, rootpath) end - # Add a contributor to a package - fun add_contrib(person: String, mpackage: MPackage, res: Template) - do - var name = person - var email = null - var page = null - - # Regular expressions are broken, need to investigate. - # So split manually. - # - #var re = "([^<(]*?)(<([^>]*?)>)?(\\((.*)\\))?".to_re - #var m = (person+" ").search(re) - #print "{person}: `{m or else "?"}` `{m[1] or else "?"}` `{m[3] or else "?"}` `{m[5] or else "?"}`" - do - var sp1 = person.split_once_on("<") - if sp1.length < 2 then - break - end - var sp2 = sp1.last.split_once_on(">") - if sp2.length < 2 then - break - end - name = sp1.first.trim - email = sp2.first.trim - var sp3 = sp2.last.split_once_on("(") - if sp3.length < 2 then - break - end - var sp4 = sp3.last.split_once_on(")") - if sp4.length < 2 then - break - end - page = sp4.first.trim - end - - var e = name.html_escape - res.add "
  • " - if page != null then - res.add "" - end - if email != null then - # TODO get more things from github by using the email as a key - # "https://api.github.com/search/users?q={email}+in:email" - var md5 = email.md5.to_lower - res.add " " - end - res.add "{e}" - if page != null then res.add "" - res.add "
  • " - end - # Recursively generate a level in the file tree of the *content* section private fun gen_content_level(ot: OrderedTree[MConcern], os: Array[Object], res: Template) do @@ -268,9 +217,8 @@ redef class Catalog var e = homepage.html_escape res.add "
  • {e}
  • \n" end - var maintainer = mpackage.metadata("package.maintainer") - if maintainer != null then - add_contrib(maintainer, mpackage, res) + for maintainer in mpackage.maintainers do + res.add "
  • {maintainer.to_html}
  • " end var license = mpackage.metadata("package.license") if license != null then @@ -360,7 +308,7 @@ redef class Catalog if not contributors.is_empty then res.add "

    Contributors

    \n
      " for c in contributors do - add_contrib(c, mpackage, res) + res.add "
    • {c.to_html}
    • " end res.add "
    " end @@ -401,18 +349,18 @@ redef class Catalog # # The list of keys is generated first to allow fast access to the correct `

    `. # `id_prefix` is used to give an id to the `

    ` element. - fun list_by(map: MultiHashMap[String, MPackage], id_prefix: String): Template + fun list_by(map: MultiHashMap[Object, MPackage], id_prefix: String): Template do var res = new Template var keys = map.keys.to_a alpha_comparator.sort(keys) - var list = [for x in keys do "{x.html_escape}"] + var list = [for x in keys do "{x.to_s.html_escape}"] res.add_list(list, ", ", " and ") for k in keys do var projs = map[k].to_a alpha_comparator.sort(projs) - var e = k.html_escape + var e = k.to_s.html_escape res.add "

    {e} ({projs.length})

    \n
      \n" for p in projs do res.add "
    • " @@ -470,7 +418,7 @@ redef class Catalog res.add "" res.add "{p.name}" var maint = "?" - if p.maintainers.not_empty then maint = p.maintainers.first + if p.maintainers.not_empty then maint = p.maintainers.first.name.html_escape res.add "{maint}" res.add "{p.contributors.length}" if deps.not_empty then -- 1.7.9.5