mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-24 16:24:08 -04:00
notify-api-412 use black to enforce python coding style
This commit is contained in:
@@ -22,23 +22,20 @@ from app.utils.time import parse_naive_dt
|
||||
|
||||
def convert_to_boolean(value):
|
||||
if isinstance(value, str):
|
||||
if value.lower() in ['t', 'true', 'on', 'yes', '1']:
|
||||
if value.lower() in ["t", "true", "on", "yes", "1"]:
|
||||
return True
|
||||
elif value.lower() in ['f', 'false', 'off', 'no', '0']:
|
||||
elif value.lower() in ["f", "false", "off", "no", "0"]:
|
||||
return False
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def format_datetime(date):
|
||||
return '{} at {} UTC'.format(
|
||||
format_date(date),
|
||||
format_time_24h(date)
|
||||
)
|
||||
return "{} at {} UTC".format(format_date(date), format_time_24h(date))
|
||||
|
||||
|
||||
def format_datetime_24h(date):
|
||||
return '{} at {} UTC'.format(
|
||||
return "{} at {} UTC".format(
|
||||
format_date(date),
|
||||
format_time_24h(date),
|
||||
)
|
||||
@@ -49,28 +46,19 @@ def format_time(date):
|
||||
|
||||
|
||||
def format_datetime_normal(date):
|
||||
return '{} at {} UTC'.format(
|
||||
format_date_normal(date),
|
||||
format_time_24h(date)
|
||||
)
|
||||
return "{} at {} UTC".format(format_date_normal(date), format_time_24h(date))
|
||||
|
||||
|
||||
def format_datetime_short(date):
|
||||
return '{} at {} UTC'.format(
|
||||
format_date_short(date),
|
||||
format_time_24h(date)
|
||||
)
|
||||
return "{} at {} UTC".format(format_date_short(date), format_time_24h(date))
|
||||
|
||||
|
||||
def format_datetime_relative(date):
|
||||
return '{} at {} UTC'.format(
|
||||
get_human_day(date),
|
||||
format_time_24h(date)
|
||||
)
|
||||
return "{} at {} UTC".format(get_human_day(date), format_time_24h(date))
|
||||
|
||||
|
||||
def format_datetime_numeric(date):
|
||||
return '{} {} UTC'.format(
|
||||
return "{} {} UTC".format(
|
||||
format_date_numeric(date),
|
||||
format_time_24h(date),
|
||||
)
|
||||
@@ -78,34 +66,33 @@ def format_datetime_numeric(date):
|
||||
|
||||
def format_date_numeric(date):
|
||||
date = parse_naive_dt(date)
|
||||
return date.strftime('%Y-%m-%d')
|
||||
return date.strftime("%Y-%m-%d")
|
||||
|
||||
|
||||
def format_time_24h(date):
|
||||
date = parse_naive_dt(date)
|
||||
return date.strftime('%H:%M')
|
||||
return date.strftime("%H:%M")
|
||||
|
||||
|
||||
def get_human_day(time, date_prefix=''):
|
||||
|
||||
def get_human_day(time, date_prefix=""):
|
||||
# Add 1 minute to transform 00:00 into ‘midnight today’ instead of ‘midnight tomorrow’
|
||||
time = parse_naive_dt(time)
|
||||
date = (time - timedelta(minutes=1)).date()
|
||||
now = datetime.now(pytz.utc)
|
||||
|
||||
if date == (now + timedelta(days=1)).date():
|
||||
return 'tomorrow'
|
||||
return "tomorrow"
|
||||
if date == now.date():
|
||||
return 'today'
|
||||
return "today"
|
||||
if date == (now - timedelta(days=1)).date():
|
||||
return 'yesterday'
|
||||
if date.strftime('%Y') != now.strftime('%Y'):
|
||||
return '{} {} {}'.format(
|
||||
return "yesterday"
|
||||
if date.strftime("%Y") != now.strftime("%Y"):
|
||||
return "{} {} {}".format(
|
||||
date_prefix,
|
||||
_format_datetime_short(date),
|
||||
date.strftime('%Y'),
|
||||
date.strftime("%Y"),
|
||||
).strip()
|
||||
return '{} {}'.format(
|
||||
return "{} {}".format(
|
||||
date_prefix,
|
||||
_format_datetime_short(date),
|
||||
).strip()
|
||||
@@ -113,12 +100,12 @@ def get_human_day(time, date_prefix=''):
|
||||
|
||||
def format_date(date):
|
||||
date = parse_naive_dt(date)
|
||||
return date.strftime('%A %d %B %Y')
|
||||
return date.strftime("%A %d %B %Y")
|
||||
|
||||
|
||||
def format_date_normal(date):
|
||||
date = parse_naive_dt(date)
|
||||
return date.strftime('%d %B %Y').lstrip('0')
|
||||
return date.strftime("%d %B %Y").lstrip("0")
|
||||
|
||||
|
||||
def format_date_short(date):
|
||||
@@ -130,26 +117,26 @@ def format_date_human(date):
|
||||
return get_human_day(date)
|
||||
|
||||
|
||||
def format_datetime_human(date, date_prefix=''):
|
||||
return '{} at {} UTC'.format(
|
||||
get_human_day(date, date_prefix='on'),
|
||||
def format_datetime_human(date, date_prefix=""):
|
||||
return "{} at {} UTC".format(
|
||||
get_human_day(date, date_prefix="on"),
|
||||
format_time_24h(date),
|
||||
)
|
||||
|
||||
|
||||
def format_day_of_week(date):
|
||||
date = parse_naive_dt(date)
|
||||
return date.strftime('%A')
|
||||
return date.strftime("%A")
|
||||
|
||||
|
||||
def _format_datetime_short(datetime):
|
||||
return datetime.strftime('%d %B').lstrip('0')
|
||||
return datetime.strftime("%d %B").lstrip("0")
|
||||
|
||||
|
||||
def naturaltime_without_indefinite_article(date):
|
||||
return re.sub(
|
||||
'an? (.*) ago',
|
||||
lambda match: '1 {} ago'.format(match.group(1)),
|
||||
"an? (.*) ago",
|
||||
lambda match: "1 {} ago".format(match.group(1)),
|
||||
humanize.naturaltime(date),
|
||||
)
|
||||
|
||||
@@ -157,11 +144,7 @@ def naturaltime_without_indefinite_article(date):
|
||||
def format_delta(date):
|
||||
# This method assumes that date is in UTC
|
||||
date = parse_naive_dt(date)
|
||||
delta = (
|
||||
datetime.utcnow()
|
||||
) - (
|
||||
date
|
||||
)
|
||||
delta = (datetime.utcnow()) - (date)
|
||||
if delta < timedelta(seconds=30):
|
||||
return "just now"
|
||||
if delta < timedelta(seconds=60):
|
||||
@@ -173,9 +156,9 @@ def format_delta_days(date):
|
||||
# This method assumes that date is in UTC
|
||||
date = parse_naive_dt(date)
|
||||
now = datetime.utcnow()
|
||||
if date.strftime('%Y-%m-%d') == now.strftime('%Y-%m-%d'):
|
||||
if date.strftime("%Y-%m-%d") == now.strftime("%Y-%m-%d"):
|
||||
return "today"
|
||||
if date.strftime('%Y-%m-%d') == (now - timedelta(days=1)).strftime('%Y-%m-%d'):
|
||||
if date.strftime("%Y-%m-%d") == (now - timedelta(days=1)).strftime("%Y-%m-%d"):
|
||||
return "yesterday"
|
||||
return naturaltime_without_indefinite_article(now - date)
|
||||
|
||||
@@ -190,80 +173,84 @@ def valid_phone_number(phone_number):
|
||||
|
||||
def format_notification_type(notification_type):
|
||||
return {
|
||||
'email': 'Email',
|
||||
'sms': 'Text message',
|
||||
"email": "Email",
|
||||
"sms": "Text message",
|
||||
}[notification_type]
|
||||
|
||||
|
||||
def format_notification_status(status, template_type):
|
||||
return {
|
||||
'email': {
|
||||
'failed': 'Failed',
|
||||
'technical-failure': 'Technical failure',
|
||||
'temporary-failure': 'Inbox not accepting messages right now',
|
||||
'permanent-failure': 'Email address does not exist',
|
||||
'delivered': 'Delivered',
|
||||
'sending': 'Sending',
|
||||
'created': 'Sending',
|
||||
'sent': 'Delivered'
|
||||
"email": {
|
||||
"failed": "Failed",
|
||||
"technical-failure": "Technical failure",
|
||||
"temporary-failure": "Inbox not accepting messages right now",
|
||||
"permanent-failure": "Email address does not exist",
|
||||
"delivered": "Delivered",
|
||||
"sending": "Sending",
|
||||
"created": "Sending",
|
||||
"sent": "Delivered",
|
||||
},
|
||||
'sms': {
|
||||
'failed': 'Failed',
|
||||
'technical-failure': 'Technical failure',
|
||||
'temporary-failure': 'Phone not accepting messages right now',
|
||||
'permanent-failure': 'Not delivered',
|
||||
'delivered': 'Delivered',
|
||||
'sending': 'Sending',
|
||||
'created': 'Sending',
|
||||
'pending': 'Sending',
|
||||
'sent': 'Sent'
|
||||
"sms": {
|
||||
"failed": "Failed",
|
||||
"technical-failure": "Technical failure",
|
||||
"temporary-failure": "Phone not accepting messages right now",
|
||||
"permanent-failure": "Not delivered",
|
||||
"delivered": "Delivered",
|
||||
"sending": "Sending",
|
||||
"created": "Sending",
|
||||
"pending": "Sending",
|
||||
"sent": "Sent",
|
||||
},
|
||||
}[template_type].get(status, status)
|
||||
|
||||
|
||||
def format_notification_status_as_time(status, created, updated):
|
||||
return dict.fromkeys(
|
||||
{'created', 'pending', 'sending'}, ' since {}'.format(created)
|
||||
{"created", "pending", "sending"}, " since {}".format(created)
|
||||
).get(status, updated)
|
||||
|
||||
|
||||
def format_notification_status_as_field_status(status, notification_type):
|
||||
return {
|
||||
'failed': 'error',
|
||||
'technical-failure': 'error',
|
||||
'temporary-failure': 'error',
|
||||
'permanent-failure': 'error',
|
||||
'delivered': None,
|
||||
'sent': 'sent-international' if notification_type == 'sms' else None,
|
||||
'sending': 'default',
|
||||
'created': 'default',
|
||||
'pending': 'default',
|
||||
}.get(status, 'error')
|
||||
"failed": "error",
|
||||
"technical-failure": "error",
|
||||
"temporary-failure": "error",
|
||||
"permanent-failure": "error",
|
||||
"delivered": None,
|
||||
"sent": "sent-international" if notification_type == "sms" else None,
|
||||
"sending": "default",
|
||||
"created": "default",
|
||||
"pending": "default",
|
||||
}.get(status, "error")
|
||||
|
||||
|
||||
def format_notification_status_as_url(status, notification_type):
|
||||
url = partial(url_for, "main.message_status")
|
||||
|
||||
if status not in {
|
||||
'technical-failure', 'temporary-failure', 'permanent-failure',
|
||||
"technical-failure",
|
||||
"temporary-failure",
|
||||
"permanent-failure",
|
||||
}:
|
||||
return None
|
||||
|
||||
return {
|
||||
'email': url(_anchor='email-statuses'),
|
||||
'sms': url(_anchor='text-message-statuses')
|
||||
"email": url(_anchor="email-statuses"),
|
||||
"sms": url(_anchor="text-message-statuses"),
|
||||
}.get(notification_type)
|
||||
|
||||
|
||||
def nl2br(value):
|
||||
if value:
|
||||
return Markup(Take(Field(
|
||||
value,
|
||||
html='escape',
|
||||
)).then(
|
||||
utils_nl2br
|
||||
))
|
||||
return ''
|
||||
return Markup(
|
||||
Take(
|
||||
Field(
|
||||
value,
|
||||
html="escape",
|
||||
)
|
||||
).then(utils_nl2br)
|
||||
)
|
||||
return ""
|
||||
|
||||
|
||||
# this formatter appears to only be used in the letter module
|
||||
@@ -290,34 +277,37 @@ def linkable_name(value):
|
||||
|
||||
def format_thousands(value):
|
||||
if isinstance(value, Number):
|
||||
return '{:,.0f}'.format(value)
|
||||
return "{:,.0f}".format(value)
|
||||
if value is None:
|
||||
return ''
|
||||
return ""
|
||||
return value
|
||||
|
||||
|
||||
def email_safe(string, whitespace='.'):
|
||||
def email_safe(string, whitespace="."):
|
||||
# strips accents, diacritics etc
|
||||
string = ''.join(c for c in unicodedata.normalize('NFD', string) if unicodedata.category(c) != 'Mn')
|
||||
string = ''.join(
|
||||
word.lower() if word.isalnum() or word == whitespace else ''
|
||||
for word in re.sub(r'\s+', whitespace, string.strip())
|
||||
string = "".join(
|
||||
c
|
||||
for c in unicodedata.normalize("NFD", string)
|
||||
if unicodedata.category(c) != "Mn"
|
||||
)
|
||||
string = re.sub(r'\.{2,}', '.', string)
|
||||
return string.strip('.')
|
||||
string = "".join(
|
||||
word.lower() if word.isalnum() or word == whitespace else ""
|
||||
for word in re.sub(r"\s+", whitespace, string.strip())
|
||||
)
|
||||
string = re.sub(r"\.{2,}", ".", string)
|
||||
return string.strip(".")
|
||||
|
||||
|
||||
def id_safe(string):
|
||||
return email_safe(string, whitespace='-')
|
||||
return email_safe(string, whitespace="-")
|
||||
|
||||
|
||||
def round_to_significant_figures(value, number_of_significant_figures):
|
||||
if value == 0:
|
||||
return value
|
||||
return int(round(
|
||||
value,
|
||||
number_of_significant_figures - int(floor(log10(abs(value)))) - 1
|
||||
))
|
||||
return int(
|
||||
round(value, number_of_significant_figures - int(floor(log10(abs(value)))) - 1)
|
||||
)
|
||||
|
||||
|
||||
def redact_mobile_number(mobile_number, spacing=""):
|
||||
@@ -331,146 +321,132 @@ def redact_mobile_number(mobile_number, spacing=""):
|
||||
|
||||
def get_time_left(created_at, service_data_retention_days=7):
|
||||
return ago.human(
|
||||
(
|
||||
datetime.now(timezone.utc)
|
||||
) - (
|
||||
dateutil.parser.parse(created_at).replace(hour=0, minute=0, second=0) + timedelta(
|
||||
days=service_data_retention_days + 1
|
||||
)
|
||||
(datetime.now(timezone.utc))
|
||||
- (
|
||||
dateutil.parser.parse(created_at).replace(hour=0, minute=0, second=0)
|
||||
+ timedelta(days=service_data_retention_days + 1)
|
||||
),
|
||||
future_tense='Data available for {}',
|
||||
past_tense='Data no longer available', # No-one should ever see this
|
||||
precision=1
|
||||
future_tense="Data available for {}",
|
||||
past_tense="Data no longer available", # No-one should ever see this
|
||||
precision=1,
|
||||
)
|
||||
|
||||
|
||||
def starts_with_initial(name):
|
||||
return bool(re.match(r'^.\.', name))
|
||||
return bool(re.match(r"^.\.", name))
|
||||
|
||||
|
||||
def remove_middle_initial(name):
|
||||
return re.sub(r'\s+.\s+', ' ', name)
|
||||
return re.sub(r"\s+.\s+", " ", name)
|
||||
|
||||
|
||||
def remove_digits(name):
|
||||
return ''.join(c for c in name if not c.isdigit())
|
||||
return "".join(c for c in name if not c.isdigit())
|
||||
|
||||
|
||||
def normalize_spaces(name):
|
||||
return ' '.join(name.split())
|
||||
return " ".join(name.split())
|
||||
|
||||
|
||||
def guess_name_from_email_address(email_address):
|
||||
possible_name = re.split(r"[\@\+]", email_address)[0]
|
||||
|
||||
possible_name = re.split(r'[\@\+]', email_address)[0]
|
||||
if "." not in possible_name or starts_with_initial(possible_name):
|
||||
return ""
|
||||
|
||||
if '.' not in possible_name or starts_with_initial(possible_name):
|
||||
return ''
|
||||
|
||||
return Take(
|
||||
possible_name
|
||||
).then(
|
||||
str.replace, '.', ' '
|
||||
).then(
|
||||
remove_digits
|
||||
).then(
|
||||
remove_middle_initial
|
||||
).then(
|
||||
str.title
|
||||
).then(
|
||||
make_quotes_smart
|
||||
).then(
|
||||
normalize_spaces
|
||||
return (
|
||||
Take(possible_name)
|
||||
.then(str.replace, ".", " ")
|
||||
.then(remove_digits)
|
||||
.then(remove_middle_initial)
|
||||
.then(str.title)
|
||||
.then(make_quotes_smart)
|
||||
.then(normalize_spaces)
|
||||
)
|
||||
|
||||
|
||||
def message_count_label(count, template_type, suffix='sent'):
|
||||
def message_count_label(count, template_type, suffix="sent"):
|
||||
if suffix:
|
||||
return f'{message_count_noun(count, template_type)} {suffix}'
|
||||
return f"{message_count_noun(count, template_type)} {suffix}"
|
||||
return message_count_noun(count, template_type)
|
||||
|
||||
|
||||
def message_count_noun(count, template_type):
|
||||
if template_type is None:
|
||||
if count == 1:
|
||||
return 'message'
|
||||
return "message"
|
||||
else:
|
||||
return 'messages'
|
||||
return "messages"
|
||||
|
||||
if template_type == 'sms':
|
||||
if template_type == "sms":
|
||||
if count == 1:
|
||||
return 'text message'
|
||||
return "text message"
|
||||
else:
|
||||
return 'text messages'
|
||||
return "text messages"
|
||||
|
||||
elif template_type == 'email':
|
||||
elif template_type == "email":
|
||||
if count == 1:
|
||||
return 'email'
|
||||
return "email"
|
||||
else:
|
||||
return 'emails'
|
||||
return "emails"
|
||||
|
||||
|
||||
def message_count(count, template_type):
|
||||
return (
|
||||
f'{format_thousands(count)} '
|
||||
f'{message_count_noun(count, template_type)}'
|
||||
)
|
||||
return f"{format_thousands(count)} " f"{message_count_noun(count, template_type)}"
|
||||
|
||||
|
||||
def recipient_count_label(count, template_type):
|
||||
|
||||
if template_type is None:
|
||||
if count == 1:
|
||||
return 'recipient'
|
||||
return "recipient"
|
||||
else:
|
||||
return 'recipients'
|
||||
return "recipients"
|
||||
|
||||
if template_type == 'sms':
|
||||
if template_type == "sms":
|
||||
if count == 1:
|
||||
return 'phone number'
|
||||
return "phone number"
|
||||
else:
|
||||
return 'phone numbers'
|
||||
return "phone numbers"
|
||||
|
||||
elif template_type == 'email':
|
||||
elif template_type == "email":
|
||||
if count == 1:
|
||||
return 'email address'
|
||||
return "email address"
|
||||
else:
|
||||
return 'email addresses'
|
||||
return "email addresses"
|
||||
|
||||
|
||||
def recipient_count(count, template_type):
|
||||
return (
|
||||
f'{format_thousands(count)} '
|
||||
f'{recipient_count_label(count, template_type)}'
|
||||
f"{format_thousands(count)} " f"{recipient_count_label(count, template_type)}"
|
||||
)
|
||||
|
||||
|
||||
def iteration_count(count):
|
||||
if count == 1:
|
||||
return 'once'
|
||||
return "once"
|
||||
elif count == 2:
|
||||
return 'twice'
|
||||
return "twice"
|
||||
else:
|
||||
return f'{count} times'
|
||||
return f"{count} times"
|
||||
|
||||
|
||||
def character_count(count):
|
||||
if count == 1:
|
||||
return '1 character'
|
||||
return f'{format_thousands(count)} characters'
|
||||
return "1 character"
|
||||
return f"{format_thousands(count)} characters"
|
||||
|
||||
|
||||
def format_mobile_network(network):
|
||||
if network in ('three', 'vodafone', 'o2'):
|
||||
if network in ("three", "vodafone", "o2"):
|
||||
return network.capitalize()
|
||||
return 'EE'
|
||||
return "EE"
|
||||
|
||||
|
||||
def format_billions(count):
|
||||
return humanize.intword(count)
|
||||
|
||||
|
||||
def format_yes_no(value, yes='Yes', no='No', none='No'):
|
||||
def format_yes_no(value, yes="Yes", no="No", none="No"):
|
||||
if value is None:
|
||||
return none
|
||||
return yes if value else no
|
||||
@@ -482,11 +458,11 @@ def square_metres_to_square_miles(area):
|
||||
|
||||
def format_auth_type(auth_type, with_indefinite_article=False):
|
||||
indefinite_article, auth_type = {
|
||||
'email_auth': ('an', 'Email link'),
|
||||
'sms_auth': ('a', 'Text message code'),
|
||||
"email_auth": ("an", "Email link"),
|
||||
"sms_auth": ("a", "Text message code"),
|
||||
}[auth_type]
|
||||
|
||||
if with_indefinite_article:
|
||||
return f'{indefinite_article} {auth_type.lower()}'
|
||||
return f"{indefinite_article} {auth_type.lower()}"
|
||||
|
||||
return auth_type
|
||||
|
||||
Reference in New Issue
Block a user