2024-05-10 01:27:51 +00:00
|
|
|
from datetime import datetime
|
2016-11-02 20:47:13 +00:00
|
|
|
import mimetypes
|
2023-10-19 22:52:39 +00:00
|
|
|
|
2024-03-13 02:13:42 +00:00
|
|
|
from django.conf import settings
|
2024-03-20 10:41:42 +00:00
|
|
|
from django.http import FileResponse, Http404, HttpResponse, HttpResponseRedirect
|
2024-05-10 01:27:51 +00:00
|
|
|
from django.shortcuts import render
|
2024-03-20 10:41:42 +00:00
|
|
|
from django.template import RequestContext, Template
|
2018-11-20 16:58:34 +00:00
|
|
|
|
2024-05-10 01:27:51 +00:00
|
|
|
from .blog.models import Entry
|
|
|
|
from .news.models import PressRelease
|
|
|
|
from .supporters.models import Supporter
|
2015-03-03 18:40:18 +00:00
|
|
|
|
2024-05-10 01:27:51 +00:00
|
|
|
|
|
|
|
def frontpage(request):
|
|
|
|
"""Conservancy front page view
|
|
|
|
|
|
|
|
Performs all object queries necessary to render the front page.
|
|
|
|
"""
|
|
|
|
now = datetime.now()
|
|
|
|
context = {
|
|
|
|
'press_releases': PressRelease.objects.all().filter(pub_date__lte=now, sites=2)[:5],
|
|
|
|
'supporters_count': Supporter.objects.all().filter(display_until_date__gte=now).count(),
|
|
|
|
'blog': Entry.objects.all().filter(pub_date__lte=now)[:5],
|
|
|
|
}
|
|
|
|
return render(request, "frontpage.html", context)
|
|
|
|
|
|
|
|
|
|
|
|
def content(request, *args, **kwargs):
|
2024-03-13 02:13:42 +00:00
|
|
|
"""Faux CMS: bulk website content stored in templates and document files.
|
|
|
|
|
|
|
|
Rationale: Many websites have a CMS and store the majority of their website
|
|
|
|
content in a relational database eg. WordPress or Wagtail. That's useful
|
|
|
|
because various people can easily be given access to edit the website. The
|
|
|
|
downside is that is application complexity - the management of who change
|
|
|
|
what, when it changed and what changed becomes an application concern. At
|
|
|
|
the other end of the spectrum, we have files that are checked into a Git
|
|
|
|
repository - we get the precise who/what/when out of the box with Git, but
|
|
|
|
require you to have some technical knowledge and appropriate access to
|
|
|
|
commit. Since you're committing to a code repository, this also opens up the
|
|
|
|
possibility to break things you couldn't break via a CMS.
|
|
|
|
|
|
|
|
This view serves most of the textual pages and documents on
|
|
|
|
sfconservancy.org. It works a little like Apache serving mixed PHP/static
|
|
|
|
files - it looks at the URL and tries to find a matching file on the
|
|
|
|
filesystem. If it finds a template, it renders it via Django's template
|
|
|
|
infrastructure. If it finds a file but it's not a template, it will serve
|
|
|
|
the file as-is.
|
|
|
|
"""
|
2024-03-20 10:41:42 +00:00
|
|
|
base_path = settings.BASE_DIR / 'content'
|
2023-09-07 13:15:48 +00:00
|
|
|
path = request.path.lstrip('/')
|
|
|
|
if path.endswith('/'):
|
|
|
|
path += 'index.html'
|
2024-03-13 02:13:42 +00:00
|
|
|
full_path = (base_path / path).resolve()
|
|
|
|
safe_from_path_traversal = full_path.is_relative_to(base_path)
|
2024-03-20 04:45:46 +00:00
|
|
|
if full_path.is_dir():
|
|
|
|
# Should have been accessed with a trailing slash.
|
|
|
|
return HttpResponseRedirect(request.path + '/')
|
|
|
|
elif not full_path.exists() or not safe_from_path_traversal:
|
2024-03-13 02:13:42 +00:00
|
|
|
raise Http404()
|
|
|
|
is_template = mimetypes.guess_type(full_path)[0] == 'text/html'
|
|
|
|
if not is_template:
|
|
|
|
return FileResponse(open(full_path, 'rb'))
|
2016-11-02 20:47:13 +00:00
|
|
|
else:
|
2024-03-20 10:41:42 +00:00
|
|
|
# These template are intentionally not in the template loader path, so
|
|
|
|
# we open them directly, rather than using the template loader.
|
2024-03-21 23:10:57 +00:00
|
|
|
with open(full_path, encoding='utf-8') as t:
|
2024-03-20 10:41:42 +00:00
|
|
|
template = Template(t.read())
|
|
|
|
context = RequestContext(request, kwargs)
|
|
|
|
return HttpResponse(template.render(context))
|