Commit 1d10af69 by Clinton Blackburn Committed by Clinton Blackburn

Updated image download code to continue if a download fails for a course

Failure to download an image for one course should not stop execution of downloads for other courses. Exception handling is now in place to ensure we do not prematurely exit the program.

LEARNER-2463
parent 58665dd5
......@@ -42,21 +42,25 @@ class Command(BaseCommand):
for course in courses:
logger.info('Retrieving image for course [%s] from [%s]...', course.key, course.card_image_url)
response = requests.get(course.card_image_url)
if response.status_code == requests.codes.ok: # pylint: disable=no-member
content_type = response.headers['Content-Type'].lower()
extension = IMAGE_TYPES.get(content_type)
try:
response = requests.get(course.card_image_url)
if extension:
filename = '{uuid}.{extension}'.format(uuid=str(course.uuid), extension=extension)
course.image.save(filename, ContentFile(response.content))
logger.info('Image for course [%s] successfully updated.', course.key)
else:
# pylint: disable=line-too-long
msg = 'Image retrieved for course [%s] from [%s] has an unknown content type [%s] and will not be saved.'
logger.error(msg, course.key, course.card_image_url, content_type)
if response.status_code == requests.codes.ok: # pylint: disable=no-member
content_type = response.headers['Content-Type'].lower()
extension = IMAGE_TYPES.get(content_type)
if extension:
filename = '{uuid}.{extension}'.format(uuid=str(course.uuid), extension=extension)
course.image.save(filename, ContentFile(response.content))
logger.info('Image for course [%s] successfully updated.', course.key)
else:
# pylint: disable=line-too-long
msg = 'Image retrieved for course [%s] from [%s] has an unknown content type [%s] and will not be saved.'
logger.error(msg, course.key, course.card_image_url, content_type)
else:
msg = 'Failed to download image for course [%s] from [%s]! Response was [%d]:\n%s'
logger.error(msg, course.key, course.card_image_url, response.status_code, response.content)
else:
msg = 'Failed to download image for course [%s] from [%s]! Response was [%d]:\n%s'
logger.error(msg, course.key, course.card_image_url, response.status_code, response.content)
except Exception: # pylint: disable=broad-except
logger.exception('An unknown exception occurred while downloading image for course [%s]', course.key)
......@@ -25,6 +25,10 @@ class TestDownloadCourseImages:
)
return image_url, body
def assert_course_has_no_image(self, course):
course.refresh_from_db()
assert not bool(course.image)
@responses.activate
def test_download(self):
image_url, image_content = self.mock_image_response()
......@@ -66,9 +70,7 @@ class TestDownloadCourseImages:
)
assert len(responses.calls) == 1
course.refresh_from_db()
assert not bool(course.image)
self.assert_course_has_no_image(course)
@responses.activate
def test_download_with_invalid_status_code(self):
......@@ -88,11 +90,27 @@ class TestDownloadCourseImages:
)
assert len(responses.calls) == 1
course.refresh_from_db()
assert not bool(course.image)
self.assert_course_has_no_image(course)
def test_download_without_courses(self):
with mock.patch(self.LOGGER_PATH) as mock_logger:
call_command('download_course_images')
mock_logger.info.assert_called_with('All courses are up to date.')
@responses.activate
def test_download_with_unexpected_error(self):
image_url, __ = self.mock_image_response()
course = CourseFactory(card_image_url=image_url, image=None)
with mock.patch('stdimage.models.StdImageFieldFile.save', side_effect=Exception) as mock_save:
with mock.patch(self.LOGGER_PATH) as mock_logger:
call_command('download_course_images')
mock_logger.exception.assert_called_once_with(
'An unknown exception occurred while downloading image for course [%s]',
course.key
)
mock_save.assert_called_once()
assert len(responses.calls) == 1
self.assert_course_has_no_image(course)
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