I wanted to get an overview of the nimble packages but there isn't a browse 
function, so I wrote the nim program below. To use it you need to download 
`packages.json` from [nimble.packages](https://github.com/nim-lang/packages/). 
    
    
    {.experimental: "codeReordering".}
    
    # TODO download the JSON file if mtime is older than today
    
    import algorithm
    import json
    import os
    import sequtils
    import strformat
    import strutils except escape
    import sugar
    import unicode
    import xmltree
    
    const Outfile = "nimble-packages.html"
    
    type
      Entry = object
        name: string
        url: string
        tags: seq[string]
        description: string
        license: string
        web: string
    
    main()
    
    proc main() =
      let filename = getFilename() # May not return
      let entries = entryItems(filename)
      writeHtmlTable(entries)
    
    proc getFilename(): string =
      let args = commandLineParams()
      if len(args) == 0 or args[0] == "-h" or args[0] == "--help":
        echo("usage: ", lastPathPart(getAppFilename()),
             " /path/to/nimble.packages.json")
        quit()
      args[0]
    
    proc entryItems(filename: string): seq[Entry] =
      for item in parseJson(readFile(filename)):
        var entry: Entry
        try:
          entry = to(item, Entry)
        except KeyError:
          for tag in ["name", "url", "description", "license", "web"]:
            try:
              let node = item[tag]
              let text = node.getStr()
              case tag
              of "name": entry.name = text
              of "url": entry.url = text
              of "description": entry.description = text
              of "license": entry.license = text
              of "web": entry.web = text
            except KeyError:
              discard # ignore missing for now
          try:
            let node = item["tags"]
            if node.kind == JArray:
              var tags = newSeq[string]()
              for element in node.getElems():
                tags.add(element.getStr())
              entry.tags = tags
          except KeyError:
            discard # no tags
        if entry.name == "":
          continue
        entry.tags = sorted(entry.tags.mapIt(it.toLower()))
        result.add(entry)
        if entry.url == "":
          entry.url = entry.web
      result.sort((a, b) => cmpIgnoreCase(a.name, b.name))
    
    proc writeHtmlTable(entries: seq[Entry]) =
      var file = open(Outfile, fmWrite)
      defer: close(file)
      file.write("<table>\n")
      file.write("<tr><th>Name/Link</th><th>Description</th><th>Tags</th>" &
                 "<th>License</th></tr>\n")
      for entry in entries:
        let name = &"<a href=\"{entry.url}\">{escape(entry.name)}</a>"
        let description = escape(entry.description)
        let tags = escape(join(entry.tags, ", "))
        let license = escape(entry.license)
        file.write(&"<tr><td>{name}</td><td>{description}</td>" &
                   &"<td>{tags}</td><td>{license}</td></tr>\n")
      file.write("</table>\n")
      file.write(&"<p>{len(entries)} packages.</p>\n")
    
    
    Run

Reply via email to