Files
org-social-relay/app/feeds/utils.py
2025-11-05 15:03:20 +01:00

90 lines
2.6 KiB
Python

"""
Utility functions for working with posts and feeds
"""
from typing import List
from app.feeds.models import Post, Profile
def get_parent_chain(post: Post, max_depth: int = 100) -> List[str]:
"""
Calculate the parent chain for a post.
Returns a list of post URLs from the root ancestor to the immediate parent.
For example, if the chain is: Alice → Bob → Carol → Dave → Current post
This returns: [Alice_URL, Bob_URL, Carol_URL, Dave_URL]
Args:
post: The Post object to calculate the chain for
max_depth: Maximum depth to traverse (prevents infinite loops)
Returns:
List of post URLs in order from root to immediate parent
"""
if not post.reply_to:
# This post is a root post (no parent)
return []
chain = []
current_reply_to = post.reply_to
depth = 0
while current_reply_to and depth < max_depth:
# Add current parent to chain
chain.append(current_reply_to)
# Parse the reply_to URL to find the parent post
try:
if "#" not in current_reply_to:
break
feed_url, post_id = current_reply_to.split("#", 1)
# Find the parent post
profile = Profile.objects.filter(feed=feed_url).first()
if not profile:
break
parent_post = Post.objects.filter(profile=profile, post_id=post_id).first()
if not parent_post:
break
# Move up to the next parent
current_reply_to = parent_post.reply_to
depth += 1
except (ValueError, AttributeError):
break
# Reverse the chain so it goes from root to immediate parent
chain.reverse()
return chain
def add_relay_headers(response):
"""
Add global ETag and Last-Modified headers to a response.
This ensures all endpoints return consistent caching headers.
The headers are retrieved from the RelayMetadata model, which is updated
by the scan_feeds task after each scan. This way:
- All endpoints return the same ETag and Last-Modified
- Headers are added even when serving cached responses
- The ETag changes only when feeds are actually scanned
Args:
response: Django REST framework Response object
Returns:
The same response object with headers added
"""
from app.feeds.models import RelayMetadata
etag, last_modified = RelayMetadata.get_global_metadata()
response["ETag"] = f'"{etag}"'
response["Last-Modified"] = last_modified.strftime("%a, %d %b %Y %H:%M:%S GMT")
return response