W3C home > Mailing lists > Public > www-archive@w3.org > October 2007

Re: URI Templates - optional variables? (explain.cgi)

From: Dan Connolly <connolly@w3.org>
Date: Wed, 17 Oct 2007 23:46:21 -0500
To: Joe Gregorio <joe@bitworking.org>
Cc: www-archive <www-archive@w3.org>
Message-Id: <1192682781.25511.233.camel@pav>
On Wed, 2007-10-17 at 21:17 -0400, Joe Gregorio wrote:
> On 10/17/07, Dan Connolly <connolly@w3.org> wrote:
> > spiffy.
> >
> > I'd like to look at the source. I looked around and couldn't
> > find it. Is it world-readable?
> 
> My bad, I didn't check it into subversion. It's now been
> added to the uri-templates project.

OK, found it.
http://uri-templates.googlecode.com/svn/trunk/explain.cgi

>  It's about 80 lines
> of pretty sloppy Python code, so you've been warned :)

Yeah... looks like perl code. ;-)

OK... as an exercise in understanding the code, I
made the main body into a function, factored
out 3 parts, and added doctests. Enjoy.

While I was at it, I think I fixed a bug: in
the case of "Not a valid URI Template", I think
your code gives an HTTP 200 and then prints
an HTTP 400 status message in the body.

You might add a clue about how to satisfy 'import tpg'
in template_parser.py; tpg isn't in apt nor the CheeseShop,
so I had to hunt for it a bit.
http://christophe.delord.free.fr/tpg/index.html

I made an hg clone of the SVN project with hgimportsvn first,
just for fun our out of habit or whatever...

http://homer.w3.org/~connolly/projects/uri-templates/
6:3609c0d2de5f 2007-10-17 factored cgi handler into 3 parts with
doctests
5:dfb20fe77f99 2007-10-17 move CGI routine to a function; add --test
command-line option


-- 
Dan Connolly, W3C http://www.w3.org/People/Connolly/
gpg D3C2 887B 0F92 6005 C541  0875 0F91 96DE 6E52 C29E

# HG changeset patch
# User Dan Connolly http://www.w3.org/People/Connolly/
# Date 1192679565 18000
# Branch trunk
# Node ID dfb20fe77f991a902b6efbb20810ce18c22ed318
# Parent  4d68f2e5c387bb1bfa380f5a35e585f456856d05
move CGI routine to a function; add --test command-line option

diff -r 4d68f2e5c387 -r dfb20fe77f99 explain.cgi
--- a/explain.cgi	Wed Oct 17 20:17:40 2007 -0500
+++ b/explain.cgi	Wed Oct 17 22:52:45 2007 -0500
@@ -33,51 +33,60 @@ def explain(expansion, line, parsed_exp)
 
      
 
-form = cgi.FieldStorage()
-if not form.has_key("t"):
-  error("No URI Template was provided")
-else:
-  template = form["t"].value
+def handle():
+  form = cgi.FieldStorage()
+  if not form.has_key("t"):
+    error("No URI Template was provided")
+  else:
+    template = form["t"].value
 
-  print "Status: 200"
-  print "Content-Type: text/plain"
-  print ""
-  print template
-  parts = re.split("(\{[^\}]*\})", template)
-  try:
-    parsed = URITemplate(template)
-  except:
-    error("Not a valid URI Template")
-  parser = Parser()
-  expansions = []
-  length = 0
-  line = [] 
-  for p in parts:
-    if len(p) and p[0] == '{':
-      expansions.append((p, length, length+len(p), length+len(p)/2))
-      line.append("\\")
-      line.append("_" * (len(p)-2))
-      line.append("/")
-    else:
-      line.append(" " * len(p))
-    length += len(p)
-  print "".join(line)
-  line = [" "] * len(template)
-  for (s, begin, end, middle) in expansions:
-    line[middle] = "|"
-  print "".join(line)
-  print "".join(line)
-  expansions.reverse()
-  for (s, begin, end, middle) in expansions:
-      parsed_exp = parser(s[1:-1])
-      line[middle] = "+"
-      line[middle+1] = "-"
-      line[middle+2] = ">"
-      line = line[:middle+3]
-      "".join(line)
-      explain(s, line, parsed_exp)
+    print "Status: 200"
+    print "Content-Type: text/plain"
+    print ""
+    print template
+    parts = re.split("(\{[^\}]*\})", template)
+    try:
+      parsed = URITemplate(template)
+    except:
+      error("Not a valid URI Template")
+    parser = Parser()
+    expansions = []
+    length = 0
+    line = [] 
+    for p in parts:
+      if len(p) and p[0] == '{':
+        expansions.append((p, length, length+len(p), length+len(p)/2))
+        line.append("\\")
+        line.append("_" * (len(p)-2))
+        line.append("/")
+      else:
+        line.append(" " * len(p))
+      length += len(p)
+    print "".join(line)
+    line = [" "] * len(template)
+    for (s, begin, end, middle) in expansions:
+      line[middle] = "|"
+    print "".join(line)
+    print "".join(line)
+    expansions.reverse()
+    for (s, begin, end, middle) in expansions:
+        parsed_exp = parser(s[1:-1])
+        line[middle] = "+"
+        line[middle+1] = "-"
+        line[middle+2] = ">"
+        line = line[:middle+3]
+        "".join(line)
+        explain(s, line, parsed_exp)
 
