mirror of https://github.com/zulip/zulip.git
python: Convert percent formatting to .format for translated strings.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
eda396376c
commit
f364d06fb5
|
@ -243,7 +243,7 @@ def get_chart_data(request: HttpRequest, user_profile: UserProfile, chart_name:
|
||||||
labels_sort_function = None
|
labels_sort_function = None
|
||||||
include_empty_subgroups = True
|
include_empty_subgroups = True
|
||||||
else:
|
else:
|
||||||
raise JsonableError(_("Unknown chart name: %s") % (chart_name,))
|
raise JsonableError(_("Unknown chart name: {}").format(chart_name))
|
||||||
|
|
||||||
# Most likely someone using our API endpoint. The /stats page does not
|
# Most likely someone using our API endpoint. The /stats page does not
|
||||||
# pass a start or end in its requests.
|
# pass a start or end in its requests.
|
||||||
|
@ -252,8 +252,9 @@ def get_chart_data(request: HttpRequest, user_profile: UserProfile, chart_name:
|
||||||
if end is not None:
|
if end is not None:
|
||||||
end = convert_to_UTC(end)
|
end = convert_to_UTC(end)
|
||||||
if start is not None and end is not None and start > end:
|
if start is not None and end is not None and start > end:
|
||||||
raise JsonableError(_("Start time is later than end time. Start: %(start)s, End: %(end)s") %
|
raise JsonableError(_("Start time is later than end time. Start: {start}, End: {end}").format(
|
||||||
{'start': start, 'end': end})
|
start=start, end=end,
|
||||||
|
))
|
||||||
|
|
||||||
if realm is None:
|
if realm is None:
|
||||||
# Note that this value is invalid for Remote tables; be
|
# Note that this value is invalid for Remote tables; be
|
||||||
|
|
|
@ -135,7 +135,9 @@ def renewal_amount(plan: CustomerPlan, event_time: datetime) -> int: # nocovera
|
||||||
|
|
||||||
class BillingError(Exception):
|
class BillingError(Exception):
|
||||||
# error messages
|
# error messages
|
||||||
CONTACT_SUPPORT = _("Something went wrong. Please contact %s.") % (settings.ZULIP_ADMINISTRATOR,)
|
CONTACT_SUPPORT = _("Something went wrong. Please contact {email}.").format(
|
||||||
|
email=settings.ZULIP_ADMINISTRATOR,
|
||||||
|
)
|
||||||
TRY_RELOADING = _("Something went wrong. Please reload the page.")
|
TRY_RELOADING = _("Something went wrong. Please reload the page.")
|
||||||
|
|
||||||
# description is used only for tests
|
# description is used only for tests
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from typing import Any, Dict, Optional, Union, cast
|
from typing import Any, Dict, Optional, Union
|
||||||
|
|
||||||
import stripe
|
import stripe
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -85,14 +85,17 @@ def payment_method_string(stripe_customer: stripe.Customer) -> str:
|
||||||
if stripe_source is None: # nocoverage
|
if stripe_source is None: # nocoverage
|
||||||
return _("No payment method on file")
|
return _("No payment method on file")
|
||||||
if stripe_source.object == "card":
|
if stripe_source.object == "card":
|
||||||
return _("%(brand)s ending in %(last4)s") % {
|
assert isinstance(stripe_source, stripe.Card)
|
||||||
'brand': cast(stripe.Card, stripe_source).brand,
|
return _("{brand} ending in {last4}").format(
|
||||||
'last4': cast(stripe.Card, stripe_source).last4}
|
brand=stripe_source.brand, last4=stripe_source.last4,
|
||||||
|
)
|
||||||
# There might be one-off stuff we do for a particular customer that
|
# There might be one-off stuff we do for a particular customer that
|
||||||
# would land them here. E.g. by default we don't support ACH for
|
# would land them here. E.g. by default we don't support ACH for
|
||||||
# automatic payments, but in theory we could add it for a customer via
|
# automatic payments, but in theory we could add it for a customer via
|
||||||
# the Stripe dashboard.
|
# the Stripe dashboard.
|
||||||
return _("Unknown payment method. Please contact %s.") % (settings.ZULIP_ADMINISTRATOR,) # nocoverage
|
return _("Unknown payment method. Please contact {email}.").format(
|
||||||
|
email=settings.ZULIP_ADMINISTRATOR,
|
||||||
|
) # nocoverage
|
||||||
|
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def upgrade(request: HttpRequest, user: UserProfile,
|
def upgrade(request: HttpRequest, user: UserProfile,
|
||||||
|
|
|
@ -171,7 +171,7 @@ SPLIT_BOUNDARY_REGEX = re.compile(fr'[{SPLIT_BOUNDARY}]')
|
||||||
|
|
||||||
# Regexes which check capitalization in sentences.
|
# Regexes which check capitalization in sentences.
|
||||||
DISALLOWED_REGEXES = [re.compile(regex) for regex in [
|
DISALLOWED_REGEXES = [re.compile(regex) for regex in [
|
||||||
r'^[a-z]', # Checks if the sentence starts with a lower case character.
|
r'^[a-z](?!\})', # Checks if the sentence starts with a lower case character.
|
||||||
r'^[A-Z][a-z]+[\sa-z0-9]+[A-Z]', # Checks if an upper case character exists
|
r'^[A-Z][a-z]+[\sa-z0-9]+[A-Z]', # Checks if an upper case character exists
|
||||||
# after a lower case character when the first character is in upper case.
|
# after a lower case character when the first character is in upper case.
|
||||||
]]
|
]]
|
||||||
|
|
|
@ -81,6 +81,14 @@ rules:
|
||||||
severity: ERROR
|
severity: ERROR
|
||||||
message: "Do not write a SQL injection vulnerability please"
|
message: "Do not write a SQL injection vulnerability please"
|
||||||
|
|
||||||
|
- id: translated-format
|
||||||
|
languages: [python]
|
||||||
|
pattern-either:
|
||||||
|
- pattern: django.utils.translation.ugettext(... .format(...))
|
||||||
|
- pattern: django.utils.translation.ugettext(f"...")
|
||||||
|
severity: ERROR
|
||||||
|
message: "Format strings after translation, not before"
|
||||||
|
|
||||||
- id: mutable-default-type
|
- id: mutable-default-type
|
||||||
languages: [python]
|
languages: [python]
|
||||||
pattern-either:
|
pattern-either:
|
||||||
|
@ -122,5 +130,6 @@ rules:
|
||||||
pattern-either:
|
pattern-either:
|
||||||
- pattern: '"..." % ...'
|
- pattern: '"..." % ...'
|
||||||
- pattern: '("...") % ...'
|
- pattern: '("...") % ...'
|
||||||
|
- pattern: django.utils.translation.ugettext(...) % ...
|
||||||
severity: ERROR
|
severity: ERROR
|
||||||
message: "Prefer f-strings or .format for string formatting"
|
message: "Prefer f-strings or .format for string formatting"
|
||||||
|
|
|
@ -1948,7 +1948,7 @@ def validate_recipient_user_profiles(user_profiles: Sequence[UserProfile],
|
||||||
for user_profile in user_profiles:
|
for user_profile in user_profiles:
|
||||||
if (not user_profile.is_active and not user_profile.is_mirror_dummy and
|
if (not user_profile.is_active and not user_profile.is_mirror_dummy and
|
||||||
not allow_deactivated) or user_profile.realm.deactivated:
|
not allow_deactivated) or user_profile.realm.deactivated:
|
||||||
raise ValidationError(_("'%s' is no longer using Zulip.") % (user_profile.email,))
|
raise ValidationError(_("'{email}' is no longer using Zulip.").format(email=user_profile.email))
|
||||||
recipient_profiles_map[user_profile.id] = user_profile
|
recipient_profiles_map[user_profile.id] = user_profile
|
||||||
if not is_cross_realm_bot_email(user_profile.email):
|
if not is_cross_realm_bot_email(user_profile.email):
|
||||||
realms.add(user_profile.realm_id)
|
realms.add(user_profile.realm_id)
|
||||||
|
@ -2132,14 +2132,16 @@ def check_schedule_message(sender: UserProfile, client: Client,
|
||||||
|
|
||||||
def check_default_stream_group_name(group_name: str) -> None:
|
def check_default_stream_group_name(group_name: str) -> None:
|
||||||
if group_name.strip() == "":
|
if group_name.strip() == "":
|
||||||
raise JsonableError(_("Invalid default stream group name '%s'") % (group_name,))
|
raise JsonableError(_("Invalid default stream group name '{}'").format(group_name))
|
||||||
if len(group_name) > DefaultStreamGroup.MAX_NAME_LENGTH:
|
if len(group_name) > DefaultStreamGroup.MAX_NAME_LENGTH:
|
||||||
raise JsonableError(_("Default stream group name too long (limit: %s characters)")
|
raise JsonableError(_("Default stream group name too long (limit: {} characters)").format(
|
||||||
% (DefaultStreamGroup.MAX_NAME_LENGTH,))
|
DefaultStreamGroup.MAX_NAME_LENGTH,
|
||||||
|
))
|
||||||
for i in group_name:
|
for i in group_name:
|
||||||
if ord(i) == 0:
|
if ord(i) == 0:
|
||||||
raise JsonableError(_("Default stream group name '%s' contains NULL (0x00) characters.")
|
raise JsonableError(_("Default stream group name '{}' contains NULL (0x00) characters.").format(
|
||||||
% (group_name,))
|
group_name,
|
||||||
|
))
|
||||||
|
|
||||||
def send_rate_limited_pm_notification_to_bot_owner(sender: UserProfile,
|
def send_rate_limited_pm_notification_to_bot_owner(sender: UserProfile,
|
||||||
realm: Realm,
|
realm: Realm,
|
||||||
|
@ -2194,19 +2196,19 @@ def send_pm_if_empty_stream(stream: Optional[Stream],
|
||||||
}
|
}
|
||||||
if stream is None:
|
if stream is None:
|
||||||
if stream_id is not None:
|
if stream_id is not None:
|
||||||
content = _("Your bot `%(bot_identity)s` tried to send a message to stream ID "
|
content = _("Your bot `{bot_identity}` tried to send a message to stream ID "
|
||||||
"%(stream_id)s, but there is no stream with that ID.") % arg_dict
|
"{stream_id}, but there is no stream with that ID.").format(**arg_dict)
|
||||||
else:
|
else:
|
||||||
assert(stream_name is not None)
|
assert(stream_name is not None)
|
||||||
content = _("Your bot `%(bot_identity)s` tried to send a message to stream "
|
content = _("Your bot `{bot_identity}` tried to send a message to stream "
|
||||||
"#**%(stream_name)s**, but that stream does not exist. "
|
"#**{stream_name}**, but that stream does not exist. "
|
||||||
"Click [here](#streams/new) to create it.") % arg_dict
|
"Click [here](#streams/new) to create it.").format(**arg_dict)
|
||||||
else:
|
else:
|
||||||
if num_subscribers_for_stream_id(stream.id) > 0:
|
if num_subscribers_for_stream_id(stream.id) > 0:
|
||||||
return
|
return
|
||||||
content = _("Your bot `%(bot_identity)s` tried to send a message to "
|
content = _("Your bot `{bot_identity}` tried to send a message to "
|
||||||
"stream #**%(stream_name)s**. The stream exists but "
|
"stream #**{stream_name}**. The stream exists but "
|
||||||
"does not have any subscribers.") % arg_dict
|
"does not have any subscribers.").format(**arg_dict)
|
||||||
|
|
||||||
send_rate_limited_pm_notification_to_bot_owner(sender, realm, content)
|
send_rate_limited_pm_notification_to_bot_owner(sender, realm, content)
|
||||||
|
|
||||||
|
@ -2349,7 +2351,9 @@ def check_message(sender: UserProfile, client: Client, addressee: Addressee,
|
||||||
|
|
||||||
error_msg = check_widget_content(widget_content)
|
error_msg = check_widget_content(widget_content)
|
||||||
if error_msg:
|
if error_msg:
|
||||||
raise JsonableError(_('Widgets: %s') % (error_msg,))
|
raise JsonableError(_('Widgets: {error_msg}').format(
|
||||||
|
error_msg=error_msg,
|
||||||
|
))
|
||||||
|
|
||||||
return {'message': message, 'stream': stream, 'local_id': local_id,
|
return {'message': message, 'stream': stream, 'local_id': local_id,
|
||||||
'sender_queue_id': sender_queue_id, 'realm': realm,
|
'sender_queue_id': sender_queue_id, 'realm': realm,
|
||||||
|
@ -3583,12 +3587,13 @@ def do_rename_stream(stream: Stream,
|
||||||
sender,
|
sender,
|
||||||
stream,
|
stream,
|
||||||
Realm.STREAM_EVENTS_NOTIFICATION_TOPIC,
|
Realm.STREAM_EVENTS_NOTIFICATION_TOPIC,
|
||||||
_('@_**%(user_name)s|%(user_id)d** renamed stream **%(old_stream_name)s** to '
|
_('@_**{user_name}|{user_id}** renamed stream **{old_stream_name}** to '
|
||||||
'**%(new_stream_name)s**.') % {
|
'**{new_stream_name}**.').format(
|
||||||
'user_name': user_profile.full_name,
|
user_name=user_profile.full_name,
|
||||||
'user_id': user_profile.id,
|
user_id=user_profile.id,
|
||||||
'old_stream_name': old_name,
|
old_stream_name=old_name,
|
||||||
'new_stream_name': new_name},
|
new_stream_name=new_name,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
# Even though the token doesn't change, the web client needs to update the
|
# Even though the token doesn't change, the web client needs to update the
|
||||||
# email forwarding address to display the correctly-escaped new name.
|
# email forwarding address to display the correctly-escaped new name.
|
||||||
|
@ -3734,7 +3739,7 @@ def lookup_default_stream_groups(default_stream_group_names: List[str],
|
||||||
default_stream_group = DefaultStreamGroup.objects.get(
|
default_stream_group = DefaultStreamGroup.objects.get(
|
||||||
name=group_name, realm=realm)
|
name=group_name, realm=realm)
|
||||||
except DefaultStreamGroup.DoesNotExist:
|
except DefaultStreamGroup.DoesNotExist:
|
||||||
raise JsonableError(_('Invalid default stream group %s') % (group_name,))
|
raise JsonableError(_('Invalid default stream group {}').format(group_name))
|
||||||
default_stream_groups.append(default_stream_group)
|
default_stream_groups.append(default_stream_group)
|
||||||
return default_stream_groups
|
return default_stream_groups
|
||||||
|
|
||||||
|
@ -3771,15 +3776,16 @@ def do_create_default_stream_group(realm: Realm, group_name: str,
|
||||||
for stream in streams:
|
for stream in streams:
|
||||||
if stream in default_streams:
|
if stream in default_streams:
|
||||||
raise JsonableError(_(
|
raise JsonableError(_(
|
||||||
"'%(stream_name)s' is a default stream and cannot be added to '%(group_name)s'")
|
"'{stream_name}' is a default stream and cannot be added to '{group_name}'",
|
||||||
% {'stream_name': stream.name, 'group_name': group_name})
|
).format(stream_name=stream.name, group_name=group_name))
|
||||||
|
|
||||||
check_default_stream_group_name(group_name)
|
check_default_stream_group_name(group_name)
|
||||||
(group, created) = DefaultStreamGroup.objects.get_or_create(
|
(group, created) = DefaultStreamGroup.objects.get_or_create(
|
||||||
name=group_name, realm=realm, description=description)
|
name=group_name, realm=realm, description=description)
|
||||||
if not created:
|
if not created:
|
||||||
raise JsonableError(_("Default stream group '%(group_name)s' already exists")
|
raise JsonableError(_(
|
||||||
% {'group_name': group_name})
|
"Default stream group '{group_name}' already exists",
|
||||||
|
).format(group_name=group_name))
|
||||||
|
|
||||||
group.streams.set(streams)
|
group.streams.set(streams)
|
||||||
notify_default_stream_groups(realm)
|
notify_default_stream_groups(realm)
|
||||||
|
@ -3790,12 +3796,12 @@ def do_add_streams_to_default_stream_group(realm: Realm, group: DefaultStreamGro
|
||||||
for stream in streams:
|
for stream in streams:
|
||||||
if stream in default_streams:
|
if stream in default_streams:
|
||||||
raise JsonableError(_(
|
raise JsonableError(_(
|
||||||
"'%(stream_name)s' is a default stream and cannot be added to '%(group_name)s'")
|
"'{stream_name}' is a default stream and cannot be added to '{group_name}'",
|
||||||
% {'stream_name': stream.name, 'group_name': group.name})
|
).format(stream_name=stream.name, group_name=group.name))
|
||||||
if stream in group.streams.all():
|
if stream in group.streams.all():
|
||||||
raise JsonableError(_(
|
raise JsonableError(_(
|
||||||
"Stream '%(stream_name)s' is already present in default stream group '%(group_name)s'")
|
"Stream '{stream_name}' is already present in default stream group '{group_name}'",
|
||||||
% {'stream_name': stream.name, 'group_name': group.name})
|
).format(stream_name=stream.name, group_name=group.name))
|
||||||
group.streams.add(stream)
|
group.streams.add(stream)
|
||||||
|
|
||||||
group.save()
|
group.save()
|
||||||
|
@ -3806,8 +3812,8 @@ def do_remove_streams_from_default_stream_group(realm: Realm, group: DefaultStre
|
||||||
for stream in streams:
|
for stream in streams:
|
||||||
if stream not in group.streams.all():
|
if stream not in group.streams.all():
|
||||||
raise JsonableError(_(
|
raise JsonableError(_(
|
||||||
"Stream '%(stream_name)s' is not present in default stream group '%(group_name)s'")
|
"Stream '{stream_name}' is not present in default stream group '{group_name}'",
|
||||||
% {'stream_name': stream.name, 'group_name': group.name})
|
).format(stream_name=stream.name, group_name=group.name))
|
||||||
group.streams.remove(stream)
|
group.streams.remove(stream)
|
||||||
|
|
||||||
group.save()
|
group.save()
|
||||||
|
@ -3816,10 +3822,10 @@ def do_remove_streams_from_default_stream_group(realm: Realm, group: DefaultStre
|
||||||
def do_change_default_stream_group_name(realm: Realm, group: DefaultStreamGroup,
|
def do_change_default_stream_group_name(realm: Realm, group: DefaultStreamGroup,
|
||||||
new_group_name: str) -> None:
|
new_group_name: str) -> None:
|
||||||
if group.name == new_group_name:
|
if group.name == new_group_name:
|
||||||
raise JsonableError(_("This default stream group is already named '%s'") % (new_group_name,))
|
raise JsonableError(_("This default stream group is already named '{}'").format(new_group_name))
|
||||||
|
|
||||||
if DefaultStreamGroup.objects.filter(name=new_group_name, realm=realm).exists():
|
if DefaultStreamGroup.objects.filter(name=new_group_name, realm=realm).exists():
|
||||||
raise JsonableError(_("Default stream group '%s' already exists") % (new_group_name,))
|
raise JsonableError(_("Default stream group '{}' already exists").format(new_group_name))
|
||||||
|
|
||||||
group.name = new_group_name
|
group.name = new_group_name
|
||||||
group.save()
|
group.save()
|
||||||
|
@ -4172,9 +4178,9 @@ def do_update_message_flags(user_profile: UserProfile,
|
||||||
valid_flags = [item for item in UserMessage.flags
|
valid_flags = [item for item in UserMessage.flags
|
||||||
if item not in UserMessage.NON_API_FLAGS]
|
if item not in UserMessage.NON_API_FLAGS]
|
||||||
if flag not in valid_flags:
|
if flag not in valid_flags:
|
||||||
raise JsonableError(_("Invalid flag: '%s'") % (flag,))
|
raise JsonableError(_("Invalid flag: '{}'").format(flag))
|
||||||
if flag in UserMessage.NON_EDITABLE_FLAGS:
|
if flag in UserMessage.NON_EDITABLE_FLAGS:
|
||||||
raise JsonableError(_("Flag not editable: '%s'") % (flag,))
|
raise JsonableError(_("Flag not editable: '{}'").format(flag))
|
||||||
flagattr = getattr(UserMessage.flags, flag)
|
flagattr = getattr(UserMessage.flags, flag)
|
||||||
|
|
||||||
msgs = UserMessage.objects.filter(user_profile=user_profile,
|
msgs = UserMessage.objects.filter(user_profile=user_profile,
|
||||||
|
@ -4250,15 +4256,19 @@ def notify_topic_moved_streams(user_profile: UserProfile,
|
||||||
if send_notification_to_new_thread:
|
if send_notification_to_new_thread:
|
||||||
internal_send_stream_message(
|
internal_send_stream_message(
|
||||||
new_stream.realm, sender, new_stream, new_topic,
|
new_stream.realm, sender, new_stream, new_topic,
|
||||||
_("This topic was moved here from %(old_location)s by %(user)s")
|
_("This topic was moved here from {old_location} by {user}").format(
|
||||||
% dict(old_location=old_topic_link, user=user_mention))
|
old_location=old_topic_link, user=user_mention,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
if send_notification_to_old_thread:
|
if send_notification_to_old_thread:
|
||||||
# Send a notification to the old stream that the topic was moved.
|
# Send a notification to the old stream that the topic was moved.
|
||||||
internal_send_stream_message(
|
internal_send_stream_message(
|
||||||
old_stream.realm, sender, old_stream, old_topic,
|
old_stream.realm, sender, old_stream, old_topic,
|
||||||
_("This topic was moved by %(user)s to %(new_location)s")
|
_("This topic was moved by {user} to {new_location}").format(
|
||||||
% dict(user=user_mention, new_location=new_topic_link))
|
user=user_mention, new_location=new_topic_link,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
def get_user_info_for_message_updates(message_id: int) -> MessageUpdateUserInfoResult:
|
def get_user_info_for_message_updates(message_id: int) -> MessageUpdateUserInfoResult:
|
||||||
|
|
||||||
|
@ -4992,8 +5002,8 @@ def estimate_recent_invites(realms: Iterable[Realm], *, days: int) -> int:
|
||||||
def check_invite_limit(realm: Realm, num_invitees: int) -> None:
|
def check_invite_limit(realm: Realm, num_invitees: int) -> None:
|
||||||
'''Discourage using invitation emails as a vector for carrying spam.'''
|
'''Discourage using invitation emails as a vector for carrying spam.'''
|
||||||
msg = _("You do not have enough remaining invites. "
|
msg = _("You do not have enough remaining invites. "
|
||||||
"Please contact %s to have your limit raised. "
|
"Please contact {email} to have your limit raised. "
|
||||||
"No invitations were sent.") % (settings.ZULIP_ADMINISTRATOR,)
|
"No invitations were sent.").format(email=settings.ZULIP_ADMINISTRATOR)
|
||||||
if not settings.OPEN_REALM_CREATION:
|
if not settings.OPEN_REALM_CREATION:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -5617,7 +5627,7 @@ def check_add_user_group(realm: Realm, name: str, initial_members: List[UserProf
|
||||||
user_group = create_user_group(name, initial_members, realm, description=description)
|
user_group = create_user_group(name, initial_members, realm, description=description)
|
||||||
do_send_create_user_group_event(user_group, initial_members)
|
do_send_create_user_group_event(user_group, initial_members)
|
||||||
except django.db.utils.IntegrityError:
|
except django.db.utils.IntegrityError:
|
||||||
raise JsonableError(_("User group '%s' already exists.") % (name,))
|
raise JsonableError(_("User group '{}' already exists.").format(name))
|
||||||
|
|
||||||
def do_send_user_group_update_event(user_group: UserGroup, data: Dict[str, Any]) -> None:
|
def do_send_user_group_update_event(user_group: UserGroup, data: Dict[str, Any]) -> None:
|
||||||
event = dict(type="user_group", op='update', group_id=user_group.id, data=data)
|
event = dict(type="user_group", op='update', group_id=user_group.id, data=data)
|
||||||
|
@ -5628,7 +5638,7 @@ def do_update_user_group_name(user_group: UserGroup, name: str) -> None:
|
||||||
user_group.name = name
|
user_group.name = name
|
||||||
user_group.save(update_fields=['name'])
|
user_group.save(update_fields=['name'])
|
||||||
except django.db.utils.IntegrityError:
|
except django.db.utils.IntegrityError:
|
||||||
raise JsonableError(_("User group '%s' already exists.") % (name,))
|
raise JsonableError(_("User group '{}' already exists.").format(name))
|
||||||
do_send_user_group_update_event(user_group, dict(name=name))
|
do_send_user_group_update_event(user_group, dict(name=name))
|
||||||
|
|
||||||
def do_update_user_group_description(user_group: UserGroup, description: str) -> None:
|
def do_update_user_group_description(user_group: UserGroup, description: str) -> None:
|
||||||
|
|
|
@ -18,7 +18,7 @@ def get_user_profiles(emails: Iterable[str], realm: Realm) -> List[UserProfile]:
|
||||||
try:
|
try:
|
||||||
user_profile = get_user_including_cross_realm(email, realm)
|
user_profile = get_user_including_cross_realm(email, realm)
|
||||||
except UserProfile.DoesNotExist:
|
except UserProfile.DoesNotExist:
|
||||||
raise JsonableError(_("Invalid email '%s'") % (email,))
|
raise JsonableError(_("Invalid email '{}'").format(email))
|
||||||
user_profiles.append(user_profile)
|
user_profiles.append(user_profile)
|
||||||
return user_profiles
|
return user_profiles
|
||||||
|
|
||||||
|
|
|
@ -174,7 +174,7 @@ def get_existing_user_errors(
|
||||||
|
|
||||||
if existing_user_profile.is_active:
|
if existing_user_profile.is_active:
|
||||||
if verbose:
|
if verbose:
|
||||||
msg = _('%s already has an account') % (email,)
|
msg = _('{email} already has an account').format(email=email)
|
||||||
else:
|
else:
|
||||||
msg = _("Already has an account.")
|
msg = _("Already has an account.")
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -52,7 +52,7 @@ def emoji_name_to_emoji_code(realm: Realm, emoji_name: str) -> Tuple[str, str]:
|
||||||
return emoji_name, Reaction.ZULIP_EXTRA_EMOJI
|
return emoji_name, Reaction.ZULIP_EXTRA_EMOJI
|
||||||
if emoji_name in name_to_codepoint:
|
if emoji_name in name_to_codepoint:
|
||||||
return name_to_codepoint[emoji_name], Reaction.UNICODE_EMOJI
|
return name_to_codepoint[emoji_name], Reaction.UNICODE_EMOJI
|
||||||
raise JsonableError(_("Emoji '%s' does not exist") % (emoji_name,))
|
raise JsonableError(_("Emoji '{}' does not exist").format(emoji_name))
|
||||||
|
|
||||||
def check_emoji_request(realm: Realm, emoji_name: str, emoji_code: str,
|
def check_emoji_request(realm: Realm, emoji_name: str, emoji_code: str,
|
||||||
emoji_type: str) -> None:
|
emoji_type: str) -> None:
|
||||||
|
|
|
@ -21,7 +21,7 @@ def check_supported_events_narrow_filter(narrow: Iterable[Sequence[str]]) -> Non
|
||||||
for element in narrow:
|
for element in narrow:
|
||||||
operator = element[0]
|
operator = element[0]
|
||||||
if operator not in ["stream", "topic", "sender", "is"]:
|
if operator not in ["stream", "topic", "sender", "is"]:
|
||||||
raise JsonableError(_("Operator %s not supported.") % (operator,))
|
raise JsonableError(_("Operator {} not supported.").format(operator))
|
||||||
|
|
||||||
def is_web_public_compatible(narrow: Iterable[Dict[str, str]]) -> bool:
|
def is_web_public_compatible(narrow: Iterable[Dict[str, str]]) -> bool:
|
||||||
for element in narrow:
|
for element in narrow:
|
||||||
|
|
|
@ -238,15 +238,17 @@ def parse_gcm_options(options: Dict[str, Any], data: Dict[str, Any]) -> str:
|
||||||
else: # `'event': 'remove'`, presumably
|
else: # `'event': 'remove'`, presumably
|
||||||
priority = 'normal'
|
priority = 'normal'
|
||||||
if priority not in ('normal', 'high'):
|
if priority not in ('normal', 'high'):
|
||||||
raise JsonableError(_("Invalid GCM option to bouncer: priority %r")
|
raise JsonableError(_(
|
||||||
% (priority,))
|
"Invalid GCM option to bouncer: priority {!r}",
|
||||||
|
).format(priority))
|
||||||
|
|
||||||
if options:
|
if options:
|
||||||
# We're strict about the API; there is no use case for a newer Zulip
|
# We're strict about the API; there is no use case for a newer Zulip
|
||||||
# server talking to an older bouncer, so we only need to provide
|
# server talking to an older bouncer, so we only need to provide
|
||||||
# one-way compatibility.
|
# one-way compatibility.
|
||||||
raise JsonableError(_("Invalid GCM options to bouncer: %s")
|
raise JsonableError(_(
|
||||||
% (ujson.dumps(options),))
|
"Invalid GCM options to bouncer: {}",
|
||||||
|
).format(ujson.dumps(options)))
|
||||||
|
|
||||||
return priority # when this grows a second option, can make it a tuple
|
return priority # when this grows a second option, can make it a tuple
|
||||||
|
|
||||||
|
@ -600,9 +602,9 @@ def get_apns_alert_subtitle(message: Message) -> str:
|
||||||
On an iOS notification, this is the second bolded line.
|
On an iOS notification, this is the second bolded line.
|
||||||
"""
|
"""
|
||||||
if message.trigger == "mentioned":
|
if message.trigger == "mentioned":
|
||||||
return _("%(full_name)s mentioned you:") % dict(full_name=message.sender.full_name)
|
return _("{full_name} mentioned you:").format(full_name=message.sender.full_name)
|
||||||
elif message.trigger == "wildcard_mentioned":
|
elif message.trigger == "wildcard_mentioned":
|
||||||
return _("%(full_name)s mentioned everyone:") % dict(full_name=message.sender.full_name)
|
return _("{full_name} mentioned everyone:").format(full_name=message.sender.full_name)
|
||||||
elif message.recipient.type == Recipient.PERSONAL:
|
elif message.recipient.type == Recipient.PERSONAL:
|
||||||
return ""
|
return ""
|
||||||
# For group PMs, or regular messages to a stream, just use a colon to indicate this is the sender.
|
# For group PMs, or regular messages to a stream, just use a colon to indicate this is the sender.
|
||||||
|
|
|
@ -77,7 +77,7 @@ def send_to_push_bouncer(method: str,
|
||||||
if 'code' in result_dict and result_dict['code'] == 'INVALID_ZULIP_SERVER':
|
if 'code' in result_dict and result_dict['code'] == 'INVALID_ZULIP_SERVER':
|
||||||
# Invalid Zulip server credentials should email this server's admins
|
# Invalid Zulip server credentials should email this server's admins
|
||||||
raise PushNotificationBouncerException(
|
raise PushNotificationBouncerException(
|
||||||
_("Push notifications bouncer error: %s") % (msg,))
|
_("Push notifications bouncer error: {}").format(msg))
|
||||||
else:
|
else:
|
||||||
# But most other errors coming from the push bouncer
|
# But most other errors coming from the push bouncer
|
||||||
# server are client errors (e.g. never-registered token)
|
# server are client errors (e.g. never-registered token)
|
||||||
|
|
|
@ -348,7 +348,7 @@ def has_request_variables(view_func: ViewFuncT) -> ViewFuncT:
|
||||||
try:
|
try:
|
||||||
val = ujson.loads(val)
|
val = ujson.loads(val)
|
||||||
except Exception:
|
except Exception:
|
||||||
raise JsonableError(_('Argument "%s" is not valid JSON.') % (post_var_name,))
|
raise JsonableError(_('Argument "{}" is not valid JSON.').format(post_var_name))
|
||||||
|
|
||||||
error = param.validator(post_var_name, val)
|
error = param.validator(post_var_name, val)
|
||||||
if error:
|
if error:
|
||||||
|
|
|
@ -115,12 +115,12 @@ def create_streams_if_needed(realm: Realm,
|
||||||
|
|
||||||
def check_stream_name(stream_name: str) -> None:
|
def check_stream_name(stream_name: str) -> None:
|
||||||
if stream_name.strip() == "":
|
if stream_name.strip() == "":
|
||||||
raise JsonableError(_("Invalid stream name '%s'") % (stream_name,))
|
raise JsonableError(_("Invalid stream name '{}'").format(stream_name))
|
||||||
if len(stream_name) > Stream.MAX_NAME_LENGTH:
|
if len(stream_name) > Stream.MAX_NAME_LENGTH:
|
||||||
raise JsonableError(_("Stream name too long (limit: %s characters).") % (Stream.MAX_NAME_LENGTH,))
|
raise JsonableError(_("Stream name too long (limit: {} characters).").format(Stream.MAX_NAME_LENGTH))
|
||||||
for i in stream_name:
|
for i in stream_name:
|
||||||
if ord(i) == 0:
|
if ord(i) == 0:
|
||||||
raise JsonableError(_("Stream name '%s' contains NULL (0x00) characters.") % (stream_name,))
|
raise JsonableError(_("Stream name '{}' contains NULL (0x00) characters.").format(stream_name))
|
||||||
|
|
||||||
def subscribed_to_stream(user_profile: UserProfile, stream_id: int) -> bool:
|
def subscribed_to_stream(user_profile: UserProfile, stream_id: int) -> bool:
|
||||||
return Subscription.objects.filter(
|
return Subscription.objects.filter(
|
||||||
|
@ -177,7 +177,7 @@ def access_stream_for_send_message(sender: UserProfile,
|
||||||
return
|
return
|
||||||
|
|
||||||
# All other cases are an error.
|
# All other cases are an error.
|
||||||
raise JsonableError(_("Not authorized to send to stream '%s'") % (stream.name,))
|
raise JsonableError(_("Not authorized to send to stream '{}'").format(stream.name))
|
||||||
|
|
||||||
def check_for_exactly_one_stream_arg(stream_id: Optional[int], stream: Optional[str]) -> None:
|
def check_for_exactly_one_stream_arg(stream_id: Optional[int], stream: Optional[str]) -> None:
|
||||||
if stream_id is None and stream is None:
|
if stream_id is None and stream is None:
|
||||||
|
@ -276,14 +276,14 @@ def check_stream_name_available(realm: Realm, name: str) -> None:
|
||||||
check_stream_name(name)
|
check_stream_name(name)
|
||||||
try:
|
try:
|
||||||
get_stream(name, realm)
|
get_stream(name, realm)
|
||||||
raise JsonableError(_("Stream name '%s' is already taken.") % (name,))
|
raise JsonableError(_("Stream name '{}' is already taken.").format(name))
|
||||||
except Stream.DoesNotExist:
|
except Stream.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def access_stream_by_name(user_profile: UserProfile,
|
def access_stream_by_name(user_profile: UserProfile,
|
||||||
stream_name: str,
|
stream_name: str,
|
||||||
allow_realm_admin: bool=False) -> Tuple[Stream, Recipient, Optional[Subscription]]:
|
allow_realm_admin: bool=False) -> Tuple[Stream, Recipient, Optional[Subscription]]:
|
||||||
error = _("Invalid stream name '%s'") % (stream_name,)
|
error = _("Invalid stream name '{}'").format(stream_name)
|
||||||
try:
|
try:
|
||||||
stream = get_realm_stream(stream_name, user_profile.realm_id)
|
stream = get_realm_stream(stream_name, user_profile.realm_id)
|
||||||
except Stream.DoesNotExist:
|
except Stream.DoesNotExist:
|
||||||
|
@ -345,7 +345,7 @@ def can_access_stream_history(user_profile: UserProfile, stream: Stream) -> bool
|
||||||
|
|
||||||
if stream.is_history_public_to_subscribers():
|
if stream.is_history_public_to_subscribers():
|
||||||
# In this case, we check if the user is subscribed.
|
# In this case, we check if the user is subscribed.
|
||||||
error = _("Invalid stream name '%s'") % (stream.name,)
|
error = _("Invalid stream name '{}'").format(stream.name)
|
||||||
try:
|
try:
|
||||||
(recipient, sub) = access_stream_common(user_profile, stream, error)
|
(recipient, sub) = access_stream_common(user_profile, stream, error)
|
||||||
except JsonableError:
|
except JsonableError:
|
||||||
|
@ -440,8 +440,9 @@ def list_to_streams(streams_raw: Iterable[Mapping[str, Any]],
|
||||||
if not user_profile.can_create_streams():
|
if not user_profile.can_create_streams():
|
||||||
raise JsonableError(_('User cannot create streams.'))
|
raise JsonableError(_('User cannot create streams.'))
|
||||||
elif not autocreate:
|
elif not autocreate:
|
||||||
raise JsonableError(_("Stream(s) (%s) do not exist") % ", ".join(
|
raise JsonableError(_("Stream(s) ({}) do not exist").format(
|
||||||
stream_dict["name"] for stream_dict in missing_stream_dicts))
|
", ".join(stream_dict["name"] for stream_dict in missing_stream_dicts),
|
||||||
|
))
|
||||||
|
|
||||||
# We already filtered out existing streams, so dup_streams
|
# We already filtered out existing streams, so dup_streams
|
||||||
# will normally be an empty list below, but we protect against somebody
|
# will normally be an empty list below, but we protect against somebody
|
||||||
|
@ -458,7 +459,7 @@ def access_default_stream_group_by_id(realm: Realm, group_id: int) -> DefaultStr
|
||||||
try:
|
try:
|
||||||
return DefaultStreamGroup.objects.get(realm=realm, id=group_id)
|
return DefaultStreamGroup.objects.get(realm=realm, id=group_id)
|
||||||
except DefaultStreamGroup.DoesNotExist:
|
except DefaultStreamGroup.DoesNotExist:
|
||||||
raise JsonableError(_("Default stream group with id '%s' does not exist.") % (group_id,))
|
raise JsonableError(_("Default stream group with id '{}' does not exist.").format(group_id))
|
||||||
|
|
||||||
def get_stream_by_narrow_operand_access_unchecked(operand: Union[str, int], realm: Realm) -> Stream:
|
def get_stream_by_narrow_operand_access_unchecked(operand: Union[str, int], realm: Realm) -> Stream:
|
||||||
"""This is required over access_stream_* in certain cases where
|
"""This is required over access_stream_* in certain cases where
|
||||||
|
|
|
@ -78,12 +78,13 @@ def check_valid_bot_config(bot_type: int, service_name: str,
|
||||||
config_options = {c[1]: c[2] for c in integration.config_options}
|
config_options = {c[1]: c[2] for c in integration.config_options}
|
||||||
break
|
break
|
||||||
if not config_options:
|
if not config_options:
|
||||||
raise JsonableError(_("Invalid integration '%s'.") % (service_name,))
|
raise JsonableError(_("Invalid integration '{}'.").format(service_name))
|
||||||
|
|
||||||
missing_keys = set(config_options.keys()) - set(config_data.keys())
|
missing_keys = set(config_options.keys()) - set(config_data.keys())
|
||||||
if missing_keys:
|
if missing_keys:
|
||||||
raise JsonableError(_("Missing configuration parameters: %s") % (
|
raise JsonableError(_("Missing configuration parameters: {}").format(
|
||||||
missing_keys,))
|
missing_keys,
|
||||||
|
))
|
||||||
|
|
||||||
for key, validator in config_options.items():
|
for key, validator in config_options.items():
|
||||||
value = config_data[key]
|
value = config_data[key]
|
||||||
|
@ -196,12 +197,12 @@ def user_ids_to_users(user_ids: Sequence[int], realm: Realm) -> List[UserProfile
|
||||||
found_user_ids = user_profiles_by_id.keys()
|
found_user_ids = user_profiles_by_id.keys()
|
||||||
missed_user_ids = [user_id for user_id in user_ids if user_id not in found_user_ids]
|
missed_user_ids = [user_id for user_id in user_ids if user_id not in found_user_ids]
|
||||||
if missed_user_ids:
|
if missed_user_ids:
|
||||||
raise JsonableError(_("Invalid user ID: %s") % (missed_user_ids[0],))
|
raise JsonableError(_("Invalid user ID: {}").format(missed_user_ids[0]))
|
||||||
|
|
||||||
user_profiles = list(user_profiles_by_id.values())
|
user_profiles = list(user_profiles_by_id.values())
|
||||||
for user_profile in user_profiles:
|
for user_profile in user_profiles:
|
||||||
if user_profile.realm != realm:
|
if user_profile.realm != realm:
|
||||||
raise JsonableError(_("Invalid user ID: %s") % (user_profile.id,))
|
raise JsonableError(_("Invalid user ID: {}").format(user_profile.id))
|
||||||
return user_profiles
|
return user_profiles
|
||||||
|
|
||||||
def access_bot_by_id(user_profile: UserProfile, user_id: int) -> UserProfile:
|
def access_bot_by_id(user_profile: UserProfile, user_id: int) -> UserProfile:
|
||||||
|
|
|
@ -56,7 +56,7 @@ def set_type_structure(type_structure: TypeStructure) -> Callable[[FuncT], Any]:
|
||||||
@set_type_structure("str")
|
@set_type_structure("str")
|
||||||
def check_string(var_name: str, val: object) -> Optional[str]:
|
def check_string(var_name: str, val: object) -> Optional[str]:
|
||||||
if not isinstance(val, str):
|
if not isinstance(val, str):
|
||||||
return _('%s is not a string') % (var_name,)
|
return _('{var_name} is not a string').format(var_name=var_name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@set_type_structure("str")
|
@set_type_structure("str")
|
||||||
|
@ -78,7 +78,7 @@ def check_string_in(possible_values: Union[Set[str], List[str]]) -> Validator:
|
||||||
if not_str is not None:
|
if not_str is not None:
|
||||||
return not_str
|
return not_str
|
||||||
if val not in possible_values:
|
if val not in possible_values:
|
||||||
return _("Invalid %s") % (var_name,)
|
return _("Invalid {var_name}").format(var_name=var_name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return validator
|
return validator
|
||||||
|
@ -91,7 +91,7 @@ def check_capped_string(max_length: int) -> Validator:
|
||||||
@set_type_structure("str")
|
@set_type_structure("str")
|
||||||
def validator(var_name: str, val: object) -> Optional[str]:
|
def validator(var_name: str, val: object) -> Optional[str]:
|
||||||
if not isinstance(val, str):
|
if not isinstance(val, str):
|
||||||
return _('%s is not a string') % (var_name,)
|
return _('{var_name} is not a string').format(var_name=var_name)
|
||||||
if len(val) > max_length:
|
if len(val) > max_length:
|
||||||
return _("{var_name} is too long (limit: {max_length} characters)").format(
|
return _("{var_name} is too long (limit: {max_length} characters)").format(
|
||||||
var_name=var_name, max_length=max_length)
|
var_name=var_name, max_length=max_length)
|
||||||
|
@ -103,7 +103,7 @@ def check_string_fixed_length(length: int) -> Validator:
|
||||||
@set_type_structure("str")
|
@set_type_structure("str")
|
||||||
def validator(var_name: str, val: object) -> Optional[str]:
|
def validator(var_name: str, val: object) -> Optional[str]:
|
||||||
if not isinstance(val, str):
|
if not isinstance(val, str):
|
||||||
return _('%s is not a string') % (var_name,)
|
return _('{var_name} is not a string').format(var_name=var_name)
|
||||||
if len(val) != length:
|
if len(val) != length:
|
||||||
return _("{var_name} has incorrect length {length}; should be {target_length}").format(
|
return _("{var_name} has incorrect length {length}; should be {target_length}").format(
|
||||||
var_name=var_name, target_length=length, length=len(val))
|
var_name=var_name, target_length=length, length=len(val))
|
||||||
|
@ -117,17 +117,17 @@ def check_long_string(var_name: str, val: object) -> Optional[str]:
|
||||||
@set_type_structure("date")
|
@set_type_structure("date")
|
||||||
def check_date(var_name: str, val: object) -> Optional[str]:
|
def check_date(var_name: str, val: object) -> Optional[str]:
|
||||||
if not isinstance(val, str):
|
if not isinstance(val, str):
|
||||||
return _('%s is not a string') % (var_name,)
|
return _('{var_name} is not a string').format(var_name=var_name)
|
||||||
try:
|
try:
|
||||||
datetime.strptime(val, '%Y-%m-%d')
|
datetime.strptime(val, '%Y-%m-%d')
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return _('%s is not a date') % (var_name,)
|
return _('{var_name} is not a date').format(var_name=var_name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@set_type_structure("int")
|
@set_type_structure("int")
|
||||||
def check_int(var_name: str, val: object) -> Optional[str]:
|
def check_int(var_name: str, val: object) -> Optional[str]:
|
||||||
if not isinstance(val, int):
|
if not isinstance(val, int):
|
||||||
return _('%s is not an integer') % (var_name,)
|
return _('{var_name} is not an integer').format(var_name=var_name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def check_int_in(possible_values: List[int]) -> Validator:
|
def check_int_in(possible_values: List[int]) -> Validator:
|
||||||
|
@ -137,7 +137,7 @@ def check_int_in(possible_values: List[int]) -> Validator:
|
||||||
if not_int is not None:
|
if not_int is not None:
|
||||||
return not_int
|
return not_int
|
||||||
if val not in possible_values:
|
if val not in possible_values:
|
||||||
return _("Invalid %s") % (var_name,)
|
return _("Invalid {var_name}").format(var_name=var_name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return validator
|
return validator
|
||||||
|
@ -145,23 +145,23 @@ def check_int_in(possible_values: List[int]) -> Validator:
|
||||||
@set_type_structure("float")
|
@set_type_structure("float")
|
||||||
def check_float(var_name: str, val: object) -> Optional[str]:
|
def check_float(var_name: str, val: object) -> Optional[str]:
|
||||||
if not isinstance(val, float):
|
if not isinstance(val, float):
|
||||||
return _('%s is not a float') % (var_name,)
|
return _('{var_name} is not a float').format(var_name=var_name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@set_type_structure("bool")
|
@set_type_structure("bool")
|
||||||
def check_bool(var_name: str, val: object) -> Optional[str]:
|
def check_bool(var_name: str, val: object) -> Optional[str]:
|
||||||
if not isinstance(val, bool):
|
if not isinstance(val, bool):
|
||||||
return _('%s is not a boolean') % (var_name,)
|
return _('{var_name} is not a boolean').format(var_name=var_name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@set_type_structure("str")
|
@set_type_structure("str")
|
||||||
def check_color(var_name: str, val: object) -> Optional[str]:
|
def check_color(var_name: str, val: object) -> Optional[str]:
|
||||||
if not isinstance(val, str):
|
if not isinstance(val, str):
|
||||||
return _('%s is not a string') % (var_name,)
|
return _('{var_name} is not a string').format(var_name=var_name)
|
||||||
valid_color_pattern = re.compile(r'^#([a-fA-F0-9]{3,6})$')
|
valid_color_pattern = re.compile(r'^#([a-fA-F0-9]{3,6})$')
|
||||||
matched_results = valid_color_pattern.match(val)
|
matched_results = valid_color_pattern.match(val)
|
||||||
if not matched_results:
|
if not matched_results:
|
||||||
return _('%s is not a valid hex color code') % (var_name,)
|
return _('{var_name} is not a valid hex color code').format(var_name=var_name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def check_none_or(sub_validator: Validator) -> Validator:
|
def check_none_or(sub_validator: Validator) -> Validator:
|
||||||
|
@ -190,11 +190,12 @@ def check_list(sub_validator: Optional[Validator], length: Optional[int]=None) -
|
||||||
@set_type_structure(type_structure)
|
@set_type_structure(type_structure)
|
||||||
def f(var_name: str, val: object) -> Optional[str]:
|
def f(var_name: str, val: object) -> Optional[str]:
|
||||||
if not isinstance(val, list):
|
if not isinstance(val, list):
|
||||||
return _('%s is not a list') % (var_name,)
|
return _('{var_name} is not a list').format(var_name=var_name)
|
||||||
|
|
||||||
if length is not None and length != len(val):
|
if length is not None and length != len(val):
|
||||||
return (_('%(container)s should have exactly %(length)s items') %
|
return (_('{container} should have exactly {length} items').format(
|
||||||
{'container': var_name, 'length': length})
|
container=var_name, length=length,
|
||||||
|
))
|
||||||
|
|
||||||
if sub_validator:
|
if sub_validator:
|
||||||
for i, item in enumerate(val):
|
for i, item in enumerate(val):
|
||||||
|
@ -215,12 +216,13 @@ def check_dict(required_keys: Iterable[Tuple[str, Validator]]=[],
|
||||||
@set_type_structure(type_structure)
|
@set_type_structure(type_structure)
|
||||||
def f(var_name: str, val: object) -> Optional[str]:
|
def f(var_name: str, val: object) -> Optional[str]:
|
||||||
if not isinstance(val, dict):
|
if not isinstance(val, dict):
|
||||||
return _('%s is not a dict') % (var_name,)
|
return _('{var_name} is not a dict').format(var_name=var_name)
|
||||||
|
|
||||||
for k, sub_validator in required_keys:
|
for k, sub_validator in required_keys:
|
||||||
if k not in val:
|
if k not in val:
|
||||||
return (_('%(key_name)s key is missing from %(var_name)s') %
|
return (_('{key_name} key is missing from {var_name}').format(
|
||||||
{'key_name': k, 'var_name': var_name})
|
key_name=k, var_name=var_name,
|
||||||
|
))
|
||||||
vname = f'{var_name}["{k}"]'
|
vname = f'{var_name}["{k}"]'
|
||||||
error = sub_validator(vname, val[k])
|
error = sub_validator(vname, val[k])
|
||||||
if error:
|
if error:
|
||||||
|
@ -251,7 +253,7 @@ def check_dict(required_keys: Iterable[Tuple[str, Validator]]=[],
|
||||||
optional_keys_set = {x[0] for x in optional_keys}
|
optional_keys_set = {x[0] for x in optional_keys}
|
||||||
delta_keys = set(val.keys()) - required_keys_set - optional_keys_set
|
delta_keys = set(val.keys()) - required_keys_set - optional_keys_set
|
||||||
if len(delta_keys) != 0:
|
if len(delta_keys) != 0:
|
||||||
return _("Unexpected arguments: %s") % (", ".join(list(delta_keys)),)
|
return _("Unexpected arguments: {}").format(", ".join(list(delta_keys)))
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -280,17 +282,16 @@ def check_variable_type(allowed_type_funcs: Iterable[Validator]) -> Validator:
|
||||||
for func in allowed_type_funcs:
|
for func in allowed_type_funcs:
|
||||||
if not func(var_name, val):
|
if not func(var_name, val):
|
||||||
return None
|
return None
|
||||||
return _('%s is not an allowed_type') % (var_name,)
|
return _('{var_name} is not an allowed_type').format(var_name=var_name)
|
||||||
return enumerated_type_check
|
return enumerated_type_check
|
||||||
|
|
||||||
def equals(expected_val: object) -> Validator:
|
def equals(expected_val: object) -> Validator:
|
||||||
@set_type_structure(f'equals("{str(expected_val)}")')
|
@set_type_structure(f'equals("{str(expected_val)}")')
|
||||||
def f(var_name: str, val: object) -> Optional[str]:
|
def f(var_name: str, val: object) -> Optional[str]:
|
||||||
if val != expected_val:
|
if val != expected_val:
|
||||||
return (_('%(variable)s != %(expected_value)s (%(value)s is wrong)') %
|
return (_('{variable} != {expected_value} ({value} is wrong)').format(
|
||||||
{'variable': var_name,
|
variable=var_name, expected_value=expected_val, value=val,
|
||||||
'expected_value': expected_val,
|
))
|
||||||
'value': val})
|
|
||||||
return None
|
return None
|
||||||
return f
|
return f
|
||||||
|
|
||||||
|
@ -313,7 +314,7 @@ def check_url(var_name: str, val: object) -> Optional[str]:
|
||||||
validate(val)
|
validate(val)
|
||||||
return None
|
return None
|
||||||
except ValidationError:
|
except ValidationError:
|
||||||
return _('%s is not a URL') % (var_name,)
|
return _('{var_name} is not a URL').format(var_name=var_name)
|
||||||
|
|
||||||
@set_type_structure('str')
|
@set_type_structure('str')
|
||||||
def check_external_account_url_pattern(var_name: str, val: object) -> Optional[str]:
|
def check_external_account_url_pattern(var_name: str, val: object) -> Optional[str]:
|
||||||
|
@ -435,7 +436,7 @@ def check_string_or_int_list(var_name: str, val: object) -> Optional[str]:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if not isinstance(val, list):
|
if not isinstance(val, list):
|
||||||
return _('%s is not a string or an integer list') % (var_name,)
|
return _('{var_name} is not a string or an integer list').format(var_name=var_name)
|
||||||
|
|
||||||
return check_list(check_int)(var_name, val)
|
return check_list(check_int)(var_name, val)
|
||||||
|
|
||||||
|
@ -444,4 +445,4 @@ def check_string_or_int(var_name: str, val: object) -> Optional[str]:
|
||||||
if isinstance(val, str) or isinstance(val, int):
|
if isinstance(val, str) or isinstance(val, int):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return _('%s is not a string or integer') % (var_name,)
|
return _('{var_name} is not a string or integer').format(var_name=var_name)
|
||||||
|
|
|
@ -54,4 +54,4 @@ def process_zcommands(content: str, user_profile: UserProfile) -> Dict[str, Any]
|
||||||
switch_command='fluid-width',
|
switch_command='fluid-width',
|
||||||
setting='fluid_layout_width',
|
setting='fluid_layout_width',
|
||||||
setting_value=False))
|
setting_value=False))
|
||||||
raise JsonableError(_('No such command: %s') % (command,))
|
raise JsonableError(_('No such command: {}').format(command))
|
||||||
|
|
|
@ -211,7 +211,7 @@ class RealmEmojiTest(ZulipTestCase):
|
||||||
with get_test_image_file('img.png') as fp:
|
with get_test_image_file('img.png') as fp:
|
||||||
with self.settings(MAX_EMOJI_FILE_SIZE=0):
|
with self.settings(MAX_EMOJI_FILE_SIZE=0):
|
||||||
result = self.client_post('/json/realm/emoji/my_emoji', {'file': fp})
|
result = self.client_post('/json/realm/emoji/my_emoji', {'file': fp})
|
||||||
self.assert_json_error(result, 'Uploaded file is larger than the allowed limit of 0 MB')
|
self.assert_json_error(result, 'Uploaded file is larger than the allowed limit of 0 MiB')
|
||||||
|
|
||||||
def test_upload_already_existed_emoji(self) -> None:
|
def test_upload_already_existed_emoji(self) -> None:
|
||||||
self.login('iago')
|
self.login('iago')
|
||||||
|
|
|
@ -164,7 +164,7 @@ class FileUploadTest(UploadSerializeMixin, ZulipTestCase):
|
||||||
# would be 1MB.
|
# would be 1MB.
|
||||||
with self.settings(MAX_FILE_UPLOAD_SIZE=0):
|
with self.settings(MAX_FILE_UPLOAD_SIZE=0):
|
||||||
result = self.client_post("/json/user_uploads", {'f1': fp})
|
result = self.client_post("/json/user_uploads", {'f1': fp})
|
||||||
self.assert_json_error(result, 'Uploaded file is larger than the allowed limit of 0 MB')
|
self.assert_json_error(result, 'Uploaded file is larger than the allowed limit of 0 MiB')
|
||||||
|
|
||||||
def test_multiple_upload_failure(self) -> None:
|
def test_multiple_upload_failure(self) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -1163,7 +1163,7 @@ class AvatarTest(UploadSerializeMixin, ZulipTestCase):
|
||||||
with get_test_image_file(self.correct_files[0][0]) as fp:
|
with get_test_image_file(self.correct_files[0][0]) as fp:
|
||||||
with self.settings(MAX_AVATAR_FILE_SIZE=0):
|
with self.settings(MAX_AVATAR_FILE_SIZE=0):
|
||||||
result = self.client_post("/json/users/me/avatar", {'file': fp})
|
result = self.client_post("/json/users/me/avatar", {'file': fp})
|
||||||
self.assert_json_error(result, "Uploaded file is larger than the allowed limit of 0 MB")
|
self.assert_json_error(result, "Uploaded file is larger than the allowed limit of 0 MiB")
|
||||||
|
|
||||||
def tearDown(self) -> None:
|
def tearDown(self) -> None:
|
||||||
destroy_uploads()
|
destroy_uploads()
|
||||||
|
@ -1336,7 +1336,7 @@ class RealmIconTest(UploadSerializeMixin, ZulipTestCase):
|
||||||
with get_test_image_file(self.correct_files[0][0]) as fp:
|
with get_test_image_file(self.correct_files[0][0]) as fp:
|
||||||
with self.settings(MAX_ICON_FILE_SIZE=0):
|
with self.settings(MAX_ICON_FILE_SIZE=0):
|
||||||
result = self.client_post("/json/realm/icon", {'file': fp})
|
result = self.client_post("/json/realm/icon", {'file': fp})
|
||||||
self.assert_json_error(result, "Uploaded file is larger than the allowed limit of 0 MB")
|
self.assert_json_error(result, "Uploaded file is larger than the allowed limit of 0 MiB")
|
||||||
|
|
||||||
def tearDown(self) -> None:
|
def tearDown(self) -> None:
|
||||||
destroy_uploads()
|
destroy_uploads()
|
||||||
|
@ -1479,7 +1479,7 @@ class RealmLogoTest(UploadSerializeMixin, ZulipTestCase):
|
||||||
with self.settings(MAX_LOGO_FILE_SIZE=0):
|
with self.settings(MAX_LOGO_FILE_SIZE=0):
|
||||||
result = self.client_post("/json/realm/logo", {'file': fp, 'night':
|
result = self.client_post("/json/realm/logo", {'file': fp, 'night':
|
||||||
ujson.dumps(self.night)})
|
ujson.dumps(self.night)})
|
||||||
self.assert_json_error(result, "Uploaded file is larger than the allowed limit of 0 MB")
|
self.assert_json_error(result, "Uploaded file is larger than the allowed limit of 0 MiB")
|
||||||
|
|
||||||
def tearDown(self) -> None:
|
def tearDown(self) -> None:
|
||||||
destroy_uploads()
|
destroy_uploads()
|
||||||
|
|
|
@ -566,13 +566,17 @@ def fetch_events(query: Mapping[str, Any]) -> Dict[str, Any]:
|
||||||
client.event_queue.newest_pruned_id is not None
|
client.event_queue.newest_pruned_id is not None
|
||||||
and last_event_id < client.event_queue.newest_pruned_id
|
and last_event_id < client.event_queue.newest_pruned_id
|
||||||
):
|
):
|
||||||
raise JsonableError(_("An event newer than %s has already been pruned!") % (last_event_id,))
|
raise JsonableError(_("An event newer than {event_id} has already been pruned!").format(
|
||||||
|
event_id=last_event_id,
|
||||||
|
))
|
||||||
client.event_queue.prune(last_event_id)
|
client.event_queue.prune(last_event_id)
|
||||||
if (
|
if (
|
||||||
client.event_queue.newest_pruned_id is not None
|
client.event_queue.newest_pruned_id is not None
|
||||||
and last_event_id != client.event_queue.newest_pruned_id
|
and last_event_id != client.event_queue.newest_pruned_id
|
||||||
):
|
):
|
||||||
raise JsonableError(_("Event %s was not in this queue") % (last_event_id,))
|
raise JsonableError(_("Event {event_id} was not in this queue").format(
|
||||||
|
event_id=last_event_id,
|
||||||
|
))
|
||||||
was_connected = client.finish_current_handler()
|
was_connected = client.finish_current_handler()
|
||||||
|
|
||||||
if not client.event_queue.empty() or dont_block:
|
if not client.event_queue.empty() or dont_block:
|
||||||
|
|
|
@ -15,6 +15,6 @@ from zerver.models import UserProfile
|
||||||
def mark_hotspot_as_read(request: HttpRequest, user: UserProfile,
|
def mark_hotspot_as_read(request: HttpRequest, user: UserProfile,
|
||||||
hotspot: str=REQ(validator=check_string)) -> HttpResponse:
|
hotspot: str=REQ(validator=check_string)) -> HttpResponse:
|
||||||
if hotspot not in ALL_HOTSPOTS:
|
if hotspot not in ALL_HOTSPOTS:
|
||||||
return json_error(_('Unknown hotspot: %s') % (hotspot,))
|
return json_error(_('Unknown hotspot: {}').format(hotspot))
|
||||||
do_mark_hotspot_as_read(user, hotspot)
|
do_mark_hotspot_as_read(user, hotspot)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -852,8 +852,9 @@ def get_messages_backend(request: HttpRequest, user_profile: UserProfile,
|
||||||
apply_markdown: bool=REQ(validator=check_bool, default=True)) -> HttpResponse:
|
apply_markdown: bool=REQ(validator=check_bool, default=True)) -> HttpResponse:
|
||||||
anchor = parse_anchor_value(anchor_val, use_first_unread_anchor_val)
|
anchor = parse_anchor_value(anchor_val, use_first_unread_anchor_val)
|
||||||
if num_before + num_after > MAX_MESSAGES_PER_FETCH:
|
if num_before + num_after > MAX_MESSAGES_PER_FETCH:
|
||||||
return json_error(_("Too many messages requested (maximum %s).")
|
return json_error(_("Too many messages requested (maximum {}).").format(
|
||||||
% (MAX_MESSAGES_PER_FETCH,))
|
MAX_MESSAGES_PER_FETCH,
|
||||||
|
))
|
||||||
|
|
||||||
if user_profile.realm.email_address_visibility != Realm.EMAIL_ADDRESS_VISIBILITY_EVERYONE:
|
if user_profile.realm.email_address_visibility != Realm.EMAIL_ADDRESS_VISIBILITY_EVERYONE:
|
||||||
# If email addresses are only available to administrators,
|
# If email addresses are only available to administrators,
|
||||||
|
@ -1218,7 +1219,7 @@ def mark_topic_as_read(request: HttpRequest,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not topic_exists:
|
if not topic_exists:
|
||||||
raise JsonableError(_('No such topic \'%s\'') % (topic_name,))
|
raise JsonableError(_('No such topic \'{}\'').format(topic_name))
|
||||||
|
|
||||||
count = do_mark_stream_messages_as_read(user_profile, request.client, stream, topic_name)
|
count = do_mark_stream_messages_as_read(user_profile, request.client, stream, topic_name)
|
||||||
|
|
||||||
|
@ -1413,7 +1414,7 @@ def send_message_backend(request: HttpRequest, user_profile: UserProfile,
|
||||||
try:
|
try:
|
||||||
realm = get_realm(realm_str)
|
realm = get_realm(realm_str)
|
||||||
except Realm.DoesNotExist:
|
except Realm.DoesNotExist:
|
||||||
return json_error(_("Unknown organization '%s'") % (realm_str,))
|
return json_error(_("Unknown organization '{}'").format(realm_str))
|
||||||
|
|
||||||
if client.name in ["zephyr_mirror", "irc_mirror", "jabber_mirror", "JabberMirror"]:
|
if client.name in ["zephyr_mirror", "irc_mirror", "jabber_mirror", "JabberMirror"]:
|
||||||
# Here's how security works for mirroring:
|
# Here's how security works for mirroring:
|
||||||
|
|
|
@ -30,7 +30,7 @@ def get_presence_backend(request: HttpRequest, user_profile: UserProfile,
|
||||||
|
|
||||||
presence_dict = get_presence_for_user(target.id)
|
presence_dict = get_presence_for_user(target.id)
|
||||||
if len(presence_dict) == 0:
|
if len(presence_dict) == 0:
|
||||||
return json_error(_('No presence data for %s') % (email,))
|
return json_error(_('No presence data for {email}').format(email=email))
|
||||||
|
|
||||||
# For initial version, we just include the status and timestamp keys
|
# For initial version, we just include the status and timestamp keys
|
||||||
result = dict(presence=presence_dict[target.email])
|
result = dict(presence=presence_dict[target.email])
|
||||||
|
@ -77,7 +77,7 @@ def update_active_status_backend(request: HttpRequest, user_profile: UserProfile
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
status_val = UserPresence.status_from_string(status)
|
status_val = UserPresence.status_from_string(status)
|
||||||
if status_val is None:
|
if status_val is None:
|
||||||
raise JsonableError(_("Invalid status: %s") % (status,))
|
raise JsonableError(_("Invalid status: {}").format(status))
|
||||||
elif user_profile.presence_enabled:
|
elif user_profile.presence_enabled:
|
||||||
update_user_presence(user_profile, request.client, timezone_now(),
|
update_user_presence(user_profile, request.client, timezone_now(),
|
||||||
status_val, new_user_input)
|
status_val, new_user_input)
|
||||||
|
|
|
@ -94,7 +94,7 @@ def update_realm(
|
||||||
# Additional validation/error checking beyond types go here, so
|
# Additional validation/error checking beyond types go here, so
|
||||||
# the entire request can succeed or fail atomically.
|
# the entire request can succeed or fail atomically.
|
||||||
if default_language is not None and default_language not in get_available_language_codes():
|
if default_language is not None and default_language not in get_available_language_codes():
|
||||||
raise JsonableError(_("Invalid language '%s'") % (default_language,))
|
raise JsonableError(_("Invalid language '{}'").format(default_language))
|
||||||
if description is not None and len(description) > 1000:
|
if description is not None and len(description) > 1000:
|
||||||
return json_error(_("Organization description is too long."))
|
return json_error(_("Organization description is too long."))
|
||||||
if name is not None and len(name) > Realm.MAX_REALM_NAME_LENGTH:
|
if name is not None and len(name) > Realm.MAX_REALM_NAME_LENGTH:
|
||||||
|
|
|
@ -26,8 +26,8 @@ def create_realm_domain(request: HttpRequest, user_profile: UserProfile,
|
||||||
except ValidationError as e:
|
except ValidationError as e:
|
||||||
return json_error(_('Invalid domain: {}').format(e.messages[0]))
|
return json_error(_('Invalid domain: {}').format(e.messages[0]))
|
||||||
if RealmDomain.objects.filter(realm=user_profile.realm, domain=domain).exists():
|
if RealmDomain.objects.filter(realm=user_profile.realm, domain=domain).exists():
|
||||||
return json_error(_("The domain %(domain)s is already"
|
return json_error(_("The domain {domain} is already"
|
||||||
" a part of your organization.") % {'domain': domain})
|
" a part of your organization.").format(domain=domain))
|
||||||
realm_domain = do_add_realm_domain(user_profile.realm, domain, allow_subdomains)
|
realm_domain = do_add_realm_domain(user_profile.realm, domain, allow_subdomains)
|
||||||
return json_success({'new_domain': [realm_domain.id, realm_domain.domain]})
|
return json_success({'new_domain': [realm_domain.id, realm_domain.domain]})
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ def patch_realm_domain(request: HttpRequest, user_profile: UserProfile, domain:
|
||||||
realm_domain = RealmDomain.objects.get(realm=user_profile.realm, domain=domain)
|
realm_domain = RealmDomain.objects.get(realm=user_profile.realm, domain=domain)
|
||||||
do_change_realm_domain(realm_domain, allow_subdomains)
|
do_change_realm_domain(realm_domain, allow_subdomains)
|
||||||
except RealmDomain.DoesNotExist:
|
except RealmDomain.DoesNotExist:
|
||||||
return json_error(_('No entry found for domain %(domain)s.') % {'domain': domain})
|
return json_error(_('No entry found for domain {domain}.').format(domain=domain))
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
||||||
@require_realm_admin
|
@require_realm_admin
|
||||||
|
@ -50,5 +50,5 @@ def delete_realm_domain(request: HttpRequest, user_profile: UserProfile,
|
||||||
realm_domain = RealmDomain.objects.get(realm=user_profile.realm, domain=domain)
|
realm_domain = RealmDomain.objects.get(realm=user_profile.realm, domain=domain)
|
||||||
do_remove_realm_domain(realm_domain)
|
do_remove_realm_domain(realm_domain)
|
||||||
except RealmDomain.DoesNotExist:
|
except RealmDomain.DoesNotExist:
|
||||||
return json_error(_('No entry found for domain %(domain)s.') % {'domain': domain})
|
return json_error(_('No entry found for domain {domain}.').format(domain=domain))
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -32,8 +32,9 @@ def upload_emoji(request: HttpRequest, user_profile: UserProfile,
|
||||||
return json_error(_("You must upload exactly one file."))
|
return json_error(_("You must upload exactly one file."))
|
||||||
emoji_file = list(request.FILES.values())[0]
|
emoji_file = list(request.FILES.values())[0]
|
||||||
if (settings.MAX_EMOJI_FILE_SIZE * 1024 * 1024) < emoji_file.size:
|
if (settings.MAX_EMOJI_FILE_SIZE * 1024 * 1024) < emoji_file.size:
|
||||||
return json_error(_("Uploaded file is larger than the allowed limit of %s MB") % (
|
return json_error(_("Uploaded file is larger than the allowed limit of {} MiB").format(
|
||||||
settings.MAX_EMOJI_FILE_SIZE))
|
settings.MAX_EMOJI_FILE_SIZE,
|
||||||
|
))
|
||||||
|
|
||||||
realm_emoji = check_add_realm_emoji(user_profile.realm,
|
realm_emoji = check_add_realm_emoji(user_profile.realm,
|
||||||
emoji_name,
|
emoji_name,
|
||||||
|
@ -49,7 +50,7 @@ def delete_emoji(request: HttpRequest, user_profile: UserProfile,
|
||||||
if not RealmEmoji.objects.filter(realm=user_profile.realm,
|
if not RealmEmoji.objects.filter(realm=user_profile.realm,
|
||||||
name=emoji_name,
|
name=emoji_name,
|
||||||
deactivated=False).exists():
|
deactivated=False).exists():
|
||||||
raise JsonableError(_("Emoji '%s' does not exist") % (emoji_name,))
|
raise JsonableError(_("Emoji '{}' does not exist").format(emoji_name))
|
||||||
check_emoji_admin(user_profile, emoji_name)
|
check_emoji_admin(user_profile, emoji_name)
|
||||||
do_remove_realm_emoji(user_profile.realm, emoji_name)
|
do_remove_realm_emoji(user_profile.realm, emoji_name)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -43,8 +43,9 @@ def export_realm(request: HttpRequest, user: UserProfile) -> HttpResponse:
|
||||||
property='messages_sent:client:day'))
|
property='messages_sent:client:day'))
|
||||||
if (total_messages > MAX_MESSAGE_HISTORY or
|
if (total_messages > MAX_MESSAGE_HISTORY or
|
||||||
user.realm.currently_used_upload_space_bytes() > MAX_UPLOAD_QUOTA):
|
user.realm.currently_used_upload_space_bytes() > MAX_UPLOAD_QUOTA):
|
||||||
return json_error(_('Please request a manual export from %s.') % (
|
return json_error(_('Please request a manual export from {email}.').format(
|
||||||
settings.ZULIP_ADMINISTRATOR,))
|
email=settings.ZULIP_ADMINISTRATOR,
|
||||||
|
))
|
||||||
|
|
||||||
row = RealmAuditLog.objects.create(realm=realm,
|
row = RealmAuditLog.objects.create(realm=realm,
|
||||||
event_type=event_type,
|
event_type=event_type,
|
||||||
|
|
|
@ -20,8 +20,9 @@ def upload_icon(request: HttpRequest, user_profile: UserProfile) -> HttpResponse
|
||||||
|
|
||||||
icon_file = list(request.FILES.values())[0]
|
icon_file = list(request.FILES.values())[0]
|
||||||
if ((settings.MAX_ICON_FILE_SIZE * 1024 * 1024) < icon_file.size):
|
if ((settings.MAX_ICON_FILE_SIZE * 1024 * 1024) < icon_file.size):
|
||||||
return json_error(_("Uploaded file is larger than the allowed limit of %s MB") % (
|
return json_error(_("Uploaded file is larger than the allowed limit of {} MiB").format(
|
||||||
settings.MAX_ICON_FILE_SIZE))
|
settings.MAX_ICON_FILE_SIZE,
|
||||||
|
))
|
||||||
upload_icon_image(icon_file, user_profile)
|
upload_icon_image(icon_file, user_profile)
|
||||||
do_change_icon_source(user_profile.realm, user_profile.realm.ICON_UPLOADED)
|
do_change_icon_source(user_profile.realm, user_profile.realm.ICON_UPLOADED)
|
||||||
icon_url = realm_icon_url(user_profile.realm)
|
icon_url = realm_icon_url(user_profile.realm)
|
||||||
|
|
|
@ -24,8 +24,9 @@ def upload_logo(request: HttpRequest, user_profile: UserProfile,
|
||||||
return json_error(_("You must upload exactly one logo."))
|
return json_error(_("You must upload exactly one logo."))
|
||||||
logo_file = list(request.FILES.values())[0]
|
logo_file = list(request.FILES.values())[0]
|
||||||
if ((settings.MAX_LOGO_FILE_SIZE * 1024 * 1024) < logo_file.size):
|
if ((settings.MAX_LOGO_FILE_SIZE * 1024 * 1024) < logo_file.size):
|
||||||
return json_error(_("Uploaded file is larger than the allowed limit of %s MB") % (
|
return json_error(_("Uploaded file is larger than the allowed limit of {} MiB").format(
|
||||||
settings.MAX_LOGO_FILE_SIZE))
|
settings.MAX_LOGO_FILE_SIZE,
|
||||||
|
))
|
||||||
upload_logo_image(logo_file, user_profile, night)
|
upload_logo_image(logo_file, user_profile, night)
|
||||||
do_change_logo_source(user_profile.realm, user_profile.realm.LOGO_UPLOADED, night)
|
do_change_logo_source(user_profile.realm, user_profile.realm.LOGO_UPLOADED, night)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -356,12 +356,14 @@ def you_were_just_subscribed_message(acting_user: UserProfile,
|
||||||
stream_names: Set[str]) -> str:
|
stream_names: Set[str]) -> str:
|
||||||
subscriptions = sorted(list(stream_names))
|
subscriptions = sorted(list(stream_names))
|
||||||
if len(subscriptions) == 1:
|
if len(subscriptions) == 1:
|
||||||
return _("@**%(full_name)s** subscribed you to the stream #**%(stream_name)s**.") % \
|
return _("@**{full_name}** subscribed you to the stream #**{stream_name}**.").format(
|
||||||
{"full_name": acting_user.full_name,
|
full_name=acting_user.full_name,
|
||||||
"stream_name": subscriptions[0]}
|
stream_name=subscriptions[0],
|
||||||
|
)
|
||||||
|
|
||||||
message = _("@**%(full_name)s** subscribed you to the following streams:") % \
|
message = _("@**{full_name}** subscribed you to the following streams:").format(
|
||||||
{"full_name": acting_user.full_name}
|
full_name=acting_user.full_name,
|
||||||
|
)
|
||||||
message += "\n\n"
|
message += "\n\n"
|
||||||
for stream_name in subscriptions:
|
for stream_name in subscriptions:
|
||||||
message += f"* #**{stream_name}**\n"
|
message += f"* #**{stream_name}**\n"
|
||||||
|
@ -416,7 +418,9 @@ def add_subscriptions_backend(
|
||||||
authorized_streams, unauthorized_streams = \
|
authorized_streams, unauthorized_streams = \
|
||||||
filter_stream_authorization(user_profile, existing_streams)
|
filter_stream_authorization(user_profile, existing_streams)
|
||||||
if len(unauthorized_streams) > 0 and authorization_errors_fatal:
|
if len(unauthorized_streams) > 0 and authorization_errors_fatal:
|
||||||
return json_error(_("Unable to access stream (%s).") % unauthorized_streams[0].name)
|
return json_error(_("Unable to access stream ({stream_name}).").format(
|
||||||
|
stream_name=unauthorized_streams[0].name,
|
||||||
|
))
|
||||||
# Newly created streams are also authorized for the creator
|
# Newly created streams are also authorized for the creator
|
||||||
streams = authorized_streams + created_streams
|
streams = authorized_streams + created_streams
|
||||||
|
|
||||||
|
@ -519,9 +523,10 @@ def add_subscriptions_backend(
|
||||||
sender=sender,
|
sender=sender,
|
||||||
stream=stream,
|
stream=stream,
|
||||||
topic=Realm.STREAM_EVENTS_NOTIFICATION_TOPIC,
|
topic=Realm.STREAM_EVENTS_NOTIFICATION_TOPIC,
|
||||||
content=_('Stream created by @_**%(user_name)s|%(user_id)d**.') % {
|
content=_('Stream created by @_**{user_name}|{user_id}**.').format(
|
||||||
'user_name': user_profile.full_name,
|
user_name=user_profile.full_name,
|
||||||
'user_id': user_profile.id},
|
user_id=user_profile.id,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -675,11 +680,11 @@ def update_subscription_properties_backend(
|
||||||
value = change["value"]
|
value = change["value"]
|
||||||
|
|
||||||
if property not in property_converters:
|
if property not in property_converters:
|
||||||
return json_error(_("Unknown subscription property: %s") % (property,))
|
return json_error(_("Unknown subscription property: {}").format(property))
|
||||||
|
|
||||||
(stream, recipient, sub) = access_stream_by_id(user_profile, stream_id)
|
(stream, recipient, sub) = access_stream_by_id(user_profile, stream_id)
|
||||||
if sub is None:
|
if sub is None:
|
||||||
return json_error(_("Not subscribed to stream id %d") % (stream_id,))
|
return json_error(_("Not subscribed to stream id {}").format(stream_id))
|
||||||
|
|
||||||
property_conversion = property_converters[property](property, value)
|
property_conversion = property_converters[property](property, value)
|
||||||
if property_conversion:
|
if property_conversion:
|
||||||
|
|
|
@ -107,8 +107,9 @@ def upload_file_backend(request: HttpRequest, user_profile: UserProfile) -> Http
|
||||||
user_file = list(request.FILES.values())[0]
|
user_file = list(request.FILES.values())[0]
|
||||||
file_size = user_file.size
|
file_size = user_file.size
|
||||||
if settings.MAX_FILE_UPLOAD_SIZE * 1024 * 1024 < file_size:
|
if settings.MAX_FILE_UPLOAD_SIZE * 1024 * 1024 < file_size:
|
||||||
return json_error(_("Uploaded file is larger than the allowed limit of %s MB") % (
|
return json_error(_("Uploaded file is larger than the allowed limit of {} MiB").format(
|
||||||
settings.MAX_FILE_UPLOAD_SIZE))
|
settings.MAX_FILE_UPLOAD_SIZE,
|
||||||
|
))
|
||||||
check_upload_within_quota(user_profile.realm, file_size)
|
check_upload_within_quota(user_profile.realm, file_size)
|
||||||
|
|
||||||
uri = upload_message_image_from_request(request, user_file, user_profile)
|
uri = upload_message_image_from_request(request, user_file, user_profile)
|
||||||
|
|
|
@ -99,7 +99,9 @@ def add_members_to_group_backend(request: HttpRequest, user_profile: UserProfile
|
||||||
|
|
||||||
for user_profile in user_profiles:
|
for user_profile in user_profiles:
|
||||||
if user_profile.id in existing_member_ids:
|
if user_profile.id in existing_member_ids:
|
||||||
raise JsonableError(_("User %s is already a member of this group") % (user_profile.id,))
|
raise JsonableError(_("User {user_id} is already a member of this group").format(
|
||||||
|
user_id=user_profile.id,
|
||||||
|
))
|
||||||
|
|
||||||
bulk_add_members_to_user_group(user_group, user_profiles)
|
bulk_add_members_to_user_group(user_group, user_profiles)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
@ -114,7 +116,7 @@ def remove_members_from_group_backend(request: HttpRequest, user_profile: UserPr
|
||||||
group_member_ids = get_user_group_members(user_group)
|
group_member_ids = get_user_group_members(user_group)
|
||||||
for member in members:
|
for member in members:
|
||||||
if (member not in group_member_ids):
|
if (member not in group_member_ids):
|
||||||
raise JsonableError(_("There is no member '%s' in this user group") % (member,))
|
raise JsonableError(_("There is no member '{}' in this user group").format(member))
|
||||||
|
|
||||||
remove_members_from_user_group(user_group, user_profiles)
|
remove_members_from_user_group(user_group, user_profiles)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -95,7 +95,7 @@ def json_change_settings(request: HttpRequest, user_profile: UserProfile,
|
||||||
except RateLimited as e:
|
except RateLimited as e:
|
||||||
secs_to_freedom = int(float(str(e)))
|
secs_to_freedom = int(float(str(e)))
|
||||||
return json_error(
|
return json_error(
|
||||||
_("You're making too many attempts! Try again in %s seconds.") % (secs_to_freedom,),
|
_("You're making too many attempts! Try again in {} seconds.").format(secs_to_freedom),
|
||||||
)
|
)
|
||||||
|
|
||||||
if not check_password_strength(new_password):
|
if not check_password_strength(new_password):
|
||||||
|
@ -221,7 +221,7 @@ def json_change_notify_settings(
|
||||||
|
|
||||||
if (notification_sound is not None and
|
if (notification_sound is not None and
|
||||||
notification_sound not in get_available_notification_sounds()):
|
notification_sound not in get_available_notification_sounds()):
|
||||||
raise JsonableError(_("Invalid notification sound '%s'") % (notification_sound,))
|
raise JsonableError(_("Invalid notification sound '{}'").format(notification_sound))
|
||||||
|
|
||||||
req_vars = {k: v for k, v in list(locals().items()) if k in user_profile.notification_setting_types}
|
req_vars = {k: v for k, v in list(locals().items()) if k in user_profile.notification_setting_types}
|
||||||
|
|
||||||
|
@ -241,8 +241,9 @@ def set_avatar_backend(request: HttpRequest, user_profile: UserProfile) -> HttpR
|
||||||
|
|
||||||
user_file = list(request.FILES.values())[0]
|
user_file = list(request.FILES.values())[0]
|
||||||
if ((settings.MAX_AVATAR_FILE_SIZE * 1024 * 1024) < user_file.size):
|
if ((settings.MAX_AVATAR_FILE_SIZE * 1024 * 1024) < user_file.size):
|
||||||
return json_error(_("Uploaded file is larger than the allowed limit of %s MB") % (
|
return json_error(_("Uploaded file is larger than the allowed limit of {} MiB").format(
|
||||||
settings.MAX_AVATAR_FILE_SIZE))
|
settings.MAX_AVATAR_FILE_SIZE,
|
||||||
|
))
|
||||||
upload_avatar_image(user_file, user_profile, user_profile)
|
upload_avatar_image(user_file, user_profile, user_profile)
|
||||||
do_change_avatar_fields(user_profile, UserProfile.AVATAR_FROM_USER)
|
do_change_avatar_fields(user_profile, UserProfile.AVATAR_FROM_USER)
|
||||||
user_avatar_url = avatar_url(user_profile)
|
user_avatar_url = avatar_url(user_profile)
|
||||||
|
|
|
@ -479,8 +479,9 @@ def create_user_backend(request: HttpRequest, user_profile: UserProfile,
|
||||||
try:
|
try:
|
||||||
email_allowed_for_realm(email, user_profile.realm)
|
email_allowed_for_realm(email, user_profile.realm)
|
||||||
except DomainNotAllowedForRealmError:
|
except DomainNotAllowedForRealmError:
|
||||||
return json_error(_("Email '%(email)s' not allowed in this organization") %
|
return json_error(_("Email '{email}' not allowed in this organization").format(
|
||||||
{'email': email})
|
email=email,
|
||||||
|
))
|
||||||
except DisposableEmailError:
|
except DisposableEmailError:
|
||||||
return json_error(_("Disposable email addresses are not allowed in this organization"))
|
return json_error(_("Disposable email addresses are not allowed in this organization"))
|
||||||
except EmailContainsPlusError:
|
except EmailContainsPlusError:
|
||||||
|
@ -488,7 +489,7 @@ def create_user_backend(request: HttpRequest, user_profile: UserProfile,
|
||||||
|
|
||||||
try:
|
try:
|
||||||
get_user_by_delivery_email(email, user_profile.realm)
|
get_user_by_delivery_email(email, user_profile.realm)
|
||||||
return json_error(_("Email '%s' already in use") % (email,))
|
return json_error(_("Email '{}' already in use").format(email))
|
||||||
except UserProfile.DoesNotExist:
|
except UserProfile.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,7 @@ def api_freshdesk_webhook(request: HttpRequest, user_profile: UserProfile,
|
||||||
if ticket_data.get(key) is None:
|
if ticket_data.get(key) is None:
|
||||||
logging.warning("Freshdesk webhook error. Payload was:")
|
logging.warning("Freshdesk webhook error. Payload was:")
|
||||||
logging.warning(request.body)
|
logging.warning(request.body)
|
||||||
return json_error(_("Missing key %s in JSON") % (key,))
|
return json_error(_("Missing key {} in JSON").format(key))
|
||||||
|
|
||||||
ticket = TicketDict(ticket_data)
|
ticket = TicketDict(ticket_data)
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ def api_wordpress_webhook(request: HttpRequest, user_profile: UserProfile,
|
||||||
data = WP_LOGIN_TEMPLATE.format(name=user_login)
|
data = WP_LOGIN_TEMPLATE.format(name=user_login)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return json_error(_("Unknown WordPress webhook action: %s") % (hook,))
|
return json_error(_("Unknown WordPress webhook action: {}").format(hook))
|
||||||
|
|
||||||
topic = 'WordPress Notification'
|
topic = 'WordPress Notification'
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ def register_remote_server(
|
||||||
url_validator = URLValidator()
|
url_validator = URLValidator()
|
||||||
url_validator('http://' + hostname)
|
url_validator('http://' + hostname)
|
||||||
except ValidationError:
|
except ValidationError:
|
||||||
raise JsonableError(_('%s is not a valid hostname') % (hostname,))
|
raise JsonableError(_('{} is not a valid hostname').format(hostname))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
validate_email(contact_email)
|
validate_email(contact_email)
|
||||||
|
@ -179,7 +179,7 @@ def validate_incoming_table_data(server: RemoteZulipServer, model: Any,
|
||||||
last_id = get_last_id_from_server(server, model)
|
last_id = get_last_id_from_server(server, model)
|
||||||
for row in rows:
|
for row in rows:
|
||||||
if is_count_stat and row['property'] not in COUNT_STATS:
|
if is_count_stat and row['property'] not in COUNT_STATS:
|
||||||
raise JsonableError(_("Invalid property %s") % (row['property'],))
|
raise JsonableError(_("Invalid property {}").format(row['property']))
|
||||||
if row['id'] <= last_id:
|
if row['id'] <= last_id:
|
||||||
raise JsonableError(_("Data is out of order."))
|
raise JsonableError(_("Data is out of order."))
|
||||||
last_id = row['id']
|
last_id = row['id']
|
||||||
|
|
Loading…
Reference in New Issue