Exemplo n.º 1
0
    def get(self, request):
        # Get the state param from the request.
        state = str(request.GET.get('state'))
        # Replace %xx characters with single quotes and UTF8 decode the string.
        state = urllib.unquote(state).decode('utf8')
        # Deserialize the JSON string.
        state = anyjson.deserialize(b64decode(state))

        if not validate_token(settings.SECRET_KEY, state.get('token'),
                              request.user.pk):
            return HttpResponseBadRequest()

        error = request.GET.get('error')
        if error:
            messages.error(
                self.request,
                _('Sorry, Lily needs authorization from Google to synchronize your email account.'
                  ))
            return HttpResponseRedirect('/#/preferences/emailaccounts')

        credentials = FLOW.step2_exchange(code=request.GET.get('code'))

        # Setup service to retrieve email address.
        service = build_gmail_service(credentials)
        profile = service.users().getProfile(userId='me').execute()

        # Create account based on email address.
        account, created = EmailAccount.objects.get_or_create(
            owner=request.user, email_address=profile.get('emailAddress'))

        # Store credentials based on new email account.
        storage = Storage(GmailCredentialsModel, 'id', account, 'credentials')
        storage.put(credentials)

        # Set account as authorized.
        account.is_authorized = True
        account.is_deleted = False

        account.label = account.label or account.email_address
        account.from_name = account.from_name or ' '.join(
            account.email_address.split('@')[0].split('.')).title()

        set_to_public = bool(int(state.get('public')))
        if account.public is not set_to_public:
            account.public = set_to_public

        only_sync_new_mails = bool(int(state.get('only_new')))
        if only_sync_new_mails and created:
            # Setting it before the first sync means it will only fetch changes starting now.
            account.history_id = profile.get('historyId')
            account.full_sync_finished = True

        account.save()

        post_intercom_event(event_name='email-account-added',
                            user_id=request.user.id)

        return HttpResponseRedirect('/#/preferences/emailaccounts/edit/%s' %
                                    account.pk)
Exemplo n.º 2
0
    def formset_valid(self, formset):
        """
        This function is called when the formset is deemed valid.
        An email is sent to all email fields which are filled in.
        If the request is done via ajax give json back with a success message, otherwise
        redirect to the success url.
        """
        protocol = self.request.is_secure() and 'https' or 'http'
        date_string = date.today().strftime('%d%m%Y')

        # Get the current site or empty string
        try:
            current_site = Site.objects.get_current()
        except Site.DoesNotExist:
            current_site = ''

        for form in formset:
            if form in formset.deleted_forms:
                continue

            first_name = form.cleaned_data.get('first_name')

            email = form.cleaned_data.get('email')
            tenant_id = self.request.user.tenant_id
            hash = sha256('%s-%s-%s-%s' % (
                tenant_id,
                email,
                date_string,
                settings.SECRET_KEY
            )).hexdigest()
            invite_link = '%s://%s%s' % (protocol, current_site, reverse_lazy('invitation_accept', kwargs={
                'tenant_id': tenant_id,
                'first_name': first_name,
                'email': email,
                'date': date_string,
                'hash': hash,
            }))

            # Email to the user
            send_templated_mail(
                template_name='invitation',
                from_email=settings.DEFAULT_FROM_EMAIL,
                recipient_list=[form.cleaned_data['email']],
                context={
                    'current_site': current_site,
                    'full_name': self.request.user.full_name,
                    'name': first_name,
                    'invite_link': invite_link,
                }
            )

            post_intercom_event(event_name='invite-sent', user_id=self.request.user.id)

        if is_ajax(self.request):
            return HttpResponse(anyjson.serialize({
                'error': False,
                'html': _('The invitations were sent successfully'),
            }), content_type='application/json')
        return HttpResponseRedirect(self.get_success_url())
