Example #1
0
def safe_join(base, *paths):
    """
    Joins one or more path components to the base path component intelligently.
    Returns a normalized, absolute version of the final path.

    The final path must be located inside of the base path component (otherwise
    a ValueError is raised).
    """
    base = force_text(base)
    paths = [force_text(p) for p in paths]
    final_path = abspathu(join(base, *paths))
    base_path = abspathu(base)
    # Ensure final_path starts with base_path (using normcase to ensure we
    # don't false-negative on case insensitive operating systems like Windows),
    # further, one of the following conditions must be true:
    #  a) The next character is the path separator (to prevent conditions like
    #     safe_join("/dir", "/../d"))
    #  b) The final path must be the same as the base path.
    #  c) The base path must be the most root path (meaning either "/" or "C:\\")
    if (
        not normcase(final_path).startswith(normcase(base_path + sep))
        and normcase(final_path) != normcase(base_path)
        and dirname(normcase(base_path)) != normcase(base_path)
    ):
        raise ValueError(
            "The joined path (%s) is located outside of the base " "path component (%s)" % (final_path, base_path)
        )
    return final_path
Example #2
0
def wrap(text, width):
    """
    A word-wrap function that preserves existing line breaks and most spaces in
    the text. Expects that existing line breaks are posix newlines.
    """
    text = force_text(text)
    def _generator():
        it = iter(text.split(' '))
        word = next(it)
        yield word
        pos = len(word) - word.rfind('\n') - 1
        for word in it:
            if "\n" in word:
                lines = word.split('\n')
            else:
                lines = (word,)
            pos += len(lines[0]) + 1
            if pos > width:
                yield '\n'
                pos = len(lines[-1])
            else:
                yield ' '
                if len(lines) > 1:
                    pos = len(lines[-1])
            yield word
    return ''.join(_generator())
Example #3
0
def get_text_list(list_, last_word='or'):
    """
    >>> get_text_list(['a', 'b', 'c', 'd'])
    'a, b, c or d'
    >>> get_text_list(['a', 'b', 'c'], 'and')
    'a, b and c'
    >>> get_text_list(['a', 'b'], 'and')
    'a and b'
    >>> get_text_list(['a'])
    'a'
    >>> get_text_list([])
    ''
    """
    if len(list_) == 0: return ''
    if len(list_) == 1: return force_text(list_[0])
    return '%s %s %s' % (
        # Translators: This string is used as a separator between list elements
        ', '.join([force_text(i) for i in list_][:-1]),
        force_text(last_word), force_text(list_[-1]))
Example #4
0
def get_valid_filename(s):
    """
    Returns the given string converted to a string that can be used for a clean
    filename. Specifically, leading and trailing spaces are removed; other
    spaces are converted to underscores; and anything that is not a unicode
    alphanumeric, dash, underscore, or dot, is removed.
    >>> get_valid_filename("john's portrait in 2004.jpg")
    'johns_portrait_in_2004.jpg'
    """
    s = force_text(s).strip().replace(' ', '_')
    return re.sub(r'(?u)[^-\w.]', '', s)
Example #5
0
 def add_truncation_text(self, text, truncate=None):
     if truncate is None:
         truncate = ('String to return when truncating text',
                     '%(truncated_text)s...')
     truncate = force_text(truncate)
     if '%(truncated_text)s' in truncate:
         return truncate % {'truncated_text': text}
     # The truncation text didn't contain the %(truncated_text)s string
     # replacement argument so just append it to the text.
     if text.endswith(truncate):
         # But don't append the truncation text if the current text already
         # ends in this.
         return text
     return '%s%s' % (text, truncate)
Example #6
0
def smart_split(text):
    r"""
    Generator that splits a string by spaces, leaving quoted phrases together.
    Supports both single and double quotes, and supports escaping quotes with
    backslashes. In the output, strings will keep their initial and trailing
    quote marks and escaped quotes will remain escaped (the results can then
    be further processed with unescape_string_literal()).

    >>> list(smart_split(r'This is "a person\'s" test.'))
    ['This', 'is', '"a person\\\'s"', 'test.']
    >>> list(smart_split(r"Another 'person\'s' test."))
    ['Another', "'person\\'s'", 'test.']
    >>> list(smart_split(r'A "\"funky\" style" test.'))
    ['A', '"\\"funky\\" style"', 'test.']
    """
    text = force_text(text)
    for bit in smart_split_re.finditer(text):
        yield bit.group(0)
Example #7
0
 def __init__(self, text):
     super(Truncator, self).__init__(lambda: force_text(text))
Example #8
0
def recapitalize(text):
    "Recapitalizes text, placing caps after end-of-sentence punctuation."
    text = force_text(text).lower()
    capsRE = re.compile(r'(?:^|(?<=[\.\?\!] ))([a-z])')
    text = capsRE.sub(lambda x: x.group(1).upper(), text)
    return text
Example #9
0
def normalize_newlines(text):
    return force_text(re.sub(r'\r\n|\r|\n', '\n', text))
Example #10
0
from gzip import GzipFile
from io import BytesIO

from pystorages.utils.encoding import force_text
from pystorages.utils.functional import allow_lazy, SimpleLazyObject
from pystorages.utils.safestring import mark_safe
import six
from six.moves import html_entities

if not six.PY3:
    # Import force_unicode even though this module doesn't use it, because some
    # people rely on it being here.
    from pystorages.utils.encoding import force_unicode

# Capitalizes the first letter of a string.
capfirst = lambda x: x and force_text(x)[0].upper() + force_text(x)[1:]
capfirst = allow_lazy(capfirst, six.text_type)

# Set up regular expressions
re_words = re.compile(r'&.*?;|<.*?>|(\w[\w-]*)', re.U|re.S)
re_tag = re.compile(r'<(/)?([^ ]+?)(?:(\s*/)| .*?)?>', re.S)


def wrap(text, width):
    """
    A word-wrap function that preserves existing line breaks and most spaces in
    the text. Expects that existing line breaks are posix newlines.
    """
    text = force_text(text)
    def _generator():
        it = iter(text.split(' '))