source file: /home/buildslave/tahoe/edgy/build/src/allmydata/scripts/tahoe_ls.py
file stats: 127 lines, 109 executed: 85.8% covered
coverage versus previous test: 0 lines added, 0 lines removed
    1. 
    2. import urllib, time
    3. import simplejson
    4. from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path
    5. from allmydata.scripts.common_http import do_http
    6. 
    7. def list(options):
    8.     nodeurl = options['node-url']
    9.     aliases = options.aliases
   10.     where = options.where
   11.     stdout = options.stdout
   12.     stderr = options.stderr
   13. 
   14.     if not nodeurl.endswith("/"):
   15.         nodeurl += "/"
   16.     if where.endswith("/"):
   17.         where = where[:-1]
   18.     rootcap, path = get_alias(aliases, where, DEFAULT_ALIAS)
   19.     url = nodeurl + "uri/%s" % urllib.quote(rootcap)
   20.     if path:
   21.         # move where.endswith check here?
   22.         url += "/" + escape_path(path)
   23.     assert not url.endswith("/")
   24.     url += "?t=json"
   25.     resp = do_http("GET", url)
   26.     if resp.status == 404:
   27.         print >>stderr, "No such file or directory"
   28.         return 2
   29.     if resp.status != 200:
   30.         print >>stderr, "Error during GET: %s %s %s" % (resp.status,
   31.                                                         resp.reason,
   32.                                                         resp.read())
   33.         if resp.status == 0:
   34.             return 3
   35.         else:
   36.             return resp.status
   37. 
   38.     data = resp.read()
   39. 
   40.     if options['json']:
   41.         print >>stdout, data
   42.         return
   43. 
   44.     try:
   45.         parsed = simplejson.loads(data)
   46.     except Exception, le:
   47.         le.args = tuple(le.args + (data,))
   48.         raise
   49.     nodetype, d = parsed
   50.     children = {}
   51.     if nodetype == "dirnode":
   52.         children = d['children']
   53.     elif nodetype == "filenode":
   54.         childname = path.split("/")[-1]
   55.         children = {childname: d}
   56.     childnames = sorted(children.keys())
   57.     now = time.time()
   58. 
   59.     # we build up a series of rows, then we loop through them to compute a
   60.     # maxwidth so we can format them tightly. Size, filename, and URI are the
   61.     # variable-width ones.
   62.     rows = []
   63. 
   64.     for name in childnames:
   65.         name = unicode(name)
   66.         child = children[name]
   67.         childtype = child[0]
   68. 
   69.         # See webapi.txt for a discussion of the meanings of unix local
   70.         # filesystem mtime and ctime, Tahoe mtime and ctime, and Tahoe
   71.         # linkmotime and linkcrtime.
   72.         ctime = child[1].get("metadata", {}).get('tahoe', {}).get("linkcrtime")
   73.         if not ctime:
   74.             ctime = child[1]["metadata"].get("ctime")
   75. 
   76.         mtime = child[1].get("metadata", {}).get('tahoe', {}).get("linkmotime")
   77.         if not mtime:
   78.             mtime = child[1]["metadata"].get("mtime")
   79.         rw_uri = child[1].get("rw_uri")
   80.         ro_uri = child[1].get("ro_uri")
   81.         if ctime:
   82.             # match for formatting that GNU 'ls' does
   83.             if (now - ctime) > 6*30*24*60*60:
   84.                 # old files
   85.                 fmt = "%b %d  %Y"
   86.             else:
   87.                 fmt = "%b %d %H:%M"
   88.             ctime_s = time.strftime(fmt, time.localtime(ctime))
   89.         else:
   90.             ctime_s = "-"
   91.         if childtype == "dirnode":
   92.             t0 = "d"
   93.             size = "-"
   94.             classify = "/"
   95.         elif childtype == "filenode":
   96.             t0 = "-"
   97.             size = str(child[1]['size'])
   98.             classify = ""
   99.             if rw_uri:
  100.                 classify = "*"
  101.         else:
  102.             t0 = "?"
  103.             size = "?"
  104.             classify = "?"
  105.         t1 = "-"
  106.         if ro_uri:
  107.             t1 = "r"
  108.         t2 = "-"
  109.         if rw_uri:
  110.             t2 = "w"
  111.         t3 = "-"
  112.         if childtype == "dirnode":
  113.             t3 = "x"
  114. 
  115.         uri = rw_uri or ro_uri
  116. 
  117.         line = []
  118.         if options["long"]:
  119.             line.append(t0+t1+t2+t3)
  120.             line.append(size)
  121.             line.append(ctime_s)
  122.         if not options["classify"]:
  123.             classify = ""
  124.         line.append(name + classify)
  125.         if options["uri"]:
  126.             line.append(uri)
  127.         if options["readonly-uri"]:
  128.             line.append(ro_uri or "-")
  129. 
  130.         rows.append(line)
  131. 
  132.     max_widths = []
  133.     left_justifys = []
  134.     for row in rows:
  135.         for i,cell in enumerate(row):
  136.             while len(max_widths) <= i:
  137.                 max_widths.append(0)
  138.             while len(left_justifys) <= i:
  139.                 left_justifys.append(False)
  140.             max_widths[i] = max(max_widths[i], len(cell))
  141.             if cell.startswith("URI"):
  142.                 left_justifys[i] = True
  143.     if len(left_justifys) == 1:
  144.         left_justifys[0] = True
  145.     fmt_pieces = []
  146.     for i in range(len(max_widths)):
  147.         piece = "%"
  148.         if left_justifys[i]:
  149.             piece += "-"
  150.         piece += str(max_widths[i])
  151.         piece += "s"
  152.         fmt_pieces.append(piece)
  153.     fmt = " ".join(fmt_pieces)
  154.     for row in rows:
  155.         print >>stdout, (fmt % tuple(row)).rstrip()
  156. 
  157.     return 0
  158. 
  159. # error cases that need improvement:
  160. #  list-one-file: tahoe ls my:docs/Makefile