Skip to content

Commit

Permalink
Fix hackathon list page loadtime (#7254)
Browse files Browse the repository at this point in the history
* remove unused fields

* refactor: load context from perftools.models.JSONStore

* fix isort

Co-authored-by: Dan Lipert <[email protected]>
  • Loading branch information
walidmujahid and danlipert authored Aug 25, 2020
1 parent 93ac742 commit 6bcbf73
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 69 deletions.
44 changes: 22 additions & 22 deletions app/dashboard/templates/dashboard/hackathon/hackathons.html
Original file line number Diff line number Diff line change
Expand Up @@ -116,73 +116,73 @@ <h2 class="mt-4">Build with the coolest Web3 projects </h2>

<div class="row my-4">
{% if events|length %}
{% load date_fromisoformat timesince_fromisoformat %}
<div class="container custom-container">
<div class="row">
{% for event in events %}
<style>
#{{event.hackathon.slug}} .card-header {
background: {{ event.hackathon.background_color }};
#{{event.slug}} .card-header {
background: {{ event.background_color }};
}
</style>

<div class="col-xs-12 col-md-9 col-lg-8 col-xl-6 mx-auto hackathon-list {{ event.title }} {% if event.title != default_tab %}hidden{% endif %}">
<div class="col-xs-12 col-md-9 col-lg-8 col-xl-6 mx-auto hackathon-list {{ event.type }} {% if event.type != default_tab %}hidden{% endif %}">

<div class="card flex-row flex-wrap mb-5" id="{{ event.hackathon.slug }}">
<div class="card flex-row flex-wrap mb-5" id="{{ event.slug }}">

<div class="card-header text-center col-12 col-sm-4 px-0">
{% firstof event.hackathon.logo_svg or event.hackathon.logo as logo %}
{% if logo %}
<img class="hackathon-card-logo" src="{{ MEDIA_URL }}{{ logo }}" alt="Hackathon logo" />
{% if event.logo %}
<img class="hackathon-card-logo" src="{{ MEDIA_URL }}{{ event.logo }}" alt="Hackathon logo" />
{% else %}
<div class="hackathon-card-logo text-center px-3 font-caption">
{{ event.hackathon.name }}
{{ event.name }}
</div>
{% endif %}
</div>

<div class="card-body col-12 col-sm-8">
<h5 class="font-subheader font-weight-semibold">
<a href="{% url 'hackathon' event.hackathon.slug %}" class="text-black" target="_blank" rel="noopener noreferrer">
{{ event.hackathon.name }}
<a href="{% url 'hackathon' event.slug %}" class="text-black" target="_blank" rel="noopener noreferrer">
{{ event.name }}
</a>
</h5>
<div class="font-smaller-2">
<span class>From</span>
<time class="font-weight-bold" datetime="{{ event.hackathon.start_date|date:'c' }}">{{ event.hackathon.start_date|date:"m/d/Y" }}</time>
<time class="font-weight-bold" datetime="{{ event.start_date|date_fromisoformat:'c' }}">{{ event.start_date|date_fromisoformat:"m/d/Y" }}</time>
<span>To</span>
<time class="font-weight-bold" datetime="{{ event.hackathon.end_date|date:'c' }}">{{ event.hackathon.end_date|date:"m/d/Y" }}</time>
<time class="font-weight-bold" datetime="{{ event.end_date|date_fromisoformat:'c' }}">{{ event.end_date|date_fromisoformat:"m/d/Y" }}</time>
</div>
<div class="mt-3 font-smaller-2 hackathon-summary">
<p>{{ event.hackathon.hackathon_summary }}</p>
<p>{{ event.summary }}</p>
</div>
<div class="mt-3 font-smaller-2">
<span class="pr-1">Sponsored by</span>
{% for sponsor in event.hackathon.sponsor_profiles.all %}
{% for sponsor in event.sponsor_profiles %}
<a href="{{ sponsor.absolute_url }}" target="_blank"><img class="rounded-circle" style="width:21px;" src="{{ sponsor.avatar_url }}" /></a>
{% endfor %}
</div>
<div class="mt-3 hackathon-actions">
{% if event.hackathon.end_date|timesince <= "1 min" %}
<a href="{% url 'hackathon_onboard' event.hackathon.slug %}" class="btn btn-gc-blue font-caption font-weight-semibold px-3 mb-2">
{% if event.end_date|timesince_fromisoformat <= "1 min" %}
<a href="{% url 'hackathon_onboard' event.slug %}" class="btn btn-gc-blue font-caption font-weight-semibold px-3 mb-2">
<i class="fas fa-user-plus mr-2 d-none d-sm-inline"></i>
Join
</a>
{% endif %}
{% if event.hackathon.display_showcase %}
<a href="{% url 'hackathon_showcase_proxy' event.hackathon.slug %}" class="btn btn-gc-blue font-caption font-weight-semibold px-3 mb-2">
{% if event.display_showcase %}
<a href="{% url 'hackathon_showcase_proxy' event.slug %}" class="btn btn-gc-blue font-caption font-weight-semibold px-3 mb-2">
<i class="fas fa-star d-none d-sm-inline" style="font-size:6.5px;position:relative;top:0.2rem;left:0.2rem;"></i>
<i class="fas fa-star mr-1 d-none d-sm-inline"></i>
Showcase
</a>
{% endif %}
{% if event.hackathon.start_date|timesince >= "1 min" and event.hackathon.end_date|timesince <= "1 min"%}
<a href="{% url 'hackathon_prizes' event.hackathon.slug %}" class="btn button--secondary font-caption font-weight-semibold px-3 mb-2">
{% if event.start_date|timesince_fromisoformat >= "1 min" and event.end_date|timesince_fromisoformat <= "1 min"%}
<a href="{% url 'hackathon_prizes' event.slug %}" class="btn button--secondary font-caption font-weight-semibold px-3 mb-2">
<i class="fas fa-trophy mr-2 d-none d-sm-inline"></i>
Prizes
</a>
{% endif %}
{% if event.hackathon.show_results %}
<a href="{% url 'hackathon_projects' event.hackathon.slug %}" class="btn button--secondary font-caption font-weight-semibold px-3 mb-2">
{% if event.show_results %}
<a href="{% url 'hackathon_projects' event.slug %}" class="btn button--secondary font-caption font-weight-semibold px-3 mb-2">
<i class="fas fa-dharmachakra mr-2 d-none d-sm-inline"></i>
Projects
</a>
Expand Down
22 changes: 22 additions & 0 deletions app/dashboard/templatetags/date_fromisoformat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from django import template
from django.utils.formats import date_format

