<commit_before># models/request_mailer.rb:
# Alerts relating to requests.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
# Email: <EMAIL>; WWW: http://www.mysociety.org/
#
# $Id: request_mailer.rb,v 1.89 2009-10-04 21:53:54 francis Exp $

class RequestMailer < ApplicationMailer
    
    # Used when an FOI officer uploads a response from their web browser - this is
    # the "fake" email used to store in the same format in the database as if they
    # had emailed it.
    def fake_response(info_request, from_user, body, attachment_name, attachment_content)
        @from = from_user.name_and_email
        @recipients = info_request.incoming_name_and_email
        @body = {
            :body => body
        }
        if !attachment_name.nil? && !attachment_content.nil?
            IncomingMessage # load global filename_to_mimetype XXX should move filename_to_mimetype to proper namespace
            calc_mime = filename_to_mimetype(attachment_name)
            if calc_mime
                content_type = calc_mime
            else
                content_type = 'application/octet-stream'
            end

            attachment :content_type => content_type,
                :body => attachment_content,
                :filename => attachment_name
        end
    end

    # Incoming message arrived for a request, but new responses have been stopped.
    def stopped_responses(info_request, email, raw_email_data)
        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # we don't care about bounces, likely from spammers
                'Auto-Submitted' => 'auto-replied' # http://tools.ietf.org/html/rfc3834
        @recipients = email.from_addrs[0].to_s
        @subject = "Your response to an FOI request was not delivered"
        attachment :content_type => 'message/rfc822', :body => raw_email_data,
            :filename => "original.eml", :transfer_encoding => '7bit', :content_disposition => 'inline'
        @body = { 
            :info_request => info_request,
            :contact_email => MySociety::Config.get("CONTACT_EMAIL", '<EMAIL>@localhost')     
        }
    end

    # An FOI response is outside the scope of the system, and needs admin attention
    def requires_admin(info_request)
        @from = info_request.user.name_and_email
        @recipients = contact_from_name_and_email
        @subject = "FOI response requires admin - " + info_request.title
        url = main_url(request_url(info_request))
        admin_url = request_admin_url(info_request)
        @body = {:info_request => info_request, :url => url, :admin_url => admin_url }
    end

    # Tell the requester that a new response has arrived
    def new_response(info_request, incoming_message)
        # Don't use login link here, just send actual URL. This is
        # because people tend to forward these emails amongst themselves.
        url = main_url(incoming_message_url(incoming_message))

        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
                'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
        @recipients = info_request.user.name_and_email
        @subject = "New response to your FOI request - " + info_request.title
        @body = { :incoming_message => incoming_message, :info_request => info_request, :url => url }
    end

    # Tell the requester that the public body is late in replying
    def overdue_alert(info_request, user)
        respond_url = respond_to_last_url(info_request) + "#followup"

        post_redirect = PostRedirect.new(
            :uri => respond_url,
            :user_id => user.id)
        post_redirect.save!
        url = confirm_url(:email_token => post_redirect.email_token)

        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
                'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
        @recipients = user.name_and_email
        @subject = "Delayed response to your FOI request - " + info_request.title
        @body = { :info_request => info_request, :url => url }
    end

    # Tell the requester that the public body is very late in replying
    def very_overdue_alert(info_request, user)
        respond_url = respond_to_last_url(info_request) + "#followup"

        post_redirect = PostRedirect.new(
            :uri => respond_url,
            :user_id => user.id)
        post_redirect.save!
        url = confirm_url(:email_token => post_redirect.email_token)

        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
                'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
        @recipients = user.name_and_email
        @subject = "You're long overdue a response to your FOI request - " + info_request.title
        @body = { :info_request => info_request, :url => url }
    end

    # Tell the requester that they need to say if the new response
    # contains info or not
    def new_response_reminder_alert(info_request, incoming_message)
        # Make a link going to the form to describe state, and which logs the
        # user in.
        post_redirect = PostRedirect.new(
            :uri => main_url(request_url(info_request)) + "#describe_state_form_1",
            :user_id => info_request.user.id)
        post_redirect.save!
        url = confirm_url(:email_token => post_redirect.email_token)

        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
                'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
        @recipients = info_request.user.name_and_email
        @subject = "Was the response you got to your FOI request any good?"
        @body = { :incoming_message => incoming_message, :info_request => info_request, :url => url }
    end

    # Tell the requester that someone updated their old unclassified request
    def old_unclassified_updated(info_request)
        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
                'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
        @recipients = info_request.user.name_and_email
        @subject = "Someone has updated the status of your request"
        url = main_url(request_url(info_request))
        @body = {:info_request => info_request, :url => url}
    end

    # Tell the requester that they need to clarify their request
    def not_clarified_alert(info_request, incoming_message)
        respond_url = show_response_url(:id => info_request.id, :incoming_message_id => incoming_message.id)
        respond_url = respond_url + "#followup" 

        post_redirect = PostRedirect.new(
            :uri => respond_url,
            :user_id => info_request.user.id)
        post_redirect.save!
        url = confirm_url(:email_token => post_redirect.email_token)

        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
                'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
        @recipients = info_request.user.name_and_email
        @subject = "Clarify your FOI request - " + info_request.title
        @body = { :incoming_message => incoming_message, :info_request => info_request, :url => url }
    end

    # Tell requester that somebody add an annotation to their request
    def comment_on_alert(info_request, comment)
        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
                'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
        @recipients = info_request.user.name_and_email
        @subject = "Somebody added a note to your FOI request - " + info_request.title
        @body = { :comment => comment, :info_request => info_request, :url => main_url(comment_url(comment)) }
    end
    def comment_on_alert_plural(info_request, count, earliest_unalerted_comment)
        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
                'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
        @recipients = info_request.user.name_and_email
        @subject = "Some notes have been added to your FOI request - " + info_request.title
        @body = { :count => count, :info_request => info_request, :url => main_url(comment_url(earliest_unalerted_comment)) }
    end

    # Class function, called by script/mailin with all incoming responses.
    # [ This is a copy (Monkeypatch!) of function from action_mailer/base.rb,
    # but which additionally passes the raw_email to the member function, as we
    # want to record it. ]
    def self.receive(raw_email)
        logger.info "Received mail:\n #{raw_email}" unless logger.nil?
        mail = TMail::Mail.parse(raw_email)
        mail.base64_decode
        new.receive(mail, raw_email)
    end

    # Find which info requests the email is for
    def requests_matching_email(email)
        # We deliberately don't use Envelope-to here, so ones that are BCC
        # drop into the holding pen for checking.
        reply_info_requests = [] # XXX should be set?
        for address in (email.to || []) + (email.cc || [])
            reply_info_request = InfoRequest.find_by_incoming_email(address)
            reply_info_requests.push(reply_info_request) if reply_info_request
        end
        return reply_info_requests
    end

    # Member function, called on the new class made in self.receive above
    def receive(email, raw_email)
        # Find which info requests the email is for
        reply_info_requests = self.requests_matching_email(email)

        # Nothing found, so save in holding pen
        if reply_info_requests.size == 0 
            InfoRequest.holding_pen_request.receive(email, raw_email)
            return
        end<commit_msg>Explain why we want to record the original raw email<commit_after># models/request_mailer.rb:
