FIX: Failed incoming emails could create empty topics

A failure condition is eliminated where a topic would be created, but post
creation would fail, leaving the forum with a topic without any posts.
By asking PostCreator to create the topic instead, inside of its
transaction, this failure condition is eliminated.

Additionally, attachments are restored to working status. Previously,
the attachment code would build up the post raw, but then drop it and
not do anything with the result (creating orphaned uploads). By actually
placing the raw value back in the options hash, it is included in the
created post.
This commit is contained in:
riking 2014-08-26 17:30:12 -07:00
parent 30b102aa98
commit 0d0225133c
1 changed files with 20 additions and 18 deletions

View File

@ -94,7 +94,6 @@ module Email
{type: :invalid, obj: nil} {type: :invalid, obj: nil}
end end
private
def parse_body def parse_body
html = nil html = nil
@ -168,37 +167,37 @@ module Email
[/quote]" [/quote]"
end end
private
def create_reply def create_reply
create_post_with_attachments(email_log.user, @body, @email_log.topic_id, @email_log.post.post_number) create_post_with_attachments(@email_log.user,
raw: @body,
topic_id: @email_log.topic_id,
reply_to_post_number: @email_log.post.post_number)
end end
def create_new_topic def create_new_topic
topic = TopicCreator.new( post = create_post_with_attachments(@user,
@user, raw: @body,
Guardian.new(@user), title: @message.subject,
category: @category_id, category: @category_id)
title: @message.subject,
).create
post = create_post_with_attachments(@user, @body, topic.id)
EmailLog.create( EmailLog.create(
email_type: "topic_via_incoming_email", email_type: "topic_via_incoming_email",
to_address: @message.to.first, to_address: @message.from.first, # pick from address because we want the user's email
topic_id: topic.id, topic_id: post.topic.id,
user_id: @user.id, user_id: @user.id,
) )
post post
end end
def create_post_with_attachments(user, raw, topic_id, reply_to_post_number=nil) def create_post_with_attachments(user, post_opts={})
options = { options = {
raw: raw,
topic_id: topic_id,
cooking_options: { traditional_markdown_linebreaks: true }, cooking_options: { traditional_markdown_linebreaks: true },
} }.merge(post_opts)
options[:reply_to_post_number] = reply_to_post_number if reply_to_post_number
raw = options[:raw]
# deal with attachments # deal with attachments
@message.attachments.each do |attachment| @message.attachments.each do |attachment|
@ -215,9 +214,10 @@ module Email
ensure ensure
tmp.close! tmp.close!
end end
end end
options[:raw] = raw
create_post(user, options) create_post(user, options)
end end
@ -232,9 +232,11 @@ module Email
def create_post(user, options) def create_post(user, options)
creator = PostCreator.new(user, options) creator = PostCreator.new(user, options)
post = creator.create post = creator.create
if creator.errors.present? if creator.errors.present?
raise InvalidPost, creator.errors.full_messages.join("\n") raise InvalidPost, creator.errors.full_messages.join("\n")
end end
post post
end end