changeset 404:41411066b16d

Fixing #199; redid the downloads so the user has more control about how to save the file.
author Brian Neal <bgneal@gmail.com>
date Sun, 27 Mar 2011 23:21:17 +0000 (2011-03-27)
parents 6e425c9b9d16
children c99d8981068b
files gpp/downloads/static/js/downloads-get.js gpp/downloads/urls.py gpp/downloads/views.py gpp/templates/downloads/download.html gpp/templates/downloads/download_detail.html gpp/templates/downloads/download_list.html gpp/templates/downloads/download_summary.html gpp/templates/downloads/navigation.html
diffstat 8 files changed, 75 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gpp/downloads/static/js/downloads-get.js	Sun Mar 27 23:21:17 2011 +0000
@@ -0,0 +1,33 @@
+$(document).ready(function() {
+    $('.dl-button').each(function(n) {
+        var button = $(this);
+        var id = button.attr('id');
+        var numeric_id = -1;
+        if (id.match(/dl-(\d+)/))
+        {
+            numeric_id = RegExp.$1;
+        }
+        button.click(function() {
+           button.attr('disabled', 'disabled').val('Getting link, stand by...');
+           $.ajax({
+               url: '/downloads/request/', 
+               type: 'POST',
+               data: { id: numeric_id },
+               dataType: 'json',
+               success: function(result) {
+                  var link_id = result.id;
+                  var div = $('#link-' + link_id);
+                  div.hide();
+                  div.html(
+                     'Thank you! Your download is now ready. <a href="' + result.url +
+                        '">Click here to download</a>.');
+                  div.fadeIn(3000);
+               },
+               error: function (xhr, textStatus, ex) {
+                   alert('Oops, an error occurred. ' + xhr.statusText + ' - ' + 
+                      xhr.responseText);
+               }
+           });
+        });
+    });
+});
--- a/gpp/downloads/urls.py	Sun Mar 27 18:22:48 2011 +0000
+++ b/gpp/downloads/urls.py	Sun Mar 27 23:21:17 2011 +0000
@@ -10,10 +10,9 @@
        'category',
        name='downloads-category'),
     url(r'^details/(\d+)/$', 'details', name='downloads-details'),
-    url(r'^(\d+)/$', 'download', name='downloads-download'),
     url(r'^new/$', 'new', name='downloads-new'),
     url(r'^popular/$', 'popular', name='downloads-popular'),
-    url(r'^random/$', 'random_download', name='downloads-random'),
+    url(r'^request/$', 'request_download', name='downloads-request_download'),
     url(r'^rate/$', 'rate_download', name='downloads-rate'),
     url(r'^rating/$', 'rating', name='downloads-rating'),
     url(r'^thanks/$', 'thanks', name='downloads-add_thanks'),
--- a/gpp/downloads/views.py	Sun Mar 27 18:22:48 2011 +0000
+++ b/gpp/downloads/views.py	Sun Mar 27 23:21:17 2011 +0000
@@ -11,10 +11,12 @@
 from django.http import HttpResponseRedirect
 from django.http import HttpResponseForbidden
 from django.http import HttpResponseBadRequest
+from django.http import HttpResponseNotFound
 from django.core.paginator import InvalidPage
 from django.core.urlresolvers import reverse
 from django.db.models import Q
 from django.views.decorators.http import require_POST
+import django.utils.simplejson as json
 
 from core.paginator import DiggPaginator
 from core.functions import email_admins
@@ -47,7 +49,7 @@
 # Maps URL component to database field name for the Download table:
 
 DOWNLOAD_FIELD_MAP = {
-   'title': 'title', 
+   'title': 'title',
    'date': '-date_added',
    'rating': '-average_score',
    'hits': '-hits'
@@ -76,8 +78,8 @@
     return render_to_response('downloads/download_list.html', {
         's' : sort,
         'category' : cat,
-        'page' : the_page, 
-        }, 
+        'page' : the_page,
+        },
         context_instance = RequestContext(request))
 
 #######################################################################
@@ -98,7 +100,7 @@
     return render_to_response('downloads/download_summary.html', {
         'page': the_page,
         'title': 'Newest Downloads',
-        }, 
+        },
         context_instance = RequestContext(request))
 
 #######################################################################
@@ -119,7 +121,7 @@
     return render_to_response('downloads/download_summary.html', {
         'page': the_page,
         'title': 'Popular Downloads',
-        }, 
+        },
         context_instance = RequestContext(request))
 
 #######################################################################
@@ -139,53 +141,24 @@
     return render_to_response('downloads/download_summary.html', {
         'page': the_page,
         'title': 'Highest Rated Downloads',
-        }, 
+        },
         context_instance = RequestContext(request))
 
 #######################################################################
 
 @login_required
-@require_POST
-def download(request, id):
-    download = Download.public_objects.get(pk=id)
-    if download is None:
-        raise Http404
-    return _redirect_download(download)
-
-#######################################################################
-
-def _redirect_download(download):
-    download.hits += 1
-    download.save()
-    return HttpResponseRedirect(download.file.url)
-
-#######################################################################
-
-@login_required
 def details(request, id):
     download = Download.public_objects.get(pk=id)
     if download is None:
         raise Http404
     return render_to_response('downloads/download_detail.html', {
         'download' : download,
-        }, 
+        },
         context_instance = RequestContext(request))
 
 #######################################################################
 
 @login_required
