测试gitnore
This commit is contained in:
@@ -4,7 +4,9 @@ import html
|
||||
import json
|
||||
import re
|
||||
from html.parser import HTMLParser
|
||||
from urllib.parse import parse_qsl, quote, unquote, urlencode, urlsplit, urlunsplit
|
||||
from urllib.parse import (
|
||||
parse_qsl, quote, unquote, urlencode, urlsplit, urlunsplit,
|
||||
)
|
||||
|
||||
from django.utils.encoding import punycode
|
||||
from django.utils.functional import Promise, keep_lazy, keep_lazy_text
|
||||
@@ -14,16 +16,17 @@ from django.utils.safestring import SafeData, SafeString, mark_safe
|
||||
from django.utils.text import normalize_newlines
|
||||
|
||||
# Configuration for urlize() function.
|
||||
TRAILING_PUNCTUATION_CHARS = ".,:;!"
|
||||
WRAPPING_PUNCTUATION = [("(", ")"), ("[", "]")]
|
||||
TRAILING_PUNCTUATION_CHARS = '.,:;!'
|
||||
WRAPPING_PUNCTUATION = [('(', ')'), ('[', ']')]
|
||||
|
||||
# List of possible strings used for bullets in bulleted lists.
|
||||
DOTS = ["·", "*", "\u2022", "•", "•", "•"]
|
||||
DOTS = ['·', '*', '\u2022', '•', '•', '•']
|
||||
|
||||
word_split_re = _lazy_re_compile(r"""([\s<>"']+)""")
|
||||
simple_url_re = _lazy_re_compile(r"^https?://\[?\w", re.IGNORECASE)
|
||||
word_split_re = _lazy_re_compile(r'''([\s<>"']+)''')
|
||||
simple_url_re = _lazy_re_compile(r'^https?://\[?\w', re.IGNORECASE)
|
||||
simple_url_2_re = _lazy_re_compile(
|
||||
r"^www\.|^(?!http)\w[^@]+\.(com|edu|gov|int|mil|net|org)($|/.*)$", re.IGNORECASE
|
||||
r'^www\.|^(?!http)\w[^@]+\.(com|edu|gov|int|mil|net|org)($|/.*)$',
|
||||
re.IGNORECASE
|
||||
)
|
||||
|
||||
|
||||
@@ -41,22 +44,22 @@ def escape(text):
|
||||
|
||||
|
||||
_js_escapes = {
|
||||
ord("\\"): "\\u005C",
|
||||
ord("'"): "\\u0027",
|
||||
ord('"'): "\\u0022",
|
||||
ord(">"): "\\u003E",
|
||||
ord("<"): "\\u003C",
|
||||
ord("&"): "\\u0026",
|
||||
ord("="): "\\u003D",
|
||||
ord("-"): "\\u002D",
|
||||
ord(";"): "\\u003B",
|
||||
ord("`"): "\\u0060",
|
||||
ord("\u2028"): "\\u2028",
|
||||
ord("\u2029"): "\\u2029",
|
||||
ord('\\'): '\\u005C',
|
||||
ord('\''): '\\u0027',
|
||||
ord('"'): '\\u0022',
|
||||
ord('>'): '\\u003E',
|
||||
ord('<'): '\\u003C',
|
||||
ord('&'): '\\u0026',
|
||||
ord('='): '\\u003D',
|
||||
ord('-'): '\\u002D',
|
||||
ord(';'): '\\u003B',
|
||||
ord('`'): '\\u0060',
|
||||
ord('\u2028'): '\\u2028',
|
||||
ord('\u2029'): '\\u2029'
|
||||
}
|
||||
|
||||
# Escape every ASCII character with a value less than 32.
|
||||
_js_escapes.update((ord("%c" % z), "\\u%04X" % z) for z in range(32))
|
||||
_js_escapes.update((ord('%c' % z), '\\u%04X' % z) for z in range(32))
|
||||
|
||||
|
||||
@keep_lazy(str, SafeString)
|
||||
@@ -66,9 +69,9 @@ def escapejs(value):
|
||||
|
||||
|
||||
_json_script_escapes = {
|
||||
ord(">"): "\\u003E",
|
||||
ord("<"): "\\u003C",
|
||||
ord("&"): "\\u0026",
|
||||
ord('>'): '\\u003E',
|
||||
ord('<'): '\\u003C',
|
||||
ord('&'): '\\u0026',
|
||||
}
|
||||
|
||||
|
||||
@@ -79,12 +82,10 @@ def json_script(value, element_id):
|
||||
the escaped JSON in a script tag.
|
||||
"""
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
|
||||
json_str = json.dumps(value, cls=DjangoJSONEncoder).translate(_json_script_escapes)
|
||||
return format_html(
|
||||
'<script id="{}" type="application/json">{}</script>',
|
||||
element_id,
|
||||
mark_safe(json_str),
|
||||
element_id, mark_safe(json_str)
|
||||
)
|
||||
|
||||
|
||||
@@ -97,7 +98,7 @@ def conditional_escape(text):
|
||||
"""
|
||||
if isinstance(text, Promise):
|
||||
text = str(text)
|
||||
if hasattr(text, "__html__"):
|
||||
if hasattr(text, '__html__'):
|
||||
return text.__html__()
|
||||
else:
|
||||
return escape(text)
|
||||
@@ -128,23 +129,22 @@ def format_html_join(sep, format_string, args_generator):
|
||||
format_html_join('\n', "<li>{} {}</li>", ((u.first_name, u.last_name)
|
||||
for u in users))
|
||||
"""
|
||||
return mark_safe(
|
||||
conditional_escape(sep).join(
|
||||
format_html(format_string, *args) for args in args_generator
|
||||
)
|
||||
)
|
||||
return mark_safe(conditional_escape(sep).join(
|
||||
format_html(format_string, *args)
|
||||
for args in args_generator
|
||||
))
|
||||
|
||||
|
||||
@keep_lazy_text
|
||||
def linebreaks(value, autoescape=False):
|
||||
"""Convert newlines into <p> and <br>s."""
|
||||
value = normalize_newlines(value)
|
||||
paras = re.split("\n{2,}", str(value))
|
||||
paras = re.split('\n{2,}', str(value))
|
||||
if autoescape:
|
||||
paras = ["<p>%s</p>" % escape(p).replace("\n", "<br>") for p in paras]
|
||||
paras = ['<p>%s</p>' % escape(p).replace('\n', '<br>') for p in paras]
|
||||
else:
|
||||
paras = ["<p>%s</p>" % p.replace("\n", "<br>") for p in paras]
|
||||
return "\n\n".join(paras)
|
||||
paras = ['<p>%s</p>' % p.replace('\n', '<br>') for p in paras]
|
||||
return '\n\n'.join(paras)
|
||||
|
||||
|
||||
class MLStripper(HTMLParser):
|
||||
@@ -157,13 +157,13 @@ class MLStripper(HTMLParser):
|
||||
self.fed.append(d)
|
||||
|
||||
def handle_entityref(self, name):
|
||||
self.fed.append("&%s;" % name)
|
||||
self.fed.append('&%s;' % name)
|
||||
|
||||
def handle_charref(self, name):
|
||||
self.fed.append("&#%s;" % name)
|
||||
self.fed.append('&#%s;' % name)
|
||||
|
||||
def get_data(self):
|
||||
return "".join(self.fed)
|
||||
return ''.join(self.fed)
|
||||
|
||||
|
||||
def _strip_once(value):
|
||||
@@ -182,9 +182,9 @@ def strip_tags(value):
|
||||
# Note: in typical case this loop executes _strip_once once. Loop condition
|
||||
# is redundant, but helps to reduce number of executions of _strip_once.
|
||||
value = str(value)
|
||||
while "<" in value and ">" in value:
|
||||
while '<' in value and '>' in value:
|
||||
new_value = _strip_once(value)
|
||||
if value.count("<") == new_value.count("<"):
|
||||
if value.count('<') == new_value.count('<'):
|
||||
# _strip_once wasn't able to detect more tags.
|
||||
break
|
||||
value = new_value
|
||||
@@ -194,18 +194,17 @@ def strip_tags(value):
|
||||
@keep_lazy_text
|
||||
def strip_spaces_between_tags(value):
|
||||
"""Return the given HTML with spaces between tags removed."""
|
||||
return re.sub(r">\s+<", "><", str(value))
|
||||
return re.sub(r'>\s+<', '><', str(value))
|
||||
|
||||
|
||||
def smart_urlquote(url):
|
||||
"""Quote a URL if it isn't already quoted."""
|
||||
|
||||
def unquote_quote(segment):
|
||||
segment = unquote(segment)
|
||||
# Tilde is part of RFC3986 Unreserved Characters
|
||||
# https://tools.ietf.org/html/rfc3986#section-2.3
|
||||
# See also https://bugs.python.org/issue16285
|
||||
return quote(segment, safe=RFC3986_SUBDELIMS + RFC3986_GENDELIMS + "~")
|
||||
return quote(segment, safe=RFC3986_SUBDELIMS + RFC3986_GENDELIMS + '~')
|
||||
|
||||
# Handle IDN before quoting.
|
||||
try:
|
||||
@@ -222,10 +221,8 @@ def smart_urlquote(url):
|
||||
if query:
|
||||
# Separately unquoting key/value, so as to not mix querystring separators
|
||||
# included in query values. See #22267.
|
||||
query_parts = [
|
||||
(unquote(q[0]), unquote(q[1]))
|
||||
for q in parse_qsl(query, keep_blank_values=True)
|
||||
]
|
||||
query_parts = [(unquote(q[0]), unquote(q[1]))
|
||||
for q in parse_qsl(query, keep_blank_values=True)]
|
||||
# urlencode will take care of quoting
|
||||
query = urlencode(query_parts)
|
||||
|
||||
@@ -257,7 +254,7 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
|
||||
def trim_url(x, limit=trim_url_limit):
|
||||
if limit is None or len(x) <= limit:
|
||||
return x
|
||||
return "%s…" % x[: max(0, limit - 1)]
|
||||
return '%s…' % x[:max(0, limit - 1)]
|
||||
|
||||
def trim_punctuation(lead, middle, trail):
|
||||
"""
|
||||
@@ -271,15 +268,13 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
|
||||
# Trim wrapping punctuation.
|
||||
for opening, closing in WRAPPING_PUNCTUATION:
|
||||
if middle.startswith(opening):
|
||||
middle = middle[len(opening) :]
|
||||
middle = middle[len(opening):]
|
||||
lead += opening
|
||||
trimmed_something = True
|
||||
# Keep parentheses at the end only if they're balanced.
|
||||
if (
|
||||
middle.endswith(closing)
|
||||
and middle.count(closing) == middle.count(opening) + 1
|
||||
):
|
||||
middle = middle[: -len(closing)]
|
||||
if (middle.endswith(closing) and
|
||||
middle.count(closing) == middle.count(opening) + 1):
|
||||
middle = middle[:-len(closing)]
|
||||
trail = closing + trail
|
||||
trimmed_something = True
|
||||
# Trim trailing punctuation (after trimming wrapping punctuation,
|
||||
@@ -288,52 +283,51 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
|
||||
middle_unescaped = html.unescape(middle)
|
||||
stripped = middle_unescaped.rstrip(TRAILING_PUNCTUATION_CHARS)
|
||||
if middle_unescaped != stripped:
|
||||
punctuation_count = len(middle_unescaped) - len(stripped)
|
||||
trail = middle[-punctuation_count:] + trail
|
||||
middle = middle[:-punctuation_count]
|
||||
trail = middle[len(stripped):] + trail
|
||||
middle = middle[:len(stripped) - len(middle_unescaped)]
|
||||
trimmed_something = True
|
||||
return lead, middle, trail
|
||||
|
||||
def is_email_simple(value):
|
||||
"""Return True if value looks like an email address."""
|
||||
# An @ must be in the middle of the value.
|
||||
if "@" not in value or value.startswith("@") or value.endswith("@"):
|
||||
if '@' not in value or value.startswith('@') or value.endswith('@'):
|
||||
return False
|
||||
try:
|
||||
p1, p2 = value.split("@")
|
||||
p1, p2 = value.split('@')
|
||||
except ValueError:
|
||||
# value contains more than one @.
|
||||
return False
|
||||
# Dot must be in p2 (e.g. example.com)
|
||||
if "." not in p2 or p2.startswith("."):
|
||||
if '.' not in p2 or p2.startswith('.'):
|
||||
return False
|
||||
return True
|
||||
|
||||
words = word_split_re.split(str(text))
|
||||
for i, word in enumerate(words):
|
||||
if "." in word or "@" in word or ":" in word:
|
||||
if '.' in word or '@' in word or ':' in word:
|
||||
# lead: Current punctuation trimmed from the beginning of the word.
|
||||
# middle: Current state of the word.
|
||||
# trail: Current punctuation trimmed from the end of the word.
|
||||
lead, middle, trail = "", word, ""
|
||||
lead, middle, trail = '', word, ''
|
||||
# Deal with punctuation.
|
||||
lead, middle, trail = trim_punctuation(lead, middle, trail)
|
||||
|
||||
# Make URL we want to point to.
|
||||
url = None
|
||||
nofollow_attr = ' rel="nofollow"' if nofollow else ""
|
||||
nofollow_attr = ' rel="nofollow"' if nofollow else ''
|
||||
if simple_url_re.match(middle):
|
||||
url = smart_urlquote(html.unescape(middle))
|
||||
elif simple_url_2_re.match(middle):
|
||||
url = smart_urlquote("http://%s" % html.unescape(middle))
|
||||
elif ":" not in middle and is_email_simple(middle):
|
||||
local, domain = middle.rsplit("@", 1)
|
||||
url = smart_urlquote('http://%s' % html.unescape(middle))
|
||||
elif ':' not in middle and is_email_simple(middle):
|
||||
local, domain = middle.rsplit('@', 1)
|
||||
try:
|
||||
domain = punycode(domain)
|
||||
except UnicodeError:
|
||||
continue
|
||||
url = "mailto:%s@%s" % (local, domain)
|
||||
nofollow_attr = ""
|
||||
url = 'mailto:%s@%s' % (local, domain)
|
||||
nofollow_attr = ''
|
||||
|
||||
# Make link.
|
||||
if url:
|
||||
@@ -342,7 +336,7 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
|
||||
lead, trail = escape(lead), escape(trail)
|
||||
trimmed = escape(trimmed)
|
||||
middle = '<a href="%s"%s>%s</a>' % (escape(url), nofollow_attr, trimmed)
|
||||
words[i] = mark_safe("%s%s%s" % (lead, middle, trail))
|
||||
words[i] = mark_safe('%s%s%s' % (lead, middle, trail))
|
||||
else:
|
||||
if safe_input:
|
||||
words[i] = mark_safe(word)
|
||||
@@ -352,7 +346,7 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
|
||||
words[i] = mark_safe(word)
|
||||
elif autoescape:
|
||||
words[i] = escape(word)
|
||||
return "".join(words)
|
||||
return ''.join(words)
|
||||
|
||||
|
||||
def avoid_wrapping(value):
|
||||
@@ -368,12 +362,12 @@ def html_safe(klass):
|
||||
A decorator that defines the __html__ method. This helps non-Django
|
||||
templates to detect classes whose __str__ methods return SafeString.
|
||||
"""
|
||||
if "__html__" in klass.__dict__:
|
||||
if '__html__' in klass.__dict__:
|
||||
raise ValueError(
|
||||
"can't apply @html_safe to %s because it defines "
|
||||
"__html__()." % klass.__name__
|
||||
)
|
||||
if "__str__" not in klass.__dict__:
|
||||
if '__str__' not in klass.__dict__:
|
||||
raise ValueError(
|
||||
"can't apply @html_safe to %s because it doesn't "
|
||||
"define __str__()." % klass.__name__
|
||||
|
||||
Reference in New Issue
Block a user