Require login to download a note, shift points around #302
authorCharles Connell <charles@connells.org>
Fri, 24 Jan 2014 05:35:54 +0000 (00:35 -0500)
committerCharles Connell <charles@connells.org>
Fri, 24 Jan 2014 05:35:54 +0000 (00:35 -0500)
karmaworld/apps/notes/views.py
karmaworld/apps/users/models.py
karmaworld/assets/img/note_download_disabled.png [new file with mode: 0644]
karmaworld/assets/js/note-detail.js
karmaworld/templates/base.html
karmaworld/templates/courses/course_list.html
karmaworld/templates/notes/note_detail.html
karmaworld/urls.py
karmaworld/utils/ajax_increment.py

index 2a19ae9c7e8d8bb8794d0391fbefd465d11fbd1e..5093b27b0408e8263e8808aa2f3fd05bb2b6c4b8 100644 (file)
@@ -255,3 +255,15 @@ def flag_note(request, pk):
     return ajax_increment(Note, request, pk, FLAG_FIELD, process_note_flag_events)
 
 
+def process_downloaded_note(request_user, note):
+    """Record that somebody has downloaded a note"""
+    if request_user.is_authenticated() and request_user != note.user:
+        NoteKarmaEvent.create_event(request_user, note, NoteKarmaEvent.DOWNLOADED_NOTE)
+        NoteKarmaEvent.create_event(note.user, note, NoteKarmaEvent.HAD_NOTE_DOWNLOADED)
+
+
+def downloaded_note(request, pk):
+    """Record that somebody has flagged a note."""
+    return ajax_base(Note, request, pk, process_downloaded_note)
+
+
index a8090afc6cd4b19d8aff0940b6ae41e4b3a4b779..a2e549fbab950646f4814b0956940897b08cbe11 100644 (file)
@@ -136,12 +136,17 @@ class NoteKarmaEvent(BaseKarmaEvent):
     NOTE_DELETED = 'deleted'
     GIVE_FLAG    = 'give_flag'
     GET_FLAGGED  = 'get_flagged'
+    DOWNLOADED_NOTE = 'downloaded'
+    HAD_NOTE_DOWNLOADED = 'was_downloaded'
+
     EVENT_TYPE_CHOICES = (
         (UPLOAD,       "You uploaded a note"),
         (THANKS,       "You received a thanks for your note"),
         (NOTE_DELETED, "Your note was deleted"),
         (GIVE_FLAG,    "You flagged a note"),
         (GET_FLAGGED,  "Your note was flagged as spam"),
+        (DOWNLOADED_NOTE,  "You downloaded a note"),
+        (HAD_NOTE_DOWNLOADED,  "Your note was downloaded"),
     )
     note = models.ForeignKey('notes.Note')
     event_type = models.CharField(max_length=15, choices=EVENT_TYPE_CHOICES)
@@ -151,7 +156,9 @@ class NoteKarmaEvent(BaseKarmaEvent):
         THANKS: 1,
         NOTE_DELETED: -5,
         GIVE_FLAG: -1,
-        GET_FLAGGED: -100
+        GET_FLAGGED: -100,
+        DOWNLOADED_NOTE: -2,
+        HAD_NOTE_DOWNLOADED: 2,
     }
 
     def get_message(self):
diff --git a/karmaworld/assets/img/note_download_disabled.png b/karmaworld/assets/img/note_download_disabled.png
new file mode 100644 (file)
index 0000000..f9d94de
Binary files /dev/null and b/karmaworld/assets/img/note_download_disabled.png differ
index 14d3a58f79f8668f58ed622a4cf08f51f4421b5f..da96df8508aad422a74c03a4bb65fe571d536955 100644 (file)
@@ -104,4 +104,18 @@ $(function() {
       });
     }
   });
