-
-
Notifications
You must be signed in to change notification settings - Fork 775
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
Redesign Daily Email #6471
Redesign Daily Email #6471
Changes from 45 commits
ee2f26e
b009e5b
3615b3f
8140ead
a6aba03
c1fbab2
4796f68
c626e45
9d90bfc
a99e615
a1fd51b
2204c3b
04cad32
a91a9df
6908487
9160ee3
c88381e
30d89a1
275b3cf
f764e91
23dbd6d
f82e503
20fbe3b
f2fbe3e
99744a2
b309e75
39ddda1
0a15906
86b7d08
7cc39b1
0cb046a
02ae986
dd1bb60
ab81775
8f4e52c
d86ce29
2751f2c
fd83ff1
165d0a4
b22a7e7
12d1050
2f1ce82
c014741
d0bdd37
6fcb88a
feae48b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,7 +42,7 @@ | |
from cacheops import cached_view | ||
from chartit import PivotChart, PivotDataPool | ||
from chat.tasks import update_chat_notifications | ||
from dashboard.models import Profile, TokenApproval | ||
from dashboard.models import Profile, TokenApproval, HackathonEvent, Activity | ||
from dashboard.utils import create_user_action, get_orgs_perms, is_valid_eth_address | ||
from enssubdomain.models import ENSSubdomainRegistration | ||
from gas.utils import recommend_min_gas_price_to_confirm_in_time | ||
|
@@ -52,6 +52,7 @@ | |
from marketing.models import AccountDeletionRequest, EmailSubscriber, Keyword, LeaderboardRank | ||
from marketing.utils import delete_user_from_mailchimp, get_or_save_email_subscriber, validate_slack_integration | ||
from quests.models import Quest | ||
from grants.models import Grant | ||
from retail.emails import ALL_EMAILS, render_new_bounty, render_nth_day_email_campaign | ||
from retail.helpers import get_ip | ||
|
||
|
@@ -983,12 +984,38 @@ def trending_quests(): | |
).order_by('-recent_attempts').all()[0:10] | ||
return quests | ||
|
||
def quest_of_the_day(): | ||
quest = trending_quests()[0] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this guaranteed to be different day over day? id be annoyed if i got the same quest every day There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And Wouldn't number of recent attempts make the trending quests different each day? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think using the upstream changes is fine. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will rebase on upstream master and fix merge conflicts. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
return quest | ||
|
||
def upcoming_grant(): | ||
grant = Grant.objects.order_by('-weighted_shuffle').first() | ||
return grant | ||
|
||
def upcoming_hackathon(): | ||
try: | ||
return HackathonEvent.objects.filter(end_date__gt=timezone.now()).order_by('-start_date') | ||
except HackathonEvent.DoesNotExist: | ||
try: | ||
return [HackathonEvent.objects.filter(start_date__gte=timezone.now()).order_by('start_date').first()] | ||
except HackathonEvent.DoesNotExist: | ||
return None | ||
|
||
def latest_activities(user): | ||
from retail.views import get_specific_activities | ||
cutoff_date = timezone.now() - timezone.timedelta(days=7) | ||
activities = get_specific_activities('connect', 0, user, 0)[:4] | ||
return activities | ||
|
||
@staff_member_required | ||
def new_bounty_daily_preview(request): | ||
profile = request.user.profile | ||
keywords = profile.keywords | ||
hours_back = 2000 | ||
|
||
new_bounties, all_bounties = get_bounties_for_keywords(keywords, hours_back) | ||
quests = trending_quests() | ||
response_html, _ = render_new_bounty('[email protected]', new_bounties, all_bounties, offset=3, trending_quests=quests) | ||
max_bounties = 5 | ||
if len(new_bounties) > max_bounties: | ||
new_bounties = new_bounties[0:max_bounties] | ||
response_html, _ = render_new_bounty(settings.CONTACT_EMAIL, new_bounties, old_bounties='', offset=3, quest_of_the_day=quest_of_the_day(), upcoming_grant=upcoming_grant(), upcoming_hackathon=upcoming_hackathon(), latest_activities=latest_activities(request.user)) | ||
return HttpResponse(response_html) |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -529,10 +529,47 @@ def render_funder_stale(github_username, days=60, time_as_str='a couple months') | |||
return response_html, response_txt | ||||
|
||||
|
||||
def render_new_bounty(to_email, bounties, old_bounties, offset=3, trending_quests=[]): | ||||
def render_new_bounty(to_email, bounties, old_bounties, offset=3, quest_of_the_day={}, upcoming_grant={}, upcoming_hackathon={}, latest_activities={}, from_date=date.today(), days_ago=7): | ||||
from townsquare.utils import is_email_townsquare_enabled, is_there_an_action_available | ||||
email_style = (int(timezone.now().strftime("%-j")) + offset) % 24 | ||||
from dashboard.models import Profile | ||||
from inbox.models import Notification | ||||
sub = get_or_save_email_subscriber(to_email, 'internal') | ||||
|
||||
email_style = 26 | ||||
|
||||
# Get notifications count from the Profile.User of to_email | ||||
try: | ||||
profile = Profile.objects.filter(email__iexact=to_email).last() | ||||
except Profile.DoesNotExist: | ||||
pass | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we want to pass here instead of failing? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems all emails that come at |
||||
|
||||
from_date = from_date + timedelta(days=1) | ||||
to_date = from_date - timedelta(days=days_ago) | ||||
|
||||
try: | ||||
notifications_count = Notification.objects.filter(to_user=profile.user.id, is_read=False, created_on__range=[to_date, from_date]).count() | ||||
except Notification.DoesNotExist: | ||||
pass | ||||
|
||||
upcoming_events = [] | ||||
if upcoming_grant: | ||||
upcoming_events.append({ | ||||
'event': upcoming_grant, | ||||
'title': upcoming_grant.title, | ||||
'image_url': upcoming_grant.logo.url if upcoming_grant.logo else f'{settings.STATIC_URL}v2/images/emails/grants-neg.png', | ||||
'url': upcoming_grant.url, | ||||
'date': upcoming_grant.next_clr_calc_date.strftime("%Y-%d-%m") if upcoming_grant.next_clr_calc_date else upcoming_grant.created_on.strftime("%Y-%d-%m") | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is the CLR calc date being used here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you should use grants.views.after_that_next_round_begin instead probably this is just the clr calc date |
||||
}) | ||||
if upcoming_hackathon: | ||||
for hackathon in upcoming_hackathon: | ||||
upcoming_events.append({ | ||||
'event': hackathon, | ||||
'title': hackathon.name, | ||||
'image_url': hackathon.logo.url if hackathon.logo else f'{settings.STATIC_URL}v2/images/emails/hackathons-neg.png', | ||||
'url': hackathon.url, | ||||
'date': hackathon.start_date.strftime("%Y-%d-%m") | ||||
}) | ||||
|
||||
params = { | ||||
'old_bounties': old_bounties, | ||||
'bounties': bounties, | ||||
|
@@ -542,7 +579,10 @@ def render_new_bounty(to_email, bounties, old_bounties, offset=3, trending_quest | |||
'email_type': 'new_bounty_notifications', | ||||
'base_url': settings.BASE_URL, | ||||
'show_action': True, | ||||
'trending_quests': trending_quests, | ||||
'quest_of_the_day': quest_of_the_day, | ||||
'upcoming_events': upcoming_events, | ||||
'activities': latest_activities, | ||||
'notifications_count': notifications_count, | ||||
'show_action': is_email_townsquare_enabled(to_email) and is_there_an_action_available() | ||||
} | ||||
|
||||
|
@@ -560,7 +600,7 @@ def render_unread_notification_email_weekly_roundup(to_email, from_date=date.tod | |||
from_date = from_date + timedelta(days=1) | ||||
to_date = from_date - timedelta(days=days_ago) | ||||
|
||||
notifications = Notification.objects.filter(to_user=profile.id, is_read=False, created_on__range=[to_date, from_date]).count() | ||||
notifications = Notification.objects.filter(to_user=profile.user.id, is_read=False, created_on__range=[to_date, from_date]).count() | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice catch here! 👍 |
||||
|
||||
params = { | ||||
'subscriber': subscriber, | ||||
|
@@ -1146,7 +1186,7 @@ def weekly_recap(request): | |||
|
||||
@staff_member_required | ||||
def unread_notification_email_weekly_roundup(request): | ||||
response_html, _ = render_unread_notification_email_weekly_roundup('[email protected]') | ||||
response_html, _, _ = render_unread_notification_email_weekly_roundup('[email protected]') | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we render this email such that we use the requester's email rather than hardcode it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The hardcoded email was actually already there: Line 1138 in 144365c
response_html, _, _ is what I actually wanted to add because it's part of the bugfix above. See commit 18d165d
Could change it to:
Should I? |
||||
return HttpResponse(response_html) | ||||
|
||||
@staff_member_required | ||||
|
@@ -1224,9 +1264,10 @@ def resend_new_tip(request): | |||
@staff_member_required | ||||
def new_bounty(request): | ||||
from dashboard.models import Bounty | ||||
from marketing.views import quest_of_the_day, upcoming_grant, upcoming_hackathon, latest_activities | ||||
bounties = Bounty.objects.current().order_by('-web3_created')[0:3] | ||||
old_bounties = Bounty.objects.current().order_by('-web3_created')[0:3] | ||||
response_html, _ = render_new_bounty(settings.CONTACT_EMAIL, bounties, old_bounties, int(request.GET.get('offset', 2))) | ||||
response_html, _ = render_new_bounty(settings.CONTACT_EMAIL, bounties, old_bounties='', offset=int(request.GET.get('offset', 2)), quest_of_the_day=quest_of_the_day(), upcoming_grant=upcoming_grant(), upcoming_hackathon=upcoming_hackathon(), latest_activities=latest_activities(request.user)) | ||||
return HttpResponse(response_html) | ||||
|
||||
|
||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are you planning on updating the subject line of this email? right now it advertises new bounties. it should probalby not anymore.
@frankchen07 any thoughts on a great subject line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: (The?) Gitcoin Daily Digest
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@PixelantDesign @frankchen07 any thoughts here? Gitcoin Daily Digest is good but rather generic. i wonder if we should test adding dynamic data to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets go with "Gitcoin Daily (x Bounties, y quests/ z hacakthons)" where each variable is the number of each in the email
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 03137b3