mirror of https://github.com/zulip/zulip.git
mypy: Add EmojiInfo type.
We now serialize still_url as None for non-animated emojis, instead of omitting the field. The webapp does proper checks for falsiness here. The mobile app does not yet use the field (to my knowledge). We bump the API version here. More discussion here: https://chat.zulip.org/#narrow/stream/378-api-design/topic/still_url/near/1302573
This commit is contained in:
parent
a6201b430f
commit
c04a8097f3
|
@ -84,6 +84,7 @@ exports.test_realm_emojis = {
|
||||||
author_id: 222,
|
author_id: 222,
|
||||||
deactivated: false,
|
deactivated: false,
|
||||||
source_url: "/some/path/to/emoji",
|
source_url: "/some/path/to/emoji",
|
||||||
|
still_url: null,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,14 @@ format used by the Zulip server that they are interacting with.
|
||||||
|
|
||||||
## Changes in Zulip 5.0
|
## Changes in Zulip 5.0
|
||||||
|
|
||||||
|
**Feature level 113**
|
||||||
|
|
||||||
|
* `GET /realm/emoji`, `POST /realm/emoji/{emoji_name}`, [`GET
|
||||||
|
/events`](/api/get-events), [`POST /register`](/api/register-queue):
|
||||||
|
The `still_url` field for custom emoji objects is now always
|
||||||
|
present, with a value of null for non-animated emoji. Previously, it
|
||||||
|
only was present for animated emoji.
|
||||||
|
|
||||||
**Feature level 112**
|
**Feature level 112**
|
||||||
|
|
||||||
* [`GET /events`](/api/get-events): Updated `update_message` event type
|
* [`GET /events`](/api/get-events): Updated `update_message` event type
|
||||||
|
|
|
@ -33,7 +33,7 @@ DESKTOP_WARNING_VERSION = "5.4.3"
|
||||||
# Changes should be accompanied by documentation explaining what the
|
# Changes should be accompanied by documentation explaining what the
|
||||||
# new level means in templates/zerver/api/changelog.md, as well as
|
# new level means in templates/zerver/api/changelog.md, as well as
|
||||||
# "**Changes**" entries in the endpoint's documentation in `zulip.yaml`.
|
# "**Changes**" entries in the endpoint's documentation in `zulip.yaml`.
|
||||||
API_FEATURE_LEVEL = 112
|
API_FEATURE_LEVEL = 113
|
||||||
|
|
||||||
# Bump the minor PROVISION_VERSION to indicate that folks should provision
|
# Bump the minor PROVISION_VERSION to indicate that folks should provision
|
||||||
# only when going from an old version of the code to a newer version. Bump
|
# only when going from an old version of the code to a newer version. Bump
|
||||||
|
|
|
@ -712,9 +712,7 @@ realm_emoji_type = DictType(
|
||||||
("source_url", str),
|
("source_url", str),
|
||||||
("deactivated", bool),
|
("deactivated", bool),
|
||||||
("author_id", int),
|
("author_id", int),
|
||||||
],
|
("still_url", OptionalType(str)),
|
||||||
optional_keys=[
|
|
||||||
("still_url", str),
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1503,7 +1503,7 @@ class Emoji(markdown.inlinepatterns.Pattern):
|
||||||
orig_syntax = match.group("syntax")
|
orig_syntax = match.group("syntax")
|
||||||
name = orig_syntax[1:-1]
|
name = orig_syntax[1:-1]
|
||||||
|
|
||||||
active_realm_emoji: Dict[str, Dict[str, str]] = {}
|
active_realm_emoji: Dict[str, EmojiInfo] = {}
|
||||||
db_data = self.md.zulip_db_data
|
db_data = self.md.zulip_db_data
|
||||||
if db_data is not None:
|
if db_data is not None:
|
||||||
active_realm_emoji = db_data["active_realm_emoji"]
|
active_realm_emoji = db_data["active_realm_emoji"]
|
||||||
|
|
|
@ -37,6 +37,7 @@ from django.utils.timezone import now as timezone_now
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from django.utils.translation import gettext_lazy
|
from django.utils.translation import gettext_lazy
|
||||||
from django_cte import CTEManager
|
from django_cte import CTEManager
|
||||||
|
from typing_extensions import TypedDict
|
||||||
|
|
||||||
from confirmation import settings as confirmation_settings
|
from confirmation import settings as confirmation_settings
|
||||||
from zerver.lib import cache
|
from zerver.lib import cache
|
||||||
|
@ -100,6 +101,15 @@ MAX_LANGUAGE_ID_LENGTH: int = 50
|
||||||
STREAM_NAMES = TypeVar("STREAM_NAMES", Sequence[str], AbstractSet[str])
|
STREAM_NAMES = TypeVar("STREAM_NAMES", Sequence[str], AbstractSet[str])
|
||||||
|
|
||||||
|
|
||||||
|
class EmojiInfo(TypedDict):
|
||||||
|
id: str
|
||||||
|
name: str
|
||||||
|
source_url: str
|
||||||
|
deactivated: bool
|
||||||
|
author_id: Optional[int]
|
||||||
|
still_url: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
def query_for_ids(query: QuerySet, user_ids: List[int], field: str) -> QuerySet:
|
def query_for_ids(query: QuerySet, user_ids: List[int], field: str) -> QuerySet:
|
||||||
"""
|
"""
|
||||||
This function optimizes searches of the form
|
This function optimizes searches of the form
|
||||||
|
@ -726,11 +736,11 @@ class Realm(models.Model):
|
||||||
return f"<Realm: {self.string_id} {self.id}>"
|
return f"<Realm: {self.string_id} {self.id}>"
|
||||||
|
|
||||||
@cache_with_key(get_realm_emoji_cache_key, timeout=3600 * 24 * 7)
|
@cache_with_key(get_realm_emoji_cache_key, timeout=3600 * 24 * 7)
|
||||||
def get_emoji(self) -> Dict[str, Dict[str, Any]]:
|
def get_emoji(self) -> Dict[str, EmojiInfo]:
|
||||||
return get_realm_emoji_uncached(self)
|
return get_realm_emoji_uncached(self)
|
||||||
|
|
||||||
@cache_with_key(get_active_realm_emoji_cache_key, timeout=3600 * 24 * 7)
|
@cache_with_key(get_active_realm_emoji_cache_key, timeout=3600 * 24 * 7)
|
||||||
def get_active_emoji(self) -> Dict[str, Dict[str, Any]]:
|
def get_active_emoji(self) -> Dict[str, EmojiInfo]:
|
||||||
return get_active_realm_emoji_uncached(self)
|
return get_active_realm_emoji_uncached(self)
|
||||||
|
|
||||||
def get_admin_users_and_bots(
|
def get_admin_users_and_bots(
|
||||||
|
@ -1058,9 +1068,7 @@ class RealmEmoji(models.Model):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def get_realm_emoji_dicts(
|
def get_realm_emoji_dicts(realm: Realm, only_active_emojis: bool = False) -> Dict[str, EmojiInfo]:
|
||||||
realm: Realm, only_active_emojis: bool = False
|
|
||||||
) -> Dict[str, Dict[str, Any]]:
|
|
||||||
query = RealmEmoji.objects.filter(realm=realm).select_related("author")
|
query = RealmEmoji.objects.filter(realm=realm).select_related("author")
|
||||||
if only_active_emojis:
|
if only_active_emojis:
|
||||||
query = query.filter(deactivated=False)
|
query = query.filter(deactivated=False)
|
||||||
|
@ -1073,12 +1081,13 @@ def get_realm_emoji_dicts(
|
||||||
author_id = realm_emoji.author_id
|
author_id = realm_emoji.author_id
|
||||||
emoji_url = get_emoji_url(realm_emoji.file_name, realm_emoji.realm_id)
|
emoji_url = get_emoji_url(realm_emoji.file_name, realm_emoji.realm_id)
|
||||||
|
|
||||||
emoji_dict = dict(
|
emoji_dict: EmojiInfo = dict(
|
||||||
id=str(realm_emoji.id),
|
id=str(realm_emoji.id),
|
||||||
name=realm_emoji.name,
|
name=realm_emoji.name,
|
||||||
source_url=emoji_url,
|
source_url=emoji_url,
|
||||||
deactivated=realm_emoji.deactivated,
|
deactivated=realm_emoji.deactivated,
|
||||||
author_id=author_id,
|
author_id=author_id,
|
||||||
|
still_url=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
if realm_emoji.is_animated:
|
if realm_emoji.is_animated:
|
||||||
|
@ -1095,11 +1104,11 @@ def get_realm_emoji_dicts(
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
def get_realm_emoji_uncached(realm: Realm) -> Dict[str, Dict[str, Any]]:
|
def get_realm_emoji_uncached(realm: Realm) -> Dict[str, EmojiInfo]:
|
||||||
return get_realm_emoji_dicts(realm)
|
return get_realm_emoji_dicts(realm)
|
||||||
|
|
||||||
|
|
||||||
def get_active_realm_emoji_uncached(realm: Realm) -> Dict[str, Dict[str, Any]]:
|
def get_active_realm_emoji_uncached(realm: Realm) -> Dict[str, EmojiInfo]:
|
||||||
realm_emojis = get_realm_emoji_dicts(realm, only_active_emojis=True)
|
realm_emojis = get_realm_emoji_dicts(realm, only_active_emojis=True)
|
||||||
d = {}
|
d = {}
|
||||||
for emoji_id, emoji_dict in realm_emojis.items():
|
for emoji_id, emoji_dict in realm_emojis.items():
|
||||||
|
|
|
@ -13931,8 +13931,9 @@ components:
|
||||||
emoji's image can be found.
|
emoji's image can be found.
|
||||||
still_url:
|
still_url:
|
||||||
type: string
|
type: string
|
||||||
|
nullable: true
|
||||||
description: |
|
description: |
|
||||||
Only present when the emoji's image is animated.
|
Only non-null when the emoji's image is animated.
|
||||||
|
|
||||||
The path relative to the organization's URL where a still
|
The path relative to the organization's URL where a still
|
||||||
(not animated) version of the emoji can be found. (This is
|
(not animated) version of the emoji can be found. (This is
|
||||||
|
@ -13942,7 +13943,9 @@ components:
|
||||||
where continuously animating it would be a bad user experience
|
where continuously animating it would be a bad user experience
|
||||||
(E.g. because it would be distracting).
|
(E.g. because it would be distracting).
|
||||||
|
|
||||||
**Changes**: New in Zulip 5.0 (feature level 97).
|
**Changes**: New in Zulip 5.0 (added as optional field in
|
||||||
|
feature level 97 and then made mandatory, but nullable, in
|
||||||
|
feature level 113).
|
||||||
deactivated:
|
deactivated:
|
||||||
type: boolean
|
type: boolean
|
||||||
description: |
|
description: |
|
||||||
|
|
Loading…
Reference in New Issue