Skip to content

Commit cfac30d

Browse files
committed
Merge remote-tracking branch 'origin/stable'
2 parents 20491a0 + e741f2e commit cfac30d

File tree

8 files changed

+245
-19
lines changed

8 files changed

+245
-19
lines changed

app/dashboard/templates/bounty/details2.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ <h4 id="title" class="font-title p-0 text-center text-lg-left">[[bounty.title]]<
6666
<span id="value_in_token">[[ bounty.value_true ]] [[ bounty.token_name ]]</span>
6767
</p>
6868
</div>
69-
<div v-if="bounty.web3_type == 'qr'" id="value_in_usdt_wrapper" class="tag usd ml-3" data-toggle="tooltip" data-html="true" :title='`<div class="tooltip-info">The funding in this bounty adds up to $${bounty.value_in_usdt_now} USD </div>`'>
69+
<div v-if="bounty.value_in_usdt_now" id="value_in_usdt_wrapper" class="tag usd ml-3" data-toggle="tooltip" data-html="true" :title='`<div class="tooltip-info">The funding in this bounty adds up to $${bounty.value_in_usdt_now} USD </div>`'>
7070
<p class="inner-tooltip">
7171
<span id="value_in_usdt">[[bounty.value_in_usdt_now]]</span>
7272
<span>USD</span>

app/dashboard/templates/dashboard/hackathon/onboard.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,11 +251,11 @@ <h4 class="text-uppercase font-weight-bolder text-left">How does the Hackathon w
251251
</div>
252252
<div class="col-12 col-md-6 d-flex flex-column justify-content-center pt-4 pt-md-0">
253253
<b class="counter">{% trans "Check out the Prizes" %}</b>
254-
{% blocktrans %}
254+
255255
<p class="">
256-
Visit the <a target="_blank" href="{{ hackathon_url }}#bounties">Prize Explorer</a> to check out the prizes posted by our hackathon sponsors. Click each prize to show important details, including the submission requirements, submission deadline, etc.
256+
Visit the <a target="_blank" href="{% url 'hackathon' hackathon.slug %}">Prize Explorer</a> to check out the prizes posted by our hackathon sponsors. Click each prize to show important details, including the submission requirements, submission deadline, etc.
257257
</p>
258-
{% endblocktrans %}
258+
259259
</div>
260260
</div>
261261
<div class="row px-5 my-5">
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# -*- coding: utf-8 -*-
2+
"""Define the Grant subminer management command.
3+
4+
Copyright (C) 2020 Gitcoin Core
5+
6+
This program is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU Affero General Public License as published
8+
by the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU Affero General Public License for more details.
15+
16+
You should have received a copy of the GNU Affero General Public License
17+
along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
19+
"""
20+
from datetime import datetime
21+
22+
from django.conf import settings
23+
from django.core.management.base import BaseCommand
24+
from django.db.models import Max, F
25+
from django.utils import timezone
26+
27+
from dashboard.utils import get_tx_status, has_tx_mined
28+
from grants.clr import predict_clr
29+
from grants.models import Contribution, Grant, CartActivity, Subscription
30+
from grants.views import clr_active, round_end, next_round_start
31+
from marketing.mails import warn_subscription_failed, remember_your_cart
32+
from townsquare.models import MatchRound
33+
34+
35+
class Command(BaseCommand):
36+
help = 'Sent reminder to user who forgot its cart '
37+
38+
def add_arguments(self, parser):
39+
parser.add_argument(
40+
'--test',
41+
default=False,
42+
type=bool,
43+
help="Only process and display the carts to being delivered"
44+
)
45+
parser.add_argument(
46+
'--full-cart',
47+
default=False,
48+
type=bool,
49+
help="Should the cart being delivered partially"
50+
)
51+
parser.add_argument(
52+
'--hours',
53+
type=int,
54+
help="Should the cart being delivered partially"
55+
)
56+
57+
58+
def handle(self, *args, **options):
59+
last_activity_by_user = CartActivity.objects.filter(latest=True, created_on__gt=next_round_start).exclude(metadata=[])
60+
count = 0
61+
if options.get('hours'):
62+
hours = options.get('hours')
63+
else:
64+
hours = int((round_end - datetime.now()).total_seconds() / 3600)
65+
66+
for activity in last_activity_by_user:
67+
print(activity)
68+
69+
# Check if this cart is still valid
70+
no_checkout_grants = []
71+
for grant_entry in activity.metadata:
72+
subscription = Subscription.objects.filter(grant_id=grant_entry['grant_id'],
73+
contributor_profile=activity.profile,
74+
created_on__gt=activity.created_on,
75+
created_on__lte=round_end).first()
76+
77+
if not subscription:
78+
no_checkout_grants.append(grant_entry)
79+
80+
if options['full_cart']:
81+
if len(no_checkout_grants) != len(activity.metadata):
82+
print(f' * Activity {activity.id}: The grants were partially contributed but no notification will be delivered')
83+
continue
84+
85+
cart_query = [f'{grant["grant_id"]};{grant.get("grant_donation_amount", 5)};{grant.get("token_local_id", 283)}'
86+
for grant in no_checkout_grants]
87+
88+
cart_query = ','.join(cart_query)
89+
90+
if not cart_query:
91+
print(f'** No items left in the {activity.profile}\'s cart')
92+
continue
93+
94+
if not options['test']:
95+
try:
96+
remember_your_cart(activity.profile, cart_query, no_checkout_grants, hours)
97+
count += 1
98+
except Exception as e:
99+
print(f'!! Failed to sent cart reminder email to {activity.profile}')
100+
print(e)
101+
102+
print(f'\n\nSent {count} emails of {last_activity_by_user.count()} carts')
103+