+
+  $("#note-download-button").click(function(event) {
+    // disable handler so it won't be run again
+    $(this).unbind('click');
+
+    // tell server that somebody downloaded
+    // this note
+    $.ajax({
+      url: note_downloaded_url,
+      dataType: "json",
+      type: 'POST',
+      async: false
+    });
+  });
 });
index c1ced8457682b5c0284cd29c1f2ab39efcb3cd03..11dd8049167896ed69e20e8c1ce8c16a7065361c 100644 (file)
@@ -11,6 +11,7 @@
   <link rel="stylesheet" type="text/css" media="all" href="{{ STATIC_URL }}vendor/foundation-4.2.3/css/foundation.css">
   <link rel="stylesheet" type="text/css" media="all" href="{{ STATIC_URL }}css/global.css">
   <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">
+  <link rel="stylesheet" href="{{ STATIC_URL }}css/vendor/opentip.css"> <!-- opentip -->
   <!-- include Font Awesome -->
   <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
 
@@ -52,6 +53,7 @@
 {% endblock %}
 <!-- end block bodyscripts -->
 <script src="{{ STATIC_URL }}js/jquery-scrollto.min.js" ></script>
+<script src="{{ STATIC_URL }}js/opentip-jquery-excanvas.min.js"></script>
 
 </body>
 </html>
index 3d3ee2cd735219e9df1d9e23974b9b7e1d2fbb19..7d6b4f1c36d111b3f607b09c03385a329836d36a 100644 (file)
@@ -10,7 +10,6 @@
 <!-- <link rel="stylesheet" href="{{ STATIC_URL }}css/responsive-tables.css"> -->
 <link rel="stylesheet" href="{{ STATIC_URL }}css/course_list_table.css">
 <link rel="stylesheet" href="{{ STATIC_URL }}css/datatables-css/jquery.dataTables.css"> <!-- dataTables -->
-<link rel="stylesheet" href="{{ STATIC_URL }}css/vendor/opentip.css"> <!-- opentip -->
 {% endblock %}
 
 {% block pagescripts %}
