forked from CenterForOpenScience/osf.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.py
84 lines (65 loc) · 2.29 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import re
from typing import Final
from collections.abc import Iterable
import pytz
import time
from datetime import datetime
from bleach.sanitizer import Cleaner, ALLOWED_TAGS, ALLOWED_PROTOCOLS, ALLOWED_ATTRIBUTES
from bleach.css_sanitizer import CSSSanitizer, ALLOWED_CSS_PROPERTIES
from django.utils import timezone
from werkzeug.utils import secure_filename as werkzeug_secure_filename
def iso8601format(dt):
"""Given a datetime object, return an associated ISO-8601 string"""
return dt.strftime('%Y-%m-%dT%H:%M:%SZ') if dt else ''
def secure_filename(filename):
"""Return a secure version of a filename.
Uses ``werkzeug.utils.secure_filename``, but explicitly allows for leading
underscores.
:param filename str: A filename to sanitize
:return: Secure version of filename
"""
secure = werkzeug_secure_filename(filename)
# Check for leading underscores, and add them back in
try:
secure = re.search('^_+', filename).group() + secure
except AttributeError:
pass
return secure
_sentinel: Final = object()
def sanitize_html(
text: str,
tags: set[str] = ALLOWED_TAGS,
attributes: dict[str, Iterable[str]] | Iterable[str] = _sentinel,
protocols: set[str] = ALLOWED_PROTOCOLS,
strip: bool = False,
styles: set[str] | None = ALLOWED_CSS_PROPERTIES,
strip_comments: bool = True,
filters: list = None,
) -> str:
css_sanitizer = None
if attributes == _sentinel:
attributes = ALLOWED_ATTRIBUTES
if styles is not None:
css_sanitizer = CSSSanitizer(allowed_css_properties=styles)
cleaner = Cleaner(
tags=tags,
attributes=attributes,
protocols=protocols,
strip=strip,
strip_comments=strip_comments,
css_sanitizer=css_sanitizer,
filters=filters,
)
return cleaner.clean(text)
def get_timestamp():
return int(time.time())
def throttle_period_expired(timestamp, throttle):
if not timestamp:
return True
elif isinstance(timestamp, datetime):
if timestamp.tzinfo:
return (timezone.now() - timestamp).total_seconds() > throttle
else:
return (timezone.now() - timestamp.replace(tzinfo=pytz.utc)).total_seconds() > throttle
else:
return (get_timestamp() - timestamp) > throttle