app/grants/templates/grants/detail/tabs.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ <h4>Grant Sybil Profile</h4>
114114
- Suspicious Ethereum Interactions
115115
- Suspicious SMS Address
116116
- Suspicious Account Activity
117+
- BrightID Trust Score (coming soon)
118+
- Idena Network Trust Score (coming soon)
119+
- KYC (maybe coming soon)
117120

118121
a grant's RiskScore ™️ is equal to its SybilScore ™️ * its matching funds for this round.
119122
</pre>

app/marketing/mails.py

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
render_start_work_approved, render_start_work_new_applicant, render_start_work_rejected,
4646
render_subscription_terminated_email, render_successful_contribution_email, render_support_cancellation_email,
4747
render_tax_report, render_thank_you_for_supporting_email, render_tip_email,
48-
render_unread_notification_email_weekly_roundup, render_wallpost, render_weekly_recap,
48+
render_unread_notification_email_weekly_roundup, render_wallpost, render_weekly_recap, render_remember_your_cart,
4949
)
5050
from sendgrid.helpers.mail import Attachment, Content, Email, Mail, Personalization
5151
from sendgrid.helpers.stats import Category
@@ -118,7 +118,7 @@ def send_mail(from_email, _to_email, subject, body, html=False,
118118
mail.add_attachment(attachment)
119119

120120
# debug logs
121-
logger.info(f"-- Sending Mail '{subject}' to {to_email.email}")
121+
logger.info(f"-- Sending Mail '{subject}' to {to_email}")
122122
try:
123123
response = sg.client.mail.send.post(request_body=mail.get())
124124
except UnauthorizedError as e:
@@ -1031,7 +1031,7 @@ def grant_match_distribution_test_txn(match):
10311031
coupon = f"Pick up ONE item of Gitcoin Schwag at http://store.gitcoin.co/ at 50% off with coupon code {settings.GRANTS_COUPON_50_OFF}"
10321032
if match.amount > 1000:
10331033
coupon = f"Pick up ONE item of Gitcoin Schwag at http://store.gitcoin.co/ at 100% off with coupon code {settings.GRANTS_COUPON_100_OFF}"
1034-
# NOTE: IF YOURE A CLEVER BISCUT AND FOUND THIS BY READING OUR CODEBASE,
1034+
# NOTE: IF YOURE A CLEVER BISCUT AND FOUND THIS BY READING OUR CODEBASE,
10351035
# THEN GOOD FOR YOU! HERE IS A 100% OFF COUPON CODE U CAN USE (LIMIT OF 1 FOR THE FIRST PERSON
10361036
# TO FIND THIS EASTER EGG) : GRANTS-ROUND-5-HAXXOR
10371037
try:
@@ -1090,9 +1090,9 @@ def grant_match_distribution_final_txn(match):
10901090
10911091
We have sent your {rounded_amount} DAI to the address on file at {match.grant.admin_address}. The txid of this transaction is {match.payout_tx}.
10921092
1093-
Congratulations on a successful Gitcoin Grants Round {match.round_number}.
1093+
Congratulations on a successful Gitcoin Grants Round {match.round_number}.
10941094
1095-
What now?
1095+
What now?
10961096
1. Send a tweet letting us know how these grant funds are being used to support your project (our twitter username is @gitcoin).
10971097
2. Remember to update your grantees on what you use the funds for by clicking through to your grant ( https://gitcoin.co{match.grant.get_absolute_url()} ) and posting to your activity feed.
10981098
3. Celebrate 🎉 and then get back to BUIDLing something great. 🛠
@@ -1216,7 +1216,7 @@ def new_bounty_daily(bounties, old_bounties, to_emails=None):
12161216
bounties = bounties[0:max_bounties]
12171217
if to_emails is None:
12181218
to_emails = []
1219-
1219+
12201220
from marketing.views import quest_of_the_day, upcoming_grant, upcoming_hackathon, latest_activities, upcoming_dates, upcoming_dates, email_announcements
12211221
quest = quest_of_the_day()
12221222
grant = upcoming_grant()
@@ -1258,7 +1258,7 @@ def new_bounty_daily(bounties, old_bounties, to_emails=None):
12581258
elif old_bounties:
12591259
plural_old_bounties = "Bounties" if len(old_bounties)>1 else "Bounty"
12601260
new_bounties = f"💰{len(old_bounties)} {plural_old_bounties}"
1261-
1261+
12621262
new_quests = ""
12631263
if quest:
12641264
new_quests = f"🎯1 Quest"
@@ -1551,7 +1551,7 @@ def quarterly_stats(to_emails=None, platform_wide_stats=None):
15511551
)
15521552
finally:
15531553
translation.activate(cur_language)
1554-
1554+
15551555

15561556
def tax_report(to_emails=None, zip_paths=None, tax_year=None):
15571557
if to_emails is None:
@@ -1570,18 +1570,18 @@ def tax_report(to_emails=None, zip_paths=None, tax_year=None):
15701570
html, text = render_tax_report(to_email, tax_year)
15711571
from_email = settings.CONTACT_EMAIL
15721572
send_mail(
1573-
from_email,
1574-
to_email,
1575-
subject,
1576-
text,
1577-
html,
1573+
from_email,
1574+
to_email,
1575+
subject,
1576+
text,
1577+
html,
15781578
from_name="Kevin Owocki (Gitcoin.co)",
15791579
categories=['marketing', func_name()],
15801580
zip_path=zip_paths[idx]
15811581
)
1582-
finally:
1582+
finally:
15831583
translation.activate(cur_language)
1584-
1584+
15851585

15861586
def bounty_expire_warning(bounty, to_emails=None):
15871587
if not bounty or not bounty.value_in_usdt_now:
@@ -1903,3 +1903,19 @@ def fund_request_email(request, to_emails, is_new=False):
19031903
send_mail(from_email, to_email, subject, text, html, categories=['transactional', func_name()])
19041904
finally:
19051905
translation.activate(cur_language)
1906+
1907+
1908+
def remember_your_cart(profile, cart_query, grants, hours):
1909+
to_email = profile.email
1910+
from_email = settings.CONTACT_EMAIL
1911+
1912+
cur_language = translation.get_language()
1913+
try:
1914+
setup_lang(to_email)
1915+
subject = f"⏱{hours} hours left 🛒 Your grant cart is waiting for you 🛒"
1916+
html, text = render_remember_your_cart(cart_query, grants, hours)
1917+
1918+
if not should_suppress_notification_email(to_email, 'grant_updates'):
1919+
send_mail(from_email, to_email, subject, text, html, categories=['marketing', func_name()])
1920+
finally:
1921+
translation.activate(cur_language)

app/retail/emails.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1621,3 +1621,18 @@ def start_work_applicant_expired(request):
16211621
bounty = Bounty.objects.last()
16221622
response_html, _, _ = render_start_work_applicant_expired(interest, bounty)
16231623
return HttpResponse(response_html)
1624+
1625+
1626+
1627+
def render_remember_your_cart(grants_query, grants, hours):
1628+
params = {
1629+
'base_url': settings.BASE_URL,
1630+
'desc': f'Only left {hours} hours until the end of the match round and seems you have some grants on your cart',
1631+
'cart_query': grants_query,
1632+
'grants': grants
1633+
}
1634+
1635+
response_html = premailer_transform(render_to_string("emails/cart.html", params))
1636+
response_txt = render_to_string("emails/cart.txt", params)
1637+
1638+
return response_html, response_txt

app/retail/templates/emails/cart.html

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
{% extends 'emails/template.html' %}
2+
{% comment %}
3+
Copyright (C) 2020 Gitcoin Core
4+
5+
This program is free software: you can redistribute it and/or modify
6+
it under the terms of the GNU Affero General Public License as published
7+
by the Free Software Foundation, either version 3 of the License, or
8+
(at your option) any later version.
9+
10+
This program is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
GNU Affero General Public License for more details.
14+
15+
You should have received a copy of the GNU Affero General Public License
16+
along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
{% endcomment %}
18+
{% load i18n humanize %}
19+
20+
{% block content %}
21+
22+
<style>
23+
.arrow-up{
24+
width: 0;
25+
height: 0;
26+
border-left: 15px solid transparent;
27+
border-right: 15px solid transparent;
28+
border-bottom: 15px solid #ddd;
29+
margin-left: auto;
30+
margin-right: auto;
31+
}
32+
33+
#founder_announce {
34+
background-color: #fafafa;
35+
margin-bottom: 15px;
36+
}
37+
38+
#founder_announce a{
39+
font-weight: bold;
40+
}
41+
</style>
42+
43+
<div>
44+
<h1 class="text-centre">{% trans "Your cart is waiting for you" %}</h1>
45+
</div>
46+
47+
<a href="https://gitcoin.co/owocki">
48+
<img style="width: 100px; height: 100px;" src="https://gitcoin.co/dynamic/avatar/owocki">
49+
</a>
50+
<div class="arrow-up">&nbsp;</div>
51+
<div id="founder_announce" style="border: 1px solid #ddd; max-width: 500px; text-align: center; margin-left: auto; margin-right: auto; margin-bottom: 25px;">
52+
<p style="margin: 5px; border-radius: 5px;">
53+
{{desc|safe}}
54+
</p>
55+
</div>
56+
57+
<HR>
58+
59+
<div>
60+
<p style="margin: 5px; border-radius: 5px;">
61+
You have the following {{grants|length}} grants in your cart:
62+
</p>
63+
<ol>
64+
{% for grant in grants %}
65+
<li><b>{{ grant.grant_title }}</b> ({{ grant.grant_donation_amount|default:5 }} {{ grant.grant_donation_currency|default:"DAI" }})</li>
66+
{% endfor %}
67+
</ol>
68+
</div>
69+
70+
<HR>
71+
72+
<a href={{base_url}}>
73+
<div style="margin-bottom: 2em; margin-top: 2em;">
74+
<a class="button large" href="{{base_url}}{% url 'grants:grants_bulk_add' cart_query %}">{% trans "Go to cart" %}</a>
75+
</div>
76+
</a>
77+
78+
79+
{% endblock %}

app/retail/templates/emails/cart.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Your cart is waiting for you
2+
3+
{{ desc }}.
4+
5+
Your cart grants:
6+
{% for grant in grants %}
7+
- {{ grant.grant_title }} ({{ grant.grant_donation_amount|default:5 }} {{ grant.grant_donation_currency|default:"DAI" }})
8+
{% endfor %}
9+
10+
Checkout your cart: {{base_url}}{% url 'grants:grants_bulk_add' cart_query %}

0 commit comments

Comments
 (0)