--- a/pvl/syslog/tail.py Tue Feb 19 19:28:40 2013 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-"""
- Iterate over input lines in filesystem files.
-"""
-
-import os
-
-import logging; log = logging.getLogger('pvl.syslog.tail')
-
-class Tail (object) :
- """
- Follow a file on the filesystem, reading lines until EOF, and re-opening if replaced.
-
- Never blocks, no fileno() to poll. Just poll(timeout=POLL).
-
- Not writable.
- """
-
- POLL = 2.0
-
- def __init__ (self, path, skip=None, **opts) :
- log.debug("%s", path)
-
- self.path = path
- self.file = self.stat = None # closed
-
- self.open()
-
- if skip :
- self.skip()
-
- def _stat (self) :
- """
- Return a key identifying the file at our path.
- """
-
- st = os.stat(self.path)
-
- stat = st.st_dev, st.st_ino
-
- return stat
-
- def _open (self) :
- """
- Return the opened file.
- """
-
- return open(self.path, 'r')
-
- def open (self) :
- """
- Re-opens our file when closed.
-
- Raises ValueError if already open.
- """
-
- if self.file is None :
- # XXX: use fstat for "atomic" open+stat?
- self.file = self._open()
- self.stat = self._stat()
-
- log.debug("%s: %s: %s", self, self.file, self.stat)
-
- else :
- raise ValueError("%s: open already open tail" % (self, ))
-
- def changed (self) :
- """
- Has the underlying file changed?
- """
-
- return self._stat() != self.stat
-
- def readline (self) :
- """
- Reads a line from the file, without trailing \n.
-
- Returns None on EOF.
- """
-
- line = self.file.readline()
-
- if not line :
- line = None
- else :
- line = line.rstrip('\r\n')
-
- log.debug("%s", line)
-
- return line
-
- def readlines (self, eof_mark=False) :
- """
- Reads any available lines from the file.
-
- Reopens the file on EOF if the underlying file changed.
-
- eof_mark: yields a special None line when this happens.
- """
-
- while True :
- line = self.readline()
-
- if line is not None :
- yield line
-
- elif self.changed() :
- log.debug("EOF: reopen")
-
- self.close()
- self.open()
-
- if eof_mark :
- yield None # special token
-
- # keep going
- continue
-
- else :
- log.debug("EOF: wait")
- break
-
- __iter__ = readlines
-
- def skip (self) :
- """
- Skip any available lines.
- """
-
- log.debug("%s", self)
-
- for line in self.readlines() :
- pass
-
- def close (self) :
- """
- Close our file, if open. Further operations raise ValueError.
-
- log.warn's if already closed.
- """
-
- if self.file :
- log.debug("%s", self)
- self.file.close()
- self.file = None
- else :
- log.warn("%s: close on already closed tail", self)
-
- def __str__ (self) :
- return self.path
-