import dateutil.parser


register = template.Library()


@register.filter(expects_localtime=True, is_safe=False)
def date_fromisoformat(value, arg=None):
"""Get datetime.datetime from isofromat string then use given format."""

if value in (None, ''):
return ''
try:
return date_format(dateutil.parser.parse(value), arg)
except AttributeError:
try:
return format(dateutil.parser.parse(value), arg)
except AttributeError:
return ''
21 changes: 21 additions & 0 deletions app/dashboard/templatetags/timesince_fromisoformat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from django import template
from django.utils.timesince import timesince

import dateutil.parser


register = template.Library()


@register.filter(is_safe=False)
def timesince_fromisoformat(value, arg=None):
"""Convert value to datetime.datetime object then format as timesince."""

if not value:
return ''
try:
if arg:
return timesince(dateutil.parser.parse(value), arg)
return timesince(dateutil.parser.parse(value))
except (ValueError, TypeError):
return ''
39 changes: 29 additions & 10 deletions app/dashboard/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1091,16 +1091,35 @@ def get_token_recipient_senders(network, recipient_address, token_address):
return [process_log(log) for log in logs]


def get_hackathon_event(title, event, network):
event_bounties = Bounty.objects.filter(event=event, network=network)
def get_hackathons_page_default_tabs():
from perftools.models import JSONStore

return JSONStore.objects.get(key='hackathons', view='hackathons').data[0]


def get_hackathon_events():
from perftools.models import JSONStore

return JSONStore.objects.get(key='hackathons', view='hackathons').data[1]


def set_hackathon_event(type, event):
return {
'title': title,
'hackathon': event,
'value_in_usdt': sum(
prize_usdt.value_in_usdt_now
for prize_usdt
in event_bounties
),
'registrants': HackathonRegistration.objects.filter(hackathon=event).count()
'type': type,
'name': event.name,
'slug': event.slug,
'background_color': event.background_color,
'logo': event.logo.name or event.logo_svg.name,
'start_date': event.start_date.isoformat(),
'end_date': event.end_date.isoformat(),
'summary': event.hackathon_summary,
'sponsor_profiles': [
{
'absolute_url': sponsor.absolute_url,
'avatar_url': sponsor.avatar_url,
}
for sponsor in event.sponsor_profiles.all()
],
'display_showcase': event.display_showcase,
'show_results': event.show_results,
}
45 changes: 8 additions & 37 deletions app/dashboard/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_GET, require_POST

