[extensions-web] Back-port from class-based views to function views.



commit 344fbb06199d9ddea907bfdfe700f6e19b8cd3e4
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Wed Oct 19 14:57:48 2011 -0400

    Back-port from class-based views to function views.

 sweettooth/auth/views.py                           |    4 +-
 sweettooth/decorators.py                           |   37 +++
 sweettooth/errorreports/urls.py                    |    4 +-
 sweettooth/errorreports/views.py                   |   39 ++--
 sweettooth/extensions/models.py                    |    9 +
 .../extensions/templates/extensions/list.html      |    2 +-
 sweettooth/extensions/urls.py                      |   30 +-
 sweettooth/extensions/views.py                     |  295 ++++++++------------
 sweettooth/review/urls.py                          |   16 +-
 sweettooth/review/views.py                         |  192 ++++++--------
 sweettooth/utils.py                                |    6 +
 11 files changed, 307 insertions(+), 327 deletions(-)
---
diff --git a/sweettooth/auth/views.py b/sweettooth/auth/views.py
index 9cefde6..e3e3969 100644
--- a/sweettooth/auth/views.py
+++ b/sweettooth/auth/views.py
@@ -3,13 +3,15 @@ from django.contrib.auth import models
 from django.contrib.auth import login as auth_login, authenticate
 from django.contrib.auth.decorators import login_required
 from django.contrib.auth.views import login, logout
-from django.shortcuts import get_object_or_404, render, redirect
+from django.shortcuts import get_object_or_404, redirect
 
 from auth import forms
 
 from review.models import CodeReview
 from extensions.models import Extension
 
+from utils import render
+
 def profile(request, user):
     userobj = get_object_or_404(models.User, username=user)
 
diff --git a/sweettooth/decorators.py b/sweettooth/decorators.py
new file mode 100644
index 0000000..ca548b0
--- /dev/null
+++ b/sweettooth/decorators.py
@@ -0,0 +1,37 @@
+
+from django.shortcuts import get_object_or_404
+from django.http import HttpResponse, HttpResponseForbidden
+from django.utils.safestring import mark_safe
+
+import functools
+import json
+
+def model_view(model):
+    def inner(view):
+        @functools.wraps(view)
+        def new_view(request, pk, **kw):
+            obj = get_object_or_404(model, pk=pk)
+            return view(request, obj, **kw)
+        return new_view
+    return inner
+
+def post_only_view(view):
+    @functools.wraps(view)
+    def new_view(request, **kw):
+        if request.method != 'POST':
+            return HttpResponseForbidden()
+        return view(request, **kw)
+    return new_view
+
+def ajax_view(view):
+    @functools.wraps(view)
+    def new_view(request, **kw):
+        response = view(request, **kw)
+        if response is None:
+            return HttpResponse()
+        if not isinstance(response, HttpResponse):
+            response = HttpResponse(mark_safe(json.dumps(response)),
+                                    content_type="application/json")
+        return response
+
+    return new_view
diff --git a/sweettooth/errorreports/urls.py b/sweettooth/errorreports/urls.py
index 98115ab..6c73dcb 100644
--- a/sweettooth/errorreports/urls.py
+++ b/sweettooth/errorreports/urls.py
@@ -5,8 +5,8 @@ from errorreports import views
 
 urlpatterns = patterns('',
     url(r'^report/(?P<pk>\d+)',
-        views.ReportErrorView.as_view(), name='errorreports-report'),
+        views.report_error_view, name='errorreports-report'),
 
     url(r'^view/(?P<pk>\d+)',
-        views.ViewErrorReportView.as_view(), name='errorreports-view'),
+        views.view_error_report_view, name='errorreports-view'),
 )
diff --git a/sweettooth/errorreports/views.py b/sweettooth/errorreports/views.py
index 3cdc43f..fcb80c4 100644
--- a/sweettooth/errorreports/views.py
+++ b/sweettooth/errorreports/views.py
@@ -1,19 +1,18 @@
 
 from django.contrib import messages
 from django.shortcuts import redirect
-from django.views.generic import DetailView
 
 from errorreports.models import ErrorReport, error_reported
-from extensions.models import ExtensionVersion, VISIBLE_STATUSES
+from extensions.models import ExtensionVersion
 
