log_source.py
changeset 93 48fca00689e3
parent 86 645cf9c4441e
child 94 6673de9bc911
--- a/log_source.py	Wed Feb 11 01:21:22 2009 +0200
+++ b/log_source.py	Wed Feb 11 02:07:07 2009 +0200
@@ -3,10 +3,10 @@
 """
 
 import datetime, calendar, itertools, functools, math
-import os, errno
+import os, os.path, errno
 import pytz
 
-import config
+import config, utils
 
 class LogSourceDecoder (object) :
     """
@@ -161,6 +161,17 @@
         """
 
         abstract
+    
+    def get_modified (self, dt=None) :
+        """
+            Returns a sequence of LogLines that may have been *modified* from their old values since the given datetime.
+
+            If the datetime is not given, *all* lines are returned
+
+            The LogLines should be in time order.
+        """
+
+        abstract
 
 class LogFile (object) :
     """
@@ -364,12 +375,14 @@
         # convert to date and use that
         return self._get_logfile_date(dtz.date())
 
-    def _get_logfile_date (self, d, load=True) :
+    def _get_logfile_date (self, d, load=True, stat=True, ignore_missing=True) :
         """
-            Get the logfile corresponding to the given naive date in our timezone. If load is False, only test for the
-            presence of the logfile, do not actually open it.
+            Get the logfile corresponding to the given naive date in our timezone. 
+            
+            If load is False, only test for the presence of the logfile, do not actually open it. If stat is given,
+            then this returns the stat() result
 
-            Returns None if the logfile does not exist.
+            Returns None if the logfile does not exist, unless ignore_missing is given as False.
         """
 
         # format filename
@@ -383,6 +396,10 @@
                 # open+return the LogFile
                 return LogFile(path, self.parser, self.decoder, start_date=d, channel=self.channel)
             
+            elif stat :
+                # stat
+                return os.stat(path)
+
             else :
                 # test
                 return os.path.exists(path)
@@ -390,12 +407,33 @@
         # XXX: move to LogFile
         except IOError, e :
             # return None for missing files
-            if e.errno == errno.ENOENT :
+            if e.errno == errno.ENOENT and ignore_missing :
                 return None
 
             else :
                 raise
     
+    def _iter_logfile_dates (self) :
+        """
+            Yields a series of naive datetime objects representing the logfiles that are available, in time order
+        """
+
+        # listdir
+        filenames = os.listdir(self.path)
+
+        # sort
+        filenames.sort()
+
+        # iter files
+        for filename in filenames :
+            try :
+                # parse date + yield
+                yield datetime.datetime.strptime(filename, self.filename_fmt).replace(tzinfo=self.tz)
+            
+            except :
+                # ignore
+                continue
+            
     def _iter_date_reverse (self, dt=None) :
         """
             Yields an infinite series of naive date objects in our timezone, iterating backwards in time starting at the
@@ -566,3 +604,27 @@
                 # valid
                 yield dt.date()
 
+    def get_modified (self, dt=None) :
+        """
+            Returns the contents off all logfiles with mtimes past the given date
+        """
+        
+        # iterate through all available logfiles in date order, as datetimes
+        for log_date in self._iter_logfile_dates() :
+            # compare against dt?
+            if dt :
+                # stat
+                st = self._get_logfile_date(log_date, load=False, stat=True)
+
+                # not modified?
+                if utils.from_utc_timestamp(st.st_mtime) < dt :
+                    # skip
+                    continue
+                
+            # open
+            logfile = self._get_logfile_date(log_date, ignore_missing=False)
+
+            # yield all lines
+            for line in logfile.read_full() :
+                yield line
+