# Alerts relating to requests.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
# Email: <EMAIL>; WWW: http://www.mysociety.org/
#
# $Id: request_mailer.rb,v 1.89 2009-10-04 21:53:54 francis Exp $

class RequestMailer < ApplicationMailer
    
    # Used when an FOI officer uploads a response from their web browser - this is
    # the "fake" email used to store in the same format in the database as if they
    # had emailed it.
    def fake_response(info_request, from_user, body, attachment_name, attachment_content)
        @from = from_user.name_and_email
        @recipients = info_request.incoming_name_and_email
        @body = {
            :body => body
        }
        if !attachment_name.nil? && !attachment_content.nil?
            IncomingMessage # load global filename_to_mimetype XXX should move filename_to_mimetype to proper namespace
            calc_mime = filename_to_mimetype(attachment_name)
            if calc_mime
                content_type = calc_mime
            else
                content_type = 'application/octet-stream'
            end

            attachment :content_type => content_type,
                :body => attachment_content,
                :filename => attachment_name
        end
    end

    # Incoming message arrived for a request, but new responses have been stopped.
    def stopped_responses(info_request, email, raw_email_data)
        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # we don't care about bounces, likely from spammers
                'Auto-Submitted' => 'auto-replied' # http://tools.ietf.org/html/rfc3834
        @recipients = email.from_addrs[0].to_s
        @subject = "Your response to an FOI request was not delivered"
        attachment :content_type => 'message/rfc822', :body => raw_email_data,
            :filename => "original.eml", :transfer_encoding => '7bit', :content_disposition => 'inline'
        @body = { 
            :info_request => info_request,
            :contact_email => MySociety::Config.get("CONTACT_EMAIL", 'contact@localhost')     
        }
    end

    # An FOI response is outside the scope of the system, and needs admin attention
    def requires_admin(info_request)
        @from = info_request.user.name_and_email
        @recipients = contact_from_name_and_email
        @subject = "FOI response requires admin - " + info_request.title
        url = main_url(request_url(info_request))
        admin_url = request_admin_url(info_request)
        @body = {:info_request => info_request, :url => url, :admin_url => admin_url }
    end

    # Tell the requester that a new response has arrived
    def new_response(info_request, incoming_message)
        # Don't use login link here, just send actual URL. This is
        # because people tend to forward these emails amongst themselves.
        url = main_url(incoming_message_url(incoming_message))

        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
                'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
        @recipients = info_request.user.name_and_email
        @subject = "New response to your FOI request - " + info_request.title
        @body = { :incoming_message => incoming_message, :info_request => info_request, :url => url }
    end

    # Tell the requester that the public body is late in replying
    def overdue_alert(info_request, user)
        respond_url = respond_to_last_url(info_request) + "#followup"

        post_redirect = PostRedirect.new(
            :uri => respond_url,
            :user_id => user.id)
        post_redirect.save!
        url = confirm_url(:email_token => post_redirect.email_token)

        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
                'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
        @recipients = user.name_and_email
        @subject = "Delayed response to your FOI request - " + info_request.title
        @body = { :info_request => info_request, :url => url }
    end

    # Tell the requester that the public body is very late in replying
    def very_overdue_alert(info_request, user)
        respond_url = respond_to_last_url(info_request) + "#followup"

        post_redirect = PostRedirect.new(
            :uri => respond_url,
            :user_id => user.id)
        post_redirect.save!
        url = confirm_url(:email_token => post_redirect.email_token)

        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
                'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
        @recipients = user.name_and_email
        @subject = "You're long overdue a response to your FOI request - " + info_request.title
        @body = { :info_request => info_request, :url => url }
    end

    # Tell the requester that they need to say if the new response
    # contains info or not
    def new_response_reminder_alert(info_request, incoming_message)
        # Make a link going to the form to describe state, and which logs the
        # user in.
        post_redirect = PostRedirect.new(
            :uri => main_url(request_url(info_request)) + "#describe_state_form_1",
            :user_id => info_request.user.id)
        post_redirect.save!
        url = confirm_url(:email_token => post_redirect.email_token)

        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
                'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
        @recipients = info_request.user.name_and_email
        @subject = "Was the response you got to your FOI request any good?"
        @body = { :incoming_message => incoming_message, :info_request => info_request, :url => url }
    end

    # Tell the requester that someone updated their old unclassified request
    def old_unclassified_updated(info_request)
        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
                'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
        @recipients = info_request.user.name_and_email
        @subject = "Someone has updated the status of your request"
        url = main_url(request_url(info_request))
        @body = {:info_request => info_request, :url => url}
    end

    # Tell the requester that they need to clarify their request
    def not_clarified_alert(info_request, incoming_message)
        respond_url = show_response_url(:id => info_request.id, :incoming_message_id => incoming_message.id)
        respond_url = respond_url + "#followup" 

        post_redirect = PostRedirect.new(
            :uri => respond_url,
            :user_id => info_request.user.id)
        post_redirect.save!
        url = confirm_url(:email_token => post_redirect.email_token)

        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
                'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
        @recipients = info_request.user.name_and_email
        @subject = "Clarify your FOI request - " + info_request.title
        @body = { :incoming_message => incoming_message, :info_request => info_request, :url => url }
    end

    # Tell requester that somebody add an annotation to their request
    def comment_on_alert(info_request, comment)
        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
                'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
        @recipients = info_request.user.name_and_email
        @subject = "Somebody added a note to your FOI request - " + info_request.title
        @body = { :comment => comment, :info_request => info_request, :url => main_url(comment_url(comment)) }
    end
    def comment_on_alert_plural(info_request, count, earliest_unalerted_comment)
        @from = contact_from_name_and_email
        headers 'Return-Path' => blackhole_email, 'Reply-To' => @from, # not much we can do if the user's email is broken
                'Auto-Submitted' => 'auto-generated' # http://tools.ietf.org/html/rfc3834
        @recipients = info_request.user.name_and_email
        @subject = "Some notes have been added to your FOI request - " + info_request.title
        @body = { :count => count, :info_request => info_request, :url => main_url(comment_url(earliest_unalerted_comment)) }
    end

    # Class function, called by script/mailin with all incoming responses.
    # [ This is a copy (Monkeypatch!) of function from action_mailer/base.rb,
    # but which additionally passes the raw_email to the member function, as we
    # want to record it. 
    #
    # That is because we want to be sure we properly record the actual message
    # received in its raw form - so any information won't be lost in a round
    # trip via TMail, or by bugs in it, and so we can use something other than
    # TMail at a later date. And so we can offer an option to download the
    # actual original mail sent by the authority in the admin interface (so
    # can check that attachment decoding failures are problems in the message,
    # not in our code). ]
    def self.receive(raw_email)
        logger.info "Received mail:\n #{raw_email}" unless logger.nil?
        mail = TMail::Mail.parse(raw_email)
        mail.base64_decode
        new.receive(mail, raw_email)
    end

    # Find which info requests the email is for
    def requests_matching_email(email)
        # We deliberately don't use Envelope-to here, so ones that are BCC
        # drop into the holding pen for checking.
        reply_info_requests = [] # XXX should be set?
        for address in (email.to || []) + (email.cc || [])
            reply_info_request = InfoRequest.find_by_incoming_email(address)
            reply_info_requests.push(reply_info_request) if reply_info_request
        end
        return reply_info_requests
    end

    # Member function, called on the new class made in self.receive above
    def receive(email, raw_email)
        # Find which info requests the email is for
        reply_info_requests = self.requests_matching_email(email)

        # Nothing found, so save in holding pen
        if reply_info_requests.size == 0 
            InfoRequest.holding_pen_request.receive(email, raw_email)
            return
        end
{'fraction_non_alphanumeric': 0.09103531263016615, 'fraction_numerical': 0.006109131300041653, 'mean_word_length': 2.8129521792835717, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 158, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5367591', 'n_tokens_mistral': 6461, 'n_tokens_neox': 6192, 'n_words': 1810}