# Path: apps/blog/models/db.py
# class Post(CacheMixin, models.Model):
#     (block, preview, publish) = range(3)
#     POST_STARUS_CHOICES = [
#         (block, _("block")),
#         (preview, _("preview")),
#         (publish, _("publish")),
#     ]
# 
#     title = models.CharField(_("title"), max_length=255)
#     slug = models.SlugField(
#         max_length=30, default="", unique=True, editable=False
#     )
#     content = models.TextField(blank=True)
#     status = models.IntegerField(
#         _("status"), choices=POST_STARUS_CHOICES, default=preview
#     )
#     created_at = models.DateTimeField(
#         _("created_at"), auto_now_add=True, db_index=True, editable=False
#     )
#     updated_at = models.DateTimeField(
#         _("updated_at"), auto_now=True, db_index=True, editable=False
#     )
# 
#     tags = TaggableManager(blank=True)
# 
#     images = GenericRelation(Image, related_query_name="images")
# 
#     objects = PostManager()
# 
#     class Meta:
#         ordering = ["-created_at"]
#         verbose_name = _("posts")
#         verbose_name_plural = _("posts")
# 
#     def __str__(self):
#         return self.title
# 
#     @cached_property
#     def url(self) -> str:
#         return self.get_absolute_url()
# 
#     @cached_property
#     def created_at_ts(self) -> float:
#         return self.created_at.timestamp()
# 
#     @cached_property
#     def updated_at_ts(self) -> float:
#         return self.updated_at.timestamp()
# 
#     @cached_property
#     def digest(self):
#         value = self.get_value_from_cache("digest")
#         if value is None:
#             value = strip_tags(self.html_content)
#             self.set_value_to_cache("digest", value, timeout=86400)
#         return value
# 
#     @cached_property
#     def html_content(self):
#         value = self.get_value_from_cache("html:content")
#         if value is None:
#             value, toc = self.render_markdown()
#             self.set_value_to_cache("html:content", value, timeout=86400)
#         return value
# 
#     @property
#     def toc(self):
#         html, toc = self.render_markdown()
#         return toc
# 
#     def process_content(self):
#         _content = f"{self.title}{strip_tags(self.html_content)}"
#         _content = re.sub("(\\d|\\W)+", " ", _content)
#         _content = re.sub(r"\s+", " ", _content)
#         _content = _content.lower()
#         return _content
# 
#     def tag_list(self) -> List[str]:
#         return [o.name for o in self.tags.all()]
# 
#     def tag_string(self):
#         return ",".join(self.tag_list())
# 
#     def get_absolute_url(self) -> str:
#         return f"/posts/{self.slug}/"
# 
#     def render_markdown(self):
#         html = md.convert(self.content)
#         return html, md.toc


from xml.sax.saxutils import XMLGenerator
from django.contrib.syndication.views import Feed
from django.urls import reverse
from django.utils.encoding import smart_str
from django.utils.feedgenerator import Rss201rev2Feed
from django.utils.html import strip_tags, escape
from apps.blog.models import Post
        handler.endElement("rss")

    def rss_attributes(self):
        attrs = super(PostsFeedGenerator, self).rss_attributes()
        attrs["xmlns:content"] = "http://purl.org/rss/1.0/modules/content/"
        attrs["xmlns:media"] = "http://search.yahoo.com/mrss/"
        attrs["xmlns:georss"] = "http://www.georss.org/georss"
        attrs["xmlns:dc"] = "http://purl.org/dc/elements/1.1/"
        return attrs

    def add_item_elements(self, handler, item):
        super(PostsFeedGenerator, self).add_item_elements(handler, item)

        if item["content_encoded"] is not None:
            handler.addQuickElement(
                "content:encoded", item["content_encoded"], escape=False
            )

    # return Article.objects.published().order_by('-pub_time')[0:20]


class PostFeeds(Feed):
    feed_type = PostsFeedGenerator
    title = "Python观察员"
    link = "https://www.jiaxin.im"
    author_email = "edison7500@gmail.com"
    feed_copyright = "since 2008 jiaxin.im All rights reserved."
    description = "Python观察员，python，django，scrapy，ios"

    def items(self):

