takahe/core/views.py

128 lines
3.7 KiB
Python
Raw Normal View History

from typing import ClassVar
import markdown_it
2023-01-29 11:27:07 -08:00
from django.conf import settings
from django.http import HttpResponse
2022-12-17 14:30:51 -08:00
from django.shortcuts import redirect
2022-12-05 09:55:30 -08:00
from django.utils.decorators import method_decorator
from django.utils.safestring import mark_safe
2022-11-16 05:53:39 -08:00
from django.views.generic import TemplateView, View
from django.views.static import serve
2022-11-05 13:17:27 -07:00
from activities.services.timeline import TimelineService
2022-11-13 15:14:38 -08:00
from activities.views.timelines import Home
2022-12-05 09:55:30 -08:00
from core.decorators import cache_page
from core.models import Config
2022-11-05 13:17:27 -07:00
def homepage(request):
if request.user.is_authenticated:
return Home.as_view()(request)
elif request.domain.config_domain.single_user:
return redirect(f"/@{request.domain.config_domain.single_user}/")
2022-11-05 13:17:27 -07:00
else:
return About.as_view()(request)
2022-11-05 13:17:27 -07:00
@method_decorator(cache_page(public_only=True), name="dispatch")
class About(TemplateView):
template_name = "about.html"
2022-11-05 13:17:27 -07:00
def get_context_data(self):
service = TimelineService(None)
2022-11-05 13:17:27 -07:00
return {
"current_page": "about",
"content": mark_safe(
markdown_it.MarkdownIt().render(Config.system.site_about)
),
"posts": service.local()[:10],
2022-11-05 13:17:27 -07:00
}
2022-11-16 05:53:39 -08:00
class StaticContentView(View):
"""
A view that returns a bit of static content.
"""
# Content type of the static payload
content_type: str
# The static content that will be returned by the view
static_content: ClassVar[str | bytes]
def __init__(self, **kwargs):
super().__init__(**kwargs)
if getattr(StaticContentView, "static_content", None) is None:
StaticContentView.static_content = self.get_static_content()
def get(self, request, *args, **kwargs):
return HttpResponse(
StaticContentView.static_content,
content_type=self.content_type,
)
def get_static_content(self) -> str | bytes:
"""
Override to generate the view's static content.
"""
raise NotImplementedError()
2023-01-29 11:27:07 -08:00
@method_decorator(cache_page(60 * 60), name="dispatch")
class RobotsTxt(TemplateView):
"""
Serves the robots.txt for Takahē
To specify additional user-agents to disallow, use TAKAHE_ROBOTS_TXT_DISALLOWED_USER_AGENTS
"""
template_name = "robots.txt"
content_type = "text/plain"
def get_context_data(self):
return {
"user_agents": getattr(settings, "ROBOTS_TXT_DISALLOWED_USER_AGENTS", []),
}
class FlatPage(TemplateView):
"""
Serves a "flat page" from a config option,
returning 404 if it is empty.
"""
template_name = "flatpage.html"
config_option = None
title = None
2022-12-17 14:30:51 -08:00
def get(self, request, *args, **kwargs):
if self.config_option is None:
raise ValueError("No config option provided")
2022-12-17 14:30:51 -08:00
self.content = getattr(Config.system, self.config_option)
# If the content is a plain URL, then redirect to it instead
if (
"\n" not in self.content
and " " not in self.content
and "://" in self.content
):
return redirect(self.content)
return super().get(request, *args, **kwargs)
def get_context_data(self):
html = markdown_it.MarkdownIt().render(self.content)
return {
"title": self.title,
"content": mark_safe(html),
}
def custom_static_serve(*args, **keywords):
"""
Set the correct `Content-Type` header for static WebP images
since Django cannot guess the MIME type of WebP images.
"""
response = serve(*args, **keywords)
if keywords["path"].endswith(".webp"):
response.headers["Content-Type"] = "image/webp"
return response