2022-12-25 21:26:15 +00:00
|
|
|
from typing import ClassVar
|
|
|
|
|
2022-12-06 02:21:00 +00:00
|
|
|
import markdown_it
|
2023-01-29 19:27:07 +00:00
|
|
|
from django.conf import settings
|
2022-12-25 21:26:15 +00:00
|
|
|
from django.http import HttpResponse
|
2022-12-17 22:30:51 +00:00
|
|
|
from django.shortcuts import redirect
|
2022-12-05 17:55:30 +00:00
|
|
|
from django.utils.decorators import method_decorator
|
2022-12-06 02:21:00 +00:00
|
|
|
from django.utils.safestring import mark_safe
|
2022-11-16 13:53:39 +00:00
|
|
|
from django.views.generic import TemplateView, View
|
2022-12-15 17:31:25 +00:00
|
|
|
from django.views.static import serve
|
2022-11-05 20:17:27 +00:00
|
|
|
|
2022-12-22 21:06:35 +00:00
|
|
|
from activities.services.timeline import TimelineService
|
2022-11-13 23:14:38 +00:00
|
|
|
from activities.views.timelines import Home
|
2022-12-05 17:55:30 +00:00
|
|
|
from core.decorators import cache_page
|
2022-12-06 02:21:00 +00:00
|
|
|
from core.models import Config
|
2022-11-05 20:17:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
def homepage(request):
|
|
|
|
if request.user.is_authenticated:
|
|
|
|
return Home.as_view()(request)
|
2023-05-03 20:35:41 +00:00
|
|
|
elif request.domain.config_domain.single_user:
|
|
|
|
return redirect(f"/@{request.domain.config_domain.single_user}/")
|
2022-11-05 20:17:27 +00:00
|
|
|
else:
|
2022-12-22 21:06:35 +00:00
|
|
|
return About.as_view()(request)
|
2022-11-05 20:17:27 +00:00
|
|
|
|
|
|
|
|
2022-12-06 05:23:07 +00:00
|
|
|
@method_decorator(cache_page(public_only=True), name="dispatch")
|
2022-12-22 21:06:35 +00:00
|
|
|
class About(TemplateView):
|
|
|
|
template_name = "about.html"
|
2022-11-05 20:17:27 +00:00
|
|
|
|
|
|
|
def get_context_data(self):
|
2023-04-28 01:09:16 +00:00
|
|
|
service = TimelineService(None)
|
2022-11-05 20:17:27 +00:00
|
|
|
return {
|
2022-12-22 21:06:35 +00:00
|
|
|
"current_page": "about",
|
|
|
|
"content": mark_safe(
|
2022-12-06 02:21:00 +00:00
|
|
|
markdown_it.MarkdownIt().render(Config.system.site_about)
|
|
|
|
),
|
2022-12-22 21:06:35 +00:00
|
|
|
"posts": service.local()[:10],
|
2022-11-05 20:17:27 +00:00
|
|
|
}
|
2022-11-16 13:53:39 +00:00
|
|
|
|
|
|
|
|
2022-12-25 21:26:15 +00: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 19:27:07 +00: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", []),
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-12-06 02:21:00 +00:00
|
|
|
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 22:30:51 +00:00
|
|
|
def get(self, request, *args, **kwargs):
|
2022-12-06 02:21:00 +00:00
|
|
|
if self.config_option is None:
|
|
|
|
raise ValueError("No config option provided")
|
2022-12-17 22:30:51 +00: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)
|
2022-12-06 02:21:00 +00:00
|
|
|
return {
|
|
|
|
"title": self.title,
|
|
|
|
"content": mark_safe(html),
|
|
|
|
}
|
2022-12-15 17:31:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
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
|