-class ReportErrorView(DetailView):
-    queryset = ExtensionVersion.objects.filter(status__in=VISIBLE_STATUSES)
-    context_object_name = "version"
-    template_name = "errorreports/report.html"
+from decorators import post_only_view, model_view
+from utils import render
 
-    def post(self, request, *args, **kwargs):
-        self.object = self.get_object()
+ model_view(ExtensionVersion.objects.visible())
+def report_error_view(request, obj):
+    extension, version = obj.extension, obj
 
+    if request.method == 'POST':
         if request.POST['has_errors']:
             errors = request.POST['error']
         else:
@@ -26,23 +25,27 @@ class ReportErrorView(DetailView):
         else:
             user, email = None, request.POST['email']
 
-        report = ErrorReport(version=self.object,
+        report = ErrorReport(version=version,
                              comment=comment,
                              errors=errors,
                              user=user,
                              email=email)
         report.save()
 
-        error_reported.send(sender=self, version=self.object, report=report)
+        error_reported.send(sender=request, version=version, report=report)
 
         messages.info(request, "Thank you for your error report!")
 
         return redirect('extensions-version-detail',
-                        pk=self.object.pk,
-                        ext_pk=self.object.extension.pk,
-                        slug=self.object.extension.slug)
-
-class ViewErrorReportView(DetailView):
-    model = ErrorReport
-    context_object_name = "report"
-    template_name = "errorreports/view.html"
+                        pk=version.pk,
+                        ext_pk=extension.pk,
+                        slug=extension.slug)
+
+    else:
+        context = dict(version=version,
+                       extension=extension)
+        return render(request, 'errorreports/report.html', context)
+
+ model_view(ErrorReport)
+def view_error_report_view(request, obj):
+    return render(request, 'errorreports/view.html', dict(report=obj))
diff --git a/sweettooth/extensions/models.py b/sweettooth/extensions/models.py
index 0be22d9..e1ee881 100644
--- a/sweettooth/extensions/models.py
+++ b/sweettooth/extensions/models.py
@@ -152,6 +152,13 @@ def parse_zipfile_metadata(uploaded_file):
 # uuid max length + suffix max length
 filename_max_length = Extension._meta.get_field('uuid').max_length + len(".v000.shell-version.zip")
 
+class ExtensionVersionManager(models.Manager):
+    def locked(self):
+        return self.filter(status=STATUS_LOCKED)
+
+    def visible(self):
+        return self.filter(status__in=VISIBLE_STATUSES)
+
 class ExtensionVersion(models.Model):
     extension = models.ForeignKey(Extension, related_name="versions")
     version = models.IntegerField(default=0)
@@ -171,6 +178,8 @@ class ExtensionVersion(models.Model):
     source = models.FileField(upload_to=make_filename,
                               max_length=filename_max_length)
 
+    objects = ExtensionVersionManager()
+
     @property
     def shell_versions_json(self):
         return json.dumps([sv.version_string for sv in self.shell_versions.all()])
diff --git a/sweettooth/extensions/templates/extensions/list.html b/sweettooth/extensions/templates/extensions/list.html
index 82026b5..7c570bc 100644
--- a/sweettooth/extensions/templates/extensions/list.html
+++ b/sweettooth/extensions/templates/extensions/list.html
@@ -1,7 +1,7 @@
 {% extends "base.html" %}
 {% block body %}
   <ul class="extensions">
-  {% for extension in extensions %}
+  {% for extension in extension_list %}
   {% with version=extension.latest_version %}
     <li class="extension">
       {% if extension.icon %}
diff --git a/sweettooth/extensions/urls.py b/sweettooth/extensions/urls.py
index 3c2f6f1..218d289 100644
--- a/sweettooth/extensions/urls.py
+++ b/sweettooth/extensions/urls.py
@@ -1,6 +1,7 @@
 
 from django.conf.urls.defaults import patterns, include, url
-from django.views.generic import ListView, TemplateView
+from django.views.generic.simple import direct_to_template
+from django.views.generic.list_detail import object_list
 
 from extensions import views, models
 
