Skip to content
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
6 changes: 6 additions & 0 deletions home_page_counters.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"public_competitions": 0,
"users": 0,
"submissions": 0,
"last_updated": "2000-01-01T00:00:00.000000+00:00"
}
35 changes: 35 additions & 0 deletions src/apps/analytics/tasks.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import time
import logging
import json
from celery_config import app
from datetime import datetime, timezone, timedelta
from django.db.models import (
Expand Down Expand Up @@ -551,6 +552,40 @@ def create_storage_analytics_snapshot():
)


@app.task(queue="site-worker")
def update_home_page_counters():
starting_time = time.process_time()
logger.info("Task update_home_page_counters Started")

# Count public competitions
public_competitions = Competition.objects.filter(published=True).count()

# Count active users
# TODO: do not count deleted users
users = User.objects.all().count()

# Count all submissions
submissions = Submission.objects.all().count()

# Create counters data
counters_data = {
"public_competitions": public_competitions,
"users": users,
"submissions": submissions,
"last_updated": datetime.now(timezone.utc).isoformat()
}

# Save latest counters in the file
log_file = "/app/home_page_counters.json"
with open(log_file, "w") as f:
json.dump(counters_data, f, indent=4)

elapsed_time = time.process_time() - starting_time
logger.info(
"Task update_home_page_counters Completed. Duration = {:.3f} seconds".format(elapsed_time)
)


@app.task(queue="site-worker") # 12 hours
def reset_computed_storage_analytics():
logger.info("Task reset_computed_storage_analytics started")
Expand Down
25 changes: 0 additions & 25 deletions src/apps/pages/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,6 @@ class HomeView(TemplateView):
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)

# TODO: Optimize fetching the statistics
# Possibly from a file where they are written by an automated script once a day
# For now showing latest numbers from live codabench
# The following commented code is slowing down the loading of the home page

# data = Competition.objects.aggregate(
# count=Count('*'),
# published_comps=Count('pk', filter=Q(published=True)),
# unpublished_comps=Count('pk', filter=Q(published=False)),
# )

# public_competitions = data['published_comps']
# users = User.objects.all().count()
# submissions = Submission.objects.all().count()

public_competitions = 204
users = 12216
submissions = 70276

context['general_stats'] = [
{'label': "Public Competitions", 'count': public_competitions},
{'label': "Users", 'count': users},
{'label': "Submissions", 'count': submissions},
]

announcement = Announcement.objects.all().first()
context['announcement'] = announcement.text if announcement else None

Expand Down
4 changes: 4 additions & 0 deletions src/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@
'task': 'analytics.tasks.create_storage_analytics_snapshot',
'schedule': crontab(hour='2', minute='0', day_of_week='sun') # Every Sunday at 02:00 UTC time
},
'update_home_page_counters': {
'task': 'analytics.tasks.update_home_page_counters',
'schedule': timedelta(days=1), # Run every 24 hours
},
'reset_computed_storage_analytics': {
'task': 'analytics.tasks.reset_computed_storage_analytics',
'schedule': crontab(hour='2', minute='0', day_of_month='1', month_of_year="*/3") # Every 3 month at 02:00 UTC on the 1st
Expand Down
31 changes: 20 additions & 11 deletions src/templates/pages/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,27 @@ <h3 class="ui icon header">

<!-- Stats section -->
<div class="ui three column grid" id="general-stats">
{% for stat in general_stats %}
<div class="column">
<div class="ui statistic">
<div class="value">
{{ stat.count }}
</div>
<div class="label">
{{ stat.label }}
</div>
</div>
<!-- Public Competitions -->
<div class="column">
<div class="ui statistic">
<div class="value">{{ HOME_PAGE_COUNTERS_INFO.public_competitions }}</div>
<div class="label">Public Competitions</div>
</div>
</div>
<!-- Users -->
<div class="column">
<div class="ui statistic">
<div class="value">{{ HOME_PAGE_COUNTERS_INFO.users }}</div>
<div class="label">Users</div>
</div>
</div>
<!-- Submissions -->
<div class="column">
<div class="ui statistic">
<div class="value">{{ HOME_PAGE_COUNTERS_INFO.submissions }}</div>
<div class="label">Submissions</div>
</div>
{% endfor %}
</div>
</div>

<!-- About Section -->
Expand Down
15 changes: 15 additions & 0 deletions src/utils/context_processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Set the absolute path for the version file
VERSION_FILE_PATH = os.path.join(os.path.dirname(BASE_DIR), 'version.json')
# Set the absolute path for the home page counters file
HOME_PAGE_COUNTERS_FILE_PATH = os.path.join(os.path.dirname(BASE_DIR), 'home_page_counters.json')


def common_settings(request):
Expand Down Expand Up @@ -32,6 +34,18 @@ def common_settings(request):
except json.JSONDecodeError:
version_info = {"tag_name": "invalid"}

# Read home page counters information from the home_page_counters.json file
home_page_counters_info = {}
try:
with open(HOME_PAGE_COUNTERS_FILE_PATH) as counters_file:
home_page_counters_info = json.load(counters_file)
except Exception:
home_page_counters_info = {
"public_competitions": 0,
"users": 0,
"submissions": 0
}

return {
'STORAGE_TYPE': settings.STORAGE_TYPE,
'MAX_EXECUTION_TIME_LIMIT': settings.MAX_EXECUTION_TIME_LIMIT,
Expand All @@ -41,4 +55,5 @@ def common_settings(request):
'ENABLE_SIGN_UP': settings.ENABLE_SIGN_UP,
'ENABLE_SIGN_IN': settings.ENABLE_SIGN_IN,
'VERSION_INFO': version_info,
'HOME_PAGE_COUNTERS_INFO': home_page_counters_info
}