Skip to content

Commit

Permalink
Popular/trending hashtags and posts
Browse files Browse the repository at this point in the history
  • Loading branch information
dcwatson committed May 4, 2024
1 parent 75f403c commit 10b9f5d
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 6 deletions.
1 change: 1 addition & 0 deletions activities/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ def guess_mimetypes(self, request, queryset):

class PostAttachmentInline(admin.StackedInline):
model = PostAttachment
autocomplete_fields = ["author"]
extra = 0


Expand Down
25 changes: 24 additions & 1 deletion activities/models/hashtag.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import urlman
from django.conf import settings
from django.db import models, transaction
from django.db import connection, models, transaction
from django.utils import timezone

from core.models import Config
Expand Down Expand Up @@ -175,6 +175,29 @@ def usage_days(self, num: int = 7) -> dict[date, int]:
results[date(year, month, day)] = val
return dict(sorted(results.items(), reverse=True)[:num])

@classmethod
def popular(cls, days=7, limit=20, offset=None) -> list["Hashtag"]:
sql = """
SELECT jsonb_array_elements_text(hashtags) AS tag, count(id) AS uses
FROM activities_post
WHERE state NOT IN ('deleted', 'deleted_fanned_out') AND
created::date >= %s
GROUP BY tag
ORDER BY uses DESC
LIMIT %s
OFFSET %s
"""
since = timezone.now().date() - timedelta(days=days)
if offset is None:
offset = 0
with connection.cursor() as cur:
cur.execute(sql, (since, limit, offset))
names = [r[0] for r in cur.fetchall()]
# Grab all the popular tags at once.
tags = {t.hashtag: t for t in cls.objects.filter(hashtag__in=names)}
# Make sure we return the list in the original order of usage count.
return [tags[name] for name in names if name in tags]

@classmethod
def ensure_hashtag(cls, name):
"""
Expand Down
20 changes: 15 additions & 5 deletions api/views/trends.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from django.db.models import Count
from django.http import HttpRequest
from hatchway import api_view

from activities.models import Hashtag, Post
from api import schemas
from api.decorators import scope_required
from hatchway import api_view


@scope_required("read")
Expand All @@ -12,8 +14,9 @@ def trends_tags(
limit: int = 10,
offset: int | None = None,
) -> list[schemas.Tag]:
# We don't implement this yet
return []
return [
schemas.Tag.from_hashtag(t) for t in Hashtag.popular(limit=limit, offset=offset)
]


@scope_required("read")
Expand All @@ -23,8 +26,15 @@ def trends_statuses(
limit: int = 10,
offset: int | None = None,
) -> list[schemas.Status]:
# We don't implement this yet
return []
if offset is None:
offset = 0
posts = list(
Post.objects.not_hidden()
.visible_to(request.identity)
.annotate(num_interactions=Count("interactions"))
.order_by("-num_interactions", "-created")[offset : offset + limit]
)
return schemas.Status.map_from_post(posts, request.identity)


@scope_required("read")
Expand Down

0 comments on commit 10b9f5d

Please sign in to comment.