mirror of
https://github.com/zulip/zulip.git
synced 2025-11-10 08:56:10 +00:00
Since production testing of `message_retention_days` is finished, we can enable this feature in the organization settings page. We already had this setting in frontend but it was bit rotten and not rendered in templates. Here we replaced our past text-input based setting with a dropdown-with-text-input setting approach which is more consistent with our existing UI. Along with frontend changes, we also incorporated a backend change to handle making retention period forever. This change introduces a new convertor `to_positive_or_allowed_int` which only allows positive integers and an allowed value for settings like `message_retention_days` which can be a positive integer or has the value `Realm.RETAIN_MESSAGE_FOREVER` when we change the setting to retain message forever. This change made `to_not_negative_int_or_none` redundant so removed it as well. Fixes: #14854
125 lines
6.0 KiB
Python
125 lines
6.0 KiB
Python
import time
|
|
from typing import Iterable, Optional, Sequence
|
|
|
|
import ujson
|
|
from django.http import HttpRequest, HttpResponse
|
|
from django.utils.translation import ugettext as _
|
|
|
|
from zerver.decorator import REQ, has_request_variables, internal_notify_view, \
|
|
process_client
|
|
from zerver.lib.response import json_error, json_success
|
|
from zerver.lib.validator import check_bool, check_int, check_list, check_string, \
|
|
to_non_negative_int
|
|
from zerver.models import Client, UserProfile, get_client, get_user_profile_by_id
|
|
from zerver.tornado.event_queue import fetch_events, \
|
|
get_client_descriptor, process_notification
|
|
from zerver.tornado.handlers import AsyncDjangoHandler
|
|
from zerver.tornado.exceptions import BadEventQueueIdError
|
|
|
|
@internal_notify_view(True)
|
|
def notify(request: HttpRequest) -> HttpResponse:
|
|
process_notification(ujson.loads(request.POST['data']))
|
|
return json_success()
|
|
|
|
@has_request_variables
|
|
def cleanup_event_queue(request: HttpRequest, user_profile: UserProfile,
|
|
queue_id: str=REQ()) -> HttpResponse:
|
|
client = get_client_descriptor(str(queue_id))
|
|
if client is None:
|
|
raise BadEventQueueIdError(queue_id)
|
|
if user_profile.id != client.user_profile_id:
|
|
return json_error(_("You are not authorized to access this queue"))
|
|
request._log_data['extra'] = "[%s]" % (queue_id,)
|
|
client.cleanup()
|
|
return json_success()
|
|
|
|
@internal_notify_view(True)
|
|
@has_request_variables
|
|
def get_events_internal(request: HttpRequest,
|
|
user_profile_id: int = REQ(validator=check_int)) -> HttpResponse:
|
|
user_profile = get_user_profile_by_id(user_profile_id)
|
|
request._requestor_for_logs = user_profile.format_requestor_for_logs()
|
|
process_client(request, user_profile, client_name="internal")
|
|
return get_events_backend(request, user_profile)
|
|
|
|
def get_events(request: HttpRequest, user_profile: UserProfile) -> HttpResponse:
|
|
return get_events_backend(request, user_profile)
|
|
|
|
@has_request_variables
|
|
def get_events_backend(request: HttpRequest, user_profile: UserProfile,
|
|
# user_client is intended only for internal Django=>Tornado requests
|
|
# and thus shouldn't be documented for external use.
|
|
user_client: Optional[Client]=REQ(converter=get_client, default=None,
|
|
intentionally_undocumented=True),
|
|
last_event_id: Optional[int]=REQ(converter=int, default=None),
|
|
queue_id: Optional[str]=REQ(default=None),
|
|
# apply_markdown, client_gravatar, all_public_streams, and various
|
|
# other parameters are only used when registering a new queue via this
|
|
# endpoint. This is a feature used primarily by get_events_internal
|
|
# and not expected to be used by third-party clients.
|
|
apply_markdown: bool=REQ(default=False, validator=check_bool,
|
|
intentionally_undocumented=True),
|
|
client_gravatar: bool=REQ(default=False, validator=check_bool,
|
|
intentionally_undocumented=True),
|
|
slim_presence: bool=REQ(default=False, validator=check_bool,
|
|
intentionally_undocumented=True),
|
|
all_public_streams: bool=REQ(default=False, validator=check_bool,
|
|
intentionally_undocumented=True),
|
|
event_types: Optional[str]=REQ(default=None, validator=check_list(check_string),
|
|
intentionally_undocumented=True),
|
|
dont_block: bool=REQ(default=False, validator=check_bool),
|
|
narrow: Iterable[Sequence[str]]=REQ(default=[], validator=check_list(None),
|
|
intentionally_undocumented=True),
|
|
lifespan_secs: int=REQ(default=0, converter=to_non_negative_int,
|
|
intentionally_undocumented=True)
|
|
) -> HttpResponse:
|
|
# Extract the Tornado handler from the request
|
|
handler: AsyncDjangoHandler = request._tornado_handler
|
|
|
|
if user_client is None:
|
|
valid_user_client = request.client
|
|
else:
|
|
valid_user_client = user_client
|
|
|
|
events_query = dict(
|
|
user_profile_id = user_profile.id,
|
|
queue_id = queue_id,
|
|
last_event_id = last_event_id,
|
|
event_types = event_types,
|
|
client_type_name = valid_user_client.name,
|
|
all_public_streams = all_public_streams,
|
|
lifespan_secs = lifespan_secs,
|
|
narrow = narrow,
|
|
dont_block = dont_block,
|
|
handler_id = handler.handler_id)
|
|
|
|
if queue_id is None:
|
|
events_query['new_queue_data'] = dict(
|
|
user_profile_id = user_profile.id,
|
|
realm_id = user_profile.realm_id,
|
|
event_types = event_types,
|
|
client_type_name = valid_user_client.name,
|
|
apply_markdown = apply_markdown,
|
|
client_gravatar = client_gravatar,
|
|
slim_presence = slim_presence,
|
|
all_public_streams = all_public_streams,
|
|
queue_timeout = lifespan_secs,
|
|
last_connection_time = time.time(),
|
|
narrow = narrow)
|
|
|
|
result = fetch_events(events_query)
|
|
if "extra_log_data" in result:
|
|
request._log_data['extra'] = result["extra_log_data"]
|
|
|
|
if result["type"] == "async":
|
|
# Mark this response with .asynchronous; this will result in
|
|
# Tornado discarding the response and instead long-polling the
|
|
# request. See zulip_finish for more design details.
|
|
handler._request = request
|
|
response = json_success()
|
|
response.asynchronous = True
|
|
return response
|
|
if result["type"] == "error":
|
|
raise result["exception"]
|
|
return json_success(result["response"])
|