diff --git a/kalite/coachreports/static/js/coachreports/exercise_mastery_view.js b/kalite/coachreports/static/js/coachreports/exercise_mastery_view.js index 96b4c1d0c3..2741185f38 100644 --- a/kalite/coachreports/static/js/coachreports/exercise_mastery_view.js +++ b/kalite/coachreports/static/js/coachreports/exercise_mastery_view.js @@ -30,7 +30,7 @@ $(function() { // adjust view in data cells $(selector).each(function() { - $(this).toggle() + $(this).toggle(); }); $(selector).each(function() { $(this).height(20); diff --git a/kalite/contentload/management/commands/generate_assessment_zips.py b/kalite/contentload/management/commands/generate_assessment_zips.py index 20a97a5d28..df5b4a4d78 100644 --- a/kalite/contentload/management/commands/generate_assessment_zips.py +++ b/kalite/contentload/management/commands/generate_assessment_zips.py @@ -110,14 +110,15 @@ def localhosted_image_urls(items): # we copy so we make sure we don't modify the items passed in to this function newitems = copy.deepcopy(items) - url_to_replace = r'https?://[\w\.\-\/]+\/(?P[\w\.\-]+\.(png|gif|jpg))' - for _, v in newitems.iteritems(): - old_item_data = v['item_data'] - v['item_data'] = re.sub(url_to_replace, _old_item_url_to_content_url, old_item_data) + v['item_data'] = convert_urls(v['item_data']) return newitems +def convert_urls(string): + """ Convert urls in i18n strings into localhost urls. """ + url_to_replace = r'https?://[\w\.\-\/]+\/(?P[\w\.\-]+\.(png|gif|jpg|JPEG|JPG))' + return re.sub(url_to_replace, _old_item_url_to_content_url, string) def _old_item_url_to_content_url(matchobj): return "/content/khan/%s" % matchobj.group("filename") diff --git a/kalite/contentload/tests/generate_assessment_zips.py b/kalite/contentload/tests/generate_assessment_zips.py index f90df0f32a..d11fec1546 100644 --- a/kalite/contentload/tests/generate_assessment_zips.py +++ b/kalite/contentload/tests/generate_assessment_zips.py @@ -8,6 +8,7 @@ from mock import patch, MagicMock from django.core.management import call_command +from django.test import TestCase import kalite.version as version from kalite.testing import KALiteTestCase @@ -20,6 +21,19 @@ "assessment_items_sample.json") +class TestUrlConversion(TestCase): + + def test_url_converted(self): + url_string = "A string with http://example.com/cat_pics.gif" + expected_string = "A string with /content/khan/cat_pics.gif" + self.assertEqual(expected_string, mod.convert_urls(url_string)) + + def test_multiple_urls_in_one_string_converted(self): + url_string = "A string with http://example.com/cat_pics.JPEG http://example.com/cat_pics2.gif" + expected_string = "A string with /content/khan/cat_pics.JPEG /content/khan/cat_pics2.gif" + self.assertEqual(expected_string, mod.convert_urls(url_string)) + + class GenerateAssessmentItemsCommandTests(KALiteTestCase): def setUp(self): diff --git a/python-packages/securesync/devices/models.py b/python-packages/securesync/devices/models.py index 4db881fccc..b84efe9bfe 100755 --- a/python-packages/securesync/devices/models.py +++ b/python-packages/securesync/devices/models.py @@ -8,7 +8,7 @@ from django.conf import settings from django.contrib.auth.models import check_password from django.core.exceptions import ValidationError, ObjectDoesNotExist -from django.db import models, transaction +from django.db import models, transaction, IntegrityError from django.db.models import Q from django.db.models.expressions import F from django.utils.text import compress_string @@ -207,13 +207,12 @@ def set_key(self, key): self.key = key def get_key(self): - self.key = None if not self.key: try: if self.get_metadata().is_own_device: self.key = crypto.get_own_key() - except: - # If device has not yet been saved, but ID is set, then getting metadata may fail (on MySQL) + except Device.DoesNotExist: + # get_metadata can fail if the Device instance hasn't been persisted to the db pass if not self.key and self.public_key: self.key = crypto.Key(public_key_string=self.public_key) @@ -224,7 +223,12 @@ def _hashable_representation(self): return super(Device, self)._hashable_representation(fields=fields) def get_metadata(self): - return DeviceMetadata.objects.get_or_create(device=self)[0] + try: + return DeviceMetadata.objects.get_or_create(device=self)[0] + except IntegrityError as e: + # Possible from get_or_create if the DeviceMetadata object doesn't exist + # and the Device hasn't been persisted to the database yet. + raise Device.DoesNotExist() def get_counter_position(self): """