@@ -157,5 +156,4 @@ $(document).ready(function() {
 {% endblock %}
 
 {% block bodyscripts %}
-  <script src="{{ STATIC_URL }}js/opentip-jquery-excanvas.min.js"></script>
 {% endblock bodyscripts %}
\ No newline at end of file
index df01226573c350ef5cad4274d3e1196bf1939160..187031cfae1aff521b3510ed7cf13167c0d994de 100644 (file)
@@ -13,6 +13,7 @@
   <script type="text/javascript">
     var note_thank_url = "{% url 'thank_note' note.id %}"
     var note_flag_url = "{% url 'flag_note' note.id %}"
+    var note_downloaded_url = "{% url 'downloaded_note' note.id %}"
     var csrf_token = "{{ csrf_token }}";
   </script>
   <script src="{{ STATIC_URL }}js/setup-ajax.js"></script>
               <a href="#" id="thank-button-disabled" {% if not already_thanked %} class="hide" {% endif %}><img src="{{ STATIC_URL }}img/note_thank_disabled.png" alt="note_thank" width="34" height="34"/></a>
             </div>
             <div class="small-4 column">
-              <a href="{{ note.fp_file }}">
-                <img src="{{ STATIC_URL }}img/note_download.png" alt="note_download" width="51" height="36" />
-              </a>
+              {% if user.is_authenticated %}
+                <a id="note-download-button" href="{{ note.fp_file }}">
+                  <img
+                    src="{{ STATIC_URL }}img/note_download.png"
+                    alt="note_download"
+                    width="51" height="36"
+                    data-ot="It costs 2 karma points to download a note"
+                    data-ot-target="true"
+                    data-ot-tip-joint="top center"
+                    data-ot-target-joint="bottom center"
+                    data-ot-background="white"
+                    data-ot-border-color="black"
+                    class="opentip" />
+                </a>
+              {% else %}
+                <img src="{{ STATIC_URL }}img/note_download_disabled.png" alt="note_download" width="51" height="36"
+                    data-ot="You need to log in to download a note"
+                    data-ot-target="true"
+                    data-ot-tip-joint="top center"
+                    data-ot-target-joint="bottom center"
+                    data-ot-background="white"
+                    data-ot-border-color="black"
+                    class="opentip" />
+              {% endif %}
             </div>
           </div>
         </div><!-- /note_actions -->
 
 {% endblock %}
 
+
index 6cbffeb0b40adf376b32e22f8d003b07289764ed..ee571f234968cd3e42d701d5b5366fa920ef5664 100644 (file)
@@ -15,7 +15,7 @@ from karmaworld.apps.courses.views import CourseListView
 from karmaworld.apps.courses.views import school_list
 from karmaworld.apps.courses.views import school_course_list
 from karmaworld.apps.courses.views import school_course_instructor_list
-from karmaworld.apps.notes.views import NoteView, thank_note, NoteSearchView, flag_note
+from karmaworld.apps.notes.views import NoteView, thank_note, NoteSearchView, flag_note, downloaded_note
 from karmaworld.apps.notes.views import RawNoteDetailView
 from karmaworld.apps.notes.views import PDFView
 from karmaworld.apps.moderation import moderator
@@ -96,6 +96,8 @@ urlpatterns = patterns('',
     url(r'^ajax/note/thank/(?P<pk>[\d]+)/$', thank_note, name='thank_note'),
     # Ajax endpoint to flag a note
     url(r'^ajax/note/flag/(?P<pk>[\d]+)/$', flag_note, name='flag_note'),
+    # Ajax endpoint to record that somebody downloaded a note
+    url(r'^ajax/note/downloaded/(?P<pk>[\d]+)/$', downloaded_note, name='downloaded_note'),
     # Ajax endpoint to flag a course
     url(r'^ajax/course/flag/(?P<pk>[\d]+)/$', flag_course, name='flag_course'),
 
index d399443d2327b7fb47027ccfa60474a9f9053fcb..2e6e4668afbc763a4dfdd0e349a07b06ce9f4a3a 100644 (file)
@@ -7,29 +7,36 @@ def format_session_increment_field(cls, id, field):
     return cls.__name__ + '-' + field + '-' + str(id)
 
 
-def ajax_increment(cls, request, pk, field, event_processor=None):
-    """Increment a note's field by one."""
+def ajax_base(cls, request, pk, event_processor):
+    """Handle an AJAX request"""
     if not (request.method == 'POST' and request.is_ajax()):
         # return that the api call failed
         return HttpResponseBadRequest(json.dumps({'status': 'fail', 'message': 'must be a POST ajax request'}),
                                       mimetype="application/json")
 
     try:
-        # Increment counter
-        note = cls.objects.get(pk=pk)
-        count = getattr(note, field)
-        setattr(note, field,  count+1)
-        note.save()
+        obj = cls.objects.get(pk=pk)
+        event_processor(request.user, obj)
+
+    except ObjectDoesNotExist:
+        return HttpResponseNotFound(json.dumps({'status': 'fail', 'message': 'id does not match a ' + cls.__name__}),
+                                    mimetype="application/json")
+
+    return HttpResponse(status=204)
+
+
+def ajax_increment(cls, request, pk, field, event_processor=None):
+    def ajax_increment_work(request_user, obj):
+        count = getattr(obj, field)
+        setattr(obj, field,  count+1)
+        obj.save()
 
         if event_processor:
-            event_processor(request.user, note)
+            event_processor(request.user, obj)
 
         # Record that user has performed this, to prevent
         # them from doing it again
         request.session[format_session_increment_field(cls, pk, field)] = True
-    except ObjectDoesNotExist:
-        return HttpResponseNotFound(json.dumps({'status': 'fail', 'message': 'note id does not match a note'}),
-                                    mimetype="application/json")
 
-    return HttpResponse(status=204)
+    return ajax_base(cls, request, pk, ajax_increment_work)