From 54974a51ca9bc7bb3482c84705e4184435abb4f4 Mon Sep 17 00:00:00 2001 From: lduarte1991 Date: Fri, 6 Jun 2014 10:09:22 -0400 Subject: [PATCH 1/2] Annotation Tools: Added CommonAnnotatorMixin --- common/lib/xmodule/xmodule/annotator_mixin.py | 43 +++++++++++++++++++ .../xmodule/xmodule/imageannotation_module.py | 42 ++---------------- .../xmodule/xmodule/textannotation_module.py | 41 ++---------------- .../xmodule/xmodule/videoannotation_module.py | 42 +++--------------- 4 files changed, 56 insertions(+), 112 deletions(-) diff --git a/common/lib/xmodule/xmodule/annotator_mixin.py b/common/lib/xmodule/xmodule/annotator_mixin.py index aa597702db..114dde292c 100644 --- a/common/lib/xmodule/xmodule/annotator_mixin.py +++ b/common/lib/xmodule/xmodule/annotator_mixin.py @@ -6,7 +6,10 @@ from lxml import etree from urlparse import urlparse from os.path import splitext, basename from HTMLParser import HTMLParser +from xblock.core import Scope, String +# Make '_' a no-op so we can scrape strings +_ = lambda text: text def get_instructions(xmltree): """ Removes from the xmltree and returns them as a string, otherwise None. """ @@ -53,3 +56,43 @@ def html_to_text(html): htmlstripper = MLStripper() htmlstripper.feed(html) return htmlstripper.get_data() + + +class CommonAnnotatorMixin(object): + annotation_storage_url = String( + help=_("Location of Annotation backend"), + scope=Scope.settings, + default="http://your_annotation_storage.com", + display_name=_("Url for Annotation Storage") + ) + annotation_token_secret = String( + help=_("Secret string for annotation storage"), + scope=Scope.settings, + default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + display_name=_("Secret Token String for Annotation") + ) + default_tab = String( + display_name=_("Default Annotations Tab"), + help=_("Select which tab will be the default in the annotations table: myNotes, Instructor, or Public."), + scope=Scope.settings, + default="myNotes", + ) + # currently only supports one instructor, will build functionality for multiple later + instructor_email = String( + display_name=_("Email for 'Instructor' Annotations"), + help=_("Email of the user that will be attached to all annotations that will be found in 'Instructor' tab."), + scope=Scope.settings, + default="", + ) + annotation_mode = String( + display_name=_("Mode for Annotation Tool"), + help=_("Type in number corresponding to following modes: 'instructor' or 'everyone'"), + scope=Scope.settings, + default="everyone", + ) + extra_context = { + 'annotation_storage': annotation_storage_url, + 'default_tab': default_tab, + 'instructor_email': instructor_email, + 'annotation_mode': annotation_mode, + } \ No newline at end of file diff --git a/common/lib/xmodule/xmodule/imageannotation_module.py b/common/lib/xmodule/xmodule/imageannotation_module.py index 40d50b8b06..31c095da59 100644 --- a/common/lib/xmodule/xmodule/imageannotation_module.py +++ b/common/lib/xmodule/xmodule/imageannotation_module.py @@ -7,7 +7,7 @@ from pkg_resources import resource_string from xmodule.x_module import XModule from xmodule.raw_module import RawDescriptor from xblock.core import Scope, String -from xmodule.annotator_mixin import get_instructions, html_to_text +from xmodule.annotator_mixin import CommonAnnotatorMixin, get_instructions, html_to_text from xmodule.annotator_token import retrieve_token from xblock.fragment import Fragment @@ -51,40 +51,9 @@ class AnnotatableFields(object): scope=Scope.settings, default='professor:green,teachingAssistant:blue', ) - annotation_storage_url = String( - help=_("Location of Annotation backend"), - scope=Scope.settings, - default="http://your_annotation_storage.com", - display_name=_("Url for Annotation Storage") - ) - annotation_token_secret = String( - help=_("Secret string for annotation storage"), - scope=Scope.settings, - default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - display_name=_("Secret Token String for Annotation") - ) - default_tab = String( - display_name=_("Default Annotations Tab"), - help=_("Select which tab will be the default in the annotations table: myNotes, Instructor, or Public."), - scope=Scope.settings, - default="myNotes", - ) - # currently only supports one instructor, will build functionality for multiple later - instructor_email = String( - display_name=_("Email for 'Instructor' Annotations"), - help=_("Email of the user that will be attached to all annotations that will be found in 'Instructor' tab."), - scope=Scope.settings, - default="", - ) - annotation_mode = String( - display_name=_("Mode for Annotation Tool"), - help=_("Type in number corresponding to following modes: 'instructor' or 'everyone'"), - scope=Scope.settings, - default="everyone", - ) -class ImageAnnotationModule(AnnotatableFields, XModule): +class ImageAnnotationModule(AnnotatableFields, CommonAnnotatorMixin, XModule): '''Image Annotation Module''' js = { 'coffee': [ @@ -119,15 +88,12 @@ class ImageAnnotationModule(AnnotatableFields, XModule): context = { 'display_name': self.display_name_with_default, 'instructions_html': self.instructions, - 'annotation_storage': self.annotation_storage_url, 'token': retrieve_token(self.user, self.annotation_token_secret), 'tag': self.instructor_tags, 'openseadragonjson': self.openseadragonjson, - 'default_tab': self.default_tab, - 'instructor_email': self.instructor_email, - 'annotation_mode': self.annotation_mode, } - + context.update(self.extra_context) + print context fragment = Fragment(self.system.render_template('imageannotation.html', context)) fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js") fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js") diff --git a/common/lib/xmodule/xmodule/textannotation_module.py b/common/lib/xmodule/xmodule/textannotation_module.py index 2bdda68ea2..1f10cea193 100644 --- a/common/lib/xmodule/xmodule/textannotation_module.py +++ b/common/lib/xmodule/xmodule/textannotation_module.py @@ -6,7 +6,7 @@ from pkg_resources import resource_string from xmodule.x_module import XModule from xmodule.raw_module import RawDescriptor from xblock.core import Scope, String -from xmodule.annotator_mixin import get_instructions +from xmodule.annotator_mixin import CommonAnnotatorMixin, get_instructions from xmodule.annotator_token import retrieve_token from xblock.fragment import Fragment import textwrap @@ -47,46 +47,15 @@ class AnnotatableFields(object): scope=Scope.settings, default='None', ) - annotation_storage_url = String( - help=_("Location of Annotation backend"), - scope=Scope.settings, - default="http://your_annotation_storage.com", - display_name=_("Url for Annotation Storage"), - ) - annotation_token_secret = String( - help=_("Secret string for annotation storage"), - scope=Scope.settings, - default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - display_name=_("Secret Token String for Annotation"), - ) diacritics = String( display_name=_("Diacritic Marks"), help=_("Add diacritic marks to be added to a text using the comma-separated form, i.e. markname;urltomark;baseline,markname2;urltomark2;baseline2"), scope=Scope.settings, default='', ) - default_tab = String( - display_name=_("Default Annotations Tab"), - help=_("Select which tab will be the default in the annotations table: myNotes, Instructor, or Public."), - scope=Scope.settings, - default="myNotes", - ) - # currently only supports one instructor, will build functionality for multiple later - instructor_email = String( - display_name=_("Email for 'Instructor' Annotations"), - help=_("Email of the user that will be attached to all annotations that will be found in 'Instructor' tab."), - scope=Scope.settings, - default="", - ) - annotation_mode = String( - display_name=_("Mode for Annotation Tool"), - help=_("Type in number corresponding to following modes: 'instructor' or 'everyone'"), - scope=Scope.settings, - default="everyone", - ) -class TextAnnotationModule(AnnotatableFields, XModule): +class TextAnnotationModule(AnnotatableFields, CommonAnnotatorMixin, XModule): ''' Text Annotation Module ''' js = {'coffee': [], 'js': []} @@ -117,13 +86,11 @@ class TextAnnotationModule(AnnotatableFields, XModule): 'source': self.source, 'instructions_html': self.instructions, 'content_html': self.content, - 'annotation_storage': self.annotation_storage_url, 'token': retrieve_token(self.user_email, self.annotation_token_secret), 'diacritic_marks': self.diacritics, - 'default_tab': self.default_tab, - 'instructor_email': self.instructor_email, - 'annotation_mode': self.annotation_mode, } + context.update(self.extra_context) + print context fragment = Fragment(self.system.render_template('textannotation.html', context)) fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js") fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js") diff --git a/common/lib/xmodule/xmodule/videoannotation_module.py b/common/lib/xmodule/xmodule/videoannotation_module.py index 95848c0e9e..cf93bf31d5 100644 --- a/common/lib/xmodule/xmodule/videoannotation_module.py +++ b/common/lib/xmodule/xmodule/videoannotation_module.py @@ -7,7 +7,7 @@ from pkg_resources import resource_string from xmodule.x_module import XModule from xmodule.raw_module import RawDescriptor from xblock.core import Scope, String -from xmodule.annotator_mixin import get_instructions, get_extension +from xmodule.annotator_mixin import CommonAnnotatorMixin, get_instructions, get_extension from xmodule.annotator_token import retrieve_token from xblock.fragment import Fragment @@ -45,39 +45,9 @@ class AnnotatableFields(object): scope=Scope.settings, default="" ) - annotation_storage_url = String( - help=_("Location of Annotation backend"), - scope=Scope.settings, - default="http://your_annotation_storage.com", - display_name=_("Url for Annotation Storage"), - ) - annotation_token_secret = String( - help=_("Secret string for annotation storage"), - scope=Scope.settings, - default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - display_name=_("Secret Token String for Annotation") - ) - default_tab = String( - display_name=_("Default Annotations Tab"), - help=_("Select which tab will be the default in the annotations table: myNotes, Instructor, or Public."), - scope=Scope.settings, - default="myNotes", - ) - # currently only supports one instructor, will build functionality for multiple later - instructor_email = String( - display_name=_("Email for 'Instructor' Annotations"), - help=_("Email of the user that will be attached to all annotations that will be found in 'Instructor' tab."), - scope=Scope.settings, - default="", - ) - annotation_mode = String( - display_name=_("Mode for Annotation Tool"), - help=_("Type in number corresponding to following modes: 'instructor' or 'everyone'"), - scope=Scope.settings, - default="everyone", - ) -class VideoAnnotationModule(AnnotatableFields, XModule): + +class VideoAnnotationModule(AnnotatableFields, CommonAnnotatorMixin, XModule): '''Video Annotation Module''' js = { 'coffee': [ @@ -123,12 +93,10 @@ class VideoAnnotationModule(AnnotatableFields, XModule): 'typeSource': extension, 'poster': self.poster_url, 'content_html': self.content, - 'annotation_storage': self.annotation_storage_url, 'token': retrieve_token(self.user_email, self.annotation_token_secret), - 'default_tab': self.default_tab, - 'instructor_email': self.instructor_email, - 'annotation_mode': self.annotation_mode, } + context.update(self.extra_context) + print context fragment = Fragment(self.system.render_template('videoannotation.html', context)) fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js") fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js") From 3bfb633fd396d6a3c3b317915ccc95e4d3d117bc Mon Sep 17 00:00:00 2001 From: lduarte1991 Date: Fri, 6 Jun 2014 12:36:59 -0400 Subject: [PATCH 2/2] Annotator Tool: Fixed delete bug and factored out settings Removed print context --- common/lib/xmodule/xmodule/annotator_mixin.py | 6 ---- .../xmodule/xmodule/imageannotation_module.py | 6 ++-- .../xmodule/xmodule/textannotation_module.py | 6 ++-- .../xmodule/xmodule/videoannotation_module.py | 6 ++-- common/static/js/vendor/ova/catch/js/catch.js | 33 +++++++++++-------- 5 files changed, 31 insertions(+), 26 deletions(-) diff --git a/common/lib/xmodule/xmodule/annotator_mixin.py b/common/lib/xmodule/xmodule/annotator_mixin.py index 114dde292c..93768f564c 100644 --- a/common/lib/xmodule/xmodule/annotator_mixin.py +++ b/common/lib/xmodule/xmodule/annotator_mixin.py @@ -90,9 +90,3 @@ class CommonAnnotatorMixin(object): scope=Scope.settings, default="everyone", ) - extra_context = { - 'annotation_storage': annotation_storage_url, - 'default_tab': default_tab, - 'instructor_email': instructor_email, - 'annotation_mode': annotation_mode, - } \ No newline at end of file diff --git a/common/lib/xmodule/xmodule/imageannotation_module.py b/common/lib/xmodule/xmodule/imageannotation_module.py index 31c095da59..b605dfa131 100644 --- a/common/lib/xmodule/xmodule/imageannotation_module.py +++ b/common/lib/xmodule/xmodule/imageannotation_module.py @@ -91,9 +91,11 @@ class ImageAnnotationModule(AnnotatableFields, CommonAnnotatorMixin, XModule): 'token': retrieve_token(self.user, self.annotation_token_secret), 'tag': self.instructor_tags, 'openseadragonjson': self.openseadragonjson, + 'annotation_storage': self.annotation_storage_url, + 'default_tab': self.default_tab, + 'instructor_email': self.instructor_email, + 'annotation_mode': self.annotation_mode, } - context.update(self.extra_context) - print context fragment = Fragment(self.system.render_template('imageannotation.html', context)) fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js") fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js") diff --git a/common/lib/xmodule/xmodule/textannotation_module.py b/common/lib/xmodule/xmodule/textannotation_module.py index 1f10cea193..cdfe43857d 100644 --- a/common/lib/xmodule/xmodule/textannotation_module.py +++ b/common/lib/xmodule/xmodule/textannotation_module.py @@ -88,9 +88,11 @@ class TextAnnotationModule(AnnotatableFields, CommonAnnotatorMixin, XModule): 'content_html': self.content, 'token': retrieve_token(self.user_email, self.annotation_token_secret), 'diacritic_marks': self.diacritics, + 'annotation_storage': self.annotation_storage_url, + 'default_tab': self.default_tab, + 'instructor_email': self.instructor_email, + 'annotation_mode': self.annotation_mode, } - context.update(self.extra_context) - print context fragment = Fragment(self.system.render_template('textannotation.html', context)) fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js") fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js") diff --git a/common/lib/xmodule/xmodule/videoannotation_module.py b/common/lib/xmodule/xmodule/videoannotation_module.py index cf93bf31d5..17dc49acb5 100644 --- a/common/lib/xmodule/xmodule/videoannotation_module.py +++ b/common/lib/xmodule/xmodule/videoannotation_module.py @@ -94,9 +94,11 @@ class VideoAnnotationModule(AnnotatableFields, CommonAnnotatorMixin, XModule): 'poster': self.poster_url, 'content_html': self.content, 'token': retrieve_token(self.user_email, self.annotation_token_secret), + 'annotation_storage': self.annotation_storage_url, + 'default_tab': self.default_tab, + 'instructor_email': self.instructor_email, + 'annotation_mode': self.annotation_mode, } - context.update(self.extra_context) - print context fragment = Fragment(self.system.render_template('videoannotation.html', context)) fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js") fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js") diff --git a/common/static/js/vendor/ova/catch/js/catch.js b/common/static/js/vendor/ova/catch/js/catch.js index 130d51a35e..a45b778d99 100644 --- a/common/static/js/vendor/ova/catch/js/catch.js +++ b/common/static/js/vendor/ova/catch/js/catch.js @@ -613,21 +613,26 @@ CatchAnnotation.prototype = { var annotations = annotator.plugins['Store'].annotations, tot = typeof annotations !='undefined'?annotations.length:0, attempts = 0; // max 100 + if(annotation.media == "image"){ + self.refreshCatch(true); + self.checkTotAnnotations(); + } else { //This is to watch the annotations object, to see when is deleted the annotation - var ischanged = function(){ - var new_tot = annotator.plugins['Store'].annotations.length; - if (attempts<100) - setTimeout(function(){ - if (new_tot != tot){ - self.refreshCatch(true); - self.checkTotAnnotations(); - }else{ - attempts++; - ischanged(); - } - },100); //wait for the change in the annotations - }; - ischanged(); + var ischanged = function(){ + var new_tot = annotator.plugins['Store'].annotations.length; + if (attempts<100) + setTimeout(function(){ + if (new_tot != tot){ + self.refreshCatch(true); + self.checkTotAnnotations(); + }else{ + attempts++; + ischanged(); + } + },100); //wait for the change in the annotations + }; + ischanged(); + } }); annotator.subscribe("annotationCreated", function (annotation){ var attempts = 0; // max 100