(*) implements validate_ methods for all timestamp objects
authorThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Thu, 30 Nov 2006 10:12:01 +0000 (10:12 +0000)
committerThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Thu, 30 Nov 2006 10:12:01 +0000 (10:12 +0000)
(*) now allows multiple sync() calls on the same object by
    reverting human-readable form to unix timestamp if needed
(*) removes extra reload formerly needed in Cache

PLC/Cache.py
PLC/Nodes.py
PLC/Persons.py
PLC/Sites.py
PLC/Slices.py
PLC/Table.py

index 61ebcfc..0390704 100644 (file)
@@ -4,7 +4,7 @@ from PLC.Filter import Filter
 from PLC.Table import Row, Table
 
 verbose_flag=False;
-verbose_flag=True;
+#verbose_flag=True;
 def verbose (*args):
     if verbose_flag:
        print (args)
@@ -59,15 +59,15 @@ class Cache:
        def transcode (self, alien_id):
            """ transforms an alien id into a local one """
            # locate alien obj from alien_id
-           verbose ('.entering transcode with alien_id',alien_id,)
+           #verbose ('.entering transcode with alien_id',alien_id,)
            alien_object=self.alien_objects_byid[alien_id]
-           verbose ('..located alien_obj',)
+           #verbose ('..located alien_obj',)
            name = alien_object [self.class_key]
-           verbose ('...got name',name,)
+           #verbose ('...got name',name,)
            local_object=self.local_objects_byname[name]
-           verbose ('....found local obj')
+           #verbose ('....found local obj')
            local_id=local_object[self.primary_key]
-           verbose ('.....and local_id',local_id)
+           #verbose ('.....and local_id',local_id)
            return local_id
            
 
@@ -150,7 +150,7 @@ class Cache:
         ### index upon class_key for future searches
         local_objects_index = local_objects.dict(class_key)
 
-       verbose ('update_table',classname,local_objects_index.keys())
+       #verbose ('update_table',classname,local_objects_index.keys())
 
        ### mark entries for this peer outofdate
         new_count=0
@@ -225,10 +225,6 @@ class Cache:
                     local_object[field]=1
                 verbose('Early sync on',local_object)
                 local_object.sync()
-                verbose('Early syncing of %s, reloading'%object_name)
-                # sigh: now we have to reload it because of side-effects, like e.g. on Slice.expires
-                local_object=table_class(self.api, {class_key:object_name})[0]
-                verbose('After reload',local_object)
 
             # this row is now valid
             local_object.uptodate=True
@@ -241,7 +237,7 @@ class Cache:
                alien_value = alien_object[field]
                transcoder = xref_accessories[xref['field']]['transcoder']
                if isinstance (alien_value,list):
-                   verbose ('update_table list-transcoding ',xref['class'],' aliens=',alien_value,)
+                   #verbose ('update_table list-transcoding ',xref['class'],' aliens=',alien_value,)
                    local_values=[]
                    for a in alien_value:
                        try:
@@ -249,7 +245,7 @@ class Cache:
                        except:
                            # could not transcode - might be from another peer that we dont know about..
                            pass
-                   verbose (" transcoded as ",local_values)
+                   #verbose (" transcoded as ",local_values)
                    xref_table = xref_accessories[xref['field']]['xref_table']
                    # newly created objects dont have xref fields set yet
                    try:
@@ -260,7 +256,7 @@ class Cache:
                                            former_xrefs,
                                            local_values)
                elif isinstance (alien_value,int):
-                   verbose ('update_table atom-transcoding ',xref['class'],' aliens=',alien_value,)
+                   #verbose ('update_table atom-transcoding ',xref['class'],' aliens=',alien_value,)
                    new_value = transcoder.transcode(alien_value)
                    local_object[field] = new_value
 
@@ -354,7 +350,7 @@ class Cache:
                 if local_object['peer_id'] != peer_id:
                     verbose ('FOUND local sa - skipped')
                     continue