@@ -10,35 +11,36 @@ upload_patterns = patterns('',
 )
 
 ajax_patterns = patterns('',
-    url(r'^edit/(?P<pk>\d+)', views.AjaxInlineEditView.as_view(), name='extensions-ajax-inline'),
-    url(r'^submit/(?P<pk>\d+)', views.AjaxSubmitAndLockView.as_view(), name='extensions-ajax-submit'),
-    url(r'^upload/screenshot/(?P<pk>\d+)', views.AjaxImageUploadView.as_view(field='screenshot'), name='extensions-ajax-screenshot'),
-    url(r'^upload/icon/(?P<pk>\d+)', views.AjaxImageUploadView.as_view(field='icon'), name='extensions-ajax-icon'),
-    url(r'^detail/', views.AjaxDetailsView.as_view(), name='extensions-ajax-details'),
+    url(r'^edit/(?P<pk>\d+)', views.ajax_inline_edit_view, name='extensions-ajax-inline'),
+    url(r'^submit/(?P<pk>\d+)', views.ajax_submit_and_lock_view, name='extensions-ajax-submit'),
+    url(r'^upload/screenshot/(?P<pk>\d+)', views.ajax_image_upload_view(field='screenshot'), name='extensions-ajax-screenshot'),
+    url(r'^upload/icon/(?P<pk>\d+)', views.ajax_image_upload_view(field='icon'), name='extensions-ajax-icon'),
+    url(r'^detail/', views.ajax_details_view, name='extensions-ajax-details'),
 )
 
 shell_patterns = patterns('',
-    url(r'^extension-info/', views.AjaxDetailsView.as_view()),
+    url(r'^extension-info/', views.ajax_details_view),
 
     url(r'^download-extension/(?P<uuid>.+)\.shell-extension\.zip$',
         views.download),
 )
 
 urlpatterns = patterns('',
-    url(r'^$', ListView.as_view(queryset=models.Extension.objects.visible(),
-                                context_object_name="extensions",
-                                template_name="extensions/list.html"), name='extensions-index'),
+    url(r'^$', object_list, dict(queryset=models.Extension.objects.visible(),
+                                 template_object_name='extension',
+                                 template_name='extensions/list.html'),
+        name='extensions-index'),
 
     # we ignore PK of extension, and get extension from version PK
     url(r'^extension/(?P<ext_pk>\d+)/(?P<slug>.+)/version/(?P<pk>\d+)/$',
-        views.ExtensionVersionView.as_view(), name='extensions-version-detail'),
+        views.extension_version_view, name='extensions-version-detail'),
 
     url(r'^extension/(?P<pk>\d+)/(?P<slug>.+)/$',
-        views.ExtensionLatestVersionView.as_view(), name='extensions-detail'),
+        views.extension_latest_version_view, name='extensions-detail'),
     url(r'^extension/(?P<pk>\d+)/$',
-        views.ExtensionLatestVersionView.as_view(), dict(slug=None), name='extensions-detail'),
+        views.extension_latest_version_view, dict(slug=None), name='extensions-detail'),
 
-    url(r'^local/', TemplateView.as_view(template_name="extensions/local.html"), name='extensions-local'),
+    url(r'^local/', direct_to_template, dict(template='extensions/local.html'), name='extensions-local'),
 
     url(r'^upload/', include(upload_patterns)),
     url(r'^ajax/', include(ajax_patterns)),
diff --git a/sweettooth/extensions/views.py b/sweettooth/extensions/views.py
index a06ddad..aad9e46 100644
--- a/sweettooth/extensions/views.py
+++ b/sweettooth/extensions/views.py
@@ -1,22 +1,16 @@
 
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-from django.core.exceptions import ObjectDoesNotExist
 from django.core.urlresolvers import reverse
 from django.contrib.auth.decorators import login_required
 from django.contrib import messages
-from django.http import HttpResponse, HttpResponseForbidden, Http404
-from django.shortcuts import get_object_or_404, render, redirect
-from django.utils.safestring import mark_for_escaping
-from django.views.generic import DetailView, View
-from django.views.generic.detail import SingleObjectMixin
+from django.http import HttpResponseForbidden, Http404
+from django.shortcuts import get_object_or_404, redirect
 
 from extensions import models
 from extensions.forms import UploadForm
 
+from decorators import ajax_view, model_view, post_only_view
+from utils import render
+
 def download(request, uuid):
     pk = request.GET['version_tag']
     version = get_object_or_404(models.ExtensionVersion, pk=pk)
