USER_PROFILE_FLAGS_FIELD = 'flagged_notes'
+def note_page_context_helper(note, request, context):
+ if note.is_pdf():
+ context['pdf_controls'] = True
+
+ if request.user.is_authenticated():
+ try:
+ request.user.get_profile().thanked_notes.get(pk=note.pk)
+ context['already_thanked'] = True
+ except ObjectDoesNotExist:
+ pass
+
+ try:
+ request.user.get_profile().flagged_notes.get(pk=note.pk)
+ context['already_flagged'] = True
+ except ObjectDoesNotExist:
+ pass
+
+
class NoteDetailView(DetailView):
""" Class-based view for the note html page """
model = Note
context_object_name = u"note" # name passed to template
- keyword_form_class = formset_factory(KeywordForm)
-
- def post(self, request, *args, **kwargs):
- formset = self.keyword_form_class(request.POST)
- if formset.is_valid():
- self.keyword_form_valid(formset)
- self.keyword_formset = self.keyword_form_class(initial=self.get_initial_keywords())
- return super(NoteDetailView, self).get(request, *args, **kwargs)
- else:
- self.keyword_formset = formset
- return super(NoteDetailView, self).get(request, *args, **kwargs)
-
- def get(self, request, *args, **kwargs):
- self.keyword_formset = self.keyword_form_class(initial=self.get_initial_keywords())
- return super(NoteDetailView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
""" Generate custom context for the page rendering a Note
+ if pdf, set the `pdf` flag
"""
- kwargs['keyword_prototype_form'] = KeywordForm
- kwargs['keyword_formset'] = self.keyword_formset
- kwargs['keywords'] = Keyword.objects.filter(note=self.object)
-
- if self.object.is_pdf():
- kwargs['pdf_controls'] = True
+ kwargs['show_note_container'] = True
- if self.request.user.is_authenticated():
- try:
- self.request.user.get_profile().thanked_notes.get(pk=self.object.pk)
- kwargs['already_thanked'] = True
- except ObjectDoesNotExist:
- pass
-
- try:
- self.request.user.get_profile().flagged_notes.get(pk=self.object.pk)
- kwargs['already_flagged'] = True
- except ObjectDoesNotExist:
- pass
+ note_page_context_helper(self.object, self.request, kwargs)
return super(NoteDetailView, self).get_context_data(**kwargs)
- def get_initial_keywords(self):
- existing_keywords = self.get_object().keyword_set.order_by('id')
- initial_data = [{'keyword': keyword.word, 'definition': keyword.definition, 'id': keyword.pk}
- for keyword in existing_keywords]
- return initial_data
-
- def keyword_form_valid(self, formset):
- for form in formset:
- word = form['keyword'].data
- definition = form['definition'].data
- id = form['id'].data
- if word == '':
- continue
- try:
- keyword_object = Keyword.objects.get(id=id)
- except (ValueError, ObjectDoesNotExist):
- keyword_object = Keyword()
-
- keyword_object.note = self.get_object()
- keyword_object.word = word
- keyword_object.definition = definition
- keyword_object.save()
-
class NoteSaveView(FormView, SingleObjectMixin):
""" Save a Note and then view the page,
return view(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
- if request.POST['action'] == 'tags-form':
- view = NoteSaveView.as_view()
- else:
- view = NoteDetailView.as_view()
+ view = NoteSaveView.as_view()
return view(request, *args, **kwargs)
+class NoteKeywordsView(FormView, SingleObjectMixin):
+ """ Class-based view for the note html page """
+ model = Note
+ context_object_name = u"note" # name passed to template
+ form_class = formset_factory(KeywordForm)
+ template_name = 'notes/note_detail.html'
+
+ def get_object(self, queryset=None):
+ return Note.objects.get(slug=self.kwargs['slug'])
+
+ def post(self, request, *args, **kwargs):
+ self.object = self.get_object()
+ formset = self.form_class(request.POST)
+ if formset.is_valid():
+ self.keyword_form_valid(formset)
+ self.keyword_formset = self.form_class(initial=self.get_initial_keywords())
+ return super(NoteKeywordsView, self).get(request, *args, **kwargs)
+ else:
+ self.keyword_formset = formset
+ return super(NoteKeywordsView, self).get(request, *args, **kwargs)
+
+ def get(self, request, *args, **kwargs):
+ self.object = self.get_object()
+ self.keyword_formset = self.form_class(initial=self.get_initial_keywords())
+ return super(NoteKeywordsView, self).get(request, *args, **kwargs)
+
+ def get_context_data(self, **kwargs):
+ kwargs['keyword_prototype_form'] = KeywordForm
+ kwargs['keyword_formset'] = self.keyword_formset
+ kwargs['keywords'] = Keyword.objects.filter(note=self.get_object())
+ kwargs['show_keywords'] = True
+
+ note_page_context_helper(self.get_object(), self.request, kwargs)
+
+ return super(NoteKeywordsView, self).get_context_data(**kwargs)
+
+ def get_initial_keywords(self):
+ existing_keywords = self.get_object().keyword_set.order_by('id')
+ initial_data = [{'keyword': keyword.word, 'definition': keyword.definition, 'id': keyword.pk}
+ for keyword in existing_keywords]
+ return initial_data
+
+ def keyword_form_valid(self, formset):
+ for form in formset:
+ word = form['keyword'].data
+ definition = form['definition'].data
+ id = form['id'].data
+ if word == '':
+ continue
+ try:
+ keyword_object = Keyword.objects.get(id=id)
+ except (ValueError, ObjectDoesNotExist):
+ keyword_object = Keyword()
+
+ keyword_object.note = self.get_object()
+ keyword_object.word = word
+ keyword_object.definition = definition
+ keyword_object.save()
+
+
class NoteSearchView(ListView):
template_name = 'notes/search_results.html'
mimetype="application/json")
-def set_delete_keyword(request):
+def set_delete_keyword_annotator(request):
return ajax_base(request, process_set_delete_keyword, ('POST', 'PUT', 'DELETE'))
-def get_keywords(request):
+def get_keywords_annotator(request):
annotation_uri = request.GET['uri']
try:
return HttpResponseNotFound(json.dumps({'status': 'fail', 'message': e.message}),
mimetype="application/json")
+
+def get_keywords_datatables(request):
+ annotation_uri = request.GET['uri']
+
+ try:
+ keywords = Keyword.objects.filter(note_id=annotation_uri)
+ keywords_data = {
+ 'total': len(keywords),
+ 'rows': []
+ }
+ for keyword in keywords:
+ keyword_data = {
+ 'quote': keyword.word,
+ 'text': keyword.definition,
+ 'ranges': json.loads(keyword.ranges),
+ 'created': keyword.timestamp.isoformat(),
+ }
+ keywords_data['rows'].append(keyword_data)
+
+ return HttpResponse(json.dumps(keywords_data), mimetype='application/json')
+
+ except ObjectDoesNotExist, e:
+ return HttpResponseNotFound(json.dumps({'status': 'fail', 'message': e.message}),
+ mimetype="application/json")
+
{{ note.course.school.name }}
{% endif %}
- <span style="display: inline;"><span class="show-for-large-up"><i class="fa fa-thumbs-up"></i> <span id="thank-number">{{ note.thanks }}</span> Thanks</span></span>
+ <span style="display: inline;"><span class="show-for-large-up"><i class="fa fa-thumbs-up"></i> <span id="thank-number">{{ note.thanks }}</span> Thank{{ note.thanks|pluralize }}</span></span>
</div>
</div>
<div class="row">
<div id="tabs" class="small-12 columns">
- <dl class="tabs show-for-large-up" data-tab data-options="deep_linking: true; scroll_to_content: false">
- <dd class="active"><a href="#note_container">Note</a></dd>
- <dd id="keywords-tab-button"><a href="#keywords">Key Terms & Definitions</a></dd>
+ <dl class="tabs show-for-large-up">
+ <dd id="note-tab-button" class="{% if show_note_container %}active{% endif %}">
+ <a href="{{ note.get_absolute_url }}">Note</a>
+ </dd>
+ <dd id="keywords-tab-button" class="{% if show_keywords %}active{% endif %}">
+ <a href="{{ note.get_absolute_keywords_url }}">Key Terms & Definitions</a>
+ </dd>
</dl>
- <div id="tabs-content" class="tabs-content">
- <div id="note_container" class="content active">
+ <div class="tabs-content">
+ </div>
+ {% if show_note_container %}
+ <div id="note_container" class="">
{% if pdf_controls %}
<div id="zoom-buttons" class="row show-for-medium-up">
<div id="outline-btn-wrapper" class="small-1 columns hide show-for-medium-up">
</div><!-- /body_copy -->
</div>
</div><!-- /note_container -->
-
+ {% endif %}
+ {% if show_keywords %}
<div id="keywords" class="content">
<div class="row">
<div class="small-12 columns">
{% endfor %}
</table>
- <form id="keyword-form" action="{{ note.get_absolute_url }}#keywords" method="post" class="hide">
+ <form id="keyword-form" action="{{ note.get_absolute_keywords_url }}" method="post" class="hide">
{% csrf_token %}
{{ keyword_formset.management_form }}
<div class="hide" id="keyword-form-prototype">
</form>
</div>
</div>
- </div>
- </div>
+ </div> <!-- keywords -->
+ {% endif %}
</div>
</div>
from karmaworld.apps.courses.views import CourseListView
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, edit_note_tags
+from karmaworld.apps.notes.views import NoteView, thank_note, NoteSearchView, flag_note, downloaded_note, edit_note_tags, \
+ NoteKeywordsView
from karmaworld.apps.moderation import moderator
from karmaworld.apps.document_upload.views import save_fp_upload
-from karmaworld.apps.quizzes.views import QuizView, KeywordEditView, quiz_answer, get_keywords, \
- set_delete_keyword
+from karmaworld.apps.quizzes.views import QuizView, KeywordEditView, quiz_answer, get_keywords_annotator, \
+ set_delete_keyword_annotator, get_keywords_datatables
from karmaworld.apps.users.views import ProfileView
from ajax_select import urls as ajax_select_urls
# Check if a quiz answer is correct
url(r'^ajax/quiz/check/$', quiz_answer, name='quiz_answer'),
- url(r'^ajax/annotations/annotations$', set_delete_keyword, name='set_keyword'),
- url(r'^ajax/annotations/search/$', get_keywords, name='get_keywords'),
+ url(r'^ajax/annotations/annotations$', set_delete_keyword_annotator, name='set_keyword'),
+ url(r'^ajax/annotations/search/$', get_keywords_annotator, name='get_keywords'),
+
# Valid url cases to the Note page
# a: school/course/id
# note file by note.slug
url(r'^note/' + SLUG.format('school_') + '/' + SLUG.format('course_') +'/'+ SLUG.format('') +'$',
NoteView.as_view(), name='note_detail'),
+ url(r'^note/' + SLUG.format('school_') + '/' + SLUG.format('course_') +'/'+ SLUG.format('') +'/keywords/$',
+ NoteKeywordsView.as_view(), name='note_keywords'),
# Quizzes
url(r'^quiz/(?P<pk>[\d]+)/$',