Esempio n. 1
0
 def save(self, domain_override=None,
          subject_template_name='registration/password_reset_subject.txt',
          email_template_name='registration/password_reset_email.html',
          use_https=False, token_generator=default_token_generator,
          from_email=None, request=None):
     """
     Cleaned save that doesn't do lots of stuff we don't need. Adds
     categories to emails and allows them to be html.
     """
     email = self.cleaned_data['email']
     user = User.objects.get_email_owner(email)
     if user is None:
         return
     c = {
         'user': user,
         'uid': urlsafe_base64_encode(force_bytes(user.pk)),
         'token': token_generator.make_token(user)
     }
     headers = {
         'X-SMTPAPI': '{"category": "Forgotten Password for User %s"}' % (
             user.pk)
     }
     body = loader.render_to_string(email_template_name, c)
     send_email(body, email_type=settings.FORGOTTEN_PASSWORD,
                recipients=[email], headers=headers,
                domain=get_current_seosite('domain', 'lower'))
Esempio n. 2
0
    def send_activation_email(self,
                              primary=True,
                              password=None,
                              custom_msg=None):
        if self.activation_key_expired():
            self.reset_activation()
        if custom_msg:
            custom_msg = custom_msg.replace('\n', '<br>')
            custom_msg = mark_safe(custom_msg)

        ctx_dict = {
            'activation_key': self.activation_key,
            'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS,
            'password': password,
            'primary': primary,
            'user': self.user,
            'custom_msg': custom_msg
        }
        message = render_to_string('registration/activation_email.html',
                                   ctx_dict)
        message = Pynliner().from_string(message).run()

        site = getattr(settings, 'SITE', None)

        headers = {
            'X-SMTPAPI': '{"category": "Activation sent (%s)"}' % self.pk
        }

        send_email(message,
                   email_type=settings.ACTIVATION,
                   recipients=[self.email],
                   site=site,
                   headers=headers)
Esempio n. 3
0
    def send_update_email(self, msg, custom_msg=None):
        """
        This function is meant to be called from the shell. It sends a notice to
        the user that their saved search has been updated by the system or an
        admin.

        Inputs:
        :msg:   The description of the update. Passed through verbatim to the
                template.

        Returns:
        nothing

        """
        context_dict = {
            'saved_searches': [(self,)],
            'message': msg,
            'custom_msg': custom_msg,
            'contains_pss': hasattr(self, 'partnersavedsearch')
        }
        message = render_to_string("mysearches/email_update.html",
                                   context_dict)

        category = '{"category": "My.jobs Saved Search Updated (%s:%s)"}' % (
            self.content_type,
            self.pk)
        headers = {'X-SMTPAPI': category}
        send_email(message, email_type=settings.SAVED_SEARCH_UPDATED,
                   recipients=[self.email], label=self.label.strip(),
                   headers=headers)
        SavedSearchLog.objects.create(
            reason='Jobs are not sent in saved search update emails',
            was_sent=True, was_received=False, recipient=self.user,
            recipient_email=self.email, new_jobs=0, backfill_jobs=0)
Esempio n. 4
0
    def send_activation_email(self, primary=True, password=None,
                              custom_msg=None):
        if self.activation_key_expired():
            self.reset_activation()
        if custom_msg:
            custom_msg = custom_msg.replace('\n', '<br>')
            custom_msg = mark_safe(custom_msg)

        ctx_dict = {'activation_key': self.activation_key,
                    'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS,
                    'password': password,
                    'primary': primary,
                    'user': self.user,
                    'custom_msg': custom_msg}
        message = render_to_string('registration/activation_email.html',
                                   ctx_dict)
        message = Pynliner().from_string(message).run()

        site = getattr(settings, 'SITE', None)

        headers = {
            'X-SMTPAPI': '{"category": "Activation sent (%s)"}' % self.pk
        }

        send_email(message, email_type=settings.ACTIVATION,
                   recipients=[self.email], site=site, headers=headers)
Esempio n. 5
0
 def save(self, domain_override=None,
          subject_template_name='registration/password_reset_subject.txt',
          email_template_name='registration/password_reset_email.html',
          use_https=False, token_generator=default_token_generator,
          from_email=None, request=None):
     """
     Cleaned save that doesn't do lots of stuff we don't need. Adds
     categories to emails and allows them to be html.
     """
     email = self.cleaned_data['email']
     user = User.objects.get_email_owner(email)
     if user is None:
         return
     c = {
         'user': user,
         'uid': urlsafe_base64_encode(force_bytes(user.pk)),
         'token': token_generator.make_token(user)
     }
     headers = {
         'X-SMTPAPI': '{"category": "Forgotten Password for User %s"}' % (
             user.pk)
     }
     body = loader.render_to_string(email_template_name, c)
     send_email(body, email_type=settings.FORGOTTEN_PASSWORD,
                recipients=[email], headers=headers,
                domain=get_current_seosite('domain', 'lower'))
Esempio n. 6
0
def send_contact_record_email_response(created_records, created_contacts,
                                       attachment_failures, unmatched_contacts,
                                       error, to_email, is_nuo=False,
                                       company=None, buckets=None):

    # Multiple outreach email addresses may have been provided. We should have
    # already ensured that they all belong to one company. Pick one to use in
    # our return email.
    bucket = ''
    if buckets:
        bucket = buckets[0]
    ctx = {
        'created_records': created_records,
        'created_contacts': created_contacts,
        'error': error,
        'unmatched_contacts': unmatched_contacts,
        'attachment_failures': attachment_failures,
        'company': company,
        'to_email': to_email,
        'bucket': bucket,
    }

    template = 'mypartners/email/email_response.html'
    if is_nuo:
        template = 'mypartners/email/nuo_email_response.html'
    message = render_to_string(template,
                               ctx)
    headers = {
        'X-SMTPAPI': '{"category": "Communication Record %s"}' % (
            'Failure' if error is not None else 'Success')
    }

    send_email(message, email_type=settings.CREATE_CONTACT_RECORD,
               recipients=[to_email], headers=headers)
Esempio n. 7
0
    def send_update_email(self, msg, custom_msg=None):
        """
        This function is meant to be called from the shell. It sends a notice to
        the user that their saved search has been updated by the system or an
        admin.

        Inputs:
        :msg:   The description of the update. Passed through verbatim to the
                template.

        Returns:
        nothing

        """
        context_dict = {
            'saved_searches': [(self, )],
            'message': msg,
            'custom_msg': custom_msg,
            'contains_pss': hasattr(self, 'partnersavedsearch')
        }
        message = render_to_string("mysearches/email_update.html",
                                   context_dict)

        category = '{"category": "My.jobs Saved Search Updated (%s:%s)"}' % (
            self.content_type, self.pk)
        headers = {'X-SMTPAPI': category}

        default_reason = 'Jobs are not sent in saved search update emails',
        log_kwargs = {
            'reason': default_reason,
            'was_sent': True,
            'was_received': False,
            'recipient': self.user,
            'recipient_email': self.email,
            'new_jobs': 0,
            'backfill_jobs': 0
        }
        try:
            send_email(message,
                       email_type=settings.SAVED_SEARCH_UPDATED,
                       recipients=[self.email],
                       label=self.label.strip(),
                       headers=headers)
        except Exception as e:
            log_kwargs['was_sent'] = False
            log_kwargs['reason'] = getattr(e, 'smtp_error', e.message)

        if context_dict['contains_pss']:
            reason = log_kwargs['reason']
            if reason == default_reason:
                # Similar to the logic in initial_email, this default reason
                # serves as a reminder that having zero jobs in this email
                # is intentional and expected.
                reason = None
            self.partnersavedsearch.create_record(
                "Automatic sending of updated partner saved search.",
                failure_message=reason)

        SavedSearchLog.objects.create(**log_kwargs)
Esempio n. 8
0
    def send_disable_email(self):
        message = render_to_string('mysearches/email_disable.html',
                                   {'saved_search': self})

        category = '{"category": "My.jobs Saved Search Disabled (%s:%s)"}' % (
            self.content_type,
            self.pk)
        headers = {'X-SMTPAPI': category}
        send_email(message, email_type=settings.SAVED_SEARCH_DISABLED,
                   recipients=[self.email], headers=headers)
Esempio n. 9
0
    def send_update_email(self, msg, custom_msg=None):
        """
        This function is meant to be called from the shell. It sends a notice to
        the user that their saved search has been updated by the system or an
        admin.

        Inputs:
        :msg:   The description of the update. Passed through verbatim to the
                template.

        Returns:
        nothing

        """
        context_dict = {
            'saved_searches': [(self,)],
            'message': msg,
            'custom_msg': custom_msg,
            'contains_pss': hasattr(self, 'partnersavedsearch')
        }
        message = render_to_string("mysearches/email_update.html",
                                   context_dict)

        category = '{"category": "My.jobs Saved Search Updated (%s:%s)"}' % (
            self.content_type,
            self.pk)
        headers = {'X-SMTPAPI': category}

        default_reason = 'Jobs are not sent in saved search update emails',
        log_kwargs = {
            'reason': default_reason,
            'was_sent': True, 'was_received': False, 'recipient': self.user,
            'recipient_email': self.email, 'new_jobs': 0, 'backfill_jobs': 0
        }
        try:
            send_email(message, email_type=settings.SAVED_SEARCH_UPDATED,
                       recipients=[self.email], label=self.label.strip(),
                       headers=headers)
        except Exception as e:
            log_kwargs['was_sent'] = False
            log_kwargs['reason'] = getattr(e, 'smtp_error', e.message)

        if context_dict['contains_pss']:
            reason = log_kwargs['reason']
            if reason == default_reason:
                # Similar to the logic in initial_email, this default reason
                # serves as a reminder that having zero jobs in this email
                # is intentional and expected.
                reason = None
            self.partnersavedsearch.create_record(
                "Automatic sending of updated partner saved search.",
                failure_message=reason
            )

        SavedSearchLog.objects.create(**log_kwargs)
Esempio n. 10
0
    def send_disable_email(self):
        message = render_to_string('mysearches/email_disable.html',
                                   {'saved_search': self})

        category = '{"category": "My.jobs Saved Search Disabled (%s:%s)"}' % (
            self.content_type, self.pk)
        headers = {'X-SMTPAPI': category}
        send_email(message,
                   email_type=settings.SAVED_SEARCH_DISABLED,
                   recipients=[self.email],
                   headers=headers)
Esempio n. 11
0
    def initial_email(self, custom_msg=None, send=True):
        """
        Generates the body for an initial saved search notification and returns
        it or sends it in an email based on the opt in status of the user.

        Inputs:
        :custom_msg: Custom message to be added when manually resending an
            initial email
        :send: Denotes if we should send the generated email (True) or return
            the body (False). If False, the body will be used in an invitation.
            Default: True

        Outputs:
        :message: Generated email body (if :send: is False) or None
        """
        log_kwargs = {
            'reason': 'Jobs are not sent in initial saved search emails',
            'was_sent': False,
            'was_received': False,
            'recipient': self.user,
            'recipient_email': self.email,
            'new_jobs': 0,
            'backfill_jobs': 0,
            'uuid': uuid.uuid4().hex
        }
        message = None
        if self.user.opt_in_myjobs:
            # Even if send=False, this will still get sent; send=False currently
            # means the generated email body will be used in an invitation.
            log_kwargs['was_sent'] = True
            context_dict = {'saved_searches': [(self,)],
                            'custom_msg': custom_msg,
                            'contains_pss': hasattr(self, 'partnersavedsearch')}
            message = render_to_string("mysearches/email_initial.html",
                                       context_dict)
            message = Pynliner().from_string(message).run()

            if send:
                category = ('{"category": "My.jobs Saved Search Created '
                            '(%s:%s|%s)"}') % (
                                self.content_type,
                                self.pk,
                                log_kwargs['uuid'])
                headers = {'X-SMTPAPI': category}
                send_email(message, email_type=settings.SAVED_SEARCH_INITIAL,
                           recipients=[self.email], label=self.label.strip(),
                           headers=headers)
        else:
            log_kwargs['reason'] = "User can't receive MyJobs email"
        SavedSearchLog.objects.create(**log_kwargs)

        if not send:
            return message
Esempio n. 12
0
    def send_opt_out_notifications(self, saved_searches=None):
        """
        Notify saved search creators that a user has opted out of their emails.
        """
        from mysearches.models import PartnerSavedSearch

        subject = "My.jobs Partner Saved Search Update"

        saved_searches = saved_searches or PartnerSavedSearch.objects.filter(
            user=self)

        # MySQL doesn't support passing a column to distinct, and I don't want
        # to deal with dictionaries returned by `values()`, so I just keep
        # track of unique contacts manually.
        contacts = []
        # need the partner name, so can't send a batch email or message
        for pss in saved_searches:
            if (pss.email, pss.partner) in contacts:
                continue

            contacts.append((pss.email, pss.partner))

            # send notification email
            message = render_to_string(
                "mysearches/email_opt_out.html",
                {'user': self,
                 'partner': pss.partner,
                 'company': pss.provider})

            headers = {
                'X-SMTPAPI': '{"category": "Partner Saved Search Opt Out '
                             '(%s:%s)"}' % (pss.pk, pss.created_by.pk)
            }

            email_type = settings.PARTNER_SAVED_SEARCH_RECIPIENT_OPTED_OUT
            send_email(message,  email_type=email_type,
                       recipients=[pss.created_by.email], headers=headers)

            # create PRM message
            body = render_to_string(
                "mysearches/email_opt_out_message.html",
                {'user': self,
                 'partner': pss.partner,
                 'company': pss.provider})
            Message.objects.create_message(
                subject, body, users=[pss.created_by])
Esempio n. 13
0
    def send_invoice_email(self, send_to_admins=True, other_recipients=None):
        """
        Sends the invoice email to the company admins along with any other
        optional recipients.

        Inputs:
        :send_to_admins:    If True will send the invoice to all CompanyUsers
                            of the Company that owns the product.
                            [Defaults to True]

        :other_recipients:  A list object that contains the other recipient(s)
                            email so we can send them the invoice

        """
        from seo.models import CompanyUser

        other_recipients = [] if not other_recipients else other_recipients

        data = {
            'invoice': self,
            'purchases': self.invoiced_products.all(),
            'AUTHORIZE_NET': Invoice.AUTHORIZE_NET,
            'FREE': Invoice.FREE,
            'OFFLINE_PURCHASE': Invoice.OFFLINE_PURCHASE,
        }

        owner = self.owner
        group, _ = Group.objects.get_or_create(name=self.ADMIN_GROUP_NAME)
        owner_admins = []
        if send_to_admins:
            owner_admins = CompanyUser.objects.filter(company=owner,
                                                      group=group)
            owner_admins = owner_admins.values_list('user__email', flat=True)

        recipients = set(other_recipients + list(owner_admins))
        if recipients:
            body = render_to_string('postajob/invoice_email.html', data)
            site = getattr(settings, 'SITE', None)
            headers = {
                'X-SMTPAPI': '{"category": "Invoice sent (%s)"}' % self.pk
            }
            send_email(body, email_type=settings.INVOICE, recipients=recipients,
                       site=site, headers=headers)
Esempio n. 14
0
    def send_email(self):
        group, _ = Group.objects.get_or_create(name=self.ADMIN_GROUP_NAME)
        admin_emails = self.owner.role_set.filter(
            user__groups=group).values_list('user__email', flat=True)

        # Confirm that the request object was fully created and still exists
        # before sending the email.
        if self.request_object():
            data = {
                'request': self,
                'requester': self.requesting_company().name,
            }
            body = render_to_string('postajob/request_email.html', data)
            site = getattr(settings, 'SITE', None)
            headers = {
                'X-SMTPAPI': '{"category": "Request Created (%s)"}' % self.pk
            }
            send_email(body, settings.POSTING_REQUEST_CREATED,
                       recipients=admin_emails, site=site, headers=headers)
Esempio n. 15
0
def send_contact_record_email_response(created_records, created_contacts,
                                       attachment_failures, unmatched_contacts,
                                       error, to_email):
    ctx = {
        'created_records': created_records,
        'created_contacts': created_contacts,
        'error': error,
        'unmatched_contacts': unmatched_contacts,
        'attachment_failures': attachment_failures,
    }

    message = render_to_string('mypartners/email/email_response.html',
                               ctx)
    headers = {
        'X-SMTPAPI': '{"category": "Communication Record %s"}' % (
            'Failure' if error is not None else 'Success')
    }

    send_email(message, email_type=settings.CREATE_CONTACT_RECORD,
               recipients=[to_email], headers=headers)
Esempio n. 16
0
def send_contact_record_email_response(created_records,
                                       created_contacts,
                                       attachment_failures,
                                       unmatched_contacts,
                                       error,
                                       to_email,
                                       is_nuo=False,
                                       company=None,
                                       buckets=None):

    # Multiple outreach email addresses may have been provided. We should have
    # already ensured that they all belong to one company. Pick one to use in
    # our return email.
    bucket = ''
    if buckets:
        bucket = buckets[0]
    ctx = {
        'created_records': created_records,
        'created_contacts': created_contacts,
        'error': error,
        'unmatched_contacts': unmatched_contacts,
        'attachment_failures': attachment_failures,
        'company': company,
        'to_email': to_email,
        'bucket': bucket,
    }

    template = 'mypartners/email/email_response.html'
    if is_nuo:
        template = 'mypartners/email/nuo_email_response.html'
    message = render_to_string(template, ctx)
    headers = {
        'X-SMTPAPI':
        '{"category": "Communication Record %s"}' %
        ('Failure' if error is not None else 'Success')
    }

    send_email(message,
               email_type=settings.CREATE_CONTACT_RECORD,
               recipients=[to_email],
               headers=headers)
Esempio n. 17
0
    def send_invoice_email(self, send_to_admins=True, other_recipients=None):
        """
        Sends the invoice email to the company admins along with any other
        optional recipients.

        Inputs:
        :send_to_admins:    If True will send the invoice to all admin users of
                            the Company that owns the product.[Default: True]

        :other_recipients:  A list object that contains the other recipient(s)
                            email so we can send them the invoice

        """
        other_recipients = other_recipients or []

        data = {
            'invoice': self,
            'purchases': self.invoiced_products.all(),
            'AUTHORIZE_NET': Invoice.AUTHORIZE_NET,
            'FREE': Invoice.FREE,
            'OFFLINE_PURCHASE': Invoice.OFFLINE_PURCHASE,
        }

        owner = self.owner
        group, _ = Group.objects.get_or_create(name=self.ADMIN_GROUP_NAME)
        owner_admins = owner.role_set.filter(user__groups=group).values_list(
            'user__email', flat=True) if send_to_admins else []

        recipients = set(other_recipients).union(owner_admins)
        if recipients:
            body = render_to_string('postajob/invoice_email.html', data)
            site = getattr(settings, 'SITE', None)
            headers = {
                'X-SMTPAPI': '{"category": "Invoice sent (%s)"}' % self.pk
            }
            send_email(body,
                       email_type=settings.INVOICE,
                       recipients=recipients,
                       site=site,
                       headers=headers)
Esempio n. 18
0
    def send_email(self):
        group, _ = Group.objects.get_or_create(name=self.ADMIN_GROUP_NAME)
        admin_emails = self.owner.role_set.filter(
            user__groups=group).values_list('user__email', flat=True)

        # Confirm that the request object was fully created and still exists
        # before sending the email.
        if self.request_object():
            data = {
                'request': self,
                'requester': self.requesting_company().name,
            }
            body = render_to_string('postajob/request_email.html', data)
            site = getattr(settings, 'SITE', None)
            headers = {
                'X-SMTPAPI': '{"category": "Request Created (%s)"}' % self.pk
            }
            send_email(body,
                       settings.POSTING_REQUEST_CREATED,
                       recipients=admin_emails,
                       site=site,
                       headers=headers)
Esempio n. 19
0
    def send_email(self, custom_msg=None):
        log_kwargs = {
            'was_sent': False,
            'was_received': False,
            'recipient': self.user,
            'recipient_email': self.email,
            'new_jobs': 0,
            'backfill_jobs': 0,
            'uuid': uuid.uuid4().hex
        }
        total_jobs = 0
        saved_searches = self.user.savedsearch_set.filter(is_active=True)
        search_list = []
        contains_pss = False
        for search in saved_searches:
            items, count = search.get_feed_items()
            total_jobs += count
            pss = None
            if hasattr(search, 'partnersavedsearch'):
                pss = search.partnersavedsearch
            elif isinstance(search, PartnerSavedSearch):
                pss = search

            if pss is not None:
                # New jobs will have a "new" key in their job dictionaries.
                # We can count the number that do not
                log_kwargs['backfill_jobs'] += len([item for item in items
                                                    if not item.get('new')])
                log_kwargs['new_jobs'] += count - log_kwargs['backfill_jobs']
                contains_pss = True
                extras = pss.url_extras
                if extras:
                    mypartners.helpers.add_extra_params_to_jobs(items, extras)
                    search.url = mypartners.helpers.add_extra_params(search.url,
                                                                     extras)
                pss.create_record(custom_msg)
            search_list.append((search, items, count))

        saved_searches = [(search, items, count)
                          for search, items, count in search_list
                          if (items or hasattr(search, 'partnersavedsearch'))]

        if self.user.can_receive_myjobs_email() and saved_searches:
            log_kwargs['was_sent'] = True
            context_dict = {
                'saved_searches': saved_searches,
                'digest': self,
                'custom_msg': custom_msg,
                'contains_pss': contains_pss
            }
            message = render_to_string('mysearches/email_digest.html',
                                       context_dict)
            category = '{"category": "My.jobs Saved Search Digest Send (%s:%s:%s:%s)"}' % (
                self.content_type,
                self.pk,
                ','.join([str(search[0].pk) for search in saved_searches]),
                log_kwargs['uuid'])
            headers = {'X-SMTPAPI': category}
            send_email(message, email_type=settings.SAVED_SEARCH_DIGEST,
                       recipients=[self.email], headers=headers)

            sent_search_kwargs = {
                'pk__in': [search[0].pk for search in saved_searches]
            }
            searches_sent = SavedSearch.objects.filter(**sent_search_kwargs)
            searches_sent.update(last_sent=datetime.now())
        else:
            if not saved_searches:
                log_kwargs['reason'] = ("No saved searches or saved searches "
                                        "have no jobs")
            else:
                log_kwargs['reason'] = "User can't receive MyJobs email"
        SavedSearchLog.objects.create(**log_kwargs)
Esempio n. 20
0
    def initial_email(self, custom_msg=None, send=True):
        """
        Generates the body for an initial saved search notification and returns
        it or sends it in an email based on the opt in status of the user.

        Inputs:
        :custom_msg: Custom message to be added when manually resending an
            initial email
        :send: Denotes if we should send the generated email (True) or return
            the body (False). If False, the body will be used in an invitation.
            Default: True

        Outputs:
        :message: Generated email body (if :send: is False) or None
        """
        default_reason = 'Jobs are not sent in initial saved search emails'
        log_kwargs = {
            'reason': default_reason,
            'was_sent': False,
            'was_received': False,
            'recipient': self.user,
            'recipient_email': self.email,
            'new_jobs': 0,
            'backfill_jobs': 0,
            'uuid': uuid.uuid4().hex
        }
        message = None
        if self.user.opt_in_myjobs:
            # Even if send=False, this will still get sent; send=False currently
            # means the generated email body will be used in an invitation.
            log_kwargs['was_sent'] = True
            context_dict = {'saved_searches': [(self,)],
                            'custom_msg': custom_msg,
                            'contains_pss': hasattr(self, 'partnersavedsearch')}
            message = render_to_string("mysearches/email_initial.html",
                                       context_dict)
            message = Pynliner().from_string(message).run()

            if send:
                category = ('{"category": "My.jobs Saved Search Created '
                            '(%s:%s|%s)"}') % (
                                self.content_type,
                                self.pk,
                                log_kwargs['uuid'])
                headers = {'X-SMTPAPI': category}
                try:
                    send_email(message, email_type=settings.SAVED_SEARCH_INITIAL,
                               recipients=[self.email], label=self.label.strip(),
                               headers=headers)
                except Exception as e:
                    log_kwargs['was_sent'] = False
                    log_kwargs['reason'] = getattr(e, 'smtp_error', e.message)

                if context_dict['contains_pss']:
                    reason = log_kwargs['reason']
                    if reason == default_reason:
                        # Most other instances of SavedSearchLog have nothing
                        # in the reason field when successful. This one is a
                        # little different, serving as a reminder of why this
                        # particular email contains no jobs.
                        reason = None
                    self.partnersavedsearch.create_record(
                        "Automatic sending of initial partner saved search",
                        failure_message=reason
                    )
        else:
            log_kwargs['reason'] = "User can't receive MyJobs email"
        SavedSearchLog.objects.create(**log_kwargs)

        if not send:
            return message
Esempio n. 21
0
    def send_email(self, custom_msg=None):
        log_kwargs = {
            'was_sent': False,
            'was_received': False,
            'recipient': self.user,
            'recipient_email': self.email,
            'new_jobs': 0,
            'backfill_jobs': 0,
            'uuid': uuid.uuid4().hex
        }
        total_jobs = 0
        saved_searches = self.user.savedsearch_set.filter(is_active=True)
        search_list = []
        needs_records = []
        contains_pss = False
        for search in saved_searches:
            items, count = search.get_feed_items()
            total_jobs += count
            pss = None
            if hasattr(search, 'partnersavedsearch'):
                pss = search.partnersavedsearch
            elif isinstance(search, PartnerSavedSearch):
                pss = search

            if pss is not None:
                # We know partner searches require communication records but
                # we need to put off the creation of them until we find out
                # if said communication was successful.
                needs_records.append(pss)
                # New jobs will have a "new" key in their job dictionaries.
                # We can count the number that do not
                log_kwargs['backfill_jobs'] += len(
                    [item for item in items if not item.get('new')])
                log_kwargs['new_jobs'] += count - log_kwargs['backfill_jobs']
                contains_pss = True
                extras = pss.url_extras
                if extras:
                    mypartners.helpers.add_extra_params_to_jobs(items, extras)
                    search.url = mypartners.helpers.add_extra_params(
                        search.url, extras)
            search_list.append((search, items, count))

        saved_searches = [(search, items, count)
                          for search, items, count in search_list
                          if (items or hasattr(search, 'partnersavedsearch'))]

        if self.user.can_receive_myjobs_email() and saved_searches:
            log_kwargs['was_sent'] = True
            context_dict = {
                'saved_searches': saved_searches,
                'digest': self,
                'custom_msg': custom_msg,
                'contains_pss': contains_pss
            }
            message = render_to_string('mysearches/email_digest.html',
                                       context_dict)
            category = '{"category": "My.jobs Saved Search Digest Send (%s:%s:%s:%s)"}' % (
                self.content_type, self.pk, ','.join(
                    [str(search[0].pk)
                     for search in saved_searches]), log_kwargs['uuid'])
            headers = {'X-SMTPAPI': category}
            try:
                send_email(message,
                           email_type=settings.SAVED_SEARCH_DIGEST,
                           recipients=[self.email],
                           headers=headers)
            except Exception as e:
                log_kwargs['was_sent'] = False
                log_kwargs['reason'] = getattr(e, 'smtp_error', e.message)
            else:
                sent_search_kwargs = {
                    'pk__in': [search[0].pk for search in saved_searches]
                }
                searches_sent = SavedSearch.objects.filter(
                    **sent_search_kwargs)
                searches_sent.update(last_sent=datetime.now())
        else:
            if not saved_searches:
                log_kwargs['reason'] = ("No saved searches or saved searches "
                                        "have no jobs")
            else:
                log_kwargs['reason'] = "User can't receive MyJobs email"
        for pss in needs_records:
            pss.create_record(custom_msg,
                              failure_message=log_kwargs.get('reason'))
        SavedSearchLog.objects.create(**log_kwargs)
Esempio n. 22
0
    def send_email(self, custom_msg=None, additional_categories=None,
                   additional_headers=None):
        log_kwargs = {
            'was_sent': False,
            'was_received': False,
            'recipient': self.user,
            'recipient_email': self.email,
            'new_jobs': 0,
            'backfill_jobs': 0,
            'uuid': uuid.uuid4().hex
        }
        if self.user.can_receive_myjobs_email():
            items, count = self.get_feed_items()
            is_pss = hasattr(self, 'partnersavedsearch')
            if items or is_pss:
                log_kwargs['was_sent'] = True
                if is_pss:
                    extras = self.partnersavedsearch.url_extras
                    if extras:
                        mypartners.helpers.add_extra_params_to_jobs(items,
                                                                    extras)
                        self.url = mypartners.helpers.add_extra_params(self.url,
                                                                       extras)
                if self.custom_message and not custom_msg:
                    custom_msg = self.custom_message

                context_dict = {'saved_searches': [(self, items, count)],
                                'custom_msg': custom_msg,
                                'contains_pss': is_pss}
                message = render_to_string('mysearches/email_single.html',
                                           context_dict)
                categories = [('My.jobs Saved Search Sent '
                               '({content_type}:{pk}|{uuid})').format(
                                   content_type=self.content_type,
                                   pk=self.pk, uuid=log_kwargs['uuid']),
                              settings.ENVIRONMENT]

                # additional_categories and additional_headers are used when
                # sending email from qc/staging to stop SendGrid's url
                # redirection and to enable us to drop events that we shouldn't
                # be processing (QC emails getting posted to Production)
                if additional_categories is not None:
                    categories.extend(
                        additional_categories if isinstance(
                            additional_categories, list)
                        else [additional_categories])
                categories = ['"%s"' % category for category in categories]
                category = '[%s]' % ','.join(categories)
                header = ['"category": ' + category]
                if additional_headers is not None:
                    header.extend(
                        additional_headers if isinstance(
                            additional_headers, list)
                        else [additional_headers])
                header = '{%s}' % (','.join(header), )
                headers = {'X-SMTPAPI': header}

                send_email(message, email_type=settings.SAVED_SEARCH,
                           recipients=[self.email], label=self.label.strip(),
                           headers=headers)

                self.last_sent = datetime.now()
                self.save()

                if is_pss:
                    record = self.partnersavedsearch.create_record(custom_msg)
                    log_kwargs['contact_record'] = record
                    log_kwargs['new_jobs'] = len([item for item in items
                                                 if item.get('new')])
                    log_kwargs['backfill_jobs'] = count - log_kwargs['new_jobs']

                else:
                    log_kwargs['new_jobs'] = count
                    log_kwargs['backfill_jobs'] = 0
            else:
                log_kwargs['reason'] = 'No jobs'
        else:
            log_kwargs['reason'] = "User can't receive MyJobs email"
        SavedSearchLog.objects.create(**log_kwargs)
Esempio n. 23
0
    def initial_email(self, custom_msg=None, send=True):
        """
        Generates the body for an initial saved search notification and returns
        it or sends it in an email based on the opt in status of the user.

        Inputs:
        :custom_msg: Custom message to be added when manually resending an
            initial email
        :send: Denotes if we should send the generated email (True) or return
            the body (False). If False, the body will be used in an invitation.
            Default: True

        Outputs:
        :message: Generated email body (if :send: is False) or None
        """
        default_reason = 'Jobs are not sent in initial saved search emails'
        log_kwargs = {
            'reason': default_reason,
            'was_sent': False,
            'was_received': False,
            'recipient': self.user,
            'recipient_email': self.email,
            'new_jobs': 0,
            'backfill_jobs': 0,
            'uuid': uuid.uuid4().hex
        }
        message = None
        if self.user.opt_in_myjobs:
            # Even if send=False, this will still get sent; send=False currently
            # means the generated email body will be used in an invitation.
            log_kwargs['was_sent'] = True
            context_dict = {
                'saved_searches': [(self, )],
                'custom_msg': custom_msg,
                'contains_pss': hasattr(self, 'partnersavedsearch')
            }
            message = render_to_string("mysearches/email_initial.html",
                                       context_dict)
            message = Pynliner().from_string(message).run()

            if send:
                category = ('{"category": "My.jobs Saved Search Created '
                            '(%s:%s|%s)"}') % (self.content_type, self.pk,
                                               log_kwargs['uuid'])
                headers = {'X-SMTPAPI': category}
                try:
                    send_email(message,
                               email_type=settings.SAVED_SEARCH_INITIAL,
                               recipients=[self.email],
                               label=self.label.strip(),
                               headers=headers)
                except Exception as e:
                    log_kwargs['was_sent'] = False
                    log_kwargs['reason'] = getattr(e, 'smtp_error', e.message)

                if context_dict['contains_pss']:
                    reason = log_kwargs['reason']
                    if reason == default_reason:
                        # Most other instances of SavedSearchLog have nothing
                        # in the reason field when successful. This one is a
                        # little different, serving as a reminder of why this
                        # particular email contains no jobs.
                        reason = None
                    self.partnersavedsearch.create_record(
                        "Automatic sending of initial partner saved search",
                        failure_message=reason)
        else:
            log_kwargs['reason'] = "User can't receive MyJobs email"
        SavedSearchLog.objects.create(**log_kwargs)

        if not send:
            return message