-                verbose('FOUND already cached sa')
+                verbose('FOUND already cached sa - setting value')
                 local_object['value'] = alien_object['value']
             # create it if missing
             except:
index f83c740..4c1c695 100644 (file)
@@ -4,7 +4,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: Nodes.py,v 1.25 2006/11/28 10:25:03 thierry Exp $
+# $Id: Nodes.py,v 1.26 2006/11/28 14:55:00 thierry Exp $
 #
 
 from types import StringTypes
@@ -88,6 +88,12 @@ class Node(Row):
 
         return boot_state
 
+    # timestamps
+    def validate_date_created (self, timestamp):
+       return self.validate_timestamp (timestamp)
+    def validate_last_updated (self, timestamp):
+       return self.validate_timestamp (timestamp)
+
     def delete(self, commit = True):
         """
         Delete existing node.
index 87e936f..fd5645c 100644 (file)
@@ -4,7 +4,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: Persons.py,v 1.21 2006/11/25 09:35:36 thierry Exp $
+# $Id: Persons.py,v 1.22 2006/11/28 14:55:00 thierry Exp $
 #
 
 from types import StringTypes
@@ -116,6 +116,13 @@ class Person(Row):
             salt = md5.md5(salt).hexdigest()[:8] 
             return crypt.crypt(password.encode(self.api.encoding), magic + salt + "$")
 
+    # timestamps
+    # verification_expires in the DB but not exposed here
+    def validate_date_created (self, timestamp):
+       return self.validate_timestamp (timestamp)
+    def validate_last_updated (self, timestamp):
+       return self.validate_timestamp (timestamp)
+
     def can_update(self, person):
         """
         Returns true if we can update the specified person. We can
index 14cd51e..d05b285 100644 (file)
@@ -86,6 +86,12 @@ class Site(Row):
 
         return longitude
 
+    # timestamps
+    def validate_date_created (self, timestamp):
+       return self.validate_timestamp (timestamp)
+    def validate_last_updated (self, timestamp):
+       return self.validate_timestamp (timestamp)
+
     def add_person(self, person, commit = True):
         """
         Add person to existing site.
index e8f64cc..2add8ac 100644 (file)
@@ -75,13 +75,14 @@ class Slice(Row):
 
         return instantiation
 
+    # timestamps
+    def validate_created (self, timestamp):
+       return self.validate_timestamp (timestamp)
+
     def validate_expires(self, expires):
         # N.B.: Responsibility of the caller to ensure that expires is
         # not too far into the future.
-        if expires < time.time():
-            raise PLCInvalidArgument, "Expiration date must be in the future"
-
-        return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(expires))
+       return self.validate_timestamp (expires,True)
 
     def add_person(self, person, commit = True):
         """
index 328c1d2..9041c26 100644 (file)
@@ -1,3 +1,6 @@
+import time
+import calendar
+
 from PLC.Faults import *
 from PLC.Parameter import Parameter
 
@@ -47,6 +50,19 @@ class Row(dict):
                 validate = getattr(self, 'validate_' + key)
                 self[key] = validate(value)
 
+    time_format = "%Y-%m-%d %H:%M:%S"
+    def validate_timestamp (self, timestamp, check_future=False):
+       # in case we try to sync the same object twice
+       if isinstance(timestamp,str):
+           # calendar.timegm is the inverse of time.gmtime, in that it computes in UTC
+           # surprisingly enough, no other method in the time module behaves this way
+            # this method is documented in the time module's documentation
+           timestamp = calendar.timegm (time.strptime (timestamp,Row.time_format))
+       human = time.strftime (Row.time_format, time.gmtime(timestamp))
+       if check_future and (timestamp < time.time()):
+            raise PLCInvalidArgument, "%s: date must be in the future"%human
+       return human
+
     def sync(self, commit = True, insert = None):
         """
         Flush changes back to the database.