mirror of
https://github.com/zulip/zulip.git
synced 2025-11-09 08:26:11 +00:00
scheduledmessages: Start using/expecting delivery_type as a param.
This commit is contained in:
@@ -350,6 +350,7 @@ function patch_request_for_scheduling(request) {
|
|||||||
|
|
||||||
new_request.content = message;
|
new_request.content = message;
|
||||||
new_request.deliver_at = deliver_at;
|
new_request.deliver_at = deliver_at;
|
||||||
|
new_request.delivery_type = 'send_later';
|
||||||
new_request.tz_guess = moment.tz.guess();
|
new_request.tz_guess = moment.tz.guess();
|
||||||
return new_request;
|
return new_request;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1041,6 +1041,10 @@ def do_schedule_messages(messages: Sequence[Optional[MutableMapping[str, Any]]])
|
|||||||
scheduled_message.stream = message['stream']
|
scheduled_message.stream = message['stream']
|
||||||
scheduled_message.realm = message['realm']
|
scheduled_message.realm = message['realm']
|
||||||
scheduled_message.scheduled_timestamp = message['deliver_at']
|
scheduled_message.scheduled_timestamp = message['deliver_at']
|
||||||
|
if message['delivery_type'] == 'send_later':
|
||||||
|
scheduled_message.delivery_type = ScheduledMessage.SEND_LATER
|
||||||
|
elif message['delivery_type'] == 'remind':
|
||||||
|
scheduled_message.delivery_type = ScheduledMessage.REMIND
|
||||||
|
|
||||||
scheduled_messages.append(scheduled_message)
|
scheduled_messages.append(scheduled_message)
|
||||||
|
|
||||||
@@ -1690,7 +1694,7 @@ def check_send_message(sender: UserProfile, client: Client, message_type_name: T
|
|||||||
def check_schedule_message(sender: UserProfile, client: Client,
|
def check_schedule_message(sender: UserProfile, client: Client,
|
||||||
message_type_name: Text, message_to: Sequence[Text],
|
message_type_name: Text, message_to: Sequence[Text],
|
||||||
topic_name: Optional[Text], message_content: Text,
|
topic_name: Optional[Text], message_content: Text,
|
||||||
deliver_at: datetime.datetime,
|
delivery_type: Text, deliver_at: datetime.datetime,
|
||||||
realm: Optional[Realm]=None,
|
realm: Optional[Realm]=None,
|
||||||
forwarder_user_profile: Optional[UserProfile]=None
|
forwarder_user_profile: Optional[UserProfile]=None
|
||||||
) -> int:
|
) -> int:
|
||||||
@@ -1704,6 +1708,7 @@ def check_schedule_message(sender: UserProfile, client: Client,
|
|||||||
message_content, realm=realm,
|
message_content, realm=realm,
|
||||||
forwarder_user_profile=forwarder_user_profile)
|
forwarder_user_profile=forwarder_user_profile)
|
||||||
message['deliver_at'] = deliver_at
|
message['deliver_at'] = deliver_at
|
||||||
|
message['delivery_type'] = delivery_type
|
||||||
return do_schedule_messages([message])[0]
|
return do_schedule_messages([message])[0]
|
||||||
|
|
||||||
def check_stream_name(stream_name: Text) -> None:
|
def check_stream_name(stream_name: Text) -> None:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from django.utils.timezone import now as timezone_now
|
|||||||
|
|
||||||
from zerver.lib.context_managers import lockfile
|
from zerver.lib.context_managers import lockfile
|
||||||
from zerver.lib.logging_util import log_to_file
|
from zerver.lib.logging_util import log_to_file
|
||||||
from zerver.models import ScheduledMessage, Message
|
from zerver.models import ScheduledMessage, Message, get_user
|
||||||
from zerver.lib.actions import do_send_messages
|
from zerver.lib.actions import do_send_messages
|
||||||
from zerver.lib.addressee import Addressee
|
from zerver.lib.addressee import Addressee
|
||||||
|
|
||||||
@@ -27,13 +27,21 @@ Usage: ./manage.py deliver_scheduled_messages
|
|||||||
|
|
||||||
def construct_message(self, scheduled_message: ScheduledMessage) -> Dict[str, Any]:
|
def construct_message(self, scheduled_message: ScheduledMessage) -> Dict[str, Any]:
|
||||||
message = Message()
|
message = Message()
|
||||||
message.sender = scheduled_message.sender
|
original_sender = scheduled_message.sender
|
||||||
message.content = scheduled_message.content
|
message.content = scheduled_message.content
|
||||||
message.recipient = scheduled_message.recipient
|
message.recipient = scheduled_message.recipient
|
||||||
message.subject = scheduled_message.subject
|
message.subject = scheduled_message.subject
|
||||||
message.pub_date = timezone_now()
|
message.pub_date = timezone_now()
|
||||||
message.sending_client = scheduled_message.sending_client
|
message.sending_client = scheduled_message.sending_client
|
||||||
|
|
||||||
|
delivery_type = scheduled_message.delivery_type
|
||||||
|
if delivery_type == ScheduledMessage.SEND_LATER:
|
||||||
|
message.sender = original_sender
|
||||||
|
elif delivery_type == ScheduledMessage.REMIND:
|
||||||
|
message.sender = get_user(settings.REMINDER_BOT, original_sender.realm)
|
||||||
|
whos_reminding = ('%s asked me to do a reminder about:\n' % (original_sender.full_name))
|
||||||
|
message.content = whos_reminding + message.content
|
||||||
|
|
||||||
return {'message': message, 'stream': scheduled_message.stream,
|
return {'message': message, 'stream': scheduled_message.stream,
|
||||||
'realm': scheduled_message.realm}
|
'realm': scheduled_message.realm}
|
||||||
|
|
||||||
|
|||||||
@@ -1280,7 +1280,8 @@ class ScheduledMessageTest(ZulipTestCase):
|
|||||||
return ScheduledMessage.objects.all().order_by('-id')[0]
|
return ScheduledMessage.objects.all().order_by('-id')[0]
|
||||||
|
|
||||||
def do_schedule_message(self, msg_type: str, to: str, msg: str,
|
def do_schedule_message(self, msg_type: str, to: str, msg: str,
|
||||||
defer_until: str, tz_guess: str='',
|
defer_until: str='', tz_guess: str='',
|
||||||
|
delivery_type: str='send_later',
|
||||||
realm_str: str='zulip') -> HttpResponse:
|
realm_str: str='zulip') -> HttpResponse:
|
||||||
self.login(self.example_email("hamlet"))
|
self.login(self.example_email("hamlet"))
|
||||||
|
|
||||||
@@ -1288,15 +1289,18 @@ class ScheduledMessageTest(ZulipTestCase):
|
|||||||
if msg_type == 'stream':
|
if msg_type == 'stream':
|
||||||
subject = 'Test subject'
|
subject = 'Test subject'
|
||||||
|
|
||||||
result = self.client_post("/json/messages",
|
payload = {"type": msg_type,
|
||||||
{"type": msg_type,
|
"to": to,
|
||||||
"to": to,
|
"client": "test suite",
|
||||||
"client": "test suite",
|
"content": msg,
|
||||||
"content": msg,
|
"subject": subject,
|
||||||
"subject": subject,
|
"realm_str": realm_str,
|
||||||
"realm_str": realm_str,
|
"delivery_type": delivery_type,
|
||||||
"deliver_at": defer_until,
|
"tz_guess": tz_guess}
|
||||||
"tz_guess": tz_guess})
|
if defer_until:
|
||||||
|
payload["deliver_at"] = defer_until
|
||||||
|
|
||||||
|
result = self.client_post("/json/messages", payload)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def test_schedule_message(self) -> None:
|
def test_schedule_message(self) -> None:
|
||||||
@@ -1311,27 +1315,44 @@ class ScheduledMessageTest(ZulipTestCase):
|
|||||||
self.assert_json_success(result)
|
self.assert_json_success(result)
|
||||||
self.assertEqual(message.content, 'Test message 1')
|
self.assertEqual(message.content, 'Test message 1')
|
||||||
self.assertEqual(message.scheduled_timestamp, convert_to_UTC(defer_until))
|
self.assertEqual(message.scheduled_timestamp, convert_to_UTC(defer_until))
|
||||||
|
self.assertEqual(message.delivery_type, ScheduledMessage.SEND_LATER)
|
||||||
|
# Scheduling a message for reminders.
|
||||||
|
result = self.do_schedule_message('stream', 'Verona',
|
||||||
|
content + ' 2', defer_until_str,
|
||||||
|
delivery_type='remind')
|
||||||
|
message = self.last_scheduled_message()
|
||||||
|
self.assert_json_success(result)
|
||||||
|
self.assertEqual(message.delivery_type, ScheduledMessage.REMIND)
|
||||||
|
|
||||||
# Scheduling a private message is successful.
|
# Scheduling a private message is successful.
|
||||||
result = self.do_schedule_message('private', self.example_email("othello"),
|
result = self.do_schedule_message('private', self.example_email("othello"),
|
||||||
content + ' 2', defer_until_str)
|
content + ' 3', defer_until_str)
|
||||||
message = self.last_scheduled_message()
|
|
||||||
self.assert_json_success(result)
|
|
||||||
self.assertEqual(message.content, 'Test message 2')
|
|
||||||
self.assertEqual(message.scheduled_timestamp, convert_to_UTC(defer_until))
|
|
||||||
|
|
||||||
# Scheduling a message while guessing timezone.
|
|
||||||
tz_guess = 'Asia/Kolkata'
|
|
||||||
result = self.do_schedule_message('stream', 'Verona', content + ' 3',
|
|
||||||
defer_until_str, tz_guess=tz_guess)
|
|
||||||
message = self.last_scheduled_message()
|
message = self.last_scheduled_message()
|
||||||
self.assert_json_success(result)
|
self.assert_json_success(result)
|
||||||
self.assertEqual(message.content, 'Test message 3')
|
self.assertEqual(message.content, 'Test message 3')
|
||||||
|
self.assertEqual(message.scheduled_timestamp, convert_to_UTC(defer_until))
|
||||||
|
self.assertEqual(message.delivery_type, ScheduledMessage.SEND_LATER)
|
||||||
|
|
||||||
|
result = self.do_schedule_message('private', self.example_email("othello"),
|
||||||
|
content + ' 4', defer_until_str,
|
||||||
|
delivery_type='remind')
|
||||||
|
message = self.last_scheduled_message()
|
||||||
|
self.assert_json_success(result)
|
||||||
|
self.assertEqual(message.delivery_type, ScheduledMessage.REMIND)
|
||||||
|
|
||||||
|
# Scheduling a message while guessing timezone.
|
||||||
|
tz_guess = 'Asia/Kolkata'
|
||||||
|
result = self.do_schedule_message('stream', 'Verona', content + ' 5',
|
||||||
|
defer_until_str, tz_guess=tz_guess)
|
||||||
|
message = self.last_scheduled_message()
|
||||||
|
self.assert_json_success(result)
|
||||||
|
self.assertEqual(message.content, 'Test message 5')
|
||||||
local_tz = get_timezone(tz_guess)
|
local_tz = get_timezone(tz_guess)
|
||||||
# Since mypy is not able to recognize localize and normalize as attributes of tzinfo we use ignore.
|
# Since mypy is not able to recognize localize and normalize as attributes of tzinfo we use ignore.
|
||||||
utz_defer_until = local_tz.normalize(local_tz.localize(defer_until)) # type: ignore # Reason in comment on previous line.
|
utz_defer_until = local_tz.normalize(local_tz.localize(defer_until)) # type: ignore # Reason in comment on previous line.
|
||||||
self.assertEqual(message.scheduled_timestamp,
|
self.assertEqual(message.scheduled_timestamp,
|
||||||
convert_to_UTC(utz_defer_until))
|
convert_to_UTC(utz_defer_until))
|
||||||
|
self.assertEqual(message.delivery_type, ScheduledMessage.SEND_LATER)
|
||||||
|
|
||||||
# Test with users timezone setting as set to some timezone rather than
|
# Test with users timezone setting as set to some timezone rather than
|
||||||
# empty. This will help interpret timestamp in users local timezone.
|
# empty. This will help interpret timestamp in users local timezone.
|
||||||
@@ -1339,15 +1360,16 @@ class ScheduledMessageTest(ZulipTestCase):
|
|||||||
user.timezone = 'US/Pacific'
|
user.timezone = 'US/Pacific'
|
||||||
user.save(update_fields=['timezone'])
|
user.save(update_fields=['timezone'])
|
||||||
result = self.do_schedule_message('stream', 'Verona',
|
result = self.do_schedule_message('stream', 'Verona',
|
||||||
content + ' 4', defer_until_str)
|
content + ' 6', defer_until_str)
|
||||||
message = self.last_scheduled_message()
|
message = self.last_scheduled_message()
|
||||||
self.assert_json_success(result)
|
self.assert_json_success(result)
|
||||||
self.assertEqual(message.content, 'Test message 4')
|
self.assertEqual(message.content, 'Test message 6')
|
||||||
local_tz = get_timezone(user.timezone)
|
local_tz = get_timezone(user.timezone)
|
||||||
# Since mypy is not able to recognize localize and normalize as attributes of tzinfo we use ignore.
|
# Since mypy is not able to recognize localize and normalize as attributes of tzinfo we use ignore.
|
||||||
utz_defer_until = local_tz.normalize(local_tz.localize(defer_until)) # type: ignore # Reason in comment on previous line.
|
utz_defer_until = local_tz.normalize(local_tz.localize(defer_until)) # type: ignore # Reason in comment on previous line.
|
||||||
self.assertEqual(message.scheduled_timestamp,
|
self.assertEqual(message.scheduled_timestamp,
|
||||||
convert_to_UTC(utz_defer_until))
|
convert_to_UTC(utz_defer_until))
|
||||||
|
self.assertEqual(message.delivery_type, ScheduledMessage.SEND_LATER)
|
||||||
|
|
||||||
def test_scheduling_in_past(self) -> None:
|
def test_scheduling_in_past(self) -> None:
|
||||||
# Scheduling a message in past should fail.
|
# Scheduling a message in past should fail.
|
||||||
@@ -1369,6 +1391,13 @@ class ScheduledMessageTest(ZulipTestCase):
|
|||||||
content + ' 1', defer_until)
|
content + ' 1', defer_until)
|
||||||
self.assert_json_error(result, 'Invalid timestamp for scheduling message.')
|
self.assert_json_error(result, 'Invalid timestamp for scheduling message.')
|
||||||
|
|
||||||
|
def test_missing_deliver_at(self) -> None:
|
||||||
|
content = "Test message"
|
||||||
|
|
||||||
|
result = self.do_schedule_message('stream', 'Verona',
|
||||||
|
content + ' 1')
|
||||||
|
self.assert_json_error(result, 'Missing deliver_at in a request for delayed message delivery')
|
||||||
|
|
||||||
class EditMessageTest(ZulipTestCase):
|
class EditMessageTest(ZulipTestCase):
|
||||||
def check_message(self, msg_id: int, subject: Optional[Text]=None,
|
def check_message(self, msg_id: int, subject: Optional[Text]=None,
|
||||||
content: Optional[Text]=None) -> Message:
|
content: Optional[Text]=None) -> Message:
|
||||||
|
|||||||
@@ -908,7 +908,7 @@ def same_realm_jabber_user(user_profile: UserProfile, email: Text) -> bool:
|
|||||||
def handle_deferred_message(sender: UserProfile, client: Client,
|
def handle_deferred_message(sender: UserProfile, client: Client,
|
||||||
message_type_name: Text, message_to: Sequence[Text],
|
message_type_name: Text, message_to: Sequence[Text],
|
||||||
topic_name: Optional[Text],
|
topic_name: Optional[Text],
|
||||||
message_content: Text,
|
message_content: Text, delivery_type: Text,
|
||||||
defer_until: Text, tz_guess: Text,
|
defer_until: Text, tz_guess: Text,
|
||||||
forwarder_user_profile: UserProfile,
|
forwarder_user_profile: UserProfile,
|
||||||
realm: Optional[Realm]) -> HttpResponse:
|
realm: Optional[Realm]) -> HttpResponse:
|
||||||
@@ -934,7 +934,7 @@ def handle_deferred_message(sender: UserProfile, client: Client,
|
|||||||
return json_error(_("Invalid timestamp for scheduling message. Choose a time in future."))
|
return json_error(_("Invalid timestamp for scheduling message. Choose a time in future."))
|
||||||
|
|
||||||
check_schedule_message(sender, client, message_type_name, message_to,
|
check_schedule_message(sender, client, message_type_name, message_to,
|
||||||
topic_name, message_content,
|
topic_name, message_content, delivery_type,
|
||||||
deliver_at, realm=realm,
|
deliver_at, realm=realm,
|
||||||
forwarder_user_profile=forwarder_user_profile)
|
forwarder_user_profile=forwarder_user_profile)
|
||||||
return json_success({"deliver_at": str(deliver_at_usertz)})
|
return json_success({"deliver_at": str(deliver_at_usertz)})
|
||||||
@@ -953,6 +953,7 @@ def send_message_backend(request: HttpRequest, user_profile: UserProfile,
|
|||||||
realm_str: Optional[Text]=REQ('realm_str', default=None),
|
realm_str: Optional[Text]=REQ('realm_str', default=None),
|
||||||
local_id: Optional[Text]=REQ(default=None),
|
local_id: Optional[Text]=REQ(default=None),
|
||||||
queue_id: Optional[Text]=REQ(default=None),
|
queue_id: Optional[Text]=REQ(default=None),
|
||||||
|
delivery_type: Optional[Text]=REQ('delivery_type', default='send_now'),
|
||||||
defer_until: Optional[Text]=REQ('deliver_at', default=None),
|
defer_until: Optional[Text]=REQ('deliver_at', default=None),
|
||||||
tz_guess: Optional[Text]=REQ('tz_guess', default=None)) -> HttpResponse:
|
tz_guess: Optional[Text]=REQ('tz_guess', default=None)) -> HttpResponse:
|
||||||
client = request.client
|
client = request.client
|
||||||
@@ -999,10 +1000,13 @@ def send_message_backend(request: HttpRequest, user_profile: UserProfile,
|
|||||||
else:
|
else:
|
||||||
sender = user_profile
|
sender = user_profile
|
||||||
|
|
||||||
if defer_until:
|
if (delivery_type == 'send_later' or delivery_type == 'remind') and defer_until is None:
|
||||||
|
return json_error(_("Missing deliver_at in a request for delayed message delivery"))
|
||||||
|
|
||||||
|
if delivery_type == 'send_later' or delivery_type == 'remind' and defer_until:
|
||||||
return handle_deferred_message(sender, client, message_type_name,
|
return handle_deferred_message(sender, client, message_type_name,
|
||||||
message_to, topic_name, message_content,
|
message_to, topic_name, message_content,
|
||||||
defer_until, tz_guess,
|
delivery_type, defer_until, tz_guess,
|
||||||
forwarder_user_profile=user_profile,
|
forwarder_user_profile=user_profile,
|
||||||
realm=realm)
|
realm=realm)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user