Exemplo n.º 3
0
    def get(self, request):
        # Get the state param from the request.
        state = str(request.GET.get('state'))
        # Replace %xx characters with single quotes and UTF8 decode the string.
        state = urllib.unquote(state).decode('utf8')
        # Deserialize the JSON string.
        state = anyjson.deserialize(b64decode(state))

        if not validate_token(settings.SECRET_KEY, state.get('token'), request.user.pk):
            return HttpResponseBadRequest()

        error = request.GET.get('error')
        if error:
            messages.error(
                self.request,
                _('Sorry, Lily needs authorization from Google to synchronize your email account.')
            )
            return HttpResponseRedirect('/#/preferences/emailaccounts')

        credentials = FLOW.step2_exchange(code=request.GET.get('code'))

        # Setup service to retrieve email address.
        service = build_gmail_service(credentials)
        profile = service.users().getProfile(userId='me').execute()

        # Create account based on email address.
        account, created = EmailAccount.objects.get_or_create(
            owner=request.user,
            email_address=profile.get('emailAddress')
        )

        # Store credentials based on new email account.
        storage = Storage(GmailCredentialsModel, 'id', account, 'credentials')
        storage.put(credentials)

        # Set account as authorized.
        account.is_authorized = True
        account.is_deleted = False

        account.label = account.label or account.email_address
        account.from_name = account.from_name or ' '.join(account.email_address.split('@')[0].split('.')).title()

        set_to_public = bool(int(state.get('public')))
        if account.public is not set_to_public:
            account.public = set_to_public

        only_sync_new_mails = bool(int(state.get('only_new')))
        if only_sync_new_mails and created:
            # Setting it before the first sync means it will only fetch changes starting now.
            account.history_id = profile.get('historyId')
            account.first_sync_finished = True

        account.save()

        post_intercom_event(event_name='email-account-added', user_id=request.user.id)

        return HttpResponseRedirect('/#/preferences/emailaccounts/edit/%s' % account.pk)
Exemplo n.º 4
0
    def form_valid(self, form):
        # Saves instance
        response = super(CreateEmailTemplateView, self).form_valid(form)

        # Show save messages
        message = _('%s has been created.') % self.object.name
        messages.success(self.request, message)

        post_intercom_event(event_name='email-template-created', user_id=self.request.user.id)

        return response
Exemplo n.º 5
0
    def form_valid(self, form):
        # Saves instance
        response = super(CreateEmailTemplateView, self).form_valid(form)

        # Show save messages
        message = _('%s has been created.') % self.object.name
        messages.success(self.request, message)

        post_intercom_event(event_name='email-template-created',
                            user_id=self.request.user.id)

        return response