@@ -26,196 +20,147 @@ def download(request, uuid):
 
     return redirect(version.source.url)
 
-class ExtensionLatestVersionView(DetailView):
-    model = models.Extension
-    context_object_name = "version"
-
-    @property
-    def template_name(self):
-        # If the user can edit the model, let him do so.
-        if self.object.extension.user_has_access(self.request.user):
-            return "extensions/detail_edit.html"
-        return "extensions/detail.html"
-
-    def get(self, request, **kwargs):
-        # Redirect if we don't match the slug.
-        slug = self.kwargs.get('slug')
-        self.object = self.get_object()
-        if self.object is None:
-            raise Http404()
+# Even though this is showing a version, the PK matches an extension
+ model_view(models.Extension)
+def extension_latest_version_view(request, obj, **kwargs):
+    extension, version = obj, obj.latest_version
+
+    if version is None:
+        raise Http404()
 
-        if slug == self.object.extension.slug:
-            context = self.get_context_data(object=self.object)
-            status = self.object.status
-            context['is_editable'] = status in models.EDITABLE_STATUSES
-            context['is_visible'] = status in models.VISIBLE_STATUSES
-            context['status'] = status
-            return self.render_to_response(context)
+    # Redirect if we don't match the slug.
+    slug = kwargs.get('slug')
 
-        kwargs = dict(self.kwargs)
-        kwargs.update(dict(slug=self.object.extension.slug))
+    if slug != extension.slug:
+        kwargs = dict(kwargs)
+        kwargs.update(dict(slug=extension.slug))
         return redirect('extensions-detail', **kwargs)
 
-    def get_object(self):
-        extension = super(ExtensionLatestVersionView, self).get_object()
-        return extension.latest_version
+    # If the user can edit the model, let him do so.
+    if extension.user_has_access(request.user):
+        template_name = "extensions/detail_edit.html"
+    else:
+        template_name = "extensions/detail.html"
+
+    status = version.status
+    context = dict(version = version,
+                   extension = extension,
+                   is_editable = status in models.EDITABLE_STATUSES,
+                   is_visible = status in models.VISIBLE_STATUSES,
+                   status = status)
+    return render(request, template_name, context)
 
-class ExtensionVersionView(DetailView):
-    model = models.ExtensionVersion
-    context_object_name = "version"
+ model_view(models.ExtensionVersion)
+def extension_version_view(request, obj, **kwargs):
+    extension, version = obj.extension, obj
 
-    @property
-    def template_name(self):
-        # If the user can edit the model, let him do so.
-        if self.object.extension.user_has_access(self.request.user):
-            return "extensions/detail_edit.html"
-        return "extensions/detail.html"
+    is_preview = False
 
-    def get(self, request, **kwargs):
-        self.object = self.get_object()
+    status = version.status
+    if status == models.STATUS_NEW:
+        # If it's unreviewed and unlocked, this is a preview
+        # for pre-lock.
+        is_preview = True
 
-        if self.object is None:
+        # Don't allow anybody (even moderators) to peek pre-lock.
+        if extension.creator != request.user:
             raise Http404()
 
-        is_preview = False
-        status = self.object.status
-        if status == models.STATUS_NEW:
-            # If it's unreviewed and unlocked, this is a preview
-            # for pre-lock.
-            is_preview = True
-
-            # Don't allow anybody (even moderators) to peek pre-lock.
-            if self.object.extension.creator != request.user:
-                raise Http404()
-
-        # Redirect if we don't match the slug or extension PK.
-        slug = self.kwargs.get('slug')
-        extpk = self.kwargs.get('ext_pk')
-        try:
-            extpk = int(extpk)
-        except ValueError:
-            extpk = None
-
-        if slug == self.object.extension.slug and extpk == self.object.extension.pk:
-            context = self.get_context_data(object=self.object)
-            context['is_preview'] = is_preview
-            context['is_editable'] = status in models.EDITABLE_STATUSES
-            context['is_visible'] = status in models.VISIBLE_STATUSES
-            context['is_rejected'] = status in models.REJECTED_STATUSES
-
-            if not is_preview:
-                context['old_version'] = self.object != self.object.extension.latest_version
-            context['status'] = status
-            return self.render_to_response(context)
-
-        kwargs = dict(self.kwargs)
-        kwargs.update(dict(slug=self.object.extension.slug,
-                           ext_pk=self.object.extension.pk))
+    # Redirect if we don't match the slug or extension PK.
+    slug = kwargs.get('slug')
+    extpk = kwargs.get('ext_pk')
+    try:
+        extpk = int(extpk)
+    except ValueError:
+        extpk = None
+
+    if slug != extension.slug or extpk != extension.pk:
+        kwargs.update(dict(slug=extension.slug,
+                           ext_pk=extension.pk))
         return redirect('extensions-version-detail', **kwargs)
 
