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-- |
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 |