Exemplo n.º 6
0
def send_message(email_outbox_message_id, original_message_id=None):
    """
    Send EmailOutboxMessage.

    Args:
        email_outbox_message_id (int): id of the EmailOutboxMessage
        original_message_id (int, optional): ID of the original EmailMessage
    """
    send_logger = logging.getLogger('email_errors_temp_logger')
    send_logger.info('Start sending email_outbox_message: %d' %
                     (email_outbox_message_id, ))

    sent_success = False
    try:
        email_outbox_message = EmailOutboxMessage.objects.get(
            pk=email_outbox_message_id)
    except EmailOutboxMessage.DoesNotExist:
        raise

    email_account = email_outbox_message.send_from
    if not email_account.is_authorized:
        logger.error('EmailAccount not authorized: %s', email_account)
        return sent_success

    # If we reply or forward, we want to add the thread_id.
    original_message_thread_id = None
    if original_message_id:
        try:
            original_message = EmailMessage.objects.get(pk=original_message_id)
            if original_message.account.id is email_account.id:
                original_message_thread_id = original_message.thread_id
        except EmailMessage.DoesNotExist:
            raise

    # Add template attachments.
    if email_outbox_message.template_attachment_ids:
        template_attachment_id_list = email_outbox_message.template_attachment_ids.split(
            ',')
        for template_attachment_id in template_attachment_id_list:
            try:
                template_attachment = EmailTemplateAttachment.objects.get(
                    pk=template_attachment_id)
            except EmailTemplateAttachment.DoesNotExist:
                pass
            else:
                attachment = EmailOutboxAttachment()
                attachment.content_type = template_attachment.content_type
                attachment.size = template_attachment.size
                attachment.email_outbox_message = email_outbox_message
                attachment.attachment = template_attachment.attachment
                attachment.tenant_id = template_attachment.tenant_id
                attachment.save()

    # Add attachment from original message (if mail is being forwarded).
    if email_outbox_message.original_attachment_ids:
        original_attachment_id_list = email_outbox_message.original_attachment_ids.split(
            ',')
        for attachment_id in original_attachment_id_list:
            try:
                original_attachment = EmailAttachment.objects.get(
                    pk=attachment_id)
            except EmailAttachment.DoesNotExist:
                pass
            else:
                outbox_attachment = EmailOutboxAttachment()
                outbox_attachment.email_outbox_message = email_outbox_message
                outbox_attachment.tenant_id = original_attachment.message.tenant_id

                file = default_storage._open(
                    original_attachment.attachment.name)
                file.open()
                content = file.read()
                file.close()

                file = ContentFile(content)
                file.name = original_attachment.attachment.name

                outbox_attachment.attachment = file
                outbox_attachment.inline = original_attachment.inline
                outbox_attachment.size = file.size
                outbox_attachment.save()

    manager = None
    try:
        manager = GmailManager(email_account)
        manager.send_email_message(email_outbox_message.message(),
                                   original_message_thread_id)
        logger.debug('Message sent from: %s', email_account)
        # Seems like everything went right, so the EmailOutboxMessage object isn't needed any more.
        email_outbox_message.delete()
        sent_success = True
        # TODO: This should probably be moved to the front end once
        # we can notify users about sent mails.
        post_intercom_event(event_name='email-sent',
                            user_id=email_account.owner.id)
    except HttpAccessTokenRefreshError:
        logger.warning('EmailAccount not authorized: %s', email_account)
        pass
    except Exception as e:
        logger.error(traceback.format_exc(e))
        raise
    finally:
        if manager:
            manager.cleanup()

    send_logger.info(
        'Done sending email_outbox_message: %d And sent_succes value: %s' %
        (email_outbox_message_id, sent_success))
    return sent_success
Exemplo n.º 7
0
    def get(self, request):
        error = request.GET.get('error')
        if error:
            messages.error(
                self.request,
                _('Sorry, Lily needs authorization from Google to synchronize your email account.')
            )
            return HttpResponseRedirect('/#/preferences/emailaccounts')

        # Get the state param from the request.
        state = str(request.GET.get('state'))
        # Replace %xx characters with single quotes and UTF8 decode the string.
        state = urllib.unquote(state).decode('utf8')
        # Deserialize the JSON string.
        state = anyjson.deserialize(b64decode(state))

        if not validate_token(settings.SECRET_KEY, state.get('token'), request.user.pk):
            return HttpResponseBadRequest()

        credentials = FLOW.step2_exchange(code=request.GET.get('code'))

        # Setup service to retrieve email address from Google.
        gmail_service = GmailService(credentials)
        try:
            profile = gmail_service.execute_service(gmail_service.service.users().getProfile(userId='me'))
        except HttpError as error:
            error = anyjson.loads(error.content)
            error = error.get('error', error)
            if error.get('code') == 400 and error.get('message') == 'Mail service not enabled':
                messages.error(self.request, _('Mail is not enabled for this email account.'))
            else:
                messages.error(self.request, error.get('message'))

            if not request.user.info.registration_finished:
                # User is still busy with registration, so redirect to email account setup step again.
                return HttpResponseRedirect(reverse('register_email_account_setup'))
            else:
                return HttpResponseRedirect('/#/preferences/emailaccounts')

        # Create account based on email address.
        try:
            account, created = EmailAccount.objects.get_or_create(
                owner=request.user,
                tenant_id=request.user.tenant_id,
                email_address=profile.get('emailAddress')
            )
        except EmailAccount.MultipleObjectsReturned:
            account, created = EmailAccount.objects.get_or_create(
                owner=request.user,
                tenant_id=request.user.tenant_id,
                email_address=profile.get('emailAddress'),
                is_deleted=False
            )

        # Store credentials based on new email account.
        storage = Storage(GmailCredentialsModel, 'id', account, 'credentials')
        storage.put(credentials)

        account.is_deleted = False

        if request.user.tenant.billing.is_free_plan:
            account.privacy = EmailAccount.PRIVATE

        if created:
            account.only_new = None

        account.save()

        post_intercom_event(event_name='email-account-added', user_id=request.user.id)

        if not request.user.info.registration_finished:
            # User is still busy with registration, so redirect to the next step in the flow.
            return HttpResponseRedirect(reverse('register_email_account_details'))
        else:
            return HttpResponseRedirect('/#/preferences/emailaccounts/edit/%s' % account.pk)
