Source Code

/ src / blog / views.py

from django.shortcuts import get_object_or_404, render
from blog.models import Author, Post, Column
from django.db.models import Q, Case, When, Value, IntegerField, Count
from blog.archive import build_month_context, build_year_context
from django.urls import reverse
from django.utils.feedgenerator import Rss201rev2Feed
from django.http import HttpResponse
from django.conf import settings
from xml.dom import minidom


def blog_index(request):
    news_posts = Post.objects.filter(column__slug="news").order_by("-date").first()

    posts = Post.objects.exclude(
        Q(image__isnull=True) | Q(image__exact="")
    )

    if news_posts:

        posts = posts.exclude(
            Q(column__slug="news") & ~Q(id=news_posts.id)
        )

    posts = posts.order_by("-date")

    featured_authors = Author.objects.filter(featured=True)

    main_authors = Author.objects.filter(is_staff=True)

    return render(request, "blog/post_list.html", {
        "posts": posts,
        "featured_authors": featured_authors,
        "main_authors": main_authors,
        "is_homepage" : True
    })


def friends_index(request):
    return render(request, "blog/post_list.html", {
        "posts": None,
        "column": {"name": "Posts by Friends", "description": "if you want to be on this page, send your RSS file"},
        "rss_key": "!all"
    })

def column_list(request):
    columns = (
        Column.objects
        .annotate(
            post_count=Count("post")
        )
        .order_by("-post_count", "name")
    )

    return render(request, "blog/column_list.html", {"columns": columns})

def column_index(request, column):
    column = get_object_or_404(Column, slug=column)

    posts = Post.objects.filter(column=column).exclude(
        Q(image__isnull=True) | Q(image__exact="")
    ).order_by("-date")

    column_authors = Author.objects.filter(
        post__in=posts,
    ).distinct()
    return render(request, "blog/post_list.html", {
        "posts": posts,
        "column": column,
        "column_authors": column_authors,
    })

def posts_encrypted(request):
    posts = Post.objects.filter(encrypted_content__isnull=False).order_by("-date")
    return render(request, "blog/post_list.html", {
        "posts": posts,
        "column": {"name": "Encrypted Posts 🔐", "description": "let me know if you break in"},
    })

def posts_recycle(request):
    posts = Post.objects.filter(image__isnull=True).order_by("-date")
    return render(request, "blog/post_list.html", {
        "posts": posts,
        "column": {"name": "Recycle Bin 🗑️", "description": "might delete later"},
    })

def archive_year(request, year):
    ctx = build_year_context(year)
    return render(request, "blog/archive_year.html", ctx)


def archive_month(request, year, month, day=None):
    ctx = build_month_context(year, month)

    posts_in_day = None
    if day is not None:
        posts_in_day = Post.objects.filter(
            date__year=year,
            date__month=month,
            date__day=day
        ).order_by("date")

    ctx.update({
        "day": day,
        "posts_in_day": posts_in_day,
    })

    return render(request, "blog/archive_month.html", ctx)


def post_detail(request, year, month, day, slug):
    year = int(year)
    month = int(month)
    day = int(day)

    post = get_object_or_404(
        Post,
        slug=slug,
        date__year=year,
        date__month=month,
        date__day=day,
    )

    ctx = build_month_context(year, month)

    ctx.update({
        "post": post,
        "day": day,
        "posts_in_day": [post],
    })

    return render(request, "blog/post_detail.html", ctx)


def author_detail(request, author_key):
    author = get_object_or_404(Author, slug=author_key)
    posts = Post.objects.filter(author=author).order_by("-date")

    if author.slug == "RisingThumb" or author.slug == "dannarchy":
        rss_key = author.slug
    else:
        rss_key = None


    return render(
        request,
        "blog/author_detail.html",
        {
            "author": author,
            "posts": posts,
            "rss_key": rss_key
        }
    )


def author_list(request):
    authors = (
        Author.objects
        .annotate(
            post_count=Count("post"),   # number of posts for each author
            sort_order=Case(
                When(slug="nobo", then=Value(0)),
                When(featured=True, then=Value(1)),
                default=Value(2),
                output_field=IntegerField(),
            )
        )
        .order_by("sort_order", "-post_count", "name")
    )

    return render(request, "blog/author_list.html", {
        "authors": authors,
        "subheading": "Authors"
    })


def rss_feed(request):
    """
    Returns a full RSS feed as XML.
    """
    feed = Rss201rev2Feed(
        title=settings.SITE_TITLE,
        link=settings.SITE_URL,
        description=f"Latest Posts on {settings.SITE_TITLE}",
        language="en",
    )

    posts = Post.objects.order_by("-date")[:20]

    for p in posts:
        link = reverse(
            "post_detail",
            kwargs={
                "year": p.date.year,
                "month": f"{p.date.month:02d}",
                "day": f"{p.date.day:02d}",
                "slug": p.slug,
            }
        )
        full_link = settings.SITE_URL + link

        feed.add_item(
            title=p.title,
            link=full_link,
            description=p.description,
            pubdate=p.date,
            guid=full_link,
            unique_id=full_link,
            unique_id_is_permalink=True
        )


    raw_xml = feed.writeString("utf-8")

    parsed = minidom.parseString(raw_xml)
    pretty_xml = parsed.toprettyxml(indent="  ", encoding="utf-8")

    return HttpResponse(pretty_xml, content_type="application/rss+xml")


def page_community(request):
    return render(request, "blog/page_community.html", {})

def page_webrings(request):

    main_authors = Author.objects.filter(is_staff=True)

    return render(request, "blog/page_webrings.html", {
        "main_authors": main_authors,
    })