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

chore: email setup no applicant bounty #5062

Merged
merged 4 commits into from
Sep 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,11 @@
retail.emails.funder_payout_reminder,
name='funder_payout_reminder'
),
re_path(
r'^_administration/email/no_applicant_reminder$',
retail.emails.no_applicant_reminder,
name='no_applicant_reminder'
),

# settings
re_path(r'^settings/email/(.*)', marketing.views.email_settings, name='email_settings'),
Expand Down
27 changes: 25 additions & 2 deletions app/marketing/mails.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
render_featured_funded_bounty, render_funder_payout_reminder, render_funder_stale, render_gdpr_reconsent,
render_gdpr_update, render_grant_cancellation_email, render_kudos_email, render_match_email, 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_nth_day_email_campaign, render_quarterly_stats,
render_reserved_issue, render_share_bounty, render_start_work_applicant_about_to_expire,
render_new_supporter_email, render_new_work_submission, render_no_applicant_reminder, render_nth_day_email_campaign,
render_quarterly_stats, 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_thank_you_for_supporting_email, render_tip_email,
Expand Down Expand Up @@ -527,6 +527,29 @@ def funder_payout_reminder(to_email, bounty, github_username, live):
return html


def no_applicant_reminder(to_email, bounty):
from_email = settings.SERVER_EMAIL
subject = "Get more applicants on your bounty"
html, text = render_no_applicant_reminder(to_email=to_email, bounty=bounty)
if (live):
try:
send_mail(
from_email,
to_email,
subject,
text,
html,
from_name="No Reply from Gitcoin.co",
categories=['marketing', func_name()],
Copy link
Contributor

Choose a reason for hiding this comment

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

not sure if this should be transactional.

)
except Exception as e:
logger.warning(e)
return False
return True
else:
return html


def share_bounty(emails, msg, profile, invite_url=None, kudos_invite=False):
for email in emails:
to_email = email
Expand Down
48 changes: 48 additions & 0 deletions app/marketing/management/commands/no_applicants_email.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'''
Copyright (C) 2019 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/>.

'''
from django.conf import settings
from django.core.management.base import BaseCommand
from django.db.models import Q
from django.utils import timezone

from dashboard.models import Bounty
from marketing.mails import no_applicant_reminder


class Command(BaseCommand):

help = 'sends reminder emails to funders whose bounties have 0 applications'
thelostone-mc marked this conversation as resolved.
Show resolved Hide resolved

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

start_time_3_days = timezone.now() - timezone.timedelta(hours=24 * 3)
end_time_3_days = timezone.now() - timezone.timedelta(hours=24 * 4)

start_time_7_days = timezone.now() - timezone.timedelta(hours=24 * 7)
end_time_7_days = timezone.now() - timezone.timedelta(hours=24 * 8)
bounties = Bounty.objects.current().filter(
network='mainnet',
(Q(created_on__range=[end_time_3_days, start_time_3_days]) | Q(created_on__range=[end_time_7_days, start_time_7_days]))
idx_status='open',
)

for bounty in [b for b in bounties if b.no_of_applicants == 0]:
Copy link
Contributor

Choose a reason for hiding this comment

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

cool this will solve contest bounties.

no_applicant_reminder(bounty.bounty_owner_email, bounty)
35 changes: 32 additions & 3 deletions app/retail/emails.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,6 @@ def render_quarterly_stats(to_email, platform_wide_stats):
params = {**quarterly_stats, **platform_wide_stats}
params['profile'] = profile
params['subscriber'] = get_or_save_email_subscriber(to_email, 'internal'),
print(params)
response_html = premailer_transform(render_to_string("emails/quarterly_stats.html", params))
response_txt = render_to_string("emails/quarterly_stats.txt", params)

Expand All @@ -322,6 +321,16 @@ def render_funder_payout_reminder(**kwargs):
return response_html, response_txt


def render_no_applicant_reminder(bounty):
params = {
'bounty': bounty,
'directory_link': '/users?skills=' + bounty.keywords.lower()
Copy link
Member Author

@thelostone-mc thelostone-mc Aug 23, 2019

Choose a reason for hiding this comment

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

@octavioamu / @PixelantDesign so if the bounty has keywords Python, javascript, MySQL , Moloch
The button would redirect to all those filters being applied => and no users would be shown as we would be searching for user who has all those 4 skills (especially Moloch)

We could match this against an exhaustive list at our end but even then we would end up with 3 skillm Python, javascript, MySQL and we might not have users with all 3 filters

Copy link
Contributor

Choose a reason for hiding this comment

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

I think is ok, since the skills needed are that. The users search will open without results and then the user can remove skills and filter new stuff to match the ones he need.

}
response_html = premailer_transform(render_to_string("emails/bounty/no_applicant_reminder.html", params))
response_txt = render_to_string("emails/bounty/no_applicant_reminder.txt", params)
return response_html, response_txt


