pvl/syslog/file.py
author Tero Marttila <terom@paivola.fi>
Sun, 13 Jan 2013 02:11:12 +0200
changeset 117 58aebcd35e1a
parent 114 2e88e1d8e604
child 136 de243aafe33b
permissions -rw-r--r--
pvl.syslog.file: flush in __call__
114
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
"""
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
    Iterate over lines in file-like objects (without buffering lines!), write (flushing output).
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     3
"""
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     4
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     5
import logging; log = logging.getLogger('pvl.syslog.file')
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     6
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     7
class File (object) :
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     8
    """
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     9
        Follow a file-like object, reading lines until no more are available. Never raises EOFError.
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    10
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    11
        Works with python file objects that buffer readlines() when using e.g. `tail -f ... | python -u ...`.
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    12
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    13
        readline() may block once there is no more input available, or may return None for evermore.
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    14
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    15
        There is no fileno(), this is not pollable. At all. Don't even iterate on this with a timeout.
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    16
        XXX: should this really return None? Might really be better to raise EOFError.. except that readlines() should return normally at EOF...
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    17
    """
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    18
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    19
    @classmethod
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    20
    def open (cls, path, mode='r', **opts) :
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    21
        return cls(open(path, mode), **opts)
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    22
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    23
    EOL = '\n'
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    24
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    25
    def __init__ (self, file) :
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    26
        log.debug("%s", file)
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    27
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    28
        self.file = file
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    29
        
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    30
    def readline (self) :
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    31
        """
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    32
            Reads a line from the file, without trailing \n.
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    33
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    34
            Returns None on EOF.
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    35
        """
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    36
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    37
        line = self.file.readline()
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    38
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    39
        if not line :
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    40
            line = None
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    41
        else : 
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    42
            line = line.rstrip('\r\n')
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    43
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    44
        log.debug("%s", line)
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    45
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    46
        return line
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    47
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    48
    def readlines (self) :
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    49
        """
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    50
            Reads any available lines from the file.
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    51
        """
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    52
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    53
        while True :
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    54
            line = self.readline()
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    55
            
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    56
            if line is None :
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    57
                return
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    58
            else :
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    59
                yield line
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    60
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    61
    __iter__ = readlines
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    62
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    63
    def writeline (self, line, eol=EOL) :
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    64
        """
117
58aebcd35e1a pvl.syslog.file: flush in __call__
Tero Marttila <terom@paivola.fi>
parents: 114
diff changeset
    65
            Write out line.
114
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    66
        """
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    67
117
58aebcd35e1a pvl.syslog.file: flush in __call__
Tero Marttila <terom@paivola.fi>
parents: 114
diff changeset
    68
        log.debug("%s", line)
58aebcd35e1a pvl.syslog.file: flush in __call__
Tero Marttila <terom@paivola.fi>
parents: 114
diff changeset
    69
58aebcd35e1a pvl.syslog.file: flush in __call__
Tero Marttila <terom@paivola.fi>
parents: 114
diff changeset
    70
        self.file.write(str(line))
114
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    71
        self.file.write(eol)
117
58aebcd35e1a pvl.syslog.file: flush in __call__
Tero Marttila <terom@paivola.fi>
parents: 114
diff changeset
    72
58aebcd35e1a pvl.syslog.file: flush in __call__
Tero Marttila <terom@paivola.fi>
parents: 114
diff changeset
    73
    def __call__ (self, *lines) :
58aebcd35e1a pvl.syslog.file: flush in __call__
Tero Marttila <terom@paivola.fi>
parents: 114
diff changeset
    74
        """
58aebcd35e1a pvl.syslog.file: flush in __call__
Tero Marttila <terom@paivola.fi>
parents: 114
diff changeset
    75
            Write out lines, and flush.
58aebcd35e1a pvl.syslog.file: flush in __call__
Tero Marttila <terom@paivola.fi>
parents: 114
diff changeset
    76
        """
58aebcd35e1a pvl.syslog.file: flush in __call__
Tero Marttila <terom@paivola.fi>
parents: 114
diff changeset
    77
58aebcd35e1a pvl.syslog.file: flush in __call__
Tero Marttila <terom@paivola.fi>
parents: 114
diff changeset
    78
        for line in lines :
58aebcd35e1a pvl.syslog.file: flush in __call__
Tero Marttila <terom@paivola.fi>
parents: 114
diff changeset
    79
            self.writeline(line)
58aebcd35e1a pvl.syslog.file: flush in __call__
Tero Marttila <terom@paivola.fi>
parents: 114
diff changeset
    80
114
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    81
        self.file.flush()
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    82
2e88e1d8e604 pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    83