filters.py 2.12 KB
Newer Older
Laurent Bachelier's avatar
Laurent Bachelier committed
1 2
# -*- coding: utf-8 -*-

3
# Copyright (C) 2011 Romain Bignon, Laurent Bachelier
Laurent Bachelier's avatar
Laurent Bachelier committed
4
#
Romain Bignon's avatar
Romain Bignon committed
5
# This file is part of assnet.
6
#
Romain Bignon's avatar
Romain Bignon committed
7
# assnet is free software: you can redistribute it and/or modify
Laurent Bachelier's avatar
Laurent Bachelier committed
8
# it under the terms of the GNU Affero General Public License as published by
9 10
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
Laurent Bachelier's avatar
Laurent Bachelier committed
11
#
Romain Bignon's avatar
Romain Bignon committed
12
# assnet is distributed in the hope that it will be useful,
Laurent Bachelier's avatar
Laurent Bachelier committed
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Laurent Bachelier's avatar
Laurent Bachelier committed
15 16 17
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
Romain Bignon's avatar
Romain Bignon committed
18
# along with assnet. If not, see <http://www.gnu.org/licenses/>.
19

Laurent Bachelier's avatar
Laurent Bachelier committed
20

21
from urlparse import urlsplit, urlunsplit
Laurent Bachelier's avatar
Laurent Bachelier committed
22 23 24
from urllib import quote
from paste.url import URL

Laurent Bachelier's avatar
Laurent Bachelier committed
25

26 27
__all__ = ['compact', 'quote_url', 'quote_path', 'quote_and_decode_url']

Laurent Bachelier's avatar
Laurent Bachelier committed
28

29 30 31 32
UNSAFE_CHARS = {
    '?': quote('?'),
    '&': quote('&'),
    ';': quote(';'),
33
    ':': quote(':'),
34 35 36 37 38 39
    ',': quote(','),
    '=': quote('='),
    ' ': quote(' '),
    '+': quote('+'),
    ':': quote(':'),
    '$': quote('$'),
Laurent Bachelier's avatar
Laurent Bachelier committed
40
    '"': quote('"'),
41 42
}

Laurent Bachelier's avatar
Laurent Bachelier committed
43

Laurent Bachelier's avatar
Laurent Bachelier committed
44 45 46
def compact(text):
    return text.replace('\n', ' ').strip()

Laurent Bachelier's avatar
Laurent Bachelier committed
47

48 49 50 51 52 53
def quote_path(path):
    """
    Quote a path (see quote_url)
    """
    return ''.join([UNSAFE_CHARS.get(c, c) for c in path])

Laurent Bachelier's avatar
Laurent Bachelier committed
54

Laurent Bachelier's avatar
Laurent Bachelier committed
55 56 57
def quote_url(url):
    """
    Quote the path part of an URL object and return the full URL as a string.
Laurent Bachelier's avatar
Laurent Bachelier committed
58 59 60
    Special characters in the URL are not considered as the query string or
    any other parameters, they should be in their dedicated variables
    of the URL class.
Laurent Bachelier's avatar
Laurent Bachelier committed
61
    """
62
    purl = urlsplit(url.url)
63
    # do not escape the scheme and netloc
64
    if purl.scheme and purl.netloc:
65 66 67 68 69 70
        path = urlunsplit((None, None, purl.path, purl.query, purl.fragment))
        basepath = urlunsplit((purl.scheme, purl.netloc, '', None, None))
    else:
        path = url.url
        basepath = ''
    return URL(basepath + quote_path(path), vars=url.vars).href
71

Laurent Bachelier's avatar
Laurent Bachelier committed
72

73 74 75 76 77
def quote_and_decode_url(url):
    """
    Like quote_url but for usage in Mako templates
    """
    return quote_url(url).decode('utf-8')