Skip to content

Commit

Permalink
Merge pull request #2806 from gitcoinco/ks_emails
Browse files Browse the repository at this point in the history
[WIP]: Email implementation
  • Loading branch information
captnseagraves authored Nov 14, 2018
2 parents 748ab50 + cfa4755 commit bc34beb
Show file tree
Hide file tree
Showing 14 changed files with 258 additions and 68 deletions.
12 changes: 12 additions & 0 deletions app/app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,18 @@

# admin views
re_path(r'^_administration/?', admin.site.urls, name='admin'),
path('_administration/email/new_grant', retail.emails.new_grant, name='admin_new_grant'),
path('_administration/email/new_supporter', retail.emails.new_supporter, name='admin_new_supporter'),
path(
'_administration/email/thank_you_for_supporting',
retail.emails.thank_you_for_supporting,
name='admin_thank_you_for_supporting'
),
path(
'_administration/email/support_cancellation',
retail.emails.support_cancellation,
name='admin_support_cancellation'
),
path('_administration/email/new_kudos', retail.emails.new_kudos, name='new_kudos'),
path('_administration/email/kudos_mint', retail.emails.kudos_mint, name='kudos_mint'),
path('_administration/email/kudos_mkt', retail.emails.kudos_mkt, name='kudos_mkt'),
Expand Down
5 changes: 4 additions & 1 deletion app/assets/v2/js/grants/fund_grant.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ $(document).ready(function() {
}
if (periodSeconds) {
realPeriodSeconds = periodSeconds;
data.frequency = realPeriodSeconds;
}
}

Expand Down Expand Up @@ -105,6 +104,8 @@ $(document).ready(function() {
data[this.name] = this.value;
});

data.frequency = realPeriodSeconds;

console.log('data', data);

form.submit();
Expand All @@ -124,6 +125,8 @@ $(document).ready(function() {
data[this.name] = this.value;
});

data.frequency = realPeriodSeconds;

console.log('data', data);

form.submit();
Expand Down
2 changes: 1 addition & 1 deletion app/dashboard/migrations/0110_auto_20181027_1727.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 2.1.2 on 2018-10-27 17:27
# Generated by Django 2.1.2 on 2018-11-06 23:11

from django.db import migrations, models
import django.db.models.deletion
Expand Down
9 changes: 8 additions & 1 deletion app/grants/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ class Migration(migrations.Migration):
('created_on', models.DateTimeField(db_index=True, default=economy.models.get_time)),
('modified_on', models.DateTimeField(default=economy.models.get_time)),
('tx_id', models.CharField(default='0x0', help_text='The transaction ID of the Contribution.', max_length=255)),
('from_address', models.CharField(default='0x0', help_text='The wallet address tokens are sent from.', max_length=255)),
('to_address', models.CharField(default='0x0', help_text='The wallet address tokens are sent to.', max_length=255)),
('token_address', models.CharField(default='0x0', help_text='The token address to be used with the Subscription.', max_length=255)),
('token_amount', models.DecimalField(decimal_places=4, default=1, help_text='The promised contribution amount per period.', max_digits=50)),
('period_seconds', models.DecimalField(decimal_places=0, default=0, help_text='The number of seconds thats constitues a period.', max_digits=50)),
('gas_price', models.DecimalField(decimal_places=4, default=0, help_text='The amount of token used to incentivize subminers.', max_digits=50)),
('nonce', models.DecimalField(decimal_places=0, default=0, help_text='The of the subscription metaTx.', max_digits=50)),
],
options={
'abstract': False,
Expand All @@ -41,7 +48,7 @@ class Migration(migrations.Migration):
('logo', models.ImageField(blank=True, help_text='The Grant logo image.', null=True, upload_to=grants.utils.get_upload_filename)),
('logo_svg', models.FileField(blank=True, help_text='The Grant logo SVG.', null=True, upload_to=grants.utils.get_upload_filename)),
('admin_address', models.CharField(default='0x0', help_text='The wallet address for the administrator of this Grant.', max_length=255)),
('frequency', models.DecimalField(decimal_places=0, default=30, help_text='The payout frequency of the Grant.', max_digits=50)),
('frequency', models.DecimalField(decimal_places=0, default=2592000, help_text='The payout frequency of the Grant.', max_digits=50)),
('amount_goal', models.DecimalField(decimal_places=4, default=1, help_text='The contribution goal amount for the Grant.', max_digits=50)),
('amount_received', models.DecimalField(decimal_places=4, default=0, help_text='The total amount received for the Grant.', max_digits=50)),
('token_address', models.CharField(default='0x0', help_text='The token address to be used with the Grant.', max_length=255)),
Expand Down
6 changes: 6 additions & 0 deletions app/grants/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

from grants.forms import MilestoneForm
from grants.models import Grant, Milestone, Subscription
from marketing.mails import new_grant, new_supporter, support_cancellation, thank_you_for_supporting
from marketing.models import Keyword
from web3 import HTTPProvider, Web3

Expand Down Expand Up @@ -179,6 +180,7 @@ def grant_new(request):
'logo': logo,
}
grant = Grant.objects.create(**grant_kwargs)
new_grant(grant, profile)

if team_members:
grant.team_members.add(*list(map(int, team_members)))
Expand Down Expand Up @@ -258,6 +260,8 @@ def grant_fund(request, grant_id):
subscription.contributor_profile = profile
subscription.grant = grant
subscription.save()
new_supporter(grant, subscription)
thank_you_for_supporting(grant, subscription, profile)
return redirect(reverse('grants:details', args=(grant.pk, )))

params = {
Expand All @@ -276,10 +280,12 @@ def subscription_cancel(request, grant_id, subscription_id):
subscription = Subscription.objects.select_related('grant').get(pk=subscription_id)
grant = getattr(subscription, 'grant', None)
now = datetime.datetime.now()
profile = request.user.profile if request.user.is_authenticated else None

if request.method == 'POST':
subscription.active = False
subscription.save()
support_cancellation(grant, subscription, profile)
return redirect(reverse('grants:details', args=(grant.pk, )))

params = {
Expand Down
70 changes: 66 additions & 4 deletions app/marketing/mails.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@
render_bounty_startwork_expire_warning, render_bounty_unintersted, render_faucet_rejected, render_faucet_request,
render_funder_stale, render_gdpr_reconsent, render_gdpr_update, render_kudos_email, render_match_email,
render_new_bounty, render_new_bounty_acceptance, render_new_bounty_rejection, render_new_bounty_roundup,
render_new_work_submission, render_quarterly_stats, render_start_work_applicant_about_to_expire,
render_start_work_applicant_expired, render_start_work_approved, render_start_work_new_applicant,
render_start_work_rejected, render_tip_email,
render_new_grant_email, render_new_supporter_email, render_new_work_submission, render_quarterly_stats,
render_start_work_applicant_about_to_expire, render_start_work_applicant_expired, render_start_work_approved,
render_start_work_new_applicant, render_start_work_rejected, render_support_cancellation_email,
render_thank_you_for_supporting_email, render_tip_email,
)
from sendgrid.helpers.mail import Content, Email, Mail, Personalization
from sendgrid.helpers.stats import Category
Expand Down Expand Up @@ -68,7 +69,7 @@ def send_mail(from_email, _to_email, subject, body, html=False,
content = Content(contenttype, html) if html else Content(contenttype, body)

# TODO: A bit of a hidden state change here. Really confusing when doing development.
# Maybe this should be a variable passed into the function the value is set upstream?
# Maybe this should be a variable passed into the function the value is set upstream?
if settings.IS_DEBUG_ENV or debug_mode:
to_email = Email(settings.CONTACT_EMAIL) # just to be double secret sure of what were doing in dev
subject = _("[DEBUG] ") + subject
Expand All @@ -92,6 +93,7 @@ def send_mail(from_email, _to_email, subject, body, html=False,
for category in categories:
mail.add_category(Category(category))


# debug logs
logger.info(f"-- Sending Mail '{subject}' to {to_email}")
try:
Expand All @@ -105,6 +107,66 @@ def send_mail(from_email, _to_email, subject, body, html=False,
return response


def new_grant(grant, profile):
from_email = settings.CONTACT_EMAIL
to_email = profile.email
cur_language = translation.get_language()

try:
setup_lang(to_email)
html, text, subject = render_new_grant_email(grant)

if not should_suppress_notification_email(to_email, 'new_grant'):
send_mail(from_email, to_email, subject, text, html, categories=['transactional', func_name()])
finally:
translation.activate(cur_language)


def new_supporter(grant, subscription):
from_email = settings.CONTACT_EMAIL
to_email = subscription.contributor_profile.email
cur_language = translation.get_language()

try:
setup_lang(to_email)
html, text, subject = render_new_supporter_email(grant, subscription)

if not should_suppress_notification_email(to_email, 'new_supporter'):
send_mail(from_email, to_email, subject, text, html, categories=['transactional', func_name()])
finally:
translation.activate(cur_language)


def thank_you_for_supporting(grant, subscription, profile):
from_email = settings.CONTACT_EMAIL
to_email = profile.email
cur_language = translation.get_language()

try:
setup_lang(to_email)
html, text, subject = render_thank_you_for_supporting_email(grant, subscription)

if not should_suppress_notification_email(to_email, 'thank_you_for_supporting'):
send_mail(from_email, to_email, subject, text, html, categories=['transactional', func_name()])
finally:
translation.activate(cur_language)


def support_cancellation(grant, subscription, profile):
from_email = settings.CONTACT_EMAIL
to_email = profile.email
cur_language = translation.get_language()

try:
setup_lang(to_email)
html, text, subject = render_support_cancellation_email(grant, subscription)

if not should_suppress_notification_email(to_email, 'support_cancellation'):
send_mail(from_email, to_email, subject, text, html, categories=['transactional', func_name()])
finally:
translation.activate(cur_language)


def admin_contact_funder(bounty, text, from_user):
from_email = from_user.email
to_email = bounty.bounty_owner_email
Expand Down
86 changes: 86 additions & 0 deletions app/retail/emails.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import cssutils
import premailer
from grants.models import Grant, Subscription
from marketing.models import LeaderboardRank
from marketing.utils import get_or_save_email_subscriber
from retail.utils import strip_double_chars, strip_html
Expand Down Expand Up @@ -67,6 +68,91 @@ def premailer_transform(html):
return p.transform()


def render_new_grant_email(grant):
params = {
'grant': grant
}
response_html = premailer_transform(render_to_string("emails/grants/new_grant.html", params))
response_txt = render_to_string("emails/grants/new_grant.txt", params)
subject = "Your Gitcoin Grant"

return response_html, response_txt, subject


def render_new_supporter_email(grant, subscription):
params = {
'grant': grant,
'subscription': subscription
}
response_html = premailer_transform(render_to_string("emails/grants/new_supporter.html", params))
response_txt = render_to_string("emails/grants/new_supporter.txt", params)
subject = "You have a new Grant supporter!"

return response_html, response_txt, subject


def render_thank_you_for_supporting_email(grant, subscription):
params = {
'grant': grant,
'subscription': subscription
}
response_html = premailer_transform(render_to_string("emails/grants/thank_you_for_supporting.html", params))
response_txt = render_to_string("emails/grants/thank_you_for_supporting.txt", params)
subject = "Thank you for supporting Grants on Gitcoin!"

return response_html, response_txt, subject


def render_support_cancellation_email(grant, subscription):
params = {
'grant': grant,
'subscription': subscription
}
response_html = premailer_transform(render_to_string("emails/grants/support_cancellation.html", params))
response_txt = render_to_string("emails/grants/support_cancellation.txt", params)
subject = "Your subscription on Gitcoin Grants has been cancelled"

return response_html, response_txt, subject


@staff_member_required
def support_cancellation(request):
# giving specific pk because I am sure this grant has at least one subscription
grant = Grant.objects.get(pk=14)
subscription = Subscription.objects.filter(grant__pk=grant.pk).first()

response_html, response_txt, _ = render_support_cancellation_email(grant, subscription)
return HttpResponse(response_html)


@staff_member_required
def thank_you_for_supporting(request):
# giving specific pk because I am sure this grant has at least one subscription
grant = Grant.objects.get(pk=8)
subscription = Subscription.objects.filter(grant__pk=grant.pk).first()

response_html, response_txt, _ = render_thank_you_for_supporting_email(grant, subscription)
return HttpResponse(response_html)


@staff_member_required
def new_supporter(request):
# giving specific pk because I am sure this grant has at least one subscription
grant = Grant.objects.get(pk=8)
subscription = Subscription.objects.filter(grant__pk=grant.pk).first()

response_html, response_txt, _ = render_new_supporter_email(grant, subscription)
return HttpResponse(response_html)


@staff_member_required
def new_grant(request):
grant = Grant.objects.all().order_by('-created_on')[0]

response_html, response_txt, _ = render_new_grant_email(grant)
return HttpResponse(response_html)


def render_tip_email(to_email, tip, is_new):
warning = tip.network if tip.network != 'mainnet' else ""
already_redeemed = bool(tip.receive_txid)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% extends 'emails/template.html' %}
{% comment %}
Copyright (C) 2017 Gitcoin Core
Copyright (C) 2018 Gitcoin Core

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
Expand All @@ -16,7 +16,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.

{% endcomment %}
{% load i18n humanize %}
{% load i18n %}
{% load static %}

{% block content %}
Expand Down Expand Up @@ -67,21 +67,22 @@ <h1>{% trans "New Grant Created" %}</h1>

<hr>

<img src="{% static grant.icon %}" alt="grant icon" width="50px" height="50px" >
<img src="{% if grant.logo and grant.logo.url %}{{ grant.logo.url }}{% else %}{% static 'v2/images/bitmap.png' %}{% endif %}" alt="grant logo" width="25%" >

<p class="grant-email-name">{{grant.name}}</p>
<p class="grant-email-subtitle">{{grant.desc}}</p>
<p class="grant-email-name">{{ grant.title }}</p>
<p class="grant-email-subtitle">{{ grant.description }}</p>

<div>
<p class="grant-email-amount">{{grant.amount}}</p>
<p class="grant-email-subtitle">{% trans "You are seeking " %}{{ grant.amount_goal }} {% trans "ETH total" %}</p>
<p class="grant-email-subtitle">{% trans "and " %}{{ grant.monthly_goal }} {% trans "ETH monthly" %}</p>
</div>

<p class="grant-email-subtitle">{% blocktrans %}The details of your grant can be seen <a href="{{grant.url}">here.</a>{% endblocktrans %}</p>
<p class="grant-email-subtitle">{% trans "The details of your grant can be seen" %} <a href="{% url 'grants:details' grant.pk %}">{% trans "here." %}</a></p>

<hr>

<div>
<a class="button grant-email-button" href="{{grant.url}">{% trans "View Grant" %}</a>
<a class="button grant-email-button" href="{% url 'grants:details' grant.pk %}">{% trans "View Grant" %}</a>
</div>

{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
{% trans "You've created a new grant!" %}
{% trans "Get ready to buidl and push forward open source!" %}

{{grant.name}}
{{grant.desc}}
{{ grant.title }}
{{ grant.description }}

{{grant.amount}}
{{ grant.amount_goal }}

{% trans "The details of your grant can be seen here:" %} {{grant.url}}
{% trans "The details of your grant can be seen here:" %} {{ grant.reference_url }}
Loading

0 comments on commit bc34beb

Please sign in to comment.