def handle_label(self, label, **options): mail_cnt = 0 for user in CustomUser.objects.all(): mail_address = user.email if not mail_address: continue relevant_proposals = Proposal.objects.all() dt = None if user.daily_digest and label=='daily': dt = 1 if user.weekly_digest and label=='weekly': dt = 7 if dt is None: continue relevant_proposals = relevant_proposals.filter(voting_date__gte=timezone.now()-timedelta(days=dt), voting_date__lte=timezone.now()) | \ relevant_proposals.filter(expire_date__gte=timezone.now()-timedelta(days=dt), expire_date__lte=timezone.now()) | \ relevant_proposals.filter(create_date__gte=timezone.now()-timedelta(days=dt), create_date__lte=timezone.now()) if user.send_new: new_proposals = relevant_proposals.filter(voting_stage='DISCUSSION') else: new_proposals = None if user.send_voting: voting_proposals = relevant_proposals.filter(voting_stage='VOTING') else: voting_proposals = None if user.send_finished: finished_proposals = relevant_proposals.filter(voting_stage__in=['APPROVED','REJECTED']) else: finished_proposals = None if user.send_favorites_and_voted: new_proposals = None voting_proposals = voting_proposals.filter(favorited_by=user) finished_proposals = finished_proposals.filter(favorited_by=user) | finished_proposals.filter(proposal_votes__user=user) if not new_proposals and not voting_proposals and not finished_proposals: continue #no need to send a mail if there's nothing in it unsubscribecode = UnsubscribeCode(user=user, code=random.SystemRandom().getrandbits(64)) unsubscribecode.save() text = render_to_string('mails/digestmail.html', dictionary={ 'new_proposals':new_proposals, 'voting_proposals':voting_proposals, 'finished_proposals':finished_proposals, 'unsubscribecode':unsubscribecode, 'label':label, 'user':user }) print "mail sent to:",mail_address try: #pass send_mail('GetOpinionated', text, settings.DEFAULT_FROM_EMAIL, [mail_address], fail_silently=False) except SMTPRecipientsRefused: print "refused" continue mail_cnt += 1 self.stdout.write('Successfully sent the mails:\n') self.stdout.write('{} mails sent\n'.format(mail_cnt))
def handle(self, *args, **options): ## parse arguments try: # get arguments assert 1 <= len(args) <= 2, "One or two arguments are required for this command" filepath = args[0] groupname = args[1] if len(args) > 1 else None # check filepath assert os.path.exists(filepath), "email file not found" # parse file emails = [l.strip() for l in open(filepath).readlines()] # quick check on emails for email in emails: assert '@' in email, "Not every email has an @ (like {})".format(email) for char in "(){}[], ": assert char not in email, "Illegal character ({}) in email ({})".format(char, email) # check for doubles assert len(set(emails)) == len(emails), 'There are doubles in the emails list' # check groupname if groupname: try: group = Group.objects.get(name=groupname) except Group.DoesNotExist: raise AssertionError('Group name does not exist') except AssertionError as e: return self.stderr.write("Error parsing arguments: {}\n\n".format(e)) ### Part 1: create new accounts ### for email in emails: if User.objects.filter(email=email).count() == 0: ## generate user data username = email.split('@')[0][0:-3] assert username, 'illegal email address: {}'.format(email) while User.objects.filter(username=username).count() != 0: username += '1' first_name = username last_name = "" ## create user self.stdout.write("Creating account for {} with username {}\n".format(email, username)) user = CustomUser.objects.create_user(username) user.email = email user.first_name = first_name user.last_name = last_name #mail user logincode = LoginCode(user=user, code=random.SystemRandom().getrandbits(128)) logincode.save() unsubscribecode = UnsubscribeCode(user=user, code=random.SystemRandom().getrandbits(64)) unsubscribecode.save() text = render_to_string('mails/invite-mail.html', dictionary={ 'logincode':logincode, 'unsubscribecode':unsubscribecode, 'user':user }) try: #pass send_mail('GetOpinionated: vote online for the {}'.format(settings.DEFAULT_DOCUMENT_DESCRIPTION_LONG), text, settings.DEFAULT_FROM_EMAIL, [email], fail_silently=False) user.save() print "mail sent to:" , email except SMTPRecipientsRefused: print "refused" continue else: self.stdout.write("Account already exists for {}\n".format(email)) ### Part 2: add users to group ### if groupname: self.stdout.write("\nAdding all users in list to group '{}'...\n".format(groupname)) for email in emails: user = User.objects.get(email=email) group.user_set.add(user) self.stdout.write("Done\n\n".format(groupname)) self.stdout.write("Done\n\n".format(groupname))
def handle(self, *args, **options): ## parse arguments try: # get arguments assert 1 <= len(args) <= 2, "One or two arguments are required for this command" filepath = args[0] groupname = args[1] if len(args) > 1 else None # check filepath assert os.path.exists(filepath), "email file not found" # parse file emails = [l.strip() for l in open(filepath).readlines()] # quick check on emails for email in emails: assert '@' in email, "Not every email has an @ (like {})".format(email) for char in "(){}[], ": assert char not in email, "Illegal character ({}) in email ({})".format(char, email) # check for doubles assert len(set(emails)) == len(emails), 'There are doubles in the emails list' # check groupname if groupname: try: group = Group.objects.get(name=groupname) except Group.DoesNotExist: raise AssertionError('Group name does not exist') except AssertionError as e: return self.stderr.write("Error parsing arguments: {}\n\n".format(e)) ### Part 1: create new accounts ### for email in emails: if User.objects.filter(email=email).count() == 0: ## generate user data username = email.split('@')[0][0:-3] assert username, 'illegal email address: {}'.format(email) while User.objects.filter(username=username).count() != 0: username += '1' first_name = username last_name = "" ## create user self.stdout.write("Creating account for {} with username {}\n".format(email, username)) user = CustomUser.objects.create_user(username) user.email = email user.first_name = first_name user.last_name = last_name #mail user logincode = LoginCode(user=user, code=random.SystemRandom().getrandbits(128)) logincode.save() unsubscribecode = UnsubscribeCode(user=user, code=random.SystemRandom().getrandbits(64)) unsubscribecode.save() text = render_to_string('mails/invite-mail.html', dictionary={ 'logincode':logincode, 'unsubscribecode':unsubscribecode, 'user':user }) try: #pass send_mail('GetOpinionated: vote online for the {}'.format(settings.DEFAULT_DOCUMENT_DESCRIPTION_LONG), text, settings.DEFAULT_FROM_EMAIL, [email], fail_silently=False) user.save() print "mail sent to:",email except SMTPRecipientsRefused: print "refused" continue else: self.stdout.write("Account already exists for {}\n".format(email)) ### Part 2: add users to group ### if groupname: self.stdout.write("\nAdding all users in list to group '{}'...\n".format(groupname)) for email in emails: user = User.objects.get(email=email) group.user_set.add(user) self.stdout.write("Done\n\n".format(groupname)) self.stdout.write("Done\n\n".format(groupname))
def handle_label(self, label, **options): mail_cnt = 0 for user in CustomUser.objects.all(): mail_address = user.email if not mail_address: continue relevant_proposals = Proposal.objects.all() dt = None if user.daily_digest and label == 'daily': dt = 1 if user.weekly_digest and label == 'weekly': dt = 7 if dt is None: continue relevant_proposals = relevant_proposals.filter(voting_date__gte=timezone.now()-timedelta(days=dt), voting_date__lte=timezone.now()) | \ relevant_proposals.filter(expire_date__gte=timezone.now()-timedelta(days=dt), expire_date__lte=timezone.now()) | \ relevant_proposals.filter(create_date__gte=timezone.now()-timedelta(days=dt), create_date__lte=timezone.now()) if user.send_new: new_proposals = relevant_proposals.filter( voting_stage='DISCUSSION') else: new_proposals = None if user.send_voting: voting_proposals = relevant_proposals.filter( voting_stage='VOTING') else: voting_proposals = None if user.send_finished: finished_proposals = relevant_proposals.filter( voting_stage__in=['APPROVED', 'REJECTED']) else: finished_proposals = None if user.send_favorites_and_voted: new_proposals = None voting_proposals = voting_proposals.filter(favorited_by=user) finished_proposals = finished_proposals.filter( favorited_by=user) | finished_proposals.filter( proposal_votes__user=user) if not new_proposals and not voting_proposals and not finished_proposals: continue #no need to send a mail if there's nothing in it unsubscribecode = UnsubscribeCode( user=user, code=random.SystemRandom().getrandbits(64)) unsubscribecode.save() text = render_to_string('mails/digestmail.html', dictionary={ 'new_proposals': new_proposals, 'voting_proposals': voting_proposals, 'finished_proposals': finished_proposals, 'unsubscribecode': unsubscribecode, 'label': label, 'user': user }) print "mail sent to:", mail_address try: #pass send_mail('GetOpinionated', text, settings.DEFAULT_FROM_EMAIL, [mail_address], fail_silently=False) except SMTPRecipientsRefused: print "refused" continue mail_cnt += 1 self.stdout.write('Successfully sent the mails:\n') self.stdout.write('{} mails sent\n'.format(mail_cnt))
def handle_label(self, mail_frequency, **options): # argument checks assert mail_frequency in ["IMMEDIATELY", "DAILY", "WEEKLY"] mail_cnt = 0 for user in CustomUser.objects.filter(mail_frequency=mail_frequency).all(): # check if valid email if not user.email or "@" not in user.email: continue ### get all relevant events from queue ### # pop personal events personal_event_listeners = [] if user.mail_when_related_event: for item in PersonalEventEmailQueue.objects.filter(event_listener__user=user): event_listener = item.event_listener if not event_listener.seen_by_user: event_listener.event = event_listener.event.cast() personal_event_listeners.append(event_listener) item.delete() # get global events global_events = [] for item in GlobalEventEmailQueue.objects.all(): if user not in item.already_mailed_users.all(): event = item.event.cast() eligible_event = False if isinstance(event, ProposalLifeCycleEvent): if user.mail_when_voting_stage_change == "ALWAYS": eligible_event = True elif user.mail_when_voting_stage_change == "I_REACTED": eligible_event = ( user in event.get_listening_users() and event.new_voting_stage != "DISCUSSION" ) elif user.mail_when_voting_stage_change == "I_STARRED": eligible_event = ( user in event.proposal.favorited_by.all() and event.new_voting_stage != "DISCUSSION" ) elif user.mail_when_voting_stage_change == "NEVER": eligible_event = False else: raise NotImplementedError( "Global events of type {} are not supported by the mailer yet.".format(type(event)) ) if eligible_event: global_events.append(event) item.already_mailed_users.add(user) # filter duplicate events between personal events and global events personal_event_listeners = [p for p in personal_event_listeners if p.event not in global_events] # filter very old events def check_and_warn_old_event(event): if event.date_created < timezone.now() - timedelta(days=8): self.stderr.write("Warning: found old event: {}\n".format(event)) return True return False personal_event_listeners = [p for p in personal_event_listeners if not check_and_warn_old_event(p.event)] global_events = [event for event in global_events if not check_and_warn_old_event(event)] ### convert events to bundledevents ### bundledevents = [] # add personal events bundledevents += listeners_to_bundled_events(personal_event_listeners) # add global events bundledevents += [ BundledEvent(events=[event], unseen_events=[], reading_user=user) for event in global_events ] ### check if there are events to email about ### if not bundledevents: continue ### get email text ### unsubscribecode = UnsubscribeCode(user=user, code=random.SystemRandom().getrandbits(64)) unsubscribecode.save() mail_text = render_to_string( "mails/digestmail.html", dictionary={ "DOMAIN_NAME": settings.DOMAIN_NAME, "unsubscribecode": unsubscribecode, "mail_frequency": self._HUMAN_READABLE_MAIL_FREQUENCY[mail_frequency], "bundledevents": bundledevents, "user": user, }, ) ### send mail ### try: send_mail("GetOpinionated", mail_text, settings.DEFAULT_FROM_EMAIL, [user.email], fail_silently=False) self.stdout.write("mail sent to {}\n".format(user.email)) mail_cnt += 1 except SMTPRecipientsRefused as e: self.stderr.write("mail refused to {}: {}\n".format(user.email, e)) # clean up old entries of GlobalEventEmailQueue GlobalEventEmailQueue.objects.filter(event__date_created__lte=timezone.now() - timedelta(days=7.5)).delete() # wrap up self.stdout.write("Successfully sent the mails:\n") self.stdout.write("{} mails sent\n".format(mail_cnt))
def handle_label(self, mail_frequency, **options): # argument checks assert mail_frequency in ['IMMEDIATELY', 'DAILY', 'WEEKLY'] mail_cnt = 0 for user in CustomUser.objects.filter( mail_frequency=mail_frequency).all(): # check if valid email if not user.email or '@' not in user.email: continue ### get all relevant events from queue ### # pop personal events personal_event_listeners = [] if user.mail_when_related_event: for item in PersonalEventEmailQueue.objects.filter( event_listener__user=user): event_listener = item.event_listener if not event_listener.seen_by_user: event_listener.event = event_listener.event.cast() personal_event_listeners.append(event_listener) item.delete() # get global events global_events = [] for item in GlobalEventEmailQueue.objects.all(): if user not in item.already_mailed_users.all(): event = item.event.cast() eligible_event = False if isinstance(event, ProposalLifeCycleEvent): if user.mail_when_voting_stage_change == 'ALWAYS': eligible_event = True elif user.mail_when_voting_stage_change == 'I_REACTED': eligible_event = user in event.get_listening_users( ) and event.new_voting_stage != 'DISCUSSION' elif user.mail_when_voting_stage_change == 'I_STARRED': eligible_event = user in event.proposal.favorited_by.all( ) and event.new_voting_stage != 'DISCUSSION' elif user.mail_when_voting_stage_change == 'NEVER': eligible_event = False else: raise NotImplementedError( "Global events of type {} are not supported by the mailer yet." .format(type(event))) if eligible_event: global_events.append(event) item.already_mailed_users.add(user) # filter duplicate events between personal events and global events personal_event_listeners = [ p for p in personal_event_listeners if p.event not in global_events ] # filter very old events def check_and_warn_old_event(event): if event.date_created < timezone.now() - timedelta(days=8): self.stderr.write( "Warning: found old event: {}\n".format(event)) return True return False personal_event_listeners = [ p for p in personal_event_listeners if not check_and_warn_old_event(p.event) ] global_events = [ event for event in global_events if not check_and_warn_old_event(event) ] ### convert events to bundledevents ### bundledevents = [] # add personal events bundledevents += listeners_to_bundled_events( personal_event_listeners) # add global events bundledevents += [ BundledEvent(events=[event], unseen_events=[], reading_user=user) for event in global_events ] ### check if there are events to email about ### if not bundledevents: continue ### get email text ### unsubscribecode = UnsubscribeCode( user=user, code=random.SystemRandom().getrandbits(64)) unsubscribecode.save() mail_text = render_to_string( 'mails/digestmail.html', dictionary={ 'DOMAIN_NAME': settings.DOMAIN_NAME, 'unsubscribecode': unsubscribecode, 'mail_frequency': self._HUMAN_READABLE_MAIL_FREQUENCY[mail_frequency], 'bundledevents': bundledevents, 'user': user, }) ### send mail ### try: send_mail('GetOpinionated', mail_text, settings.DEFAULT_FROM_EMAIL, [user.email], fail_silently=False) self.stdout.write("mail sent to {}\n".format(user.email)) mail_cnt += 1 except SMTPRecipientsRefused as e: self.stderr.write("mail refused to {}: {}\n".format( user.email, e)) # clean up old entries of GlobalEventEmailQueue GlobalEventEmailQueue.objects.filter( event__date_created__lte=timezone.now() - timedelta(days=7.5)).delete() # wrap up self.stdout.write('Successfully sent the mails:\n') self.stdout.write('{} mails sent\n'.format(mail_cnt))