mirror of
https://github.com/DarrenOfficial/dpaste.git
synced 2024-11-15 16:12:51 +11:00
Make all views class-based.
This commit is contained in:
parent
82d49d0ed1
commit
1c2e26c930
4 changed files with 228 additions and 207 deletions
|
@ -2,34 +2,34 @@
|
||||||
|
|
||||||
<form method="post" action="" class="form-horizontal">
|
<form method="post" action="" class="form-horizontal">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ snippet_form.non_field_errors }}
|
{{ form.non_field_errors }}
|
||||||
<div style="display: none;">{{ snippet_form.title }}</div>
|
<div style="display: none;">{{ form.title }}</div>
|
||||||
|
|
||||||
<div class="
|
<div class="
|
||||||
control-group
|
control-group
|
||||||
form-content
|
form-content
|
||||||
superenter
|
superenter
|
||||||
{% if is_new %}autofocus{% endif %}
|
{% if not object %}autofocus{% endif %}
|
||||||
{% if snippet_form.content.errors %}error{% endif %}
|
{% if form.content.errors %}error{% endif %}
|
||||||
">
|
">
|
||||||
{{ snippet_form.content }}
|
{{ form.content }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="control-group form-options">
|
<div class="control-group form-options">
|
||||||
<div class="form-options-lexer
|
<div class="form-options-lexer
|
||||||
{% if snippet_form.lexer.errors %}control-group error{% endif %}">
|
{% if form.lexer.errors %}control-group error{% endif %}">
|
||||||
<div class="input-append">
|
<div class="input-append">
|
||||||
{{ snippet_form.lexer }}
|
{{ form.lexer }}
|
||||||
</div>
|
</div>
|
||||||
{% for error in snippet_form.lexer.errors %}
|
{% for error in form.lexer.errors %}
|
||||||
<span class="help-inline">{{ error }}</span>
|
<span class="help-inline">{{ error }}</span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<div class="form-options-expire">
|
<div class="form-options-expire">
|
||||||
{{ snippet_form.expires.errors }}
|
{{ form.expires.errors }}
|
||||||
<div class="input-prepend">
|
<div class="input-prepend">
|
||||||
<span class="add-on"><i class="icon-trash" title="{% trans "Expire in" %}"></i></span>
|
<span class="add-on"><i class="icon-trash" title="{% trans "Expire in" %}"></i></span>
|
||||||
{{ snippet_form.expires }}
|
{{ form.expires }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,14 +6,15 @@ from .. import views
|
||||||
L = getattr(settings, 'DPASTE_SLUG_LENGTH', 4)
|
L = getattr(settings, 'DPASTE_SLUG_LENGTH', 4)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^about/$', views.about, name='dpaste_about'),
|
url(r'^about/$', views.AboutView.as_view(), name='dpaste_about'),
|
||||||
|
|
||||||
url(r'^$', views.snippet_new, name='snippet_new'),
|
url(r'^$', views.SnippetView.as_view(), name='snippet_new'),
|
||||||
url(r'^diff/$', views.snippet_diff, name='snippet_diff'),
|
url(r'^diff/$', views.SnippetDiffView.as_view(), name='snippet_diff'),
|
||||||
url(r'^history/$', views.snippet_history, name='snippet_history'),
|
url(r'^history/$', views.SnippetHistory.as_view(), name='snippet_history'),
|
||||||
url(r'^delete/$', views.snippet_delete, name='snippet_delete'),
|
url(r'^delete/$', views.SnippetDeleteView.as_view(), name='snippet_delete'),
|
||||||
url(r'^(?P<snippet_id>[a-zA-Z0-9]{%d,})/?$' % L, views.snippet_details, name='snippet_details'),
|
|
||||||
url(r'^(?P<snippet_id>[a-zA-Z0-9]{%d,})/delete/$' % L, views.snippet_delete, name='snippet_delete'),
|
url(r'^(?P<snippet_id>[a-zA-Z0-9]{%d,})/?$' % L, views.SnippetDetailView.as_view(), name='snippet_details'),
|
||||||
|
url(r'^(?P<snippet_id>[a-zA-Z0-9]{%d,})/delete/$' % L, views.SnippetDeleteView.as_view(), name='snippet_delete'),
|
||||||
url(r'^(?P<snippet_id>[a-zA-Z0-9]{%d,})/gist/$' % L, views.snippet_gist, name='snippet_gist'),
|
url(r'^(?P<snippet_id>[a-zA-Z0-9]{%d,})/gist/$' % L, views.snippet_gist, name='snippet_gist'),
|
||||||
url(r'^(?P<snippet_id>[a-zA-Z0-9]{%d,})/raw/?$' % L, views.snippet_details, {'template_name': 'dpaste/snippet_details_raw.html', 'is_raw': True}, name='snippet_details_raw'),
|
url(r'^(?P<snippet_id>[a-zA-Z0-9]{%d,})/raw/?$' % L, views.SnippetRawView.as_view(), name='snippet_details_raw'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from django.conf.urls import patterns, url
|
from django.conf.urls import patterns, url
|
||||||
|
|
||||||
from ..views import snippet_api
|
from ..views import APIView
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^api/$', snippet_api, name='dpaste_api_create_snippet'),
|
url(r'^api/$', APIView.as_view(), name='dpaste_api_create_snippet'),
|
||||||
]
|
]
|
||||||
|
|
214
dpaste/views.py
214
dpaste/views.py
|
@ -9,12 +9,14 @@ from django.core.urlresolvers import reverse
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from django.http import (Http404, HttpResponse, HttpResponseBadRequest,
|
from django.http import (Http404, HttpResponse, HttpResponseBadRequest,
|
||||||
HttpResponseRedirect)
|
HttpResponseRedirect)
|
||||||
from django.shortcuts import get_object_or_404, render_to_response
|
from django.shortcuts import get_object_or_404
|
||||||
from django.template.context import RequestContext
|
from django.utils.decorators import method_decorator
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
from django.views.defaults import page_not_found as django_page_not_found
|
from django.views.defaults import page_not_found as django_page_not_found
|
||||||
from django.views.defaults import server_error as django_server_error
|
from django.views.defaults import server_error as django_server_error
|
||||||
|
from django.views.generic.base import View, TemplateView
|
||||||
|
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
|
||||||
|
|
||||||
|
@ -33,38 +35,47 @@ template_globals = {
|
||||||
# Snippet Handling
|
# Snippet Handling
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
def snippet_new(request, template_name='dpaste/snippet_new.html'):
|
from django.views.generic import FormView
|
||||||
|
|
||||||
|
class SnippetView(FormView):
|
||||||
"""
|
"""
|
||||||
Create a new snippet.
|
Create a new snippet.
|
||||||
"""
|
"""
|
||||||
if request.method == "POST":
|
form_class = SnippetForm
|
||||||
snippet_form = SnippetForm(data=request.POST, request=request)
|
template_name = 'dpaste/snippet_new.html'
|
||||||
if snippet_form.is_valid():
|
|
||||||
new_snippet = snippet_form.save()
|
|
||||||
url = new_snippet.get_absolute_url()
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
else:
|
|
||||||
snippet_form = SnippetForm(request=request)
|
|
||||||
|
|
||||||
template_context = {
|
def get_form_kwargs(self):
|
||||||
'snippet_form': snippet_form,
|
kwargs = super(SnippetView, self).get_form_kwargs()
|
||||||
|
kwargs.update({
|
||||||
|
'request': self.request,
|
||||||
|
})
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
ctx = super(SnippetView, self).get_context_data(**kwargs)
|
||||||
|
ctx.update(template_globals)
|
||||||
|
ctx.update({
|
||||||
'lexer_list': LEXER_LIST,
|
'lexer_list': LEXER_LIST,
|
||||||
'is_new': True,
|
})
|
||||||
}
|
return ctx
|
||||||
|
|
||||||
return render_to_response(
|
def form_valid(self, form):
|
||||||
template_name,
|
snippet = form.save()
|
||||||
template_context,
|
return HttpResponseRedirect(snippet.get_absolute_url())
|
||||||
RequestContext(request, template_globals)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def snippet_details(request, snippet_id, template_name='dpaste/snippet_details.html', is_raw=False):
|
class SnippetDetailView(SnippetView, DetailView):
|
||||||
"""
|
"""
|
||||||
Details list view of a snippet. Handles the actual view, reply and
|
Details list view of a snippet. Handles the actual view, reply and
|
||||||
tree/diff view.
|
tree/diff view.
|
||||||
"""
|
"""
|
||||||
snippet = get_object_or_404(Snippet, secret_id=snippet_id)
|
queryset = Snippet.objects.all()
|
||||||
|
template_name = 'dpaste/snippet_details.html'
|
||||||
|
slug_url_kwarg = 'snippet_id'
|
||||||
|
slug_field = 'secret_id'
|
||||||
|
|
||||||
|
def get(self, *args, **kwargs):
|
||||||
|
snippet = self.get_object()
|
||||||
|
|
||||||
# One-Time snippet get deleted if the view count matches our limit
|
# One-Time snippet get deleted if the view count matches our limit
|
||||||
if snippet.expire_type == Snippet.EXPIRE_ONETIME \
|
if snippet.expire_type == Snippet.EXPIRE_ONETIME \
|
||||||
|
@ -76,60 +87,57 @@ def snippet_details(request, snippet_id, template_name='dpaste/snippet_details.h
|
||||||
snippet.view_count += 1
|
snippet.view_count += 1
|
||||||
snippet.save()
|
snippet.save()
|
||||||
|
|
||||||
tree = snippet.get_root()
|
return super(SnippetDetailView, self).get(*args, **kwargs)
|
||||||
tree = tree.get_descendants(include_self=True)
|
|
||||||
|
|
||||||
new_snippet_initial = {
|
def get_initial(self):
|
||||||
|
snippet = self.get_object()
|
||||||
|
return {
|
||||||
'content': snippet.content,
|
'content': snippet.content,
|
||||||
'lexer': snippet.lexer,
|
'lexer': snippet.lexer,
|
||||||
}
|
}
|
||||||
|
|
||||||
if request.method == "POST":
|
def form_valid(self, form):
|
||||||
snippet_form = SnippetForm(
|
snippet = form.save(parent=self.get_object())
|
||||||
data=request.POST,
|
return HttpResponseRedirect(snippet.get_absolute_url())
|
||||||
request=request,
|
|
||||||
initial=new_snippet_initial)
|
|
||||||
if snippet_form.is_valid():
|
|
||||||
new_snippet = snippet_form.save(parent=snippet)
|
|
||||||
url = new_snippet.get_absolute_url()
|
|
||||||
return HttpResponseRedirect(url)
|
|
||||||
else:
|
|
||||||
snippet_form = SnippetForm(
|
|
||||||
initial=new_snippet_initial,
|
|
||||||
request=request)
|
|
||||||
|
|
||||||
template_context = {
|
def get_context_data(self, **kwargs):
|
||||||
'snippet_form': snippet_form,
|
self.object = snippet = self.get_object()
|
||||||
'snippet': snippet,
|
tree = snippet.get_root().get_descendants(include_self=True)
|
||||||
'lexers': LEXER_LIST,
|
|
||||||
|
ctx = super(SnippetDetailView, self).get_context_data(**kwargs)
|
||||||
|
ctx.update(template_globals)
|
||||||
|
ctx.update({
|
||||||
'lines': range(snippet.get_linecount()),
|
'lines': range(snippet.get_linecount()),
|
||||||
'tree': tree,
|
'tree': tree,
|
||||||
'wordwrap': snippet.lexer in LEXER_WORDWRAP and 'True' or 'False',
|
'wordwrap': snippet.lexer in LEXER_WORDWRAP and 'True' or 'False',
|
||||||
'gist': getattr(settings, 'DPASTE_ENABLE_GIST', True),
|
'gist': getattr(settings, 'DPASTE_ENABLE_GIST', True),
|
||||||
}
|
})
|
||||||
|
return ctx
|
||||||
|
|
||||||
response = render_to_response(
|
|
||||||
template_name,
|
|
||||||
template_context,
|
|
||||||
RequestContext(request, template_globals)
|
|
||||||
)
|
|
||||||
|
|
||||||
if is_raw:
|
class SnippetRawView(SnippetDetailView):
|
||||||
|
"""
|
||||||
|
Display the raw content of a snippet
|
||||||
|
"""
|
||||||
|
template_name = 'dpaste/snippet_details_raw.html'
|
||||||
|
|
||||||
|
def render_to_response(self, context, **response_kwargs):
|
||||||
|
snippet = self.get_object()
|
||||||
|
response = HttpResponse(snippet.content)
|
||||||
response['Content-Type'] = 'text/plain;charset=UTF-8'
|
response['Content-Type'] = 'text/plain;charset=UTF-8'
|
||||||
response['X-Content-Type-Options'] = 'nosniff'
|
response['X-Content-Type-Options'] = 'nosniff'
|
||||||
return response
|
return response
|
||||||
else:
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
def snippet_delete(request, snippet_id=None):
|
class SnippetDeleteView(View):
|
||||||
"""
|
"""
|
||||||
Delete a snippet. This is allowed by anybody as long as he knows the
|
Delete a snippet. This is allowed by anybody as long as he knows the
|
||||||
snippet id. I got too many manual requests to do this, mostly for legal
|
snippet id. I got too many manual requests to do this, mostly for legal
|
||||||
reasons and the chance to abuse this is not given anyway, since snippets
|
reasons and the chance to abuse this is not given anyway, since snippets
|
||||||
always expire.
|
always expire.
|
||||||
"""
|
"""
|
||||||
snippet_id = snippet_id or request.POST.get('snippet_id')
|
def dispatch(self, request, *args, **kwargs):
|
||||||
|
snippet_id = self.kwargs.get('snippet_id') or request.POST.get('snippet_id')
|
||||||
if not snippet_id:
|
if not snippet_id:
|
||||||
raise Http404('No snippet id given')
|
raise Http404('No snippet id given')
|
||||||
snippet = get_object_or_404(Snippet, secret_id=snippet_id)
|
snippet = get_object_or_404(Snippet, secret_id=snippet_id)
|
||||||
|
@ -137,57 +145,64 @@ def snippet_delete(request, snippet_id=None):
|
||||||
return HttpResponseRedirect(reverse('snippet_new'))
|
return HttpResponseRedirect(reverse('snippet_new'))
|
||||||
|
|
||||||
|
|
||||||
def snippet_history(request, template_name='dpaste/snippet_list.html'):
|
class SnippetHistory(TemplateView):
|
||||||
"""
|
"""
|
||||||
Display the last `n` snippets created by this user (and saved in his
|
Display the last `n` snippets created by this user (and saved in his
|
||||||
session).
|
session).
|
||||||
"""
|
"""
|
||||||
snippet_list = None
|
template_name = 'dpaste/snippet_list.html'
|
||||||
snippet_id_list = request.session.get('snippet_list', None)
|
|
||||||
if snippet_id_list:
|
def get(self, request, *args, **kwargs):
|
||||||
snippet_list = Snippet.objects.filter(pk__in=snippet_id_list)
|
snippet_id_list = request.session.get('snippet_list', [])
|
||||||
|
self.snippet_list = Snippet.objects.filter(pk__in=snippet_id_list)
|
||||||
|
|
||||||
if 'delete-all' in request.GET:
|
if 'delete-all' in request.GET:
|
||||||
if snippet_list:
|
self.snippet_list.delete()
|
||||||
for s in snippet_list:
|
|
||||||
s.delete()
|
|
||||||
return HttpResponseRedirect(reverse('snippet_history'))
|
return HttpResponseRedirect(reverse('snippet_history'))
|
||||||
|
return super(SnippetHistory, self).get(request, *args, **kwargs)
|
||||||
|
|
||||||
template_context = {
|
def get_context_data(self, **kwargs):
|
||||||
|
ctx = super(SnippetHistory, self).get_context_data(**kwargs)
|
||||||
|
ctx.update(template_globals)
|
||||||
|
ctx.update({
|
||||||
'snippets_max': getattr(settings, 'DPASTE_MAX_SNIPPETS_PER_USER', 10),
|
'snippets_max': getattr(settings, 'DPASTE_MAX_SNIPPETS_PER_USER', 10),
|
||||||
'snippet_list': snippet_list,
|
'snippet_list': self.snippet_list,
|
||||||
}
|
})
|
||||||
|
return ctx
|
||||||
return render_to_response(
|
|
||||||
template_name,
|
|
||||||
template_context,
|
|
||||||
RequestContext(request, template_globals)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def snippet_diff(request, template_name='dpaste/snippet_diff.html'):
|
class SnippetDiffView(TemplateView):
|
||||||
"""
|
"""
|
||||||
Display a diff between two given snippet secret ids.
|
Display a diff between two given snippet secret ids.
|
||||||
"""
|
"""
|
||||||
|
template_name = 'dpaste/snippet_diff.html'
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Some validation around input files we will compare later.
|
||||||
|
"""
|
||||||
if request.GET.get('a') and request.GET.get('a').isdigit() \
|
if request.GET.get('a') and request.GET.get('a').isdigit() \
|
||||||
and request.GET.get('b') and request.GET.get('b').isdigit():
|
and request.GET.get('b') and request.GET.get('b').isdigit():
|
||||||
try:
|
try:
|
||||||
fileA = Snippet.objects.get(pk=int(request.GET.get('a')))
|
self.fileA = Snippet.objects.get(pk=int(request.GET.get('a')))
|
||||||
fileB = Snippet.objects.get(pk=int(request.GET.get('b')))
|
self.fileB = Snippet.objects.get(pk=int(request.GET.get('b')))
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
return HttpResponseBadRequest(u'Selected file(s) does not exist.')
|
return HttpResponseBadRequest(u'Selected file(s) does not exist.')
|
||||||
else:
|
else:
|
||||||
return HttpResponseBadRequest(u'You must select two snippets.')
|
return HttpResponseBadRequest(u'You must select two snippets.')
|
||||||
|
|
||||||
|
return super(SnippetDiffView, self).get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def get_diff(self):
|
||||||
class DiffText(object):
|
class DiffText(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
diff = DiffText()
|
diff = DiffText()
|
||||||
|
|
||||||
if fileA.content != fileB.content:
|
if self.fileA.content != self.fileB.content:
|
||||||
d = difflib.unified_diff(
|
d = difflib.unified_diff(
|
||||||
fileA.content.splitlines(),
|
self.fileA.content.splitlines(),
|
||||||
fileB.content.splitlines(),
|
self.fileB.content.splitlines(),
|
||||||
'Original',
|
'Original',
|
||||||
'Current',
|
'Current',
|
||||||
lineterm=''
|
lineterm=''
|
||||||
|
@ -199,17 +214,17 @@ def snippet_diff(request, template_name='dpaste/snippet_diff.html'):
|
||||||
diff.content = _(u'No changes were made between this two files.')
|
diff.content = _(u'No changes were made between this two files.')
|
||||||
diff.lexer = 'text'
|
diff.lexer = 'text'
|
||||||
|
|
||||||
template_context = {
|
return diff
|
||||||
'snippet': diff,
|
|
||||||
'fileA': fileA,
|
|
||||||
'fileB': fileB,
|
|
||||||
}
|
|
||||||
|
|
||||||
return render_to_response(
|
def get_context_data(self, **kwargs):
|
||||||
template_name,
|
ctx = super(SnippetDiffView, self).get_context_data(**kwargs)
|
||||||
template_context,
|
ctx.update(template_globals)
|
||||||
RequestContext(request, template_globals)
|
ctx.update({
|
||||||
)
|
'snippet': self.get_diff(),
|
||||||
|
'fileA': self.fileA,
|
||||||
|
'fileB': self.fileB,
|
||||||
|
})
|
||||||
|
return ctx
|
||||||
|
|
||||||
|
|
||||||
def snippet_gist(request, snippet_id): # pragma: no cover
|
def snippet_gist(request, snippet_id): # pragma: no cover
|
||||||
|
@ -247,22 +262,22 @@ def snippet_gist(request, snippet_id): # pragma: no cover
|
||||||
# Static pages
|
# Static pages
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
def about(request, template_name='dpaste/about.html'):
|
class AboutView(TemplateView):
|
||||||
"""
|
"""
|
||||||
A rather static page, we need a view just to display a couple of
|
A rather static page, we need a view just to display a couple of
|
||||||
statistics.
|
statistics.
|
||||||
"""
|
"""
|
||||||
template_context = {
|
template_name = 'dpaste/about.html'
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
ctx = super(AboutView, self).get_context_data(**kwargs)
|
||||||
|
ctx.update(template_globals)
|
||||||
|
ctx.update({
|
||||||
'total': Snippet.objects.count(),
|
'total': Snippet.objects.count(),
|
||||||
'stats': Snippet.objects.values('lexer').annotate(
|
'stats': Snippet.objects.values('lexer').annotate(
|
||||||
count=Count('lexer')).order_by('-count')[:5],
|
count=Count('lexer')).order_by('-count')[:5],
|
||||||
}
|
})
|
||||||
|
return ctx
|
||||||
return render_to_response(
|
|
||||||
template_name,
|
|
||||||
template_context,
|
|
||||||
RequestContext(request, template_globals)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
@ -293,8 +308,13 @@ FORMAT_MAPPING = {
|
||||||
'json': _format_json,
|
'json': _format_json,
|
||||||
}
|
}
|
||||||
|
|
||||||
@csrf_exempt
|
|
||||||
def snippet_api(request):
|
class APIView(View):
|
||||||
|
"""
|
||||||
|
API View
|
||||||
|
"""
|
||||||
|
@method_decorator(csrf_exempt)
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
content = request.POST.get('content', '').strip()
|
content = request.POST.get('content', '').strip()
|
||||||
lexer = request.POST.get('lexer', LEXER_DEFAULT).strip()
|
lexer = request.POST.get('lexer', LEXER_DEFAULT).strip()
|
||||||
filename = request.POST.get('filename', '').strip()
|
filename = request.POST.get('filename', '').strip()
|
||||||
|
|
Loading…
Reference in a new issue