def render_bounty_feedback(bounty, persona='submitter', previous_bounties=[]):
previous_bounties_str = ", ".join([bounty.github_url for bounty in previous_bounties])
if persona == 'fulfiller':
Expand Down Expand Up @@ -954,8 +963,8 @@ def render_new_bounty_roundup(to_email):
'url': 'https://github.com/ethresearch/eth-wiki/issues/9',
'primer': 'Correcting Merkle Patricia Trie Example',
}, ]


num_leadboard_items = 5
highlight_kudos_ids = []
num_kudos_to_show = 15
Expand Down Expand Up @@ -1163,6 +1172,26 @@ def funder_payout_reminder(request):
response_html, _ = render_funder_payout_reminder(bounty=bounty, github_username=github_username)
return HttpResponse(response_html)


@staff_member_required
def no_applicant_reminder(request):
"""Display the no applicant for bounty reminder email template.

Params:
username (str): The Github username to reference in the email.

Returns:
HttpResponse: The HTML version of the templated HTTP response.

"""
from dashboard.models import Bounty
bounty = Bounty.objects.filter(
idx_status='open', current_bounty=True, interested__isnull=True
).first()
response_html, _ = render_no_applicant_reminder(bounty=bounty)
return HttpResponse(response_html)


@staff_member_required
def funder_stale(request):
"""Display the stale funder email template.
Expand Down
2 changes: 1 addition & 1 deletion app/retail/templates/emails/bounty.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
}
</style>

<div class="centered-contents bounty-box">
<div class="text-center bounty-box">
{% if primer %}
<div class="bounty-primer">
<p>{{ primer }}<p>
Expand Down
117 changes: 117 additions & 0 deletions app/retail/templates/emails/bounty/no_applicant_reminder.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
{% extends 'emails/template.html' %}
{% comment %}
Copyright (C) 2019 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>
h1 {
font-size: 2rem;
}

h2 a {
color: black;
text-decoration: none;
font-size: 1.5rem;
font-weight: 300;
}

p {
font-size: 1.1rem;
font-weight: 300;
max-width: 35rem;
line-height: 25px;
margin-left: auto;
margin-right: auto;
}

.tag.token {
background-color: #e7f0fa;
color: #3E00FF;
}

.tag.usd {
background-color: #d6fbeb;
color: #00A55E;
}

.tag {
text-align: center;
margin: 4px;
border-radius: 2px;
padding: 3px 12px;
cursor: pointer;
white-space: nowrap;
display: inline-block;
}

.tag p {
font-weight: 500;
font-size: 0.85rem;
margin: 0;
}

.bounty-box {
max-width: 50rem;
}

.btn-container {
margin-top: 4rem;
}
</style>

<div class="bounty-box">
<h1>Get more applicants on your bounty</h2>

<p class="mb-0 mt-4">We noticed you dont have any contributors on your bounty.</p>
<p class="mt-1">
Go to the Users Directory to discover and invite the best contributors
for your bounty!
</p>

{% if bounty %}
<img class="rounded mt-3" src="{{ bounty.avatar_url }}" width="100" height="100">

<h2>
<a href="{{ bounty.absolute_url }}">
{{ bounty.title }}
</a>
</h2>

<div class="tag token">
<p>
<span>{{ bounty.token_name }}</span>
<span>{{ bounty.value_true }}</span>
</p>
</div>

<div class="tag usd">
<p>
<span>{{ bounty.value_in_usdt_now }}</span>
<span>USD</span>
</p>
</div>

{% endif %}

<p class="btn-container">
<a class="button" href="{{ directory_link }}">GO TO USERS DIRECTORY</a>
</p>
</div>
{% endblock %}
12 changes: 12 additions & 0 deletions app/retail/templates/emails/bounty/no_applicant_reminder.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{% load humanize %}

Get more applicant on your bounty!

We noticed you dont have any contributors on your bounty
Bounty Title : {{ bount.title }}
Bounty Link : {{ bounty.absolute_url }}
Bounty Amount : {{ bounty.value_true }} {{ bounty.token_name }}
Bounty Amount (USD) : {{ bounty.value_in_usdt_now }} USD

Go to the Users Directory {{ directory_link }} to discover and invite the best contributors
for your bounty!
2 changes: 1 addition & 1 deletion app/retail/templates/emails/bounty_roundup.html
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ <h5>{% trans "Grow Open Source &amp; Make Some ETH" %}</h5>
{% include 'emails/bounty.html' with bounty=bounty.obj small=1 primer=bounty.primer %}
{% endfor %}

<div class="centered-contents">
<div class="text-center">
<p>{% trans "Don't see anything that strikes your fancy above?" %}</p>
<p>{% trans "There are more issues in the Gitcoin Issue Explorer:" %}</p>

Expand Down
8 changes: 1 addition & 7 deletions app/retail/templates/emails/bounty_small.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,6 @@
{% load i18n humanize %}

<style>
.bounty-box {
margin-bottom: 1em;
padding-top: 1.5em;
padding-bottom: 1em;
border-bottom: 1px solid #e0e0e0;
}

.bounty-avatar {
text-align: right;
Expand Down Expand Up @@ -52,7 +46,7 @@
}
</style>

<div class="centered-contents bounty-box {% if count|divisibleby:2 %}even{%else%}odd{%endif%}">
<div class="text-center bounty-box {% if count|divisibleby:2 %}even{%else%}odd{%endif%}">
{% if primer %}
<div class="bounty-primer">
<p>{{primer}}<p>
Expand Down
8 changes: 4 additions & 4 deletions app/retail/templates/emails/funded_featured_bounty.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<h1 style="margin-top: 50px;">{% trans "Your bounty is now live!" %}</h1>
<h2 style="margin-top: 10px;">{% trans "(& being sent to Gitcoin's worldwide community of developers)" %}</h2>

<div class="primary-content centered-contents" style="margin-top: 40px;">
<div class="primary-content text-center" style="margin-top: 40px;">
<img id="funded_featured_bounty" width="400" src="{% static "v2/images/emails/funded_featured_bounty.png" %}" alt="Funded featured bounty" title="Grow Open Source Image" style="max-width: 100%;">

<div style="margin-bottom: 20px;">
Expand Down Expand Up @@ -57,9 +57,9 @@ <h2 style="margin-top: 10px;">{% trans "(& being sent to Gitcoin's worldwide com
</div>
</div>
</div>
<div class="centered-contents" >
<div class="text-center" >
{% if bounty.is_featured %}
<div class="centered-contents" style="display: flex; justify-content: center; border-top: 1px solid #979797; border-bottom: 1px solid #979797; padding: 50px; text-align: center">
<div class="text-center" style="display: flex; justify-content: center; border-top: 1px solid #979797; border-bottom: 1px solid #979797; padding: 50px; text-align: center">
<img src="{% static "v2/images/emails/funded_featured_bounty_banner.png" %}" width="100" style="margin-right: 30px" alt="Featured bounty avatar" id="featured_bounty_detail_image">
<div style="margin-top: 30px;">
<h3 style="color: #0D0764; text-align: justify;">{% trans "Your bounty is now featured" %}</h3>
Expand All @@ -68,7 +68,7 @@ <h3 style="color: #0D0764; text-align: justify;">{% trans "Your bounty is now fe
</div>
{% endif %}
{% if bounty.repo_type == 'private' %}
<div class="centered-contents" style="border-top: 1px solid #979797; border-bottom: 1px solid #979797; padding: 50px; text-align: center;">
<div class="text-center" style="border-top: 1px solid #979797; border-bottom: 1px solid #979797; padding: 50px; text-align: center;">
<h3 style="font-size: 2.1em;">{% trans "What to do next" %}</h3>

<div style="padding: 20px 10px 20px; text-align: center;" class="desktop-col">
Expand Down
2 changes: 1 addition & 1 deletion app/retail/templates/emails/kudos_mint.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ <h3>
</div>
</div>

<div class="centered-contents kudos-box">
<div class="text-center kudos-box">
<div class="kudos">
<div class="kudos-contents">

Expand Down
2 changes: 1 addition & 1 deletion app/retail/templates/emails/new_bounty_acceptance.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ <h1>🌈 {% trans "Funds Paid!" %} 🌈</h1>
<!-- {% include 'emails/bounty.html' with bounty=bounty %} -->

{% if unrated_count > 0 %}
<div class="centered-contents" style="border-bottom: 1px solid #979797; padding: 50px; text-align: center">
<div class="text-center" style="border-bottom: 1px solid #979797; padding: 50px; text-align: center">
<img src="{% static "v2/images/emails/rate-capture.png" %}" width="341" style="max-width: 100%;" alt="capture rating" id="capture_rating">
<div style="margin-top: 30px;">
<h3 style="color: #0D0764; text-align: center;">{% trans "How was your experience?" %}</h3>
Expand Down
2 changes: 1 addition & 1 deletion app/retail/templates/emails/new_tip.html
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ <h3>
</h3>
</div>

<div class="centered-contents tip-box">
<div class="text-center tip-box">
<div class="tip">
<div class="tip-contents">
{% if tip.github_url %}
Expand Down
Loading