def send_invitation(self): key = self.key inviter = self.inviter recipient = self.recipient email = self.recipient_email organization = self.organization invite_type = self.invite_type.lower() template = 'organization_invite.txt' html_template = 'organization_invite.html' inviter_name = f'{inviter.first_name} {inviter.last_name}' subject = f'{inviter_name} has invited you to join {organization.name}' email_context = { 'access_type': invite_type.lower(), 'organization_title': organization.name, 'organization_link': f'{BASE_FRONTEND_URL}/org/join/{key}', 'inviter_name': inviter_name } if recipient: email_context[ 'user_name'] = f'{recipient.first_name} {recipient.last_name}' else: email_context['user_name'] = 'User' send_email_message([email], template, subject, email_context, html_template)
def notify_inactivity(self, paper_count=0, comment_count=0): recipient = [self.email] subject = "[Editor] Weekly Inactivity" email_context = { "name": f"{self.first_name} {self.last_name}", "paper_count": paper_count, "comment_count": comment_count, } send_email_message( recipient, "editor_inactivity.txt", subject, email_context, "editor_inactivity.html", )
def send_academic_verification_email(self, user, user_distribution_record): author_profile = user.author_profile user_name = author_profile.first_name if author_profile.last_name: user_name += ' ' + author_profile.last_name context = { **base_email_context, 'user_name': user_name, 'reward_amount': user_distribution_record.amount, 'user_profile': f'{BASE_FRONTEND_URL}/user/{user.id}/overview', } subject = 'Your ResearchHub Verification is Approved!' send_email_message(user.email, 'academic_verification_email.txt', subject, context, html_template='academic_verification_email.html')
def actions_notifications(action_ids, notif_interval=NotificationFrequencies.IMMEDIATE): # NOTE: This only supports immediate updates for now. actions = Action.objects.filter(id__in=action_ids) user_to_action = {} for action in actions: item = action.item if hasattr(item, "users_to_notify"): for user in set(item.users_to_notify): try: r = user.emailrecipient if isinstance(item, Thread): # Need to somehow differentiate # between authored papers and posts subscription = r.paper_subscription elif isinstance(item, Comment): subscription = r.comment_subscription elif isinstance(item, Reply): subscription = r.reply_subscription else: subscription = r if r.receives_notifications and not subscription.none: if user_to_action.get(r): user_to_action[r].append(action) else: user_to_action[r] = [action] except AttributeError as e: logging.warning(e) else: logging.info("action: ({action}) is missing users_to_notify field") for r in user_to_action: subject = build_subject(notif_interval) context = build_notification_context(user_to_action[r]) send_email_message( r.email, "notification_email.txt", subject, context, html_template="notification_email.html", )
def send_distribution_email(user, content_stats): context = { **base_email_context, 'user_name': get_author_full_name(user), 'reward_amount': content_stats['reward_amount'], 'uploaded_paper_count': content_stats['uploaded_paper_count'], 'total_paper_votes': content_stats['total_paper_votes'], 'discussion_count': content_stats['discussion_count'], 'total_comment_votes': content_stats['total_comment_votes'], 'total_votes_given': content_stats['total_votes_given'], 'uploaded_papers': content_stats['uploaded_papers'], 'action_links': content_stats['action_links'], } subject = 'Notification From ResearchHub' send_email_message(user.email, 'distribution_email.txt', subject, context, html_template='distribution_email.html')
def send_invitation(self): key = self.key recipient = self.recipient email = self.recipient_email note = self.note invite_type = self.invite_type.lower() template = 'note_invite.txt' html_template = 'note_invite.html' subject = 'ResearchHub | Note Collaboration' email_context = { 'access_type': invite_type.lower(), 'note_title': note.title, 'note_link': f'{BASE_FRONTEND_URL}/note/join/{key}', } if recipient: email_context[ 'user_name'] = f'{recipient.first_name} {recipient.last_name}' else: email_context['user_name'] = 'User' send_email_message([email], template, subject, email_context, html_template)
def invite_to_hub(self, request, pk=None): recipients = request.data.get('emails', []) if len(recipients) < 1: message = 'Field `emails` can not be empty' error = ValidationError(message) return Response(error.detail, status=400) subject = 'Researchhub Hub Invitation' hub = Hub.objects.filter(is_removed=False).get(id=pk) base_url = request.META['HTTP_ORIGIN'] emailContext = { 'hub_name': hub.name.capitalize(), 'link': base_url + '/hubs/{}/'.format(hub.name), 'opt_out': base_url + '/email/opt-out/' } subscriber_emails = hub.subscribers.all().values_list('email', flat=True) # Don't send to hub subscribers if len(subscriber_emails) > 0: for recipient in recipients: if recipient in subscriber_emails: recipients.remove(recipient) result = send_email_message(recipients, 'invite_to_hub_email.txt', subject, emailContext, 'invite_to_hub_email.html') response = {'email_sent': False, 'result': result} if len(result['success']) > 0: response = {'email_sent': True, 'result': result} return Response(response, status=200)
def send_editor_hub_digest(frequency): emails = [] etl = EmailTaskLog.objects.create(emails="", notification_frequency=frequency) end_date = timezone.now() start_date = calculate_hub_digest_start_date(end_date, frequency) for hub in Hub.objects.iterator(): editor_permissions = hub.editor_permission_groups.iterator() for editor_permission in editor_permissions: user = editor_permission.user if not check_editor_can_receive_digest(user, frequency): continue documents = hub.related_documents.filter( created_date__gte=start_date, created_date__lte=end_date, is_removed=False, ) if documents.count() == 0: continue paper_ids = documents.exclude(paper__isnull=True).values_list( "paper_id", flat=True) post_ids = documents.exclude(posts__isnull=True).values_list( "posts", flat=True) hypothesis_ids = documents.exclude( hypothesis__isnull=True).values_list("hypothesis", flat=True) actions = Action.objects.filter( Q( content_type=ContentType.objects.get_for_model(Paper), object_id__in=paper_ids, ) | Q( content_type=ContentType.objects.get_for_model( ResearchhubPost), object_id__in=post_ids, ) | Q( content_type=ContentType.objects.get_for_model(Hypothesis), object_id__in=hypothesis_ids, )).distinct("id") email_context = { **base_email_context, "first_name": user.first_name, "last_name": user.last_name, "actions": [act.email_context() for act in actions], } recipient = [user.email] subject = "ResearchHub | Your Editor Digest" send_email_message( recipient, "editor_digest.txt", subject, email_context, "editor_digest.html", "ResearchHub Digest <*****@*****.**>", ) emails += recipient etl.emails = ",".join(emails) etl.save()
def send_hub_digest(frequency): etl = EmailTaskLog.objects.create(emails="", notification_frequency=frequency) end_date = timezone.now() start_date = calculate_hub_digest_start_date(end_date, frequency) upvotes = Count( "vote", filter=Q( vote__vote_type=PaperVote.UPVOTE, vote__updated_date__gte=start_date, vote__updated_date__lte=end_date, ), ) downvotes = Count( "vote", filter=Q( vote__vote_type=PaperVote.DOWNVOTE, vote__created_date__gte=start_date, vote__created_date__lte=end_date, ), ) # TODO don't include censored threads? thread_counts = Count( "threads", filter=Q( threads__created_date__gte=start_date, threads__created_date__lte=end_date, # threads__is_removed=False, ), ) comment_counts = Count( "threads__comments", filter=Q( threads__comments__created_date__gte=start_date, threads__comments__created_date__lte=end_date, # threads__comments__is_removed=False, ), ) reply_counts = Count( "threads__comments__replies", filter=Q( threads__comments__replies__created_date__gte=start_date, threads__comments__replies__created_date__lte=end_date, # threads__comments__replies__is_removed=False, ), ) users = Hub.objects.filter( subscribers__isnull=False, is_removed=False, ).values_list("subscribers", flat=True) # TODO find best by hub and then in mem sort for each user? more efficient? emails = [] for user in User.objects.filter(id__in=users, is_suspended=False): if not check_can_receive_digest(user, frequency): continue users_papers = Paper.objects.filter( hubs__in=user.subscribed_hubs.all()) most_voted_and_uploaded_in_interval = (users_papers.filter( uploaded_date__gte=start_date, uploaded_date__lte=end_date).filter( score__gt=0).order_by("-score")[:3]) most_discussed_in_interval = (users_papers.annotate( discussions=thread_counts + comment_counts + reply_counts).filter( discussions__gt=0).order_by("-discussions")[:3]) most_voted_in_interval = users_papers.filter( score__gt=0).order_by("-score")[:2] papers = (most_voted_and_uploaded_in_interval or most_discussed_in_interval or most_voted_in_interval) if len(papers) == 0: continue email_context = { **base_email_context, "first_name": user.first_name, "last_name": user.last_name, "papers": papers, "preview_text": papers[0].tagline, } recipient = [user.email] # subject = 'Research Hub | Your Weekly Digest' subject = papers[0].title[0:86] + "..." send_email_message( recipient, "weekly_digest_email.txt", subject, email_context, "weekly_digest_email.html", "ResearchHub Digest <*****@*****.**>", ) emails += recipient etl.emails = ",".join(emails) etl.save()
def send_support_email(profile_url, sender_name, recipient_name, email, amount, date, payment_type, email_type, content_type, object_id, paper_id=None): paper_data = {} object_supported = 'profile' if content_type == 'paper': paper = Paper.objects.get(id=object_id) url = f'{BASE_FRONTEND_URL}/paper/{paper.id}/{paper.slug}' paper_data['title'] = paper.title paper_summary = f'From Paper: {paper.summary}' if paper.summary else '' paper_data['summary'] = paper_summary paper_data['uploaded_by'] = paper.uploaded_by.full_name() paper_data['discussion_count'] = paper.discussion_count paper_data['paper_type'] = ''.join( paper.paper_type.split('_')).capitalize() paper_data['url'] = url object_supported = 'paper' elif content_type == 'thread': paper = Paper.objects.get(id=paper_id) url = f'{BASE_FRONTEND_URL}/paper/{paper.id}/{paper.slug}#comments' object_supported = f""" <a href="{url}" class="header-link">thread</a> """ object_supported = 'thread' elif content_type == 'comment': paper = Paper.objects.get(id=paper_id) url = f'{BASE_FRONTEND_URL}/paper/{paper.id}/{paper.slug}#comments' object_supported = f""" <a href="{url}" class="header-link">comment</a> """ elif content_type == 'reply': paper = Paper.objects.get(id=paper_id) url = f'{BASE_FRONTEND_URL}/paper/{paper.id}/{paper.slug}#comments' object_supported = f""" <a href="{url}" class="header-link">reply</a> """ elif content_type == 'summary': paper = Paper.objects.get(id=paper_id) url = f'{BASE_FRONTEND_URL}/paper/{paper.id}/{paper.slug}#summary' object_supported = f""" <a href="{url}" class="header-link">summary</a> """ elif content_type == 'bulletpoint': paper = Paper.objects.get(id=paper_id) url = f'{BASE_FRONTEND_URL}/paper/{paper.id}/{paper.slug}#takeaways' object_supported = f""" <a href="{url}" class="header-link">key takeaway</a> """ if payment_type == Support.STRIPE: payment_type = 'USD' elif payment_type == Support.PAYPAL: payment_type = 'Paypal' elif payment_type == Support.ETH: payment_type = 'Ethereum' elif payment_type == Support.BTC: payment_type = 'Bitcoin' elif payment_type in Support.RSC_ON_CHAIN: payment_type = 'RSC' elif payment_type in Support.RSC_OFF_CHAIN: payment_type = 'RSC' context = { **base_email_context, 'amount': amount, 'date': date, 'method': payment_type, 'email': email, 'recipient': email_type == 'recipient', 'sender_name': sender_name, 'recipient_name': recipient_name, 'paper': paper_data, 'user_profile': profile_url, 'object_supported': object_supported, 'url': url } print(url) if email_type == 'sender': subject = 'Receipt From ResearchHub' send_email_message(email, 'support_receipt.txt', subject, context, html_template='support_receipt.html') elif email_type == 'recipient': subject = 'Someone Sent You RSC on ResearchHub!' send_email_message(email, 'support_receipt.txt', subject, context, html_template='support_receipt.html')