Exemplo n.º 8
0
    def create(self, request):
        protocol = self.request.is_secure() and 'https' or 'http'
        date_string = date.today().strftime('%d%m%Y')
        tenant_id = self.request.user.tenant_id

        # Get the current site or empty string.
        try:
            current_site = Site.objects.get_current()
        except Site.DoesNotExist:
            current_site = ''

        invites = request.data.get('invites')
        errors = []
        has_errors = False

        for invite in invites:
            first_name = invite.get('first_name')
            email = invite.get('email')
            valid_email = True
            error = {}

            try:
                validate_email(email)
            except:
                valid_email = False

            if not first_name or not email or not valid_email:
                error = {
                    'name':
                    [_('Please enter a first name and valid email address')],
                }
                has_errors = True

            if LilyUser.objects.filter(email=email, is_active=True).exists():
                error = {
                    'name':
                    [_('A user with this email address already exists')],
                }
                has_errors = True

            errors.append(error)

            if UserInvite.objects.filter(email=email).exists():
                # Send a new invite if one was already sent.
                UserInvite.objects.filter(email=email).delete()

        if has_errors:
            return Response({'invites': errors},
                            status=status.HTTP_400_BAD_REQUEST)

        for invite in invites:
            first_name = invite.get('first_name')
            email = invite.get('email')

            params = {
                'first_name': first_name,
                'email': email,
            }

            invite = UserInvite.objects.filter(**params).first()
            # An invite was already sent, so delete the old one.
            if invite:
                invite.delete()

            # We always want to create a new invite.
            invite = UserInvite.objects.create(**params)

            hash = sha256('%s-%s-%s-%s-%s' %
                          (tenant_id, invite.id, email, date_string,
                           settings.SECRET_KEY)).hexdigest()
            invite_link = '%s://%s%s' % (protocol, current_site,
                                         reverse_lazy(
                                             'invitation_accept',
                                             kwargs={
                                                 'tenant_id': tenant_id,
                                                 'first_name': first_name,
                                                 'email': email,
                                                 'date': date_string,
                                                 'hash': hash,
                                             }))

            # Email to the user.
            send_templated_mail(
                template_name='users/email/invitation.email',
                recipient_list=[email],
                context={
                    'current_site': current_site,
                    'inviter_full_name': self.request.user.full_name,
                    'inviter_first_name': self.request.user.first_name,
                    'recipient_first_name': first_name,
                    'invite_link': invite_link,
                },
                from_email=settings.EMAIL_PERSONAL_HOST_USER,
                auth_user=settings.EMAIL_PERSONAL_HOST_USER,
                auth_password=settings.EMAIL_PERSONAL_HOST_PASSWORD)

        if len(invites):
            post_intercom_event(event_name='invite-sent',
                                user_id=self.request.user.id)

            return Response(status=status.HTTP_200_OK)