import dateutil
import dateutil.parser
import magic
import pytz
from app.services import RedisService, TwilioService
Expand Down Expand Up @@ -118,9 +118,11 @@
)
from .router import HackathonEventSerializer, HackathonProjectSerializer, TribesSerializer, TribesTeamSerializer
from .utils import (
apply_new_bounty_deadline, get_bounty, get_bounty_id, get_context, get_custom_avatars, get_hackathon_event,
get_unrated_bounties_count, get_web3, has_tx_mined, is_valid_eth_address, re_market_bounty,
record_user_action_on_interest, release_bounty_to_the_public, sync_payout, web3_process_bounty,
apply_new_bounty_deadline, get_bounty, get_bounty_id, get_context,
get_custom_avatars, get_hackathon_events, get_hackathons_page_default_tabs,
get_unrated_bounties_count, get_web3, has_tx_mined, is_valid_eth_address,
re_market_bounty, record_user_action_on_interest,
release_bounty_to_the_public, sync_payout, web3_process_bounty,
)

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -4356,53 +4358,22 @@ def hackathon_registration(request):
def get_hackathons(request):
"""Handle rendering all Hackathons."""

current_hackathon_events = HackathonEvent.objects.current().filter(visible=True).order_by('-start_date')
upcoming_hackathon_events = HackathonEvent.objects.upcoming().filter(visible=True).order_by('-start_date')
finished_hackathon_events = HackathonEvent.objects.finished().filter(visible=True).order_by('-start_date')
all_hackathon_events = HackathonEvent.objects.all().filter(visible=True)

network = get_default_network()

tabs = [
('current', 'happening now'),
('upcoming', 'upcoming'),
('finished', 'completed'),
]

hackathon_events = []

if current_hackathon_events.exists():
for event in current_hackathon_events:
event_dict = get_hackathon_event('current', event, network)
hackathon_events.append(event_dict)

if upcoming_hackathon_events.exists():
for event in upcoming_hackathon_events:
event_dict = get_hackathon_event('upcoming', event, network)
hackathon_events.append(event_dict)

if finished_hackathon_events.exists():
for event in finished_hackathon_events:
event_dict = get_hackathon_event('finished', event, network)
hackathon_events.append(event_dict)


params = {
'active': 'hackathons',
'title': 'Hackathons',
'avatar_url': request.build_absolute_uri(static('v2/images/twitter_cards/tw_cards-02.png')),
'card_desc': "Gitcoin runs Virtual Hackathons. Learn, earn, and connect with the best hackers in the space -- only on Gitcoin.",
'tabs': tabs,
'events': hackathon_events,
'events': get_hackathon_events(),
'default_tab': get_hackathons_page_default_tabs(),
}

if current_hackathon_events.exists():
params['default_tab'] = 'current'
elif upcoming_hackathon_events.exists():
params['default_tab'] = 'upcoming'
else:
params['default_tab'] = 'finished'

return TemplateResponse(request, 'dashboard/hackathon/hackathons.html', params)


Expand Down
44 changes: 44 additions & 0 deletions app/perftools/management/commands/create_page_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from django.utils.functional import Promise

from dashboard.models import HackathonEvent, Profile
from dashboard.utils import set_hackathon_event
from economy.models import EncodeAnything, SuperModel
from perftools.models import JSONStore
from retail.utils import build_stat_results, programming_languages
Expand Down Expand Up @@ -217,6 +218,48 @@ def create_hackathon_cache():
hackathon.get_total_winners(force=True)


def create_hackathon_list_page_cache():
print('create_hackathon_list_page_cache')

view = 'hackathons'
keyword = 'hackathons'
current_hackathon_events = HackathonEvent.objects.current().filter(visible=True).order_by('-start_date')
upcoming_hackathon_events = HackathonEvent.objects.upcoming().filter(visible=True).order_by('-start_date')
finished_hackathon_events = HackathonEvent.objects.finished().filter(visible=True).order_by('-start_date')

events = []

if current_hackathon_events.exists():
for event in current_hackathon_events:
events.append(set_hackathon_event('current', event))

if upcoming_hackathon_events.exists():
for event in upcoming_hackathon_events:
events.append(set_hackathon_event('upcoming', event))

if finished_hackathon_events.exists():
for event in finished_hackathon_events:
events.append(set_hackathon_event('finished', event))

default_tab = None

if current_hackathon_events.exists():
default_tab = 'current'
elif upcoming_hackathon_events.exists():
default_tab = 'upcoming'
else:
default_tab = 'finished'

with transaction.atomic():
JSONStore.objects.filter(view=view).all().delete()
data = [default_tab, events]
JSONStore.objects.create(
view=view,
key=keyword,
data=data,
)


def create_results_cache():
print('results')
keywords = ['']
Expand Down Expand Up @@ -278,3 +321,4 @@ def handle(self, *args, **options):
create_grants_cache()
create_contributor_landing_page_context()
create_hackathon_cache()
create_hackathon_list_page_cache()

0 comments on commit 6bcbf73

Please sign in to comment.