2020-01-21 06:35:58 +00:00
|
|
|
from django.conf import settings
|
|
|
|
from django.contrib.auth.models import AnonymousUser
|
|
|
|
from django.contrib.syndication.views import Feed
|
|
|
|
from django.core.cache import cache
|
|
|
|
from django.utils import timezone
|
|
|
|
from django.utils.feedgenerator import Atom1Feed
|
|
|
|
|
|
|
|
from judge.jinja2.markdown import markdown
|
|
|
|
from judge.models import BlogPost, Comment, Problem
|
|
|
|
|
2021-01-08 02:22:53 +00:00
|
|
|
import re
|
|
|
|
|
|
|
|
|
|
|
|
# https://lsimons.wordpress.com/2011/03/17/stripping-illegal-characters-out-of-xml-in-python/
|
2022-05-14 17:57:27 +00:00
|
|
|
def escape_xml_illegal_chars(val, replacement="?"):
|
|
|
|
_illegal_xml_chars_RE = re.compile(
|
|
|
|
"[\x00-\x08\x0b\x0c\x0e-\x1F\uD800-\uDFFF\uFFFE\uFFFF]"
|
|
|
|
)
|
2021-01-08 02:22:53 +00:00
|
|
|
return _illegal_xml_chars_RE.sub(replacement, val)
|
2020-01-21 06:35:58 +00:00
|
|
|
|
2022-05-14 17:57:27 +00:00
|
|
|
|
2020-01-21 06:35:58 +00:00
|
|
|
class ProblemFeed(Feed):
|
2022-05-14 17:57:27 +00:00
|
|
|
title = "Recently Added %s Problems" % settings.SITE_NAME
|
|
|
|
link = "/"
|
|
|
|
description = (
|
|
|
|
"The latest problems added on the %s website" % settings.SITE_LONG_NAME
|
|
|
|
)
|
2020-01-21 06:35:58 +00:00
|
|
|
|
|
|
|
def items(self):
|
2022-05-14 17:57:27 +00:00
|
|
|
return (
|
|
|
|
Problem.objects.filter(is_public=True, is_organization_private=False)
|
|
|
|
.defer("description")
|
|
|
|
.order_by("-date", "-id")[:25]
|
|
|
|
)
|
2020-01-21 06:35:58 +00:00
|
|
|
|
|
|
|
def item_title(self, problem):
|
|
|
|
return problem.name
|
|
|
|
|
|
|
|
def item_description(self, problem):
|
2022-05-14 17:57:27 +00:00
|
|
|
key = "problem_feed:%d" % problem.id
|
2020-01-21 06:35:58 +00:00
|
|
|
desc = cache.get(key)
|
|
|
|
if desc is None:
|
2022-10-26 06:11:37 +00:00
|
|
|
desc = str(markdown(problem.description))[:500] + "..."
|
2021-01-12 03:58:24 +00:00
|
|
|
desc = escape_xml_illegal_chars(desc)
|
2020-01-21 06:35:58 +00:00
|
|
|
cache.set(key, desc, 86400)
|
|
|
|
return desc
|
|
|
|
|
|
|
|
def item_pubdate(self, problem):
|
|
|
|
return problem.date
|
|
|
|
|
|
|
|
item_updateddate = item_pubdate
|
|
|
|
|
|
|
|
|
|
|
|
class AtomProblemFeed(ProblemFeed):
|
|
|
|
feed_type = Atom1Feed
|
|
|
|
subtitle = ProblemFeed.description
|
|
|
|
|
|
|
|
|
|
|
|
class CommentFeed(Feed):
|
2022-05-14 17:57:27 +00:00
|
|
|
title = "Latest %s Comments" % settings.SITE_NAME
|
|
|
|
link = "/"
|
|
|
|
description = "The latest comments on the %s website" % settings.SITE_LONG_NAME
|
2020-01-21 06:35:58 +00:00
|
|
|
|
|
|
|
def items(self):
|
|
|
|
return Comment.most_recent(AnonymousUser(), 25)
|
|
|
|
|
|
|
|
def item_title(self, comment):
|
2022-05-14 17:57:27 +00:00
|
|
|
return "%s -> %s" % (comment.author.user.username, comment.page_title)
|
2020-01-21 06:35:58 +00:00
|
|
|
|
|
|
|
def item_description(self, comment):
|
2022-05-14 17:57:27 +00:00
|
|
|
key = "comment_feed:%d" % comment.id
|
2020-01-21 06:35:58 +00:00
|
|
|
desc = cache.get(key)
|
|
|
|
if desc is None:
|
2022-10-27 19:55:37 +00:00
|
|
|
desc = str(markdown(comment.body))
|
2021-01-12 03:58:24 +00:00
|
|
|
desc = escape_xml_illegal_chars(desc)
|
2020-01-21 06:35:58 +00:00
|
|
|
cache.set(key, desc, 86400)
|
|
|
|
return desc
|
|
|
|
|
|
|
|
def item_pubdate(self, comment):
|
|
|
|
return comment.time
|
|
|
|
|
|
|
|
item_updateddate = item_pubdate
|
|
|
|
|
|
|
|
|
|
|
|
class AtomCommentFeed(CommentFeed):
|
|
|
|
feed_type = Atom1Feed
|
|
|
|
subtitle = CommentFeed.description
|
|
|
|
|
|
|
|
|
|
|
|
class BlogFeed(Feed):
|
2022-05-14 17:57:27 +00:00
|
|
|
title = "Latest %s Blog Posts" % settings.SITE_NAME
|
|
|
|
link = "/"
|
|
|
|
description = "The latest blog posts from the %s" % settings.SITE_LONG_NAME
|
2020-01-21 06:35:58 +00:00
|
|
|
|
|
|
|
def items(self):
|
2022-05-14 17:57:27 +00:00
|
|
|
return BlogPost.objects.filter(
|
|
|
|
visible=True, publish_on__lte=timezone.now()
|
|
|
|
).order_by("-sticky", "-publish_on")
|
2020-01-21 06:35:58 +00:00
|
|
|
|
|
|
|
def item_title(self, post):
|
|
|
|
return post.title
|
|
|
|
|
|
|
|
def item_description(self, post):
|
2022-05-14 17:57:27 +00:00
|
|
|
key = "blog_feed:%d" % post.id
|
2020-01-21 06:35:58 +00:00
|
|
|
summary = cache.get(key)
|
|
|
|
if summary is None:
|
2022-10-27 19:55:37 +00:00
|
|
|
summary = str(markdown(post.summary or post.content))
|
2021-01-08 02:22:53 +00:00
|
|
|
summary = escape_xml_illegal_chars(summary)
|
2020-01-21 06:35:58 +00:00
|
|
|
cache.set(key, summary, 86400)
|
|
|
|
return summary
|
|
|
|
|
|
|
|
def item_pubdate(self, post):
|
|
|
|
return post.publish_on
|
|
|
|
|
|
|
|
item_updateddate = item_pubdate
|
|
|
|
|
|
|
|
|
|
|
|
class AtomBlogFeed(BlogFeed):
|
|
|
|
feed_type = Atom1Feed
|
|
|
|
subtitle = BlogFeed.description
|