[cig-commits] r14564 - cs/portal/trunk/northridge/SeismoWebPortal

leif at geodynamics.org leif at geodynamics.org
Wed Apr 1 18:14:06 PDT 2009


Author: leif
Date: 2009-04-01 18:14:06 -0700 (Wed, 01 Apr 2009)
New Revision: 14564

Modified:
   cs/portal/trunk/northridge/SeismoWebPortal/models.py
Log:
Fixed some serious bugs in the "archive"/duplicate-run-matching code.


Modified: cs/portal/trunk/northridge/SeismoWebPortal/models.py
===================================================================
--- cs/portal/trunk/northridge/SeismoWebPortal/models.py	2009-04-02 00:43:30 UTC (rev 14563)
+++ cs/portal/trunk/northridge/SeismoWebPortal/models.py	2009-04-02 01:14:06 UTC (rev 14564)
@@ -42,11 +42,20 @@
             return False
         return True
 
+    def archive(self):
+        ctype = ContentType.objects.get_for_model(self.__class__)
+        a, created = Archive.objects.get_or_create(objType = ctype, objId = self.id)
+        return a
 
+
 class ImmutableObject(MaybeArchival):
-    
-    def archivalObject(self):
-        Archive.objects.create(obj = self) # prevent deletion
+
+    def archivalObject(self, weak=False):
+        if weak:
+            if self.isArchival():
+                return self
+            return None
+        self.archive() # prevent deletion
         return self
 
 
@@ -60,29 +69,37 @@
                 continue
             if f.attname == 'name':
                 continue
-            sa, oa = getattr(self, f.attname), getattr(other, f.attname)
-            if isinstance(sa, Model):
+            attname = f.attname
+            if attname.endswith("_id"):
+                attname = attname[:-3]
+            sa, oa = getattr(self, attname), getattr(other, attname)
+            if isinstance(sa, EditableObject):
                 if not sa.matches(oa):
                     return False
             elif sa != oa:
                 return False
         return True
 
-    def archivalObject(self):
+    def archivalObject(self, weak=False):
         from copy import copy
         ctype = ContentType.objects.get_for_model(self.__class__)
         for a in Archive.objects.filter(objType = ctype):
             if a.obj.matches(self):
                 return a.obj
+        if weak:
+            return None
         # Copy so that the user can still edit the original.
         obj = copy(self)
         obj.id = None
         for f in self._meta.fields:
-            attr = getattr(self, f.attname)
+            attname = f.attname
+            if attname.endswith("_id"):
+                attname = attname[:-3]
+            attr = getattr(self, attname)
             if isinstance(attr, Model):
-                setattr(obj, f.attname, attr.archivalObject())
+                setattr(obj, attname, attr.archivalObject())
         obj.save()
-        Archive.objects.create(obj = obj)
+        obj.archive()
         return obj
 
 
@@ -127,10 +144,14 @@
         self.source_set.all().delete()
         super(Event, self).delete()
 
-    def archivalObject(self, zero_half_duration):
+    def archivalObject(self, zero_half_duration, weak=False):
         if self.singleSource:
-            return self.singleSource.archivalObject(zero_half_duration)
-        Archive.objects.create(obj = self) # prevent deletion
+            return self.singleSource.archivalObject(zero_half_duration, weak=weak)
+        if weak:
+            if self.isArchival():
+                return self
+            return None
+        self.archive() # prevent deletion
         return self
 
     def iterCMTSolutions(self):
@@ -187,11 +208,11 @@
     mrp = property(_getMrpStr2f)
     mtp = property(_getMtpStr2f)
 
-    def archivalObject(self, zero_half_duration):
+    def archivalObject(self, zero_half_duration, weak=False):
         halfDuration = self.halfDuration
         if zero_half_duration:
             halfDuration = 0.0
-        obj, created = ArchivedSource.objects.get_or_create(
+        kwds = dict(
             halfDuration = halfDuration,
             latitude = self.latitude, # db_index
             longitude = self.longitude, # db_index
@@ -203,6 +224,13 @@
             Mrp = self.Mrp,
             Mtp = self.Mtp
             )
+        if weak:
+            try:
+                obj = ArchivedSource.objects.get(**kwds)
+            except ArchivedSource.DoesNotExist:
+                obj = None
+        else:
+            obj, created = ArchivedSource.objects.get_or_create(**kwds)
         return obj
 
     def scalarSeismicMoment(self):
@@ -683,8 +711,10 @@
 
     def _getArchive(self):
         if not hasattr(self, '_archive'):
+            kwds = self.archiveKeywords(weak=True)
+            if kwds is None:
+                return None
             self._archive = None
-            kwds = self.archiveKeywords()
             for a in ArchivedRun.objects.filter(record_length__gte = self.record_length, **kwds).order_by('record_length'):
                 self._archive = a
                 break
@@ -710,15 +740,20 @@
     def __str__(self):
         return "Run %04d" % self.id
 
-    def archiveKeywords(self):
+    def archiveKeywords(self, weak=False):
         if not hasattr(self, '_archiveKeywords'):
             zero_half_duration = (self.zero_half_duration and
                                   self.parameters.code == Specfem3DGlobeParameters.code)
         
-            event = self.event.archivalObject(zero_half_duration)
-            stationList = self.stationList.archivalObject()
-            parameters = self.parameters.archivalObject()
-        
+            event = self.event.archivalObject(zero_half_duration, weak=weak)
+            stationList = self.stationList.archivalObject(weak=weak)
+            parameters = self.parameters.archivalObject(weak=weak)
+            if (event is None or
+                stationList is None or
+                parameters is None):
+                assert weak
+                return None
+            
             self._archiveKeywords = dict(
                 eventType = event.contentType(),
                 eventId = event.id,



More information about the CIG-COMMITS mailing list