1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
# ========================================================================
# Copyright (c) 2007, Metaweb Technologies, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY METAWEB TECHNOLOGIES AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL METAWEB
# TECHNOLOGIES OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# ========================================================================
#
# URI Templating in Python
#
# see http://bitworking.org/projects/URI-Templates/
# and http://bitworking.org/news/URI_Templates
#
# this implementation can also parse URIs, as long as the
# template is sufficiently specific. to allow this to work
# the '/' character is forbidden in keys when parsing.
# later it should be possible to loosen this restriction.
#
# TODO:
# simplify the syntax calling in - currently
# uri = new URITemplate(ut.template).run({...})
# allow parsing to be aware of www. and trailing /
# nail down quoting issues
#
import os, sys, re
class URITemplate(object):
VARREF = re.compile(r'\{([0-9a-zA-Z_]+)\}')
def __init__(self, s):
self.template = s;
self.params = []
tsplit = self.VARREF.split(s)
rxs = ['^']
for i in range(len(tsplit)):
if i % 2:
# track the vars used
self.params.append(tsplit[i])
# vars match any string
# XXX vars are assumed to lack '/' - this is imperfect...
rxs.append('([^/]*)')
else:
# quote special chars regexp interpretation
rxs.append(re.escape(tsplit[i]))
rxs.append('$')
self._parser = re.compile(''.join(rxs))
def __repr__(self):
return '<URITemplate %r>' % self.template
def run (self, **args):
def repl(m):
key = m.group(1)
return args[key]
uri = self.VARREF.sub(repl,self.template)
# XXX for testing, compare this to args array
if self.parse(uri) is None:
print 're-parsing generated uri failed: %r, %r' % (uri, self.template)
return uri
def parse(self, uri):
m = self._parser.match(uri)
if m is None:
return None
return dict(zip(self.params, m.groups()))
if __name__ == '__main__':
ut = URITemplate('xxx{key}yyy')
print ut.run(key='ABC')
|