# Path: apps/blog/models/db.py
# class Post(CacheMixin, models.Model):
#     (block, preview, publish) = range(3)
#     POST_STARUS_CHOICES = [
#         (block, _("block")),
#         (preview, _("preview")),
#         (publish, _("publish")),
#     ]
# 
#     title = models.CharField(_("title"), max_length=255)
#     slug = models.SlugField(
#         max_length=30, default="", unique=True, editable=False
#     )
#     content = models.TextField(blank=True)
#     status = models.IntegerField(
#         _("status"), choices=POST_STARUS_CHOICES, default=preview
#     )
#     created_at = models.DateTimeField(
#         _("created_at"), auto_now_add=True, db_index=True, editable=False
#     )
#     updated_at = models.DateTimeField(
#         _("updated_at"), auto_now=True, db_index=True, editable=False
#     )
# 
#     tags = TaggableManager(blank=True)
# 
#     images = GenericRelation(Image, related_query_name="images")
# 
#     objects = PostManager()
# 
#     class Meta:
#         ordering = ["-created_at"]
#         verbose_name = _("posts")
#         verbose_name_plural = _("posts")
# 
#     def __str__(self):
#         return self.title
# 
#     @cached_property
#     def url(self) -> str:
#         return self.get_absolute_url()
# 
#     @cached_property
#     def created_at_ts(self) -> float:
#         return self.created_at.timestamp()
# 
#     @cached_property
#     def updated_at_ts(self) -> float:
#         return self.updated_at.timestamp()
# 
#     @cached_property
#     def digest(self):
#         value = self.get_value_from_cache("digest")
#         if value is None:
#             value = strip_tags(self.html_content)
#             self.set_value_to_cache("digest", value, timeout=86400)
#         return value
# 
#     @cached_property
#     def html_content(self):
#         value = self.get_value_from_cache("html:content")
#         if value is None:
#             value, toc = self.render_markdown()
#             self.set_value_to_cache("html:content", value, timeout=86400)
#         return value
# 
#     @property
#     def toc(self):
#         html, toc = self.render_markdown()
#         return toc
# 
#     def process_content(self):
#         _content = f"{self.title}{strip_tags(self.html_content)}"
#         _content = re.sub("(\\d|\\W)+", " ", _content)
#         _content = re.sub(r"\s+", " ", _content)
#         _content = _content.lower()
#         return _content
# 
#     def tag_list(self) -> List[str]:
#         return [o.name for o in self.tags.all()]
# 
#     def tag_string(self):
#         return ",".join(self.tag_list())
# 
#     def get_absolute_url(self) -> str:
#         return f"/posts/{self.slug}/"
# 
#     def render_markdown(self):
#         html = md.convert(self.content)
#         return html, md.toc


# Path: apps/blog/feeds.py
from xml.sax.saxutils import XMLGenerator
from django.contrib.syndication.views import Feed
from django.urls import reverse
from django.utils.encoding import smart_str
from django.utils.feedgenerator import Rss201rev2Feed
from django.utils.html import strip_tags, escape
from apps.blog.models import Post

        handler.endElement("rss")

    def rss_attributes(self):
        attrs = super(PostsFeedGenerator, self).rss_attributes()
        attrs["xmlns:content"] = "http://purl.org/rss/1.0/modules/content/"
        attrs["xmlns:media"] = "http://search.yahoo.com/mrss/"
        attrs["xmlns:georss"] = "http://www.georss.org/georss"
        attrs["xmlns:dc"] = "http://purl.org/dc/elements/1.1/"
        return attrs

    def add_item_elements(self, handler, item):
        super(PostsFeedGenerator, self).add_item_elements(handler, item)

        if item["content_encoded"] is not None:
            handler.addQuickElement(
                "content:encoded", item["content_encoded"], escape=False
            )

    # return Article.objects.published().order_by('-pub_time')[0:20]


class PostFeeds(Feed):
    feed_type = PostsFeedGenerator
    title = "Python观察员"
    link = "https://www.jiaxin.im"
    author_email = "edison7500@gmail.com"
    feed_copyright = "since 2008 jiaxin.im All rights reserved."
    description = "Python观察员，python，django，scrapy，ios"

    def items(self):

        return Post.objects.filter(status=Post.publish)[:10]