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))