Hello Django users,

I want to receive mails from mailgun in a Django web application. I have 
problem with parsing the data to the form. As you can see, in the froms.py 
there is a field_map, to convert the fields Mailgun sends to the model 
fields. This is not working. All fields that are not converted I receive, 
but for example the from field I cannot retrieve. I have installed Django 
1.8 and Python2.7. The code is from
https://github.com/hedberg/django-mailgun-incoming I think this would work 
for Django < 1.8, because in Django 1.8 is introduced the obligation to 
specify the fields. In older versions, omitting both fields and exclude 
resulted in a form with all the model’s fields. Doing this now raises an 
ImproperlyConfigured exception.Hope someone can help me. Thanks in advance

Here is the link to Mailgun for more information 
https://documentation.mailgun.com/user_manual.html#routes
forms.py

from django import forms
from models import EmailBaseModel

class EmailForm(forms.ModelForm):
    field_map = {'from_str':'from',
                 'body_plain':'body-plain',
                 'body_html':'body-html',
                 'stripped_text':'stripped-text',
                 'stripped_html':'stripped-html',
                 'message_headers':'message-headers',
                 'stripped_signature':'stripped-signature',
                 'content_id_map':'content-id-map'}

    class Meta:
    #    model = EmailBaseModel
        fields = '__all__'    

    def __init__(self, *args, **kwargs):
        super(EmailForm, self).__init__(*args, **kwargs)
        for (field_name, form_key) in self.field_map.items():
            self.fields[form_key] = self.fields[field_name]
            del self.fields[field_name]
        self.fields['attachment-count'] = forms.IntegerField(required=False)
        
    def clean(self):
        for (field_name, form_key) in self.field_map.items():
            if form_key in self.cleaned_data:
                self.cleaned_data[field_name] = self.cleaned_data[form_key]
        return self.cleaned_data

views.py

# -*- coding: utf-8 -*-import hashlib, hmacimport logging#import pdb
from django.conf import settings
from django.http import HttpResponse, HttpResponseBadRequest
from django.forms.models import modelform_factory
from django.views.generic.base import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from mailgun_incoming.models import Attachment, IncomingEmail
from mailgun_incoming.signals import email_received
from mailgun_incoming.forms import EmailForm

logger = logging.getLogger(__name__)

API_KEY = getattr(settings, "MAILGUN_ACCESS_KEY", "")
VERIFY_SIGNATURE = getattr(settings, "MAILGUN_VERIFY_INCOMING", API_KEY!="")
class Incoming(View):
    #pdb.set_trace()
    email_model = IncomingEmail
    attachment_model = Attachment
    form = EmailForm
    api_key = API_KEY
    verify = VERIFY_SIGNATURE
    
    def get_form(self):
        return modelform_factory(self.email_model, form=self.form)
    
    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(Incoming, self).dispatch(*args, **kwargs)
    
    def post(self, request, *args, **kwargs):
        if self.verify:
            verified = self.verify_signature(request.POST.get('token',''),
                              request.POST.get('timestamp',''),
                              request.POST.get('signature',''))
            if not verified:
                logger.debug("Signature verification failed. Email posted from 
%s. %s" % (
                              request.META.get('REMOTE_ADDR','<no remote 
addr>'),
                              request.POST.get('subject', '')))
                return HttpResponseBadRequest("Invalid signature")
                
        form = self.get_form()(request.POST)
        
        if form.is_valid():
            #save email
            
            email = form.save()
            #save attachments
            attachments = []
            if form.cleaned_data.get('attachment-count',0):
                attachments = []
                #reverse mapping in content_ids dict
                content_ids = dict((attnr,cid) for cid,attnr in 
(email.content_ids or {}).iteritems())
                i = 1
                for file in request.FILES.values():
                    attachment = self.attachment_model(email=email, file=file, 
content_id=content_ids.get('attachment-{0!s}'.format(i),'')).save()
                    attachments.append(attachment)
                    i += 1
            self.handle_email(email, attachments=attachments)
        else:
            logger.debug("Received email message contained errors. %s" % 
form.errors)
        
        return HttpResponse("OK")
    
    def handle_email(self, email, attachments=None):
        email_received.send(sender=self.email_model, instance=email, 
attachments=attachments or [])
    
    def verify_signature(self, token, timestamp, signature):
        return signature == hmac.new(key=self.api_key,
                                 msg='{0}{1}'.format(timestamp, token),
                                 digestmod=hashlib.sha256).hexdigest()

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/13e083da-7998-425d-839d-82d8fbfe0b4d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to