mirror of
https://github.com/zulip/zulip.git
synced 2025-10-24 08:33:43 +00:00
Similar to group based setting values, we expect the client to send the previous content alongwith the edited content to the edit message endpoint. We reject the request incase the previous content doesn't match the current message content, which could happen in case two users simultaneously edit a message - which will be implemented in #33051.
76 lines
1.8 KiB
Python
76 lines
1.8 KiB
Python
import hashlib
|
|
import re
|
|
import secrets
|
|
from collections.abc import Callable
|
|
from typing import TypeVar
|
|
|
|
from django.db import models
|
|
|
|
T = TypeVar("T")
|
|
|
|
|
|
def generate_api_key() -> str:
|
|
api_key = ""
|
|
while len(api_key) < 32:
|
|
# One iteration suffices 99.4992% of the time.
|
|
api_key += secrets.token_urlsafe(3 * 9).replace("_", "").replace("-", "")
|
|
return api_key[:32]
|
|
|
|
|
|
def has_api_key_format(key: str) -> bool:
|
|
return bool(re.fullmatch(r"([A-Za-z0-9]){32}", key))
|
|
|
|
|
|
def assert_is_not_none(value: T | None) -> T:
|
|
assert value is not None
|
|
return value
|
|
|
|
|
|
def process_list_in_batches(
|
|
lst: list[T], chunk_size: int, process_batch: Callable[[list[T]], None]
|
|
) -> None:
|
|
offset = 0
|
|
|
|
while True:
|
|
items = lst[offset : offset + chunk_size]
|
|
if not items:
|
|
break
|
|
process_batch(items)
|
|
offset += chunk_size
|
|
|
|
|
|
def optional_bytes_to_mib(value: int | None) -> int | None:
|
|
if value is None:
|
|
return None
|
|
else:
|
|
return value >> 20
|
|
|
|
|
|
def get_fk_field_name(model: type[models.Model], related_model: type[models.Model]) -> str | None:
|
|
"""
|
|
Get the name of the foreign key field in model, pointing the related_model table.
|
|
Returns None if there is no such field.
|
|
|
|
Example usage:
|
|
|
|
get_fk_field_name(UserProfile, Realm) returns "realm"
|
|
"""
|
|
|
|
fields = model._meta.get_fields()
|
|
foreign_key_fields_to_related_model = [
|
|
field
|
|
for field in fields
|
|
if hasattr(field, "related_model") and field.related_model == related_model
|
|
]
|
|
|
|
if len(foreign_key_fields_to_related_model) == 0:
|
|
return None
|
|
|
|
assert len(foreign_key_fields_to_related_model) == 1
|
|
|
|
return foreign_key_fields_to_related_model[0].name
|
|
|
|
|
|
def sha256_hash(text: str) -> str:
|
|
return hashlib.sha256(text.encode()).hexdigest()
|