Exemplo n.º 9
0
    def create(self, request):
        protocol = self.request.is_secure() and 'https' or 'http'
        date_string = date.today().strftime('%d%m%Y')
        tenant_id = self.request.user.tenant_id

        # Get the current site or empty string.
        try:
            current_site = Site.objects.get_current()
        except Site.DoesNotExist:
            current_site = ''

        invites = request.data.get('invites')
        errors = []
        has_errors = False

        for invite in invites:
            first_name = invite.get('first_name')
            email = invite.get('email')
            valid_email = True
            error = {}

            try:
                validate_email(email)
            except:
                valid_email = False

            if not first_name or not email or not valid_email:
                error = {
                    'name': [_('Please enter a first name and valid email address')],
                }
                has_errors = True

            if LilyUser.objects.filter(email=email, is_active=True).exists():
                error = {
                    'name': [_('A user with this email address already exists')],
                }
                has_errors = True

            errors.append(error)

            if UserInvite.objects.filter(email=email).exists():
                # Send a new invite if one was already sent.
                UserInvite.objects.filter(email=email).delete()

        if has_errors:
            return Response({'invites': errors}, status=status.HTTP_400_BAD_REQUEST)

        for invite in invites:
            first_name = invite.get('first_name')
            email = invite.get('email')

            params = {
                'first_name': first_name,
                'email': email,
            }

            invite = UserInvite.objects.filter(**params).first()
            # An invite was already sent, so delete the old one.
            if invite:
                invite.delete()

            # We always want to create a new invite.
            invite = UserInvite.objects.create(**params)

            hash = sha256('%s-%s-%s-%s-%s' % (
                tenant_id,
                invite.id,
                email,
                date_string,
                settings.SECRET_KEY
            )).hexdigest()
            invite_link = '%s://%s%s' % (protocol, current_site, reverse_lazy('invitation_accept', kwargs={
                'tenant_id': tenant_id,
                'first_name': first_name,
                'email': email,
                'date': date_string,
                'hash': hash,
            }))

            # Email to the user.
            send_templated_mail(
                template_name='users/email/invitation.email',
                recipient_list=[email],
                context={
                    'current_site': current_site,
                    'inviter_full_name': self.request.user.full_name,
                    'inviter_first_name': self.request.user.first_name,
                    'recipient_first_name': first_name,
                    'invite_link': invite_link,
                },
                from_email=settings.EMAIL_PERSONAL_HOST_USER,
                auth_user=settings.EMAIL_PERSONAL_HOST_USER,
                auth_password=settings.EMAIL_PERSONAL_HOST_PASSWORD
            )

        if len(invites):
            post_intercom_event(event_name='invite-sent', user_id=self.request.user.id)

            return Response(status=status.HTTP_200_OK)
