From b3c062be1b68b46fb4b1826a45afc6459f0026e9 Mon Sep 17 00:00:00 2001 From: Ayub khan Date: Tue, 8 Oct 2019 17:40:15 +0500 Subject: [PATCH] BOM-848 Different Hash Values hashlib produces different md5 hash in python3 against same values as compared to python2. --- cms/djangoapps/contentstore/views/item.py | 16 ++++++---------- lms/djangoapps/courseware/module_render.py | 11 +---------- .../courseware/tests/test_module_render.py | 2 +- openedx/core/lib/xblock_utils/__init__.py | 18 ++++++++++++++++++ 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/cms/djangoapps/contentstore/views/item.py b/cms/djangoapps/contentstore/views/item.py index a21bf41f5c..66e7c0e3ae 100644 --- a/cms/djangoapps/contentstore/views/item.py +++ b/cms/djangoapps/contentstore/views/item.py @@ -51,7 +51,12 @@ from models.settings.course_grading import CourseGradingModel from openedx.core.djangoapps.schedules.config import COURSE_UPDATE_WAFFLE_FLAG from openedx.core.djangoapps.waffle_utils import WaffleSwitch from openedx.core.lib.gating import api as gating_api -from openedx.core.lib.xblock_utils import request_token, wrap_xblock, wrap_xblock_aside +from openedx.core.lib.xblock_utils import ( + hash_resource, + request_token, + wrap_xblock, + wrap_xblock_aside, +) from static_replace import replace_static_urls from student.auth import has_studio_read_access, has_studio_write_access from util.date_utils import get_default_time_display @@ -87,15 +92,6 @@ ALWAYS = lambda x: True highlights_setting = WaffleSwitch(u'dynamic_pacing', u'studio_course_update') -def hash_resource(resource): - """ - Hash a :class:`web_fragments.fragment.FragmentResource`. - """ - md5 = hashlib.md5() - md5.update(repr(resource).encode('utf-8')) - return md5.hexdigest() - - def _filter_entrance_exam_grader(graders): """ If the entrance exams feature is enabled we need to hide away the grader from diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 43c5ae8fc0..36e7036661 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -76,6 +76,7 @@ from openedx.core.lib.url_utils import quote_slashes, unquote_slashes from openedx.core.lib.xblock_utils import ( add_staff_markup, get_aside_from_xblock, + hash_resource, is_xblock_aside, replace_course_urls, replace_jump_to_id_urls, @@ -1219,16 +1220,6 @@ def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, course return webob_to_django_response(resp) -def hash_resource(resource): - """ - Hash a :class:`web_fragments.fragment.FragmentResource - """ - md5 = hashlib.md5() - for data in resource: - md5.update(repr(data).encode('utf-8')) - return md5.hexdigest() - - @api_view(['GET']) @view_auth_classes(is_authenticated=True) def xblock_view(request, course_id, usage_id, view_name): diff --git a/lms/djangoapps/courseware/tests/test_module_render.py b/lms/djangoapps/courseware/tests/test_module_render.py index a9d37a8569..1a6ce2760b 100644 --- a/lms/djangoapps/courseware/tests/test_module_render.py +++ b/lms/djangoapps/courseware/tests/test_module_render.py @@ -513,7 +513,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase): decoded or otherwise. """ resources = ['ASCII text', u'❄ I am a special snowflake.', "❄ So am I, but I didn't tell you."] - self.assertEqual(hash_resource(resources), 'a76e27c8e80ca3efd7ce743093aa59e0') + self.assertEqual(hash_resource(resources), '50c2ae79fbce9980e0803848914b0a09') @ddt.ddt diff --git a/openedx/core/lib/xblock_utils/__init__.py b/openedx/core/lib/xblock_utils/__init__.py index 0bd47f6d35..6efcc3a973 100644 --- a/openedx/core/lib/xblock_utils/__init__.py +++ b/openedx/core/lib/xblock_utils/__init__.py @@ -4,6 +4,7 @@ Functions that can are used to modify XBlock fragments for use in the LMS and St from __future__ import absolute_import import datetime +import hashlib import json import logging import re @@ -550,3 +551,20 @@ def get_aside_from_xblock(xblock, aside_type): xblock.core.XBlockAside: Instance of an xblock aside """ return xblock.runtime.get_aside_of_type(xblock, aside_type) + + +def hash_resource(resource): + """ + Hash a :class:`web_fragments.fragment.FragmentResource + Those hash values are used to avoid loading the resources + multiple times. + """ + md5 = hashlib.md5() + for data in resource: + if isinstance(data, bytes): + md5.update(data) + elif isinstance(data, six.string_types): + md5.update(data.encode('utf-8')) + else: + md5.update(repr(data).encode('utf-8')) + return md5.hexdigest()