]> git.openstreetmap.org Git - osqa.git/blobdiff - forum/models/utils.py
If you're a superuser viweing a user auth settings, don't present the option to add...
[osqa.git] / forum / models / utils.py
index 984a55ccb20bb1c1372b27e26965bdc6125320fd..5ac89001c07ceaaab616ca92b2e9a2308cd23771 100644 (file)
@@ -1,44 +1,84 @@
 from django.db import models
 from django.core.cache import cache
 from django.conf import settings
-#try:
-#      import cPickle as pickle
-#except ImportError:
-import pickle
-import django.dispatch
+from django.utils.encoding import force_unicode
+
+try:
+    from cPickle import loads, dumps
+except ImportError:
+    from pickle import loads, dumps
+
+from copy import deepcopy
+from base64 import b64encode, b64decode
+from zlib import compress, decompress
+
 
 class PickledObject(str):
-       pass
+    pass
+
+def dbsafe_encode(value, compress_object=True):
+    if not compress_object:
+        value = b64encode(dumps(deepcopy(value)))
+    else:
+        value = b64encode(compress(dumps(deepcopy(value))))
+    return PickledObject(value)
+
+def dbsafe_decode(value, compress_object=True):
+    if not compress_object:
+        value = loads(b64decode(value))
+    else:
+        value = loads(decompress(b64decode(value)))
+    return value
 
 class PickledObjectField(models.Field):
     __metaclass__ = models.SubfieldBase
 
+    def __init__(self, *args, **kwargs):
+        self.compress = kwargs.pop('compress', True)
+        self.protocol = kwargs.pop('protocol', 2)
+        kwargs.setdefault('null', True)
+        kwargs.setdefault('editable', False)
+        super(PickledObjectField, self).__init__(*args, **kwargs)
+
+    def get_default(self):
+        if self.has_default():
+            if callable(self.default):
+                return self.default()
+            return self.default
+
+        return super(PickledObjectField, self).get_default()
+
     def to_python(self, value):
-        if isinstance (value, PickledObject):
-            return value
-
-        try:
-            return pickle.loads(value.encode('utf-8'))
-        except:
-            return value
-    
-    def get_db_prep_save(self, value):
         if value is not None:
-            if isinstance(value, PickledObject):
-                return str(value)
-            else:
-                           value = pickle.dumps(value)
+            try:
+                value = dbsafe_decode(value, self.compress)
+            except:
+                if isinstance(value, PickledObject):
+                    raise
+        return value
 
+    def get_db_prep_value(self, value):
+        if value is not None and not isinstance(value, PickledObject):
+            value = force_unicode(dbsafe_encode(value, self.compress))
         return value
 
+    def value_to_string(self, obj):
+        value = self._get_val_from_obj(obj)
+        return self.get_db_prep_value(value)
+
     def get_internal_type(self):
         return 'TextField'
 
+    def get_db_prep_lookup(self, lookup_type, value):
+        if lookup_type not in ['exact', 'in', 'isnull']:
+            raise TypeError('Lookup type %s is not supported.' % lookup_type)
+        return super(PickledObjectField, self).get_db_prep_lookup(lookup_type, value)
+
 
 class KeyValueManager(models.Manager):
 
     def create_cache_key(self, key):
-        return "%s:key_value:%s" % (settings.APP_URL, key)
+        return "%s:keyvalue:%s" % (settings.APP_URL, key)
 
     def save_to_cache(self, instance):
         cache.set(self.create_cache_key(instance.key), instance, 2592000)