mirror of
https://github.com/DarrenOfficial/dpaste.git
synced 2024-11-23 03:46:37 +11:00
Cache Fixes, Django 4.0 Update
This commit is contained in:
parent
0291bcd908
commit
49ca2d7631
7 changed files with 49 additions and 47 deletions
|
@ -1,6 +1,14 @@
|
||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
3.6 (master)
|
||||||
|
------------
|
||||||
|
|
||||||
|
- Added support for Python 3.9.
|
||||||
|
- Added support for Python 3.10.
|
||||||
|
- Removed cache headers for all views except 404. Due to that snippets can be
|
||||||
|
deleted, it's not trivial to have them removed from upstream caches.
|
||||||
|
|
||||||
3.5 (2020-01-08)
|
3.5 (2020-01-08)
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,9 @@ from django.apps import AppConfig, apps
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from logging import getLogger
|
||||||
|
|
||||||
|
log = getLogger(__file__)
|
||||||
|
|
||||||
class dpasteAppConfig(AppConfig):
|
class dpasteAppConfig(AppConfig):
|
||||||
name = "dpaste"
|
name = "dpaste"
|
||||||
|
@ -610,12 +613,8 @@ class dpasteAppConfig(AppConfig):
|
||||||
# ('zephir', 'Zephir')
|
# ('zephir', 'Zephir')
|
||||||
]
|
]
|
||||||
|
|
||||||
# Whether to send out cache headers (Max-Age, Never-Cache, etc.).
|
# Cache timeout for 404 and static pages. Snippets don't have an explicit
|
||||||
CACHE_HEADER = True
|
# Cache timeout set to avoid caching in upstream proxies.
|
||||||
|
|
||||||
# Defines how long pages are cached by upstream Proxies (Max-Age Header).
|
|
||||||
# This does not affect caching of snippets, their max-age limit is set
|
|
||||||
# to the expire date.
|
|
||||||
CACHE_TIMEOUT = 60 * 10
|
CACHE_TIMEOUT = 60 * 10
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
from django.conf.urls import include, url
|
from django.urls import include, re_path
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r"^", include("dpaste.urls.dpaste_api")),
|
re_path(r"^", include("dpaste.urls.dpaste_api")),
|
||||||
url(r"^", include("dpaste.urls.dpaste")),
|
re_path(r"^", include("dpaste.urls.dpaste")),
|
||||||
url(r"^i18n/", include("django.conf.urls.i18n")),
|
re_path(r"^i18n/", include("django.conf.urls.i18n")),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Custom error handlers which load `dpaste/<code>.html` instead of `<code>.html`
|
# Custom error handlers which load `dpaste/<code>.html` instead of `<code>.html`
|
||||||
handler404 = "dpaste.views.page_not_found"
|
handler404 = "dpaste.views.handler404"
|
||||||
handler500 = "dpaste.views.server_error"
|
handler500 = "dpaste.views.handler500"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.conf.urls import url
|
from django.urls import re_path
|
||||||
from django.views.decorators.cache import cache_control
|
from django.views.decorators.cache import cache_control
|
||||||
from django.views.decorators.clickjacking import xframe_options_exempt
|
from django.views.decorators.clickjacking import xframe_options_exempt
|
||||||
from django.views.generic import TemplateView
|
from django.views.generic import TemplateView
|
||||||
|
@ -11,8 +11,8 @@ L = getattr(settings, "DPASTE_SLUG_LENGTH", 4)
|
||||||
config = apps.get_app_config("dpaste")
|
config = apps.get_app_config("dpaste")
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r"^$", views.SnippetView.as_view(), name="snippet_new"),
|
re_path(r"^$", views.SnippetView.as_view(), name="snippet_new"),
|
||||||
url(
|
re_path(
|
||||||
r"^about/$",
|
r"^about/$",
|
||||||
cache_control(max_age=config.CACHE_TIMEOUT)(
|
cache_control(max_age=config.CACHE_TIMEOUT)(
|
||||||
TemplateView.as_view(
|
TemplateView.as_view(
|
||||||
|
@ -22,18 +22,18 @@ urlpatterns = [
|
||||||
),
|
),
|
||||||
name="dpaste_about",
|
name="dpaste_about",
|
||||||
),
|
),
|
||||||
url(r"^history/$", views.SnippetHistory.as_view(), name="snippet_history"),
|
re_path(r"^history/$", views.SnippetHistory.as_view(), name="snippet_history"),
|
||||||
url(
|
re_path(
|
||||||
r"^(?P<snippet_id>[a-zA-Z0-9]{%d,})/?$" % L,
|
r"^(?P<snippet_id>[a-zA-Z0-9]{%d,})/?$" % L,
|
||||||
views.SnippetDetailView.as_view(),
|
views.SnippetDetailView.as_view(),
|
||||||
name="snippet_details",
|
name="snippet_details",
|
||||||
),
|
),
|
||||||
url(
|
re_path(
|
||||||
r"^(?P<snippet_id>[a-zA-Z0-9]{%d,})/raw/?$" % L,
|
r"^(?P<snippet_id>[a-zA-Z0-9]{%d,})/raw/?$" % L,
|
||||||
views.SnippetRawView.as_view(),
|
views.SnippetRawView.as_view(),
|
||||||
name="snippet_details_raw",
|
name="snippet_details_raw",
|
||||||
),
|
),
|
||||||
url(
|
re_path(
|
||||||
r"^(?P<snippet_id>[a-zA-Z0-9]{%d,})/slim/?$" % L,
|
r"^(?P<snippet_id>[a-zA-Z0-9]{%d,})/slim/?$" % L,
|
||||||
xframe_options_exempt(
|
xframe_options_exempt(
|
||||||
views.SnippetDetailView.as_view(template_name="dpaste/details_slim.html")
|
views.SnippetDetailView.as_view(template_name="dpaste/details_slim.html")
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from django.conf.urls import url
|
from django.urls import re_path
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
|
||||||
from ..views import APIView
|
from ..views import APIView
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r"^api/$", csrf_exempt(APIView.as_view()), name="dpaste_api_create_snippet",)
|
re_path(r"^api/$", csrf_exempt(APIView.as_view()), name="dpaste_api_create_snippet",)
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import datetime
|
import datetime
|
||||||
import difflib
|
import difflib
|
||||||
|
import ipaddress
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
|
@ -14,19 +15,22 @@ from django.shortcuts import get_object_or_404, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.cache import add_never_cache_headers, patch_cache_control
|
from django.utils.cache import add_never_cache_headers, patch_cache_control
|
||||||
from django.utils.http import http_date
|
from django.utils.translation import gettext
|
||||||
from django.utils.translation import ugettext
|
|
||||||
from django.views.generic import FormView
|
from django.views.generic import FormView
|
||||||
from django.views.generic.base import TemplateView, View
|
from django.views.generic.base import TemplateView, View
|
||||||
from django.views.generic.detail import DetailView
|
from django.views.generic.detail import DetailView
|
||||||
from pygments.lexers import get_lexer_for_filename
|
from pygments.lexers import get_lexer_for_filename
|
||||||
from pygments.util import ClassNotFound
|
from pygments.util import ClassNotFound
|
||||||
|
from ratelimit.decorators import ratelimit
|
||||||
|
from ratelimit.exceptions import Ratelimited
|
||||||
|
|
||||||
from dpaste import highlight
|
from dpaste import highlight
|
||||||
from dpaste.forms import SnippetForm, get_expire_values
|
from dpaste.forms import SnippetForm, get_expire_values
|
||||||
from dpaste.highlight import PygmentsHighlighter
|
from dpaste.highlight import PygmentsHighlighter
|
||||||
from dpaste.models import Snippet
|
from dpaste.models import Snippet
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
config = apps.get_app_config("dpaste")
|
config = apps.get_app_config("dpaste")
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,8 +49,6 @@ class SnippetView(FormView):
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
response = super().get(request, *args, **kwargs)
|
response = super().get(request, *args, **kwargs)
|
||||||
if config.CACHE_HEADER:
|
|
||||||
patch_cache_control(response, max_age=config.CACHE_TIMEOUT)
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def get_form_kwargs(self):
|
def get_form_kwargs(self):
|
||||||
|
@ -111,18 +113,7 @@ class SnippetDetailView(DetailView, FormView):
|
||||||
snippet.view_count += 1
|
snippet.view_count += 1
|
||||||
snippet.save(update_fields=["view_count"])
|
snippet.save(update_fields=["view_count"])
|
||||||
|
|
||||||
response = super().get(request, *args, **kwargs)
|
return super().get(request, *args, **kwargs)
|
||||||
|
|
||||||
# Set the Max-Age header up until the snippet would expire
|
|
||||||
if config.CACHE_HEADER:
|
|
||||||
if snippet.expire_type == Snippet.EXPIRE_KEEP:
|
|
||||||
patch_cache_control(response, max_age=config.CACHE_TIMEOUT)
|
|
||||||
if snippet.expire_type == Snippet.EXPIRE_ONETIME:
|
|
||||||
add_never_cache_headers(response)
|
|
||||||
if snippet.expire_type == Snippet.EXPIRE_TIME and snippet.expires:
|
|
||||||
response["Expires"] = http_date(snippet.expires.timestamp())
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
snippet = self.get_object()
|
snippet = self.get_object()
|
||||||
|
@ -153,8 +144,8 @@ class SnippetDetailView(DetailView, FormView):
|
||||||
d = difflib.unified_diff(
|
d = difflib.unified_diff(
|
||||||
snippet.parent.content.splitlines(),
|
snippet.parent.content.splitlines(),
|
||||||
snippet.content.splitlines(),
|
snippet.content.splitlines(),
|
||||||
ugettext("Previous Snippet"),
|
gettext("Previous Snippet"),
|
||||||
ugettext("Current Snippet"),
|
gettext("Current Snippet"),
|
||||||
n=1,
|
n=1,
|
||||||
)
|
)
|
||||||
diff_code = "\n".join(d).strip()
|
diff_code = "\n".join(d).strip()
|
||||||
|
@ -188,7 +179,7 @@ class SnippetRawView(SnippetDetailView):
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
if not config.RAW_MODE_ENABLED:
|
if not config.RAW_MODE_ENABLED:
|
||||||
return HttpResponseForbidden(
|
return HttpResponseForbidden(
|
||||||
ugettext("This dpaste installation has Raw view mode disabled.")
|
gettext("This dpaste installation has Raw view mode disabled.")
|
||||||
)
|
)
|
||||||
return super().dispatch(request, *args, **kwargs)
|
return super().dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
|
@ -332,7 +323,10 @@ class APIView(View):
|
||||||
expire_type = Snippet.EXPIRE_TIME
|
expire_type = Snippet.EXPIRE_TIME
|
||||||
|
|
||||||
snippet = Snippet.objects.create(
|
snippet = Snippet.objects.create(
|
||||||
content=content, lexer=lexer, expires=expires, expire_type=expire_type,
|
content=content,
|
||||||
|
lexer=lexer,
|
||||||
|
expires=expires,
|
||||||
|
expire_type=expire_type,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Custom formatter for the API response
|
# Custom formatter for the API response
|
||||||
|
@ -349,17 +343,15 @@ class APIView(View):
|
||||||
# handle them here.
|
# handle them here.
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def handler404(request, exception=None, template_name="dpaste/404.html"):
|
||||||
def page_not_found(request, exception=None, template_name="dpaste/404.html"):
|
|
||||||
context = {}
|
context = {}
|
||||||
context.update(config.extra_template_context)
|
context.update(config.extra_template_context)
|
||||||
response = render(request, template_name, context, status=404)
|
response = render(request, template_name, context, status=404)
|
||||||
if config.CACHE_HEADER:
|
patch_cache_control(response, max_age=config.CACHE_TIMEOUT)
|
||||||
patch_cache_control(response, max_age=config.CACHE_TIMEOUT)
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
def server_error(request, template_name="dpaste/500.html"):
|
def handler500(request, template_name="dpaste/500.html"):
|
||||||
context = {}
|
context = {}
|
||||||
context.update(config.extra_template_context)
|
context.update(config.extra_template_context)
|
||||||
response = render(request, template_name, context, status=500)
|
response = render(request, template_name, context, status=500)
|
||||||
|
|
5
tox.ini
5
tox.ini
|
@ -4,7 +4,8 @@ skip_missing_interpreters=True
|
||||||
envlist=
|
envlist=
|
||||||
readme
|
readme
|
||||||
coverage_setup
|
coverage_setup
|
||||||
py{36,37,38}-django-{22,30,31}
|
py{36,37,38,39,310}-django-{22,30,31,32}
|
||||||
|
py{38,39,310}-django-{40}
|
||||||
coverage_report
|
coverage_report
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
|
@ -18,6 +19,8 @@ deps=
|
||||||
django-22: django>=2.2,<3.0
|
django-22: django>=2.2,<3.0
|
||||||
django-30: django>=3.0,<3.1
|
django-30: django>=3.0,<3.1
|
||||||
django-31: django>=3.1,<3.2
|
django-31: django>=3.1,<3.2
|
||||||
|
django-32: django>=3.2,<4.0
|
||||||
|
django-40: django>=4.0,<4.1
|
||||||
|
|
||||||
[testenv:coverage_setup]
|
[testenv:coverage_setup]
|
||||||
skip_install = True
|
skip_install = True
|
||||||
|
|
Loading…
Reference in a new issue