Exemplo n.º 10
0
    def get(self, request):
        error = request.GET.get('error')
        if error:
            messages.error(
                self.request,
                _('Sorry, Lily needs authorization from Google to synchronize your email account.'
                  ))
            return HttpResponseRedirect('/#/preferences/emailaccounts')

        # Get the state param from the request.
        state = str(request.GET.get('state'))
        # Replace %xx characters with single quotes and UTF8 decode the string.
        state = urllib.unquote(state).decode('utf8')
        # Deserialize the JSON string.
        state = anyjson.deserialize(b64decode(state))

        if not validate_token(settings.SECRET_KEY, state.get('token'),
                              request.user.pk):
            return HttpResponseBadRequest()

        credentials = FLOW.step2_exchange(code=request.GET.get('code'))

        # Setup service to retrieve email address from Google.
        gmail_service = GmailService(credentials)
        try:
            profile = gmail_service.execute_service(
                gmail_service.service.users().getProfile(userId='me'))
        except HttpError as error:
            error = anyjson.loads(error.content)
            error = error.get('error', error)
            if error.get('code') == 400 and error.get(
                    'message') == 'Mail service not enabled':
                messages.error(
                    self.request,
                    _('Mail is not enabled for this email account.'))
            else:
                messages.error(self.request, error.get('message'))

            # Adding email account failed, administer it as skipping the email setup or otherwise the user will be
            # stuck in redirect loop.
            user = self.request.user
            user.info.email_account_status = UserInfo.SKIPPED
            user.info.save()

            return HttpResponseRedirect('/#/preferences/emailaccounts')

        # Create account based on email address.
        try:
            account, created = EmailAccount.objects.get_or_create(
                owner=request.user,
                tenant_id=request.user.tenant_id,
                email_address=profile.get('emailAddress'))
        except EmailAccount.MultipleObjectsReturned:
            account, created = EmailAccount.objects.get_or_create(
                owner=request.user,
                tenant_id=request.user.tenant_id,
                email_address=profile.get('emailAddress'),
                is_deleted=False)

        # Store credentials based on new email account.
        storage = Storage(GmailCredentialsModel, 'id', account, 'credentials')
        storage.put(credentials)

        account.is_deleted = False

        if request.user.tenant.billing.is_free_plan:
            account.privacy = EmailAccount.PRIVATE

        if created:
            account.only_new = None

        account.save()

        post_intercom_event(event_name='email-account-added',
                            user_id=request.user.id)

        if request.user.info and not request.user.info.email_account_status:
            # First time setup, so we want a different view.
            return HttpResponseRedirect(
                '/#/preferences/emailaccounts/setup/%s' % account.pk)
        else:
            return HttpResponseRedirect(
                '/#/preferences/emailaccounts/edit/%s' % account.pk)
Exemplo n.º 11
0
    def formset_valid(self, formset):
        """
        This function is called when the formset is deemed valid.
        An email is sent to all email fields which are filled in.
        If the request is done via ajax give json back with a success message, otherwise
        redirect to the success url.
        """
        protocol = self.request.is_secure() and 'https' or 'http'
        date_string = date.today().strftime('%d%m%Y')

        # Get the current site or empty string
        try:
            current_site = Site.objects.get_current()
        except Site.DoesNotExist:
            current_site = ''

        for form in formset:
            if form in formset.deleted_forms:
                continue

            first_name = form.cleaned_data.get('first_name')

            email = form.cleaned_data.get('email')
            tenant_id = self.request.user.tenant_id
            hash = sha256('%s-%s-%s-%s' % (tenant_id, email, date_string,
                                           settings.SECRET_KEY)).hexdigest()
            invite_link = '%s://%s%s' % (protocol, current_site,
                                         reverse_lazy(
                                             'invitation_accept',
                                             kwargs={
                                                 'tenant_id': tenant_id,
                                                 'first_name': first_name,
                                                 'email': email,
                                                 'date': date_string,
                                                 'hash': hash,
                                             }))

            # Email to the user
            send_templated_mail(
                template_name='invitation',
                recipient_list=[form.cleaned_data['email']],
                context={
                    'current_site': current_site,
                    'inviter_full_name': self.request.user.full_name,
                    'inviter_first_name': self.request.user.first_name,
                    'recipient_first_name': first_name,
                    'invite_link': invite_link,
                },
                from_email=settings.EMAIL_PERSONAL_HOST_USER,
                auth_user=settings.EMAIL_PERSONAL_HOST_USER,
                auth_password=settings.EMAIL_PERSONAL_HOST_PASSWORD)

            post_intercom_event(event_name='invite-sent',
                                user_id=self.request.user.id)

        if is_ajax(self.request):
            return HttpResponse(anyjson.serialize({
                'error':
                False,
                'html':
                _('The invitations were sent successfully'),
            }),
                                content_type='application/json')
        return HttpResponseRedirect(self.get_success_url())
