',
//Main->MediaSelector
annotationMediaSelector:
@@ -290,14 +301,14 @@ CatchAnnotation = function (element, options) {
//Reset element an create a new element div
element.html('');
-
+ this.current_tab = this.options.default_tab;
//INIT
var self = this;
$( document ).ready(function() {
self.init();
self.refreshCatch(true);
- var moreBut = self.element.find('.annotationListButtons .moreButtonCatch');
- moreBut.hide();
+ var moreBut = self.element.find('.annotationListButtons .moreButtonCatch');
+ moreBut.hide();
});
return this;
@@ -310,6 +321,7 @@ CatchAnnotation.prototype = {
this.TEMPLATENAMES = [
"annotationList", //Main
"annotationPublicPrivate", //Main->PublicPrivate
+ "annotationPublicPrivateInstructor", //Main->PublicPrivateInstructor
"annotationMediaSelector", //Main->MediaSelector
"annotationItem", //Main->ContainerRow
"annotationReply",//Main->ContainerRow->Reply
@@ -317,8 +329,8 @@ CatchAnnotation.prototype = {
"annotationDetail",//Main->ContainerRow->DetailRow
];
//annotator
- var wrapper = $('.annotator-wrapper').parent()[0],
- annotator = $.data(wrapper, 'annotator');
+ var wrapper = $('.annotator-wrapper').parent()[0];
+ var annotator = $.data(wrapper, 'annotator');
this.annotator = annotator;
//Subscribe to annotator
@@ -336,6 +348,10 @@ CatchAnnotation.prototype = {
this.HTMLTEMPLATES = CatchSources.HTMLTEMPLATES(this.options.imageUrlRoot);
this.TEMPLATES = {};
this._compileTemplates();
+ if(this.options.default_tab.toLowerCase() == 'instructor'){
+ this.options.userId = this.options.instructor_username;
+ this._refresh('','');
+ }
},
//
// GLOBAL UTILITIES
@@ -380,10 +396,18 @@ CatchAnnotation.prototype = {
if (newInstance){
var videoFormat = (mediaType === "video") ? true:false;
+ var publicprivatetemplate = '';
+ if (self.options.showPublicPrivate) {
+ if(self.options.instructor_username != ''){
+ publicprivatetemplate = self.TEMPLATES.annotationPublicPrivateInstructor();
+ } else{
+ publicprivatetemplate = self.TEMPLATES.annotationPublicPrivate();
+ }
+ }
el.html(self.TEMPLATES.annotationList({
annotationItems: annotationItems,
videoFormat: videoFormat,
- PublicPrivate: self.options.showPublicPrivate?self.TEMPLATES.annotationPublicPrivate():'',
+ PublicPrivate: publicprivatetemplate,
MediaSelector: self.options.showMediaSelector?self.TEMPLATES.annotationMediaSelector():'',
}));
}else{
@@ -402,10 +426,21 @@ CatchAnnotation.prototype = {
//Set PublicPrivate
var PublicPrivateButtons = el.find('.annotationListButtons .PublicPrivate').removeClass('active'); //reset
for (var index=0;index
From 1dcf2dc10ab1916647664469a237ed0909595447 Mon Sep 17 00:00:00 2001
From: lduarte1991
Date: Mon, 2 Jun 2014 23:27:23 -0400
Subject: [PATCH 2/8] Video Annotation Tool: Added Instructor Filter
---
.../xmodule/xmodule/videoannotation_module.py | 21 +++++++++++++++++++
lms/templates/textannotation.html | 2 --
lms/templates/videoannotation.html | 10 ++++++++-
3 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/common/lib/xmodule/xmodule/videoannotation_module.py b/common/lib/xmodule/xmodule/videoannotation_module.py
index 857ec5fcd9d4..e3fbde994423 100644
--- a/common/lib/xmodule/xmodule/videoannotation_module.py
+++ b/common/lib/xmodule/xmodule/videoannotation_module.py
@@ -57,6 +57,24 @@ class AnnotatableFields(object):
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",
+ )
+ instructor_username = String(
+ display_name=_("Username for 'Instructor' Annotations"),
+ help=_("Username 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: 1 = only instructor can annotate , 2 = Everyone can annotate"),
+ scope=Scope.settings,
+ default="2",
+ )
class VideoAnnotationModule(AnnotatableFields, XModule):
'''Video Annotation Module'''
@@ -106,6 +124,9 @@ def student_view(self, context):
'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_username': self.instructor_username,
+ '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")
diff --git a/lms/templates/textannotation.html b/lms/templates/textannotation.html
index ba27390b62f9..4a817cafd81e 100644
--- a/lms/templates/textannotation.html
+++ b/lms/templates/textannotation.html
@@ -182,8 +182,6 @@
userId = '${instructor_username}';
}
- console.log("${user.is_staff}");
-
//Catch
var annotator = ova.annotator,
catchOptions = {
diff --git a/lms/templates/videoannotation.html b/lms/templates/videoannotation.html
index 539e86909aed..2259257d68cb 100644
--- a/lms/templates/videoannotation.html
+++ b/lms/templates/videoannotation.html
@@ -175,6 +175,10 @@
var ova = new OpenVideoAnnotation.Annotator($('#videoHolder'),options);
ova.annotator.addPlugin('Tags');
+ var userId = '${user.email}';
+ if('${default_tab}'.toLowerCase() == 'instructor'){
+ userId = '${instructor_username}';
+ }
//Catch
var annotator = ova.annotator,
@@ -184,9 +188,13 @@
imageUrlRoot:imgURLRoot,
showMediaSelector: false,
showPublicPrivate: true,
- userId:'${user.email}',
+ userId:userId,
pagination:pagination,//Number of Annotations per load in the pagination,
flags:is_staff
+ flags:is_staff,
+ default_tab: "${default_tab}",
+ instructor_username: "${instructor_username}",
+ annotation_mode: "${annotation_mode}",
},
Catch = new CatchAnnotation($('#catchDIV'),catchOptions);
From 50e8ae9a6efeaf42fe3a98ad764cdd14bc1a7b3b Mon Sep 17 00:00:00 2001
From: lduarte1991
Date: Mon, 2 Jun 2014 23:31:14 -0400
Subject: [PATCH 3/8] Image Annotation Tool: Added Instructor Filter
---
.../xmodule/xmodule/imageannotation_module.py | 21 +++++++++++++++++++
lms/templates/imageannotation.html | 14 ++++++++++---
2 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/common/lib/xmodule/xmodule/imageannotation_module.py b/common/lib/xmodule/xmodule/imageannotation_module.py
index c6dc50d9cefa..754c29359ccc 100644
--- a/common/lib/xmodule/xmodule/imageannotation_module.py
+++ b/common/lib/xmodule/xmodule/imageannotation_module.py
@@ -63,6 +63,24 @@ class AnnotatableFields(object):
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",
+ )
+ instructor_username = String(
+ display_name=_("Username for 'Instructor' Annotations"),
+ help=_("Username 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: 1 = only instructor can annotate , 2 = Everyone can annotate"),
+ scope=Scope.settings,
+ default="2",
+ )
class ImageAnnotationModule(AnnotatableFields, XModule):
@@ -104,6 +122,9 @@ def student_view(self, context):
'token': retrieve_token(self.user, self.annotation_token_secret),
'tag': self.instructor_tags,
'openseadragonjson': self.openseadragonjson,
+ 'default_tab': self.default_tab,
+ 'instructor_username': self.instructor_username,
+ 'annotation_mode': self.annotation_mode,
}
fragment = Fragment(self.system.render_template('imageannotation.html', context))
diff --git a/lms/templates/imageannotation.html b/lms/templates/imageannotation.html
index e815c495063b..dce030451650 100644
--- a/lms/templates/imageannotation.html
+++ b/lms/templates/imageannotation.html
@@ -189,6 +189,11 @@
//Load the plugin Image/Text Annotation
var osda = new OpenSeadragonAnnotation($('#imageHolder'),options);
+ var userId = '${user.email}';
+ if('${default_tab}'.toLowerCase() == 'instructor'){
+ userId = '${instructor_username}';
+ }
+
//Catch
var annotator = osda.annotator,
catchOptions = {
@@ -197,9 +202,12 @@
imageUrlRoot:imgURLRoot,
showMediaSelector: false,
showPublicPrivate: true,
- userId:'${user.email}',
- pagination:pagination,//Number of Annotations per load in the pagination,
- flags:is_staff
+ userId:userId,
+ pagination:pagination,//Number of Annotations per load in the pagination,
+ flags:is_staff,
+ default_tab: "${default_tab}",
+ instructor_username: "${instructor_username}",
+ annotation_mode: "${annotation_mode}",
},
Catch = new CatchAnnotation($('#catchDIV'),catchOptions);
From b22643adc2084d5ef53c0a5b40126c581c778668 Mon Sep 17 00:00:00 2001
From: lduarte1991
Date: Tue, 3 Jun 2014 11:01:58 -0400
Subject: [PATCH 4/8] Image Annotation Tool: Annotation Mode for AB Testing
Annotation Tools PR Fixes
- forgot to overwrite the previous line
---
.../js/vendor/ova/OpenSeaDragonAnnotation.js | 27 ++++++++++---------
lms/templates/imageannotation.html | 18 ++++++++-----
lms/templates/textannotation.html | 8 +++---
lms/templates/videoannotation.html | 9 +++----
4 files changed, 33 insertions(+), 29 deletions(-)
diff --git a/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js b/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js
index d8c2f595c089..4fbadc4f47ef 100644
--- a/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js
+++ b/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js
@@ -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 == "2" || 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(){
diff --git a/lms/templates/imageannotation.html b/lms/templates/imageannotation.html
index dce030451650..e938abee42d1 100644
--- a/lms/templates/imageannotation.html
+++ b/lms/templates/imageannotation.html
@@ -34,7 +34,7 @@
## Translators: Notes below refer to annotations. They wil later be put under a "Notes" section.
-
${_('You do not have any notes.')}
+
${_('Note: only instructors may annotate.')}
@@ -72,7 +72,7 @@
var unit_id = $('#sequence-list').find('.active').attr("data-element");
uri += unit_id;
var pagination = 100,
- is_staff = !('${user.is_staff}'=='False'),
+ is_staff = ('${user.email}'=='${instructor_username}'),
options = {
optionsAnnotator: {
permissions:{
@@ -172,6 +172,8 @@
},
optionsOpenSeadragon:{
id: "imageHolder",
+ annotation_mode: "${annotation_mode}",
+ flags: is_staff,
prefixUrl: "${settings.STATIC_URL}" + "js/vendor/ova/images/",
${openseadragonjson}
},
@@ -195,8 +197,8 @@
}
//Catch
- var annotator = osda.annotator,
- catchOptions = {
+ var annotator = osda.annotator;
+ var catchOptions = {
media:'image',
externalLink:false,
imageUrlRoot:imgURLRoot,
@@ -208,8 +210,10 @@
default_tab: "${default_tab}",
instructor_username: "${instructor_username}",
annotation_mode: "${annotation_mode}",
- },
- Catch = new CatchAnnotation($('#catchDIV'),catchOptions);
-
+ };
+ if ("${annotation_mode}" == "2" || ("${annotation_mode}" == 1 && "${instructor_username}" != ""))
+ var Catch = new CatchAnnotation($('#catchDIV'),catchOptions);
+ if ("${annotation_mode}" == 1 && "${instructor_username}" == "" && !is_staff)
+ osda.annotator.destroy();
}
\ No newline at end of file
diff --git a/lms/templates/textannotation.html b/lms/templates/textannotation.html
index 4a817cafd81e..5a55410434f6 100644
--- a/lms/templates/textannotation.html
+++ b/lms/templates/textannotation.html
@@ -183,8 +183,8 @@
}
//Catch
- var annotator = ova.annotator,
- catchOptions = {
+ var annotator = ova.annotator;
+ var catchOptions = {
media:'text',
externalLink:false,
imageUrlRoot:imgURLRoot,
@@ -196,6 +196,6 @@
default_tab: "${default_tab}",
instructor_username: "${instructor_username}",
annotation_mode: "${annotation_mode}",
- },
- Catch = new CatchAnnotation($('#catchDIV'),catchOptions);
+ };
+ var Catch = new CatchAnnotation($('#catchDIV'),catchOptions);
diff --git a/lms/templates/videoannotation.html b/lms/templates/videoannotation.html
index 2259257d68cb..1ec4e18751e5 100644
--- a/lms/templates/videoannotation.html
+++ b/lms/templates/videoannotation.html
@@ -181,8 +181,8 @@
}
//Catch
- var annotator = ova.annotator,
- catchOptions = {
+ var annotator = ova.annotator;
+ var catchOptions = {
media:'video',
externalLink:false,
imageUrlRoot:imgURLRoot,
@@ -190,11 +190,10 @@
showPublicPrivate: true,
userId:userId,
pagination:pagination,//Number of Annotations per load in the pagination,
- flags:is_staff
flags:is_staff,
default_tab: "${default_tab}",
instructor_username: "${instructor_username}",
annotation_mode: "${annotation_mode}",
- },
- Catch = new CatchAnnotation($('#catchDIV'),catchOptions);
+ };
+ var Catch = new CatchAnnotation($('#catchDIV'),catchOptions);
From 68acf66f6ca78512bed981ec64da1b8d395d18f8 Mon Sep 17 00:00:00 2001
From: lduarte1991
Date: Thu, 5 Jun 2014 12:44:36 -0400
Subject: [PATCH 5/8] Annotation Tools: PR Fixes
- Fixed camel case for variable name
- Fixed indentation in imageannotation.html
- Changed all mentions of Instructor Username to Email
- Turned annotation_mode into phrase
- Fixed indentation in imageannotation.html
- Added comments in imageannotation.html
- Changing annotation_mode in OSDA
---
.../xmodule/xmodule/imageannotation_module.py | 13 +-
.../xmodule/xmodule/textannotation_module.py | 13 +-
.../xmodule/xmodule/videoannotation_module.py | 15 +-
.../js/vendor/ova/OpenSeaDragonAnnotation.js | 2 +-
common/static/js/vendor/ova/catch/js/catch.js | 88 ++++-----
lms/templates/imageannotation.html | 167 +++++++++---------
lms/templates/textannotation.html | 9 +-
lms/templates/videoannotation.html | 9 +-
8 files changed, 163 insertions(+), 153 deletions(-)
diff --git a/common/lib/xmodule/xmodule/imageannotation_module.py b/common/lib/xmodule/xmodule/imageannotation_module.py
index 754c29359ccc..40d50b8b0687 100644
--- a/common/lib/xmodule/xmodule/imageannotation_module.py
+++ b/common/lib/xmodule/xmodule/imageannotation_module.py
@@ -69,17 +69,18 @@ class AnnotatableFields(object):
scope=Scope.settings,
default="myNotes",
)
- instructor_username = String(
- display_name=_("Username for 'Instructor' Annotations"),
- help=_("Username that will be attached to all annotations that will be found in 'Instructor' tab."),
+ # 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: 1 = only instructor can annotate , 2 = Everyone can annotate"),
+ help=_("Type in number corresponding to following modes: 'instructor' or 'everyone'"),
scope=Scope.settings,
- default="2",
+ default="everyone",
)
@@ -123,7 +124,7 @@ def student_view(self, context):
'tag': self.instructor_tags,
'openseadragonjson': self.openseadragonjson,
'default_tab': self.default_tab,
- 'instructor_username': self.instructor_username,
+ 'instructor_email': self.instructor_email,
'annotation_mode': self.annotation_mode,
}
diff --git a/common/lib/xmodule/xmodule/textannotation_module.py b/common/lib/xmodule/xmodule/textannotation_module.py
index 7d47ef87fa32..2bdda68ea2e5 100644
--- a/common/lib/xmodule/xmodule/textannotation_module.py
+++ b/common/lib/xmodule/xmodule/textannotation_module.py
@@ -71,17 +71,18 @@ class AnnotatableFields(object):
scope=Scope.settings,
default="myNotes",
)
- instructor_username = String(
- display_name=_("Username for 'Instructor' Annotations"),
- help=_("Username that will be attached to all annotations that will be found in 'Instructor' tab."),
+ # 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: 1 = only instructor can annotate , 2 = Everyone can annotate"),
+ help=_("Type in number corresponding to following modes: 'instructor' or 'everyone'"),
scope=Scope.settings,
- default="2",
+ default="everyone",
)
@@ -120,7 +121,7 @@ def student_view(self, context):
'token': retrieve_token(self.user_email, self.annotation_token_secret),
'diacritic_marks': self.diacritics,
'default_tab': self.default_tab,
- 'instructor_username': self.instructor_username,
+ 'instructor_email': self.instructor_email,
'annotation_mode': self.annotation_mode,
}
fragment = Fragment(self.system.render_template('textannotation.html', context))
diff --git a/common/lib/xmodule/xmodule/videoannotation_module.py b/common/lib/xmodule/xmodule/videoannotation_module.py
index e3fbde994423..95848c0e9e2c 100644
--- a/common/lib/xmodule/xmodule/videoannotation_module.py
+++ b/common/lib/xmodule/xmodule/videoannotation_module.py
@@ -48,7 +48,7 @@ class AnnotatableFields(object):
annotation_storage_url = String(
help=_("Location of Annotation backend"),
scope=Scope.settings,
- default="http://your_annotation_storage.com",
+ default="http://your_annotation_storage.com",
display_name=_("Url for Annotation Storage"),
)
annotation_token_secret = String(
@@ -63,17 +63,18 @@ class AnnotatableFields(object):
scope=Scope.settings,
default="myNotes",
)
- instructor_username = String(
- display_name=_("Username for 'Instructor' Annotations"),
- help=_("Username that will be attached to all annotations that will be found in 'Instructor' tab."),
+ # 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: 1 = only instructor can annotate , 2 = Everyone can annotate"),
+ help=_("Type in number corresponding to following modes: 'instructor' or 'everyone'"),
scope=Scope.settings,
- default="2",
+ default="everyone",
)
class VideoAnnotationModule(AnnotatableFields, XModule):
@@ -125,7 +126,7 @@ def student_view(self, context):
'annotation_storage': self.annotation_storage_url,
'token': retrieve_token(self.user_email, self.annotation_token_secret),
'default_tab': self.default_tab,
- 'instructor_username': self.instructor_username,
+ 'instructor_email': self.instructor_email,
'annotation_mode': self.annotation_mode,
}
fragment = Fragment(self.system.render_template('videoannotation.html', context))
diff --git a/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js b/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js
index 4fbadc4f47ef..938af6e8d3f1 100644
--- a/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js
+++ b/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js
@@ -380,7 +380,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
clickTimeThreshold: viewer.clickTimeThreshold,
clickDistThreshold: viewer.clickDistThreshold
});
- if(this.options.viewer.annotation_mode == "2" || this.options.viewer.flags){
+ 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 ){
diff --git a/common/static/js/vendor/ova/catch/js/catch.js b/common/static/js/vendor/ova/catch/js/catch.js
index 950966fb0790..c2f16b98e4b9 100644
--- a/common/static/js/vendor/ova/catch/js/catch.js
+++ b/common/static/js/vendor/ova/catch/js/catch.js
@@ -42,29 +42,29 @@ annotationList:
''+
'
'+
'',
@@ -815,6 +815,10 @@ CatchAnnotation.prototype = {
var allannotations = this.annotator.plugins['Store'].annotations,
osda = this.annotator.osda;
+ if(this.options.externalLink){
+ uri += (uri.indexOf('?') >= 0)?'&osdaId='+osdaId:'?osdaId='+osdaId;
+ location.href = uri;
+ }
for(var item in allannotations){
var an = allannotations[item];
if (typeof an.id!='undefined' && an.id == osdaId){//this is the annotation
diff --git a/lms/djangoapps/notes/views.py b/lms/djangoapps/notes/views.py
index 88dc78f741ba..f121e2473a98 100644
--- a/lms/djangoapps/notes/views.py
+++ b/lms/djangoapps/notes/views.py
@@ -1,6 +1,7 @@
from django.contrib.auth.decorators import login_required
from django.http import Http404
from edxmako.shortcuts import render_to_response
+from opaque_keys.edx.locations import SlashSeparatedCourseKey
from courseware.courses import get_course_with_access
from notes.models import Note
from notes.utils import notes_enabled_for_course
@@ -10,12 +11,12 @@
@login_required
def notes(request, course_id):
''' Displays the student's notes. '''
-
- course = get_course_with_access(request.user, 'load', course_id)
+ course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
+ course = get_course_with_access(request.user, 'load', course_key)
if not notes_enabled_for_course(course):
raise Http404
- notes = Note.objects.filter(course_id=course_id, user=request.user).order_by('-created', 'uri')
+ notes = Note.objects.filter(course_id=course_key, user=request.user).order_by('-created', 'uri')
student = request.user
storage = course.annotation_storage_url
@@ -25,6 +26,7 @@ def notes(request, course_id):
'student': student,
'storage': storage,
'token': retrieve_token(student.email, course.annotation_token_secret),
+ 'default_tab': 'myNotes',
}
return render_to_response('notes.html', context)
diff --git a/lms/templates/notes.html b/lms/templates/notes.html
index 58f81be27472..569393daaa6e 100644
--- a/lms/templates/notes.html
+++ b/lms/templates/notes.html
@@ -1,6 +1,10 @@
<%! from django.utils.translation import ugettext as _ %>
<%namespace name='static' file='static_content.html'/>
+${static.css(group='style-vendor-tinymce-content', raw=True)}
+${static.css(group='style-vendor-tinymce-skin', raw=True)}
+
+
<%inherit file="main.html" />
<%!
from django.core.urlresolvers import reverse
@@ -102,7 +106,7 @@
${_('My Notes')}
if (annotation.permissions) {
tokens = annotation.permissions[action] || [];
if (is_staff){
- return true;
+ return true;
}
if (tokens.length === 0) {
return true;
@@ -128,7 +132,7 @@
${_('My Notes')}
},
},
auth: {
- tokenUrl: location.protocol+'//'+location.host+"/token?course_id=${course.id.to_deprecated_string()}"
+ token: "${token}"
},
store: {
// The endpoint of the store on your server.
@@ -158,37 +162,34 @@
${_('My Notes')}
optionsRichText: {
tinymce:{
selector: "li.annotator-item textarea",
- plugins: "media image insertdatetime link code",
+ plugins: "media image codemirror",
menubar: false,
toolbar_items_size: 'small',
extended_valid_elements : "iframe[src|frameborder|style|scrolling|class|width|height|name|align|id]",
- toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media rubric | code ",
+ toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | image rubric | code ",
}
- return true;
- },
- },
- auth: {
- token: "${token}"
- },
- store: {
- // The endpoint of the store on your server.
- prefix: "${storage}",
-
- annotationData: {},
-
- urls: {
- // These are the default URLs.
- create: '/create',
- read: '/read/:id',
- update: '/update/:id',
- destroy: '/delete/:id',
- search: '/search'
},
+ auth: {
+ token: "${token}"
+ },
+ store: {
+ // The endpoint of the store on your server.
+ prefix: "${storage}",
+
+ annotationData: {},
+
+ urls: {
+ // These are the default URLs.
+ create: '/create',
+ read: '/read/:id',
+ update: '/update/:id',
+ destroy: '/delete/:id',
+ search: '/search'
+ },
+ }
};
- tinyMCE.baseURL = "${settings.STATIC_URL}" + "js/vendor/ova";
var imgURLRoot = "${settings.STATIC_URL}" + "js/vendor/ova/catch/img/";
-
//remove old instances
if (Annotator._instances.length !== 0) {
$('#notesHolder').annotator("destroy");
@@ -207,7 +208,8 @@
${_('My Notes')}
showMediaSelector: true,
showPublicPrivate: true,
pagination:pagination,//Number of Annotations per load in the pagination,
- flags:is_staff
+ flags:is_staff,
+ default_tab: "${default_tab}",
},
Catch = new CatchAnnotation($('#catchDIV'),catchOptions);
From 54974a51ca9bc7bb3482c84705e4184435abb4f4 Mon Sep 17 00:00:00 2001
From: lduarte1991
Date: Fri, 6 Jun 2014 10:09:22 -0400
Subject: [PATCH 7/8] 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 aa597702db43..114dde292c07 100644
--- a/common/lib/xmodule/xmodule/annotator_mixin.py
+++ b/common/lib/xmodule/xmodule/annotator_mixin.py
@@ -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 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 40d50b8b0687..31c095da59c6 100644
--- a/common/lib/xmodule/xmodule/imageannotation_module.py
+++ b/common/lib/xmodule/xmodule/imageannotation_module.py
@@ -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
@@ -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 @@ 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,
- '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 2bdda68ea2e5..1f10cea193af 100644
--- a/common/lib/xmodule/xmodule/textannotation_module.py
+++ b/common/lib/xmodule/xmodule/textannotation_module.py
@@ -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
@@ -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 @@ 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,
- '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 95848c0e9e2c..cf93bf31d569 100644
--- a/common/lib/xmodule/xmodule/videoannotation_module.py
+++ b/common/lib/xmodule/xmodule/videoannotation_module.py
@@ -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
@@ -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 @@ 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),
- '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 8/8] 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 114dde292c07..93768f564c84 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 31c095da59c6..b605dfa13102 100644
--- a/common/lib/xmodule/xmodule/imageannotation_module.py
+++ b/common/lib/xmodule/xmodule/imageannotation_module.py
@@ -91,9 +91,11 @@ def student_view(self, context):
'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 1f10cea193af..cdfe43857d1b 100644
--- a/common/lib/xmodule/xmodule/textannotation_module.py
+++ b/common/lib/xmodule/xmodule/textannotation_module.py
@@ -88,9 +88,11 @@ def student_view(self, context):
'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 cf93bf31d569..17dc49acb57c 100644
--- a/common/lib/xmodule/xmodule/videoannotation_module.py
+++ b/common/lib/xmodule/xmodule/videoannotation_module.py
@@ -94,9 +94,11 @@ def student_view(self, context):
'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 130d51a35e18..a45b778d99bc 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