-class AjaxSubmitAndLockView(SingleObjectMixin, View):
-    model = models.ExtensionVersion
-
-    def get(self, request, *args, **kwargs):
+    # If the user can edit the model, let him do so.
+    if extension.user_has_access(request.user):
+        template_name = "extensions/detail_edit.html"
+    else:
+        template_name = "extensions/detail.html"
+
+    context = dict(version = version,
+                   extension = extension,
+                   is_preview = is_preview,
+                   is_editable = status in models.EDITABLE_STATUSES,
+                   is_visible = status in models.VISIBLE_STATUSES,
+                   is_rejected = status in models.REJECTED_STATUSES,
+                   status = status)
+
+    if not is_preview:
+        context['old_version'] = version != extension.latest_version
+    return render(request, template_name, context)
+
+ ajax_view
+ post_only_view
+ model_view(models.ExtensionVersion)
+def ajax_submit_and_lock_view(request, obj):
+    if not obj.extension.user_has_access(request.user):
         return HttpResponseForbidden()
 
-    def post(self, request, *args, **kwargs):
-        self.object = self.get_object()
-
-        if not self.object.extension.user_has_access(request.user):
-            return HttpResponseForbidden()
-
-        if self.object.status != models.STATUS_NEW:
-            return HttpResponseForbidden()
-
-        self.object.status = models.STATUS_LOCKED
-        self.object.save()
-
-        models.submitted_for_review.send(sender=self, version=self.object)
-
-        return HttpResponse()
-
-class AjaxInlineEditView(SingleObjectMixin, View):
-    model = models.Extension
-
-    def get(self, request, *args, **kwargs):
+    if obj.status != models.STATUS_NEW:
         return HttpResponseForbidden()
 
-    def post(self, request, *args, **kwargs):
-        self.object = self.get_object()
-
-        if not self.object.user_has_access(request.user):
-            return HttpResponseForbidden()
-
-        key = self.request.POST['id']
-        value = self.request.POST['value']
-        if key.startswith('extension_'):
-            key = key[len('extension_'):]
-
-        whitelist = 'name', 'description', 'url'
-        if key not in whitelist:
-            return HttpResponseForbidden()
-
-        setattr(self.object, key, value)
-        self.object.save()
+    obj.status = models.STATUS_LOCKED
+    obj.save()
 
-        return HttpResponse(mark_for_escaping(value))
+    models.submitted_for_review.send(sender=request, version=obj)
 
-class AjaxImageUploadView(SingleObjectMixin, View):
-    model = models.Extension
-    field = None
-
-    def get(self, request, *args, **kwargs):
+ ajax_view
+ post_only_view
+ model_view(models.Extension)
+def ajax_inline_edit_view(request, obj):
+    if not obj.user_has_access(request.user):
         return HttpResponseForbidden()
 
-    def post(self, request, *args, **kwargs):
-        self.object = self.get_object()
-
-        if not self.object.user_has_access(request.user):
-            return HttpResponseForbidden()
-
-        setattr(self.object, self.field, request.FILES['file'])
-        self.object.save()
+    key = request.POST['id']
+    value = request.POST['value']
+    if key.startswith('extension_'):
+        key = key[len('extension_'):]
 
-        return HttpResponse()
-
-class AjaxDetailsView(SingleObjectMixin, View):
-    model = models.Extension
+    whitelist = 'name', 'description', 'url'
+    if key not in whitelist:
+        return HttpResponseForbidden()
 
-    def get(self, request, *args, **kwargs):
-        self.object = self.get_object()
-        if self.object is None:
-            raise Http404()
+    setattr(object, key, value)
+    obj.save()
 
