Image Annotation Tool Fixes
- Added component to view - Added correct images for OSD - Fixed path to codemirror - Tinymce fullscreen works now - Pep8/Pylint Fixes - Default image changed and added call to super
@@ -54,6 +54,7 @@ else:
|
||||
'annotatable',
|
||||
'textannotation', # module for annotating text (with annotation table)
|
||||
'videoannotation', # module for annotating video (with annotation table)
|
||||
'imageannotation', # module for annotating image (with annotation table)
|
||||
'word_cloud',
|
||||
'graphical_slider_tool',
|
||||
'lti',
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
Annotations Tool Mixin
|
||||
This file contains global variables and functions used in the various Annotation Tools.
|
||||
"""
|
||||
from pkg_resources import resource_string
|
||||
from lxml import etree
|
||||
from urlparse import urlparse
|
||||
from os.path import splitext, basename
|
||||
from HTMLParser import HTMLParser
|
||||
|
||||
|
||||
def get_instructions(xmltree):
|
||||
""" Removes <instructions> from the xmltree and returns them as a string, otherwise None. """
|
||||
instructions = xmltree.find('instructions')
|
||||
@@ -17,8 +17,9 @@ def get_instructions(xmltree):
|
||||
return etree.tostring(instructions, encoding='unicode')
|
||||
return None
|
||||
|
||||
|
||||
def get_extension(srcurl):
|
||||
''' get the extension of a given url '''
|
||||
"""get the extension of a given url """
|
||||
if 'youtu' in srcurl:
|
||||
return 'video/youtube'
|
||||
else:
|
||||
@@ -26,20 +27,29 @@ def get_extension(srcurl):
|
||||
file_ext = splitext(basename(disassembled.path))[1]
|
||||
return 'video/' + file_ext.replace('.', '')
|
||||
|
||||
|
||||
class MLStripper(HTMLParser):
|
||||
"helper function for html_to_text below"
|
||||
def __init__(self):
|
||||
HTMLParser.__init__(self)
|
||||
self.reset()
|
||||
self.fed = []
|
||||
def handle_data(self, d):
|
||||
self.fed.append(d)
|
||||
|
||||
def handle_data(self, data):
|
||||
"""takes the data in separate chunks"""
|
||||
self.fed.append(data)
|
||||
|
||||
def handle_entityref(self, name):
|
||||
"""appends the reference to the body"""
|
||||
self.fed.append('&%s;' % name)
|
||||
|
||||
def get_data(self):
|
||||
"""joins together the seperate chunks into one cohesive string"""
|
||||
return ''.join(self.fed)
|
||||
|
||||
|
||||
def html_to_text(html):
|
||||
"strips the html tags off of the text to return plaintext"
|
||||
s = MLStripper()
|
||||
s.feed(html)
|
||||
return s.get_data()
|
||||
htmlStripper = MLStripper()
|
||||
htmlStripper.feed(html)
|
||||
return htmlStripper.get_data()
|
||||
|
||||
@@ -25,7 +25,7 @@ def retrieve_token(userid, secret):
|
||||
delta = dtnow - dtutcnow
|
||||
newhour, newmin = divmod((delta.days * 24 * 60 * 60 + delta.seconds + 30) // 60, 60) # pylint: disable=E1103
|
||||
newtime = "%s%+02d:%02d" % (dtnow.isoformat(), newhour, newmin) # pylint: disable=E1103
|
||||
# uses the issued time (UTC plus timezone), the consumer key and the user's email to maintain a
|
||||
# uses the issued time (UTC plus timezone), the consumer key and the user's email to maintain a
|
||||
# federated system in the annotation backend server
|
||||
custom_data = {"issuedAt": newtime, "consumerKey": secret, "userId": userid, "ttl": 86400}
|
||||
newtoken = create_token(secret, custom_data)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# pylint: disable=W0223
|
||||
"""
|
||||
Module for Image annotations using annotator.
|
||||
"""
|
||||
@@ -31,20 +32,7 @@ class AnnotatableFields(object):
|
||||
showNavigator: true,
|
||||
navigatorPosition: "BOTTOM_LEFT",
|
||||
showNavigationControl: true,
|
||||
tileSources: [{
|
||||
Image: {
|
||||
xmlns: "http://schemas.microsoft.com/deepzoom/2009",
|
||||
Url: "http://static.seadragon.com/content/misc/milwaukee_files/",
|
||||
TileSize: "254",
|
||||
Overlap: "1",
|
||||
Format: "jpg",
|
||||
ServerFormat: "Default",
|
||||
Size: {
|
||||
Width: "15497",
|
||||
Height: "5378"
|
||||
}
|
||||
}
|
||||
},],
|
||||
tileSources: [{"profile": "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2", "scale_factors": [1, 2, 4, 8, 16, 32, 64], "tile_height": 1024, "height": 3466, "width": 113793, "tile_width": 1024, "qualities": ["native", "bitonal", "grey", "color"], "formats": ["jpg", "png", "gif"], "@context": "http://library.stanford.edu/iiif/image-api/1.1/context.json", "@id": "http://54.187.32.48/loris/suzhou_orig.jp2"}],
|
||||
</json>
|
||||
</annotatable>
|
||||
"""))
|
||||
@@ -100,7 +88,7 @@ class ImageAnnotationModule(AnnotatableFields, XModule):
|
||||
'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),
|
||||
'token': retrieve_token(self.user, self.annotation_token_secret),
|
||||
'tag': self.instructor_tags,
|
||||
'openseadragonjson': self.openseadragonjson,
|
||||
}
|
||||
@@ -120,4 +108,4 @@ class ImageAnnotationDescriptor(AnnotatableFields, RawDescriptor):
|
||||
ImageAnnotationDescriptor.annotation_storage_url,
|
||||
ImageAnnotationDescriptor.annotation_token_secret,
|
||||
])
|
||||
return non_editable_fields
|
||||
return non_editable_fields
|
||||
|
||||
@@ -7,6 +7,7 @@ from lxml import etree
|
||||
|
||||
from xmodule.annotator_mixin import get_instructions, get_extension, html_to_text
|
||||
|
||||
|
||||
class HelperFunctionTest(unittest.TestCase):
|
||||
"""
|
||||
Tests to ensure that the following helper functions work for the annotation tool
|
||||
@@ -47,6 +48,6 @@ class HelperFunctionTest(unittest.TestCase):
|
||||
self.assertEqual(expectednotyoutube, result1)
|
||||
|
||||
def test_html_to_text(self):
|
||||
expectedText = "Testing here and not bolded here"
|
||||
expectedtext = "Testing here and not bolded here"
|
||||
result = html_to_text(self.sample_html)
|
||||
self.assertEqual(expectedText, result)
|
||||
self.assertEqual(expectedtext, result)
|
||||
|
||||
@@ -28,11 +28,11 @@ class ImageAnnotationModuleTestCase(unittest.TestCase):
|
||||
Image: {
|
||||
xmlns: "http://schemas.microsoft.com/deepzoom/2009",
|
||||
Url: "http://static.seadragon.com/content/misc/milwaukee_files/",
|
||||
TileSize: "254",
|
||||
Overlap: "1",
|
||||
Format: "jpg",
|
||||
TileSize: "254",
|
||||
Overlap: "1",
|
||||
Format: "jpg",
|
||||
ServerFormat: "Default",
|
||||
Size: {
|
||||
Size: {
|
||||
Width: "15497",
|
||||
Height: "5378"
|
||||
}
|
||||
@@ -41,7 +41,7 @@ class ImageAnnotationModuleTestCase(unittest.TestCase):
|
||||
</json>
|
||||
</annotatable>
|
||||
'''
|
||||
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Makes sure that the Module is declared and mocked with the sample xml above.
|
||||
@@ -75,4 +75,4 @@ class ImageAnnotationModuleTestCase(unittest.TestCase):
|
||||
"""
|
||||
context = self.mod.get_html()
|
||||
for key in ['display_name', 'instructions_html', 'annotation_storage', 'token', 'tag', 'openseadragonjson']:
|
||||
self.assertIn(key, context)
|
||||
self.assertIn(key, context)
|
||||
|
||||
@@ -782,6 +782,28 @@ OpenSeadragonAnnotation = function (element, options) {
|
||||
|
||||
//Set annotator.editor.OpenSeaDragon by default
|
||||
this.annotator.editor.OpenSeaDragon=-1;
|
||||
|
||||
function reloadEditor(){
|
||||
tinymce.EditorManager.execCommand('mceRemoveEditor',true, "annotator-field-0");
|
||||
tinymce.EditorManager.execCommand('mceAddEditor',true, "annotator-field-0");
|
||||
}
|
||||
|
||||
var self = this;
|
||||
document.addEventListener("fullscreenchange", function () {
|
||||
reloadEditor();
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozfullscreenchange", function () {
|
||||
reloadEditor();
|
||||
}, false);
|
||||
|
||||
document.addEventListener("webkitfullscreenchange", function () {
|
||||
reloadEditor();
|
||||
}, false);
|
||||
|
||||
document.addEventListener("msfullscreenchange", function () {
|
||||
reloadEditor();
|
||||
}, false);
|
||||
|
||||
this.options = options;
|
||||
|
||||
|
||||
BIN
common/static/js/vendor/ova/images/fullpage_grouphover.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 698 B |
BIN
common/static/js/vendor/ova/images/fullpage_hover.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 831 B |
BIN
common/static/js/vendor/ova/images/fullpage_pressed.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 817 B |
BIN
common/static/js/vendor/ova/images/fullpage_rest.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 698 B |
BIN
common/static/js/vendor/ova/images/home_grouphover.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 672 B |
BIN
common/static/js/vendor/ova/images/home_hover.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 737 B |
BIN
common/static/js/vendor/ova/images/home_pressed.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 741 B |
BIN
common/static/js/vendor/ova/images/home_rest.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 672 B |
BIN
common/static/js/vendor/ova/images/newan_grouphover.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 746 B |
BIN
common/static/js/vendor/ova/images/newan_hover.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 815 B |
BIN
common/static/js/vendor/ova/images/newan_pressed.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 828 B |
BIN
common/static/js/vendor/ova/images/newan_rest.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 746 B |
BIN
common/static/js/vendor/ova/images/next_grouphover.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 656 B |
BIN
common/static/js/vendor/ova/images/next_hover.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 753 B |
BIN
common/static/js/vendor/ova/images/next_pressed.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 752 B |
BIN
common/static/js/vendor/ova/images/next_rest.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 656 B |
BIN
common/static/js/vendor/ova/images/previous_grouphover.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 661 B |
BIN
common/static/js/vendor/ova/images/previous_hover.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 755 B |
BIN
common/static/js/vendor/ova/images/previous_pressed.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 755 B |
BIN
common/static/js/vendor/ova/images/previous_rest.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 661 B |
BIN
common/static/js/vendor/ova/images/zoomin_grouphover.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 612 B |
BIN
common/static/js/vendor/ova/images/zoomin_hover.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 608 B |
BIN
common/static/js/vendor/ova/images/zoomin_pressed.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 615 B |
BIN
common/static/js/vendor/ova/images/zoomin_rest.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 612 B |
BIN
common/static/js/vendor/ova/images/zoomout_grouphover.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 504 B |
BIN
common/static/js/vendor/ova/images/zoomout_hover.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 559 B |
BIN
common/static/js/vendor/ova/images/zoomout_pressed.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 561 B |
BIN
common/static/js/vendor/ova/images/zoomout_rest.png
vendored
Executable file → Normal file
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 504 B |
@@ -38,7 +38,7 @@ Annotator.Plugin.RichText = (function(_super) {
|
||||
}
|
||||
},
|
||||
codemirror: {
|
||||
path: "static/js/vendor"
|
||||
path: "/static/js/vendor"
|
||||
},
|
||||
plugins: "image link codemirror",
|
||||
menubar: false,
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
<%! 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)}
|
||||
<script type="text/javascript" src="${static.url('js/vendor/tinymce/js/tinymce/tinymce.full.min.js', raw=True)}" />
|
||||
<script type="text/javascript" src="${static.url('js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js', raw=True)}" />
|
||||
|
||||
<style type="text/css">
|
||||
.openseadragon1{
|
||||
@@ -33,6 +28,11 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)}
|
||||
<div class="annotatable-section">
|
||||
<div class="annotatable-content">
|
||||
<div id="imageHolder" class="openseadragon1">
|
||||
<%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)}
|
||||
<script type="text/javascript" src="${static.url('js/vendor/tinymce/js/tinymce/tinymce.full.min.js', raw=True)}" />
|
||||
<script type="text/javascript" src="${static.url('js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js', raw=True)}" />
|
||||
</div>
|
||||
<div id="catchDIV">
|
||||
<div class="annotationListContainer">${_('You do not have any notes.')}</div>
|
||||
|
||||