Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Email for Tribe Members about Hackathon Prizes #7146

Merged
1 change: 1 addition & 0 deletions app/app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,7 @@
path('_administration/email/gdpr_reconsent', retail.emails.gdpr_reconsent, name='gdpr_reconsent'),
path('_administration/email/share_bounty', retail.emails.share_bounty, name='share_bounty'),
path('_administration/email/new_tip/resend', retail.emails.resend_new_tip, name='resend_new_tip'),
path('_administration/email/tribe_hackathon_prizes', retail.emails.tribe_hackathon_prizes, name='tribe_hackathon_prizes'),
path(
'_administration/email/day_email_campaign/<int:day>',
marketing.views.day_email_campaign,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
58 changes: 58 additions & 0 deletions app/marketing/mails.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,20 @@
render_successful_contribution_email, render_support_cancellation_email, render_tax_report,
render_thank_you_for_supporting_email, render_tip_email, render_unread_notification_email_weekly_roundup,
render_wallpost, render_weekly_recap,
render_bounty_expire_warning, render_bounty_feedback, render_bounty_request, render_bounty_startwork_expire_warning,
render_bounty_unintersted, render_comment, render_faucet_rejected, render_faucet_request,
render_featured_funded_bounty, render_funder_payout_reminder, render_funder_stale, render_gdpr_reconsent,
render_gdpr_update, render_grant_cancellation_email, render_grant_recontribute, render_grant_txn_failed,
render_grant_update, render_kudos_email, render_match_distribution, render_match_email, render_mention,
render_new_bounty, render_new_bounty_acceptance, render_new_bounty_rejection, render_new_bounty_roundup,
render_new_grant_email, render_new_supporter_email, render_new_work_submission, render_no_applicant_reminder,
render_nth_day_email_campaign, render_quarterly_stats, render_remember_your_cart, render_request_amount_email,
render_reserved_issue, render_share_bounty, 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_subscription_terminated_email, render_successful_contribution_email,
render_support_cancellation_email, render_tax_report, render_thank_you_for_supporting_email, render_tip_email,
render_unread_notification_email_weekly_roundup, render_wallpost, render_weekly_recap, render_bounty_hypercharged,
render_tribe_hackathon_prizes, render_unread_notification_email_weekly_roundup, render_wallpost, render_weekly_recap,
)
from sendgrid.helpers.mail import Attachment, Content, Email, Mail, Personalization
from sendgrid.helpers.stats import Category
Expand Down Expand Up @@ -1997,3 +2011,47 @@ def remember_your_cart(profile, cart_query, grants, hours):
send_mail(from_email, to_email, subject, text, html, categories=['marketing', func_name()])
finally:
translation.activate(cur_language)

def tribe_hackathon_prizes(hackathon):
from dashboard.models import TribeMember, Sponsor
from marketing.utils import generate_hackathon_email_intro

sponsors = hackathon.sponsors.all()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have a problem here, should use sponsor_profiles we not longer use Sponsors to control hackathons

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@octavioamu @PixelantDesign I have a PR up at #7589

tribe_members_in_sponsors = TribeMember.objects.filter(org__in=[sponsor.tribe for sponsor in sponsors]).exclude(status='rejected').exclude(profile__user=None).only('profile')

for tribe_member in tribe_members_in_sponsors.distinct('profile'):
tribe_member_records = tribe_members_in_sponsors.filter(profile=tribe_member.profile)

sponsors_prizes = []
for sponsor in sponsors.filter(tribe__in=[tribe_member_record.org for tribe_member_record in tribe_member_records]):
prizes = hackathon.get_current_bounties.filter(bounty_owner_profile=sponsor.tribe)
sponsor_prize = {
"sponsor": sponsor,
"prizes": prizes
}
sponsors_prizes.append(sponsor_prize)

subject_begin = generate_hackathon_email_intro(sponsors_prizes)
subject = f"{subject_begin} participating in {hackathon.name} on Gitcoin 🚀"

try:
html, text = render_tribe_hackathon_prizes(hackathon, sponsors_prizes, subject_begin)
except:
return

profile = tribe_member.profile
to_email = profile.email
from_email = settings.CONTACT_EMAIL
if not to_email:
if profile and profile.user:
to_email = profile.user.email
if not to_email:
continue

cur_language = translation.get_language()

try:
setup_lang(to_email)
send_mail(from_email, to_email, subject, text, html, categories=['marketing', func_name()])
finally:
translation.activate(cur_language)
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'''
Copyright (C) 2020 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
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
import datetime

from django.conf import settings
from django.core.management.base import BaseCommand
from django.utils import timezone

from dashboard.models import HackathonEvent
from marketing.mails import tribe_hackathon_prizes


class Command(BaseCommand):
help = 'sends emails for tribe members about hackathon prizes sponsored by the tribe org'

def handle(self, *args, **options):
if settings.DEBUG:
print("not active in non prod environments")
return

no_of_days = 3
next_date = timezone.now() + timezone.timedelta(days=no_of_days)

upcoming_hackthons = HackathonEvent.objects.filter(start_date__date=next_date)

for upcoming_hackthon in upcoming_hackthons:
try:
tribe_hackathon_prizes(upcoming_hackthon)
except:
pass
8 changes: 8 additions & 0 deletions app/marketing/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,14 @@ def handle_marketing_callback(_input, request):
else:
messages.info(request, "You have been selected to receive a $5.00 Gitcoin Grants voucher. Login to use it.")

def generate_hackathon_email_intro(sponsors_prizes):
sponsor_names = [sponsor['sponsor'].name for sponsor in sponsors_prizes]
if (len(sponsors_prizes) > 2):
return f"{', '.join(sponsor_names)} are"
elif (len(sponsors_prizes) == 2):
return f"{' and '.join(sponsor_names)} are"
else:
return f"{sponsors_prizes[0]['sponsor'].name} is"

def func_name():
"""Determine the calling function's name.
Expand Down
47 changes: 47 additions & 0 deletions app/retail/emails.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,34 @@ def render_tip_email(to_email, tip, is_new):

return response_html, response_txt

def render_tribe_hackathon_prizes(hackathon, sponsors_prizes, intro_begin):
email_style = 'hackathon'

hackathon = {
'hackathon': hackathon,
'name': hackathon.name,
'image_url': hackathon.logo.url if hackathon.logo else f'{settings.STATIC_URL}v2/images/emails/hackathons-neg.png',
'url': hackathon.url,
}

for sponsor_prize in sponsors_prizes:
sponsor_prize['name'] = sponsor_prize['sponsor'].name
sponsor_prize['image_url'] = sponsor_prize['sponsor'].logo.url if sponsor_prize['sponsor'].logo else f'{settings.STATIC_URL}v2/images/emails/hackathons-neg.png'

intro = f"{intro_begin} participating on a new hackathon on Gitcoin: "

params = {
'hackathon': hackathon,
'sponsors_prizes': sponsors_prizes,
'intro': intro,
'email_style': email_style,
'hide_bottom_logo': True,
}

response_html = premailer_transform(render_to_string("emails/tribe_hackathon_prizes.html", params))
response_txt = render_to_string("emails/tribe_hackathon_prizes.txt", params)

return response_html, response_txt

def render_request_amount_email(to_email, request, is_new):

Expand Down Expand Up @@ -1660,7 +1688,26 @@ def start_work_applicant_expired(request):
response_html, _, _ = render_start_work_applicant_expired(interest, bounty)
return HttpResponse(response_html)

@staff_member_required
def tribe_hackathon_prizes(request):
from dashboard.models import HackathonEvent
from marketing.utils import generate_hackathon_email_intro

hackathon = HackathonEvent.objects.filter(start_date__date=(timezone.now()+timezone.timedelta(days=3))).first()

sponsors_prizes = []
for sponsor in hackathon.sponsors.all()[:3]:
prizes = hackathon.get_current_bounties.filter(bounty_owner_profile=sponsor.tribe)
sponsor_prize = {
"sponsor": sponsor,
"prizes": prizes
}
sponsors_prizes.append(sponsor_prize)

intro_begin = generate_hackathon_email_intro(sponsors_prizes)

response_html, _ = render_tribe_hackathon_prizes(hackathon,sponsors_prizes, intro_begin)
return HttpResponse(response_html)

def render_remember_your_cart(grants_query, grants, hours):
params = {
Expand Down
8 changes: 6 additions & 2 deletions app/retail/templates/emails/bounty.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,14 @@
<li style="list-style:none; margin-left: 0;">
{% if bounty.avatar_url %}
<img style="border-radius: 20px; display: block; margin-left: auto; margin-right: auto; margin-bottom: 0.5em" src="{{ bounty.avatar_url }}" width=50px height=50px>
<a style="font-weight: bold; text-decoration: none;" href="{% url "profile" highlight.who %}">{{ bounty.org_name }}</a>
{% if not prize %}
<a style="font-weight: bold; text-decoration: none;" href="{% url "profile" highlight.who %}">{{ bounty.org_name }}</a>
{% endif %}
{% else %}
* <strong>{{ bounty.org_name }}</strong>
{% endif %}
<p style="margin-bottom: 10px; margin-top:0">
{% if prize %}<b>{% endif %}
{% if primer %}
{{ primer }}
{% elif bounty.title %}
Expand All @@ -70,6 +73,7 @@
{% endif %}
{{ bounty.title }}
{% endif %}
{% if prize %}</b>{% endif %}
</p>
</li>
</ul>
Expand Down Expand Up @@ -137,5 +141,5 @@
</p>
{% endif %}
{% endif %}
{% include 'emails/shared_bounty_actions.html' %}
{% include 'emails/shared_bounty_actions.html' with prize=prize %}
</div>
4 changes: 4 additions & 0 deletions app/retail/templates/emails/shared_bounty_actions.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
<div style="margin-bottom: 2em; margin-top: 2em;">
<a class="button" href="{{ action_url }}">{{ action_copy }}</a>
</div>
{% elif prize %}
<div style="margin-bottom: 1em; margin-top: 1em;">
<a class="button large" href="{{ bounty.absolute_url }}">{% trans "View Prize" %}</a>
</div>
{% else %}
<div style="margin-bottom: 1em; margin-top: 1em;">
<a class="button" href="{{ bounty.absolute_url }}">{% trans "View on Gitcoin.co" %}</a>
Expand Down
1 change: 1 addition & 0 deletions app/retail/templates/emails/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,7 @@
{% elif email_style == 26 %} <img id="logo" src="{% static "v2/images/emails/email_header26.png" %}" alt="Gitcoin" title="Gitcoin Logo">
{% elif email_style == 27 %} <img id="logo" src="{% static "v2/images/emails/email_header27.png" %}" alt="Gitcoin" title="Gitcoin Logo">
{% elif email_style == 28 %} <img id="logo" src="{% static "v2/images/emails/email_header28.png" %}" alt="Gitcoin" title="Gitcoin Logo">
{% elif email_style == 'hackathon' %} <img id="logo" src="{% static "v2/images/emails/email_header_hackathon.png" %}" alt="Gitcoin" title="Gitcoin Logo">
{% else %}
<img id="logo" src="{% static "v2/images/logo_large.png" %}" alt="Gitcoin" title="Gitcoin Logo">
{% endif %}
Expand Down
88 changes: 88 additions & 0 deletions app/retail/templates/emails/tribe_hackathon_prizes.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
{% extends 'emails/template.html' %}
{% comment %}
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
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
{% endcomment %}
{% load i18n humanize %}

{% block content %}

<style>
.sponsor-logo {
width: 65px;
height: 65px;
margin: 20px 0;
}
.hackathon-image {
width: 100%;
height: 200px;
margin-top: 30px;
background-color: #000000;
}
.left {
text-align: left;
}
.message {
margin-top: 3em;
margin-bottom: 0;
}
.container p a {
color: #3E00FF;
}
.inner-container {
width: 75%;
margin-left: auto;
margin-right: auto;
}
</style>

<div class="container" style="margin-bottom: 3em; padding: 0;">
<div class="inner-container">
{% for sponsor in sponsors_prizes %}
<img class="sponsor-logo" src="{{sponsor.image_url}}">
{% endfor %}
<h1>Win exciting prizes at {{ hackathon.name }}</h1>

<p class="left message"><b>{{intro}}<b>{{ hackathon.name }}</b> 🚀</p>

{% if hackathon %}
{% if hackathon.image_url %}
<img class="hackathon-image" src="{{hackathon.image_url}}">
{% endif %}
<div style="margin-bottom: 2em; margin-top: 2em;">
<a class="button large" href="{{ hackathon.url }}">Join Hackathon</a>
</div>
{% endif %}

<p class="left message">Meet a community of like-minded hackers, buidl cool stuff, and win these exciting prizes:</p>
<div style="margin-bottom: 3em;">
{% for sponsor in sponsors_prizes %}
{% if sponsor.prizes %}
<div style="margin: 4em 0">
<h3 style="text-decoration: underline;">Bounties by {{sponsor.name}}:</h3>
{% for prize in sponsor.prizes %}
{% include 'emails/bounty.html' with bounty=prize count=forloop.counter small=1 prize=1 %}
{% endfor %}
{% endif %}
</div>
{% endfor %}
</div>

<p class="left" style="margin-top: 5em;">See you @ <a href="{{ hackathon.url }}">{{ hackathon.name }}</a>!</p>

<p class="left">The Gitcoin team</p>
</div>
</div>
{% endblock %}
14 changes: 14 additions & 0 deletions app/retail/templates/emails/tribe_hackathon_prizes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Win exciting prizes with <br> {{ sponsor.name }}

{{ sponsor.name }} is participating on a new hackathon on Gitcoin: {{ hackathon.name }} 🚀

{% if prizes %}
Meet a community of like-minded hackers, buidl cool stuff, and win these exciting prizes:
{% for prize in prizes %}
{% include 'emails/bounty.html' with bounty=prize count=forloop.counter small=1 prize=1 %}
{% endfor %}
{% endif %}

See you @ {{ hackathon.name }}!

The Gitcoin team
1 change: 1 addition & 0 deletions scripts/crontab
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/us
15 10 * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash bounty_feedback_email >> /var/log/gitcoin/bounty_feedback_email.log 2>&1
15 10 * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash funder_stale_email 60 >> /var/log/gitcoin/funder_stale_email.log 2>&1
15 5 * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash new_bounties_email >> /var/log/gitcoin/new_bounties_email.log 2>&1
15 10 * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash tribe_hackathon_prizes_email >> /var/log/gitcoin/tribe_hackathon_prizes_email.log 2>&1
30 6 * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash post_data grants >> /var/log/gitcoin/post_data.log 2>&1
15 15 * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash post_data quote >> /var/log/gitcoin/post_data.log 2>&1
15 18 * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash post_data results >> /var/log/gitcoin/post_data.log 2>&1
Expand Down