-        data = {
-            'pk': self.object.pk,
-            'uuid': self.object.uuid,
-            'name': self.object.name,
-            'creator': self.object.creator.username,
-            'link': reverse('extensions-detail', kwargs=dict(pk=self.object.pk)),
-        }
+    return value
 
-        if self.object.icon:
-            data['icon'] = self.object.icon.url
+def ajax_image_upload_view(field):
+    @ajax_view
+    @post_only_view
+    @model_view(models.Extension)
+    def inner(request, obj):
+        setattr(obj, field, request.FILES['file'])
+        obj.save()
+    return field
 
-        return HttpResponse(json.dumps(data))
+ ajax_view
+def ajax_details_view(request):
+    uuid = request.GET.get('uuid', None)
 
-    def get_object(self, queryset=None):
-        if queryset is None:
-            queryset = self.get_queryset()
-        uuid = self.request.GET.get('uuid', None)
+    if uuid is None:
+        raise Http404()
 
-        if uuid is None:
-            return None
+    extension = get_object_or_404(models.Extension, uuid=uuid)
 
-        queryset = queryset.filter(uuid=uuid)
+    data = dict(pk = extension.pk,
+                uuid = extension.uuid,
+                name = extension.name,
+                creator = extension.creator.username,
+                link = reverse('extensions-detail', kwargs=dict(pk=extension.pk)))
 
-        try:
-            return queryset.get()
-        except ObjectDoesNotExist:
-            pass
+    if extension.icon:
+        data['icon'] = extension.icon.url
 
-        return None
+    return data
 
 @login_required
 def upload_file(request, pk):
diff --git a/sweettooth/review/urls.py b/sweettooth/review/urls.py
index 6f8e37d..e6da845 100644
--- a/sweettooth/review/urls.py
+++ b/sweettooth/review/urls.py
@@ -1,15 +1,19 @@
 
 from django.conf.urls.defaults import patterns, url
-from django.views.generic import ListView
+from django.views.generic.list_detail import object_list
 
+from extensions.models import ExtensionVersion
 from review import views
 
 urlpatterns = patterns('',
-    url(r'^$', views.ReviewListView.as_view(), name='review-list'),
-    url(r'^ajax/get-files/(?P<pk>\d+)', views.AjaxGetFilesView.as_view(), name='review-ajax-files'),
-    url(r'^submit/(?P<pk>\d+)', views.SubmitReviewView.as_view(), name='review-submit'),
-    url(r'^approve/(?P<pk>\d+)', views.ChangeStatusView.as_view(), name='review-approve'),
+    url(r'^$', object_list, dict(queryset=ExtensionVersion.objects.locked(),
+                                 template_object_name='version',
+                                 template_name='review/list.html'),
+        name='review-list'),
+    url(r'^ajax/get-files/(?P<pk>\d+)', views.ajax_get_files_view, name='review-ajax-files'),
+    url(r'^submit/(?P<pk>\d+)', views.submit_review_view, name='review-submit'),
+    url(r'^approve/(?P<pk>\d+)', views.change_status_view, name='review-approve'),
 
-    url(r'^(?P<pk>\d+)', views.ReviewVersionView.as_view(), name='review-version'),
+    url(r'^(?P<pk>\d+)', views.review_version_view, name='review-version'),
 
 )
diff --git a/sweettooth/review/views.py b/sweettooth/review/views.py
index 8b36540..bee543f 100644
--- a/sweettooth/review/views.py
+++ b/sweettooth/review/views.py
@@ -16,16 +16,15 @@ from django.conf import settings
 from django.core.mail import send_mail
 from django.core.urlresolvers import reverse
 from django.contrib import messages
-from django.dispatch import receiver
-from django.http import HttpResponse, HttpResponseForbidden, Http404
+from django.http import HttpResponseForbidden
 from django.shortcuts import redirect
-from django.utils.safestring import mark_safe
-from django.views.generic import View, DetailView, ListView
-from django.views.generic.detail import SingleObjectMixin
 
 from review.models import CodeReview, ChangeStatusLog, get_all_reviewers
 from extensions import models
 
