Rewrite internal_send_message to use check_send_message.

This will automatically fix bugs such as one in which
internal_send_message didn't properly strip() the subject argument
before sending a message.

We change the recipient_type argument to internal_send_message to take
the recipient type name (e.g. 'stream') both to better fit the API and
also because the previous code incorrectly handled huddles.

(imported from commit 78c2596d328f6bb1ce2eaa3eed9a9e48146e3b6a)
This commit is contained in:
Tim Abbott 2013-03-18 14:10:21 -04:00
parent bb80d1c58c
commit 97d7d31b68
4 changed files with 33 additions and 47 deletions

View File

@ -66,7 +66,7 @@ class AdminHumbugHandler(logging.Handler):
try:
internal_send_message("humbug+errors@humbughq.com",
Recipient.STREAM, "devel", self.format_subject(subject),
"stream", "devel", self.format_subject(subject),
"Error generated by %s\n\n~~~~ pytb\n%s\n\n~~~~\n%s" % (
user_info, stack_trace, request_repr))
except:

View File

@ -18,7 +18,7 @@ from zephyr.lib.create_user import create_user
from zephyr.lib.bulk_create import batch_bulk_create
from zephyr.lib import bugdown
from zephyr.lib.cache import cache_with_key, user_profile_by_id_cache_key
from zephyr.lib.decorator import get_user_profile_by_email
from zephyr.decorator import get_user_profile_by_email, json_to_list
import subprocess
import simplejson
@ -245,6 +245,17 @@ def already_sent_mirrored_message(message):
pub_date__gte=pub_date_lowres - time_window,
pub_date__lte=pub_date_lowres + time_window).exists()
def extract_recipients(raw_recipients):
try:
recipients = json_to_list(raw_recipients)
except (simplejson.decoder.JSONDecodeError, ValueError):
recipients = [raw_recipients]
# Strip recipients, and then remove any duplicates and any that
# are the empty string after being stripped.
recipients = [recipient.strip() for recipient in recipients]
return list(set(recipient for recipient in recipients if recipient))
# check_send_message:
# Returns None on success or the error message on error.
def check_send_message(sender, client, message_type_name, message_to,
@ -321,35 +332,22 @@ def check_send_message(sender, client, message_type_name, message_to,
return None
def internal_send_message(sender_email, recipient_type, recipient,
def internal_send_message(sender_email, recipient_type_name, recipients,
subject, content, realm=None):
stream = None
if len(content) > MAX_MESSAGE_LENGTH:
content = content[0:3900] + "\n\n[message was too long and has been truncated]"
rendered_content = bugdown.convert(content)
if rendered_content is None:
rendered_content = "<p>[Message could not be rendered by bugdown!]</p>"
sender = get_user_profile_by_email(sender_email)
if realm is None:
realm = sender.realm
parsed_recipients = extract_recipients(recipients)
if recipient_type_name == "stream":
stream, _ = create_stream_if_needed(realm, parsed_recipients[0])
message = Message()
message.sender = UserProfile.objects.get(user__email__iexact=sender_email)
if recipient_type == Recipient.STREAM:
if realm is None:
realm = message.sender.realm
stream, _ = create_stream_if_needed(realm, recipient)
type_id = stream.id
else:
type_id = UserProfile.objects.get(user__email__iexact=recipient).id
message.recipient = get_recipient(recipient_type, type_id)
message.subject = subject
message.content = content
message.pub_date = timezone.now()
message.sending_client = get_client("Internal")
do_send_message(message, rendered_content=rendered_content, stream=stream)
ret = check_send_message(sender, get_client("Internal"), recipient_type_name,
parsed_recipients, subject, content, realm)
if ret is not None:
logging.error("Error sending internal message by %s: %s" % (sender_email, ret))
def get_stream_colors(user_profile):
return [(sub["name"], sub["color"]) for sub in gather_subscriptions(user_profile)]
@ -465,7 +463,7 @@ def do_create_realm(domain, replay=False):
log_event({"type": "realm_created",
"domain": domain})
internal_send_message("humbug+signups@humbughq.com", Recipient.STREAM,
internal_send_message("humbug+signups@humbughq.com", "stream",
"signups", domain, "Signups enabled.")
return (realm, created)

View File

@ -464,9 +464,8 @@ def convert(md):
logging.getLogger('').error('Exception in Markdown parser: %sInput (sanitized) was: %s'
% (traceback.format_exc(), cleaned))
subject = "Markdown parser failure"
internal_send_message("humbug+errors@humbughq.com",
Recipient.STREAM, "devel", subject,
"Markdown parser failed, message sent to devel@")
internal_send_message("humbug+errors@humbughq.com", "stream",
"devel", subject, "Markdown parser failed, message sent to devel@")
mail.mail_admins(subject, "Failed message: %s\n\n%s\n\n" % (
cleaned, traceback.format_exc()),
fail_silently=False)

View File

@ -24,7 +24,7 @@ from zephyr.lib.actions import do_add_subscription, do_remove_subscription, \
log_subscription_property_change, internal_send_message, \
create_stream_if_needed, gather_subscriptions, subscribed_to_stream, \
update_user_presence, set_stream_color, get_stream_colors, update_message_flags, \
recipient_for_emails
recipient_for_emails, extract_recipients
from zephyr.forms import RegistrationForm, HomepageForm, ToSForm, is_unique, \
is_inactive, isnt_mit
from django.views.decorators.csrf import csrf_exempt
@ -112,7 +112,7 @@ def send_signup_message(sender, signups_stream, user_profile, internal=False):
internal_blurb = " "
internal_send_message(sender,
Recipient.STREAM, signups_stream, user_profile.realm.domain,
"stream", signups_stream, user_profile.realm.domain,
"%s <`%s`> just signed up for Humbug!%s(total: **%i**)" % (
user_profile.full_name,
user_profile.user.email,
@ -208,7 +208,7 @@ def accounts_register(request):
if prereg_user.referred_by is not None:
# This is a cross-realm private message.
internal_send_message("humbug+signups@humbughq.com",
Recipient.PERSONAL, prereg_user.referred_by.user.email, user_profile.realm.domain,
"private", prereg_user.referred_by.user.email, user_profile.realm.domain,
"%s <`%s`> accepted your invitation to join Humbug!" % (
user_profile.full_name,
user_profile.user.email,
@ -704,17 +704,6 @@ def mit_to_mit(user_profile, email):
domain = email.split("@", 1)[1]
return user_profile.realm.domain == domain
def extract_recipients(raw_recipients):
try:
recipients = json_to_list(raw_recipients)
except (simplejson.decoder.JSONDecodeError, ValueError):
recipients = [raw_recipients]
# Strip recipients, and then remove any duplicates and any that
# are the empty string after being stripped.
recipients = [recipient.strip() for recipient in recipients]
return list(set(recipient for recipient in recipients if recipient))
def create_mirrored_message_users(request, user_profile, recipients):
if "sender" not in request.POST:
return (False, None)
@ -754,7 +743,7 @@ def json_tutorial_send_message(request, user_profile,
# For now, we discard the recipient on PMs; the tutorial bot
# can only send to you.
internal_send_message(sender_name,
Recipient.PERSONAL,
"private",
user_profile.user.email,
"",
message_content,
@ -765,7 +754,7 @@ def json_tutorial_send_message(request, user_profile,
## TODO: For open realms, we need to use the full name here,
## so that me@gmail.com and me@hotmail.com don't get the same stream.
internal_send_message(sender_name,
Recipient.STREAM,
"stream",
tutorial_stream_name,
subject_name,
message_content,
@ -939,7 +928,7 @@ def add_subscriptions_backend(request, user_profile,
stream,
" (**invite-only**)" if private_streams[stream] else "")
internal_send_message("humbug+notifications@humbughq.com",
Recipient.PERSONAL, email, "", msg)
"private", email, "", msg)
result["subscribed"] = dict(result["subscribed"])
result["already_subscribed"] = dict(result["already_subscribed"])