-      line = line[:middle-1]
-      print "".join(line)
-      
-  
+        line = line[:middle-1]
+        print "".join(line)
+
+
+def _test():
+  import doctest
+  doctest.testmod()
+
+if __name__ == '__main__':
+  import sys
+  if '--test' in sys.argv: _test()
+  else: handle()
# HG changeset patch
# User Dan Connolly http://www.w3.org/People/Connolly/
# Date 1192682033 18000
# Branch trunk
# Node ID 3609c0d2de5fc8e799167f2fe5fcb890aec178da
# Parent  dfb20fe77f991a902b6efbb20810ce18c22ed318
factored cgi handler into 3 parts with doctests

diff -r dfb20fe77f99 -r 3609c0d2de5f explain.cgi
--- a/explain.cgi	Wed Oct 17 22:52:45 2007 -0500
+++ b/explain.cgi	Wed Oct 17 23:33:53 2007 -0500
@@ -23,6 +23,11 @@ descriptions = {
 }
 
 def explain(expansion, line, parsed_exp):
+    """
+    >>> e = ",&|q,num"
+    >>> explain(e, ' ' * 5, Parser()(e))
+          Join the members of the list ['q', 'num'] together with ''.
+    """
     op = expansion[1]
     var = parsed_exp.variables()
     arg = expansion[2:].split("|")[0]
@@ -33,24 +38,35 @@ def explain(expansion, line, parsed_exp)
 
      
 
-def handle():
+def handle_request():
   form = cgi.FieldStorage()
   if not form.has_key("t"):
     error("No URI Template was provided")
   else:
     template = form["t"].value
+  try:
+    parsed = URITemplate(template)
+  except:
+    error("Not a valid URI Template")
 
-    print "Status: 200"
-    print "Content-Type: text/plain"
-    print ""
-    print template
+  print "Status: 200"
+  print "Content-Type: text/plain"
+  print ""
+  print template
+  expansions = []
+  brackets(template, parsed, expansions)
+  l = lines(template, expansions)
+  explanations(template, expansions, l)
+
+
+def brackets(template, parsed, expansions):
+    """
+    >>> t = 'http://example/s?{,&|q,num}'
+    >>> brackets(t, URITemplate(t), [])
+                     \________/
+    """
+    
     parts = re.split("(\{[^\}]*\})", template)
-    try:
-      parsed = URITemplate(template)
-    except:
-      error("Not a valid URI Template")
-    parser = Parser()
-    expansions = []
     length = 0
     line = [] 
     for p in parts:
@@ -63,11 +79,39 @@ def handle():
         line.append(" " * len(p))
       length += len(p)
     print "".join(line)
+
+def lines(template, expansions):
+    """
+    >>> t = 'http://example/s?{,&|q,num}'
+    >>> e = []
+    >>> brackets(t, URITemplate(t), e)
+                     \________/
+    >>> len(lines(t, e))
+                          |    
+                          |    
+    27
+    """
     line = [" "] * len(template)
     for (s, begin, end, middle) in expansions:
       line[middle] = "|"
     print "".join(line)
     print "".join(line)
+    return line
+
+def explanations(template, expansions, line):
+    """
+    >>> t = 'http://example/s?{,&|q,num}'
+    >>> e = []
+    >>> brackets(t, URITemplate(t), e)
+                     \________/
+    >>> l = lines(t, e)
+                          |    
+                          |    
+    >>> explanations(t, e, l)
+                          +-> Join 'var=value' for each variable in ['q', 'num'] with '&'.
+    <BLANKLINE>             
+  """
+    parser = Parser()
     expansions.reverse()
     for (s, begin, end, middle) in expansions:
         parsed_exp = parser(s[1:-1])
@@ -89,4 +133,4 @@ if __name__ == '__main__':
 if __name__ == '__main__':
   import sys
   if '--test' in sys.argv: _test()
-  else: handle()
+  else: handle_request()



Received on Thursday, 18 October 2007 04:45:55 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 7 July 2008 08:10:19 GMT