Exemplo n.º 12
0
def send_message(email_id, original_message_id=None, draft=False):
    """
    Send EmailOutboxMessage or EmailDraft.

    Args:
        email_outbox_message_id (int): id of the EmailOutboxMessage
        original_message_id (int, optional): ID of the original EmailMessage
        draft (bool, optional): whether the newer EmailDraft should be queried
    """
    send_logger = logging.getLogger('email_errors_temp_logger')
    send_logger.info('Start sending email_outbox_message: %d' % (email_id,))

    # Below describes the differences between EmailOutboxMessage and EmailDraft.
    # As soon as EmailDraft is proven to work, this class can be refactored to only work for EmailDraft.
    email_class = EmailOutboxMessage
    email_attachment_class = EmailOutboxAttachment
    email_attachment_to_email_class_field_name = 'email_outbox_message'
    email_message_function_name = 'message'
    if draft:
        email_class = EmailDraft
        email_attachment_class = EmailDraftAttachment
        email_attachment_to_email_class_field_name = 'email_draft'
        email_message_function_name = 'mime_message'

    sent_success = False
    try:
        email = email_class.objects.get(pk=email_id)
    except email_class.DoesNotExist:
        raise

    email_account = email.send_from
    if not email_account.is_authorized:
        logger.error('EmailAccount not authorized: %s', email_account)
        return sent_success

    # If we reply or forward, we want to add the thread_id.
    original_message_thread_id = None
    if original_message_id:
        try:
            original_message = EmailMessage.objects.get(pk=original_message_id)
            if original_message.account.id is email_account.id:
                original_message_thread_id = original_message.thread_id
        except EmailMessage.DoesNotExist:
            raise

    # Add template attachments.
    if email.template_attachment_ids:
        template_attachment_id_list = email.template_attachment_ids.split(',')
        for template_attachment_id in template_attachment_id_list:
            try:
                template_attachment = EmailTemplateAttachment.objects.get(pk=template_attachment_id)
            except EmailTemplateAttachment.DoesNotExist:
                pass
            else:
                attachment = email_attachment_class()
                attachment.content_type = template_attachment.content_type
                attachment.size = template_attachment.size
                setattr(attachment, email_attachment_to_email_class_field_name, email)
                attachment.attachment = template_attachment.attachment
                attachment.tenant_id = template_attachment.tenant_id
                attachment.save()

    # Add attachment from original message (if mail is being forwarded).
    if email.original_attachment_ids:
        original_attachment_id_list = email.original_attachment_ids.split(',')
        for attachment_id in original_attachment_id_list:
            try:
                original_attachment = EmailAttachment.objects.get(pk=attachment_id)
            except EmailAttachment.DoesNotExist:
                pass
            else:
                outbox_attachment = email_attachment_class()
                setattr(outbox_attachment, email_attachment_to_email_class_field_name, email)
                outbox_attachment.tenant_id = original_attachment.message.tenant_id

                file = default_storage._open(original_attachment.attachment.name)
                file.open()
                content = file.read()
                file.close()

                file = ContentFile(content)
                file.name = original_attachment.attachment.name

                outbox_attachment.attachment = file
                outbox_attachment.inline = original_attachment.inline
                outbox_attachment.size = file.size
                outbox_attachment.save()

    manager = None
    try:
        manager = GmailManager(email_account)
        manager.send_email_message(getattr(email, email_message_function_name)(), original_message_thread_id)
        logger.debug('Message sent from: %s', email_account)
        # Seems like everything went right, so the EmailOutboxMessage object isn't needed any more.
        email.delete()
        sent_success = True
        # TODO: This should probably be moved to the front end once
        # we can notify users about sent mails.
        post_intercom_event(event_name='email-sent', user_id=email_account.owner.id)
    except HttpAccessTokenRefreshError:
        logger.warning('EmailAccount not authorized: %s', email_account)
        pass
    except Exception as e:
        logger.error(traceback.format_exc(e))
        raise
    finally:
        if manager:
            manager.cleanup()

    send_logger.info('Done sending {}: {} And sent_succes value: {}'.format(
        email_attachment_to_email_class_field_name,
        email_id,
        sent_success
    ))

    return sent_success
