Commit 207ce4ed by Clinton Blackburn

Resolved decompression errors during tests

Note that this change will require deleting all CourseStructure data. This data should be regenerated using the generate_course_structure management command.

XCOM-513
parent 3bf6b9bd
...@@ -4,12 +4,10 @@ import gzip ...@@ -4,12 +4,10 @@ import gzip
import logging import logging
from django.db import models from django.db import models
from django.db.models.signals import post_init
from django.utils.text import compress_string from django.utils.text import compress_string
from config_models.models import ConfigurationModel from config_models.models import ConfigurationModel
logger = logging.getLogger(__name__) # pylint: disable=invalid-name logger = logging.getLogger(__name__) # pylint: disable=invalid-name
...@@ -25,27 +23,31 @@ class RateLimitConfiguration(ConfigurationModel): ...@@ -25,27 +23,31 @@ class RateLimitConfiguration(ConfigurationModel):
pass pass
def uncompress_string(s): def decompress_string(value):
""" """
Helper function to reverse CompressedTextField.get_prep_value. Helper function to reverse CompressedTextField.get_prep_value.
""" """
try: try:
val = s.encode('utf').decode('base64') val = value.encode('utf').decode('base64')
zbuf = cStringIO.StringIO(val) zbuf = cStringIO.StringIO(val)
zfile = gzip.GzipFile(fileobj=zbuf) zfile = gzip.GzipFile(fileobj=zbuf)
ret = zfile.read() ret = zfile.read()
zfile.close() zfile.close()
except Exception as e: except Exception as e:
logger.error('String decompression failed. There may be corrupted data in the database: %s', e) logger.error('String decompression failed. There may be corrupted data in the database: %s', e)
ret = s ret = value
return ret return ret
class CompressedTextField(models.TextField): class CompressedTextField(models.TextField):
"""transparently compress data before hitting the db and uncompress after fetching""" """ TextField that transparently compresses data when saving to the database, and decompresses the data
when retrieving it from the database. """
__metaclass__ = models.SubfieldBase
def get_prep_value(self, value): def get_prep_value(self, value):
""" Compress the text data. """
if value is not None: if value is not None:
if isinstance(value, unicode): if isinstance(value, unicode):
value = value.encode('utf8') value = value.encode('utf8')
...@@ -53,28 +55,12 @@ class CompressedTextField(models.TextField): ...@@ -53,28 +55,12 @@ class CompressedTextField(models.TextField):
value = value.encode('base64').decode('utf8') value = value.encode('base64').decode('utf8')
return value return value
def post_init(self, instance=None, **kwargs): # pylint: disable=unused-argument def to_python(self, value):
value = self._get_val_from_obj(instance) """ Decompresses the value from the database. """
if value: if isinstance(value, unicode):
setattr(instance, self.attname, value) value = decompress_string(value)
def contribute_to_class(self, cls, name): return value
super(CompressedTextField, self).contribute_to_class(cls, name)
post_init.connect(self.post_init, sender=cls)
def _get_val_from_obj(self, obj):
if obj:
value = uncompress_string(getattr(obj, self.attname))
if value is not None:
try:
value = value.decode('utf8')
except UnicodeDecodeError:
pass
return value
else:
return self.get_default()
else:
return self.get_default()
def south_field_triple(self): def south_field_triple(self):
"""Returns a suitable description of this field for South.""" """Returns a suitable description of this field for South."""
......
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