Esempio n. 24
0
    def send_email(self,
                   custom_msg=None,
                   additional_categories=None,
                   additional_headers=None):
        log_kwargs = {
            'was_sent': False,
            'was_received': False,
            'recipient': self.user,
            'recipient_email': self.email,
            'new_jobs': 0,
            'backfill_jobs': 0,
            'uuid': uuid.uuid4().hex
        }
        if self.user.can_receive_myjobs_email():
            items, count = self.get_feed_items()
            is_pss = hasattr(self, 'partnersavedsearch')
            if items or is_pss:
                log_kwargs['was_sent'] = True
                if is_pss:
                    extras = self.partnersavedsearch.url_extras
                    if extras:
                        mypartners.helpers.add_extra_params_to_jobs(
                            items, extras)
                        self.url = mypartners.helpers.add_extra_params(
                            self.url, extras)
                if self.custom_message and not custom_msg:
                    custom_msg = self.custom_message

                context_dict = {
                    'saved_searches': [(self, items, count)],
                    'custom_msg': custom_msg,
                    'contains_pss': is_pss
                }
                message = render_to_string('mysearches/email_single.html',
                                           context_dict)
                categories = [('My.jobs Saved Search Sent '
                               '({content_type}:{pk}|{uuid})').format(
                                   content_type=self.content_type,
                                   pk=self.pk,
                                   uuid=log_kwargs['uuid']),
                              settings.ENVIRONMENT]

                # additional_categories and additional_headers are used when
                # sending email from qc/staging to stop SendGrid's url
                # redirection and to enable us to drop events that we shouldn't
                # be processing (QC emails getting posted to Production)
                if additional_categories is not None:
                    categories.extend(additional_categories if isinstance(
                        additional_categories, list
                    ) else [additional_categories])
                categories = ['"%s"' % category for category in categories]
                category = '[%s]' % ','.join(categories)
                header = ['"category": ' + category]
                if additional_headers is not None:
                    header.extend(additional_headers if isinstance(
                        additional_headers, list) else [additional_headers])
                header = '{%s}' % (','.join(header), )
                headers = {'X-SMTPAPI': header}

                try:
                    send_email(message,
                               email_type=settings.SAVED_SEARCH,
                               recipients=[self.email],
                               label=self.label.strip(),
                               headers=headers,
                               text_only=self.text_only)
                except Exception as e:
                    log_kwargs['was_sent'] = False
                    log_kwargs['reason'] = getattr(e, 'smtp_error', e.message)
                else:
                    self.last_sent = datetime.now()
                    self.save()

                if is_pss:
                    record = self.partnersavedsearch.create_record(
                        custom_msg, failure_message=log_kwargs.get('reason'))
                    log_kwargs['contact_record'] = record
                    log_kwargs['new_jobs'] = len(
                        [item for item in items if item.get('new')])
                    log_kwargs['backfill_jobs'] = count - \
                        log_kwargs['new_jobs']

                else:
                    log_kwargs['new_jobs'] = count
                    log_kwargs['backfill_jobs'] = 0
            else:
                log_kwargs['reason'] = 'No jobs'
        else:
            log_kwargs['reason'] = "User can't receive MyJobs email"
        SavedSearchLog.objects.create(**log_kwargs)
Esempio n. 25
0
 def email_user(self, message, email_type=settings.GENERIC, **kwargs):
     headers = kwargs.pop('headers', {})
     if 'X-SMTPAPI' not in headers:
         headers['X-SMTPAPI'] = '{"category": "Email to User (%s)"}' % self.pk
     send_email(message, email_type=email_type, recipients=[self.email],
                headers=headers, **kwargs)