python: Normalize quotes with Black.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg
2021-02-11 23:20:45 -08:00
committed by Tim Abbott
parent 11741543da
commit 6e4c3e41dc
989 changed files with 32792 additions and 32792 deletions

View File

@@ -59,7 +59,7 @@ _apns_client: Optional["APNsClient"] = None
_apns_client_initialized = False
def get_apns_client() -> 'Optional[APNsClient]':
def get_apns_client() -> "Optional[APNsClient]":
# We lazily do this import as part of optimizing Zulip's base
# import time.
from apns2.client import APNsClient
@@ -83,20 +83,20 @@ def apns_enabled() -> bool:
def modernize_apns_payload(data: Dict[str, Any]) -> Dict[str, Any]:
'''Take a payload in an unknown Zulip version's format, and return in current format.'''
"""Take a payload in an unknown Zulip version's format, and return in current format."""
# TODO this isn't super robust as is -- if a buggy remote server
# sends a malformed payload, we are likely to raise an exception.
if 'message_ids' in data:
if "message_ids" in data:
# The format sent by 1.6.0, from the earliest pre-1.6.0
# version with bouncer support up until 613d093d7 pre-1.7.0:
# 'alert': str, # just sender, and text about PM/group-PM/mention
# 'message_ids': List[int], # always just one
return {
'alert': data['alert'],
'badge': 0,
'custom': {
'zulip': {
'message_ids': data['message_ids'],
"alert": data["alert"],
"badge": 0,
"custom": {
"zulip": {
"message_ids": data["message_ids"],
},
},
}
@@ -188,7 +188,7 @@ def send_apple_push_notification(
# For some reason, "Unregistered" result values have a
# different format, as a tuple of the pair ("Unregistered", 12345132131).
result = result[0]
if result == 'Success':
if result == "Success":
logger.info("APNs: Success sending for user %d to device %s", user_id, device.token)
elif result in ["Unregistered", "BadDeviceToken", "DeviceTokenNotForTopic"]:
logger.info("APNs: Removing invalid/expired token %s (%s)", device.token, result)
@@ -220,7 +220,7 @@ def make_gcm_client() -> gcm.GCM: # nocoverage
# been using (as long as we're happy with it) -- just monkey-patch in
# that one change, because the library's API doesn't anticipate that
# as a customization point.
gcm.gcm.GCM_URL = 'https://fcm.googleapis.com/fcm/send'
gcm.gcm.GCM_URL = "https://fcm.googleapis.com/fcm/send"
return gcm.GCM(settings.ANDROID_GCM_API_KEY)
@@ -259,14 +259,14 @@ def parse_gcm_options(options: Dict[str, Any], data: Dict[str, Any]) -> str:
Returns `priority`.
"""
priority = options.pop('priority', None)
priority = options.pop("priority", None)
if priority is None:
# An older server. Identify if this seems to be an actual notification.
if data.get('event') == 'message':
priority = 'high'
if data.get("event") == "message":
priority = "high"
else: # `'event': 'remove'`, presumably
priority = 'normal'
if priority not in ('normal', 'high'):
priority = "normal"
if priority not in ("normal", "high"):
raise JsonableError(
_(
"Invalid GCM option to bouncer: priority {!r}",
@@ -323,8 +323,8 @@ def send_android_push_notification(
logger.warning("Error while pushing to GCM", exc_info=True)
return
if res and 'success' in res:
for reg_id, msg_id in res['success'].items():
if res and "success" in res:
for reg_id, msg_id in res["success"].items():
logger.info("GCM: Sent %s as %s", reg_id, msg_id)
if remote:
@@ -336,8 +336,8 @@ def send_android_push_notification(
# res.canonical will contain results when there are duplicate registrations for the same
# device. The "canonical" registration is the latest registration made by the device.
# Ref: https://developer.android.com/google/gcm/adv.html#canonical
if 'canonical' in res:
for reg_id, new_reg_id in res['canonical'].items():
if "canonical" in res:
for reg_id, new_reg_id in res["canonical"].items():
if reg_id == new_reg_id:
# I'm not sure if this should happen. In any case, not really actionable.
logger.warning("GCM: Got canonical ref but it already matches our ID %s!", reg_id)
@@ -362,9 +362,9 @@ def send_android_push_notification(
DeviceTokenClass.objects.filter(token=reg_id, kind=DeviceTokenClass.GCM).delete()
if 'errors' in res:
for error, reg_ids in res['errors'].items():
if error in ['NotRegistered', 'InvalidRegistration']:
if "errors" in res:
for error, reg_ids in res["errors"].items():
if error in ["NotRegistered", "InvalidRegistration"]:
for reg_id in reg_ids:
logger.info("GCM: Removing %s", reg_id)
# We remove all entries for this token (There
@@ -396,13 +396,13 @@ def send_notifications_to_bouncer(
gcm_options: Dict[str, Any],
) -> None:
post_data = {
'user_id': user_profile_id,
'apns_payload': apns_payload,
'gcm_payload': gcm_payload,
'gcm_options': gcm_options,
"user_id": user_profile_id,
"apns_payload": apns_payload,
"gcm_payload": gcm_payload,
"gcm_options": gcm_options,
}
# Calls zilencer.views.remote_server_notify_push
send_json_to_push_bouncer('POST', 'push/notify', post_data)
send_json_to_push_bouncer("POST", "push/notify", post_data)
#
@@ -452,18 +452,18 @@ def add_push_device_token(
# register this user with them here
if uses_notification_bouncer():
post_data = {
'server_uuid': settings.ZULIP_ORG_ID,
'user_id': user_profile.id,
'token': token_str,
'token_kind': kind,
"server_uuid": settings.ZULIP_ORG_ID,
"user_id": user_profile.id,
"token": token_str,
"token_kind": kind,
}
if kind == PushDeviceToken.APNS:
post_data['ios_app_id'] = ios_app_id
post_data["ios_app_id"] = ios_app_id
logger.info("Sending new push device to bouncer: %r", post_data)
# Calls zilencer.views.register_remote_push_device
send_to_push_bouncer('POST', 'push/register', post_data)
send_to_push_bouncer("POST", "push/register", post_data)
return token
@@ -486,10 +486,10 @@ def remove_push_device_token(user_profile: UserProfile, token_str: str, kind: in
if uses_notification_bouncer():
# TODO: Make this a remove item
post_data = {
'server_uuid': settings.ZULIP_ORG_ID,
'user_id': user_profile.id,
'token': token_str,
'token_kind': kind,
"server_uuid": settings.ZULIP_ORG_ID,
"user_id": user_profile.id,
"token": token_str,
"token_kind": kind,
}
# Calls zilencer.views.unregister_remote_push_device
send_to_push_bouncer("POST", "push/unregister", post_data)
@@ -499,8 +499,8 @@ def clear_push_device_tokens(user_profile_id: int) -> None:
# Deletes all of a user's PushDeviceTokens.
if uses_notification_bouncer():
post_data = {
'server_uuid': settings.ZULIP_ORG_ID,
'user_id': user_profile_id,
"server_uuid": settings.ZULIP_ORG_ID,
"user_id": user_profile_id,
}
send_to_push_bouncer("POST", "push/unregister/all", post_data)
return
@@ -514,7 +514,7 @@ def clear_push_device_tokens(user_profile_id: int) -> None:
def push_notifications_enabled() -> bool:
'''True just if this server has configured a way to send push notifications.'''
"""True just if this server has configured a way to send push notifications."""
if (
uses_notification_bouncer()
and settings.ZULIP_ORG_KEY is not None
@@ -554,12 +554,12 @@ def get_gcm_alert(message: Message) -> str:
Determine what alert string to display based on the missed messages.
"""
sender_str = message.sender.full_name
if message.recipient.type == Recipient.HUDDLE and message.trigger == 'private_message':
if message.recipient.type == Recipient.HUDDLE and message.trigger == "private_message":
return f"New private group message from {sender_str}"
elif message.recipient.type == Recipient.PERSONAL and message.trigger == 'private_message':
elif message.recipient.type == Recipient.PERSONAL and message.trigger == "private_message":
return f"New private message from {sender_str}"
elif message.is_stream_message() and (
message.trigger == 'mentioned' or message.trigger == 'wildcard_mentioned'
message.trigger == "mentioned" or message.trigger == "wildcard_mentioned"
):
return f"New mention from {sender_str}"
else: # message.is_stream_message() and message.trigger == 'stream_push_notify'
@@ -573,17 +573,17 @@ def get_mobile_push_content(rendered_content: str) -> str:
if "emoji" in classes:
match = re.search(r"emoji-(?P<emoji_code>\S+)", classes)
if match:
emoji_code = match.group('emoji_code')
emoji_code = match.group("emoji_code")
char_repr = ""
for codepoint in emoji_code.split('-'):
for codepoint in emoji_code.split("-"):
char_repr += chr(int(codepoint, 16))
return char_repr
# Handles realm emojis, avatars etc.
if elem.tag == "img":
return elem.get("alt", "")
if elem.tag == 'blockquote':
return '' # To avoid empty line before quote text
return elem.text or ''
if elem.tag == "blockquote":
return "" # To avoid empty line before quote text
return elem.text or ""
def format_as_quote(quote_text: str) -> str:
return "".join(
@@ -592,35 +592,35 @@ def get_mobile_push_content(rendered_content: str) -> str:
def render_olist(ol: lxml.html.HtmlElement) -> str:
items = []
counter = int(ol.get('start')) if ol.get('start') else 1
nested_levels = len(list(ol.iterancestors('ol')))
indent = ('\n' + ' ' * nested_levels) if nested_levels else ''
counter = int(ol.get("start")) if ol.get("start") else 1
nested_levels = len(list(ol.iterancestors("ol")))
indent = ("\n" + " " * nested_levels) if nested_levels else ""
for li in ol:
items.append(indent + str(counter) + '. ' + process(li).strip())
items.append(indent + str(counter) + ". " + process(li).strip())
counter += 1
return '\n'.join(items)
return "\n".join(items)
def render_spoiler(elem: lxml.html.HtmlElement) -> str:
header = elem.find_class('spoiler-header')[0]
header = elem.find_class("spoiler-header")[0]
text = process(header).strip()
if len(text) == 0:
return "(…)\n"
return f"{text} (…)\n"
def process(elem: lxml.html.HtmlElement) -> str:
plain_text = ''
if elem.tag == 'ol':
plain_text = ""
if elem.tag == "ol":
plain_text = render_olist(elem)
elif 'spoiler-block' in elem.get("class", ""):
elif "spoiler-block" in elem.get("class", ""):
plain_text += render_spoiler(elem)
else:
plain_text = get_text(elem)
sub_text = ''
sub_text = ""
for child in elem:
sub_text += process(child)
if elem.tag == 'blockquote':
if elem.tag == "blockquote":
sub_text = format_as_quote(sub_text)
plain_text += sub_text
plain_text += elem.tail or ""
@@ -645,35 +645,35 @@ def truncate_content(content: str) -> Tuple[str, bool]:
def get_base_payload(user_profile: UserProfile) -> Dict[str, Any]:
'''Common fields for all notification payloads.'''
"""Common fields for all notification payloads."""
data: Dict[str, Any] = {}
# These will let the app support logging into multiple realms and servers.
data['server'] = settings.EXTERNAL_HOST
data['realm_id'] = user_profile.realm.id
data['realm_uri'] = user_profile.realm.uri
data['user_id'] = user_profile.id
data["server"] = settings.EXTERNAL_HOST
data["realm_id"] = user_profile.realm.id
data["realm_uri"] = user_profile.realm.uri
data["user_id"] = user_profile.id
return data
def get_message_payload(user_profile: UserProfile, message: Message) -> Dict[str, Any]:
'''Common fields for `message` payloads, for all platforms.'''
"""Common fields for `message` payloads, for all platforms."""
data = get_base_payload(user_profile)
# `sender_id` is preferred, but some existing versions use `sender_email`.
data['sender_id'] = message.sender.id
data['sender_email'] = message.sender.email
data["sender_id"] = message.sender.id
data["sender_email"] = message.sender.email
if message.recipient.type == Recipient.STREAM:
data['recipient_type'] = "stream"
data['stream'] = get_display_recipient(message.recipient)
data['topic'] = message.topic_name()
data["recipient_type"] = "stream"
data["stream"] = get_display_recipient(message.recipient)
data["topic"] = message.topic_name()
elif message.recipient.type == Recipient.HUDDLE:
data['recipient_type'] = "private"
data['pm_users'] = huddle_users(message.recipient.id)
data["recipient_type"] = "private"
data["pm_users"] = huddle_users(message.recipient.id)
else: # Recipient.PERSONAL
data['recipient_type'] = "private"
data["recipient_type"] = "private"
return data
@@ -685,7 +685,7 @@ def get_apns_alert_title(message: Message) -> str:
if message.recipient.type == Recipient.HUDDLE:
recipients = get_display_recipient(message.recipient)
assert isinstance(recipients, list)
return ', '.join(sorted(r['full_name'] for r in recipients))
return ", ".join(sorted(r["full_name"] for r in recipients))
elif message.is_stream_message():
return f"#{get_display_recipient(message.recipient)} > {message.topic_name()}"
# For personal PMs, we just show the sender name.
@@ -735,7 +735,7 @@ def get_apns_badge_count_future(
def get_message_payload_apns(user_profile: UserProfile, message: Message) -> Dict[str, Any]:
'''A `message` payload for iOS, via APNs.'''
"""A `message` payload for iOS, via APNs."""
zulip_data = get_message_payload(user_profile, message)
zulip_data.update(
message_ids=[message.id],
@@ -744,14 +744,14 @@ def get_message_payload_apns(user_profile: UserProfile, message: Message) -> Dic
assert message.rendered_content is not None
content, _ = truncate_content(get_mobile_push_content(message.rendered_content))
apns_data = {
'alert': {
'title': get_apns_alert_title(message),
'subtitle': get_apns_alert_subtitle(message),
'body': content,
"alert": {
"title": get_apns_alert_title(message),
"subtitle": get_apns_alert_subtitle(message),
"body": content,
},
'sound': 'default',
'badge': get_apns_badge_count(user_profile),
'custom': {'zulip': zulip_data},
"sound": "default",
"badge": get_apns_badge_count(user_profile),
"custom": {"zulip": zulip_data},
}
return apns_data
@@ -760,12 +760,12 @@ def get_message_payload_gcm(
user_profile: UserProfile,
message: Message,
) -> Tuple[Dict[str, Any], Dict[str, Any]]:
'''A `message` payload + options, for Android via GCM/FCM.'''
"""A `message` payload + options, for Android via GCM/FCM."""
data = get_message_payload(user_profile, message)
assert message.rendered_content is not None
content, truncated = truncate_content(get_mobile_push_content(message.rendered_content))
data.update(
event='message',
event="message",
alert=get_gcm_alert(message),
zulip_message_id=message.id, # message_id is reserved for CCS
time=datetime_to_timestamp(message.date_sent),
@@ -774,7 +774,7 @@ def get_message_payload_gcm(
sender_full_name=message.sender.full_name,
sender_avatar_url=absolute_avatar_url(message.sender),
)
gcm_options = {'priority': 'high'}
gcm_options = {"priority": "high"}
return data, gcm_options
@@ -782,28 +782,28 @@ def get_remove_payload_gcm(
user_profile: UserProfile,
message_ids: List[int],
) -> Tuple[Dict[str, Any], Dict[str, Any]]:
'''A `remove` payload + options, for Android via GCM/FCM.'''
"""A `remove` payload + options, for Android via GCM/FCM."""
gcm_payload = get_base_payload(user_profile)
gcm_payload.update(
event='remove',
zulip_message_ids=','.join(str(id) for id in message_ids),
event="remove",
zulip_message_ids=",".join(str(id) for id in message_ids),
# Older clients (all clients older than 2019-02-13) look only at
# `zulip_message_id` and ignore `zulip_message_ids`. Do our best.
zulip_message_id=message_ids[0],
)
gcm_options = {'priority': 'normal'}
gcm_options = {"priority": "normal"}
return gcm_payload, gcm_options
def get_remove_payload_apns(user_profile: UserProfile, message_ids: List[int]) -> Dict[str, Any]:
zulip_data = get_base_payload(user_profile)
zulip_data.update(
event='remove',
zulip_message_ids=','.join(str(id) for id in message_ids),
event="remove",
zulip_message_ids=",".join(str(id) for id in message_ids),
)
apns_data = {
'badge': get_apns_badge_count(user_profile, message_ids),
'custom': {'zulip': zulip_data},
"badge": get_apns_badge_count(user_profile, message_ids),
"custom": {"zulip": zulip_data},
}
return apns_data
@@ -836,7 +836,7 @@ def handle_remove_push_notification(user_profile_id: int, message_ids: List[int]
UserMessage.objects.filter(
user_profile_id=user_profile_id,
message_id__in=message_ids,
).update(flags=F('flags').bitand(~UserMessage.flags.active_mobile_push_notification))
).update(flags=F("flags").bitand(~UserMessage.flags.active_mobile_push_notification))
@statsd_increment("push_notifications")
@@ -855,16 +855,16 @@ def handle_push_notification(user_profile_id: int, missed_message: Dict[str, Any
return
try:
(message, user_message) = access_message(user_profile, missed_message['message_id'])
(message, user_message) = access_message(user_profile, missed_message["message_id"])
except JsonableError:
if ArchivedMessage.objects.filter(id=missed_message['message_id']).exists():
if ArchivedMessage.objects.filter(id=missed_message["message_id"]).exists():
# If the cause is a race with the message being deleted,
# that's normal and we have no need to log an error.
return
logging.info(
"Unexpected message access failure handling push notifications: %s %s",
user_profile.id,
missed_message['message_id'],
missed_message["message_id"],
)
return
@@ -889,12 +889,12 @@ def handle_push_notification(user_profile_id: int, missed_message: Dict[str, Any
if not user_profile.long_term_idle:
logger.error(
"Could not find UserMessage with message_id %s and user_id %s",
missed_message['message_id'],
missed_message["message_id"],
user_profile_id,
)
return
message.trigger = missed_message['trigger']
message.trigger = missed_message["trigger"]
apns_payload = get_message_payload_apns(user_profile, message)
gcm_payload, gcm_options = get_message_payload_gcm(user_profile, message)