1 """Rules based url rewriter component, to get configurable RESTful urls |
1 """Rules based url rewriter component, to get configurable RESTful urls |
2 |
2 |
3 :organization: Logilab |
3 :organization: Logilab |
4 :copyright: 2007-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
4 :copyright: 2007-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
6 """ |
6 """ |
7 import re |
7 import re |
8 |
8 |
9 from cubicweb.vregistry import autoselectors |
9 from cubicweb.appobject import AppObject |
10 |
|
11 from cubicweb.common.registerers import accepts_registerer |
|
12 from cubicweb.common.appobject import AppObject |
|
13 |
10 |
14 |
11 |
15 def rgx(pattern, flags=0): |
12 def rgx(pattern, flags=0): |
16 """this is just a convenient shortcout to add the $ sign""" |
13 """this is just a convenient shortcout to add the $ sign""" |
17 return re.compile(pattern+'$', flags) |
14 return re.compile(pattern+'$', flags) |
18 |
15 |
19 class metarewriter(autoselectors): |
16 class metarewriter(type): |
20 """auto-extend rules dictionnary""" |
17 """auto-extend rules dictionnary""" |
21 def __new__(mcs, name, bases, classdict): |
18 def __new__(mcs, name, bases, classdict): |
22 # collect baseclass' rules |
19 # collect baseclass' rules |
23 rules = [] |
20 rules = [] |
24 ignore_baseclass_rules = classdict.get('ignore_baseclass_rules', False) |
21 ignore_baseclass_rules = classdict.get('ignore_baseclass_rules', False) |
53 should be tried first. The higher the priority is, the earlier the |
50 should be tried first. The higher the priority is, the earlier the |
54 rewriter will be tried |
51 rewriter will be tried |
55 """ |
52 """ |
56 __metaclass__ = metarewriter |
53 __metaclass__ = metarewriter |
57 __registry__ = 'urlrewriting' |
54 __registry__ = 'urlrewriting' |
58 __registerer__ = accepts_registerer |
|
59 __abstract__ = True |
55 __abstract__ = True |
60 |
56 |
61 id = 'urlrewriting' |
57 id = 'urlrewriting' |
62 accepts = ('Any',) |
|
63 priority = 1 |
58 priority = 1 |
64 |
59 |
65 def rewrite(self, req, uri): |
60 def rewrite(self, req, uri): |
66 raise NotImplementedError |
61 raise NotImplementedError |
67 |
62 |
81 ('/myprefs', dict(vid='epropertiesform')), |
76 ('/myprefs', dict(vid='epropertiesform')), |
82 ('/siteconfig', dict(vid='systemepropertiesform')), |
77 ('/siteconfig', dict(vid='systemepropertiesform')), |
83 ('/manage', dict(vid='manage')), |
78 ('/manage', dict(vid='manage')), |
84 ('/notfound', dict(vid='404')), |
79 ('/notfound', dict(vid='404')), |
85 ('/error', dict(vid='error')), |
80 ('/error', dict(vid='error')), |
86 (rgx('/schema/([^/]+?)/?'), dict(vid='eschema', rql=r'Any X WHERE X is EEType, X name "\1"')), |
81 (rgx('/schema/([^/]+?)/?'), dict(vid='eschema', rql=r'Any X WHERE X is CWEType, X name "\1"')), |
87 (rgx('/add/([^/]+?)/?'), dict(vid='creation', etype=r'\1')), |
82 (rgx('/add/([^/]+?)/?'), dict(vid='creation', etype=r'\1')), |
88 (rgx('/doc/images/(.+?)/?'), dict(vid='wdocimages', fid=r'\1')), |
83 (rgx('/doc/images/(.+?)/?'), dict(vid='wdocimages', fid=r'\1')), |
89 (rgx('/doc/?'), dict(vid='wdoc', fid=r'main')), |
84 (rgx('/doc/?'), dict(vid='wdoc', fid=r'main')), |
90 (rgx('/doc/(.+?)/?'), dict(vid='wdoc', fid=r'\1')), |
85 (rgx('/doc/(.+?)/?'), dict(vid='wdoc', fid=r'\1')), |
91 (rgx('/changelog/?'), dict(vid='changelog')), |
86 (rgx('/changelog/?'), dict(vid='changelog')), |
92 ] |
87 ] |
93 |
88 |
94 def rewrite(self, req, uri): |
89 def rewrite(self, req, uri): |
95 """for each `input`, `output `in rules, if `uri` matches `input`, |
90 """for each `input`, `output `in rules, if `uri` matches `input`, |
96 req's form is updated with `output` |
91 req's form is updated with `output` |
97 """ |
92 """ |
98 rset = None |
|
99 for data in self.rules: |
93 for data in self.rules: |
100 try: |
94 try: |
101 inputurl, infos, required_groups = data |
95 inputurl, infos, required_groups = data |
102 except ValueError: |
96 except ValueError: |
103 inputurl, infos = data |
97 inputurl, infos = data |
110 break |
104 break |
111 elif inputurl.match(uri): # it's a regexp |
105 elif inputurl.match(uri): # it's a regexp |
112 # XXX what about i18n ? (vtitle for instance) |
106 # XXX what about i18n ? (vtitle for instance) |
113 for param, value in infos.items(): |
107 for param, value in infos.items(): |
114 if isinstance(value, basestring): |
108 if isinstance(value, basestring): |
115 req.form[param]= inputurl.sub(value, uri) |
109 req.form[param] = inputurl.sub(value, uri) |
116 else: |
110 else: |
117 req.form[param] = value |
111 req.form[param] = value |
118 break |
112 break |
119 else: |
113 else: |
120 self.debug("no simple rewrite rule found for %s", uri) |
114 self.debug("no simple rewrite rule found for %s", uri) |
183 """ |
177 """ |
184 id = 'schemabased' |
178 id = 'schemabased' |
185 rules = [ |
179 rules = [ |
186 # rgxp : callback |
180 # rgxp : callback |
187 (rgx('/search/(.+)'), build_rset(rql=r'Any X WHERE X has_text %(text)s', |
181 (rgx('/search/(.+)'), build_rset(rql=r'Any X WHERE X has_text %(text)s', |
188 rgxgroups=[('text', 1)])), |
182 rgxgroups=[('text', 1)])), |
189 ] |
183 ] |
190 |
184 |
191 def rewrite(self, req, uri): |
185 def rewrite(self, req, uri): |
192 # XXX this could be refacted with SimpleReqRewriter |
186 # XXX this could be refacted with SimpleReqRewriter |
193 for data in self.rules: |
187 for data in self.rules: |