def save(self, user=None, *args, **kwargs):
super(RawDocument, self).save(*args, **kwargs)
+
+ def process_document(self, user=None):
if not self.is_processed:
tasks.process_raw_document.delay(self, user)
""" ajax endpoint for saving a FilePicker uploaded file form
"""
r_d_f = RawDocumentForm(request.POST)
+
if r_d_f.is_valid():
raw_document = r_d_f.save(commit=False)
raw_document.save()
# save the tags to the database, too. don't forget those guys.
r_d_f.save_m2m()
+ # Proccess document after the tags are saved so that it isn't converted
+ # to a note before the tags are attached to the document
+ raw_document.process_document()
return HttpResponse({'success'})
else:
import json
import traceback
import logging
+
+from django.core import serializers
from django.core.exceptions import ObjectDoesNotExist
from karmaworld.apps.courses.models import Course
from karmaworld.apps.notes.search import SearchIndex
"""Record that somebody has flagged a note."""
return ajax_base(Note, request, pk, process_downloaded_note)
+def edit_note_tags(request, pk):
+ """
+ Saves the posted string of tags
+ """
+ if request.method == "POST" and request.is_ajax():
+ note = Note.objects.get(pk=pk)
+
+ # note.tags.set(*json.loads(request.body))
+ note.tags.set(request.body)
+
+ note_json = serializers.serialize('json', [note,])
+ resp = json.loads(note_json)[0]
+ resp['fields']['tags'] = list(note.tags.names())
+
+ return HttpResponse(json.dumps(resp), mimetype="application/json")
+ else:
+ return HttpResponseBadRequest(json.dumps({'status': 'fail', 'message': 'Invalid request'}),
+ mimetype="application/json")
return sum
- def can_edit_courses(self):
+ def can_edit_items(self):
return (self.get_points() >= 20)
NO_BADGE = 0
#add-course-btn,
#existing-course-btn,
#save-btn,
+#save_note_tags,
#edit-save-btn
{
border: none;
- background-color: white;
+ background-color: transparent;
color: #f05a28;
cursor: pointer;
font: 30px/1.2em "MuseoSlab-300", serif;
margin-right: 3px;
}
-#note_status, #note_pedigree
+#note_status, #note_pedigree, #note_tags
{
text-align: center;
padding-top: 10px;
padding-bottom: 20px;
margin-bottom: 20px;
}
+
+.tag-span:after
+{
+ content: ', ';
+}
+
+.tag-span:last-child:after
+{
+ content: '';
+}
+
+#note_tags_form
+{
+ text-align: center;
+}
+
+#note_tags_input
+{
+ margin-left: 25%;
+ width: 50%;
+}
var newwidth;
if(document.getElementById){
- newheight = document.getElementById(id).contentWindow.document .body.scrollHeight;
- newwidth = document.getElementById(id).contentWindow.document .body.scrollWidth;
+ newheight = document.getElementById(id).contentWindow.document.body.scrollHeight;
+ newwidth = document.getElementById(id).contentWindow.document.body.scrollWidth;
}
document.getElementById(id).height = (newheight + 10) + "px";
};
});
- $.ajax(note_contents_url,
- {
- type: 'GET',
- xhrFields: {
- onprogress: function (progress) {
- var percentage = Math.floor((progress.loaded / progress.total) * 100);
- writeNoteFrame("<h3 style='text-align: center'>" + percentage + "%</h3>");
- }
- },
- success: function(data, textStatus, jqXHR) {
- writeNoteFrame(data);
- autoResize('noteframe');
- if (pdfControls == true) {
- setupPdfViewer();
- }
- },
- error: function(data, textStatus, jqXHR) {
- writeNoteFrame("<h3 style='text-align: center'>Sorry, your note could not be retrieved.</h3>");
+ $.ajax(note_contents_url, {
+ type: 'GET',
+ xhrFields: {
+ onprogress: function (progress) {
+ var percentage = Math.floor((progress.loaded / progress.total) * 100);
+ writeNoteFrame("<h3 style='text-align: center'>" + percentage + "%</h3>");
+ }
+ },
+ success: function(data, textStatus, jqXHR) {
+ writeNoteFrame(data);
+ autoResize('noteframe');
+ if (pdfControls == true) {
+ setupPdfViewer();
+ }
+ },
+ error: function(data, textStatus, jqXHR) {
+ writeNoteFrame("<h3 style='text-align: center'>Sorry, your note could not be retrieved.</h3>");
+ }
+ });
+
+ $('#edit_note_tags').click(function(event) {
+ $('#note_tags_form').slideToggle();
+ });
+
+ $('#save_note_tags').click(function(event) {
+ $.ajax({
+ url: edit_note_tags_url,
+ dataType: 'json',
+ data: $('#note_tags_input').val(),
+ // data: JSON.stringify(['test','tags']),//$('#edit-course-form').children().serialize(),
+ type: 'POST',
+ success: function(data) {
+ $('#note_tags_form').slideUp();
+ $('.tags').empty();
+ $.each(data.fields.tags, function(index, tag) {
+ $('.tags').append($('<span>', { class: 'tag-span', text: tag }));
+ });
}
});
+ });
});
<div class="row">
<div class="small-12 column center">
{% if user.is_authenticated %}
- {% if user.get_profile.can_edit_courses %}
+ {% if user.get_profile.can_edit_items %}
<a href="#" id="edit-button"><img src="{{ STATIC_URL }}img/edit.png" alt="edit_flag" width="25" height="35"/></a>
{% endif %}
</div>
</div><!-- /course_header -->
- {% if user.get_profile.can_edit_courses %}
+ {% if user.get_profile.can_edit_items %}
<section id="edit-course-form">
<form>
{% csrf_token %}
<script type="text/javascript">
var note_thank_url = "{% url 'thank_note' note.id %}"
var note_flag_url = "{% url 'flag_note' note.id %}"
+ var edit_note_tags_url = "{% url 'edit_note_tags' note.id %}"
var note_downloaded_url = "{% url 'downloaded_note' note.id %}"
var note_contents_url = "{{ S3_URL }}{{ note.get_relative_s3_path }}"
{% if pdf_controls %}
</div><!-- /note_name -->
</div>
+ <div class="row">
+ <div id="note_tags" class="twelve columns activity_details_context">
+ <span>Tags: </span>
+ <span class="tags">
+ {% for tag in note.tags.all %}
+ <span class="tag-span">{{ tag.name }}</span>
+ {% endfor %}
+ </span>
+ {% if user.get_profile.can_edit_items %}
+ <i id="edit_note_tags" class="fa fa-pencil-square-o"></i>
+ {% endif %}
+ </div><!-- /note_tags -->
+ </div>
+
+ {% if user.get_profile.can_edit_items %}
+ <div class="row">
+ <div id="note_tags_form" class="twelve columns activity_details_context hide">
+ <input id="note_tags_input" type="text" value="{% for tag in note.tags.all %}{{ tag.name }}{% if not forloop.last %}, {% endif %}{% endfor %}">
+ <button id="save_note_tags" type=button><i class="fa fa-save"></i> Save</button>
+ </div>
+ </div>
+ {% endif %}
+
<div class="row">
<div id="note_status" class="twelve columns">
<div class="activity_details_status">
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, downloaded_note
+from karmaworld.apps.notes.views import NoteView, thank_note, NoteSearchView, flag_note, downloaded_note, edit_note_tags
from karmaworld.apps.notes.views import RawNoteDetailView
from karmaworld.apps.notes.views import PDFView
from karmaworld.apps.moderation import moderator
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 update a notes tags
+ url(r'^ajax/note/tags/(?P<pk>[\d]+)/$', edit_note_tags, name='edit_note_tags'),
# 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
urllib3==1.5
google-api-python-client==1.0
django-grappelli==2.4.8
-git+https://github.com/FinalsClub/django-taggit.git
+django-taggit
git+https://github.com/btbonval/django-filepicker.git
filemagic==1.6
requests