Skip to content

Commit

Permalink
Sort collections based on updated shuffle_rank that randomizes sort w…
Browse files Browse the repository at this point in the history
…hile giving collections with meaningful metadata more of a chance of being shown closer to the top (#9672)

Refs: #9614

Co-authored-by: Tim Schultz <[email protected]>
  • Loading branch information
Tim Schultz and Tim Schultz authored Nov 17, 2021
1 parent 28defb1 commit dd5c14b
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 2 deletions.
40 changes: 39 additions & 1 deletion app/grants/management/commands/grant_collections_shuffle.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,56 @@
"""

import random
from datetime import datetime

from django.core.management.base import BaseCommand

from grants.models import GrantCollection

today = datetime.now()

# given the collection that was updated furthest in the past, give a higher score for collections updated more recently
# Max score increase is 5% for the newest collection
def grant_collection_age_score(oldest, current):
currentAge = today - current.replace(tzinfo=None)
# subtract one from ratio between current and oldest so that newest have higher chance of moving to the top
ageScore = 1 - (currentAge / oldest)
return int(ageScore * 5000)

def grant_meta_data_score(grants):
score = 0
for grant in grants:

# if grant has github url increase score by 1%
if grant.github_project_url is not None:
score += 5000

# Increase score by 1% for each grant that has a twitter verification
if grant.twitter_verified:
score += 1000

return score



class Command(BaseCommand):

help = 'grant collection shuffle'

def handle(self, *args, **options):
oldest_creation = GrantCollection.objects.earliest()
days_since_oldest_created = today - oldest_creation.created_on.replace(tzinfo=None)

for gc in GrantCollection.objects.filter(hidden=False):
gc.shuffle_rank = random.randint(0,99999)
shuffle_rank = random.randint(0,99999)

age_score = grant_collection_age_score(days_since_oldest_created, gc.created_on)
shuffle_rank += age_score

meta_data_score = grant_meta_data_score(gc.grants.all())
shuffle_rank += meta_data_score
gc.shuffle_rank = shuffle_rank

gc.save()

print('done')
3 changes: 3 additions & 0 deletions app/grants/models/grant_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class GrantCollection(SuperModel):
objects = CollectionsQuerySet.as_manager()
shuffle_rank = models.PositiveIntegerField(default=1, db_index=True)
curators = models.ManyToManyField(blank=True, to='dashboard.Profile', help_text=_('List of allowed curators'))

class Meta:
get_latest_by = 'created_on'

def generate_cache(self):
grants = self.grants.all()
Expand Down
2 changes: 1 addition & 1 deletion app/grants/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class GrantCollectionPagination(PageNumberPagination):


class GrantCollectionViewSet(viewsets.ModelViewSet):
queryset = GrantCollection.objects.order_by('id')
queryset = GrantCollection.objects.order_by('-shuffle_rank')
serializer_class = GrantCollectionSerializer
pagination_class = GrantCollectionPagination
filterset_fields = ['featured', 'profile']
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from datetime import datetime, timedelta
from io import StringIO

from django.core.management import call_command

import pytest
from grants.management.commands.grant_collections_shuffle import grant_collection_age_score, grant_meta_data_score

from ...models.factories.grant_collection_factory import GrantCollectionFactory
from ...models.factories.grant_factory import GrantFactory


@pytest.mark.django_db
def test_grant_collections_shuffle_grant_meta_data_score():
grant_1 = GrantFactory()
grant_2 = GrantFactory()

grant_1.twitter_verified = True
grant_2.twitter_verified = True

grant_1.github_project_url = 'https://github.com/gitcoinco/web'
grant_2.github_project_url = 'https://github.com/gitcoinco/web'

grants = (grant_1, grant_2)

score = grant_meta_data_score(grants)

assert score == 12000

@pytest.mark.django_db
def test_grant_collections_shuffle_calc_age_score():
today = datetime.now()
last_month = today - (today - timedelta(days=28))
last_week = today - timedelta(days=7)
score = grant_collection_age_score(last_month, last_week)
assert score == 3750

1 comment on commit dd5c14b

@frankchen07
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.