Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

No longer depends on django-picklefield and does not deepcopy results

  • Loading branch information...
commit 817a1223e1241b8dc1b1ccd3c18aa407a2f06971 1 parent 926d7df
@ask authored
View
8 djcelery/migrations/0001_initial.py
@@ -17,7 +17,7 @@ def forwards(self, orm):
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('task_id', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255)),
('status', self.gf('django.db.models.fields.CharField')(default='PENDING', max_length=50)),
- ('result', self.gf('picklefield.fields.PickledObjectField')(default=None, null=True)),
+ ('result', self.gf('djcelery.picklefield.PickledObjectField')(default=None, null=True)),
('date_done', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
('traceback', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),))
db.send_create_signal('djcelery', ['TaskMeta'])
@@ -26,7 +26,7 @@ def forwards(self, orm):
db.create_table('celery_tasksetmeta', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('taskset_id', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255)),
- ('result', self.gf('picklefield.fields.PickledObjectField')()),
+ ('result', self.gf('djcelery.picklefield.PickledObjectField')()),
('date_done', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),))
db.send_create_signal('djcelery', ['TaskSetMeta'])
@@ -165,7 +165,7 @@ def backwards(self, orm):
'Meta': {'object_name': 'TaskMeta', 'db_table': "'celery_taskmeta'"},
'date_done': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'result': ('picklefield.fields.PickledObjectField', [], {'default': 'None', 'null': 'True'}),
+ 'result': ('djcelery.picklefield.PickledObjectField', [], {'default': 'None', 'null': 'True'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'PENDING'", 'max_length': '50'}),
'task_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
'traceback': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
@@ -174,7 +174,7 @@ def backwards(self, orm):
'Meta': {'object_name': 'TaskSetMeta', 'db_table': "'celery_tasksetmeta'"},
'date_done': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'result': ('picklefield.fields.PickledObjectField', [], {}),
+ 'result': ('djcelery.picklefield.PickledObjectField', [], {}),
'taskset_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
},
'djcelery.taskstate': {
View
4 djcelery/migrations/0002_v25_changes.py
@@ -74,7 +74,7 @@ def backwards(self, orm):
'date_done': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'hidden': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'result': ('picklefield.fields.PickledObjectField', [], {'default': 'None', 'null': 'True'}),
+ 'result': ('djcelery.picklefield.PickledObjectField', [], {'default': 'None', 'null': 'True'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'PENDING'", 'max_length': '50'}),
'task_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
'traceback': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
@@ -84,7 +84,7 @@ def backwards(self, orm):
'date_done': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'hidden': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'result': ('picklefield.fields.PickledObjectField', [], {}),
+ 'result': ('djcelery.picklefield.PickledObjectField', [], {}),
'taskset_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
},
'djcelery.taskstate': {
View
3  djcelery/models.py
@@ -11,13 +11,12 @@
from django.db.models import signals
from django.utils.translation import ugettext_lazy as _
-from picklefield.fields import PickledObjectField
-
from celery import schedules
from celery import states
from celery.utils.timeutils import timedelta_seconds
from . import managers
+from .picklefield import PickledObjectField
from .utils import now
HEARTBEAT_EXPIRE = 150 # 2 minutes, 30 seconds
View
100 djcelery/picklefield.py
@@ -0,0 +1,100 @@
+"""
+ Based on django-picklefield which is
+ Copyright (c) 2009-2010 Gintautas Miliauskas
+ but some improvements including not deepcopying values.
+
+ Provides an implementation of a pickled object field.
+ Such fields can contain any picklable objects.
+
+ The implementation is taken and adopted from Django snippet #1694
+ <http://www.djangosnippets.org/snippets/1694/> by Taavi Taijala, which is in
+ turn based on Django snippet #513 <http://www.djangosnippets.org/snippets/513/>
+ by Oliver Beattie.
+
+"""
+from __future__ import absolute_import
+
+from base64 import b64encode, b64decode
+from zlib import compress, decompress
+
+from celery.utils.serialization import pickle
+
+from django.db import models
+from django.utils.encoding import force_unicode
+
+DEFAULT_PROTOCOL = 2
+
+
+class PickledObject(str):
+ pass
+
+
+def maybe_compress(value, do_compress=False):
+ if do_compress:
+ return compress(value)
+ return value
+
+
+def maybe_decompress(value, do_decompress=False):
+ if do_decompress:
+ return decompress(value)
+ return value
+
+
+def encode(value, compress_object=False, pickle_protocol=DEFAULT_PROTOCOL):
+ return b64encode(maybe_compress(
+ pickle.dumps(value, pickle_protocol), compress_object))
+
+
+def decode(value, compress_object=False):
+ return pickle.loads(maybe_decompress(b64decode(value), compress_object))
+
+
+class PickledObjectField(models.Field):
+ __metaclass__ = models.SubfieldBase
+
+ def __init__(self, compress=False, protocol=DEFAULT_PROTOCOL,
+ *args, **kwargs):
+ self.compress = compress
+ self.protocol = protocol
+ kwargs.setdefault("editable", False)
+ super(PickledObjectField, self).__init__(*args, **kwargs)
+
+ def get_default(self):
+ if self.has_default():
+ return self.default() if callable(self.default) else self.default
+ return super(PickledObjectField, self).get_default()
+
+ def to_python(self, value):
+ if value is not None:
+ try:
+ return decode(value, self.compress)
+ except Exception:
+ if isinstance(value, PickledObject):
+ raise
+ return value
+
+ def get_db_prep_value(self, value, **kwargs):
+ if value is not None and not isinstance(value, PickledObject):
+ return force_unicode(encode(value, self.compress, self.protocol))
+ return value
+
+ def value_to_string(self, obj):
+ return self.get_db_prep_value(self._get_val_from_obj(obj))
+
+ def get_internal_type(self):
+ return 'TextField'
+
+ def get_db_prep_lookup(self, lookup_type, value, *args, **kwargs):
+ 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(*args, **kwargs)
+
+try:
+ from south.modelsinspector import add_introspection_rules
+except ImportError:
+ pass
+else:
+ add_introspection_rules([],
+ ['r"^djcelery\.picklefield\.PickledObjectField'])
View
1  requirements/default.txt
@@ -1,2 +1 @@
-django-picklefield>=0.2.0
celery>=2.5.2
View
1  setup.py
@@ -173,7 +173,6 @@ def extra_args(self):
scripts=["bin/djcelerymon"],
zip_safe=False,
install_requires=[
- "django-picklefield>=0.2.0",
"celery>=2.5.2",
],
cmdclass={"test": RunTests,
Please sign in to comment.
Something went wrong with that request. Please try again.