mirror of https://github.com/zulip/zulip.git
python: Manually convert more percent-formatting to f-strings.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
3461db7ef5
commit
5dc9b55c43
|
@ -47,7 +47,7 @@ def generate_time_series_data(days: int=100, business_hours_base: float=10,
|
||||||
raise AssertionError(f"Unknown frequency: {frequency}")
|
raise AssertionError(f"Unknown frequency: {frequency}")
|
||||||
if length < 2:
|
if length < 2:
|
||||||
raise AssertionError("Must be generating at least 2 data points. "
|
raise AssertionError("Must be generating at least 2 data points. "
|
||||||
"Currently generating %s" % (length,))
|
f"Currently generating {length}")
|
||||||
growth_base = growth ** (1. / (length-1))
|
growth_base = growth ** (1. / (length-1))
|
||||||
values_no_noise = [seasonality[i % len(seasonality)] * (growth_base**i) for i in range(length)]
|
values_no_noise = [seasonality[i % len(seasonality)] * (growth_base**i) for i in range(length)]
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ def analyze_activity(options: Dict[str, Any]) -> None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
total_duration += duration
|
total_duration += duration
|
||||||
print("%-*s%s" % (37, user_profile.email, duration))
|
print(f"{user_profile.email:<37}{duration}")
|
||||||
|
|
||||||
print(f"\nTotal Duration: {total_duration}")
|
print(f"\nTotal Duration: {total_duration}")
|
||||||
print(f"\nTotal Duration in minutes: {total_duration.total_seconds() / 60.}")
|
print(f"\nTotal Duration in minutes: {total_duration.total_seconds() / 60.}")
|
||||||
|
|
|
@ -60,8 +60,7 @@ class Command(BaseCommand):
|
||||||
critical_threshold = timedelta(minutes=150)
|
critical_threshold = timedelta(minutes=150)
|
||||||
|
|
||||||
if floor_function(last_fill) != last_fill:
|
if floor_function(last_fill) != last_fill:
|
||||||
return {'status': 2, 'message': 'FillState not on %s boundary for %s' %
|
return {'status': 2, 'message': f'FillState not on {stat.frequency} boundary for {property}'}
|
||||||
(stat.frequency, property)}
|
|
||||||
|
|
||||||
time_to_last_fill = timezone_now() - last_fill
|
time_to_last_fill = timezone_now() - last_fill
|
||||||
if time_to_last_fill > critical_threshold:
|
if time_to_last_fill > critical_threshold:
|
||||||
|
@ -72,7 +71,16 @@ class Command(BaseCommand):
|
||||||
if len(critical_unfilled_properties) == 0 and len(warning_unfilled_properties) == 0:
|
if len(critical_unfilled_properties) == 0 and len(warning_unfilled_properties) == 0:
|
||||||
return {'status': 0, 'message': 'FillState looks fine.'}
|
return {'status': 0, 'message': 'FillState looks fine.'}
|
||||||
if len(critical_unfilled_properties) == 0:
|
if len(critical_unfilled_properties) == 0:
|
||||||
return {'status': 1, 'message': 'Missed filling %s once.' %
|
return {
|
||||||
(', '.join(warning_unfilled_properties),)}
|
'status': 1,
|
||||||
return {'status': 2, 'message': 'Missed filling %s once. Missed filling %s at least twice.' %
|
'message': 'Missed filling {} once.'.format(
|
||||||
(', '.join(warning_unfilled_properties), ', '.join(critical_unfilled_properties))}
|
', '.join(warning_unfilled_properties),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
'status': 2,
|
||||||
|
'message': 'Missed filling {} once. Missed filling {} at least twice.'.format(
|
||||||
|
', '.join(warning_unfilled_properties),
|
||||||
|
', '.join(critical_unfilled_properties),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
|
@ -83,8 +83,7 @@ class Command(BaseCommand):
|
||||||
last = time.time()
|
last = time.time()
|
||||||
|
|
||||||
if options['verbose']:
|
if options['verbose']:
|
||||||
print("Finished updating analytics counts through %s in %.3fs" %
|
print(f"Finished updating analytics counts through {fill_to_time} in {time.time() - start:.3f}s")
|
||||||
(fill_to_time, time.time() - start))
|
|
||||||
logger.info("Finished updating analytics counts through %s", fill_to_time)
|
logger.info("Finished updating analytics counts through %s", fill_to_time)
|
||||||
|
|
||||||
if settings.PUSH_NOTIFICATION_BOUNCER_URL and settings.SUBMIT_USAGE_STATISTICS:
|
if settings.PUSH_NOTIFICATION_BOUNCER_URL and settings.SUBMIT_USAGE_STATISTICS:
|
||||||
|
|
|
@ -746,7 +746,7 @@ def user_activity_intervals() -> Tuple[mark_safe, Dict[str, float]]:
|
||||||
|
|
||||||
total_duration += duration
|
total_duration += duration
|
||||||
realm_duration += duration
|
realm_duration += duration
|
||||||
output += " %-*s%s\n" % (37, email, duration)
|
output += f" {email:<37}{duration}\n"
|
||||||
|
|
||||||
realm_minutes[string_id] = realm_duration.total_seconds() / 60
|
realm_minutes[string_id] = realm_duration.total_seconds() / 60
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ def next_month(billing_cycle_anchor: datetime, dt: datetime) -> datetime:
|
||||||
if 20 < (proposed_next_month - dt).days < 40:
|
if 20 < (proposed_next_month - dt).days < 40:
|
||||||
return proposed_next_month
|
return proposed_next_month
|
||||||
raise AssertionError('Something wrong in next_month calculation with '
|
raise AssertionError('Something wrong in next_month calculation with '
|
||||||
'billing_cycle_anchor: %s, dt: %s' % (billing_cycle_anchor, dt))
|
f'billing_cycle_anchor: {billing_cycle_anchor}, dt: {dt}')
|
||||||
|
|
||||||
def start_of_next_billing_cycle(plan: CustomerPlan, event_time: datetime) -> datetime:
|
def start_of_next_billing_cycle(plan: CustomerPlan, event_time: datetime) -> datetime:
|
||||||
if plan.status == CustomerPlan.FREE_TRIAL:
|
if plan.status == CustomerPlan.FREE_TRIAL:
|
||||||
|
|
|
@ -87,5 +87,4 @@ if recv_diff > 16 * 1024**2:
|
||||||
if replay_diff > 16 * 1024**2:
|
if replay_diff > 16 * 1024**2:
|
||||||
report('WARNING', f'secondary is {replay_diff} bytes behind on applying received xlog')
|
report('WARNING', f'secondary is {replay_diff} bytes behind on applying received xlog')
|
||||||
|
|
||||||
report('OK', ('secondary is %d bytes behind on receiving and %d bytes behind on applying xlog'
|
report('OK', f'secondary is {recv_diff} bytes behind on receiving and {replay_diff} bytes behind on applying xlog')
|
||||||
% (recv_diff, replay_diff)))
|
|
||||||
|
|
|
@ -173,7 +173,7 @@ def get_deployment_lock(error_rerun_script: str) -> None:
|
||||||
print(FAIL + "Deployment already in progress. Please run\n" +
|
print(FAIL + "Deployment already in progress. Please run\n" +
|
||||||
" {}\n".format(error_rerun_script) +
|
" {}\n".format(error_rerun_script) +
|
||||||
"manually when the previous deployment finishes, or run\n" +
|
"manually when the previous deployment finishes, or run\n" +
|
||||||
" rmdir %s\n" % (LOCK_DIR,) +
|
" rmdir {}\n".format(LOCK_DIR) +
|
||||||
"if the previous deployment crashed." +
|
"if the previous deployment crashed." +
|
||||||
ENDC)
|
ENDC)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
@ -189,9 +189,9 @@ def run(args: Sequence[str], **kwargs: Any) -> None:
|
||||||
subprocess.check_call(args, **kwargs)
|
subprocess.check_call(args, **kwargs)
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
print()
|
print()
|
||||||
print(WHITEONRED + "Error running a subcommand of %s: %s" %
|
print(WHITEONRED + "Error running a subcommand of {}: {}".format(
|
||||||
(sys.argv[0], " ".join(map(shlex.quote, args))) +
|
sys.argv[0], " ".join(map(shlex.quote, args)),
|
||||||
ENDC)
|
) + ENDC)
|
||||||
print(WHITEONRED + "Actual error output for the subcommand is just above this." +
|
print(WHITEONRED + "Actual error output for the subcommand is just above this." +
|
||||||
ENDC)
|
ENDC)
|
||||||
print()
|
print()
|
||||||
|
|
|
@ -98,12 +98,11 @@ if change_symlink and "PWD" in os.environ:
|
||||||
if os.path.commonprefix([os.environ["PWD"], symlink]) == symlink:
|
if os.path.commonprefix([os.environ["PWD"], symlink]) == symlink:
|
||||||
print(
|
print(
|
||||||
"""
|
"""
|
||||||
%sYour shell entered its current directory through a symlink:
|
{}Your shell entered its current directory through a symlink:
|
||||||
%s
|
{}
|
||||||
which has now changed. Your shell will not see this change until you run:
|
which has now changed. Your shell will not see this change until you run:
|
||||||
cd %s
|
cd {}
|
||||||
to traverse the symlink again.%s
|
to traverse the symlink again.{}
|
||||||
"""
|
""".format(WARNING, symlink, shlex.quote(os.environ["PWD"]), ENDC),
|
||||||
% (WARNING, symlink, shlex.quote(os.environ["PWD"]), ENDC),
|
|
||||||
file=sys.stderr,
|
file=sys.stderr,
|
||||||
)
|
)
|
||||||
|
|
|
@ -148,7 +148,7 @@ def generate_secrets(development: bool = False) -> None:
|
||||||
with open(filename, "a") as f:
|
with open(filename, "a") as f:
|
||||||
f.write(
|
f.write(
|
||||||
"# Set a Redis password based on zulip-secrets.conf\n"
|
"# Set a Redis password based on zulip-secrets.conf\n"
|
||||||
"requirepass '%s'\n" % (redis_password,),
|
f"requirepass '{redis_password}'\n",
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
|
@ -200,7 +200,7 @@ def validate_indent_html(fn: str, fix: bool) -> int:
|
||||||
# Since we successfully fixed the issues, we exit with status 0
|
# Since we successfully fixed the issues, we exit with status 0
|
||||||
return 0
|
return 0
|
||||||
print('Invalid Indentation detected in file: '
|
print('Invalid Indentation detected in file: '
|
||||||
'%s\nDiff for the file against expected indented file:' % (fn,), flush=True)
|
f'{fn}\nDiff for the file against expected indented file:', flush=True)
|
||||||
with subprocess.Popen(
|
with subprocess.Popen(
|
||||||
['diff', fn, '-'],
|
['diff', fn, '-'],
|
||||||
stdin=subprocess.PIPE,
|
stdin=subprocess.PIPE,
|
||||||
|
|
|
@ -311,10 +311,14 @@ def install_yum_deps(deps_to_install: List[str]) -> None:
|
||||||
# Later steps will ensure postgres is started
|
# Later steps will ensure postgres is started
|
||||||
|
|
||||||
# Link in tsearch data files
|
# Link in tsearch data files
|
||||||
overwrite_symlink("/usr/share/myspell/en_US.dic", "/usr/pgsql-%s/share/tsearch_data/en_us.dict"
|
overwrite_symlink(
|
||||||
% (POSTGRES_VERSION,))
|
"/usr/share/myspell/en_US.dic",
|
||||||
overwrite_symlink("/usr/share/myspell/en_US.aff", "/usr/pgsql-%s/share/tsearch_data/en_us.affix"
|
"/usr/pgsql-{}/share/tsearch_data/en_us.dict".format(POSTGRES_VERSION),
|
||||||
% (POSTGRES_VERSION,))
|
)
|
||||||
|
overwrite_symlink(
|
||||||
|
"/usr/share/myspell/en_US.aff",
|
||||||
|
"/usr/pgsql-{}/share/tsearch_data/en_us.affix".format(POSTGRES_VERSION,),
|
||||||
|
)
|
||||||
|
|
||||||
def main(options: argparse.Namespace) -> "NoReturn":
|
def main(options: argparse.Namespace) -> "NoReturn":
|
||||||
|
|
||||||
|
|
|
@ -2358,8 +2358,9 @@ def do_convert(content: str,
|
||||||
# rest of the codebase from any bugs where we end up rendering
|
# rest of the codebase from any bugs where we end up rendering
|
||||||
# something huge.
|
# something huge.
|
||||||
if len(rendered_content) > MAX_MESSAGE_LENGTH * 10:
|
if len(rendered_content) > MAX_MESSAGE_LENGTH * 10:
|
||||||
raise BugdownRenderingException('Rendered content exceeds %s characters (message %s)' %
|
raise BugdownRenderingException(
|
||||||
(MAX_MESSAGE_LENGTH * 10, logging_message_id))
|
f'Rendered content exceeds {MAX_MESSAGE_LENGTH * 10} characters (message {logging_message_id})'
|
||||||
|
)
|
||||||
return rendered_content
|
return rendered_content
|
||||||
except Exception:
|
except Exception:
|
||||||
cleaned = privacy_clean_markdown(content)
|
cleaned = privacy_clean_markdown(content)
|
||||||
|
|
|
@ -309,8 +309,7 @@ def do_send_missedmessage_events_reply_in_zulip(user_profile: UserProfile,
|
||||||
recipients = {(msg['message'].recipient_id, msg['message'].topic_name()) for msg in missed_messages}
|
recipients = {(msg['message'].recipient_id, msg['message'].topic_name()) for msg in missed_messages}
|
||||||
if len(recipients) != 1:
|
if len(recipients) != 1:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'All missed_messages must have the same recipient and topic %r' %
|
f'All missed_messages must have the same recipient and topic {recipients!r}',
|
||||||
(recipients,),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# This link is no longer a part of the email, but keeping the code in case
|
# This link is no longer a part of the email, but keeping the code in case
|
||||||
|
|
|
@ -20,16 +20,15 @@ def format_email_subject(email_subject: str) -> str:
|
||||||
return email_subject.replace('\n', '\\n').replace('\r', '\\r')
|
return email_subject.replace('\n', '\\n').replace('\r', '\\r')
|
||||||
|
|
||||||
def logger_repr(report: Dict[str, Any]) -> str:
|
def logger_repr(report: Dict[str, Any]) -> str:
|
||||||
return ("Logger %(logger_name)s, from module %(log_module)s line %(log_lineno)d:"
|
return "Logger {logger_name}, from module {log_module} line {log_lineno}:".format(**report)
|
||||||
% dict(report))
|
|
||||||
|
|
||||||
def user_info_str(report: Dict[str, Any]) -> str:
|
def user_info_str(report: Dict[str, Any]) -> str:
|
||||||
if report['user_full_name'] and report['user_email']:
|
if report['user_full_name'] and report['user_email']:
|
||||||
user_info = "%(user_full_name)s (%(user_email)s)" % dict(report)
|
user_info = "{user_full_name} ({user_email})".format(**report)
|
||||||
else:
|
else:
|
||||||
user_info = "Anonymous user (not logged in)"
|
user_info = "Anonymous user (not logged in)"
|
||||||
|
|
||||||
user_info += " on %s deployment" % (report['deployment'],)
|
user_info += " on {deployment} deployment".format(**report)
|
||||||
return user_info
|
return user_info
|
||||||
|
|
||||||
def deployment_repr(report: Dict[str, Any]) -> str:
|
def deployment_repr(report: Dict[str, Any]) -> str:
|
||||||
|
@ -47,14 +46,21 @@ def notify_browser_error(report: Dict[str, Any]) -> None:
|
||||||
def email_browser_error(report: Dict[str, Any]) -> None:
|
def email_browser_error(report: Dict[str, Any]) -> None:
|
||||||
email_subject = f"Browser error for {user_info_str(report)}"
|
email_subject = f"Browser error for {user_info_str(report)}"
|
||||||
|
|
||||||
body = ("User: %(user_full_name)s <%(user_email)s> on %(deployment)s\n\n"
|
body = """\
|
||||||
"Message:\n%(message)s\n\nStacktrace:\n%(stacktrace)s\n\n"
|
User: {user_full_name} <{user_email}> on {deployment}
|
||||||
"IP address: %(ip_address)s\n"
|
|
||||||
"User agent: %(user_agent)s\n"
|
Message:
|
||||||
"href: %(href)s\n"
|
{message}
|
||||||
"Server path: %(server_path)s\n"
|
|
||||||
"Deployed version: %(version)s\n"
|
Stacktrace:
|
||||||
% dict(report))
|
{stacktrace}
|
||||||
|
|
||||||
|
IP address: {ip_address}
|
||||||
|
User agent: {user_agent}
|
||||||
|
href: {href}
|
||||||
|
Server path: {server_path}
|
||||||
|
Deployed version: {version}
|
||||||
|
""".format(**report)
|
||||||
|
|
||||||
more_info = report['more_info']
|
more_info = report['more_info']
|
||||||
if more_info is not None:
|
if more_info is not None:
|
||||||
|
@ -62,18 +68,17 @@ def email_browser_error(report: Dict[str, Any]) -> None:
|
||||||
for (key, value) in more_info.items():
|
for (key, value) in more_info.items():
|
||||||
body += f"\n {key}: {value}"
|
body += f"\n {key}: {value}"
|
||||||
|
|
||||||
body += "\n\nLog:\n{}".format(report['log'])
|
body += "\n\nLog:\n{log}".format(**report)
|
||||||
|
|
||||||
mail_admins(email_subject, body)
|
mail_admins(email_subject, body)
|
||||||
|
|
||||||
def zulip_browser_error(report: Dict[str, Any]) -> None:
|
def zulip_browser_error(report: Dict[str, Any]) -> None:
|
||||||
email_subject = "JS error: {}".format(report['user_email'])
|
email_subject = "JS error: {user_email}".format(**report)
|
||||||
|
|
||||||
user_info = user_info_str(report)
|
user_info = user_info_str(report)
|
||||||
|
|
||||||
body = f"User: {user_info}\n"
|
body = f"User: {user_info}\n"
|
||||||
body += ("Message: %(message)s\n"
|
body += "Message: {message}\n".format(**report)
|
||||||
% dict(report))
|
|
||||||
|
|
||||||
error_bot = get_system_bot(settings.ERROR_BOT)
|
error_bot = get_system_bot(settings.ERROR_BOT)
|
||||||
realm = error_bot.realm
|
realm = error_bot.realm
|
||||||
|
@ -94,17 +99,19 @@ def notify_server_error(report: Dict[str, Any], skip_error_zulip: bool=False) ->
|
||||||
zulip_server_error(report)
|
zulip_server_error(report)
|
||||||
|
|
||||||
def zulip_server_error(report: Dict[str, Any]) -> None:
|
def zulip_server_error(report: Dict[str, Any]) -> None:
|
||||||
email_subject = '%(node)s: %(message)s' % dict(report)
|
email_subject = '{node}: {message}'.format(**report)
|
||||||
|
|
||||||
logger_str = logger_repr(report)
|
logger_str = logger_repr(report)
|
||||||
user_info = user_info_str(report)
|
user_info = user_info_str(report)
|
||||||
deployment = deployment_repr(report)
|
deployment = deployment_repr(report)
|
||||||
|
|
||||||
if report['has_request']:
|
if report['has_request']:
|
||||||
request_repr = (
|
request_repr = """\
|
||||||
"Request info:\n~~~~\n"
|
Request info:
|
||||||
"- path: %(path)s\n"
|
~~~~
|
||||||
"- %(method)s: %(data)s\n") % dict(report)
|
- path: {path}
|
||||||
|
- {method}: {data}
|
||||||
|
""".format(**report)
|
||||||
for field in ["REMOTE_ADDR", "QUERY_STRING", "SERVER_NAME"]:
|
for field in ["REMOTE_ADDR", "QUERY_STRING", "SERVER_NAME"]:
|
||||||
val = report.get(field.lower())
|
val = report.get(field.lower())
|
||||||
if field == "QUERY_STRING":
|
if field == "QUERY_STRING":
|
||||||
|
@ -114,8 +121,15 @@ def zulip_server_error(report: Dict[str, Any]) -> None:
|
||||||
else:
|
else:
|
||||||
request_repr = "Request info: none"
|
request_repr = "Request info: none"
|
||||||
|
|
||||||
message = ("%s\nError generated by %s\n\n~~~~ pytb\n%s\n\n~~~~\n%s\n%s"
|
message = f"""{logger_str}
|
||||||
% (logger_str, user_info, report['stack_trace'], deployment, request_repr))
|
Error generated by {user_info}
|
||||||
|
|
||||||
|
~~~~ pytb
|
||||||
|
{report['stack_trace']}
|
||||||
|
|
||||||
|
~~~~
|
||||||
|
{deployment}
|
||||||
|
{request_repr}"""
|
||||||
|
|
||||||
error_bot = get_system_bot(settings.ERROR_BOT)
|
error_bot = get_system_bot(settings.ERROR_BOT)
|
||||||
realm = error_bot.realm
|
realm = error_bot.realm
|
||||||
|
@ -130,17 +144,18 @@ def zulip_server_error(report: Dict[str, Any]) -> None:
|
||||||
)
|
)
|
||||||
|
|
||||||
def email_server_error(report: Dict[str, Any]) -> None:
|
def email_server_error(report: Dict[str, Any]) -> None:
|
||||||
email_subject = '%(node)s: %(message)s' % dict(report)
|
email_subject = '{node}: {message}'.format(**report)
|
||||||
|
|
||||||
logger_str = logger_repr(report)
|
logger_str = logger_repr(report)
|
||||||
user_info = user_info_str(report)
|
user_info = user_info_str(report)
|
||||||
deployment = deployment_repr(report)
|
deployment = deployment_repr(report)
|
||||||
|
|
||||||
if report['has_request']:
|
if report['has_request']:
|
||||||
request_repr = (
|
request_repr = """\
|
||||||
"Request info:\n"
|
Request info:
|
||||||
"- path: %(path)s\n"
|
- path: {path}
|
||||||
"- %(method)s: %(data)s\n") % dict(report)
|
- {method}: {data}
|
||||||
|
""".format(**report)
|
||||||
for field in ["REMOTE_ADDR", "QUERY_STRING", "SERVER_NAME"]:
|
for field in ["REMOTE_ADDR", "QUERY_STRING", "SERVER_NAME"]:
|
||||||
val = report.get(field.lower())
|
val = report.get(field.lower())
|
||||||
if field == "QUERY_STRING":
|
if field == "QUERY_STRING":
|
||||||
|
@ -149,8 +164,15 @@ def email_server_error(report: Dict[str, Any]) -> None:
|
||||||
else:
|
else:
|
||||||
request_repr = "Request info: none\n"
|
request_repr = "Request info: none\n"
|
||||||
|
|
||||||
message = ("%s\nError generated by %s\n\n%s\n\n%s\n\n%s"
|
message = f"""\
|
||||||
% (logger_str, user_info, report['stack_trace'], deployment, request_repr))
|
{logger_str}
|
||||||
|
Error generated by {user_info}
|
||||||
|
|
||||||
|
{report['stack_trace']}
|
||||||
|
|
||||||
|
{deployment}
|
||||||
|
|
||||||
|
{request_repr}"""
|
||||||
|
|
||||||
mail_admins(format_email_subject(email_subject), message, fail_silently=True)
|
mail_admins(format_email_subject(email_subject), message, fail_silently=True)
|
||||||
|
|
||||||
|
|
|
@ -83,8 +83,7 @@ You can use the command list_realms to find ID of the realms in this server."""
|
||||||
return Realm.objects.get(id=val)
|
return Realm.objects.get(id=val)
|
||||||
return Realm.objects.get(string_id=val)
|
return Realm.objects.get(string_id=val)
|
||||||
except Realm.DoesNotExist:
|
except Realm.DoesNotExist:
|
||||||
raise CommandError("There is no realm with id '%s'. Aborting." %
|
raise CommandError("There is no realm with id '{}'. Aborting.".format(options["realm_id"]))
|
||||||
(options["realm_id"],))
|
|
||||||
|
|
||||||
def get_users(self, options: Dict[str, Any], realm: Optional[Realm],
|
def get_users(self, options: Dict[str, Any], realm: Optional[Realm],
|
||||||
is_bot: Optional[bool]=None,
|
is_bot: Optional[bool]=None,
|
||||||
|
|
|
@ -236,11 +236,10 @@ def notify_bot_owner(event: Dict[str, Any],
|
||||||
notification_message += f"\nThe webhook got a response with status code *{status_code}*."
|
notification_message += f"\nThe webhook got a response with status code *{status_code}*."
|
||||||
if response_content:
|
if response_content:
|
||||||
notification_message += "\nThe response contains the following payload:\n" \
|
notification_message += "\nThe response contains the following payload:\n" \
|
||||||
"```\n%s\n```" % (str(response_content),)
|
f"```\n{response_content!r}\n```"
|
||||||
if exception:
|
if exception:
|
||||||
notification_message += "\nWhen trying to send a request to the webhook service, an exception " \
|
notification_message += "\nWhen trying to send a request to the webhook service, an exception " \
|
||||||
"of type %s occurred:\n```\n%s\n```" % (
|
f"of type {type(exception).__name__} occurred:\n```\n{exception}\n```"
|
||||||
type(exception).__name__, str(exception))
|
|
||||||
|
|
||||||
message_info = dict(
|
message_info = dict(
|
||||||
type='private',
|
type='private',
|
||||||
|
@ -329,9 +328,10 @@ def do_rest_call(base_url: str,
|
||||||
request_retry(event, failure_message=failure_message)
|
request_retry(event, failure_message=failure_message)
|
||||||
|
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
response_message = ("An exception of type *%s* occurred for message `%s`! "
|
response_message = (
|
||||||
"See the Zulip server logs for more information." % (
|
f"An exception of type *{type(e).__name__}* occurred for message `{event['command']}`! "
|
||||||
type(e).__name__, event["command"]))
|
"See the Zulip server logs for more information."
|
||||||
|
)
|
||||||
logging.exception("Outhook trigger failed:")
|
logging.exception("Outhook trigger failed:")
|
||||||
fail_with_message(event, response_message)
|
fail_with_message(event, response_message)
|
||||||
notify_bot_owner(event, exception=e)
|
notify_bot_owner(event, exception=e)
|
||||||
|
|
|
@ -128,14 +128,12 @@ class EmailNotDeliveredException(Exception):
|
||||||
|
|
||||||
class DoubledEmailArgumentException(CommandError):
|
class DoubledEmailArgumentException(CommandError):
|
||||||
def __init__(self, argument_name: str) -> None:
|
def __init__(self, argument_name: str) -> None:
|
||||||
msg = "Argument '%s' is ambiguously present in both options and email template." % (
|
msg = f"Argument '{argument_name}' is ambiguously present in both options and email template."
|
||||||
argument_name)
|
|
||||||
super().__init__(msg)
|
super().__init__(msg)
|
||||||
|
|
||||||
class NoEmailArgumentException(CommandError):
|
class NoEmailArgumentException(CommandError):
|
||||||
def __init__(self, argument_name: str) -> None:
|
def __init__(self, argument_name: str) -> None:
|
||||||
msg = "Argument '%s' is required in either options or email template." % (
|
msg = f"Argument '{argument_name}' is required in either options or email template."
|
||||||
argument_name)
|
|
||||||
super().__init__(msg)
|
super().__init__(msg)
|
||||||
|
|
||||||
# When changing the arguments to this function, you may need to write a
|
# When changing the arguments to this function, you may need to write a
|
||||||
|
|
|
@ -60,8 +60,7 @@ class SourceMap:
|
||||||
webpack_prefix = "webpack:///"
|
webpack_prefix = "webpack:///"
|
||||||
if display_src.startswith(webpack_prefix):
|
if display_src.startswith(webpack_prefix):
|
||||||
display_src = display_src[len(webpack_prefix):]
|
display_src = display_src[len(webpack_prefix):]
|
||||||
out += (' = %s line %d column %d\n' %
|
out += f' = {display_src} line {result.src_line+1} column {result.src_col+1}\n'
|
||||||
(display_src, result.src_line+1, result.src_col+1))
|
|
||||||
except IndexError:
|
except IndexError:
|
||||||
out += ' [Unable to look up in source map]\n'
|
out += ' [Unable to look up in source map]\n'
|
||||||
|
|
||||||
|
|
|
@ -49,8 +49,9 @@ class Command(BaseCommand):
|
||||||
raise CommandError('Please supply a MailChimp List ID to --list-id, or add a '
|
raise CommandError('Please supply a MailChimp List ID to --list-id, or add a '
|
||||||
'ZULIP_FRIENDS_LIST_ID to your server settings file.')
|
'ZULIP_FRIENDS_LIST_ID to your server settings file.')
|
||||||
|
|
||||||
endpoint = "https://%s.api.mailchimp.com/3.0/lists/%s/members" % \
|
endpoint = "https://{}.api.mailchimp.com/3.0/lists/{}/members".format(
|
||||||
(api_key.split('-')[1], options['list_id'])
|
api_key.split('-')[1], options['list_id'],
|
||||||
|
)
|
||||||
|
|
||||||
for user in UserProfile.objects.filter(is_bot=False, is_active=True) \
|
for user in UserProfile.objects.filter(is_bot=False, is_active=True) \
|
||||||
.values('email', 'full_name', 'realm_id'):
|
.values('email', 'full_name', 'realm_id'):
|
||||||
|
|
|
@ -121,8 +121,7 @@ class Command(ZulipBaseCommand):
|
||||||
if os.path.exists(output_dir):
|
if os.path.exists(output_dir):
|
||||||
if os.listdir(output_dir):
|
if os.listdir(output_dir):
|
||||||
raise CommandError(
|
raise CommandError(
|
||||||
"Refusing to overwrite nonempty directory: %s. Aborting..."
|
f"Refusing to overwrite nonempty directory: {output_dir}. Aborting...",
|
||||||
% (output_dir,),
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
os.makedirs(output_dir)
|
os.makedirs(output_dir)
|
||||||
|
|
|
@ -51,8 +51,8 @@ class Command(ZulipBaseCommand):
|
||||||
allow_subdomains=options["allow_subdomains"])
|
allow_subdomains=options["allow_subdomains"])
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
raise CommandError("The domain %(domain)s is already a part "
|
raise CommandError(f"The domain {domain} is already a part "
|
||||||
"of your organization." % {'domain': domain})
|
"of your organization.")
|
||||||
elif options["op"] == "remove":
|
elif options["op"] == "remove":
|
||||||
try:
|
try:
|
||||||
RealmDomain.objects.get(realm=realm, domain=domain).delete()
|
RealmDomain.objects.get(realm=realm, domain=domain).delete()
|
||||||
|
|
|
@ -73,8 +73,10 @@ class Command(ZulipBaseCommand):
|
||||||
try:
|
try:
|
||||||
response = requests.post(registration_url, params=request)
|
response = requests.post(registration_url, params=request)
|
||||||
except Exception:
|
except Exception:
|
||||||
raise CommandError("Network error connecting to push notifications service (%s)"
|
raise CommandError(
|
||||||
% (settings.PUSH_NOTIFICATION_BOUNCER_URL,))
|
"Network error connecting to push notifications service "
|
||||||
|
f"({settings.PUSH_NOTIFICATION_BOUNCER_URL})",
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
|
@ -25,8 +25,11 @@ def get_users_from_emails(emails: List[str],
|
||||||
if len(users) != len(emails):
|
if len(users) != len(emails):
|
||||||
user_emails_found = {user.delivery_email for user in users}
|
user_emails_found = {user.delivery_email for user in users}
|
||||||
user_emails_not_found = '\n'.join(set(emails) - user_emails_found)
|
user_emails_not_found = '\n'.join(set(emails) - user_emails_found)
|
||||||
raise CommandError('Users with the following emails were not found:\n\n%s\n\n'
|
raise CommandError(
|
||||||
'Check if they are correct.' % (user_emails_not_found,))
|
'Users with the following emails were not found:\n\n'
|
||||||
|
f'{user_emails_not_found}\n\n'
|
||||||
|
'Check if they are correct.',
|
||||||
|
)
|
||||||
return users
|
return users
|
||||||
|
|
||||||
class Command(ZulipBaseCommand):
|
class Command(ZulipBaseCommand):
|
||||||
|
|
|
@ -193,13 +193,8 @@ def write_log_line(log_data: MutableMapping[str, Any], path: str, method: str, r
|
||||||
else:
|
else:
|
||||||
extra_request_data = ""
|
extra_request_data = ""
|
||||||
logger_client = f"({requestor_for_logs} via {client_name})"
|
logger_client = f"({requestor_for_logs} via {client_name})"
|
||||||
logger_timing = ('%5s%s%s%s%s%s %s' %
|
logger_timing = f'{format_timedelta(time_delta):>5}{optional_orig_delta}{remote_cache_output}{bugdown_output}{db_time_output}{startup_output} {path}'
|
||||||
(format_timedelta(time_delta), optional_orig_delta,
|
logger_line = f'{remote_ip:<15} {method:<7} {status_code:3} {logger_timing}{extra_request_data} {logger_client}'
|
||||||
remote_cache_output, bugdown_output,
|
|
||||||
db_time_output, startup_output, path))
|
|
||||||
logger_line = ('%-15s %-7s %3d %s%s %s' %
|
|
||||||
(remote_ip, method, status_code,
|
|
||||||
logger_timing, extra_request_data, logger_client))
|
|
||||||
if (status_code in [200, 304] and method == "GET" and path.startswith("/static")):
|
if (status_code in [200, 304] and method == "GET" and path.startswith("/static")):
|
||||||
logger.debug(logger_line)
|
logger.debug(logger_line)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -24,8 +24,7 @@ def realm_emoji_name_to_id(apps: StateApps, schema_editor: DatabaseSchemaEditor)
|
||||||
# Realm emoji used in this reaction has been deleted so this
|
# Realm emoji used in this reaction has been deleted so this
|
||||||
# reaction should also be deleted. We don't need to reverse
|
# reaction should also be deleted. We don't need to reverse
|
||||||
# this step in migration reversal code.
|
# this step in migration reversal code.
|
||||||
print("Reaction for (%s, %s) refers to deleted custom emoji %s; deleting" %
|
print(f"Reaction for ({emoji_name}, {reaction.message_id}) refers to deleted custom emoji {reaction.user_profile_id}; deleting")
|
||||||
(emoji_name, reaction.message_id, reaction.user_profile_id))
|
|
||||||
reaction.delete()
|
reaction.delete()
|
||||||
else:
|
else:
|
||||||
reaction.emoji_code = realm_emoji["id"]
|
reaction.emoji_code = realm_emoji["id"]
|
||||||
|
|
|
@ -819,8 +819,7 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase):
|
||||||
|
|
||||||
expected_result_url_prefix = f'http://testserver/login/{self.backend.name}/'
|
expected_result_url_prefix = f'http://testserver/login/{self.backend.name}/'
|
||||||
if settings.SOCIAL_AUTH_SUBDOMAIN is not None:
|
if settings.SOCIAL_AUTH_SUBDOMAIN is not None:
|
||||||
expected_result_url_prefix = ('http://%s.testserver/login/%s/' %
|
expected_result_url_prefix = f'http://{settings.SOCIAL_AUTH_SUBDOMAIN}.testserver/login/{self.backend.name}/'
|
||||||
(settings.SOCIAL_AUTH_SUBDOMAIN, self.backend.name))
|
|
||||||
|
|
||||||
if result.status_code != 302 or not result.url.startswith(expected_result_url_prefix):
|
if result.status_code != 302 or not result.url.startswith(expected_result_url_prefix):
|
||||||
return result
|
return result
|
||||||
|
@ -1773,8 +1772,8 @@ class SAMLAuthBackendTest(SocialAuthBase):
|
||||||
self.assertEqual(result.status_code, 302)
|
self.assertEqual(result.status_code, 302)
|
||||||
self.assertEqual('/login/', result.url)
|
self.assertEqual('/login/', result.url)
|
||||||
self.assertEqual(m.output, [self.logger_output(
|
self.assertEqual(m.output, [self.logger_output(
|
||||||
'/complete/saml/: Authentication request with IdP %s but this provider is not enabled '
|
'/complete/saml/: Authentication request with IdP test_idp but this provider is not enabled '
|
||||||
'for this subdomain %s.' % ("test_idp", "zephyr"), 'info',
|
'for this subdomain zephyr.', 'info',
|
||||||
)])
|
)])
|
||||||
|
|
||||||
def test_social_auth_saml_login_bad_idp_arg(self) -> None:
|
def test_social_auth_saml_login_bad_idp_arg(self) -> None:
|
||||||
|
@ -1908,7 +1907,7 @@ class SAMLAuthBackendTest(SocialAuthBase):
|
||||||
self.assertEqual(result.status_code, 302)
|
self.assertEqual(result.status_code, 302)
|
||||||
self.assertEqual('/login/', result.url)
|
self.assertEqual('/login/', result.url)
|
||||||
self.assertEqual(m.output, [self.logger_output(
|
self.assertEqual(m.output, [self.logger_output(
|
||||||
"/complete/saml/: Can't figure out subdomain for this authentication request. relayed_params: %s" % {},
|
"/complete/saml/: Can't figure out subdomain for this authentication request. relayed_params: {}",
|
||||||
"info",
|
"info",
|
||||||
)])
|
)])
|
||||||
|
|
||||||
|
@ -2598,8 +2597,8 @@ class GitHubAuthBackendTest(SocialAuthBase):
|
||||||
self.assertEqual(result.status_code, 302)
|
self.assertEqual(result.status_code, 302)
|
||||||
self.assertEqual(result.url, "/login/")
|
self.assertEqual(result.url, "/login/")
|
||||||
self.assertEqual(m.output, [self.logger_output(
|
self.assertEqual(m.output, [self.logger_output(
|
||||||
"Social auth (%s) failed because user has no verified"
|
"Social auth (GitHub) failed because user has no verified"
|
||||||
" emails associated with the account" % ("GitHub",),
|
" emails associated with the account",
|
||||||
"warning",
|
"warning",
|
||||||
)])
|
)])
|
||||||
|
|
||||||
|
@ -2622,8 +2621,8 @@ class GitHubAuthBackendTest(SocialAuthBase):
|
||||||
self.assertEqual(result.status_code, 302)
|
self.assertEqual(result.status_code, 302)
|
||||||
self.assertEqual(result.url, "/login/")
|
self.assertEqual(result.url, "/login/")
|
||||||
self.assertEqual(m.output, [self.logger_output(
|
self.assertEqual(m.output, [self.logger_output(
|
||||||
"Social auth (%s) failed because user has no verified"
|
"Social auth (GitHub) failed because user has no verified"
|
||||||
" emails associated with the account" % ("GitHub",),
|
" emails associated with the account",
|
||||||
"warning",
|
"warning",
|
||||||
)])
|
)])
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ from zerver.models import (
|
||||||
# A test validator
|
# A test validator
|
||||||
def _check_string(var_name: str, val: object) -> Optional[str]:
|
def _check_string(var_name: str, val: object) -> Optional[str]:
|
||||||
if str(val).startswith("_"):
|
if str(val).startswith("_"):
|
||||||
return ('%s starts with a "_" and is hence invalid.') % (var_name,)
|
return f'{var_name} starts with a "_" and is hence invalid.'
|
||||||
return None
|
return None
|
||||||
|
|
||||||
stripe_sample_config_options = [
|
stripe_sample_config_options = [
|
||||||
|
|
|
@ -745,17 +745,17 @@ class BugdownTest(ZulipTestCase):
|
||||||
## As of right now, all previews are mocked to be the exact same tweet
|
## As of right now, all previews are mocked to be the exact same tweet
|
||||||
return ('<div class="inline-preview-twitter">'
|
return ('<div class="inline-preview-twitter">'
|
||||||
'<div class="twitter-tweet">'
|
'<div class="twitter-tweet">'
|
||||||
'<a href="%s">'
|
f'<a href="{url}">'
|
||||||
'<img class="twitter-avatar"'
|
'<img class="twitter-avatar"'
|
||||||
' src="https://external-content.zulipcdn.net/external_content/1f7cd2436976d410eab8189ebceda87ae0b34ead/687474703a2f2f7062732e7477696d672e63'
|
' src="https://external-content.zulipcdn.net/external_content/1f7cd2436976d410eab8189ebceda87ae0b34ead/687474703a2f2f7062732e7477696d672e63'
|
||||||
'6f6d2f70726f66696c655f696d616765732f313338303931323137332f53637265656e5f73686f745f323031312d30362d30335f61745f372e33352e33'
|
'6f6d2f70726f66696c655f696d616765732f313338303931323137332f53637265656e5f73686f745f323031312d30362d30335f61745f372e33352e33'
|
||||||
'365f504d5f6e6f726d616c2e706e67">'
|
'365f504d5f6e6f726d616c2e706e67">'
|
||||||
'</a>'
|
'</a>'
|
||||||
'<p>%s</p>'
|
f'<p>{tweet_html}</p>'
|
||||||
'<span>- Eoin McMillan (@imeoin)</span>'
|
'<span>- Eoin McMillan (@imeoin)</span>'
|
||||||
'%s'
|
f'{image_html}'
|
||||||
'</div>'
|
'</div>'
|
||||||
'</div>') % (url, tweet_html, image_html)
|
'</div>')
|
||||||
|
|
||||||
msg = 'http://www.twitter.com'
|
msg = 'http://www.twitter.com'
|
||||||
converted = bugdown_convert(msg)
|
converted = bugdown_convert(msg)
|
||||||
|
@ -1451,8 +1451,8 @@ class BugdownTest(ZulipTestCase):
|
||||||
content = "@**King Hamlet**"
|
content = "@**King Hamlet**"
|
||||||
self.assertEqual(render_markdown(msg, content),
|
self.assertEqual(render_markdown(msg, content),
|
||||||
'<p><span class="user-mention" '
|
'<p><span class="user-mention" '
|
||||||
'data-user-id="%s">'
|
f'data-user-id="{user_id}">'
|
||||||
'@King Hamlet</span></p>' % (user_id,))
|
'@King Hamlet</span></p>')
|
||||||
self.assertEqual(msg.mentions_user_ids, {user_profile.id})
|
self.assertEqual(msg.mentions_user_ids, {user_profile.id})
|
||||||
|
|
||||||
def test_mention_silent(self) -> None:
|
def test_mention_silent(self) -> None:
|
||||||
|
@ -1464,8 +1464,8 @@ class BugdownTest(ZulipTestCase):
|
||||||
content = "@_**King Hamlet**"
|
content = "@_**King Hamlet**"
|
||||||
self.assertEqual(render_markdown(msg, content),
|
self.assertEqual(render_markdown(msg, content),
|
||||||
'<p><span class="user-mention silent" '
|
'<p><span class="user-mention silent" '
|
||||||
'data-user-id="%s">'
|
f'data-user-id="{user_id}">'
|
||||||
'King Hamlet</span></p>' % (user_id,))
|
'King Hamlet</span></p>')
|
||||||
self.assertEqual(msg.mentions_user_ids, set())
|
self.assertEqual(msg.mentions_user_ids, set())
|
||||||
|
|
||||||
def test_possible_mentions(self) -> None:
|
def test_possible_mentions(self) -> None:
|
||||||
|
@ -1493,10 +1493,10 @@ class BugdownTest(ZulipTestCase):
|
||||||
self.assertEqual(render_markdown(msg, content),
|
self.assertEqual(render_markdown(msg, content),
|
||||||
'<p>'
|
'<p>'
|
||||||
'<span class="user-mention" '
|
'<span class="user-mention" '
|
||||||
'data-user-id="%s">@King Hamlet</span> and '
|
f'data-user-id="{hamlet.id}">@King Hamlet</span> and '
|
||||||
'<span class="user-mention" '
|
'<span class="user-mention" '
|
||||||
'data-user-id="%s">@Cordelia Lear</span>, '
|
f'data-user-id="{cordelia.id}">@Cordelia Lear</span>, '
|
||||||
'check this out</p>' % (hamlet.id, cordelia.id))
|
'check this out</p>')
|
||||||
self.assertEqual(msg.mentions_user_ids, {hamlet.id, cordelia.id})
|
self.assertEqual(msg.mentions_user_ids, {hamlet.id, cordelia.id})
|
||||||
|
|
||||||
def test_mention_in_quotes(self) -> None:
|
def test_mention_in_quotes(self) -> None:
|
||||||
|
@ -1508,21 +1508,21 @@ class BugdownTest(ZulipTestCase):
|
||||||
content = "> @**King Hamlet** and @**Othello, the Moor of Venice**\n\n @**King Hamlet** and @**Cordelia Lear**"
|
content = "> @**King Hamlet** and @**Othello, the Moor of Venice**\n\n @**King Hamlet** and @**Cordelia Lear**"
|
||||||
self.assertEqual(render_markdown(msg, content),
|
self.assertEqual(render_markdown(msg, content),
|
||||||
'<blockquote>\n<p>'
|
'<blockquote>\n<p>'
|
||||||
'<span class="user-mention silent" data-user-id="%s">King Hamlet</span>'
|
f'<span class="user-mention silent" data-user-id="{hamlet.id}">King Hamlet</span>'
|
||||||
' and '
|
' and '
|
||||||
'<span class="user-mention silent" data-user-id="%s">Othello, the Moor of Venice</span>'
|
f'<span class="user-mention silent" data-user-id="{othello.id}">Othello, the Moor of Venice</span>'
|
||||||
'</p>\n</blockquote>\n'
|
'</p>\n</blockquote>\n'
|
||||||
'<p>'
|
'<p>'
|
||||||
'<span class="user-mention" data-user-id="%s">@King Hamlet</span>'
|
f'<span class="user-mention" data-user-id="{hamlet.id}">@King Hamlet</span>'
|
||||||
' and '
|
' and '
|
||||||
'<span class="user-mention" data-user-id="%s">@Cordelia Lear</span>'
|
f'<span class="user-mention" data-user-id="{cordelia.id}">@Cordelia Lear</span>'
|
||||||
'</p>' % (hamlet.id, othello.id, hamlet.id, cordelia.id))
|
'</p>')
|
||||||
self.assertEqual(msg.mentions_user_ids, {hamlet.id, cordelia.id})
|
self.assertEqual(msg.mentions_user_ids, {hamlet.id, cordelia.id})
|
||||||
|
|
||||||
# Both fenced quote and > quote should be identical for both silent and regular syntax.
|
# Both fenced quote and > quote should be identical for both silent and regular syntax.
|
||||||
expected = ('<blockquote>\n<p>'
|
expected = ('<blockquote>\n<p>'
|
||||||
'<span class="user-mention silent" data-user-id="%s">King Hamlet</span>'
|
f'<span class="user-mention silent" data-user-id="{hamlet.id}">King Hamlet</span>'
|
||||||
'</p>\n</blockquote>' % (hamlet.id,))
|
'</p>\n</blockquote>')
|
||||||
content = "```quote\n@**King Hamlet**\n```"
|
content = "```quote\n@**King Hamlet**\n```"
|
||||||
self.assertEqual(render_markdown(msg, content), expected)
|
self.assertEqual(render_markdown(msg, content), expected)
|
||||||
self.assertEqual(msg.mentions_user_ids, set())
|
self.assertEqual(msg.mentions_user_ids, set())
|
||||||
|
@ -1559,12 +1559,12 @@ class BugdownTest(ZulipTestCase):
|
||||||
self.assertEqual(render_markdown(msg, content),
|
self.assertEqual(render_markdown(msg, content),
|
||||||
'<p>'
|
'<p>'
|
||||||
'<span class="user-mention" '
|
'<span class="user-mention" '
|
||||||
'data-user-id="%s">@Mark Twin</span>, '
|
f'data-user-id="{twin1.id}">@Mark Twin</span>, '
|
||||||
'<span class="user-mention" '
|
'<span class="user-mention" '
|
||||||
'data-user-id="%s">@Mark Twin</span> and '
|
f'data-user-id="{twin2.id}">@Mark Twin</span> and '
|
||||||
'<span class="user-mention" '
|
'<span class="user-mention" '
|
||||||
'data-user-id="%s">@Cordelia Lear</span>, '
|
f'data-user-id="{cordelia.id}">@Cordelia Lear</span>, '
|
||||||
'hi.</p>' % (twin1.id, twin2.id, cordelia.id))
|
'hi.</p>')
|
||||||
self.assertEqual(msg.mentions_user_ids, {twin1.id, twin2.id, cordelia.id})
|
self.assertEqual(msg.mentions_user_ids, {twin1.id, twin2.id, cordelia.id})
|
||||||
|
|
||||||
def test_mention_invalid(self) -> None:
|
def test_mention_invalid(self) -> None:
|
||||||
|
@ -1599,14 +1599,14 @@ class BugdownTest(ZulipTestCase):
|
||||||
content = "@**Atomic #123**"
|
content = "@**Atomic #123**"
|
||||||
self.assertEqual(render_markdown(msg, content),
|
self.assertEqual(render_markdown(msg, content),
|
||||||
'<p><span class="user-mention" '
|
'<p><span class="user-mention" '
|
||||||
'data-user-id="%s">'
|
f'data-user-id="{test_user.id}">'
|
||||||
'@Atomic #123</span></p>' % (test_user.id,))
|
'@Atomic #123</span></p>')
|
||||||
self.assertEqual(msg.mentions_user_ids, {test_user.id})
|
self.assertEqual(msg.mentions_user_ids, {test_user.id})
|
||||||
content = "@_**Atomic #123**"
|
content = "@_**Atomic #123**"
|
||||||
self.assertEqual(render_markdown(msg, content),
|
self.assertEqual(render_markdown(msg, content),
|
||||||
'<p><span class="user-mention silent" '
|
'<p><span class="user-mention silent" '
|
||||||
'data-user-id="%s">'
|
f'data-user-id="{test_user.id}">'
|
||||||
'Atomic #123</span></p>' % (test_user.id,))
|
'Atomic #123</span></p>')
|
||||||
self.assertEqual(msg.mentions_user_ids, set())
|
self.assertEqual(msg.mentions_user_ids, set())
|
||||||
|
|
||||||
def create_user_group_for_test(self, user_group_name: str) -> UserGroup:
|
def create_user_group_for_test(self, user_group_name: str) -> UserGroup:
|
||||||
|
@ -1623,12 +1623,11 @@ class BugdownTest(ZulipTestCase):
|
||||||
content = "@**King Hamlet** @*support*"
|
content = "@**King Hamlet** @*support*"
|
||||||
self.assertEqual(render_markdown(msg, content),
|
self.assertEqual(render_markdown(msg, content),
|
||||||
'<p><span class="user-mention" '
|
'<p><span class="user-mention" '
|
||||||
'data-user-id="%s">'
|
f'data-user-id="{user_id}">'
|
||||||
'@King Hamlet</span> '
|
'@King Hamlet</span> '
|
||||||
'<span class="user-group-mention" '
|
'<span class="user-group-mention" '
|
||||||
'data-user-group-id="%s">'
|
f'data-user-group-id="{user_group.id}">'
|
||||||
'@support</span></p>' % (user_id,
|
'@support</span></p>')
|
||||||
user_group.id))
|
|
||||||
self.assertEqual(msg.mentions_user_ids, {user_profile.id})
|
self.assertEqual(msg.mentions_user_ids, {user_profile.id})
|
||||||
self.assertEqual(msg.mentions_user_group_ids, {user_group.id})
|
self.assertEqual(msg.mentions_user_group_ids, {user_group.id})
|
||||||
|
|
||||||
|
@ -1654,12 +1653,11 @@ class BugdownTest(ZulipTestCase):
|
||||||
content = "@**King Hamlet** @*support #123*"
|
content = "@**King Hamlet** @*support #123*"
|
||||||
self.assertEqual(render_markdown(msg, content),
|
self.assertEqual(render_markdown(msg, content),
|
||||||
'<p><span class="user-mention" '
|
'<p><span class="user-mention" '
|
||||||
'data-user-id="%s">'
|
f'data-user-id="{user_id}">'
|
||||||
'@King Hamlet</span> '
|
'@King Hamlet</span> '
|
||||||
'<span class="user-group-mention" '
|
'<span class="user-group-mention" '
|
||||||
'data-user-group-id="%s">'
|
f'data-user-group-id="{user_group.id}">'
|
||||||
'@support #123</span></p>' % (user_id,
|
'@support #123</span></p>')
|
||||||
user_group.id))
|
|
||||||
self.assertEqual(msg.mentions_user_ids, {user_profile.id})
|
self.assertEqual(msg.mentions_user_ids, {user_profile.id})
|
||||||
self.assertEqual(msg.mentions_user_group_ids, {user_group.id})
|
self.assertEqual(msg.mentions_user_group_ids, {user_group.id})
|
||||||
|
|
||||||
|
@ -1692,14 +1690,14 @@ class BugdownTest(ZulipTestCase):
|
||||||
self.assertEqual(render_markdown(msg, content),
|
self.assertEqual(render_markdown(msg, content),
|
||||||
'<p>'
|
'<p>'
|
||||||
'<span class="user-group-mention" '
|
'<span class="user-group-mention" '
|
||||||
'data-user-group-id="%s">'
|
f'data-user-group-id="{support.id}">'
|
||||||
'@support</span> '
|
'@support</span> '
|
||||||
'and '
|
'and '
|
||||||
'<span class="user-group-mention" '
|
'<span class="user-group-mention" '
|
||||||
'data-user-group-id="%s">'
|
f'data-user-group-id="{backend.id}">'
|
||||||
'@backend</span>, '
|
'@backend</span>, '
|
||||||
'check this out'
|
'check this out'
|
||||||
'</p>' % (support.id, backend.id))
|
'</p>')
|
||||||
|
|
||||||
self.assertEqual(msg.mentions_user_group_ids, {support.id, backend.id})
|
self.assertEqual(msg.mentions_user_group_ids, {support.id, backend.id})
|
||||||
|
|
||||||
|
|
|
@ -498,8 +498,7 @@ class UpdateCustomProfileFieldTest(CustomProfileFieldTestCase):
|
||||||
field_name = "Mentor"
|
field_name = "Mentor"
|
||||||
invalid_user_id = 1000
|
invalid_user_id = 1000
|
||||||
self.assert_error_update_invalid_value(field_name, [invalid_user_id],
|
self.assert_error_update_invalid_value(field_name, [invalid_user_id],
|
||||||
"Invalid user ID: %d"
|
f"Invalid user ID: {invalid_user_id}")
|
||||||
% (invalid_user_id,))
|
|
||||||
|
|
||||||
def test_update_profile_data_successfully(self) -> None:
|
def test_update_profile_data_successfully(self) -> None:
|
||||||
self.login('iago')
|
self.login('iago')
|
||||||
|
|
|
@ -958,18 +958,16 @@ class ImportExportTest(ZulipTestCase):
|
||||||
original_msg = Message.objects.get(content=special_characters_message, sender__realm=original_realm)
|
original_msg = Message.objects.get(content=special_characters_message, sender__realm=original_realm)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
original_msg.rendered_content,
|
original_msg.rendered_content,
|
||||||
('<div class="codehilite"><pre><span></span><code>'\n</code></pre></div>\n\n\n'
|
'<div class="codehilite"><pre><span></span><code>'\n</code></pre></div>\n\n\n'
|
||||||
'<p><span class="user-mention" data-user-id="%s">@Polonius</span></p>' %
|
f'<p><span class="user-mention" data-user-id="{orig_polonius_user.id}">@Polonius</span></p>',
|
||||||
(orig_polonius_user.id,)),
|
|
||||||
)
|
)
|
||||||
imported_polonius_user = UserProfile.objects.get(delivery_email=self.example_email("polonius"),
|
imported_polonius_user = UserProfile.objects.get(delivery_email=self.example_email("polonius"),
|
||||||
realm=imported_realm)
|
realm=imported_realm)
|
||||||
imported_msg = Message.objects.get(content=special_characters_message, sender__realm=imported_realm)
|
imported_msg = Message.objects.get(content=special_characters_message, sender__realm=imported_realm)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
imported_msg.rendered_content,
|
imported_msg.rendered_content,
|
||||||
('<div class="codehilite"><pre><span></span><code>\'\n</code></pre></div>\n'
|
'<div class="codehilite"><pre><span></span><code>\'\n</code></pre></div>\n'
|
||||||
'<p><span class="user-mention" data-user-id="%s">@Polonius</span></p>' %
|
f'<p><span class="user-mention" data-user-id="{imported_polonius_user.id}">@Polonius</span></p>',
|
||||||
(imported_polonius_user.id,)),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check recipient_id was generated correctly for the imported users and streams.
|
# Check recipient_id was generated correctly for the imported users and streams.
|
||||||
|
|
|
@ -2954,6 +2954,6 @@ WHERE user_profile_id = {hamlet_id} AND (content ILIKE '%jumping%' OR subject IL
|
||||||
'say hello')
|
'say hello')
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
hello_message['match_content'],
|
hello_message['match_content'],
|
||||||
('<p>How are you doing, <span class="user-mention" data-user-id="%s">' +
|
f'<p>How are you doing, <span class="user-mention" data-user-id="{othello.id}">'
|
||||||
'@<span class="highlight">Othello</span>, the Moor of Venice</span>?</p>') % (
|
'@<span class="highlight">Othello</span>, the Moor of Venice</span>?</p>',
|
||||||
othello.id))
|
)
|
||||||
|
|
|
@ -601,8 +601,7 @@ so maybe we shouldn't include it in pending_endpoints.
|
||||||
openapi_parameters = get_openapi_parameters(url_pattern, method,
|
openapi_parameters = get_openapi_parameters(url_pattern, method,
|
||||||
include_url_parameters=False)
|
include_url_parameters=False)
|
||||||
except Exception: # nocoverage
|
except Exception: # nocoverage
|
||||||
raise AssertionError("Could not find OpenAPI docs for %s %s" %
|
raise AssertionError(f"Could not find OpenAPI docs for {method} {url_pattern}")
|
||||||
(method, url_pattern))
|
|
||||||
|
|
||||||
# We now have everything we need to understand the
|
# We now have everything we need to understand the
|
||||||
# function as defined in our urls.py:
|
# function as defined in our urls.py:
|
||||||
|
|
|
@ -2015,5 +2015,4 @@ class PushBouncerSignupTest(ZulipTestCase):
|
||||||
contact_email="server-admin@example.com",
|
contact_email="server-admin@example.com",
|
||||||
)
|
)
|
||||||
result = self.client_post("/api/v1/remotes/server/register", request)
|
result = self.client_post("/api/v1/remotes/server/register", request)
|
||||||
self.assert_json_error(result, "Zulip server auth failure: key does not match role %s" %
|
self.assert_json_error(result, f"Zulip server auth failure: key does not match role {zulip_org_id}")
|
||||||
(zulip_org_id,))
|
|
||||||
|
|
|
@ -524,10 +524,10 @@ class RealmTest(ZulipTestCase):
|
||||||
def do_test_invalid_integer_attribute_value(self, val_name: str, invalid_val: int) -> None:
|
def do_test_invalid_integer_attribute_value(self, val_name: str, invalid_val: int) -> None:
|
||||||
|
|
||||||
possible_messages = {
|
possible_messages = {
|
||||||
"Invalid %(field_name)s" % dict(field_name=val_name),
|
f"Invalid {val_name}",
|
||||||
"Bad value for '%(field_name)s'" % dict(field_name=val_name),
|
f"Bad value for '{val_name}'",
|
||||||
"Bad value for '%(field_name)s': %(value)s" % dict(field_name=val_name, value=invalid_val),
|
f"Bad value for '{val_name}': {invalid_val}",
|
||||||
"Invalid %(field_name)s %(value)s" % dict(field_name=val_name, value=invalid_val),
|
f"Invalid {val_name} {invalid_val}",
|
||||||
}
|
}
|
||||||
|
|
||||||
req = {val_name: invalid_val}
|
req = {val_name: invalid_val}
|
||||||
|
|
|
@ -186,12 +186,16 @@ class RealmExportTest(ZulipTestCase):
|
||||||
with patch('zerver.models.Realm.currently_used_upload_space_bytes',
|
with patch('zerver.models.Realm.currently_used_upload_space_bytes',
|
||||||
return_value=11 * 1024 * 1024 * 1024):
|
return_value=11 * 1024 * 1024 * 1024):
|
||||||
result = self.client_post('/json/export/realm')
|
result = self.client_post('/json/export/realm')
|
||||||
self.assert_json_error(result, 'Please request a manual export from %s.' %
|
self.assert_json_error(
|
||||||
settings.ZULIP_ADMINISTRATOR)
|
result,
|
||||||
|
f'Please request a manual export from {settings.ZULIP_ADMINISTRATOR}.',
|
||||||
|
)
|
||||||
|
|
||||||
# Message limit is set as 250000
|
# Message limit is set as 250000
|
||||||
realm_count.value = 250001
|
realm_count.value = 250001
|
||||||
realm_count.save(update_fields=['value'])
|
realm_count.save(update_fields=['value'])
|
||||||
result = self.client_post('/json/export/realm')
|
result = self.client_post('/json/export/realm')
|
||||||
self.assert_json_error(result, 'Please request a manual export from %s.' %
|
self.assert_json_error(
|
||||||
settings.ZULIP_ADMINISTRATOR)
|
result,
|
||||||
|
f'Please request a manual export from {settings.ZULIP_ADMINISTRATOR}.',
|
||||||
|
)
|
||||||
|
|
|
@ -80,8 +80,7 @@ class SlackMessageConversion(ZulipTestCase):
|
||||||
# multiple mentioning
|
# multiple mentioning
|
||||||
message = 'Hi <@U08RGD1RD|john>: How are you?<@U0CBK5KAT> asked.'
|
message = 'Hi <@U08RGD1RD|john>: How are you?<@U0CBK5KAT> asked.'
|
||||||
text, mentioned_users, has_link = convert_to_zulip_markdown(message, users, channel_map, slack_user_map)
|
text, mentioned_users, has_link = convert_to_zulip_markdown(message, users, channel_map, slack_user_map)
|
||||||
self.assertEqual(text, 'Hi @**%s**: How are you?@**%s** asked.' %
|
self.assertEqual(text, 'Hi @**John Doe**: How are you?@**aaron.anzalone** asked.')
|
||||||
('John Doe', 'aaron.anzalone'))
|
|
||||||
self.assertEqual(mentioned_users, [540, 554])
|
self.assertEqual(mentioned_users, [540, 554])
|
||||||
|
|
||||||
# Check wrong mentioning
|
# Check wrong mentioning
|
||||||
|
|
|
@ -774,8 +774,10 @@ class StreamAdminTest(ZulipTestCase):
|
||||||
|
|
||||||
result = self.client_patch(f'/json/streams/{stream_id}',
|
result = self.client_patch(f'/json/streams/{stream_id}',
|
||||||
{'description': ujson.dumps('a' * 1025)})
|
{'description': ujson.dumps('a' * 1025)})
|
||||||
self.assert_json_error(result, "description is too long (limit: %s characters)"
|
self.assert_json_error(
|
||||||
% (Stream.MAX_DESCRIPTION_LENGTH,))
|
result,
|
||||||
|
f"description is too long (limit: {Stream.MAX_DESCRIPTION_LENGTH} characters)",
|
||||||
|
)
|
||||||
|
|
||||||
result = self.client_patch(f'/json/streams/{stream_id}',
|
result = self.client_patch(f'/json/streams/{stream_id}',
|
||||||
{'description': ujson.dumps('a\nmulti\nline\ndescription')})
|
{'description': ujson.dumps('a\nmulti\nline\ndescription')})
|
||||||
|
@ -2931,8 +2933,11 @@ class SubscriptionAPITest(ZulipTestCase):
|
||||||
get_user(invalid_principal, invalid_principal_realm)
|
get_user(invalid_principal, invalid_principal_realm)
|
||||||
result = self.common_subscribe_to_streams(self.test_user, self.streams,
|
result = self.common_subscribe_to_streams(self.test_user, self.streams,
|
||||||
{"principals": ujson.dumps([invalid_principal])})
|
{"principals": ujson.dumps([invalid_principal])})
|
||||||
self.assert_json_error(result, "User not authorized to execute queries on behalf of '%s'"
|
self.assert_json_error(
|
||||||
% (invalid_principal,), status_code=403)
|
result,
|
||||||
|
f"User not authorized to execute queries on behalf of '{invalid_principal}'",
|
||||||
|
status_code=403,
|
||||||
|
)
|
||||||
|
|
||||||
def test_subscription_add_invalid_principal(self) -> None:
|
def test_subscription_add_invalid_principal(self) -> None:
|
||||||
invalid_principal = 999
|
invalid_principal = 999
|
||||||
|
@ -2941,8 +2946,11 @@ class SubscriptionAPITest(ZulipTestCase):
|
||||||
get_user_profile_by_id_in_realm(invalid_principal, invalid_principal_realm)
|
get_user_profile_by_id_in_realm(invalid_principal, invalid_principal_realm)
|
||||||
result = self.common_subscribe_to_streams(self.test_user, self.streams,
|
result = self.common_subscribe_to_streams(self.test_user, self.streams,
|
||||||
{"principals": ujson.dumps([invalid_principal])})
|
{"principals": ujson.dumps([invalid_principal])})
|
||||||
self.assert_json_error(result, "User not authorized to execute queries on behalf of '%s'"
|
self.assert_json_error(
|
||||||
% (invalid_principal,), status_code=403)
|
result,
|
||||||
|
f"User not authorized to execute queries on behalf of '{invalid_principal}'",
|
||||||
|
status_code=403,
|
||||||
|
)
|
||||||
|
|
||||||
def test_subscription_add_principal_other_realm(self) -> None:
|
def test_subscription_add_principal_other_realm(self) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -2955,8 +2963,11 @@ class SubscriptionAPITest(ZulipTestCase):
|
||||||
self.assertIsInstance(profile, UserProfile)
|
self.assertIsInstance(profile, UserProfile)
|
||||||
result = self.common_subscribe_to_streams(self.test_user, self.streams,
|
result = self.common_subscribe_to_streams(self.test_user, self.streams,
|
||||||
{"principals": ujson.dumps([principal])})
|
{"principals": ujson.dumps([principal])})
|
||||||
self.assert_json_error(result, "User not authorized to execute queries on behalf of '%s'"
|
self.assert_json_error(
|
||||||
% (principal,), status_code=403)
|
result,
|
||||||
|
f"User not authorized to execute queries on behalf of '{principal}'",
|
||||||
|
status_code=403,
|
||||||
|
)
|
||||||
|
|
||||||
def helper_check_subs_before_and_after_remove(self, subscriptions: List[str],
|
def helper_check_subs_before_and_after_remove(self, subscriptions: List[str],
|
||||||
json_dict: Dict[str, Any],
|
json_dict: Dict[str, Any],
|
||||||
|
@ -3144,7 +3155,7 @@ class SubscriptionAPITest(ZulipTestCase):
|
||||||
with mock.patch('zerver.models.Recipient.__str__', return_value='recip'):
|
with mock.patch('zerver.models.Recipient.__str__', return_value='recip'):
|
||||||
self.assertEqual(str(subscription),
|
self.assertEqual(str(subscription),
|
||||||
'<Subscription: '
|
'<Subscription: '
|
||||||
'<UserProfile: %s %s> -> recip>' % (user_profile.email, user_profile.realm))
|
f'<UserProfile: {user_profile.email} {user_profile.realm}> -> recip>')
|
||||||
|
|
||||||
self.assertIsNone(subscription.desktop_notifications)
|
self.assertIsNone(subscription.desktop_notifications)
|
||||||
self.assertIsNone(subscription.push_notifications)
|
self.assertIsNone(subscription.push_notifications)
|
||||||
|
|
|
@ -81,8 +81,7 @@ class ThumbnailTest(ZulipTestCase):
|
||||||
self.logout()
|
self.logout()
|
||||||
result = self.api_get(
|
result = self.api_get(
|
||||||
hamlet,
|
hamlet,
|
||||||
'/thumbnail?url=%s&size=full' %
|
f'/thumbnail?url={quoted_uri}&size=full')
|
||||||
(quoted_uri,))
|
|
||||||
self.assertEqual(result.status_code, 302, result)
|
self.assertEqual(result.status_code, 302, result)
|
||||||
expected_part_url = get_file_path_urlpart(uri)
|
expected_part_url = get_file_path_urlpart(uri)
|
||||||
self.assertIn(expected_part_url, result.url)
|
self.assertIn(expected_part_url, result.url)
|
||||||
|
@ -227,8 +226,7 @@ class ThumbnailTest(ZulipTestCase):
|
||||||
user_profile = self.example_user("hamlet")
|
user_profile = self.example_user("hamlet")
|
||||||
result = self.api_get(
|
result = self.api_get(
|
||||||
user_profile,
|
user_profile,
|
||||||
'/thumbnail?url=%s&size=full' %
|
f'/thumbnail?url={quoted_uri}&size=full')
|
||||||
(quoted_uri,))
|
|
||||||
self.assertEqual(result.status_code, 302, result)
|
self.assertEqual(result.status_code, 302, result)
|
||||||
expected_part_url = get_file_path_urlpart(uri)
|
expected_part_url = get_file_path_urlpart(uri)
|
||||||
self.assertIn(expected_part_url, result.url)
|
self.assertIn(expected_part_url, result.url)
|
||||||
|
@ -237,8 +235,7 @@ class ThumbnailTest(ZulipTestCase):
|
||||||
# auth.
|
# auth.
|
||||||
user_profile = self.example_user("hamlet")
|
user_profile = self.example_user("hamlet")
|
||||||
result = self.client_get(
|
result = self.client_get(
|
||||||
'/thumbnail?url=%s&size=full&api_key=%s' %
|
f'/thumbnail?url={quoted_uri}&size=full&api_key={get_api_key(user_profile)}')
|
||||||
(quoted_uri, get_api_key(user_profile)))
|
|
||||||
self.assertEqual(result.status_code, 302, result)
|
self.assertEqual(result.status_code, 302, result)
|
||||||
expected_part_url = get_file_path_urlpart(uri)
|
expected_part_url = get_file_path_urlpart(uri)
|
||||||
self.assertIn(expected_part_url, result.url)
|
self.assertIn(expected_part_url, result.url)
|
||||||
|
|
|
@ -637,8 +637,7 @@ def request_event_queue(user_profile: UserProfile, user_client: Client, apply_ma
|
||||||
'and %s for more information.',
|
'and %s for more information.',
|
||||||
settings.ERROR_FILE_LOG_PATH, "tornado.log")
|
settings.ERROR_FILE_LOG_PATH, "tornado.log")
|
||||||
raise requests.adapters.ConnectionError(
|
raise requests.adapters.ConnectionError(
|
||||||
"Django cannot connect to Tornado server (%s); try restarting" %
|
f"Django cannot connect to Tornado server ({tornado_uri}); try restarting")
|
||||||
(tornado_uri,))
|
|
||||||
|
|
||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,7 @@ def report_send_times(request: HttpRequest, user_profile: UserProfile,
|
||||||
if displayed > 0:
|
if displayed > 0:
|
||||||
displayed_str = str(displayed)
|
displayed_str = str(displayed)
|
||||||
|
|
||||||
request._log_data["extra"] = "[%sms/%sms/%sms/echo:%s/diff:%s]" \
|
request._log_data["extra"] = f"[{time}ms/{received_str}ms/{displayed_str}ms/echo:{locally_echoed}/diff:{rendered_content_disparity}]"
|
||||||
% (time, received_str, displayed_str, locally_echoed, rendered_content_disparity)
|
|
||||||
|
|
||||||
base_key = statsd_key(user_profile.realm.string_id, clean_periods=True)
|
base_key = statsd_key(user_profile.realm.string_id, clean_periods=True)
|
||||||
statsd.timing(f"endtoend.send_time.{base_key}", time)
|
statsd.timing(f"endtoend.send_time.{base_key}", time)
|
||||||
|
|
|
@ -35,9 +35,10 @@ def api_bitbucket_webhook(request: HttpRequest, user_profile: UserProfile,
|
||||||
# Bitbucket doesn't give us enough information to really give
|
# Bitbucket doesn't give us enough information to really give
|
||||||
# a useful message :/
|
# a useful message :/
|
||||||
subject = repository['name']
|
subject = repository['name']
|
||||||
content = ("%s [force pushed](%s)."
|
content = "{} [force pushed]({}).".format(
|
||||||
% (payload.get('user', 'Someone'),
|
payload.get('user', 'Someone'),
|
||||||
payload['canon_url'] + repository['absolute_url']))
|
payload['canon_url'] + repository['absolute_url'],
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
branch = payload['commits'][-1]['branch']
|
branch = payload['commits'][-1]['branch']
|
||||||
if branches is not None and branches.find(branch) == -1:
|
if branches is not None and branches.find(branch) == -1:
|
||||||
|
|
|
@ -17,7 +17,7 @@ def api_yo_app_webhook(request: HttpRequest, user_profile: UserProfile,
|
||||||
username: str = REQ(default='Yo Bot'),
|
username: str = REQ(default='Yo Bot'),
|
||||||
topic: Optional[str] = REQ(default=None),
|
topic: Optional[str] = REQ(default=None),
|
||||||
user_ip: Optional[str] = REQ(default=None)) -> HttpResponse:
|
user_ip: Optional[str] = REQ(default=None)) -> HttpResponse:
|
||||||
body = ('Yo from %s') % (username,)
|
body = f'Yo from {username}'
|
||||||
receiving_user = get_user(email, user_profile.realm)
|
receiving_user = get_user(email, user_profile.realm)
|
||||||
check_send_private_message(user_profile, request.client, receiving_user, body)
|
check_send_private_message(user_profile, request.client, receiving_user, body)
|
||||||
return json_success()
|
return json_success()
|
||||||
|
|
|
@ -302,8 +302,9 @@ class SignupWorker(QueueProcessingWorker):
|
||||||
user_profile.id, user_profile.realm.string_id,
|
user_profile.id, user_profile.realm.string_id,
|
||||||
)
|
)
|
||||||
if settings.MAILCHIMP_API_KEY and settings.PRODUCTION:
|
if settings.MAILCHIMP_API_KEY and settings.PRODUCTION:
|
||||||
endpoint = "https://%s.api.mailchimp.com/3.0/lists/%s/members" % \
|
endpoint = "https://{}.api.mailchimp.com/3.0/lists/{}/members".format(
|
||||||
(settings.MAILCHIMP_API_KEY.split('-')[1], settings.ZULIP_FRIENDS_LIST_ID)
|
settings.MAILCHIMP_API_KEY.split('-')[1], settings.ZULIP_FRIENDS_LIST_ID,
|
||||||
|
)
|
||||||
params = dict(data)
|
params = dict(data)
|
||||||
del params['user_id']
|
del params['user_id']
|
||||||
params['list_id'] = settings.ZULIP_FRIENDS_LIST_ID
|
params['list_id'] = settings.ZULIP_FRIENDS_LIST_ID
|
||||||
|
|
Loading…
Reference in New Issue