def remove_reaction( request: HttpRequest, user_profile: UserProfile, message_id: int, emoji_code: str = REQ(), reaction_type: str = REQ(default="unicode_emoji") ) -> HttpResponse: message, user_message = access_message(user_profile, message_id) if not Reaction.objects.filter(user_profile=user_profile, message=message, emoji_code=emoji_code, reaction_type=reaction_type).exists(): raise JsonableError(_("Reaction doesn't exist.")) # Unlike adding reactions, while deleting a reaction, we don't # check whether the provided (emoji_type, emoji_code) pair is # valid in this realm. Since there's a row in the database, we # know it was valid when the user added their reaction in the # first place, so it is safe to just remove the reaction if it # exists. And the (reaction_type, emoji_code) pair may no longer be # valid in legitimate situations (e.g. if a realm emoji was # deactivated by an administrator in the meantime). do_remove_reaction(user_profile, message, emoji_code, reaction_type) return json_success()
def remove_reaction_backend(request, user_profile, emoji_name=REQ('emoji'), message_id=REQ('message_id', converter=to_non_negative_int)): # type: (HttpRequest, UserProfile, text_type, int) -> HttpResponse # access_message will throw a JsonableError exception if the user # cannot see the message (e.g. for messages to private streams). message = access_message(user_profile, message_id)[0] existing_emojis = set( message.sender.realm.get_emoji().keys()) or set(emoji_list) if emoji_name not in existing_emojis: raise JsonableError(_("Emoji '%s' does not exist" % (emoji_name, ))) # We could probably just make this check be a try/except for the # IntegrityError from it already existing, but this is a bit cleaner. if not Reaction.objects.filter(user_profile=user_profile, message=message, emoji_name=emoji_name).exists(): raise JsonableError(_("Reaction does not exist")) do_remove_reaction(user_profile, message, emoji_name) return json_success()
def remove_reaction( request: HttpRequest, user_profile: UserProfile, message_id: int, emoji_name: Optional[str] = REQ(default=None), emoji_code: Optional[str] = REQ(default=None), reaction_type: str = REQ(default="unicode_emoji"), ) -> HttpResponse: message, user_message = access_message(user_profile, message_id) if emoji_code is None: if emoji_name is None: raise JsonableError( _( "At least one of the following arguments " "must be present: emoji_name, emoji_code" ) ) # A correct full Zulip client implementation should always # pass an emoji_code, because of the corner cases discussed in # the long block comments elsewhere in this file. However, to # make it easy for simple API clients to use the reactions API # without needing the mapping between emoji names and codes, # we allow instead passing the emoji_name and looking up the # corresponding code using the current data. emoji_code = emoji_name_to_emoji_code(message.sender.realm, emoji_name)[0] if not Reaction.objects.filter( user_profile=user_profile, message=message, emoji_code=emoji_code, reaction_type=reaction_type, ).exists(): raise JsonableError(_("Reaction doesn't exist.")) # Unlike adding reactions, while deleting a reaction, we don't # check whether the provided (emoji_type, emoji_code) pair is # valid in this realm. Since there's a row in the database, we # know it was valid when the user added their reaction in the # first place, so it is safe to just remove the reaction if it # exists. And the (reaction_type, emoji_code) pair may no longer be # valid in legitimate situations (e.g. if a realm emoji was # deactivated by an administrator in the meantime). do_remove_reaction(user_profile, message, emoji_code, reaction_type) return json_success()
def remove_reaction_backend(request, user_profile, message_id, emoji_name): # type: (HttpRequest, UserProfile, int, Text) -> HttpResponse # access_message will throw a JsonableError exception if the user # cannot see the message (e.g. for messages to private streams). message = access_message(user_profile, message_id)[0] # We could probably just make this check be a try/except for the # IntegrityError from it already existing, but this is a bit cleaner. if not Reaction.objects.filter(user_profile=user_profile, message=message, emoji_name=emoji_name).exists(): raise JsonableError(_("Reaction does not exist")) do_remove_reaction(user_profile, message, emoji_name) return json_success()
def remove_reaction_backend(request, user_profile, message_id, emoji_name): # type: (HttpRequest, UserProfile, int, text_type) -> HttpResponse # access_message will throw a JsonableError exception if the user # cannot see the message (e.g. for messages to private streams). message = access_message(user_profile, message_id)[0] existing_emojis = set(message.sender.realm.get_emoji().keys()) or set(emoji_list) if emoji_name not in existing_emojis: raise JsonableError(_("Emoji '%s' does not exist" % (emoji_name,))) # We could probably just make this check be a try/except for the # IntegrityError from it already existing, but this is a bit cleaner. if not Reaction.objects.filter(user_profile=user_profile, message=message, emoji_name=emoji_name).exists(): raise JsonableError(_("Reaction does not exist")) do_remove_reaction(user_profile, message, emoji_name) return json_success()
def remove_reaction(request: HttpRequest, user_profile: UserProfile, message_id: int, emoji_code: str=REQ(), reaction_type: str=REQ(default="unicode_emoji")) -> HttpResponse: message, user_message = access_message(user_profile, message_id) if not Reaction.objects.filter(user_profile=user_profile, message=message, emoji_code=emoji_code, reaction_type=reaction_type).exists(): raise JsonableError(_("Reaction doesn't exist.")) # Unlike adding reactions, while deleting a reaction, we don't # check whether the provided (emoji_type, emoji_code) pair is # valid in this realm. Since there's a row in the database, we # know it was valid when the user added their reaction in the # first place, so it is safe to just remove the reaction if it # exists. And the (reaction_type, emoji_code) pair may no longer be # valid in legitimate situations (e.g. if a realm emoji was # deactivated by an administrator in the meantime). do_remove_reaction(user_profile, message, emoji_code, reaction_type) return json_success()
def remove_reaction(request: HttpRequest, user_profile: UserProfile, message_id: int, emoji_name: Optional[str]=REQ(default=None), emoji_code: Optional[str]=REQ(default=None), reaction_type: str=REQ(default="unicode_emoji")) -> HttpResponse: message, user_message = access_message(user_profile, message_id) if emoji_code is None: if emoji_name is None: raise JsonableError(_('At least one of the following arguments ' 'must be present: emoji_name, emoji_code')) # A correct full Zulip client implementation should always # pass an emoji_code, because of the corner cases discussed in # the long block comments elsewhere in this file. However, to # make it easy for simple API clients to use the reactions API # without needing the mapping between emoji names and codes, # we allow instead passing the emoji_name and looking up the # corresponding code using the current data. emoji_code = emoji_name_to_emoji_code(message.sender.realm, emoji_name)[0] if not Reaction.objects.filter(user_profile=user_profile, message=message, emoji_code=emoji_code, reaction_type=reaction_type).exists(): raise JsonableError(_("Reaction doesn't exist.")) # Unlike adding reactions, while deleting a reaction, we don't # check whether the provided (emoji_type, emoji_code) pair is # valid in this realm. Since there's a row in the database, we # know it was valid when the user added their reaction in the # first place, so it is safe to just remove the reaction if it # exists. And the (reaction_type, emoji_code) pair may no longer be # valid in legitimate situations (e.g. if a realm emoji was # deactivated by an administrator in the meantime). do_remove_reaction(user_profile, message, emoji_code, reaction_type) return json_success()