URL encoding is undefined. See
http://www.cherrypy.org/ticket/825
http://www.w3schools.com/TAGS/ref_urlencode.asp
http://www.rfc-editor.org/rfc/rfc2396.txt
Therefore, safe URLs should be in a subset of ASCII. We convert our
URLs to UTF-8, and then use urllib.quote_plus() to escape the UTF-8
into ASCII.
import os.path
import textwrap
import types
import os.path
import textwrap
import types
+from urllib import quote_plus
self.url = url
self.tags = tags
self.url = url
self.tags = tags
+ def clean_name(self, ascii=False):
- for from_,to in [(' ','_'), ('/', '_'),
- (',', ''), (u'\xe2\x80\x99', ''),
- ('&', 'and')]:
+ for from_,to in [(' ','_'), ('/', '_'), (',', ''), ('&', 'and')]:
name = name.replace(from_, to)
name = name.replace(from_, to)
+ if ascii == True:
+ return quote_plus(name.encode('utf-8'))
return name
def matches_tags(self, tags):
return name
def matches_tags(self, tags):
for recipe in self:
self.index[recipe.name] = recipe
self.index[recipe.clean_name()] = recipe
for recipe in self:
self.index[recipe.name] = recipe
self.index[recipe.clean_name()] = recipe
+ self.index[recipe.clean_name(ascii=True)] = recipe
def tags(self):
"""List all tags used in this cookbook.
def tags(self):
"""List all tags used in this cookbook.
if name == None:
recipe = random.choice(self.cookbook)
else:
if name == None:
recipe = random.choice(self.cookbook)
else:
- if type(name) == types.StringType:
- name = unicode(name, encoding='utf-8')
+ if isinstance(name, types.StringType):
+ name = unicode(name, 'utf-8')
recipe = self.cookbook.index[name]
template = self.env.get_template('recipe.html')
return template.render(cookbook=self.cookbook, recipe=recipe)
recipe = self.cookbook.index[name]
template = self.env.get_template('recipe.html')
return template.render(cookbook=self.cookbook, recipe=recipe)
@cherrypy.expose
def add_tag(self, name, tag):
"""Add a tag to a single recipe."""
@cherrypy.expose
def add_tag(self, name, tag):
"""Add a tag to a single recipe."""
- if type(name) == types.StringType:
- name = unicode(name, encoding='utf-8')
+ if isinstance(name, types.StringType):
+ name = unicode(name, 'utf-8')
recipe = self.cookbook.index[name]
if recipe.tags == None:
recipe.tags = []
recipe = self.cookbook.index[name]
if recipe.tags == None:
recipe.tags = []
with open(recipe.path, 'w') as f:
recipe.save(f)
raise cherrypy.HTTPRedirect(
with open(recipe.path, 'w') as f:
recipe.save(f)
raise cherrypy.HTTPRedirect(
- 'recipe?name=%s' % recipe.clean_name(), status=302)
+ u'recipe?name=%s' % recipe.clean_name(ascii=True), status=302)
@cherrypy.expose
def remove_tag(self, name, tag):
"""Remove a tag from a single recipe."""
@cherrypy.expose
def remove_tag(self, name, tag):
"""Remove a tag from a single recipe."""
- if type(name) == types.StringType:
- name = unicode(name, encoding='utf-8')
+ if isinstance(name, types.StringType):
+ name = unicode(name, 'utf-8')
recipe = self.cookbook.index[name]
if recipe.tags == None:
return
recipe = self.cookbook.index[name]
if recipe.tags == None:
return
with open(recipe.path, 'w') as f:
recipe.save(f)
raise cherrypy.HTTPRedirect(
with open(recipe.path, 'w') as f:
recipe.save(f)
raise cherrypy.HTTPRedirect(
- 'recipe?name=%s' % recipe.clean_name(), status=302)
+ u'recipe?name=%s' % recipe.clean_name(ascii=True), status=302)
def _clean_tag(self, tag):
"""Sanitize tag."""
def _clean_tag(self, tag):
"""Sanitize tag."""
</form>
<ul id="recipe-list">
{% for recipe in recipes %}
</form>
<ul id="recipe-list">
{% for recipe in recipes %}
- <li><a href="recipe?name={{ recipe.clean_name() }}">
+ <li><a href="recipe?name={{ recipe.clean_name(ascii=True) }}">
{{ recipe.name }}</li>
{% endfor %}
</ul>
{{ recipe.name }}</li>
{% endfor %}
</ul>