Commit c2425200 by lduarte1991

Annotation Tools: Add helper functions and fixed pep8/pylint errors

Small plugin fixes
parent ecb05e6b
"""
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')
if instructions is not None:
instructions.tag = 'div'
xmltree.remove(instructions)
return etree.tostring(instructions, encoding='unicode')
return None
def get_extension(srcurl):
''' get the extension of a given url '''
if 'youtu' in srcurl:
return 'video/youtube'
else:
disassembled = urlparse(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):
self.reset()
self.fed = []
def handle_data(self, d):
self.fed.append(d)
def handle_entityref(self, name):
self.fed.append('&%s;' % name)
def get_data(self):
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()
\ No newline at end of file
...@@ -23,8 +23,8 @@ def retrieve_token(userid, secret): ...@@ -23,8 +23,8 @@ def retrieve_token(userid, secret):
dtnow = datetime.datetime.now() dtnow = datetime.datetime.now()
dtutcnow = datetime.datetime.utcnow() dtutcnow = datetime.datetime.utcnow()
delta = dtnow - dtutcnow delta = dtnow - dtutcnow
newhour, newmin = divmod((delta.days * 24 * 60 * 60 + delta.seconds + 30) // 60, 60) newhour, newmin = divmod((delta.days * 24 * 60 * 60 + delta.seconds + 30) // 60, 60) # pylint: disable=E1103
newtime = "%s%+02d:%02d" % (dtnow.isoformat(), newhour, newmin) 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 # federated system in the annotation backend server
custom_data = {"issuedAt": newtime, "consumerKey": secret, "userId": userid, "ttl": 86400} custom_data = {"issuedAt": newtime, "consumerKey": secret, "userId": userid, "ttl": 86400}
......
"""
This test will run for annotator_mixin.py
"""
import unittest
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
"""
sample_xml = '''
<annotatable>
<instructions><p>Helper Test Instructions.</p></instructions>
</annotatable>
'''
sample_sourceurl = "http://video-js.zencoder.com/oceans-clip.mp4"
sample_youtubeurl = "http://www.youtube.com/watch?v=yxLIu-scR9Y"
sample_html = '<p><b>Testing here</b> and not bolded here</p>'
def test_get_instructions(self):
"""
Function takes in an input of a specific xml string with surrounding instructions tags and returns a valid html string.
"""
xmltree = etree.fromstring(self.sample_xml)
expected_xml = u"<div><p>Helper Test Instructions.</p></div>"
actual_xml = get_instructions(xmltree) # pylint: disable=W0212
self.assertIsNotNone(actual_xml)
self.assertEqual(expected_xml.strip(), actual_xml.strip())
xmltree = etree.fromstring('<annotatable>foo</annotatable>')
actual = get_instructions(xmltree) # pylint: disable=W0212
self.assertIsNone(actual)
def test_get_extension(self):
"""
Tests whether given a url if the video will return a youtube source or extension
"""
expectedyoutube = 'video/youtube'
expectednotyoutube = 'video/mp4'
result1 = get_extension(self.sample_sourceurl) # pylint: disable=W0212
result2 = get_extension(self.sample_youtubeurl) # pylint: disable=W0212
self.assertEqual(expectedyoutube, result2)
self.assertEqual(expectednotyoutube, result1)
def test_html_to_text(self):
expectedText = "Testing here and not bolded here"
result = html_to_text(self.sample_html)
self.assertEqual(expectedText, result)
\ No newline at end of file
...@@ -12,9 +12,9 @@ class TokenRetriever(unittest.TestCase): ...@@ -12,9 +12,9 @@ class TokenRetriever(unittest.TestCase):
""" """
def test_token(self): def test_token(self):
""" """
Test for the token generator. Give an a random username and secret token, it should create the properly encoded string of text. Test for the token generator. Give an a random username and secret token, it should create the properly encoded string of text.
""" """
expected = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpc3N1ZWRBdCI6ICIyMDE0LTAyLTI3VDE3OjAwOjQyLjQwNjQ0MSswOjAwIiwgImNvbnN1bWVyS2V5IjogImZha2Vfc2VjcmV0IiwgInVzZXJJZCI6ICJ1c2VybmFtZSIsICJ0dGwiOiA4NjQwMH0.Dx1PoF-7mqBOOSGDMZ9R_s3oaaLRPnn6CJgGGF2A5CQ" expected = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpc3N1ZWRBdCI6ICIyMDE0LTAyLTI3VDE3OjAwOjQyLjQwNjQ0MSswOjAwIiwgImNvbnN1bWVyS2V5IjogImZha2Vfc2VjcmV0IiwgInVzZXJJZCI6ICJ1c2VybmFtZSIsICJ0dGwiOiA4NjQwMH0.Dx1PoF-7mqBOOSGDMZ9R_s3oaaLRPnn6CJgGGF2A5CQ"
response = retrieve_token("username", "fake_secret") response = retrieve_token("username", "fake_secret")
self.assertEqual(expected.split('.')[0], response.split('.')[0]) self.assertEqual(expected.split('.')[0], response.split('.')[0])
self.assertNotEqual(expected.split('.')[2], response.split('.')[2]) self.assertNotEqual(expected.split('.')[2], response.split('.')[2])
\ No newline at end of file
...@@ -66,6 +66,6 @@ class VideoAnnotationModuleTestCase(unittest.TestCase): ...@@ -66,6 +66,6 @@ class VideoAnnotationModuleTestCase(unittest.TestCase):
""" """
Tests to make sure variables passed in truly exist within the html once it is all rendered. Tests to make sure variables passed in truly exist within the html once it is all rendered.
""" """
context = self.mod.get_html() # pylint: disable=W0212 context = self.mod.get_html() # pylint: disable=W0212
for key in ['display_name', 'instructions_html', 'sourceUrl', 'typeSource', 'poster', 'annotation_storage']: for key in ['display_name', 'instructions_html', 'sourceUrl', 'typeSource', 'poster', 'annotation_storage']:
self.assertIn(key, context) self.assertIn(key, context)
...@@ -6,6 +6,7 @@ from pkg_resources import resource_string ...@@ -6,6 +6,7 @@ from pkg_resources import resource_string
from xmodule.x_module import XModule from xmodule.x_module import XModule
from xmodule.raw_module import RawDescriptor from xmodule.raw_module import RawDescriptor
from xblock.core import Scope, String from xblock.core import Scope, String
from xmodule.annotator_mixin import get_instructions
from xmodule.annotator_token import retrieve_token from xmodule.annotator_token import retrieve_token
import textwrap import textwrap
...@@ -70,12 +71,7 @@ class TextAnnotationModule(AnnotatableFields, XModule): ...@@ -70,12 +71,7 @@ class TextAnnotationModule(AnnotatableFields, XModule):
def _extract_instructions(self, xmltree): def _extract_instructions(self, xmltree):
""" Removes <instructions> from the xmltree and returns them as a string, otherwise None. """ """ Removes <instructions> from the xmltree and returns them as a string, otherwise None. """
instructions = xmltree.find('instructions') return get_instructions(xmltree)
if instructions is not None:
instructions.tag = 'div'
xmltree.remove(instructions)
return etree.tostring(instructions, encoding='unicode')
return None
def get_html(self): def get_html(self):
""" Renders parameters to template. """ """ Renders parameters to template. """
......
...@@ -7,6 +7,7 @@ from pkg_resources import resource_string ...@@ -7,6 +7,7 @@ from pkg_resources import resource_string
from xmodule.x_module import XModule from xmodule.x_module import XModule
from xmodule.raw_module import RawDescriptor from xmodule.raw_module import RawDescriptor
from xblock.core import Scope, String from xblock.core import Scope, String
from xmodule.annotator_mixin import get_instructions, get_extension
from xmodule.annotator_token import retrieve_token from xmodule.annotator_token import retrieve_token
import textwrap import textwrap
...@@ -65,24 +66,11 @@ class VideoAnnotationModule(AnnotatableFields, XModule): ...@@ -65,24 +66,11 @@ class VideoAnnotationModule(AnnotatableFields, XModule):
def _extract_instructions(self, xmltree): def _extract_instructions(self, xmltree):
""" Removes <instructions> from the xmltree and returns them as a string, otherwise None. """ """ Removes <instructions> from the xmltree and returns them as a string, otherwise None. """
instructions = xmltree.find('instructions') return get_instructions(xmltree)
if instructions is not None:
instructions.tag = 'div'
xmltree.remove(instructions)
return etree.tostring(instructions, encoding='unicode')
return None
def _get_extension(self, srcurl): def _get_extension(self, srcurl):
''' get the extension of a given url ''' ''' get the extension of a given url '''
if 'youtu' in srcurl: return get_extension(srcurl)
return 'video/youtube'
else:
spliturl = srcurl.split(".")
extensionplus1 = spliturl[len(spliturl) - 1]
spliturl = extensionplus1.split("?")
extensionplus2 = spliturl[0]
spliturl = extensionplus2.split("#")
return 'video/' + spliturl[0]
def get_html(self): def get_html(self):
""" Renders parameters to template. """ """ Renders parameters to template. """
......
...@@ -17,9 +17,21 @@ ...@@ -17,9 +17,21 @@
} }
.annotator-wrapper .mce-container { .annotator-wrapper .mce-container {
z-index:3000000000!important; /*To fix full-screen problems*/ z-index: 3000000000!important; /*To fix full-screen problems*/
} }
.mce-container-body {
min-width: 400px;
}
.iframe[id="annotator-field"] {
width: inherit;
min-width: 400px;
}
div.mce-tinymce.mce-container.mce-panel {
min-width:400px;
}
/* Some change in the design of Annotator */ /* Some change in the design of Annotator */
.annotator-editor .annotator-widget{ .annotator-editor .annotator-widget{
...@@ -30,4 +42,4 @@ ...@@ -30,4 +42,4 @@
.mce-ico.mce-i-rubric{ .mce-ico.mce-i-rubric{
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QkBBB07nraNoQAAAhZJREFUKM+NkstrE1EUxr+5c08ykztpJtVoazHBF8FgQQzonyBKEZS6FrQKLl0EXBRT0ZULJSs3oii4TyHgu90IlTaL6qouWlv7Ck1N0BSnmZk714WbPHz07M4534+Pw3eAHdTY8A9+Nd9/bshU1DpnO4HXjh2ZY2J9/OSTxHTrnP8PvJYf+BDQ6qEDaQBB43jrTusUFy4oPjsYWYzF+VS91nxLYfdhKgONaQT3W/KMxr1XY5e+qj86f8zsKYYsZ6AvjWFzA8ORHkAnwN8So7evzL/8pzMAXL/Hq8mMv1up371T7Z+/c3n9cKeuDS6Xy6dN07zLuZ56Onk2Ed2/ANJsnE/PQMpgyffle+kYzwazB1+3waVS6X48Hr9BRPB9H57nYXplFKeSt8D1Hriug9XKF0x+Lmw+ys8m2m42DOOn4zhQSsGyLOi6jqONm9isbmFVFlDbaGKx8QaB1rvdlbNhGLAsC0IIGIYBIQSy2ROQ0oOp7wOPraHXEugRvDtnzjmi0SiICEIIEBGklAB9B6cmbG0AUnrY5m73h+m6DsYYTNMEYwxEBMY0hGNVhHkcZigBO9qHlDHS7cwYg23bAIBQKAQigud7IH0XwtxDoHwEIQ9SLKx0wa7rPiaivYyxESklXNeFBg0mjyNQTQSuATMSm6ipuYt//eVcLhdeXl5+UKlUlur1upqamVAv3j3/VCyOD3VqfwF6uLp3q+vMcgAAAABJRU5ErkJggg=='); background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QkBBB07nraNoQAAAhZJREFUKM+NkstrE1EUxr+5c08ykztpJtVoazHBF8FgQQzonyBKEZS6FrQKLl0EXBRT0ZULJSs3oii4TyHgu90IlTaL6qouWlv7Ck1N0BSnmZk714WbPHz07M4534+Pw3eAHdTY8A9+Nd9/bshU1DpnO4HXjh2ZY2J9/OSTxHTrnP8PvJYf+BDQ6qEDaQBB43jrTusUFy4oPjsYWYzF+VS91nxLYfdhKgONaQT3W/KMxr1XY5e+qj86f8zsKYYsZ6AvjWFzA8ORHkAnwN8So7evzL/8pzMAXL/Hq8mMv1up371T7Z+/c3n9cKeuDS6Xy6dN07zLuZ56Onk2Ed2/ANJsnE/PQMpgyffle+kYzwazB1+3waVS6X48Hr9BRPB9H57nYXplFKeSt8D1Hriug9XKF0x+Lmw+ys8m2m42DOOn4zhQSsGyLOi6jqONm9isbmFVFlDbaGKx8QaB1rvdlbNhGLAsC0IIGIYBIQSy2ROQ0oOp7wOPraHXEugRvDtnzjmi0SiICEIIEBGklAB9B6cmbG0AUnrY5m73h+m6DsYYTNMEYwxEBMY0hGNVhHkcZigBO9qHlDHS7cwYg23bAIBQKAQigud7IH0XwtxDoHwEIQ9SLKx0wa7rPiaivYyxESklXNeFBg0mjyNQTQSuATMSm6ipuYt//eVcLhdeXl5+UKlUlur1upqamVAv3j3/VCyOD3VqfwF6uLp3q+vMcgAAAABJRU5ErkJggg==');
background-repeat: no-repeat; background-repeat: no-repeat;
} }
\ No newline at end of file
...@@ -101,4 +101,4 @@ Annotator.Plugin.Flagging = (function(_super) { ...@@ -101,4 +101,4 @@ Annotator.Plugin.Flagging = (function(_super) {
return Flagging; return Flagging;
})(Annotator.Plugin); })(Annotator.Plugin);
\ No newline at end of file
...@@ -82,6 +82,7 @@ Annotator.Plugin.Reply = (function(_super) { ...@@ -82,6 +82,7 @@ Annotator.Plugin.Reply = (function(_super) {
var string; var string;
return self; return self;
}); });
field.remove();
this.annotation = annotation; this.annotation = annotation;
//Create the actions for the buttons //Create the actions for the buttons
return ret; return ret;
......
/*
HighlightTags Annotator Plugin v1.0 (https://github.com/lduarte1991/tags-annotator)
Copyright (C) 2014 Luis F Duarte
License: https://github.com/lduarte1991/tags-annotator/blob/master/LICENSE.rst
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*===============================================================================
===============================================================================
===============================================================================
===============================================================================
==============================================================================*/
/* /*
* jQuery Plugin: Tokenizing Autocomplete Text Entry * jQuery Plugin: Tokenizing Autocomplete Text Entry
* Version 1.6.0 * Version 1.6.0
...@@ -22,7 +46,7 @@ var DEFAULT_SETTINGS = { ...@@ -22,7 +46,7 @@ var DEFAULT_SETTINGS = {
// Display settings // Display settings
hintText: "Type in a search term", hintText: "Type in a search term",
noResultsText: "No results", noResultsText: "Not Found. Hit ENTER to add a personal tag.",
searchingText: "Searching...", searchingText: "Searching...",
deleteText: "&times;", deleteText: "&times;",
animateDropdown: true, animateDropdown: true,
...@@ -39,7 +63,7 @@ var DEFAULT_SETTINGS = { ...@@ -39,7 +63,7 @@ var DEFAULT_SETTINGS = {
prePopulate: null, prePopulate: null,
processPrePopulate: false, processPrePopulate: false,
// Manipulation settings // Manipulation settings
idPrefix: "token-input-", idPrefix: "token-input-",
// Formatters // Formatters
...@@ -271,7 +295,10 @@ $.TokenList = function (input, url_or_data, settings) { ...@@ -271,7 +295,10 @@ $.TokenList = function (input, url_or_data, settings) {
add_token($(selected_dropdown_item).data("tokeninput")); add_token($(selected_dropdown_item).data("tokeninput"));
hidden_input.change(); hidden_input.change();
return false; return false;
} } else{
add_token({id:$(this).val(), name:$(this).val()});
hidden_input.change();
}
break; break;
case KEY.ESCAPE: case KEY.ESCAPE:
...@@ -886,7 +913,7 @@ Annotator.Plugin.HighlightTags = (function(_super) { ...@@ -886,7 +913,7 @@ Annotator.Plugin.HighlightTags = (function(_super) {
HighlightTags.prototype.field = null; HighlightTags.prototype.field = null;
HighlightTags.prototype.input = null; HighlightTags.prototype.input = null;
HighlightTags.prototype.colors = null; HighlightTags.prototype.colors = null;
HighlightTags.prototype.isFirstTime = true; HighlightTags.prototype.isFirstTime = true;
//this function will initialize the plug in. Create your fields here in the editor and viewer. //this function will initialize the plug in. Create your fields here in the editor and viewer.
HighlightTags.prototype.pluginInit = function() { HighlightTags.prototype.pluginInit = function() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment