First version.
authorMikko Värri <vmj@linuxbox.fi>
Wed, 20 Jan 2010 03:33:53 +0000 (05:33 +0200)
committerMikko Värri <vmj@linuxbox.fi>
Wed, 20 Jan 2010 03:33:53 +0000 (05:33 +0200)
recycloid_models/admin.py [new file with mode: 0644]
recycloid_models/management.py [new file with mode: 0644]
recycloid_models/managers.py [new file with mode: 0644]
recycloid_models/models.py
recycloid_models/utils.py [new file with mode: 0644]

diff --git a/recycloid_models/admin.py b/recycloid_models/admin.py
new file mode 100644 (file)
index 0000000..d0844f3
--- /dev/null
@@ -0,0 +1,11 @@
+"""
+"""
+from django.contrib import admin
+
+from recycloid_models import models
+
+admin.site.register(models.StashServer)
+admin.site.register(models.StashOwner)
+admin.site.register(models.Stash)
+admin.site.register(models.StashItem)
+admin.site.register(models.StashItemImage)
diff --git a/recycloid_models/management.py b/recycloid_models/management.py
new file mode 100644 (file)
index 0000000..7cb17c8
--- /dev/null
@@ -0,0 +1,30 @@
+from django.db.models.signals import post_syncdb
+
+from recycloid_models import models
+
+
+def post_syncdb_cb(sender, **kwargs):
+       """Callback for post_syncdb signal.
+       
+       Creates the 'current stash server' object.
+       """
+       verbosity = kwargs.get('verbosity', 0)
+       interactive = kwargs.get('interactive', False)
+       
+       if models.StashServer in kwargs.get('created_models', []):
+               server = models.StashServer()
+               if verbosity:
+                       print "You just installed Recycloid's models, which means you don't have any servers defined."
+                if interactive:
+                        url = raw_input("Give API URL of the recycloid server: ")
+                        server.url = url
+                else:
+                       if verbosity:
+                               print "Be sure to add API URL to the database."
+                server.save() # we want the ID
+               if verbosity or server.id != 1:
+                       print "Be sure to add RECYCLOID_SERVER_ID=%s to settings.py." % server.id
+                server.save()
+
+
+post_syncdb.connect(post_syncdb_cb, sender=models)
diff --git a/recycloid_models/managers.py b/recycloid_models/managers.py
new file mode 100644 (file)
index 0000000..cd3d189
--- /dev/null
@@ -0,0 +1,13 @@
+from django.db.models import Manager
+
+import settings
+
+
+class StashServerManager(Manager):
+       
+       def current(self):
+               try:
+                       server_id = settings.RECYCLOID_SERVER_ID
+               except:
+                       server_id = 1
+               return self.get(pk=server_id)
index 71a8362..64693fa 100644 (file)
@@ -1,3 +1,214 @@
+"""Recycloid models.
+"""
+
+from datetime import datetime
+
+from django.contrib.auth.models import User
 from django.db import models
+from django.db.models.signals import post_save, pre_delete
+
+from recycloid_models.utils import uuid as _uuid
+from recycloid_models.managers import StashServerManager
+
+
+class IdentifiedModel(models.Model):
+       """Abstract base for objects that can be referenced by UUID"""
+       
+       uuid = models.CharField(unique=True, db_index=True, editable=False, default=_uuid, max_length=36,
+                                help_text='Universally Unique Identifier, version 4')
+       
+       class Meta:
+               abstract = True
+       
+       def __unicode__(self):
+               return u'%s %s' % (self.__class__.__name__, self.uuid)
+
+
+class StashServer(IdentifiedModel):
+        """Stash server.
+        """
+        
+       url = models.URLField(unique=True, help_text='API URL of this server')
+       
+       objects = StashServerManager()
+
+        def __unicode__(self):
+                return u'%s' % self.url
+
+
+class StashOwner(IdentifiedModel):
+       """Stash owner.
+
+        This is an extension of django.contrib.User model,
+        i.e. there's one-to-one relationship between them.
+
+        One stash server may have zero or more stash owners.
+        """
+        
+       user = models.ForeignKey(User)
+       
+       server = models.ForeignKey(StashServer)
+       
+       thumbnail = models.URLField(blank=True, help_text='Optional URL of the avatar image')
+       
+       description = models.TextField(blank=True, help_text='Optional self description')
+
+        def __unicode__(self):
+                return u'%s' % self.user.username
+
+
+class Stash(IdentifiedModel):
+       """A stash of items.
+
+        One stash owner may have zero or more stashes.
+
+        One stash server may have zero or more stashes.
+        """
+        
+       owner = models.ForeignKey(StashOwner)
+       server = models.ForeignKey(StashServer)
+       
+       latitude = models.DecimalField(max_digits=8, decimal_places=6,
+                                       help_text='WGS84 latitude coordinate [-90..90])')
+       longitude = models.DecimalField(max_digits=9, decimal_places=6,
+                                        help_text='WGS84 longitude coordinate [-180..180]')
+       
+       thumbnail = models.URLField(blank=True, help_text='Optional URL to the stash thumbnail')
+       
+       title = models.CharField(max_length=50, blank=True, help_text='Optional short description')
+       description = models.TextField(blank=True, help_text='Optional longer description')
+       
+       item_count = models.PositiveIntegerField(default=0, editable=False,
+                                                 help_text='Number of stash items in this stash')
+       
+        class Meta:
+                verbose_name_plural = u'stashes'
+
+        def __unicode__(self):
+                return u'%s' % self.title
+
+
+class StashItem(IdentifiedModel):
+       """An item in a stash.
+
+        One stash may have zero or more stash items.
+        """
+        
+       stash = models.ForeignKey(Stash)
+       
+       thumbnail = models.URLField(blank=True, help_text='Optional URL to the item thumbnail')
+       
+       title = models.CharField(max_length=50, blank=True,
+                                 help_text='Optional short description')
+       description = models.TextField(blank=True,
+                                       help_text='Optional longer description')
+       
+       created = models.DateTimeField(auto_now_add=True, editable=False, default=datetime.now,
+                                       help_text='Time when this item was created')
+       expires = models.DateTimeField(null=True, blank=True, default=None,
+                                       help_text='Optional time when this item expires')
+       modified = models.DateTimeField(auto_now=True, editable=False, default=datetime.now,
+                                        help_text='Time when this item was last modified')
+
+        def __unicode__(self):
+                return u'%s' % self.title
+
+
+class StashItemImage(IdentifiedModel):
+       """Detailed image of a stash item.
+
+        One stash item may have zero or more stash item images.
+        """
+        
+       item = models.ForeignKey(StashItem)
+       
+       url = models.URLField(help_text='URL to the item image')
+       
+       # These two fields are updated by a background process that
+       # checks the existance of images.  UI may then ignore those
+       # images that have recently been checked and did not exist.
+       #exists = models.NullBoolean(default=None, editable=False)
+       #checked = models.DateTimeField(null=True, default=None, editable=False)
+       
+       # Some usefull meta info about the remote image.
+       # Filled by the background image checker.
+       #size = models.PositiveIntegerField(null=True, default=None, editable=False)
+       #width = models.PositiveIntegerField(null=True, default=None, editable=False)
+       #height = models.PositiveIntegerField(null=True, default=None, editable=False)
+       #mimetype = models.MIMETypeField()
+       
+       # Caching related info (whatever the remote server gave us)
+       #last_modified = models.CharField(max_length=60)
+       #etag = models.CharField(max_length=60)
+       
+       # Thumbnail (relative path to image in thumbnail storage)
+       #thumbnail = models.CharField(max_length=60)
+       #accessed = models.DateTimeField(null=True, editable=False, default=None)
+
+        def __unicode__(self):
+                return u'%s' % self.url
+
+
+def on__user__post_save(sender, *args, **kwargs):
+       """Callback for post_save signal from auth.models.User.
+       
+       Creates a corresponding Recycloid StashOwner when User is
+       created.
+       """
+       print "on__user__post_save"
+       if kwargs.get('created', False):
+               print " - new User created"
+               user = kwargs.get('instance', None)
+               if user:
+                       print " - Creating Recycloid StashOwner"
+                        try:
+                                server = StashServer.objects.current()
+                                owner = StashOwner.objects.create(user=user, server=server)
+                                owner.save()
+                        except:
+                                print " - FAILED: Recycloid StashServer not yet created"
+               else:
+                       print " - No instance"
+       else:
+               print " - User only modified"
+
+post_save.connect(on__user__post_save, sender=User)
+
+
+def on__stash_item__post_save(sender, *args, **kwargs):
+       """Callback for post_save signal from StashItem
+       
+       Increments the item_count in related Stash, if an StashItem
+       was created.
+       """
+       print "on__stash_item__post_save"
+       if kwargs.get('created', False):
+               print " - new StashItem created"
+               item = kwargs.get('instance', None)
+               if item:
+                       print " - Increasing count in Stash"
+                       item.stash.item_count = item.stash.item_count + 1
+                       item.stash.save()
+               else:
+                       print " - No instance"
+       else:
+               print " - StashItem only modified"
+
+post_save.connect(on__stash_item__post_save, sender=StashItem)
+
+
+def on__stash_item__pre_delete(sender, *args, **kwargs):
+       """Callback for pre_delete signal from StashItem.
+       
+       Decrements the item_count in related Stash.
+       """
+       print "on__stash_item__pre_delete"
+       item = kwargs.get('instance', None)
+       if item:
+               print " - Decreasing count in Stash"
+               item.stash.item_count = item.stash.item_count - 1
+               item.stash.save()
+       else:
+               print " - No instance"
 
-# Create your models here.
+pre_delete.connect(on__stash_item__pre_delete, sender=StashItem)
diff --git a/recycloid_models/utils.py b/recycloid_models/utils.py
new file mode 100644 (file)
index 0000000..3ea3c9b
--- /dev/null
@@ -0,0 +1,12 @@
+try:
+       import uuid as _uuid
+       def uuid():
+               return str(_uuid.uuid4())
+except ImportError:
+       def uuid():
+               from commands import getstatusoutput as run
+               s, o = run('uuidgen -r')
+               if s == 0:
+                       return o
+               else:
+                       raise ImportError("Missing uuid library (and can't fake it)")