Seek to end unless --start given
This commit is contained in:
parent
d17173aaff
commit
9ab32e5b6b
17
kitsune
17
kitsune
|
@ -9,19 +9,24 @@ import stat
|
||||||
import time
|
import time
|
||||||
|
|
||||||
class WatchedFile:
|
class WatchedFile:
|
||||||
def __init__(self, path):
|
def __init__(self, path, seek_to_end):
|
||||||
self.path = path
|
self.path = path
|
||||||
|
self.seek_to_end = seek_to_end
|
||||||
self.reopen()
|
self.reopen()
|
||||||
|
|
||||||
def reopen(self):
|
def reopen(self):
|
||||||
self.fd = open(self.path, errors='replace')
|
self.fd = open(self.path, errors='replace')
|
||||||
self.fileno = self.fd.fileno()
|
self.fileno = self.fd.fileno()
|
||||||
self.last_ts = 0
|
self.last_ts = 0
|
||||||
|
if self.seek_to_end:
|
||||||
|
self.fd.seek(0, 2)
|
||||||
|
self.seek_to_end = False
|
||||||
|
|
||||||
def format_ts(ts_ns):
|
def format_ts(ts_ns):
|
||||||
return datetime.datetime.fromtimestamp(ts_ns / 1E9).strftime("%H:%M:%S.%f")
|
return datetime.datetime.fromtimestamp(ts_ns / 1E9).strftime("%H:%M:%S.%f")
|
||||||
|
|
||||||
def watch(args):
|
def watch(args):
|
||||||
|
seek_to_end = not args.start
|
||||||
watched_dirs = []
|
watched_dirs = []
|
||||||
watched_files = {}
|
watched_files = {}
|
||||||
filename_length = 0
|
filename_length = 0
|
||||||
|
@ -30,7 +35,7 @@ def watch(args):
|
||||||
if stat.S_ISDIR(st.st_mode):
|
if stat.S_ISDIR(st.st_mode):
|
||||||
watched_dirs.append(a)
|
watched_dirs.append(a)
|
||||||
elif stat.S_ISREG(st.st_mode):
|
elif stat.S_ISREG(st.st_mode):
|
||||||
watched_files[a] = WatchedFile(a)
|
watched_files[a] = WatchedFile(a, seek_to_end)
|
||||||
if len(a) > filename_length:
|
if len(a) > filename_length:
|
||||||
filename_length = len(a)
|
filename_length = len(a)
|
||||||
else:
|
else:
|
||||||
|
@ -47,7 +52,7 @@ def watch(args):
|
||||||
if de.is_file():
|
if de.is_file():
|
||||||
if args.match_filename is None or fnmatch.fnmatch(de.name, args.match_filename):
|
if args.match_filename is None or fnmatch.fnmatch(de.name, args.match_filename):
|
||||||
if de.path not in watched_files:
|
if de.path not in watched_files:
|
||||||
watched_files[de.path] = WatchedFile(de.path)
|
watched_files[de.path] = WatchedFile(de.path, seek_to_end)
|
||||||
if len(de.path) > filename_length:
|
if len(de.path) > filename_length:
|
||||||
filename_length = len(de.path)
|
filename_length = len(de.path)
|
||||||
|
|
||||||
|
@ -65,6 +70,10 @@ def watch(args):
|
||||||
# or just mark as deleted?
|
# or just mark as deleted?
|
||||||
pass
|
pass
|
||||||
if st.st_mtime_ns > f.last_ts:
|
if st.st_mtime_ns > f.last_ts:
|
||||||
|
if st.st_size < f.fd.tell():
|
||||||
|
# We are beyond the end of the file, so it has probably
|
||||||
|
# been truncated and rewritten - read from beginning
|
||||||
|
f.fd.seek(0, 0)
|
||||||
f.last_ts = st.st_mtime_ns
|
f.last_ts = st.st_mtime_ns
|
||||||
new_content = f.fd.read()
|
new_content = f.fd.read()
|
||||||
lines = new_content.split("\n")
|
lines = new_content.split("\n")
|
||||||
|
@ -73,9 +82,11 @@ def watch(args):
|
||||||
for ln in lines:
|
for ln in lines:
|
||||||
print(f"{f.path:{filename_length}}", format_ts(f.last_ts), ln)
|
print(f"{f.path:{filename_length}}", format_ts(f.last_ts), ln)
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
seek_to_end = False
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
ap = argparse.ArgumentParser()
|
ap = argparse.ArgumentParser()
|
||||||
|
ap.add_argument("--start", action='store_true')
|
||||||
ap.add_argument("--match-filename")
|
ap.add_argument("--match-filename")
|
||||||
ap.add_argument("files", nargs="*", default=["."])
|
ap.add_argument("files", nargs="*", default=["."])
|
||||||
args = ap.parse_args()
|
args = ap.parse_args()
|
||||||
|
|
Loading…
Reference in New Issue