diff --git a/apps/queue_manager/__init__.py b/apps/queue_manager/__init__.py new file mode 100755 index 0000000000..5b40c4e8ec --- /dev/null +++ b/apps/queue_manager/__init__.py @@ -0,0 +1,20 @@ +from queue_manager.models import Queue as QueueModel, QueuePushError + +class Queue(object): + @classmethod + def __new__(cls, name, queue_name, label=None, unique_names=False): + name = queue_name + if not label: + label=u'' + queue, created = QueueModel.objects.get_or_create( + name=name, + defaults={ + 'label': label, + 'unique_names': unique_names + } + ) + if not created: + queue.label = label + queue.unique_names = unique_names + queue.save() + return queue diff --git a/apps/queue_manager/admin.py b/apps/queue_manager/admin.py new file mode 100755 index 0000000000..14bb1dcb74 --- /dev/null +++ b/apps/queue_manager/admin.py @@ -0,0 +1,22 @@ +from django.contrib import admin + +from django.utils.translation import ugettext_lazy as _ + +from queue_manager.models import Queue, QueueItem + + +class QueueItemInline(admin.StackedInline): + model = QueueItem + + +class QueueAdmin(admin.ModelAdmin): + model = Queue + list_display = ('name', 'label', 'total_items') + inlines = [QueueItemInline] + + def total_items(self, obj): + return obj.items.all().count() + total_items.short_description = _(u'total items') + + +admin.site.register(Queue, QueueAdmin) diff --git a/apps/queue_manager/exceptions.py b/apps/queue_manager/exceptions.py new file mode 100644 index 0000000000..fc356e3b69 --- /dev/null +++ b/apps/queue_manager/exceptions.py @@ -0,0 +1,6 @@ +class QueueException(Exception): + pass + + +class QueuePushError(QueueException): + pass diff --git a/apps/queue_manager/migrations/0001_initial.py b/apps/queue_manager/migrations/0001_initial.py new file mode 100644 index 0000000000..22215e726d --- /dev/null +++ b/apps/queue_manager/migrations/0001_initial.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'Queue' + db.create_table('queue_manager_queue', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=32)), + ('unique_names', self.gf('django.db.models.fields.BooleanField')(default=False)), + )) + db.send_create_signal('queue_manager', ['Queue']) + + # Adding model 'QueueItem' + db.create_table('queue_manager_queueitem', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('queue', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['queue_manager.Queue'])), + ('creation_datetime', self.gf('django.db.models.fields.DateTimeField')()), + ('unique_name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=32, blank=True)), + ('name', self.gf('django.db.models.fields.CharField')(max_length=32, blank=True)), + ('data', self.gf('django.db.models.fields.TextField')()), + )) + db.send_create_signal('queue_manager', ['QueueItem']) + + + def backwards(self, orm): + # Deleting model 'Queue' + db.delete_table('queue_manager_queue') + + # Deleting model 'QueueItem' + db.delete_table('queue_manager_queueitem') + + + models = { + 'queue_manager.queue': { + 'Meta': {'object_name': 'Queue'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'}), + 'unique_names': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + }, + 'queue_manager.queueitem': { + 'Meta': {'object_name': 'QueueItem'}, + 'creation_datetime': ('django.db.models.fields.DateTimeField', [], {}), + 'data': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'queue': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['queue_manager.Queue']"}), + 'unique_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'blank': 'True'}) + } + } + + complete_apps = ['queue_manager'] \ No newline at end of file diff --git a/apps/queue_manager/migrations/__init__.py b/apps/queue_manager/migrations/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/queue_manager/models.py b/apps/queue_manager/models.py new file mode 100755 index 0000000000..e82781723b --- /dev/null +++ b/apps/queue_manager/models.py @@ -0,0 +1,95 @@ +from __future__ import absolute_import + +from datetime import datetime + +from django.db import models +from django.utils.translation import ugettext_lazy as _ +from django.utils.simplejson import loads, dumps +from django.db import IntegrityError + +from .exceptions import QueuePushError + +queue_labels = {} + + +class QueueManager(models.Manager): + def get_or_create(self, *args, **kwargs): + queue_labels[kwargs.get('name')] = kwargs.get('defaults', {}).get('label') + return super(QueueManager, self).get_or_create(*args, **kwargs) + + +class Queue(models.Model): + # Internal name + name = models.CharField(max_length=32, verbose_name=_(u'name'), unique=True) + unique_names = models.BooleanField(verbose_name=_(u'unique names'), default=False) + + objects = QueueManager() + + def __unicode__(self): + return unicode(self.label) or self.name + + @property + def label(self): + return queue_labels.get(self.name) + + def push(self, data, name=None): # TODO: add replace flag + if not name: + name = u'' + queue_item = QueueItem(queue=self, name=name, data=dumps(data)) + queue_item.save() + return queue_item + + def pull(self): + queue_item_qs = QueueItem.objects.filter(queue=self).order_by('-creation_datetime') + if queue_item_qs: + queue_item = queue_item_qs[0] + queue_item.delete() + return loads(queue_item.data) + + @property + def items(self): + return self.queueitem_set + + def empty(self): + self.items.all().delete() + + def save(self, *args, **kwargs): + label = getattr(self, 'label', None) + if label: + queue_labels[self.name] = label + return super(Queue, self).save(*args, **kwargs) + + # TODO: custom runtime methods + + class Meta: + verbose_name = _(u'queue') + verbose_name_plural = _(u'queues') + + +class QueueItem(models.Model): + queue = models.ForeignKey(Queue, verbose_name=_(u'queue')) + creation_datetime = models.DateTimeField(verbose_name=_(u'creation datetime'), editable=False) + unique_name = models.CharField(blank=True, max_length=32, verbose_name=_(u'name'), unique=True, editable=False) + name = models.CharField(blank=True, max_length=32, verbose_name=_(u'name')) + data = models.TextField(verbose_name=_(u'data')) + + def __unicode__(self): + return self.name + + def save(self, *args, **kwargs): + self.creation_datetime = datetime.now() + + if self.queue.unique_names: + self.unique_name = self.name + else: + self.unique_name = unicode(self.creation_datetime) + try: + super(QueueItem, self).save(*args, **kwargs) + except IntegrityError: + # TODO: Maybe replace instead or rasining exception w/ replace flag + raise QueuePushError + + class Meta: + verbose_name = _(u'queue item') + verbose_name_plural = _(u'queue items') + diff --git a/apps/queue_manager/views.py b/apps/queue_manager/views.py new file mode 100755 index 0000000000..60f00ef0ef --- /dev/null +++ b/apps/queue_manager/views.py @@ -0,0 +1 @@ +# Create your views here.