def get_owner_emails_list(self): """ Returns a list of owner's email addresses. It's tricky because directory doesn't have a clear owner. Since the owner field can be changed to whoever last edited, we'll check the creator, the email address field, member or reps if it is created from memberships and corp memberships, respectively. """ emails_list = [] # creator if self.creator and validate_email(self.creator.email): emails_list.append(self.creator.email) # the email field if validate_email(self.email): emails_list.append(self.email) # member [m] = self.membershipdefault_set.filter(status_detail='active')[:1] or [None] if m and validate_email(m.user.email): emails_list.append(m.user.email) # corp reps if hasattr(self, 'corpprofile'): corp_reps = self.corpprofile.reps.all() for rep in corp_reps: if validate_email(rep.user.email): emails_list.append(rep.user.email) return list(set(emails_list))
def get_notice_recipients(scope, scope_category, setting_name): from tendenci.apps.site_settings.utils import get_setting from tendenci.apps.base.utils import validate_email recipients = [] # global recipients g_recipients = (get_setting('site', 'global', 'allnoticerecipients')).split(',') g_recipients = [r.strip() for r in g_recipients] # module recipients m_recipients = (get_setting(scope, scope_category, setting_name)).split(',') m_recipients = [r.strip() for r in m_recipients] # consolidate [remove duplicate email address] for recipient in list(set(g_recipients + m_recipients)): if validate_email(recipient): recipients.append(recipient) # if the settings for notice recipients are not set up, return admin contact email if not recipients: admin_contact_email = (get_setting('site', 'global', 'admincontactemail')).strip() recipients = admin_contact_email.split(',') return recipients
def email_to(self): """ Return the value entered for the first field of type EmailField. """ for field in self.form_fields: field_class = field.field_type.split("/")[0] if field_class == "EmailVerificationField": return self.cleaned_data["field_%s" % field.id] user_email = getattr(self.user, "email", "").strip() if validate_email(user_email): return user_email return None
def delete_cm_subscriber(sender, instance=None, **kwargs): """Delete the subscriber from the campaign monitor list """ from tendenci.apps.base.utils import validate_email (name, email) = get_name_email(instance) if email and validate_email(email): try: list_map = ListMap.objects.get(group=instance.group) list_id = list_map.list_id alist = List(auth, list_id) if alist: subscriber_obj = Subscriber(auth, list_id, email) try: subscriber_obj.unsubscribe() except: pass except ListMap.DoesNotExist: pass
def email_notice(self, event, registration, verbosity=0, **kwargs): from tendenci.apps.notifications import models as notification from tendenci.apps.base.utils import validate_email registrant = registration.registrant if registrant and registrant.email and validate_email(registrant.email): recipient = registrant.email if recipient: if verbosity == 2: print('Sending notice email to {}'.format(recipient)) context = {'event': event, 'invoice': registration.invoice, 'reg8n': registration, 'registrant': registrant.user, } context.update(kwargs) notification.send_emails([recipient], 'event_email_abandoned', context) return True
def send_emails(emails, label, extra_context=None, on_site=True): """ This method accepts a list of email addresses as opposed to a list of users. This is a custom method as opposed to send(), send_now(), and queue() Just send the notice to a list of emails immediately. No new notice created here notification.send_emails(email_list, 'friends_invite_sent', { 'spam': 'eggs', 'foo': 'bar', ) """ # exclude blocked emails emails = [e for e in emails if not Email.is_blocked(e)] if not emails: return if extra_context is None: extra_context = {} try: notice_type = NoticeType.objects.get(label=label) except NoticeType.DoesNotExist as err: logger.warning('Skipping notification send for "{label}": {err}'.format( label=label, err=err)) # Stop here because we need a notice_type return None headers = {} protocol = getattr(settings, "DEFAULT_HTTP_PROTOCOL", "http") current_site = Site.objects.get_current() notices_url = u"%s://%s%s" % ( protocol, str(current_site), reverse("notification_notices"), ) formats = ( 'full.html', 'short.txt', 'notice.html', ) # TODO make formats configurable extra_context.update({ "notice": gettext(notice_type.display), "notices_url": notices_url, "current_site": current_site, 'SITE_GLOBAL_SITEURL': get_setting('site', 'global', 'siteurl'), 'SITE_GLOBAL_SITEDISPLAYNAME': get_setting('site', 'global', 'sitedisplayname'), }) # test for request in the extra_context if 'request' in extra_context: request = extra_context['request'] else: request = None # get prerendered format messages messages = get_formatted_messages(formats, label, extra_context) if 'admin' in label: subject = messages['short'] body = messages['full'] else: extra_context.update({'message': mark_safe(messages['short'])}) subject = render_to_string( template_name='notification/email_subject.txt', context=extra_context, request=request) extra_context.update({'message': mark_safe(messages['full'])}) body = render_to_string( template_name='notification/email_body.txt', context=extra_context, request=request) if 'reply_to' in extra_context: reply_to = extra_context['reply_to'] if reply_to: headers['Reply-To'] = reply_to else: reply_to = '' sender = extra_context.get('sender', '') if not sender: sender = get_setting('site', 'global', 'siteemailnoreplyaddress') or settings.DEFAULT_FROM_EMAIL if not sender: sender = settings.DEFAULT_FROM_EMAIL sender_display = extra_context.get('sender_display', '') # Add quotes around display name to prevent errors on sending # when display name contains comma or other control characters, - jennyq from_display = '"%s" <%s>' % (sender_display, sender) if sender_display: headers['From'] = from_display recipient_bcc = extra_context.get('recipient_bcc') or [] content_type = 'html' # removing newlines subject = ''.join(subject.splitlines()) body = add_tendenci_footer(body) for email_addr in emails: if validate_email(email_addr): recipients = [email_addr] if recipient_bcc: email = EmailMessage(subject, body, sender, recipients, recipient_bcc, headers=headers) else: email = EmailMessage(subject, body, sender, recipients, headers=headers) email.content_subtype = content_type try: email.send(fail_silently=True) # should we raise exception or not? except UnicodeError: pass to = ','.join(emails) bcc = ','.join(recipient_bcc) reply_to = reply_to or str() NoticeEmail.objects.create( emails=to, sender=sender, bcc=bcc, title=subject, content=body, reply_to=reply_to, from_display=from_display, notice_type=notice_type )
def sync_cm_subscriber(sender, instance=None, created=False, **kwargs): """Subscribe the subscriber to the campaign monitor list Check if sync_newsletters is True. Do nothing if False. """ from tendenci.apps.base.utils import validate_email from tendenci.apps.profiles.models import Profile if instance and instance.group and not instance.group.sync_newsletters: return (name, email) = get_name_email(instance) if email and validate_email(email): add_list = False add_subscriber = True list_map = None # Append custom fields from the profile profile = None if hasattr(instance, 'member'): try: profile = instance.member.profile except Profile.DoesNotExist: profile = None custom_data = [] if profile: fields = ['city', 'state', 'zipcode', 'country', 'sex', 'member_number'] for field in fields: data = {} data['Key'] = field data['Value'] = getattr(profile, field) if not data['Value']: data['Clear'] = True custom_data.append(data) try: list_map = ListMap.objects.get(group=instance.group) list_id = list_map.list_id alist = List(auth, list_id) if alist: # subscriber setup subscriber_obj = Subscriber(auth, list_id) try: # check if this user has already subscribed, if not, subscribe it try: subscriber = subscriber_obj.get(list_id, email) if str(subscriber.State).lower() == 'active': subscriber = subscriber_obj.update(email, name, custom_data, True) add_subscriber = False except BadRequest: pass except Unauthorized: alist = List(auth) add_list = True except ServerError: pass except ListMap.DoesNotExist: alist = List(auth) add_list = True try: if add_list: # this list might be deleted on campaign monitor, add it back list_id = alist.create(cm_client_id, instance.group.name, "", False, "") # custom fields setup setup_custom_fields(alist) subscriber_obj = Subscriber(auth, list_id) if not list_map: list_map = ListMap() list_map.group = instance.group list_map.list_id = list_id list_map.save() if add_subscriber: subscriber_obj.add(list_id, email, name, custom_data, True) # Returns email_address except BadRequest: pass
def api_rp_setup(data): """Create a recurrring payment account. Accepted format: json Input fields: email - required description - required amount - required cp_id - customer profile id, required pp_id - customer payment profile id, required billing_cycle_start_dt - required billing_cycle_end_dt - required response_str - required login_name login_password url first_name last_name billing_period - optional, default to 'month' billing_frequency - optional, default to 1 billing_start_dt - optional, default to today num_days - optional, default to 0 has_trial_period - optional, default to False trial_period_start_dt - optional, default to today trial_period_end_dt - optional, default to today trial_amount - optional, default to 0 Output: rp_id - a recurring payment id rp_url - url to rp username result_code """ from tendenci.apps.base.utils import validate_email import dateutil.parser as dparser from tendenci.apps.imports.utils import get_unique_username email = data.get('email', '') description = data.get('description', '') url = data.get('url') payment_amount = data.get('amount', '') taxable = data.get('taxable', 0) if taxable in ('True', 'true', '1', 1): taxable = 1 else: taxable = 0 try: tax_rate = Decimal(data.get('tax_rate', 0)) if tax_rate > 1: tax_rate = 0 except: tax_rate = 0 tax_exempt = data.get('tax_exempt', 0) if tax_exempt in ('True', 'true', '1', 1): tax_exempt = 1 else: tax_exempt = 0 try: payment_amount = Decimal(payment_amount) except: payment_amount = 0 cp_id = data.get('cp_id') pp_id = data.get('pp_id') billing_cycle_start_dt = data.get('billing_cycle_start_dt') if billing_cycle_start_dt: billing_cycle_start_dt = dparser.parse(billing_cycle_start_dt) billing_cycle_end_dt = data.get('billing_cycle_end_dt') if billing_cycle_end_dt: billing_cycle_end_dt = dparser.parse(billing_cycle_end_dt) direct_response_str = data.get('response_str') if not all([validate_email(email), description, payment_amount>0, cp_id, pp_id, billing_cycle_start_dt, billing_cycle_end_dt, direct_response_str] ): return False, {} # 1) get or create user username = data.get('login_name') # check if user already exists based on email and username users = User.objects.filter(email=email, username=username) if users: u = users[0] else: # create user account u = User() u.email=email u.username = username if not u.username: u.username = email.split('@')[0] u.username = get_unique_username(u) raw_password = data.get('login_password') if not raw_password: raw_password = User.objects.make_random_password(length=8) u.set_password(raw_password) u.first_name = data.get('first_name', '') u.last_name = data.get('last_name', '') u.is_staff = False u.is_superuser = False u.save() profile = Profile.objects.create( user=u, creator=u, creator_username=u.username, owner=u, owner_username=u.username, email=u.email ) # 2) create a recurring payment account rp = RecurringPayment() rp.user = u rp.description = description rp.url = url rp.payment_amount = payment_amount rp.taxable = taxable rp.tax_rate = tax_rate rp.tax_exempt = tax_exempt rp.customer_profile_id = cp_id rp.billing_start_dt = billing_cycle_start_dt has_trial_period = data.get('has_trial_period') trial_period_start_dt = data.get('trial_period_start_dt') trial_period_end_dt = data.get('trial_period_end_dt') if has_trial_period in ['True', '1', True, 1] and all([trial_period_start_dt, trial_period_end_dt]): rp.has_trial_period = True rp.trial_period_start_dt = dparser.parse(trial_period_start_dt) rp.trial_period_end_dt = dparser.parse(trial_period_end_dt) else: rp.has_trial_period = False rp.status_detail = 'active' rp.save() # 3) create a payment profile account payment_profile_exists = PaymentProfile.objects.filter( customer_profile_id=cp_id, payment_profile_id=pp_id ).exists() if not payment_profile_exists: PaymentProfile.objects.create( customer_profile_id=cp_id, payment_profile_id=pp_id, owner=u, owner_username=u.username ) # 4) create rp invoice billing_cycle = {'start': billing_cycle_start_dt, 'end': billing_cycle_end_dt} rp_invoice = rp.create_invoice(billing_cycle, billing_cycle_start_dt) rp_invoice.invoice.tender(rp.user) # 5) create rp transaction now = datetime.now() payment = Payment() payment.payments_pop_by_invoice_user(rp.user, rp_invoice.invoice, rp_invoice.invoice.guid) payment_transaction = PaymentTransaction( recurring_payment=rp, recurring_payment_invoice=rp_invoice, payment_profile_id=pp_id, trans_type='auth_capture', amount=rp_invoice.invoice.total, status=True) payment = payment_update_from_response(payment, direct_response_str) payment.mark_as_paid() payment.save() rp_invoice.invoice.make_payment(rp.user, Decimal(payment.amount)) rp_invoice.invoice.save() rp_invoice.payment_received_dt = now rp_invoice.save() rp.last_payment_received_dt = now rp.num_billing_cycle_completed += 1 rp.save() payment_transaction.payment = payment payment_transaction.result_code = data.get('result_code') payment_transaction.message_code = data.get('message_code') payment_transaction.message_text = data.get('message_text') payment_transaction.save() site_url = get_setting('site', 'global', 'siteurl') return True, {'rp_id': rp.id, 'rp_url': '%s%s' % (site_url, reverse('recurring_payment.view_account', args=[rp.id])), 'username': rp.user.username}
def send_newsletter(self, newsletter_id, **kwargs): from tendenci.apps.emails.models import Email from tendenci.apps.newsletters.models import Newsletter, NewsletterRecurringData from tendenci.apps.site_settings.utils import get_setting from tendenci.apps.base.utils import validate_email from tendenci.apps.newsletters.utils import get_newsletter_connection connection = get_newsletter_connection() if not connection: print( 'Exiting..Please set up your newsletter email provider before proceeding.' ) return print("Started sending newsletter...") if newsletter_id == 0: raise CommandError( 'Newsletter ID is required. Usage: ./manage.py send_newsletter <newsletter_id>' ) newsletter = Newsletter.objects.filter(pk=int(newsletter_id)) if newsletter.exists(): newsletter = newsletter[0] else: newsletter = None if not newsletter: raise CommandError( 'You are trying to send a newsletter that does not exist.') # validate sender if not validate_email(newsletter.email.sender): raise CommandError( '"{}" is not a valid sender email address.'.format( newsletter.email.sender)) if newsletter.send_status == 'queued': newsletter.send_status = 'sending' elif newsletter.send_status == 'sent': newsletter.send_status = 'resending' elif newsletter.send_status == 'resent': newsletter.send_status == 'resending' newsletter.save() if newsletter.schedule: # save start_dt and status for the recurring nr_data = NewsletterRecurringData( newsletter=newsletter, start_dt=datetime.datetime.now(), send_status=newsletter.send_status) nr_data.save() newsletter.nr_data = nr_data recipients = newsletter.get_recipients() email = newsletter.email # replace relative to absolute urls self.site_url = get_setting('site', 'global', 'siteurl') email.body = email.body.replace("src=\"/", "src=\"%s/" % self.site_url) email.body = email.body.replace("href=\"/", "href=\"%s/" % self.site_url) if newsletter.group and newsletter.group.membership_types.all().exists( ): membership_type = newsletter.group.membership_types.all()[0] else: membership_type = None counter = 0 for recipient in recipients: if hasattr(recipient.member, 'profile'): profile = recipient.member.profile else: profile = None # Skip if Don't Send Email is on if newsletter.enforce_direct_mail_flag: if profile and not profile.direct_mail: continue # skip if not a valid email address if not validate_email(recipient.member.email): continue subject = email.subject body = email.body if '[firstname]' in subject: subject = subject.replace('[firstname]', recipient.member.first_name) if '[lastname]' in subject: subject = subject.replace('[lastname]', recipient.member.last_name) if '[username]' in body: body = body.replace('[username]', recipient.member.username) if '[firstname]' in body: body = body.replace('[firstname]', recipient.member.first_name) if '[unsubscribe_url]' in body: #body = body.replace('[unsubscribe_url]', recipient.noninteractive_unsubscribe_url) # The unsubscribe_url link should be something like <a href="[unsubscribe_url]">Unsubscribe</a>. # But it can be messed up sometimes. Let's prevent that from happening. p = r'(href=\")([^\"]*)(\[unsubscribe_url\])(\")' body = re.sub( p, r'\1' + recipient.noninteractive_unsubscribe_url + r'\4', body) if '[browser_view_url]' in body: body = body.replace('[browser_view_url]', newsletter.get_browser_view_url()) if membership_type: [membership] = recipient.member.membershipdefault_set.exclude( status_detail='archive').order_by('-create_dt')[:1] or [ None ] if membership: # do find and replace urls_dict = membership.get_common_urls() for key in urls_dict.keys(): body = body.replace('[%s]' % key, urls_dict[key]) email_to_send = Email(subject=subject, body=body, sender=email.sender, sender_display=email.sender_display, reply_to=email.reply_to, recipient=recipient.member.email) print(u"Sending to {}".format(str(recipient.member.email))) email_to_send.send(connection=connection) counter += 1 print(u"Newsletter sent to {}".format(str(recipient.member.email))) if newsletter.send_to_email2 and hasattr(recipient.member, 'profile') \ and validate_email(recipient.member.profile.email2): email_to_send.recipient = recipient.member.profile.email2 email_to_send.send(connection=connection) counter += 1 print(u"Newsletter sent to {}".format( str(recipient.member.profile.email2))) if newsletter.send_status == 'sending': newsletter.send_status = 'sent' newsletter.date_email_sent = datetime.datetime.now() elif newsletter.send_status == 'resending': newsletter.send_status = 'resent' newsletter.date_last_resent = datetime.datetime.now() if not newsletter.resend_count: newsletter.resend_count = 0 newsletter.resend_count += 1 newsletter.email_sent_count = counter newsletter.save() if newsletter.nr_data: # save the finish_dt and email_sent_count for the recurring newsletter.nr_data.finish_dt = datetime.datetime.now() newsletter.nr_data.email_sent_count = newsletter.email_sent_count newsletter.nr_data.send_status = newsletter.send_status newsletter.nr_data.save() print("Successfully sent %s newsletter emails." % counter) print("Sending confirmation message to creator...") # send confirmation email subject = "Newsletter Submission Recap for %s" % newsletter.email.subject detail_url = get_setting('site', 'global', 'siteurl') + newsletter.get_absolute_url() params = { 'first_name': newsletter.email.creator.first_name, 'subject': newsletter.email.subject, 'count': counter, 'detail_url': detail_url } body = render_to_string( template_name='newsletters/newsletter_sent_email_body.html', context=params) email = Email(recipient=newsletter.email.sender, subject=subject, body=body) email.send(connection=connection) print("Confirmation email sent.") # add cache clear to resolve issue # TODO: cache clear only to specifies cache.clear() print('Cache cleared!')
def send_newsletter(self, newsletter_id, **kwargs): from tendenci.apps.emails.models import Email from tendenci.apps.newsletters.models import Newsletter from tendenci.apps.site_settings.utils import get_setting from tendenci.apps.base.utils import validate_email from tendenci.apps.newsletters.utils import get_newsletter_connection connection = get_newsletter_connection() if not connection: print('Exiting..Please set up your newsletter email provider before proceeding.') return print("Started sending newsletter...") if newsletter_id == 0: raise CommandError('Newsletter ID is required. Usage: ./manage.py send_newsletter <newsletter_id>') newsletter = Newsletter.objects.filter(pk=int(newsletter_id)) if newsletter.exists(): newsletter = newsletter[0] else: newsletter = None if not newsletter: raise CommandError('You are trying to send a newsletter that does not exist.') if newsletter.send_status == 'queued': newsletter.send_status = 'sending' elif newsletter.send_status == 'sent': newsletter.send_status = 'resending' elif newsletter.send_status == 'resent': newsletter.send_status == 'resending' newsletter.save() recipients = newsletter.get_recipients() email = newsletter.email # replace relative to absolute urls self.site_url = get_setting('site', 'global', 'siteurl') email.body = email.body.replace("src=\"/", "src=\"%s/" % self.site_url) email.body = email.body.replace("href=\"/", "href=\"%s/" % self.site_url) counter = 0 for recipient in recipients: # skip if not a valid email address if not validate_email(recipient.member.email): continue subject = email.subject body = email.body if '[firstname]' in subject: subject = subject.replace('[firstname]', recipient.member.first_name) if '[lastname]' in subject: subject = subject.replace('[lastname]', recipient.member.last_name) if '[username]' in body: body = body.replace('[username]', recipient.member.username) if '[firstname]' in body: body = body.replace('[firstname]', recipient.member.first_name) if '[unsubscribe_url]' in body: #body = body.replace('[unsubscribe_url]', recipient.noninteractive_unsubscribe_url) # The unsubscribe_url link should be something like <a href="[unsubscribe_url]">Unsubscribe</a>. # But it can be messed up sometimes. Let's prevent that from happening. p = r'(href=\")([^\"]*)(\[unsubscribe_url\])(\")' body = re.sub(p, r'\1' + recipient.noninteractive_unsubscribe_url + r'\4', body) if '[browser_view_url]' in body: body = body.replace('[browser_view_url]', newsletter.get_browser_view_url()) email_to_send = Email( subject=subject, body=body, sender=email.sender, sender_display=email.sender_display, reply_to=email.reply_to, recipient=recipient.member.email ) print(u"Sending to {}".format(unicode(recipient.member.email))) email_to_send.send(connection=connection) counter += 1 print(u"Newsletter sent to {}".format(unicode(recipient.member.email))) if newsletter.send_to_email2 and hasattr(recipient.member, 'profile') \ and validate_email(recipient.member.profile.email2): email_to_send.recipient = recipient.member.profile.email2 email_to_send.send(connection=connection) counter += 1 print(u"Newsletter sent to {}".format(unicode(recipient.member.profile.email2))) if newsletter.send_status == 'sending': newsletter.send_status = 'sent' newsletter.date_email_sent = datetime.datetime.now() elif newsletter.send_status == 'resending': newsletter.send_status = 'resent' newsletter.date_last_resent = datetime.datetime.now() if not newsletter.resend_count: newsletter.resend_count = 0 newsletter.resend_count += 1 newsletter.email_sent_count = counter newsletter.save() print("Successfully sent %s newsletter emails." % counter) print("Sending confirmation message to creator...") # send confirmation email subject = "Newsletter Submission Recap for %s" % newsletter.email.subject detail_url = get_setting('site', 'global', 'siteurl') + newsletter.get_absolute_url() params = {'first_name': newsletter.email.creator.first_name, 'subject': newsletter.email.subject, 'count': counter, 'detail_url': detail_url} body = render_to_string( 'newsletters/newsletter_sent_email_body.html', params) email = Email( recipient=newsletter.email.sender, subject=subject, body=body) email.send(connection=connection) print("Confirmation email sent.") # add cache clear to resolve issue # TODO: cache clear only to specifies cache.clear() print('Cache cleared!')
def api_add_rp(data): """Create a recurrring payment account. Accepted format: json Input fields: email - required description - required payment_amount - required billing_period - optional, default to 'month' billing_frequency - optional, default to 1 billing_start_dt - optional, default to today num_days - optional, default to 0 has_trial_period - optional, default to False trial_period_start_dt - optional, default to today trial_period_end_dt - optional, default to today trial_amount - optional, default to 0 Output: rp_id - a recurring payment id result_code """ ALLOWED_FIELES = ( "email", "description", "payment_amount", "billing_period", "billing_frequency", "billing_start_dt", "num_days", "has_trial_period", "trial_period_start_dt", "trial_period_end_dt", "trial_amount", ) from decimal import Decimal from tendenci.apps.base.utils import validate_email import dateutil.parser as dparser from tendenci.apps.imports.utils import get_unique_username email = data.get("email", "") payment_amount = data.get("payment_amount", "") try: payment_amount = Decimal(payment_amount) except: payment_amount = 0 if not all([validate_email(email), data.has_key("description"), payment_amount > 0]): return False, {} rp = RecurringPayment() for key, value in data.items(): if key in ALLOWED_FIELES: if hasattr(rp, key): setattr(rp, key, value) if rp.billing_start_dt: try: rp.billing_start_dt = dparser.parse(rp.billing_start_dt) except: rp.billing_start_dt = datetime.now() else: rp.billing_start_dt = datetime.now() if rp.trial_period_start_dt: try: rp.trial_period_start_dt = dparser.parse(rp.trial_period_start_dt) except: rp.trial_period_start_dt = datetime.now() if rp.trial_period_end_dt: try: rp.trial_period_end_dt = dparser.parse(rp.trial_period_end_dt) except: rp.trial_period_end_dt = datetime.now() rp.payment_amount = Decimal(rp.payment_amount) try: rp.billing_frequency = int(rp.billing_frequency) except: rp.billing_frequency = 1 try: rp.num_days = int(rp.num_days) except: rp.num_days = 1 if rp.has_trial_period in ["True", "1", True, 1] and all([rp.trial_period_start_dt, rp.trial_period_end_dt]): rp.has_trial_period = True else: rp.has_trial_period = False # start the real work # # get or create a user account with this email # users = User.objects.filter(email=email) # if users: # u = users[0] # else: # always create a new user account - This is very important! # it is to prevent hacker from trying to use somebody else's account. u = User() u.email = email u.username = data.get("username", "") if not u.username: u.username = email.split("@")[0] u.username = get_unique_username(u) raw_password = data.get("password", "") if not raw_password: raw_password = User.objects.make_random_password(length=8) u.set_password(raw_password) u.first_name = data.get("first_name", "") u.last_name = data.get("last_name", "") u.is_staff = False u.is_superuser = False u.save() # profile = Profile.objects.create( # user=u, # creator=u, # creator_username=u.username, # owner=u, # owner_username=u.username, # email=u.email # ) # add a recurring payment entry for this user rp.user = u # activate it when payment info is received rp.status_detail = "inactive" rp.save() return True, {"rp_id": rp.id}
def api_rp_setup(data): """Create a recurrring payment account. Accepted format: json Input fields: email - required description - required amount - required cp_id - customer profile id, required pp_id - customer payment profile id, required billing_cycle_start_dt - required billing_cycle_end_dt - required response_str - required login_name login_password url first_name last_name billing_period - optional, default to 'month' billing_frequency - optional, default to 1 billing_start_dt - optional, default to today num_days - optional, default to 0 has_trial_period - optional, default to False trial_period_start_dt - optional, default to today trial_period_end_dt - optional, default to today trial_amount - optional, default to 0 Output: rp_id - a recurring payment id rp_url - url to rp username result_code """ from decimal import Decimal from tendenci.apps.base.utils import validate_email import dateutil.parser as dparser from tendenci.apps.imports.utils import get_unique_username email = data.get("email", "") description = data.get("description", "") url = data.get("url") payment_amount = data.get("amount", "") taxable = data.get("taxable", 0) if taxable in ("True", "true", "1", 1): taxable = 1 else: taxable = 0 try: tax_rate = Decimal(data.get("tax_rate", 0)) if tax_rate > 1: tax_rate = 0 except: tax_rate = 0 tax_exempt = data.get("tax_exempt", 0) if tax_exempt in ("True", "true", "1", 1): tax_exempt = 1 else: tax_exempt = 0 try: payment_amount = Decimal(payment_amount) except: payment_amount = 0 cp_id = data.get("cp_id") pp_id = data.get("pp_id") billing_cycle_start_dt = data.get("billing_cycle_start_dt") if billing_cycle_start_dt: billing_cycle_start_dt = dparser.parse(billing_cycle_start_dt) billing_cycle_end_dt = data.get("billing_cycle_end_dt") if billing_cycle_end_dt: billing_cycle_end_dt = dparser.parse(billing_cycle_end_dt) direct_response_str = data.get("response_str") if not all( [ validate_email(email), description, payment_amount > 0, cp_id, pp_id, billing_cycle_start_dt, billing_cycle_end_dt, direct_response_str, ] ): return False, {} # 1) get or create user username = data.get("login_name") # check if user already exists based on email and username users = User.objects.filter(email=email, username=username) if users: u = users[0] else: # create user account u = User() u.email = email u.username = username if not u.username: u.username = email.split("@")[0] u.username = get_unique_username(u) raw_password = data.get("login_password") if not raw_password: raw_password = User.objects.make_random_password(length=8) u.set_password(raw_password) u.first_name = data.get("first_name", "") u.last_name = data.get("last_name", "") u.is_staff = False u.is_superuser = False u.save() profile = Profile.objects.create( user=u, creator=u, creator_username=u.username, owner=u, owner_username=u.username, email=u.email ) # 2) create a recurring payment account rp = RecurringPayment() rp.user = u rp.description = description rp.url = url rp.payment_amount = payment_amount rp.taxable = taxable rp.tax_rate = tax_rate rp.tax_exempt = tax_exempt rp.customer_profile_id = cp_id rp.billing_start_dt = billing_cycle_start_dt has_trial_period = data.get("has_trial_period") trial_period_start_dt = data.get("trial_period_start_dt") trial_period_end_dt = data.get("trial_period_end_dt") if has_trial_period in ["True", "1", True, 1] and all([trial_period_start_dt, trial_period_end_dt]): rp.has_trial_period = True rp.trial_period_start_dt = dparser.parse(trial_period_start_dt) rp.trial_period_end_dt = dparser.parse(trial_period_end_dt) else: rp.has_trial_period = False rp.status_detail = "active" rp.save() # 3) create a payment profile account payment_profile_exists = PaymentProfile.objects.filter(customer_profile_id=cp_id, payment_profile_id=pp_id).exists() if not payment_profile_exists: PaymentProfile.objects.create( customer_profile_id=cp_id, payment_profile_id=pp_id, owner=u, owner_username=u.username ) # 4) create rp invoice billing_cycle = {"start": billing_cycle_start_dt, "end": billing_cycle_end_dt} rp_invoice = rp.create_invoice(billing_cycle, billing_cycle_start_dt) rp_invoice.invoice.tender(rp.user) # 5) create rp transaction now = datetime.now() payment = Payment() payment.payments_pop_by_invoice_user(rp.user, rp_invoice.invoice, rp_invoice.invoice.guid) payment_transaction = PaymentTransaction( recurring_payment=rp, recurring_payment_invoice=rp_invoice, payment_profile_id=pp_id, trans_type="auth_capture", amount=rp_invoice.invoice.total, status=True, ) payment = payment_update_from_response(payment, direct_response_str) payment.mark_as_paid() payment.save() rp_invoice.invoice.make_payment(rp.user, Decimal(payment.amount)) rp_invoice.invoice.save() rp_invoice.payment_received_dt = now rp_invoice.save() rp.last_payment_received_dt = now rp.num_billing_cycle_completed += 1 rp.save() payment_transaction.payment = payment payment_transaction.result_code = data.get("result_code") payment_transaction.message_code = data.get("message_code") payment_transaction.message_text = data.get("message_text") payment_transaction.save() site_url = get_setting("site", "global", "siteurl") return ( True, { "rp_id": rp.id, "rp_url": "%s%s" % (site_url, reverse("recurring_payment.view_account", args=[rp.id])), "username": rp.user.username, }, )
def send_newsletter(self, newsletter_id, **kwargs): from tendenci.apps.emails.models import Email from tendenci.apps.newsletters.models import Newsletter from tendenci.apps.site_settings.utils import get_setting from tendenci.apps.base.utils import validate_email from tendenci.apps.newsletters.utils import get_newsletter_connection connection = get_newsletter_connection() if not connection: print( 'Exiting..Please set up your newsletter email provider before proceeding.' ) return print("Started sending newsletter...") if newsletter_id == 0: raise CommandError( 'Newsletter ID is required. Usage: ./manage.py send_newsletter <newsletter_id>' ) newsletter = Newsletter.objects.filter(pk=int(newsletter_id)) if newsletter.exists(): newsletter = newsletter[0] else: newsletter = None if not newsletter: raise CommandError( 'You are trying to send a newsletter that does not exist.') if newsletter.send_status == 'queued': newsletter.send_status = 'sending' elif newsletter.send_status == 'sent': newsletter.send_status = 'resending' elif newsletter.send_status == 'resent': newsletter.send_status == 'resending' newsletter.save() recipients = newsletter.get_recipients() email = newsletter.email # replace relative to absolute urls self.site_url = get_setting('site', 'global', 'siteurl') email.body = email.body.replace("src=\"/", "src=\"%s/" % self.site_url) email.body = email.body.replace("href=\"/", "href=\"%s/" % self.site_url) counter = 0 for recipient in recipients: # skip if not a valid email address if not validate_email(recipient.member.email): continue subject = email.subject body = email.body if '[firstname]' in subject: subject = subject.replace('[firstname]', recipient.member.first_name) if '[lastname]' in subject: subject = subject.replace('[lastname]', recipient.member.last_name) if '[username]' in body: body = body.replace('[username]', recipient.member.username) if '[firstname]' in body: body = body.replace('[firstname]', recipient.member.first_name) if '[unsubscribe_url]' in body: #body = body.replace('[unsubscribe_url]', recipient.noninteractive_unsubscribe_url) # The unsubscribe_url link should be something like <a href="[unsubscribe_url]">Unsubscribe</a>. # But it can be messed up sometimes. Let's prevent that from happening. p = r'(href=\")([^\"]*)(\[unsubscribe_url\])(\")' body = re.sub( p, r'\1' + recipient.noninteractive_unsubscribe_url + r'\4', body) if '[browser_view_url]' in body: body = body.replace('[browser_view_url]', newsletter.get_browser_view_url()) email_to_send = Email(subject=subject, body=body, sender=email.sender, sender_display=email.sender_display, reply_to=email.reply_to, recipient=recipient.member.email) print("Sending to %s" % recipient.member.email) email_to_send.send(connection=connection) counter += 1 print("Newsletter sent to %s" % recipient.member.email) if newsletter.send_to_email2 and hasattr(recipient.member, 'profile') \ and validate_email(recipient.member.profile.email2): email_to_send.recipient = recipient.member.profile.email2 email_to_send.send(connection=connection) counter += 1 print("Newsletter sent to %s" % recipient.member.profile.email2) if newsletter.send_status == 'sending': newsletter.send_status = 'sent' newsletter.date_email_sent = datetime.datetime.now() elif newsletter.send_status == 'resending': newsletter.send_status = 'resent' newsletter.date_last_resent = datetime.datetime.now() if not newsletter.resend_count: newsletter.resend_count = 0 newsletter.resend_count += 1 newsletter.email_sent_count = counter newsletter.save() print("Successfully sent %s newsletter emails." % counter) print("Sending confirmation message to creator...") # send confirmation email subject = "Newsletter Submission Recap for %s" % newsletter.email.subject detail_url = get_setting('site', 'global', 'siteurl') + newsletter.get_absolute_url() params = { 'first_name': newsletter.email.creator.first_name, 'subject': newsletter.email.subject, 'count': counter, 'detail_url': detail_url } body = render_to_string('newsletters/newsletter_sent_email_body.html', params) email = Email(recipient=newsletter.email.sender, subject=subject, body=body) email.send(connection=connection) print("Confirmation email sent.") # add cache clear to resolve issue # TODO: cache clear only to specifies cache.clear() print('Cache cleared!')
def do_user_import(request, user, user_object_dict, setting_dict): """ the real work is here - do the insert or update """ insert = not bool(user) # insert or update user = user or User() # existing or new user override = setting_dict['override'] # update ALL fields # insert/update user for field in user_field_names: if field == 'password' or field == 'username' or \ (not insert and field in setting_dict['key']): continue if field in user_object_dict: if override: setattr(user, field, user_object_dict[field]) else: # fill out the blank field only if getattr(user, field) == '': setattr(user, field, user_object_dict[field]) if insert: if 'username' in user_object_dict: # set username user.username = user_object_dict['username'] # generate if not username user.username = get_unique_username(user) if 'password' in user_object_dict and (insert or override): user.set_password(user_object_dict['password']) if not user.password: user.set_password(User.objects.make_random_password(length=8)) user.is_active = bool(setting_dict['interactive']) if not bool(validate_email(user.email)): user.email = '' # if not valid; empty it out # loop through user properties; truncate at max_length for key, value in user.__dict__.items(): max_length = 90 try: max_length = User._meta.get_field(key).max_length except FieldDoesNotExist: max_length = None if max_length: # truncate per max_length field attribute setattr(user, key, value[:max_length]) # username and email required if user.username and user.email: # insert/update record if insert: user.save(force_insert=True) else: user.save(force_update=True) try: # get or create profile = user.profile except Profile.DoesNotExist: profile = Profile.objects.create(user=user, creator=request.user, creator_username=request.user.username, owner=request.user, owner_username=request.user.username, ) for field in profile_field_names: if field in user_object_dict: if override: setattr(profile, field, user_object_dict[field]) else: # fill out the blank field only if getattr(profile, field) == '': setattr(profile, field, user_object_dict[field]) profile.save() # add to group if setting_dict['group']: try: gm = GroupMembership.objects.get(group=setting_dict['group'], member=user) except GroupMembership.DoesNotExist: gm = GroupMembership() gm.member = user gm.group = setting_dict['group'] gm.creator_id = request.user.id gm.creator_username = request.user.username gm.owner_id = request.user.id gm.owner_username = request.user.username gm.status = 1 gm.status_detail = 'active' gm.save() return user
def api_add_rp(data): """Create a recurrring payment account. Accepted format: json Input fields: email - required description - required payment_amount - required billing_period - optional, default to 'month' billing_frequency - optional, default to 1 billing_start_dt - optional, default to today num_days - optional, default to 0 has_trial_period - optional, default to False trial_period_start_dt - optional, default to today trial_period_end_dt - optional, default to today trial_amount - optional, default to 0 Output: rp_id - a recurring payment id result_code """ ALLOWED_FIELES = ('email', 'description', 'payment_amount', 'billing_period', 'billing_frequency', 'billing_start_dt', 'num_days', 'has_trial_period', 'trial_period_start_dt', 'trial_period_end_dt', 'trial_amount', ) from tendenci.apps.base.utils import validate_email import dateutil.parser as dparser from tendenci.apps.imports.utils import get_unique_username email = data.get('email', '') payment_amount = data.get('payment_amount', '') try: payment_amount = Decimal(payment_amount) except: payment_amount = 0 if not all([validate_email(email), 'description' in data, payment_amount>0]): return False, {} rp = RecurringPayment() for key, value in data.items(): if key in ALLOWED_FIELES: if hasattr(rp, key): setattr(rp, key, value) if rp.billing_start_dt: try: rp.billing_start_dt = dparser.parse(rp.billing_start_dt) except: rp.billing_start_dt = datetime.now() else: rp.billing_start_dt = datetime.now() if rp.trial_period_start_dt: try: rp.trial_period_start_dt = dparser.parse(rp.trial_period_start_dt) except: rp.trial_period_start_dt = datetime.now() if rp.trial_period_end_dt: try: rp.trial_period_end_dt = dparser.parse(rp.trial_period_end_dt) except: rp.trial_period_end_dt = datetime.now() rp.payment_amount = Decimal(rp.payment_amount) try: rp.billing_frequency = int(rp.billing_frequency) except: rp.billing_frequency = 1 try: rp.num_days = int(rp.num_days) except: rp.num_days = 1 if rp.has_trial_period in ['True', '1', True, 1] and all([rp.trial_period_start_dt, rp.trial_period_end_dt]): rp.has_trial_period = True else: rp.has_trial_period = False # start the real work # # get or create a user account with this email # users = User.objects.filter(email=email) # if users: # u = users[0] # else: # always create a new user account - This is very important! # it is to prevent hacker from trying to use somebody else's account. u = User() u.email=email u.username = data.get('username', '') if not u.username: u.username = email.split('@')[0] u.username = get_unique_username(u) raw_password = data.get('password', '') if not raw_password: raw_password = User.objects.make_random_password(length=8) u.set_password(raw_password) u.first_name = data.get('first_name', '') u.last_name = data.get('last_name', '') u.is_staff = False u.is_superuser = False u.save() # profile = Profile.objects.create( # user=u, # creator=u, # creator_username=u.username, # owner=u, # owner_username=u.username, # email=u.email # ) # add a recurring payment entry for this user rp.user = u # activate it when payment info is received rp.status_detail = 'inactive' rp.save() return True, {'rp_id': rp.id}
def do_user_import(request, user, user_object_dict, setting_dict): """ the real work is here - do the insert or update """ insert = not bool(user) # insert or update user = user or User() # existing or new user override = setting_dict['override'] # update ALL fields # insert/update user for field in user_field_names: if field == 'password' or field == 'username' or \ (not insert and field in setting_dict['key']): continue if field in user_object_dict: if override: setattr(user, field, user_object_dict[field]) else: # fill out the blank field only if getattr(user, field) == '': setattr(user, field, user_object_dict[field]) if insert: if 'username' in user_object_dict: # set username user.username = user_object_dict['username'] # generate if not username user.username = get_unique_username(user) if 'password' in user_object_dict and (insert or override): user.set_password(user_object_dict['password']) if not user.password: user.set_password(User.objects.make_random_password(length=8)) user.is_active = bool(setting_dict['interactive']) if not bool(validate_email(user.email)): user.email = '' # if not valid; empty it out # loop through user properties; truncate at max_length for key, value in user.__dict__.items(): max_length = 90 try: max_length = User._meta.get_field_by_name(key)[0].max_length except FieldDoesNotExist: max_length = None if max_length: # truncate per max_length field attribute setattr(user, key, value[:max_length]) # username and email required if user.username and user.email: # insert/update record if insert: user.save(force_insert=True) else: user.save(force_update=True) try: # get or create profile = user.profile except Profile.DoesNotExist: profile = Profile.objects.create(user=user, creator=request.user, creator_username=request.user.username, owner=request.user, owner_username=request.user.username, ) for field in profile_field_names: if field in user_object_dict: if override: setattr(profile, field, user_object_dict[field]) else: # fill out the blank field only if getattr(profile, field) == '': setattr(profile, field, user_object_dict[field]) profile.save() # add to group if setting_dict['group']: try: gm = GroupMembership.objects.get(group=setting_dict['group'], member=user) except GroupMembership.DoesNotExist: gm = GroupMembership() gm.member = user gm.group = setting_dict['group'] gm.creator_id = request.user.id gm.creator_username = request.user.username gm.owner_id = request.user.id gm.owner_username = request.user.username gm.status = 1 gm.status_detail = 'active' gm.save() return user
def clean(self): cleaned_data = self.cleaned_data field_function = cleaned_data.get("field_function") choices = cleaned_data.get("choices") field_type = cleaned_data.get("field_type") required = cleaned_data.get("required") if field_function == "GroupSubscription": if field_type != "BooleanField": raise forms.ValidationError(_("This field's function requires Checkbox as a field type")) if not choices: raise forms.ValidationError(_("This field's function requires at least 1 group specified.")) else: for val in choices.split(','): try: g = Group.objects.get(name=val.strip()) if not g.allow_self_add: raise forms.ValidationError(_("The group \"%(val)s\" does not allow self-add." % { 'val' : val })) except Group.DoesNotExist: raise forms.ValidationError(_("The group \"%(val)s\" does not exist" % { 'val' : val })) if field_function == "GroupSubscriptionAuto": # field_type doesn't matter since this field shouldn't be rendered anyway. if visible: raise forms.ValidationError(_("This field must not be visible to users.")) if not choices: raise forms.ValidationError(_("This field's function requires at least 1 group specified.")) else: for val in choices.split(','): try: g = Group.objects.get(name=val.strip()) if not g.allow_self_add: raise forms.ValidationError(_("The group \"%(val)s\" does not allow self-add." % { 'val' : val })) except Group.DoesNotExist: raise forms.ValidationError(_("The group \"%(val)s\" does not exist" % { 'val' : val })) if field_function == "Recipients": if (field_type != "MultipleChoiceField/django.forms.CheckboxSelectMultiple" and field_type != "MultipleChoiceField" and field_type != "BooleanField" and field_type != "ChoiceField"): raise forms.ValidationError(_("The \"Email to Recipients\" function requires Multi-select - Checkboxes " + "or Multi-select - Select Many as field type")) if field_type == "BooleanField": if not choices: raise forms.ValidationError(_("The \"Email to Recipients\" function requires at least 1 email specified.")) else: for val in choices.split(','): if not validate_email(val.strip()): raise forms.ValidationError(_("\"%(val)s\" is not a valid email address" % {'val':val})) else: if not choices: raise forms.ValidationError(_("The \"Email to Recipients\" function requires at least 1 choice specified.")) else: for val in choices.split(','): val = val.split(':') if len(val) < 2: raise forms.ValidationError(_("The \"Email to Recipients\" function requires choices to be in the following format: <choice_label>:<email_address>.")) if not validate_email(val[1].strip()): raise forms.ValidationError(_("\"%(val)s\" is not a valid email address" % {'val':val[1]})) if field_function != None and field_function.startswith("Email"): if field_type != "CharField": raise forms.ValidationError(_("This field's function requires Text as a field type")) #unrequire the display only fields if field_type == "CharField/tendenci.apps.forms_builder.forms.widgets.Description": cleaned_data['required'] = False elif field_type == "CharField/tendenci.apps.forms_builder.forms.widgets.Header": cleaned_data['required'] = False return cleaned_data
def send(self, fail_silently=False, **kwargs): recipient_list = [] recipient_bcc_list = [] headers = kwargs.get('headers', {}) attachments = kwargs.get('attachments', []) if isinstance(self.recipient, str): recipient_list = self.recipient.split(',') recipient_list = [ recipient.strip() for recipient in recipient_list if recipient.strip() != '' ] else: recipient_list = list(self.recipient) if isinstance(self.recipient_cc, str): recipient_cc_list = self.recipient_cc.split(',') recipient_cc_list = [ recipient_cc.strip() for recipient_cc in recipient_cc_list if recipient_cc.strip() != '' ] recipient_list += recipient_cc_list else: recipient_list += list(self.recipient_cc) if isinstance(self.recipient_bcc, str): recipient_bcc_list = self.recipient_bcc.split(',') recipient_bcc_list = [ recipient_bcc.strip() for recipient_bcc in recipient_bcc_list if recipient_bcc.strip() != '' ] else: recipient_bcc_list = list(self.recipient_bcc) if self.reply_to: headers['Reply-To'] = self.reply_to if not self.sender: self.sender = get_setting( 'site', 'global', 'siteemailnoreplyaddress') or settings.DEFAULT_FROM_EMAIL if self.sender_display: # Add quotes around display name to prevent errors on sending # When display name contains comma or other control characters, headers['From'] = '"%s" <%s>' % (self.sender_display, self.sender) if self.priority and self.priority == 1: headers['X-Priority'] = '1' headers['X-MSMail-Priority'] = 'High' # remove blocked from recipient_list and recipient_bcc_list temp_recipient_list = copy.copy(recipient_list) for e in temp_recipient_list: if self.is_blocked(e) or not validate_email(e): recipient_list.remove(e) temp_recipient_bcc_list = copy.copy(recipient_bcc_list) for e in temp_recipient_bcc_list: if self.is_blocked(e) or not validate_email(e): recipient_bcc_list.remove(e) if recipient_list or recipient_bcc_list: msg = EmailMessage(self.subject, add_tendenci_footer( self.body, content_type=self.content_type), self.sender, recipient_list, recipient_bcc_list, headers=headers, connection=kwargs.get('connection', None)) if self.content_type == 'html' or self.content_type == self.CONTENT_TYPE_HTML: msg.content_subtype = 'html' if attachments: for name, value in attachments: msg.attach(name, value) msg.send(fail_silently=fail_silently)