def reply_to_report(request, report_id): report = get_object_or_404(Report, pk=report_id) # Verify if this is from an author: is_author = report.submission.authors.filter(user=request.user).exists() form = CommentForm(request.POST or None, request.FILES or None, is_report_comment=True) if form.is_valid(): newcomment = form.save(commit=False) newcomment.content_object = report newcomment.is_author_reply = is_author newcomment.author = request.user.contributor newcomment.save() newcomment.grant_permissions() mail_sender = DirectMailUtil('eic/inform_eic_comment_received', comment=newcomment) mail_sender.send_mail() mail_sender = DirectMailUtil( 'commenters/inform_commenter_comment_received', comment=newcomment) mail_sender.send_mail() messages.success( request, '<h3>Thank you for contributing a Reply</h3>' 'It will soon be vetted by an Editor.') return redirect(newcomment.content_object.get_absolute_url()) context = {'report': report, 'is_author': is_author, 'form': form} return render(request, 'comments/reply_to_report.html', context)
def save(self, commit=True): self.instance.status = PUBLICATION_PREPUBLISHED if commit: self.instance.save() mail_sender = DirectMailUtil('publication_ready', instance=self.instance) mail_sender.send_mail() return self.instance
def test_non_rendered_database_entries(self): """Test non rendered mail database entries are correct after sending email.""" with self.settings( EMAIL_BACKEND='mails.backends.filebased.ModelEmailBackend'): mail_util = DirectMailUtil( 'tests/test_mail_code_1', subject='Test Subject Unique For Testing 93872', recipient_list=['*****@*****.**'], bcc=['*****@*****.**'], from_email='*****@*****.**', from_name='Test Name', weird_variable_name='John Doe') self.assertFalse(mail_util.engine._mail_sent) mail_util.send_mail() self.assertTrue(mail_util.engine._mail_sent) mail_log = MailLog.objects.last() self.assertFalse(mail_log.processed) self.assertEqual(mail_log.status, MAIL_NOT_RENDERED) self.assertEqual(mail_log.mail_code, 'tests/test_mail_code_1') self.assertEqual(mail_log.subject, 'Test Subject Unique For Testing 93872') self.assertEqual(mail_log.body, '') self.assertEqual(mail_log.body_html, '') self.assertIn('*****@*****.**', mail_log.to_recipients) self.assertIn('*****@*****.**', mail_log.bcc_recipients) self.assertEqual('Test Name <*****@*****.**>', mail_log.from_email)
def form_valid(self, form): self.object = form.save() mail_sender = DirectMailUtil('careers/jobapplication_ack', delayed_processing=False, bcc=[ '*****@*****.**', ], jobapplication=self.object) mail_sender.send_mail() return redirect(self.get_success_url())
def send_invitation(self): """Send invitation and update status.""" if self.status != STATUS_PREASSIGNED: # Only send if status is appropriate to prevent double sending return False # Send mail mail_sender = DirectMailUtil(mail_code='eic/assignment_request', assignment=self) mail_sender.send_mail() EditorialAssignment.objects.filter(id=self.id).update( date_invited=timezone.now(), status=STATUS_INVITED) return True
def test_management_command(self): """Test if management command does the updating of the mail.""" with self.settings( EMAIL_BACKEND='mails.backends.filebased.ModelEmailBackend'): mail_util = DirectMailUtil('tests/test_mail_code_1', object=self.submission) mail_util.send_mail() mail_log = MailLog.objects.last() call_command('send_mails', id=mail_log.id) mail_log.refresh_from_db() self.assertNotEqual(mail_log.body, '') self.assertNotEqual(mail_log.body_html, '') self.assertEqual(mail_log.status, MAIL_SENT)
def test_rendered_database_entries(self): """Test rendered mail database entries are correct after sending email.""" with self.settings( EMAIL_BACKEND='mails.backends.filebased.ModelEmailBackend'): mail_util = DirectMailUtil( 'tests/test_mail_code_1', delayed_processing=False, subject='Test Subject Unique For Testing 786234' ) # Use weird subject to confirm right instance. mail_util.send_mail() mail_log = MailLog.objects.last() self.assertEqual(mail_log.status, MAIL_RENDERED) self.assertEqual(mail_log.subject, 'Test Subject Unique For Testing 786234') self.assertNotEqual(mail_log.body, '') self.assertNotEqual(mail_log.body_html, '')
def reinvite_referees(self, referees): """ Duplicate and reset RefereeInvitations and send `reinvite` mail. referees - (list of) RefereeInvitation instances """ from mails.utils import DirectMailUtil # SubmissionUtils.load({'submission': self._submission}) for referee in referees: invitation = referee invitation.pk = None # Duplicate, do not remove the old invitation invitation.submission = self._submission invitation.reset_content() invitation.date_invited = timezone.now() invitation.save() mail_sender = DirectMailUtil( 'referees/reinvite_contributor_to_referee', invitation=invitation) mail_sender.send_mail()
def reply_to_comment(request, comment_id): comment = get_object_or_404(Comment, pk=comment_id) # Verify if this is from an author: related_object = comment.content_object if isinstance(related_object, Submission) or isinstance( related_object, Commentary): is_author = related_object.authors.filter( id=request.user.contributor.id).exists() elif isinstance(related_object, Report): is_author = related_object.submission.authors.filter( id=request.user.contributor.id).exists() elif isinstance(related_object, ThesisLink): # ThesisLink is_author = related_object.author == request.user.contributor else: # No idea what this could be, but just to be sure is_author = related_object.author == request.user.contributor form = CommentForm(request.POST or None, request.FILES or None) if form.is_valid(): newcomment = form.save(commit=False) newcomment.content_object = comment newcomment.is_author_reply = is_author newcomment.author = request.user.contributor newcomment.save() newcomment.grant_permissions() mail_sender = DirectMailUtil( 'commenters/inform_commenter_comment_received', comment=newcomment) mail_sender.send_mail() if isinstance(newcomment.core_content_object, Submission): mail_sender = DirectMailUtil('eic/inform_eic_comment_received', comment=newcomment) mail_sender.send_mail() messages.success( request, '<h3>Thank you for contributing a Reply</h3>' 'It will soon be vetted by an Editor.') return redirect(newcomment.content_object.get_absolute_url()) context = {'comment': comment, 'is_author': is_author, 'form': form} return render(request, 'comments/reply_to_comment.html', context)
def verify_signature(request, slug, key): petition = get_object_or_404(Petition, slug=slug) try: signature = petition.petition_signatories.get(verification_key=key) except PetitionSignatory.DoesNotExist: messages.warning(request, ('Unknown signature key.')) return redirect(petition.get_absolute_url()) if not signature.verified: # Slight reduction of db write-use signature.verified = True signature.save() messages.success(request, ('<h3>Many thanks for confirming your signature.</h3>' '<p>Please invite your colleagues to also sign.</p>')) mail_util = DirectMailUtil('signatory/thank_SPB_signature', recipient_list=[signature.email]) mail_util.send_mail() return redirect(petition.get_absolute_url())
def test_context_saved_to_database(self): """Test mail database entries have relations with their context items.""" with self.settings( EMAIL_BACKEND='mails.backends.filebased.ModelEmailBackend'): mail_util = DirectMailUtil( 'tests/test_mail_code_1', subject='Test Subject Unique For Testing 786234', weird_variable_name='TestValue1', random_submission_relation=self.submission) mail_util.send_mail() mail_log = MailLog.objects.last() context = mail_log.get_full_context() self.assertEqual(mail_log.status, MAIL_NOT_RENDERED) self.assertEqual(mail_log.subject, 'Test Subject Unique For Testing 786234') self.assertIn('random_submission_relation', context) self.assertEqual(context['random_submission_relation'], self.submission) self.assertIn('weird_variable_name', context) self.assertEqual(context['weird_variable_name'], 'TestValue1')
def organization_add_contact(request, organization_id, contactperson_id=None): organization = get_object_or_404(Organization, id=organization_id) if contactperson_id: contactperson = get_object_or_404(ContactPerson, id=contactperson_id) initial = { 'title': contactperson.title, 'first_name': contactperson.first_name, 'last_name': contactperson.last_name, 'email': contactperson.email } else: contactperson = None initial = {} form = NewContactForm(request.POST or None, initial=initial, organization=organization, contactperson=contactperson) if form.is_valid(): contact = form.save(current_user=request.user) mail_sender = DirectMailUtil( 'org_contacts/email_contact_for_activation', contact=contact) mail_sender.send_mail() for role in contact.roles.all(): event = OrganizationEvent( organization=role.organization, event=ORGANIZATION_EVENT_COMMENT, comments=('Contact for %s created; activation pending' % str(contact)), noted_on=timezone.now(), noted_by=request.user) event.save() messages.success( request, '<h3>Created contact: %s</h3>Email has been sent.' % str(contact)) return redirect( reverse('organizations:organization_details', kwargs={'pk': organization.id})) context = {'organization': organization, 'form': form} return render(request, 'organizations/organization_add_contact.html', context)
def form_valid(self, form): ticket = form.cleaned_data['ticket'] if self.request.user == ticket.defined_by: ticket.status = TICKET_STATUS_AWAITING_RESPONSE_ASSIGNEE else: ticket.status = TICKET_STATUS_AWAITING_RESPONSE_USER ticket.save() self.object = form.save() queue_managers = User.objects.filter( groups__name=ticket.queue.managing_group.name) bcc_emails = [ k['email'] for k in list(queue_managers.all().values('email')) ] if ticket.assigned_to and ticket.assigned_to.email not in bcc_emails: bcc_emails.append(ticket.assigned_to.email) print(bcc_emails) mail_sender = DirectMailUtil('helpdesk/followup_on_ticket', delayed_processing=False, bcc=bcc_emails, followup=self.object) mail_sender.send_mail() return redirect(self.get_success_url())
def new_comment(request, **kwargs): """Form view to submit new Comment.""" form = CommentForm(request.POST or None, request.FILES or None) if form.is_valid(): object_id = int(kwargs["object_id"]) type_of_object = kwargs["type_of_object"] if type_of_object == "thesislink": _object = get_object_or_404( ThesisLink.objects.open_for_commenting(), id=object_id) elif type_of_object == "submission": _object = get_object_or_404( Submission.objects.open_for_commenting(), id=object_id) _object.add_event_for_eic('A new comment has been added.') elif type_of_object == "commentary": _object = get_object_or_404( Commentary.objects.open_for_commenting(), id=object_id) new_comment = form.save(commit=False) new_comment.author = request.user.contributor new_comment.content_object = _object new_comment.save() new_comment.grant_permissions() # Mails mail_sender = DirectMailUtil( 'commenters/inform_commenter_comment_received', comment=new_comment) mail_sender.send_mail() if isinstance(new_comment.core_content_object, Submission): mail_sender = DirectMailUtil('eic/inform_eic_comment_received', comment=new_comment) mail_sender.send_mail() messages.success(request, strings.acknowledge_submit_comment) return redirect(_object.get_absolute_url()) context = {'form': form} return (render(request, 'comments/add_comment.html', context))
def save(self): """ Merge one Contributor into another. Set the previous Contributor to inactive. """ contrib_from = self.cleaned_data['to_merge'] contrib_into = self.cleaned_data['to_merge_into'] both_contribs_active = contrib_from.is_active and contrib_into.is_active contrib_from_qs = Contributor.objects.filter(pk=contrib_from.id) contrib_into_qs = Contributor.objects.filter(pk=contrib_into.id) # Step 1: update all fields within Contributor if contrib_from.profile and not contrib_into.profile: profile = contrib_from.profile contrib_from_qs.update(profile=None) contrib_into_qs.update(profile=profile) User.objects.filter(pk=contrib_from.user.id).update(is_active=False) User.objects.filter(pk=contrib_into.user.id).update(is_active=True) if contrib_from.invitation_key and not contrib_into.invitation_key: contrib_into_qs.update(invitation_key=contrib_into.invitation_key) if contrib_from.activation_key and not contrib_into.activation_key: contrib_into_qs.update(activation_key=contrib_into.activation_key) contrib_from_qs.update(status=DOUBLE_ACCOUNT) # Specify duplicate_of for deactivated Contributor contrib_from_qs.update(duplicate_of=contrib_into) # Step 2: update all ForeignKey relations Fellowship.objects.filter(contributor=contrib_from).update(contributor=contrib_into) PotentialFellowshipEvent.objects.filter( noted_by=contrib_from).update(noted_by=contrib_into) Commentary.objects.filter(requested_by=contrib_from).update(requested_by=contrib_into) Commentary.objects.filter(vetted_by=contrib_from).update(vetted_by=contrib_into) Comment.objects.filter(vetted_by=contrib_from).update(vetted_by=contrib_into) Comment.objects.filter(author=contrib_from).update(author=contrib_into) Grant.objects.filter(recipient=contrib_from).update(recipient=contrib_into) CitationNotification.objects.filter( contributor=contrib_from).update(contributor=contrib_into) PublicationAuthorsTable.objects.filter( profile=contrib_from.profile).update(profile=contrib_into.profile) UnavailabilityPeriod.objects.filter( contributor=contrib_from).update(contributor=contrib_into) Remark.objects.filter( contributor=contrib_from).update(contributor=contrib_into) AuthorshipClaim.objects.filter( claimant=contrib_from).update(claimant=contrib_into) AuthorshipClaim.objects.filter( vetted_by=contrib_from).update(vetted_by=contrib_into) Submission.objects.filter( editor_in_charge=contrib_from).update(editor_in_charge=contrib_into) Submission.objects.filter( submitted_by=contrib_from).update(submitted_by=contrib_into) EditorialAssignment.objects.filter(to=contrib_from).update(to=contrib_into) RefereeInvitation.objects.filter(referee=contrib_from).update(referee=contrib_into) RefereeInvitation.objects.filter(invited_by=contrib_from).update(invited_by=contrib_into) Report.objects.filter(vetted_by=contrib_from).update(vetted_by=contrib_into) Report.objects.filter(author=contrib_from).update(author=contrib_into) EditorialCommunication.objects.filter( referee=contrib_from).update(referee=contrib_into) ThesisLink.objects.filter(requested_by=contrib_from).update(requested_by=contrib_into) ThesisLink.objects.filter(vetted_by=contrib_from).update(vetted_by=contrib_into) # Step 3: update all ManyToMany commentaries = Commentary.objects.filter(authors__in=[contrib_from,]).all() for commentary in commentaries: commentary.authors.remove(contrib_from) commentary.authors.add(contrib_into) commentaries = Commentary.objects.filter(authors_claims__in=[contrib_from,]).all() for commentary in commentaries: commentary.authors_claims.remove(contrib_from) commentary.authors_claims.add(contrib_into) commentaries = Commentary.objects.filter(authors_false_claims__in=[contrib_from,]).all() for commentary in commentaries: commentary.authors_false_claims.remove(contrib_from) commentary.authors_false_claims.add(contrib_into) submissions = Submission.objects.filter(authors__in=[contrib_from,]).all() for submission in submissions: submission.authors.remove(contrib_from) submission.authors.add(contrib_into) submissions = Submission.objects.filter(authors_claims__in=[contrib_from,]).all() for submission in submissions: submission.authors_claims.remove(contrib_from) submission.authors_claims.add(contrib_into) submissions = Submission.objects.filter(authors_false_claims__in=[contrib_from,]).all() for submission in submissions: submission.authors_false_claims.remove(contrib_from) submission.authors_false_claims.add(contrib_into) eicrecs = EICRecommendation.objects.filter(eligible_to_vote__in=[contrib_from,]).all() for eicrec in eicrecs: eicrec.eligible_to_vote.remove(contrib_from) eicrec.eligible_to_vote.add(contrib_into) eicrecs = EICRecommendation.objects.filter(voted_for__in=[contrib_from,]).all() for eicrec in eicrecs: eicrec.voted_for.remove(contrib_from) eicrec.voted_for.add(contrib_into) eicrecs = EICRecommendation.objects.filter(voted_against__in=[contrib_from,]).all() for eicrec in eicrecs: eicrec.voted_against.remove(contrib_from) eicrec.voted_against.add(contrib_into) eicrecs = EICRecommendation.objects.filter(voted_abstain__in=[contrib_from,]).all() for eicrec in eicrecs: eicrec.voted_abstain.remove(contrib_from) eicrec.voted_abstain.add(contrib_into) thesislinks = ThesisLink.objects.filter(author_as_cont__in=[contrib_from,]).all() for tl in thesislinks: tl.author_as_cont.remove(contrib_from) tl.author_as_cont.add(contrib_into) thesislinks = ThesisLink.objects.filter(author_claims__in=[contrib_from,]).all() for tl in thesislinks: tl.author_claims.remove(contrib_from) tl.author_claims.add(contrib_into) thesislinks = ThesisLink.objects.filter(author_false_claims__in=[contrib_from,]).all() for tl in thesislinks: tl.author_false_claims.remove(contrib_from) tl.author_false_claims.add(contrib_into) thesislinks = ThesisLink.objects.filter(supervisor_as_cont__in=[contrib_from,]).all() for tl in thesislinks: tl.supervisor_as_cont.remove(contrib_from) tl.supervisor_as_cont.add(contrib_into) # If both accounts were active, inform the Contributor of the merge if both_contribs_active: mail_sender = DirectMailUtil( 'contributors/inform_contributor_duplicate_accounts_merged', object=Contributor.objects.get(id=contrib_from.id)) mail_sender.send_mail() return Contributor.objects.get(id=contrib_into.id)
def petition(request, slug): petition = get_object_or_404(Petition, slug=slug) is_signed = False initial = {} if request.user.is_authenticated: is_signed = petition.petition_signatories.verified().filter( signatory=request.user.contributor).exists() affiliation = request.user.contributor.affiliations.first() or {} institition = affiliation.institution.name if affiliation else '' country = affiliation.institution.country if affiliation else '' initial = { 'petition': petition, 'title': request.user.contributor.profile.title, 'first_name': request.user.first_name, 'last_name': request.user.last_name, 'email': request.user.email, 'country_of_employment': country, 'affiliation': institition, } form = SignPetitionForm(request.POST or None, initial=initial, petition=petition, current_user=request.user) if form.is_valid(): signature = form.save(commit=False) signature.petition = petition message = ('<h3>Many thanks for signing!</h3>' '<p>Please invite your colleagues to also sign.</p>') if request.user.is_authenticated: signature.signatory = request.user.contributor signature.verified = True signature.save() mail_util = DirectMailUtil('signatory/thank_SPB_signature', object=signature) mail_util.send_mail() else: # Generate verification key and link salt = '' for i in range(5): salt += random.choice(string.ascii_letters) salt = salt.encode('utf8') verificationsalt = form.cleaned_data['last_name'] verificationsalt = verificationsalt.encode('utf8') verification_key = hashlib.sha1(salt + verificationsalt).hexdigest() signature.verification_key = verification_key signature.save() message += '\n<p>You will receive an email with a verification link.</p>' email_text = ('Please click on the link below to confirm ' 'your signature of the petition: \n' 'https://scipost.org/petitions/' + petition.slug + '/verify_signature/' + verification_key + '.\n') email_text_html = ( '<p>Please click on the link below to confirm ' 'your signature of the petition:</p>' '<p><a href="https://scipost.org/petitions/{{ slug }}/verify_signature' '/{{ key }}">confirm your signature</a></p>') html_template = Template(email_text_html) html_version = html_template.render( Context({ 'slug': petition.slug, 'key': verification_key })) emailmessage = EmailMultiAlternatives( 'Petition signature verification', email_text, 'SciPost petitions<*****@*****.**>', [form.cleaned_data['email']], bcc=['*****@*****.**']) emailmessage.attach_alternative(html_version, 'text/html') emailmessage.send() messages.success(request, message) return redirect(petition.get_absolute_url()) context = { 'petition': petition, 'is_signed': is_signed, 'form': form, } return render(request, 'petitions/petition.html', context)
def vet_submitted_comment(request, comment_id): # Method `get_objects_for_user` gets all Comments that are assigned to the user # or *all* comments if user has the `scipost.can_vet_comments` permission. comment = get_object_or_404((get_objects_for_user( request.user, 'comments.can_vet_comments').awaiting_vetting()), id=comment_id) form = VetCommentForm(request.POST or None) if form.is_valid(): if form.cleaned_data['action_option'] == '1': # Accept the comment as is Comment.objects.filter(id=comment_id).update( status=1, vetted_by=request.user.contributor) comment.refresh_from_db() # Update `latest_activity` fields content_object = comment.content_object if hasattr(content_object, 'latest_activity'): content_object.__class__.objects.filter( id=content_object.id).update( latest_activity=timezone.now()) content_object.refresh_from_db() if isinstance(content_object, Submission): # Add events to Submission and send mail to author of the Submission content_object.add_event_for_eic( 'A Comment has been accepted.') content_object.add_event_for_author( 'A new Comment has been added.') if not comment.is_author_reply: mail_sender = DirectMailUtil( 'authors/inform_authors_comment_received', instance=content_object, comment=comment) mail_sender.send_mail() elif isinstance(content_object, Report): # Add events to related Submission and send mail to author of the Submission content_object.submission.add_event_for_eic( 'A Comment has been accepted.') content_object.submission.add_event_for_author( 'A new Comment has been added.') if comment.is_author_reply: # Email Report author: Submission authors have replied mail_sender = DirectMailUtil( 'referees/inform_referee_authors_replied_to_report', report=content_object) mail_sender.send_mail() else: # this is a Comment on the Report from another Contributor # Email Report author: Contributor has commented the Report mail_sender = DirectMailUtil( 'referees/inform_referee_contributor_commented_report', report=content_object) mail_sender.send_mail() # Email submission authors: Contributor has commented the Report mail_sender = DirectMailUtil( 'authors/inform_authors_contributor_commented_report', report=content_object) mail_sender.send_mail() elif isinstance(content_object, Comment): # This means that this Comment is part of a hierarchy of Comments. # We thus go back to the core object core_content_object = comment.core_content_object if isinstance(core_content_object, Submission): # Add events to Submission and send mail to author of the Submission core_content_object.add_event_for_eic( 'A Comment has been accepted.') core_content_object.add_event_for_author( 'A new Comment has been added.') if not comment.is_author_reply: mail_sender = DirectMailUtil( 'authors/inform_authors_comment_received', instance=core_content_object, comment=comment) mail_sender.send_mail() # In all cases, email the comment author mail_sender = DirectMailUtil( 'commenters/inform_commenter_comment_vetted', comment=comment) mail_sender.send_mail() elif form.cleaned_data['action_option'] == '2': # The comment request is simply rejected Comment.objects.filter(id=comment.id).update( status=int(form.cleaned_data['refusal_reason']), vetted_by=request.user.contributor) comment.refresh_from_db() # Send emails mail_sender = DirectMailUtil( 'commenters/inform_commenter_comment_rejected', comment=comment, email_response=form.cleaned_data['email_response_field'] ) # TODO: needs kwargs to mail template mail_sender.send_mail() if isinstance(comment.content_object, Submission): # Add event if commented to Submission comment.content_object.add_event_for_eic( 'A Comment has been rejected.') elif isinstance(comment.content_object, Report): comment.content_object.submission.add_event_for_eic( 'A Comment has been rejected.') messages.success(request, 'Submitted Comment vetted.') if isinstance(comment.content_object, Submission): submission = comment.content_object if submission.editor_in_charge == request.user.contributor: # Redirect a EIC back to the Editorial Page return redirect( reverse('submissions:editorial_page', args=(submission.preprint.identifier_w_vn_nr, ))) elif isinstance(comment.content_object, Report): submission = comment.content_object.submission if submission.editor_in_charge == request.user.contributor: # Redirect a EIC back to the Editorial Page return redirect( reverse('submissions:editorial_page', args=(submission.preprint.identifier_w_vn_nr, ))) elif request.user.has_perm('scipost.can_vet_comments'): # Redirect vetters back to check for other unvetted comments return redirect(reverse('comments:vet_submitted_comments_list')) return redirect(comment.get_absolute_url()) context = {'comment': comment, 'form': form} return (render(request, 'comments/vet_submitted_comment.html', context))
def handle(self, *args, **options): for submission in Submission.objects.open_for_reporting(): # Send reminders to referees who have not responded: for invitation in submission.referee_invitations.awaiting_response( ).auto_reminders_allowed(): # 2 days after ref invite sent out: first auto reminder if workdays_between(invitation.date_invited, timezone.now()) == 2: if invitation.referee: mail_sender = DirectMailUtil( 'referees/invite_contributor_to_referee_reminder1', invitation=invitation) mail_sender.send_mail() else: mail_sender = DirectMailUtil( 'referees/invite_unregistered_to_referee_reminder1', invitation=invitation) mail_sender.send_mail() invitation.nr_reminders += 1 invitation.date_last_reminded = timezone.now() invitation.save() # second (and final) reminder after 4 days elif workdays_between(invitation.date_invited, timezone.now()) == 4: if invitation.referee: mail_sender = DirectMailUtil( 'referees/invite_contributor_to_referee_reminder2', invitation=invitation) mail_sender.send_mail() else: mail_sender = DirectMailUtil( 'referees/invite_unregistered_to_referee_reminder2', invitation=invitation) mail_sender.send_mail() invitation.nr_reminders += 1 invitation.date_last_reminded = timezone.now() invitation.save() # after 6 days of no response, EIC is automatically emailed # with the suggestion of removing and replacing this referee elif workdays_between(invitation.date_invited, timezone.now()) == 6: mail_sender = DirectMailUtil('eic/referee_unresponsive', invitation=invitation) mail_sender.send_mail() # one week before refereeing deadline: auto email reminder to ref if workdays_between(timezone.now(), submission.reporting_deadline) == 5: for invitation in submission.referee_invitations.in_process( ).auto_reminders_allowed(): mail_sender = DirectMailUtil( 'referees/remind_referee_deadline_1week', invitation=invitation) mail_sender.send_mail()