Skip to content
37 changes: 37 additions & 0 deletions common/lib/xmodule/xmodule/annotator_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
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 <instructions> from the xmltree and returns them as a string, otherwise None. """
Expand Down Expand Up @@ -53,3 +56,37 @@ 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",
)
22 changes: 6 additions & 16 deletions common/lib/xmodule/xmodule/imageannotation_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
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

Expand Down Expand Up @@ -51,21 +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")
)


class ImageAnnotationModule(AnnotatableFields, XModule):
class ImageAnnotationModule(AnnotatableFields, CommonAnnotatorMixin, XModule):
'''Image Annotation Module'''
js = {
'coffee': [
Expand Down Expand Up @@ -100,12 +88,14 @@ def student_view(self, context):
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,
'annotation_storage': self.annotation_storage_url,
'default_tab': self.default_tab,
'instructor_email': self.instructor_email,
'annotation_mode': self.annotation_mode,
}

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")
Expand Down
21 changes: 6 additions & 15 deletions common/lib/xmodule/xmodule/textannotation_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
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
Expand Down Expand Up @@ -47,18 +47,6 @@ 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"),
Expand All @@ -67,7 +55,7 @@ class AnnotatableFields(object):
)


class TextAnnotationModule(AnnotatableFields, XModule):
class TextAnnotationModule(AnnotatableFields, CommonAnnotatorMixin, XModule):
''' Text Annotation Module '''
js = {'coffee': [],
'js': []}
Expand Down Expand Up @@ -98,9 +86,12 @@ def student_view(self, context):
'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,
'annotation_storage': self.annotation_storage_url,
'default_tab': self.default_tab,
'instructor_email': self.instructor_email,
'annotation_mode': self.annotation_mode,
}
fragment = Fragment(self.system.render_template('textannotation.html', context))
fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js")
Expand Down
22 changes: 7 additions & 15 deletions common/lib/xmodule/xmodule/videoannotation_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
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

Expand Down Expand Up @@ -45,20 +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")
)

class VideoAnnotationModule(AnnotatableFields, XModule):

class VideoAnnotationModule(AnnotatableFields, CommonAnnotatorMixin, XModule):
'''Video Annotation Module'''
js = {
'coffee': [
Expand Down Expand Up @@ -104,8 +93,11 @@ def student_view(self, context):
'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),
'annotation_storage': self.annotation_storage_url,
'default_tab': self.default_tab,
'instructor_email': self.instructor_email,
'annotation_mode': self.annotation_mode,
}
fragment = Fragment(self.system.render_template('videoannotation.html', context))
fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js")
Expand Down
27 changes: 14 additions & 13 deletions common/static/js/vendor/ova/OpenSeaDragonAnnotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -380,19 +380,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
clickTimeThreshold: viewer.clickTimeThreshold,
clickDistThreshold: viewer.clickDistThreshold
});

/* Set elements to the control menu */
viewer.annotatorControl = viewer.wrapperAnnotation.element;
if( viewer.toolbar ){
viewer.toolbar.addControl(
viewer.annotatorControl,
{anchor: $.ControlAnchor.BOTTOM_RIGHT}
);
}else{
viewer.addControl(
viewer.annotatorControl,
{anchor: $.ControlAnchor.TOP_LEFT}
);
if(this.options.viewer.annotation_mode == "everyone" || this.options.viewer.flags){
/* Set elements to the control menu */
viewer.annotatorControl = viewer.wrapperAnnotation.element;
if( viewer.toolbar ){
viewer.toolbar.addControl(
viewer.annotatorControl,
{anchor: $.ControlAnchor.BOTTOM_RIGHT}
);
}else{
viewer.addControl(
viewer.annotatorControl,
{anchor: $.ControlAnchor.TOP_LEFT}
);
}
}
},
_reset: function(){
Expand Down
20 changes: 15 additions & 5 deletions common/static/js/vendor/ova/catch/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -379,14 +379,14 @@
display:inline-block;
color:#302f2f;
font-family:arial;
font-size:15px;
font-size:14px;
font-weight:bold;
padding:6px 24px;
text-decoration:none;

margin: 0px 0px 10px 0px;
cursor:pointer;
width:140px;
width:115px;
text-align:center;
}

Expand Down Expand Up @@ -468,7 +468,7 @@
#mainCatch .searchbox input{
margin: 0;
padding: 0;
width: 60%;
width: 50%;
margin-left: 10px;
display: inline;
float: left;
Expand All @@ -493,19 +493,28 @@
cursor:pointer;
}

#mainCatch .searchbox .clear-search-icon{
font-size: 12px;
text-decoration: underline;
float: right;
margin-top: 10px;
padding-right: 3px;
cursor:pointer;
}

#mainCatch .searchbox .search-icon:hover{
opacity:0.5;
box-shadow: 2px 4px 5px #888888;
}

#mainCatch .selectors{
width:40%;
width:45%;
position:relative;
float:left;
}

#mainCatch .searchbox{
width:60%;
width:52%;
position:relative;
float:right;
}
Expand All @@ -515,6 +524,7 @@
position:relative;
padding-right:5px;
margin-top:8px;
font-size:14px;
}

#mainCatch .replies .replyItem .deleteReply{
Expand Down
Loading