Files
org-social-relay/app/boosts/views.py
Andros Fenollosa aa5f200fb5 Added boosts
2025-11-16 18:41:45 +01:00

98 lines
3.1 KiB
Python

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.core.cache import cache
import logging
from app.feeds.models import Post, Profile
logger = logging.getLogger(__name__)
class BoostsView(APIView):
"""Get boosts for a specific post"""
def get(self, request):
post_url = request.query_params.get("post")
if not post_url:
return Response(
{
"type": "Error",
"errors": ["'post' parameter is required"],
"data": None,
},
status=status.HTTP_400_BAD_REQUEST,
)
# Parse the post URL format: https://feed.com/social.org#post_id
try:
if "#" not in post_url:
raise ValueError("Invalid post URL format")
feed_url, post_id = post_url.split("#", 1)
except ValueError:
return Response(
{
"type": "Error",
"errors": ["Invalid post URL format. Expected: feed_url#post_id"],
"data": None,
},
status=status.HTTP_400_BAD_REQUEST,
)
cache_key = f"boosts_{feed_url}_{post_id}"
cached_response = cache.get(cache_key)
if cached_response is not None:
return Response(cached_response, status=status.HTTP_200_OK)
# Find the original post
try:
profile = Profile.objects.get(feed=feed_url)
Post.objects.get(profile=profile, post_id=post_id)
except (Profile.DoesNotExist, Post.DoesNotExist):
return Response(
{
"type": "Error",
"errors": ["Post not found"],
"data": None,
},
status=status.HTTP_404_NOT_FOUND,
)
# Get all boosts for this post
# A boost is a post with include property pointing to this post
original_post_url = f"{feed_url}#{post_id}"
boosts = (
Post.objects.filter(include=original_post_url)
.select_related("profile")
.order_by("-post_id")
)
# Build data according to README spec (simple list of post URLs)
boosts_data = [f"{boost.profile.feed}#{boost.post_id}" for boost in boosts]
# URL encode the post_url for the self link
from urllib.parse import quote
encoded_post_url = quote(post_url, safe="")
response_data = {
"type": "Success",
"errors": [],
"data": boosts_data,
"meta": {
"post": original_post_url,
"total": len(boosts_data),
},
"_links": {
"self": {"href": f"/boosts/?post={encoded_post_url}", "method": "GET"}
},
}
# Cache permanently (will be cleared by scan_feeds task)
cache.set(cache_key, response_data, None)
return Response(response_data, status=status.HTTP_200_OK)