Skip to content

Commit

Permalink
Merge branch 'stable'
Browse files Browse the repository at this point in the history
  • Loading branch information
owocki committed Sep 23, 2020
2 parents 7600a82 + 639e903 commit 7bd9fdc
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 84 deletions.
2 changes: 1 addition & 1 deletion app/dashboard/templates/dashboard/users-elastic.html
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ <h5 class="text-center card-user_name">
{% include 'shared/analytics.html' %}
{% include 'shared/footer_scripts.html' with slim="1" %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.5.1/vuex.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/innersearch.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/vue-innersearch.min.js"></script>
<script>
$('body').bootstrapTooltip({
selector: '[data-toggle="tooltip"]'
Expand Down
17 changes: 16 additions & 1 deletion app/marketing/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,21 @@
)


class RoundupEmailAdmin(admin.ModelAdmin):
ordering = ['-id']
list_display = ['created_on', '__str__']

def response_change(self, request, obj):
if "_send_roundup_email_myself" in request.POST:
from marketing.tasks import weekly_roundup
weekly_roundup.delay(request.user.profile.email)
self.message_user(request, "Roundup Email Queued!")
if "_send_roundup_email_everyone" in request.POST:
from marketing.tasks import send_all_weekly_roundup
send_all_weekly_roundup.delay()
self.message_user(request, "Roundup Email Queued!")
return super().response_change(request, obj)

class GeneralAdmin(admin.ModelAdmin):
ordering = ['-id']
list_display = ['created_on', '__str__']
Expand Down Expand Up @@ -136,4 +151,4 @@ def membership_length_in_days(self, instance):
admin.site.register(SlackUser, SlackUserAdmin)
admin.site.register(SlackPresence, SlackPresenceAdmin)
admin.site.register(GithubOrgToTwitterHandleMapping, GeneralAdmin)
admin.site.register(RoundupEmail, GeneralAdmin)
admin.site.register(RoundupEmail, RoundupEmailAdmin)
71 changes: 50 additions & 21 deletions app/marketing/mails.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,39 @@ def send_mail(from_email, _to_email, subject, body, html=False,
return response


def validate_email(email):

import re
regex = r'^[a-z0-9]+[\._]?[a-z0-9]+[@]\w+[.]\w{2,3}$'
if(re.search(regex,email)):
return True
return False

def get_bounties_for_keywords(keywords, hours_back):
from dashboard.models import Bounty
new_bounties_pks = []
all_bounties_pks = []

new_bounty_cutoff = (timezone.now() - timezone.timedelta(hours=hours_back))
all_bounty_cutoff = (timezone.now() - timezone.timedelta(days=60))

for keyword in keywords:
relevant_bounties = Bounty.objects.current().filter(
network='mainnet',
idx_status__in=['open'],
).keyword(keyword).exclude(bounty_reserved_for_user__isnull=False)
for bounty in relevant_bounties.filter(web3_created__gt=new_bounty_cutoff):
new_bounties_pks.append(bounty.pk)
for bounty in relevant_bounties.filter(web3_created__gt=all_bounty_cutoff):
all_bounties_pks.append(bounty.pk)
new_bounties = Bounty.objects.filter(pk__in=new_bounties_pks).order_by('-_val_usd_db')
all_bounties = Bounty.objects.filter(pk__in=all_bounties_pks).exclude(pk__in=new_bounties_pks).order_by('-_val_usd_db')

new_bounties = new_bounties.order_by('-admin_mark_as_remarket_ready')
all_bounties = all_bounties.order_by('-admin_mark_as_remarket_ready')

return new_bounties, all_bounties

def nth_day_email_campaign(nth, subscriber):
firstname = subscriber.email.split('@')[0]

Expand Down Expand Up @@ -1241,46 +1274,41 @@ def reject_faucet_request(fr):
translation.activate(cur_language)


def new_bounty_daily(bounties, old_bounties, to_emails=None, featured_bounties=[]):
def new_bounty_daily(es):

to_email = es.email
keywords = es.keywords
bounties, old_bounties = get_bounties_for_keywords(keywords, 24)
max_bounties = 5
if len(bounties) > max_bounties:
bounties = bounties[0:max_bounties]
if to_emails is None:
to_emails = []

to_emails = [to_email]

from townsquare.utils import is_email_townsquare_enabled
from marketing.views import quest_of_the_day, upcoming_grant, upcoming_hackathon, latest_activities, upcoming_dates, upcoming_dates, email_announcements
quest = quest_of_the_day()
grant = upcoming_grant()
dates = list(upcoming_hackathon()) + list(upcoming_dates())
announcements = email_announcements()
chats_count = 0
town_square_enabled = is_email_townsquare_enabled(to_email)
should_send = bounties.count() or town_square_enabled
if not should_send:
return False

offers = f""
if to_emails:
offers = ""

profile = email_to_profile(to_emails[0])
chat = ""
if profile:
try:
chats_count = profile.chat_num_unread_msgs
except:
chats_count = 0
if chats_count:
plural = 's' if chats_count > 1 else ''
chat = f"💬 {chats_count} Chat{plural}"

notifications = get_notification_count(profile, 7, timezone.now())
if notifications:
plural = 's' if notifications > 1 else ''
notifications = f"🔵 {notifications} Notification{plural}"
notifications = f"💬 {notifications} Notification{plural}"
else:
notifications = ''
has_offer = is_email_townsquare_enabled(to_emails[0]) and is_there_an_action_available()
if has_offer:
offers = f"⚡️ 1 New Action"
else:
offers = ""

new_bounties = ""
if bounties:
Expand All @@ -1289,7 +1317,7 @@ def new_bounty_daily(bounties, old_bounties, to_emails=None, featured_bounties=[
elif old_bounties:
plural_old_bounties = "Bounties" if len(old_bounties)>1 else "Bounty"
new_bounties = f"💰{len(old_bounties)} {plural_old_bounties}"

new_quests = ""
if quest:
new_quests = f"🎯1 Quest"
Expand All @@ -1307,7 +1335,7 @@ def new_bounty_daily(bounties, old_bounties, to_emails=None, featured_bounties=[
def comma(a):
return ", " if a and (new_bounties or new_quests or new_dates or new_announcements or notifications) else ""

subject = f"{chat}{comma(chat)}{notifications}{comma(notifications)}{new_announcements}{comma(new_announcements)}{new_bounties}{comma(new_bounties)}{new_dates}{comma(new_dates)}{new_quests}{comma(new_quests)}{offers}{comma(True)}👤1 Trending Avatar"
subject = f"{notifications}{comma(notifications)}{new_announcements}{comma(new_announcements)}{new_bounties}{comma(new_bounties)}{new_dates}{comma(new_dates)}{new_quests}{comma(new_quests)}{offers}"

for to_email in to_emails:
cur_language = translation.get_language()
Expand All @@ -1319,12 +1347,13 @@ def comma(a):
user = User.objects.filter(email__iexact=to_email).first()
activities = latest_activities(user)

html, text = render_new_bounty(to_email, bounties, old_bounties='', quest_of_the_day=quest, upcoming_grant=grant, upcoming_hackathon=upcoming_hackathon(), latest_activities=activities, chats_count=chats_count, featured_bounties=featured_bounties)
html, text = render_new_bounty(to_email, bounties, old_bounties='', quest_of_the_day=quest, upcoming_grant=grant, upcoming_hackathon=upcoming_hackathon(), latest_activities=activities)

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


def weekly_roundup(to_emails=None):
Expand Down
68 changes: 12 additions & 56 deletions app/marketing/management/commands/new_bounties_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,48 +23,16 @@
from django.core.management.base import BaseCommand
from django.utils import timezone

from dashboard.models import Bounty
from marketing.mails import new_bounty_daily
from marketing.models import EmailSubscriber
from marketing.tasks import new_bounty_daily
from marketing.utils import should_suppress_notification_email
from townsquare.utils import is_email_townsquare_enabled

warnings.filterwarnings("ignore")

override_in_dev = True

def validate_email(email):

import re
regex = r'^[a-z0-9]+[\._]?[a-z0-9]+[@]\w+[.]\w{2,3}$'
if(re.search(regex,email)):
return True
return False

def get_bounties_for_keywords(keywords, hours_back):
new_bounties_pks = []
all_bounties_pks = []

new_bounty_cutoff = (timezone.now() - timezone.timedelta(hours=hours_back))
all_bounty_cutoff = (timezone.now() - timezone.timedelta(days=60))

for keyword in keywords:
relevant_bounties = Bounty.objects.current().filter(
network='mainnet',
idx_status__in=['open'],
).keyword(keyword).exclude(bounty_reserved_for_user__isnull=False)
for bounty in relevant_bounties.filter(web3_created__gt=new_bounty_cutoff):
new_bounties_pks.append(bounty.pk)
for bounty in relevant_bounties.filter(web3_created__gt=all_bounty_cutoff):
all_bounties_pks.append(bounty.pk)
new_bounties = Bounty.objects.filter(pk__in=new_bounties_pks).order_by('-_val_usd_db')
all_bounties = Bounty.objects.filter(pk__in=all_bounties_pks).exclude(pk__in=new_bounties_pks).order_by('-_val_usd_db')

new_bounties = new_bounties.order_by('-admin_mark_as_remarket_ready')
all_bounties = all_bounties.order_by('-admin_mark_as_remarket_ready')

return new_bounties, all_bounties

THROTTLE_S = 0.005

class Command(BaseCommand):

Expand All @@ -79,7 +47,7 @@ def handle(self, *args, **options):
counter_eval_total = 0
counter_total = 0
counter_sent = 0
start_time = time.time()
start_time = time.time() - 1
total_count = eses.count()
print("got {} emails".format(total_count))
for es in eses:
Expand All @@ -88,34 +56,22 @@ def handle(self, *args, **options):
if should_suppress_notification_email(es.email, 'new_bounty_notifications'):
continue
# prep
now = timezone.now()

to_email = es.email
keywords = es.keywords
town_square_enabled = is_email_townsquare_enabled(to_email)
should_eval = keywords or town_square_enabled
if not should_eval:
continue
if not validate_email(to_email):
continue
counter_total += 1
new_bounties, all_bounties = get_bounties_for_keywords(keywords, hours_back)
featured_bounties = Bounty.objects.current().filter(
network='mainnet', idx_status='open',
expires_date__gt=now).order_by('metadata__hyper_tweet_counter')[:2]

# stats
speed = round((time.time() - start_time) / counter_eval_total, 2)
ETA = round((total_count - counter_eval_total) / speed / 3600, 1)
print(f"{counter_sent} sent/{counter_total} enabled/{counter_eval_total} evaluated, {speed}/s, ETA:{ETA}h, working on {to_email} ")
speed = counter_total / (time.time() - start_time)
ETA = round((total_count - counter_total) / speed / 3600, 1)
print(f"{counter_sent} sent/{counter_total} enabled/ {total_count} total, {round(speed, 2)}/s, ETA:{ETA}h, working on {to_email} ")

# send
should_send = new_bounties.count() or town_square_enabled
#should_send = new_bounties.count()
if should_send:
#print(f"sending to {to_email}")
new_bounty_daily(new_bounties, all_bounties, [to_email], featured_bounties)
#print(f"/sent to {to_email}")
did_send = new_bounty_daily(es.pk)
if did_send:
counter_sent += 1

time.sleep(THROTTLE_S)

except Exception as e:
logging.exception(e)
print(e)
8 changes: 4 additions & 4 deletions app/marketing/management/commands/roundup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@

from django.core.management.base import BaseCommand

from marketing.mails import weekly_roundup
from marketing.models import EmailSubscriber
from marketing.tasks import weekly_roundup

warnings.filterwarnings("ignore", category=DeprecationWarning)


check_already_sent = False

THROTTLE_S = 0.05

def is_already_sent_this_week(email):
from marketing.models import EmailEvent
Expand Down Expand Up @@ -103,8 +103,8 @@ def handle(self, *args, **options):
if check_already_sent and is_already_sent_this_week(to_email):
print(' -- already sent')
else:
weekly_roundup([to_email])
time.sleep(0.05)
weekly_roundup.delay(to_email)
time.sleep(THROTTLE_S)
except Exception as e:
print(e)
time.sleep(5)
50 changes: 50 additions & 0 deletions app/marketing/tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from django.conf import settings
from django.contrib.contenttypes.models import ContentType

from app.services import RedisService
from celery import app, group
from celery.utils.log import get_task_logger
from marketing.mails import new_bounty_daily as new_bounty_daily_email
from marketing.mails import weekly_roundup as weekly_roundup_email
from marketing.models import EmailSubscriber

logger = get_task_logger(__name__)

redis = RedisService().redis


@app.shared_task(bind=True, max_retries=1)
def new_bounty_daily(self, email_subscriber_id, retry: bool = True) -> None:
"""
:param self:
:param pk:
:return:
"""
es = EmailSubscriber.objects.get(pk=email_subscriber_id)
new_bounty_daily_email(es)

@app.shared_task(bind=True, max_retries=1)
def weekly_roundup(self, to_email, retry: bool = True) -> None:
"""
:param self:
:param pk:
:return:
"""
weekly_roundup_email([to_email])



@app.shared_task(bind=True, max_retries=1)
def send_all_weekly_roundup(self, retry: bool = True) -> None:
"""
:param self:
:param pk:
:return:
"""
#THROTTLE_S = 0.005
#import time
queryset = EmailSubscriber.objects.all()
email_list = list(set(queryset.values_list('email', flat=True)))
for to_email in email_list:
weekly_roundup.delay(to_email)
#time.sleep(THROTTLE_S)
2 changes: 1 addition & 1 deletion app/marketing/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
from grants.models import Grant
from marketing.country_codes import COUNTRY_CODES, COUNTRY_NAMES, FLAG_API_LINK, FLAG_ERR_MSG, FLAG_SIZE, FLAG_STYLE
from marketing.mails import new_feedback
from marketing.management.commands.new_bounties_email import get_bounties_for_keywords
from marketing.models import AccountDeletionRequest, EmailSubscriber, Keyword, LeaderboardRank, UpcomingDate
from marketing.utils import delete_user_from_mailchimp, get_or_save_email_subscriber, validate_slack_integration
from quests.models import Quest
Expand Down Expand Up @@ -1006,6 +1005,7 @@ def new_bounty_daily_preview(request):
keywords = profile.keywords
hours_back = 2000

from marketing.mails import get_bounties_for_keywords
new_bounties, all_bounties = get_bounties_for_keywords(keywords, hours_back)
max_bounties = 5
if len(new_bounties) > max_bounties:
Expand Down
3 changes: 3 additions & 0 deletions app/retail/templates/admin/change_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
<input type="submit" value="Recalculate Profile Frontend" name="_recalc_flontend" value="1">
{% elif 'dashboard/activity' in request.build_absolute_uri %}
<input type="submit" value="Make Into Nano Bounty" name="_make_nano_bounty" value="1">
{% elif 'arketing/roundupemail' in request.build_absolute_uri %}
<input type="submit" value="Send Roundup Email to myself" name="_send_roundup_email_myself" value="1">
<input type="submit" value="Send Roundup Email to EVERYONE (WARNING: BE CAREFUL!)" name="_send_roundup_email_everyone" onclick='javascript:if(!confirm("are you sure")){return false};' value="1">
{% elif 'townsquare/offer/' in request.build_absolute_uri %}
<input type="submit" value="Schedule Offer" name="_schedule_offer" value="1">
<input type="submit" value="Copy Offer" name="_copy_offer" value="1">
Expand Down

0 comments on commit 7bd9fdc

Please sign in to comment.