+from decorators import ajax_view, model_view, post_only_view
+from utils import render
+
 IMAGE_TYPES = {
     '.png':  'image/png',
     '.jpg':  'image/jpeg',
@@ -50,144 +49,117 @@ def can_approve_extension(user, extension):
 
     return False
 
-class AjaxGetFilesView(SingleObjectMixin, View):
-    model = models.ExtensionVersion
+ ajax_view
+ model_view(models.ExtensionVersion)
+def ajax_get_files_view(request, obj):
     formatter = pygments.formatters.HtmlFormatter(style="borland", cssclass="code")
 
-    def get(self, request, *args, **kwargs):
-        self.object = self.get_object()
-        if self.object is None:
-            raise Http404()
-
-        if not can_review_extension(request.user, self.object.extension):
-            return HttpResponseForbidden()
-
-        zipfile = self.object.get_zipfile('r')
+    if not can_review_extension(request.user, obj.extension):
+        return HttpResponseForbidden()
 
-        show_linenum = False
+    zipfile = obj.get_zipfile('r')
 
-        # filename => { raw, html, filename }
-        files = []
-        for filename in zipfile.namelist():
-            raw = zipfile.open(filename, 'r').read()
+    show_linenum = False
 
-            base, extension = os.path.splitext(filename)
+    # filename => { raw, html, filename }
+    files = []
+    for filename in zipfile.namelist():
+        raw = zipfile.open(filename, 'r').read()
 
-            if extension in IMAGE_TYPES:
-                mime = IMAGE_TYPES[extension]
-                raw_base64 = base64.standard_b64encode(raw)
+        base, extension = os.path.splitext(filename)
 
-                html = '<img src="data:%s;base64,%s">' % (mime, raw_base64,)
+        if extension in IMAGE_TYPES:
+            mime = IMAGE_TYPES[extension]
+            raw_base64 = base64.standard_b64encode(raw)
 
-            else:
-                try:
-                    lexer = pygments.lexers.guess_lexer_for_filename(filename, raw)
-                except pygments.util.ClassNotFound:
-                    # released pygments doesn't yet have .json
-                    # so hack around it here.
-                    if filename.endswith('.json'):
-                        lexer = pygments.lexers.get_lexer_by_name('js')
-                    else:
-                        lexer = pygments.lexers.get_lexer_by_name('text')
+            html = '<img src="data:%s;base64,%s">' % (mime, raw_base64,)
 
-                html = pygments.highlight(raw, lexer, self.formatter)
-                show_linenum = True
+        else:
+            try:
+                lexer = pygments.lexers.guess_lexer_for_filename(filename, raw)
+            except pygments.util.ClassNotFound:
+                # released pygments doesn't yet have .json
+                # so hack around it here.
+                if filename.endswith('.json'):
+                    lexer = pygments.lexers.get_lexer_by_name('js')
+                else:
+                    lexer = pygments.lexers.get_lexer_by_name('text')
 
-            files.append(dict(filename=filename,
-                              raw=raw,
-                              html=html,
-                              show_linenum=show_linenum))
+            html = pygments.highlight(raw, lexer, formatter)
+            show_linenum = True
 
-        return HttpResponse(mark_safe(json.dumps(files)),
-                            content_type="application/json")
+        files.append(dict(filename=filename,
+                          raw=raw,
+                          html=html,
+                          show_linenum=show_linenum))
 
-class ChangeStatusView(SingleObjectMixin, View):
-    model = models.ExtensionVersion
+    return files
 
-    def get(self, request, *args, **kwargs):
+ post_only_view
+ model_view(models.ExtensionVersion)
+def change_status_view(request, obj):
+    if not can_approve_extension(request.user, obj.extension):
         return HttpResponseForbidden()
 
-    def post(self, request, *args, **kwargs):
-        self.object = self.get_object()
-
-        if not can_approve_extension(request.user, self.object.extension):
-            return HttpResponseForbidden()
-
-        newstatus_string = request.POST.get('newstatus')
-        newstatus = dict(Approve=models.STATUS_ACTIVE,
-                         Reject=models.STATUS_REJECTED)[newstatus_string]
+    newstatus_string = request.POST.get('newstatus')
+    newstatus = dict(Approve=models.STATUS_ACTIVE,
+                     Reject=models.STATUS_REJECTED)[newstatus_string]
 
-        log = ChangeStatusLog(user=request.user,
-                              version=self.object,
-                              newstatus=newstatus)
-        log.save()
+    log = ChangeStatusLog(user=request.user,
+                          version=obj,
+                          newstatus=newstatus)
+    log.save()
 
-        self.object.status = newstatus
-        self.object.save()
+    obj.status = newstatus
+    obj.save()
 
-        models.status_changed.send(sender=self, version=self.object, log=log)
+    models.status_changed.send(sender=request, version=obj, log=log)
 
-        return redirect('review-list')
+    return redirect('review-list')
 
-class SubmitReviewView(SingleObjectMixin, View):
-    model = models.ExtensionVersion
+ post_only_view
+ model_view(models.ExtensionVersion)
+def submit_review_view(request, obj):
+    extension, version = obj.extension, obj
 
-    def get(self, request, *args, **kwargs):
+    if not can_review_extension(request.user, extension):
         return HttpResponseForbidden()
 
-    def post(self, request, *args, **kwargs):
-        self.object = self.get_object()
-
-        if not can_review_extension(request.user, self.object.extension):
-            return HttpResponseForbidden()
-
-        review = CodeReview(version=self.object,
-                            reviewer=request.user,
-                            comments=request.POST.get('comments'))
-        review.save()
-
-        messages.info("Thank you for reviewing %s" % (self.object.extension.name,))
-
-        models.reviewed.send(sender=self, version=self.object, review=review)
-
-        return redirect('review-list')
+    review = CodeReview(version=version,
+                        reviewer=request.user,
+                        comments=request.POST.get('comments'))
+    review.save()
 
-class ReviewVersionView(DetailView):
-    model = models.ExtensionVersion
-    context_object_name = "version"
+    messages.info(request, "Thank you for reviewing %s" % (extension.name,))
 
-    def get_context_data(self, **kwargs):
-        context = super(ReviewVersionView, self).get_context_data(**kwargs)
-        # Reviews on previous versions of the same extension.
-        previous_versions = CodeReview.objects.filter(version__extension=self.object.extension)
+    models.reviewed.send(sender=request, version=version, review=review)
 
-        # Other reviews on the same version
-        previous_reviews = self.object.reviews.all()
+    return redirect('review-list')
 
-        can_approve = can_approve_extension(self.request.user, self.object.extension)
+ model_view(models.ExtensionVersion)
+def review_version_view(request, obj):
+    extension, version = obj.extension, obj
 
-        context.update(dict(previous_versions=previous_versions,
-                            previous_reviews=previous_reviews,
-                            can_approve=can_approve))
-        return context
+    # Reviews on previous versions of the same extension.
+    previous_versions = CodeReview.objects.filter(version__extension=extension)
 
-    @property
-    def template_name(self):
-        if can_review_extension(self.request.user, self.object.extension):
-            return "review/review_reviewer.html"
-        return "review/review.html"
+    # Other reviews on the same version
+    previous_reviews = version.reviews.all()
 
-class ReviewListView(ListView):
-    queryset=models.ExtensionVersion.objects.filter(status=models.STATUS_LOCKED)
-    context_object_name="versions"
-    template_name="review/list.html"
+    can_approve = can_approve_extension(request.user, extension)
 
-    def get(self, request, *args, **kwargs):
-        if not request.user.has_perm("review.can-review-extensions"):
-            return HttpResponseForbidden()
+    context = dict(extension=extension,
+                   version=version,
+                   previous_versions=previous_versions,
+                   previous_reviews=previous_reviews,
+                   can_approve=can_approve)
 
-        return super(ReviewListView, self).get(request, *args, **kwargs)
+    if can_review_extension(request.user, extension):
+        template_name = "review/review_reviewer.html"
+    else:
+        template_name = "review/review.html"
 
+    return render(request, template_name, context)
 
 on_submitted_subject = u"""
 GNOME Shell Extensions \N{EM DASH} New review request: "%(name)s", v%(ver)d
diff --git a/sweettooth/utils.py b/sweettooth/utils.py
new file mode 100644
index 0000000..5f87004
--- /dev/null
+++ b/sweettooth/utils.py
@@ -0,0 +1,6 @@
+
+from django.shortcuts import render_to_response
+from django.template import RequestContext
+
+def render(req, *args, **kwargs):
+    return render_to_response(context_instance=RequestContext(req), *args, **kwargs)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]