Exemplo n.º 13
0
def send_message(email_outbox_message_id, original_message_id=None):
    """
    Send EmailOutboxMessage.

    Args:
        email_outbox_message_id (int): id of the EmailOutboxMessage
        original_message_id (int, optional): ID of the original EmailMessage
    """
    send_logger = logging.getLogger('email_errors_temp_logger')
    send_logger.info('Start sending email_outbox_message: %d' % (email_outbox_message_id,))

    sent_success = False
    try:
        email_outbox_message = EmailOutboxMessage.objects.get(pk=email_outbox_message_id)
    except EmailOutboxMessage.DoesNotExist:
        raise

    email_account = email_outbox_message.send_from
    if not email_account.is_authorized:
        logger.error('EmailAccount not authorized: %s', email_account)
        return sent_success

    # If we reply or forward, we want to add the thread_id.
    original_message_thread_id = None
    if original_message_id:
        try:
            original_message = EmailMessage.objects.get(pk=original_message_id)
            if original_message.account.id is email_account.id:
                original_message_thread_id = original_message.thread_id
        except EmailMessage.DoesNotExist:
            raise

    # Add template attachments.
    if email_outbox_message.template_attachment_ids:
        template_attachment_id_list = email_outbox_message.template_attachment_ids.split(',')
        for template_attachment_id in template_attachment_id_list:
            try:
                template_attachment = EmailTemplateAttachment.objects.get(pk=template_attachment_id)
            except EmailTemplateAttachment.DoesNotExist:
                pass
            else:
                attachment = EmailOutboxAttachment()
                attachment.content_type = template_attachment.content_type
                attachment.size = template_attachment.size
                attachment.email_outbox_message = email_outbox_message
                attachment.attachment = template_attachment.attachment
                attachment.tenant_id = template_attachment.tenant_id
                attachment.save()

    # Add attachment from original message (if mail is being forwarded).
    if email_outbox_message.original_attachment_ids:
        original_attachment_id_list = email_outbox_message.original_attachment_ids.split(',')
        for attachment_id in original_attachment_id_list:
            try:
                original_attachment = EmailAttachment.objects.get(pk=attachment_id)
            except EmailAttachment.DoesNotExist:
                pass
            else:
                outbox_attachment = EmailOutboxAttachment()
                outbox_attachment.email_outbox_message = email_outbox_message
                outbox_attachment.tenant_id = original_attachment.message.tenant_id

                file = default_storage._open(original_attachment.attachment.name)
                file.open()
                content = file.read()
                file.close()

                file = ContentFile(content)
                file.name = original_attachment.attachment.name

                outbox_attachment.attachment = file
                outbox_attachment.inline = original_attachment.inline
                outbox_attachment.size = file.size
                outbox_attachment.save()

    manager = None
    try:
        manager = GmailManager(email_account)
        manager.send_email_message(email_outbox_message.message(), original_message_thread_id)
        logger.debug('Message sent from: %s', email_account)
        # Seems like everything went right, so the EmailOutboxMessage object isn't needed any more.
        email_outbox_message.delete()
        sent_success = True
        # TODO: This should probably be moved to the front end once
        # we can notify users about sent mails.
        post_intercom_event(event_name='email-sent', user_id=email_account.owner.id)
    except HttpAccessTokenRefreshError:
        logger.warning('EmailAccount not authorized: %s', email_account.email_address)
        pass
    except Exception as e:
        logger.error(traceback.format_exc(e))
        raise
    finally:
        if manager:
            manager.cleanup()

    send_logger.info(
        'Done sending email_outbox_message: %d And sent_succes value: %s' % (email_outbox_message_id, sent_success)
    )
    return sent_success