-@require_POST
-def random_download(request):
-    ids = Download.public_objects.values_list('id', flat=True)
-    if not ids:
-        raise Http404
-    id = random.choice(ids)
-    download = Download.objects.get(pk=id)
-    return _redirect_download(download)
-
-#######################################################################
-
-@login_required
 def add(request):
     if request.method == 'POST':
         form = AddDownloadForm(request.POST, request.FILES)
@@ -225,7 +198,7 @@
         rating = request.POST.get('rating', None)
         if id is None or rating is None:
             return HttpResponseBadRequest('Missing id or rating.')
-        
+
         try:
             rating = int(rating)
         except ValueError:
@@ -250,3 +223,29 @@
             return HttpResponse('-1')
 
     return HttpResponseForbidden('You must be logged in to rate a download.')
+
+#######################################################################
+
+@require_POST
+def request_download(request):
+    """
+    This function is called by AJAX to request a download. We update the hit
+    count and then return a JSON object of the form:
+        { id: download-id, 'url': link-to-download }
+
+    """
+    if request.user.is_authenticated():
+        dl_id = request.POST.get('id')
+        if dl_id:
+            try:
+                dl = Download.public_objects.get(pk=dl_id)
+            except Download.DoesNotExist:
+                return HttpResponseNotFound("Download not found")
+
+            dl.hits += 1
+            dl.save()
+
+            s = json.dumps({'id': dl_id, 'url': dl.file.url})
+            return HttpResponse(s, content_type='application/json')
+
+    return HttpResponseForbidden('An error occurred.')
--- a/gpp/templates/downloads/download.html	Sun Mar 27 18:22:48 2011 +0000
+++ b/gpp/templates/downloads/download.html	Sun Mar 27 23:21:17 2011 +0000
@@ -6,7 +6,6 @@
 </dt>
 <dd>
 {{ download.html|safe }}
-<form action="{% url 'downloads-download' download.id %}" method="post">{% csrf_token %}
 <table>
 <tr>
     <th>Added By:</th>
@@ -23,7 +22,6 @@
     <th><img src="{{ STATIC_URL }}icons/comments.png" alt="Comments" title="Comments" />
        <a href="{% url 'downloads-details' download.id %}">Comments</a>:</th><td>{{ comment_count }}</td>
 </tr>
-<tr><td><input type="submit" value="Download Now" /></td></tr>
 </table>
-</form>
+<div id="link-{{ download.id }}"><button type="button" class="dl-button" id="dl-{{ download.id }}">Download</button></div>
 </dd>
--- a/gpp/templates/downloads/download_detail.html	Sun Mar 27 18:22:48 2011 +0000
+++ b/gpp/templates/downloads/download_detail.html	Sun Mar 27 23:21:17 2011 +0000
@@ -11,6 +11,7 @@
 {% script_tags "markitup jquery-ui" %}
 <script type="text/javascript" src="{{ STATIC_URL }}js/comments.js"></script>
 <script type="text/javascript" src="{{ STATIC_URL }}js/rating.js"></script>
+<script type="text/javascript" src="{{ STATIC_URL }}js/downloads-get.js"></script>
 {% endblock %}
 {% block content %}
 <h2>Downloads</h2>
--- a/gpp/templates/downloads/download_list.html	Sun Mar 27 18:22:48 2011 +0000
+++ b/gpp/templates/downloads/download_list.html	Sun Mar 27 23:21:17 2011 +0000
@@ -9,6 +9,7 @@
 {% endblock %}
 {% block custom_js %}
 <script type="text/javascript" src="{{ STATIC_URL }}js/rating.js"></script>
+<script type="text/javascript" src="{{ STATIC_URL }}js/downloads-get.js"></script>
 {% endblock %}
 {% block content %}
 <h2>Downloads</h2>
--- a/gpp/templates/downloads/download_summary.html	Sun Mar 27 18:22:48 2011 +0000
+++ b/gpp/templates/downloads/download_summary.html	Sun Mar 27 23:21:17 2011 +0000
@@ -8,6 +8,7 @@
 {% endblock %}
 {% block custom_js %}
 <script type="text/javascript" src="{{ STATIC_URL }}js/rating.js"></script>
+<script type="text/javascript" src="{{ STATIC_URL }}js/downloads-get.js"></script>
 {% endblock %}
 {% block content %}
 <h2>Downloads</h2>
--- a/gpp/templates/downloads/navigation.html	Sun Mar 27 18:22:48 2011 +0000
+++ b/gpp/templates/downloads/navigation.html	Sun Mar 27 23:21:17 2011 +0000
@@ -9,8 +9,4 @@
     <li><a href="{% url 'downloads-rating' %}">Highest Rated</a></li>
     <li><a href="{% url 'downloads-add' %}">Add</a></li>
 </ul>
-<center>
-   <form action="{% url 'downloads-random' %}" method="post">{% csrf_token %}
-      <input type="submit" title="Download a file at random" value="Surprise Me!" />
-   </form>
-</center>
+<br />