mirror of https://github.com/zulip/zulip.git
python: Elide unnecessary list wrappers.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
eff0a73925
commit
2665a3ce2b
|
@ -30,4 +30,5 @@ def time_range(
|
||||||
while current >= start:
|
while current >= start:
|
||||||
times.append(current)
|
times.append(current)
|
||||||
current -= step
|
current -= step
|
||||||
return list(reversed(times))
|
times.reverse()
|
||||||
|
return times
|
||||||
|
|
|
@ -1509,11 +1509,11 @@ class TestDeleteStats(AnalyticsTestCase):
|
||||||
FillState.objects.create(property="test", end_time=self.TIME_ZERO, state=FillState.DONE)
|
FillState.objects.create(property="test", end_time=self.TIME_ZERO, state=FillState.DONE)
|
||||||
|
|
||||||
analytics = apps.get_app_config("analytics")
|
analytics = apps.get_app_config("analytics")
|
||||||
for table in list(analytics.models.values()):
|
for table in analytics.models.values():
|
||||||
self.assertTrue(table._default_manager.exists())
|
self.assertTrue(table._default_manager.exists())
|
||||||
|
|
||||||
do_drop_all_analytics_tables()
|
do_drop_all_analytics_tables()
|
||||||
for table in list(analytics.models.values()):
|
for table in analytics.models.values():
|
||||||
self.assertFalse(table._default_manager.exists())
|
self.assertFalse(table._default_manager.exists())
|
||||||
|
|
||||||
def test_do_drop_single_stat(self) -> None:
|
def test_do_drop_single_stat(self) -> None:
|
||||||
|
@ -1533,11 +1533,11 @@ class TestDeleteStats(AnalyticsTestCase):
|
||||||
FillState.objects.create(property="to_save", end_time=self.TIME_ZERO, state=FillState.DONE)
|
FillState.objects.create(property="to_save", end_time=self.TIME_ZERO, state=FillState.DONE)
|
||||||
|
|
||||||
analytics = apps.get_app_config("analytics")
|
analytics = apps.get_app_config("analytics")
|
||||||
for table in list(analytics.models.values()):
|
for table in analytics.models.values():
|
||||||
self.assertTrue(table._default_manager.exists())
|
self.assertTrue(table._default_manager.exists())
|
||||||
|
|
||||||
do_drop_single_stat("to_delete")
|
do_drop_single_stat("to_delete")
|
||||||
for table in list(analytics.models.values()):
|
for table in analytics.models.values():
|
||||||
self.assertFalse(table._default_manager.filter(property="to_delete").exists())
|
self.assertFalse(table._default_manager.filter(property="to_delete").exists())
|
||||||
self.assertTrue(table._default_manager.filter(property="to_save").exists())
|
self.assertTrue(table._default_manager.filter(property="to_save").exists())
|
||||||
|
|
||||||
|
|
|
@ -254,10 +254,7 @@ def realm_summary_table(realm_minutes: Dict[str, float]) -> str:
|
||||||
row["string_id"] = realm_activity_link(row["string_id"])
|
row["string_id"] = realm_activity_link(row["string_id"])
|
||||||
|
|
||||||
# Count active sites
|
# Count active sites
|
||||||
def meets_goal(row: Dict[str, int]) -> bool:
|
num_active_sites = sum(row["dau_count"] >= 5 for row in rows)
|
||||||
return row["dau_count"] >= 5
|
|
||||||
|
|
||||||
num_active_sites = len(list(filter(meets_goal, rows)))
|
|
||||||
|
|
||||||
# create totals
|
# create totals
|
||||||
total_dau_count = 0
|
total_dau_count = 0
|
||||||
|
|
|
@ -438,8 +438,7 @@ def get_chart_data(
|
||||||
|
|
||||||
|
|
||||||
def sort_by_totals(value_arrays: Dict[str, List[int]]) -> List[str]:
|
def sort_by_totals(value_arrays: Dict[str, List[int]]) -> List[str]:
|
||||||
totals = [(sum(values), label) for label, values in value_arrays.items()]
|
totals = sorted(((sum(values), label) for label, values in value_arrays.items()), reverse=True)
|
||||||
totals.sort(reverse=True)
|
|
||||||
return [label for total, label in totals]
|
return [label for total, label in totals]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -343,7 +343,7 @@ field and send an event. For example:
|
||||||
def do_set_realm_authentication_methods(
|
def do_set_realm_authentication_methods(
|
||||||
realm: Realm, authentication_methods: Dict[str, bool], *, acting_user: Optional[UserProfile]
|
realm: Realm, authentication_methods: Dict[str, bool], *, acting_user: Optional[UserProfile]
|
||||||
) -> None:
|
) -> None:
|
||||||
for key, value in list(authentication_methods.items()):
|
for key, value in authentication_methods.items():
|
||||||
index = getattr(realm.authentication_methods, key).number
|
index = getattr(realm.authentication_methods, key).number
|
||||||
realm.authentication_methods.set_bit(index, int(value))
|
realm.authentication_methods.set_bit(index, int(value))
|
||||||
realm.save(update_fields=['authentication_methods'])
|
realm.save(update_fields=['authentication_methods'])
|
||||||
|
|
|
@ -36,7 +36,7 @@ class WalGPrometheusServer(BaseHTTPRequestHandler):
|
||||||
def inner(value: float, labels: Optional[Mapping[str, str]] = None) -> None:
|
def inner(value: float, labels: Optional[Mapping[str, str]] = None) -> None:
|
||||||
label_str = ""
|
label_str = ""
|
||||||
if labels:
|
if labels:
|
||||||
label_str = "{" + ",".join([f'{k}="{v}"' for k, v in labels.items()]) + "}"
|
label_str = "{" + ",".join(f'{k}="{v}"' for k, v in labels.items()) + "}"
|
||||||
self.metric_values[name][label_str] = f"{self.METRIC_PREFIX}{name}{label_str} {value}"
|
self.metric_values[name][label_str] = f"{self.METRIC_PREFIX}{name}{label_str} {value}"
|
||||||
|
|
||||||
if default_value is not None:
|
if default_value is not None:
|
||||||
|
|
|
@ -472,7 +472,7 @@ def print_line(
|
||||||
url,
|
url,
|
||||||
]
|
]
|
||||||
|
|
||||||
print(color + " ".join([p for p in parts if p is not None]) + (ENDC if use_color else ""))
|
print(color + " ".join(p for p in parts if p is not None) + (ENDC if use_color else ""))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -109,7 +109,7 @@ def assert_droplet_does_not_exist(my_token: str, droplet_name: str, recreate: bo
|
||||||
|
|
||||||
|
|
||||||
def get_ssh_keys_string_from_github_ssh_key_dicts(userkey_dicts: List[Dict[str, Any]]) -> str:
|
def get_ssh_keys_string_from_github_ssh_key_dicts(userkey_dicts: List[Dict[str, Any]]) -> str:
|
||||||
return "\n".join([userkey_dict["key"] for userkey_dict in userkey_dicts])
|
return "\n".join(userkey_dict["key"] for userkey_dict in userkey_dicts)
|
||||||
|
|
||||||
|
|
||||||
def generate_dev_droplet_user_data(
|
def generate_dev_droplet_user_data(
|
||||||
|
|
|
@ -157,7 +157,7 @@ def generate_emoji_code_to_emoji_names_maps() -> None:
|
||||||
|
|
||||||
|
|
||||||
def get_sorting_info(category: str, sort_order: int) -> str:
|
def get_sorting_info(category: str, sort_order: int) -> str:
|
||||||
return " ".join([category, str(sort_order)])
|
return f"{category} {sort_order}"
|
||||||
|
|
||||||
|
|
||||||
def get_images_html(emoji_code: str) -> str:
|
def get_images_html(emoji_code: str) -> str:
|
||||||
|
|
|
@ -422,12 +422,10 @@ def get_valid_invite_confirmations_generated_by_user(
|
||||||
multiuse_invite_ids = MultiuseInvite.objects.filter(referred_by=user_profile).values_list(
|
multiuse_invite_ids = MultiuseInvite.objects.filter(referred_by=user_profile).values_list(
|
||||||
"id", flat=True
|
"id", flat=True
|
||||||
)
|
)
|
||||||
confirmations += list(
|
confirmations += Confirmation.objects.filter(
|
||||||
Confirmation.objects.filter(
|
|
||||||
type=Confirmation.MULTIUSE_INVITE,
|
type=Confirmation.MULTIUSE_INVITE,
|
||||||
object_id__in=multiuse_invite_ids,
|
object_id__in=multiuse_invite_ids,
|
||||||
).filter(Q(expiry_date__gte=timezone_now()) | Q(expiry_date=None))
|
).filter(Q(expiry_date__gte=timezone_now()) | Q(expiry_date=None))
|
||||||
)
|
|
||||||
|
|
||||||
return confirmations
|
return confirmations
|
||||||
|
|
||||||
|
|
|
@ -774,7 +774,7 @@ def do_update_message(
|
||||||
)
|
)
|
||||||
subscriber_ids = set(subscriptions.values_list("user_profile_id", flat=True))
|
subscriber_ids = set(subscriptions.values_list("user_profile_id", flat=True))
|
||||||
|
|
||||||
users_to_be_notified += list(map(subscriber_info, sorted(subscriber_ids)))
|
users_to_be_notified += map(subscriber_info, sorted(subscriber_ids))
|
||||||
|
|
||||||
# UserTopic updates and the content of notifications depend on
|
# UserTopic updates and the content of notifications depend on
|
||||||
# whether we've moved the entire topic, or just part of it. We
|
# whether we've moved the entire topic, or just part of it. We
|
||||||
|
|
|
@ -224,7 +224,7 @@ def do_clear_mobile_push_notifications_for_ids(
|
||||||
assert len(user_profile_ids) == 1 or len(message_ids) == 1
|
assert len(user_profile_ids) == 1 or len(message_ids) == 1
|
||||||
|
|
||||||
messages_by_user = defaultdict(list)
|
messages_by_user = defaultdict(list)
|
||||||
notifications_to_update = list(
|
notifications_to_update = (
|
||||||
UserMessage.objects.filter(
|
UserMessage.objects.filter(
|
||||||
message_id__in=message_ids,
|
message_id__in=message_ids,
|
||||||
user_profile_id__in=user_profile_ids,
|
user_profile_id__in=user_profile_ids,
|
||||||
|
|
|
@ -169,7 +169,7 @@ def do_set_realm_authentication_methods(
|
||||||
) -> None:
|
) -> None:
|
||||||
old_value = realm.authentication_methods_dict()
|
old_value = realm.authentication_methods_dict()
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
for key, value in list(authentication_methods.items()):
|
for key, value in authentication_methods.items():
|
||||||
# This does queries in a loop, but this isn't a performance sensitive
|
# This does queries in a loop, but this isn't a performance sensitive
|
||||||
# path and is only run rarely.
|
# path and is only run rarely.
|
||||||
if value:
|
if value:
|
||||||
|
@ -409,15 +409,13 @@ def do_scrub_realm(realm: Realm, *, acting_user: Optional[UserProfile]) -> None:
|
||||||
# more secure against bugs that may cause Message.realm to be incorrect for some
|
# more secure against bugs that may cause Message.realm to be incorrect for some
|
||||||
# cross-realm messages to also determine the actual Recipients - to prevent
|
# cross-realm messages to also determine the actual Recipients - to prevent
|
||||||
# deletion of excessive messages.
|
# deletion of excessive messages.
|
||||||
all_recipient_ids_in_realm = (
|
all_recipient_ids_in_realm = [
|
||||||
list(Stream.objects.filter(realm=realm).values_list("recipient_id", flat=True))
|
*Stream.objects.filter(realm=realm).values_list("recipient_id", flat=True),
|
||||||
+ list(UserProfile.objects.filter(realm=realm).values_list("recipient_id", flat=True))
|
*UserProfile.objects.filter(realm=realm).values_list("recipient_id", flat=True),
|
||||||
+ list(
|
*Subscription.objects.filter(
|
||||||
Subscription.objects.filter(
|
|
||||||
recipient__type=Recipient.HUDDLE, user_profile__realm=realm
|
recipient__type=Recipient.HUDDLE, user_profile__realm=realm
|
||||||
).values_list("recipient_id", flat=True)
|
).values_list("recipient_id", flat=True),
|
||||||
)
|
]
|
||||||
)
|
|
||||||
cross_realm_bot_message_ids = list(
|
cross_realm_bot_message_ids = list(
|
||||||
Message.objects.filter(
|
Message.objects.filter(
|
||||||
# Filtering by both message.recipient and message.realm is
|
# Filtering by both message.recipient and message.realm is
|
||||||
|
|
|
@ -284,7 +284,7 @@ def build_custom_emoji(
|
||||||
# Build custom emoji
|
# Build custom emoji
|
||||||
for rc_emoji in custom_emoji_data["emoji"]:
|
for rc_emoji in custom_emoji_data["emoji"]:
|
||||||
# Subject to change with changes in database
|
# Subject to change with changes in database
|
||||||
emoji_file_id = ".".join([rc_emoji["name"], rc_emoji["extension"]])
|
emoji_file_id = f'{rc_emoji["name"]}.{rc_emoji["extension"]}'
|
||||||
|
|
||||||
emoji_file_info = emoji_file_data[emoji_file_id]
|
emoji_file_info = emoji_file_data[emoji_file_id]
|
||||||
|
|
||||||
|
@ -849,9 +849,7 @@ def separate_channel_private_and_livechat_messages(
|
||||||
private_messages: List[Dict[str, Any]],
|
private_messages: List[Dict[str, Any]],
|
||||||
livechat_messages: List[Dict[str, Any]],
|
livechat_messages: List[Dict[str, Any]],
|
||||||
) -> None:
|
) -> None:
|
||||||
private_channels_list = list(direct_id_to_direct_map.keys()) + list(
|
private_channels_list = [*direct_id_to_direct_map, *huddle_id_to_huddle_map]
|
||||||
huddle_id_to_huddle_map.keys()
|
|
||||||
)
|
|
||||||
for message in messages:
|
for message in messages:
|
||||||
if not message.get("rid"):
|
if not message.get("rid"):
|
||||||
# Message does not belong to any channel (might be
|
# Message does not belong to any channel (might be
|
||||||
|
|
|
@ -797,7 +797,7 @@ def get_messages_iterator(
|
||||||
not read all the messages into memory at once, because for
|
not read all the messages into memory at once, because for
|
||||||
large imports that can OOM kill."""
|
large imports that can OOM kill."""
|
||||||
|
|
||||||
dir_names = list(added_channels.keys()) + list(added_mpims.keys()) + list(dm_members.keys())
|
dir_names = [*added_channels, *added_mpims, *dm_members]
|
||||||
all_json_names: Dict[str, List[str]] = defaultdict(list)
|
all_json_names: Dict[str, List[str]] = defaultdict(list)
|
||||||
for dir_name in dir_names:
|
for dir_name in dir_names:
|
||||||
dir_path = os.path.join(slack_data_dir, dir_name)
|
dir_path = os.path.join(slack_data_dir, dir_name)
|
||||||
|
|
|
@ -67,7 +67,7 @@ class DictType:
|
||||||
def schema(self, var_name: str) -> str:
|
def schema(self, var_name: str) -> str:
|
||||||
# Our current schema is lossy, since our OpenAPI configs
|
# Our current schema is lossy, since our OpenAPI configs
|
||||||
# aren't rigorous about "required" fields yet.
|
# aren't rigorous about "required" fields yet.
|
||||||
keys = sorted(list(self.required_keys) + list(self.optional_keys))
|
keys = sorted([*self.required_keys, *self.optional_keys])
|
||||||
|
|
||||||
sub_schema = "\n".join(schema(name, data_type) for name, data_type in keys)
|
sub_schema = "\n".join(schema(name, data_type) for name, data_type in keys)
|
||||||
return f"{var_name} (dict):\n{indent(sub_schema)}"
|
return f"{var_name} (dict):\n{indent(sub_schema)}"
|
||||||
|
|
|
@ -145,8 +145,7 @@ def _enqueue_emails_for_realm(realm: Realm, cutoff: datetime.datetime) -> None:
|
||||||
.distinct()
|
.distinct()
|
||||||
)
|
)
|
||||||
|
|
||||||
user_ids = list(realm_user_ids - active_user_ids)
|
user_ids = sorted(realm_user_ids - active_user_ids)
|
||||||
user_ids.sort()
|
|
||||||
|
|
||||||
# We process batches of 30. We want a big enough batch
|
# We process batches of 30. We want a big enough batch
|
||||||
# to amortize work, but not so big that a single item
|
# to amortize work, but not so big that a single item
|
||||||
|
|
|
@ -1349,8 +1349,7 @@ def apply_event(
|
||||||
for user_group in state["realm_user_groups"]:
|
for user_group in state["realm_user_groups"]:
|
||||||
if user_group["id"] == event["group_id"]:
|
if user_group["id"] == event["group_id"]:
|
||||||
members = set(user_group["members"])
|
members = set(user_group["members"])
|
||||||
user_group["members"] = list(members - set(event["user_ids"]))
|
user_group["members"] = sorted(members - set(event["user_ids"]))
|
||||||
user_group["members"].sort()
|
|
||||||
elif event["op"] == "add_subgroups":
|
elif event["op"] == "add_subgroups":
|
||||||
for user_group in state["realm_user_groups"]:
|
for user_group in state["realm_user_groups"]:
|
||||||
if user_group["id"] == event["group_id"]:
|
if user_group["id"] == event["group_id"]:
|
||||||
|
@ -1360,10 +1359,9 @@ def apply_event(
|
||||||
for user_group in state["realm_user_groups"]:
|
for user_group in state["realm_user_groups"]:
|
||||||
if user_group["id"] == event["group_id"]:
|
if user_group["id"] == event["group_id"]:
|
||||||
subgroups = set(user_group["direct_subgroup_ids"])
|
subgroups = set(user_group["direct_subgroup_ids"])
|
||||||
user_group["direct_subgroup_ids"] = list(
|
user_group["direct_subgroup_ids"] = sorted(
|
||||||
subgroups - set(event["direct_subgroup_ids"])
|
subgroups - set(event["direct_subgroup_ids"])
|
||||||
)
|
)
|
||||||
user_group["direct_subgroup_ids"].sort()
|
|
||||||
elif event["op"] == "remove":
|
elif event["op"] == "remove":
|
||||||
state["realm_user_groups"] = [
|
state["realm_user_groups"] = [
|
||||||
ug for ug in state["realm_user_groups"] if ug["id"] != event["group_id"]
|
ug for ug in state["realm_user_groups"] if ug["id"] != event["group_id"]
|
||||||
|
@ -1597,8 +1595,7 @@ def post_process_state(
|
||||||
See the note above; the same technique applies below.
|
See the note above; the same technique applies below.
|
||||||
"""
|
"""
|
||||||
if "raw_users" in ret:
|
if "raw_users" in ret:
|
||||||
user_dicts = list(ret["raw_users"].values())
|
user_dicts = sorted(ret["raw_users"].values(), key=lambda x: x["user_id"])
|
||||||
user_dicts = sorted(user_dicts, key=lambda x: x["user_id"])
|
|
||||||
|
|
||||||
ret["realm_users"] = [d for d in user_dicts if d["is_active"]]
|
ret["realm_users"] = [d for d in user_dicts if d["is_active"]]
|
||||||
ret["realm_non_active_users"] = [d for d in user_dicts if not d["is_active"]]
|
ret["realm_non_active_users"] = [d for d in user_dicts if not d["is_active"]]
|
||||||
|
|
|
@ -308,16 +308,16 @@ DATE_FIELDS: Dict[TableName, List[Field]] = {
|
||||||
def sanity_check_output(data: TableData) -> None:
|
def sanity_check_output(data: TableData) -> None:
|
||||||
# First, we verify that the export tool has a declared
|
# First, we verify that the export tool has a declared
|
||||||
# configuration for every table declared in the `models.py` files.
|
# configuration for every table declared in the `models.py` files.
|
||||||
target_models = (
|
target_models = [
|
||||||
list(apps.get_app_config("analytics").get_models(include_auto_created=True))
|
*apps.get_app_config("analytics").get_models(include_auto_created=True),
|
||||||
+ list(apps.get_app_config("django_otp").get_models(include_auto_created=True))
|
*apps.get_app_config("django_otp").get_models(include_auto_created=True),
|
||||||
+ list(apps.get_app_config("otp_static").get_models(include_auto_created=True))
|
*apps.get_app_config("otp_static").get_models(include_auto_created=True),
|
||||||
+ list(apps.get_app_config("otp_totp").get_models(include_auto_created=True))
|
*apps.get_app_config("otp_totp").get_models(include_auto_created=True),
|
||||||
+ list(apps.get_app_config("phonenumber").get_models(include_auto_created=True))
|
*apps.get_app_config("phonenumber").get_models(include_auto_created=True),
|
||||||
+ list(apps.get_app_config("social_django").get_models(include_auto_created=True))
|
*apps.get_app_config("social_django").get_models(include_auto_created=True),
|
||||||
+ list(apps.get_app_config("two_factor").get_models(include_auto_created=True))
|
*apps.get_app_config("two_factor").get_models(include_auto_created=True),
|
||||||
+ list(apps.get_app_config("zerver").get_models(include_auto_created=True))
|
*apps.get_app_config("zerver").get_models(include_auto_created=True),
|
||||||
)
|
]
|
||||||
all_tables_db = {model._meta.db_table for model in target_models}
|
all_tables_db = {model._meta.db_table for model in target_models}
|
||||||
|
|
||||||
# These assertion statements will fire when we add a new database
|
# These assertion statements will fire when we add a new database
|
||||||
|
|
|
@ -333,10 +333,7 @@ def image_preview_enabled(
|
||||||
def list_of_tlds() -> List[str]:
|
def list_of_tlds() -> List[str]:
|
||||||
# Skip a few overly-common false-positives from file extensions
|
# Skip a few overly-common false-positives from file extensions
|
||||||
common_false_positives = {"java", "md", "mov", "py", "zip"}
|
common_false_positives = {"java", "md", "mov", "py", "zip"}
|
||||||
tlds = list(tld_set - common_false_positives)
|
return sorted(tld_set - common_false_positives, key=len, reverse=True)
|
||||||
|
|
||||||
tlds.sort(key=len, reverse=True)
|
|
||||||
return tlds
|
|
||||||
|
|
||||||
|
|
||||||
def walk_tree(
|
def walk_tree(
|
||||||
|
@ -762,9 +759,7 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor):
|
||||||
if image_info is None:
|
if image_info is None:
|
||||||
image_info = {}
|
image_info = {}
|
||||||
image_info["is_image"] = True
|
image_info["is_image"] = True
|
||||||
parsed_url_list = list(parsed_url)
|
image_info["image"] = parsed_url._replace(query="raw=1").geturl()
|
||||||
parsed_url_list[4] = "raw=1" # Replaces query
|
|
||||||
image_info["image"] = urllib.parse.urlunparse(parsed_url_list)
|
|
||||||
|
|
||||||
return image_info
|
return image_info
|
||||||
return None
|
return None
|
||||||
|
@ -992,8 +987,9 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor):
|
||||||
|
|
||||||
# Find the image size that is smaller than
|
# Find the image size that is smaller than
|
||||||
# TWITTER_MAX_IMAGE_HEIGHT px tall or the smallest
|
# TWITTER_MAX_IMAGE_HEIGHT px tall or the smallest
|
||||||
size_name_tuples = list(media_item["sizes"].items())
|
size_name_tuples = sorted(
|
||||||
size_name_tuples.sort(reverse=True, key=lambda x: x[1]["h"])
|
media_item["sizes"].items(), reverse=True, key=lambda x: x[1]["h"]
|
||||||
|
)
|
||||||
for size_name, size in size_name_tuples:
|
for size_name, size in size_name_tuples:
|
||||||
if size["h"] < self.TWITTER_MAX_IMAGE_HEIGHT:
|
if size["h"] < self.TWITTER_MAX_IMAGE_HEIGHT:
|
||||||
break
|
break
|
||||||
|
|
|
@ -46,8 +46,8 @@ class NestedCodeBlocksRendererTreeProcessor(markdown.treeprocessors.Treeprocesso
|
||||||
parent.tag == "p"
|
parent.tag == "p"
|
||||||
and grandparent.tag == "li"
|
and grandparent.tag == "li"
|
||||||
and parent.text is None
|
and parent.text is None
|
||||||
and len(list(parent)) == 1
|
and len(parent) == 1
|
||||||
and len(list(parent.itertext())) == 1
|
and sum(1 for text in parent.itertext()) == 1
|
||||||
):
|
):
|
||||||
# if the parent (<p>) has no text, and no children,
|
# if the parent (<p>) has no text, and no children,
|
||||||
# that means that the <code> element inside is its
|
# that means that the <code> element inside is its
|
||||||
|
|
|
@ -1401,9 +1401,11 @@ def format_unread_message_details(
|
||||||
for message_id, huddle_message_details in raw_unread_data["huddle_dict"].items():
|
for message_id, huddle_message_details in raw_unread_data["huddle_dict"].items():
|
||||||
# The client wants a list of user_ids in the conversation, excluding ourself,
|
# The client wants a list of user_ids in the conversation, excluding ourself,
|
||||||
# that is sorted in numerical order.
|
# that is sorted in numerical order.
|
||||||
user_ids = [int(s) for s in huddle_message_details["user_ids_string"].split(",")]
|
user_ids = sorted(
|
||||||
user_ids = [user_id for user_id in user_ids if user_id != my_user_id]
|
user_id
|
||||||
user_ids.sort()
|
for s in huddle_message_details["user_ids_string"].split(",")
|
||||||
|
if (user_id := int(s)) != my_user_id
|
||||||
|
)
|
||||||
message_details = MessageDetailsDict(
|
message_details = MessageDetailsDict(
|
||||||
type="private",
|
type="private",
|
||||||
user_ids=user_ids,
|
user_ids=user_ids,
|
||||||
|
|
|
@ -143,7 +143,7 @@ def bot_commands(no_help_command: bool = False) -> str:
|
||||||
]
|
]
|
||||||
if not no_help_command:
|
if not no_help_command:
|
||||||
commands.append("help")
|
commands.append("help")
|
||||||
return ", ".join(["`" + command + "`" for command in commands]) + "."
|
return ", ".join("`" + command + "`" for command in commands) + "."
|
||||||
|
|
||||||
|
|
||||||
def select_welcome_bot_response(human_response_lower: str) -> str:
|
def select_welcome_bot_response(human_response_lower: str) -> str:
|
||||||
|
|
|
@ -264,12 +264,10 @@ def send_apple_push_notification(
|
||||||
)
|
)
|
||||||
for device in devices
|
for device in devices
|
||||||
]
|
]
|
||||||
results = list(
|
results = await asyncio.gather(
|
||||||
await asyncio.gather(
|
|
||||||
*(apns_context.apns.send_notification(request) for request in requests),
|
*(apns_context.apns.send_notification(request) for request in requests),
|
||||||
return_exceptions=True,
|
return_exceptions=True,
|
||||||
)
|
)
|
||||||
)
|
|
||||||
return zip(devices, results)
|
return zip(devices, results)
|
||||||
|
|
||||||
results = apns_context.loop.run_until_complete(send_all_notifications())
|
results = apns_context.loop.run_until_complete(send_all_notifications())
|
||||||
|
@ -724,7 +722,7 @@ def get_mobile_push_content(rendered_content: str) -> str:
|
||||||
def render_olist(ol: lxml.html.HtmlElement) -> str:
|
def render_olist(ol: lxml.html.HtmlElement) -> str:
|
||||||
items = []
|
items = []
|
||||||
counter = int(ol.get("start")) if ol.get("start") else 1
|
counter = int(ol.get("start")) if ol.get("start") else 1
|
||||||
nested_levels = len(list(ol.iterancestors("ol")))
|
nested_levels = sum(1 for ancestor in ol.iterancestors("ol"))
|
||||||
indent = ("\n" + " " * nested_levels) if nested_levels else ""
|
indent = ("\n" + " " * nested_levels) if nested_levels else ""
|
||||||
|
|
||||||
for li in ol:
|
for li in ol:
|
||||||
|
|
|
@ -470,9 +470,9 @@ def has_request_variables(
|
||||||
# which could lead to inaccurate output.
|
# which could lead to inaccurate output.
|
||||||
and 200 <= return_value.status_code < 300
|
and 200 <= return_value.status_code < 300
|
||||||
):
|
):
|
||||||
ignored_parameters = set(
|
ignored_parameters = {*request.POST, *request.GET}.difference(
|
||||||
list(request.POST.keys()) + list(request.GET.keys())
|
request_notes.processed_parameters
|
||||||
).difference(request_notes.processed_parameters)
|
)
|
||||||
|
|
||||||
# This will be called each time a function decorated with
|
# This will be called each time a function decorated with
|
||||||
# has_request_variables returns a MutableJsonResponse with a
|
# has_request_variables returns a MutableJsonResponse with a
|
||||||
|
|
|
@ -94,7 +94,7 @@ def get_used_colors_for_user_ids(user_ids: List[int]) -> Dict[int, Set[str]]:
|
||||||
|
|
||||||
result: Dict[int, Set[str]] = defaultdict(set)
|
result: Dict[int, Set[str]] = defaultdict(set)
|
||||||
|
|
||||||
for row in list(query):
|
for row in query:
|
||||||
assert row["color"] is not None
|
assert row["color"] is not None
|
||||||
result[row["user_profile_id"]].add(row["color"])
|
result[row["user_profile_id"]].add(row["color"])
|
||||||
|
|
||||||
|
|
|
@ -964,8 +964,9 @@ def do_get_streams(
|
||||||
stream_ids = {stream.id for stream in streams}
|
stream_ids = {stream.id for stream in streams}
|
||||||
recent_traffic = get_streams_traffic(stream_ids, user_profile.realm)
|
recent_traffic = get_streams_traffic(stream_ids, user_profile.realm)
|
||||||
|
|
||||||
stream_dicts = [stream_to_dict(stream, recent_traffic) for stream in streams]
|
stream_dicts = sorted(
|
||||||
stream_dicts.sort(key=lambda elt: elt["name"])
|
(stream_to_dict(stream, recent_traffic) for stream in streams), key=lambda elt: elt["name"]
|
||||||
|
)
|
||||||
|
|
||||||
if include_default:
|
if include_default:
|
||||||
default_stream_ids = get_default_stream_ids_for_realm(user_profile.realm_id)
|
default_stream_ids = get_default_stream_ids_for_realm(user_profile.realm_id)
|
||||||
|
|
|
@ -10,9 +10,12 @@ from zerver.models import Stream
|
||||||
# https://www.unicode.org/faq/private_use.html#nonchar4
|
# https://www.unicode.org/faq/private_use.html#nonchar4
|
||||||
unicode_non_chars = {
|
unicode_non_chars = {
|
||||||
chr(x)
|
chr(x)
|
||||||
for x in list(range(0xFDD0, 0xFDF0)) # FDD0 through FDEF, inclusive
|
for r in [
|
||||||
+ list(range(0xFFFE, 0x110000, 0x10000)) # 0xFFFE, 0x1FFFE, ... 0x10FFFE inclusive
|
range(0xFDD0, 0xFDF0), # FDD0 through FDEF, inclusive
|
||||||
+ list(range(0xFFFF, 0x110000, 0x10000)) # 0xFFFF, 0x1FFFF, ... 0x10FFFF inclusive
|
range(0xFFFE, 0x110000, 0x10000), # 0xFFFE, 0x1FFFE, ... 0x10FFFE inclusive
|
||||||
|
range(0xFFFF, 0x110000, 0x10000), # 0xFFFF, 0x1FFFF, ... 0x10FFFF inclusive
|
||||||
|
]
|
||||||
|
for x in r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -543,9 +543,9 @@ def typed_endpoint(
|
||||||
# which could lead to inaccurate output.
|
# which could lead to inaccurate output.
|
||||||
and 200 <= return_value.status_code < 300
|
and 200 <= return_value.status_code < 300
|
||||||
):
|
):
|
||||||
ignored_parameters = set(
|
ignored_parameters = {*request.POST, *request.GET}.difference(
|
||||||
list(request.POST.keys()) + list(request.GET.keys())
|
request_notes.processed_parameters
|
||||||
).difference(request_notes.processed_parameters)
|
)
|
||||||
|
|
||||||
# This will be called each time a function decorated with @typed_endpoint
|
# This will be called each time a function decorated with @typed_endpoint
|
||||||
# returns a MutableJsonResponse with a success status_code. Because
|
# returns a MutableJsonResponse with a success status_code. Because
|
||||||
|
|
|
@ -17,7 +17,7 @@ def realm_user_count_by_role(realm: Realm) -> Dict[str, Any]:
|
||||||
str(UserProfile.ROLE_MEMBER): 0,
|
str(UserProfile.ROLE_MEMBER): 0,
|
||||||
str(UserProfile.ROLE_GUEST): 0,
|
str(UserProfile.ROLE_GUEST): 0,
|
||||||
}
|
}
|
||||||
for value_dict in list(
|
for value_dict in (
|
||||||
UserProfile.objects.filter(realm=realm, is_bot=False, is_active=True)
|
UserProfile.objects.filter(realm=realm, is_bot=False, is_active=True)
|
||||||
.values("role")
|
.values("role")
|
||||||
.annotate(Count("role"))
|
.annotate(Count("role"))
|
||||||
|
|
|
@ -229,7 +229,7 @@ def exclude_topic_mutes(
|
||||||
topic_cond = topic_match_sa(topic_name)
|
topic_cond = topic_match_sa(topic_name)
|
||||||
return and_(stream_cond, topic_cond)
|
return and_(stream_cond, topic_cond)
|
||||||
|
|
||||||
condition = not_(or_(*list(map(mute_cond, rows))))
|
condition = not_(or_(*map(mute_cond, rows)))
|
||||||
return [*conditions, condition]
|
return [*conditions, condition]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -182,11 +182,9 @@ def bulk_get_cross_realm_bots() -> Dict[str, UserProfile]:
|
||||||
where_clause = (
|
where_clause = (
|
||||||
"upper(zerver_userprofile.email::text) IN (SELECT upper(email) FROM unnest(%s) AS email)"
|
"upper(zerver_userprofile.email::text) IN (SELECT upper(email) FROM unnest(%s) AS email)"
|
||||||
)
|
)
|
||||||
users = list(
|
users = UserProfile.objects.filter(realm__string_id=settings.SYSTEM_BOT_REALM).extra(
|
||||||
UserProfile.objects.filter(realm__string_id=settings.SYSTEM_BOT_REALM).extra(
|
|
||||||
where=[where_clause], params=(emails,)
|
where=[where_clause], params=(emails,)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
return {user.email.lower(): user for user in users}
|
return {user.email.lower(): user for user in users}
|
||||||
|
|
||||||
|
|
|
@ -316,7 +316,7 @@ def check_dict(
|
||||||
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:
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
_("Unexpected arguments: {keys}").format(keys=", ".join(list(delta_keys)))
|
_("Unexpected arguments: {keys}").format(keys=", ".join(delta_keys))
|
||||||
)
|
)
|
||||||
|
|
||||||
return cast(Dict[str, ResultT], val)
|
return cast(Dict[str, ResultT], val)
|
||||||
|
|
|
@ -187,7 +187,7 @@ This is most often used for legal compliance.
|
||||||
.values_list("full_name", "delivery_email")
|
.values_list("full_name", "delivery_email")
|
||||||
)
|
)
|
||||||
|
|
||||||
return ", ".join([format_sender(e[0], e[1]) for e in users]), False
|
return ", ".join(format_sender(e[0], e[1]) for e in users), False
|
||||||
|
|
||||||
def transform_message(message: Message) -> Dict[str, str]:
|
def transform_message(message: Message) -> Dict[str, str]:
|
||||||
row = {
|
row = {
|
||||||
|
|
|
@ -34,7 +34,7 @@ def set_realm_admins_as_realm_owners(
|
||||||
str(UserProfile.ROLE_MEMBER): 0,
|
str(UserProfile.ROLE_MEMBER): 0,
|
||||||
str(UserProfile.ROLE_GUEST): 0,
|
str(UserProfile.ROLE_GUEST): 0,
|
||||||
}
|
}
|
||||||
for value_dict in list(
|
for value_dict in (
|
||||||
UserProfile.objects.filter(realm=realm, is_bot=False, is_active=True)
|
UserProfile.objects.filter(realm=realm, is_bot=False, is_active=True)
|
||||||
.values("role")
|
.values("role")
|
||||||
.annotate(Count("role"))
|
.annotate(Count("role"))
|
||||||
|
|
|
@ -8,9 +8,12 @@ from django.db.migrations.state import StateApps
|
||||||
# https://www.unicode.org/faq/private_use.html#nonchar4
|
# https://www.unicode.org/faq/private_use.html#nonchar4
|
||||||
unicode_non_chars = {
|
unicode_non_chars = {
|
||||||
chr(x)
|
chr(x)
|
||||||
for x in list(range(0xFDD0, 0xFDF0)) # FDD0 through FDEF, inclusive
|
for r in [
|
||||||
+ list(range(0xFFFE, 0x110000, 0x10000)) # 0xFFFE, 0x1FFFE, ... 0x10FFFE inclusive
|
range(0xFDD0, 0xFDF0), # FDD0 through FDEF, inclusive
|
||||||
+ list(range(0xFFFF, 0x110000, 0x10000)) # 0xFFFF, 0x1FFFF, ... 0x10FFFF inclusive
|
range(0xFFFE, 0x110000, 0x10000), # 0xFFFE, 0x1FFFE, ... 0x10FFFE inclusive
|
||||||
|
range(0xFFFF, 0x110000, 0x10000), # 0xFFFF, 0x1FFFF, ... 0x10FFFF inclusive
|
||||||
|
]
|
||||||
|
for x in r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,12 @@ from django.db.migrations.state import StateApps
|
||||||
# https://www.unicode.org/faq/private_use.html#nonchar4
|
# https://www.unicode.org/faq/private_use.html#nonchar4
|
||||||
unicode_non_chars = {
|
unicode_non_chars = {
|
||||||
chr(x)
|
chr(x)
|
||||||
for x in list(range(0xFDD0, 0xFDF0)) # FDD0 through FDEF, inclusive
|
for r in [
|
||||||
+ list(range(0xFFFE, 0x110000, 0x10000)) # 0xFFFE, 0x1FFFE, ... 0x10FFFE inclusive
|
range(0xFDD0, 0xFDF0), # FDD0 through FDEF, inclusive
|
||||||
+ list(range(0xFFFF, 0x110000, 0x10000)) # 0xFFFF, 0x1FFFF, ... 0x10FFFF inclusive
|
range(0xFFFE, 0x110000, 0x10000), # 0xFFFE, 0x1FFFE, ... 0x10FFFE inclusive
|
||||||
|
range(0xFFFF, 0x110000, 0x10000), # 0xFFFF, 0x1FFFF, ... 0x10FFFF inclusive
|
||||||
|
]
|
||||||
|
for x in r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,13 +36,11 @@ def revoke_invitations(apps: StateApps, schema_editor: BaseDatabaseSchemaEditor)
|
||||||
multiuse_invite_ids = MultiuseInvite.objects.filter(
|
multiuse_invite_ids = MultiuseInvite.objects.filter(
|
||||||
referred_by_id__in=user_ids
|
referred_by_id__in=user_ids
|
||||||
).values_list("id", flat=True)
|
).values_list("id", flat=True)
|
||||||
confirmation_ids += list(
|
confirmation_ids += Confirmation.objects.filter(
|
||||||
Confirmation.objects.filter(
|
|
||||||
type=Confirmation.MULTIUSE_INVITE,
|
type=Confirmation.MULTIUSE_INVITE,
|
||||||
expiry_date__gte=timezone_now(),
|
expiry_date__gte=timezone_now(),
|
||||||
object_id__in=multiuse_invite_ids,
|
object_id__in=multiuse_invite_ids,
|
||||||
).values_list("id", flat=True)
|
).values_list("id", flat=True)
|
||||||
)
|
|
||||||
|
|
||||||
return confirmation_ids
|
return confirmation_ids
|
||||||
|
|
||||||
|
|
|
@ -5275,7 +5275,7 @@ class TestDevAuthBackend(ZulipTestCase):
|
||||||
self.assertEqual(result.status_code, 302)
|
self.assertEqual(result.status_code, 302)
|
||||||
self.assertEqual(result["Location"], "http://zulip.testserver/")
|
self.assertEqual(result["Location"], "http://zulip.testserver/")
|
||||||
self.assert_logged_in_user_id(user_profile.id)
|
self.assert_logged_in_user_id(user_profile.id)
|
||||||
self.assertIn("otp_device_id", list(self.client.session.keys()))
|
self.assertIn("otp_device_id", self.client.session.keys())
|
||||||
|
|
||||||
def test_redirect_to_next_url(self) -> None:
|
def test_redirect_to_next_url(self) -> None:
|
||||||
def do_local_login(formaction: str) -> "TestHttpResponse":
|
def do_local_login(formaction: str) -> "TestHttpResponse":
|
||||||
|
@ -5937,7 +5937,7 @@ class TestLDAP(ZulipLDAPTestCase):
|
||||||
for key, value in ldap_dir.items():
|
for key, value in ldap_dir.items():
|
||||||
self.assertTrue(regex.match(key))
|
self.assertTrue(regex.match(key))
|
||||||
self.assertCountEqual(
|
self.assertCountEqual(
|
||||||
list(value.keys()), [*common_attrs, "uid", "thumbnailPhoto", "userAccountControl"]
|
value.keys(), [*common_attrs, "uid", "thumbnailPhoto", "userAccountControl"]
|
||||||
)
|
)
|
||||||
|
|
||||||
ldap_dir = generate_dev_ldap_dir("b", 9)
|
ldap_dir = generate_dev_ldap_dir("b", 9)
|
||||||
|
@ -5945,14 +5945,14 @@ class TestLDAP(ZulipLDAPTestCase):
|
||||||
regex = re.compile(r"(uid\=)+[a-zA-Z0-9_.+-]+(\,ou\=users\,dc\=zulip\,dc\=com)")
|
regex = re.compile(r"(uid\=)+[a-zA-Z0-9_.+-]+(\,ou\=users\,dc\=zulip\,dc\=com)")
|
||||||
for key, value in ldap_dir.items():
|
for key, value in ldap_dir.items():
|
||||||
self.assertTrue(regex.match(key))
|
self.assertTrue(regex.match(key))
|
||||||
self.assertCountEqual(list(value.keys()), [*common_attrs, "uid", "jpegPhoto"])
|
self.assertCountEqual(value.keys(), [*common_attrs, "uid", "jpegPhoto"])
|
||||||
|
|
||||||
ldap_dir = generate_dev_ldap_dir("c", 8)
|
ldap_dir = generate_dev_ldap_dir("c", 8)
|
||||||
self.assert_length(ldap_dir, 8)
|
self.assert_length(ldap_dir, 8)
|
||||||
regex = re.compile(r"(uid\=)+[a-zA-Z0-9_.+-]+(\,ou\=users\,dc\=zulip\,dc\=com)")
|
regex = re.compile(r"(uid\=)+[a-zA-Z0-9_.+-]+(\,ou\=users\,dc\=zulip\,dc\=com)")
|
||||||
for key, value in ldap_dir.items():
|
for key, value in ldap_dir.items():
|
||||||
self.assertTrue(regex.match(key))
|
self.assertTrue(regex.match(key))
|
||||||
self.assertCountEqual(list(value.keys()), [*common_attrs, "uid", "email"])
|
self.assertCountEqual(value.keys(), [*common_attrs, "uid", "email"])
|
||||||
|
|
||||||
@override_settings(AUTHENTICATION_BACKENDS=("zproject.backends.ZulipLDAPAuthBackend",))
|
@override_settings(AUTHENTICATION_BACKENDS=("zproject.backends.ZulipLDAPAuthBackend",))
|
||||||
def test_dev_ldap_fail_login(self) -> None:
|
def test_dev_ldap_fail_login(self) -> None:
|
||||||
|
|
|
@ -2498,7 +2498,7 @@ class GetOldMessagesTest(ZulipTestCase):
|
||||||
params = {k: orjson.dumps(v).decode() for k, v in raw_params.items()}
|
params = {k: orjson.dumps(v).decode() for k, v in raw_params.items()}
|
||||||
result = self.client_get("/json/messages/matches_narrow", params)
|
result = self.client_get("/json/messages/matches_narrow", params)
|
||||||
messages = self.assert_json_success(result)["messages"]
|
messages = self.assert_json_success(result)["messages"]
|
||||||
self.assert_length(list(messages.keys()), 1)
|
self.assert_length(messages, 1)
|
||||||
message = messages[str(good_id)]
|
message = messages[str(good_id)]
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
message["match_content"],
|
message["match_content"],
|
||||||
|
@ -2514,7 +2514,7 @@ class GetOldMessagesTest(ZulipTestCase):
|
||||||
params = {k: orjson.dumps(v).decode() for k, v in raw_params.items()}
|
params = {k: orjson.dumps(v).decode() for k, v in raw_params.items()}
|
||||||
result = self.client_get("/json/messages/matches_narrow", params)
|
result = self.client_get("/json/messages/matches_narrow", params)
|
||||||
messages = self.assert_json_success(result)["messages"]
|
messages = self.assert_json_success(result)["messages"]
|
||||||
self.assert_length(list(messages.keys()), 1)
|
self.assert_length(messages, 1)
|
||||||
message = messages[str(good_id)]
|
message = messages[str(good_id)]
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
message["match_content"],
|
message["match_content"],
|
||||||
|
@ -2973,7 +2973,7 @@ class GetOldMessagesTest(ZulipTestCase):
|
||||||
params = {k: orjson.dumps(v).decode() for k, v in raw_params.items()}
|
params = {k: orjson.dumps(v).decode() for k, v in raw_params.items()}
|
||||||
result = self.client_get("/json/messages/matches_narrow", params)
|
result = self.client_get("/json/messages/matches_narrow", params)
|
||||||
messages = self.assert_json_success(result)["messages"]
|
messages = self.assert_json_success(result)["messages"]
|
||||||
self.assert_length(list(messages.keys()), 1)
|
self.assert_length(messages, 1)
|
||||||
message = messages[str(good_id)]
|
message = messages[str(good_id)]
|
||||||
self.assertIn("a href=", message["match_content"])
|
self.assertIn("a href=", message["match_content"])
|
||||||
self.assertIn("http://foo.com", message["match_content"])
|
self.assertIn("http://foo.com", message["match_content"])
|
||||||
|
|
|
@ -135,14 +135,14 @@ class UserGroupTestCase(ZulipTestCase):
|
||||||
list(get_recursive_group_members(everyone_group)), [desdemona, iago, shiva]
|
list(get_recursive_group_members(everyone_group)), [desdemona, iago, shiva]
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertIn(leadership_group, list(get_recursive_membership_groups(desdemona)))
|
self.assertIn(leadership_group, get_recursive_membership_groups(desdemona))
|
||||||
self.assertIn(staff_group, list(get_recursive_membership_groups(desdemona)))
|
self.assertIn(staff_group, get_recursive_membership_groups(desdemona))
|
||||||
self.assertIn(everyone_group, list(get_recursive_membership_groups(desdemona)))
|
self.assertIn(everyone_group, get_recursive_membership_groups(desdemona))
|
||||||
|
|
||||||
self.assertIn(staff_group, list(get_recursive_membership_groups(iago)))
|
self.assertIn(staff_group, get_recursive_membership_groups(iago))
|
||||||
self.assertIn(everyone_group, list(get_recursive_membership_groups(iago)))
|
self.assertIn(everyone_group, get_recursive_membership_groups(iago))
|
||||||
|
|
||||||
self.assertIn(everyone_group, list(get_recursive_membership_groups(shiva)))
|
self.assertIn(everyone_group, get_recursive_membership_groups(shiva))
|
||||||
|
|
||||||
def test_subgroups_of_role_based_system_groups(self) -> None:
|
def test_subgroups_of_role_based_system_groups(self) -> None:
|
||||||
realm = get_realm("zulip")
|
realm = get_realm("zulip")
|
||||||
|
|
|
@ -42,7 +42,7 @@ def get_dev_users(realm: Optional[Realm] = None, extra_users_count: int = 10) ->
|
||||||
extra_users = users_query.filter(email__startswith="extrauser").order_by("email")
|
extra_users = users_query.filter(email__startswith="extrauser").order_by("email")
|
||||||
# Limit the number of extra users we offer by default
|
# Limit the number of extra users we offer by default
|
||||||
extra_users = extra_users[0:extra_users_count]
|
extra_users = extra_users[0:extra_users_count]
|
||||||
users = list(shakespearian_users) + list(extra_users)
|
users = [*shakespearian_users, *extra_users]
|
||||||
return users
|
return users
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -281,7 +281,7 @@ class MarkdownDirectoryView(ApiURLView):
|
||||||
def add_integrations_context(context: Dict[str, Any]) -> None:
|
def add_integrations_context(context: Dict[str, Any]) -> None:
|
||||||
alphabetical_sorted_categories = OrderedDict(sorted(CATEGORIES.items()))
|
alphabetical_sorted_categories = OrderedDict(sorted(CATEGORIES.items()))
|
||||||
alphabetical_sorted_integration = OrderedDict(sorted(INTEGRATIONS.items()))
|
alphabetical_sorted_integration = OrderedDict(sorted(INTEGRATIONS.items()))
|
||||||
enabled_integrations_count = len(list(filter(lambda v: v.is_enabled(), INTEGRATIONS.values())))
|
enabled_integrations_count = sum(v.is_enabled() for v in INTEGRATIONS.values())
|
||||||
# Subtract 1 so saying "Over X integrations" is correct. Then,
|
# Subtract 1 so saying "Over X integrations" is correct. Then,
|
||||||
# round down to the nearest multiple of 10.
|
# round down to the nearest multiple of 10.
|
||||||
integrations_count_display = ((enabled_integrations_count - 1) // 10) * 10
|
integrations_count_display = ((enabled_integrations_count - 1) // 10) * 10
|
||||||
|
|
|
@ -166,7 +166,7 @@ def update_realm(
|
||||||
if authentication_methods is not None:
|
if authentication_methods is not None:
|
||||||
if not user_profile.is_realm_owner:
|
if not user_profile.is_realm_owner:
|
||||||
raise OrganizationOwnerRequiredError
|
raise OrganizationOwnerRequiredError
|
||||||
if True not in list(authentication_methods.values()):
|
if True not in authentication_methods.values():
|
||||||
raise JsonableError(_("At least one authentication method must be enabled."))
|
raise JsonableError(_("At least one authentication method must be enabled."))
|
||||||
if video_chat_provider is not None and video_chat_provider not in {
|
if video_chat_provider is not None and video_chat_provider not in {
|
||||||
p["id"] for p in Realm.VIDEO_CHAT_PROVIDERS.values()
|
p["id"] for p in Realm.VIDEO_CHAT_PROVIDERS.values()
|
||||||
|
@ -285,7 +285,7 @@ def update_realm(
|
||||||
req_vars = {}
|
req_vars = {}
|
||||||
req_group_setting_vars = {}
|
req_group_setting_vars = {}
|
||||||
|
|
||||||
for k, v in list(locals().items()):
|
for k, v in locals().items():
|
||||||
if k in realm.property_types:
|
if k in realm.property_types:
|
||||||
req_vars[k] = v
|
req_vars[k] = v
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ def update_realm(
|
||||||
if k == permissions_configuration.id_field_name:
|
if k == permissions_configuration.id_field_name:
|
||||||
req_group_setting_vars[k] = v
|
req_group_setting_vars[k] = v
|
||||||
|
|
||||||
for k, v in list(req_vars.items()):
|
for k, v in req_vars.items():
|
||||||
if v is not None and getattr(realm, k) != v:
|
if v is not None and getattr(realm, k) != v:
|
||||||
do_set_realm_property(realm, k, v, acting_user=user_profile)
|
do_set_realm_property(realm, k, v, acting_user=user_profile)
|
||||||
if isinstance(v, str):
|
if isinstance(v, str):
|
||||||
|
@ -535,10 +535,8 @@ def update_realm_user_settings_defaults(
|
||||||
check_settings_values(notification_sound, email_notifications_batching_period_seconds)
|
check_settings_values(notification_sound, email_notifications_batching_period_seconds)
|
||||||
|
|
||||||
realm_user_default = RealmUserDefault.objects.get(realm=user_profile.realm)
|
realm_user_default = RealmUserDefault.objects.get(realm=user_profile.realm)
|
||||||
request_settings = {
|
request_settings = {k: v for k, v in locals().items() if (k in RealmUserDefault.property_types)}
|
||||||
k: v for k, v in list(locals().items()) if (k in RealmUserDefault.property_types)
|
for k, v in request_settings.items():
|
||||||
}
|
|
||||||
for k, v in list(request_settings.items()):
|
|
||||||
if v is not None and getattr(realm_user_default, k) != v:
|
if v is not None and getattr(realm_user_default, k) != v:
|
||||||
do_set_realm_user_default_setting(realm_user_default, k, v, acting_user=user_profile)
|
do_set_realm_user_default_setting(realm_user_default, k, v, acting_user=user_profile)
|
||||||
|
|
||||||
|
|
|
@ -361,8 +361,8 @@ def json_change_settings(
|
||||||
check_change_full_name(user_profile, full_name, user_profile)
|
check_change_full_name(user_profile, full_name, user_profile)
|
||||||
|
|
||||||
# Loop over user_profile.property_types
|
# Loop over user_profile.property_types
|
||||||
request_settings = {k: v for k, v in list(locals().items()) if k in user_profile.property_types}
|
request_settings = {k: v for k, v in locals().items() if k in user_profile.property_types}
|
||||||
for k, v in list(request_settings.items()):
|
for k, v in request_settings.items():
|
||||||
if v is not None and getattr(user_profile, k) != v:
|
if v is not None and getattr(user_profile, k) != v:
|
||||||
do_change_user_setting(user_profile, k, v, acting_user=user_profile)
|
do_change_user_setting(user_profile, k, v, acting_user=user_profile)
|
||||||
|
|
||||||
|
|
|
@ -892,7 +892,7 @@ def get_zulip_event_name(
|
||||||
return "issue_milestoned_or_demilestoned"
|
return "issue_milestoned_or_demilestoned"
|
||||||
else:
|
else:
|
||||||
return "issues"
|
return "issues"
|
||||||
elif header_event in list(EVENT_FUNCTION_MAPPER.keys()):
|
elif header_event in EVENT_FUNCTION_MAPPER:
|
||||||
return header_event
|
return header_event
|
||||||
elif header_event in IGNORED_EVENTS:
|
elif header_event in IGNORED_EVENTS:
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -526,7 +526,7 @@ def get_event(request: HttpRequest, payload: WildValue, branches: Optional[str])
|
||||||
if branches.find(branch) == -1:
|
if branches.find(branch) == -1:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if event in list(EVENT_FUNCTION_MAPPER.keys()):
|
if event in EVENT_FUNCTION_MAPPER:
|
||||||
return event
|
return event
|
||||||
|
|
||||||
raise UnsupportedWebhookEventTypeError(event)
|
raise UnsupportedWebhookEventTypeError(event)
|
||||||
|
|
|
@ -20,10 +20,10 @@ def api_jotform_webhook(
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
topic = payload["formTitle"].tame(check_string)
|
topic = payload["formTitle"].tame(check_string)
|
||||||
submission_id = payload["submissionID"].tame(check_string)
|
submission_id = payload["submissionID"].tame(check_string)
|
||||||
fields_dict = list(payload["pretty"].tame(check_string).split(", "))
|
fields = payload["pretty"].tame(check_string).split(", ")
|
||||||
|
|
||||||
form_response = f"A new submission (ID {submission_id}) was received:\n"
|
form_response = f"A new submission (ID {submission_id}) was received:\n"
|
||||||
for field in fields_dict:
|
for field in fields:
|
||||||
form_response += f"* {field}\n"
|
form_response += f"* {field}\n"
|
||||||
|
|
||||||
message = form_response.strip()
|
message = form_response.strip()
|
||||||
|
|
|
@ -26,7 +26,7 @@ def api_slack_webhook(
|
||||||
stream: str = "slack",
|
stream: str = "slack",
|
||||||
channels_map_to_topics: str = "1",
|
channels_map_to_topics: str = "1",
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
if channels_map_to_topics not in list(VALID_OPTIONS.values()):
|
if channels_map_to_topics not in VALID_OPTIONS.values():
|
||||||
raise JsonableError(_("Error: channels_map_to_topics parameter other than 0 or 1"))
|
raise JsonableError(_("Error: channels_map_to_topics parameter other than 0 or 1"))
|
||||||
|
|
||||||
if channels_map_to_topics == VALID_OPTIONS["SHOULD_BE_MAPPED"]:
|
if channels_map_to_topics == VALID_OPTIONS["SHOULD_BE_MAPPED"]:
|
||||||
|
|
Loading…
Reference in New Issue