scroll by wheel

This commit is contained in:
2021-10-24 20:02:11 +02:00
parent 6e831c66be
commit b99fb35727
2 changed files with 58 additions and 17 deletions

View File

@@ -1,3 +1,4 @@
import threading
from typing import List
import os
from line import Line
@@ -6,27 +7,56 @@ from settings import Settings
class LogFileModel:
_lock = threading.RLock()
def __init__(self, file):
self._file = file
def data(self, byte_offset:int, lines: int) -> List[Line]:
result : List[Line] = []
def data(self, byte_offset, scroll_lines, lines) -> List[Line]:
#print("data(%s, %s, %s)" % (byte_offset, scroll_lines, lines))
lines_before_offset: List[Line] = []
lines_after_offset: List[Line] = []
result: List[Line] = []
lines_to_find = lines # + -1 * scroll_lines
# TODO handle lines longer than 4096 bytes
with open(self._file, 'r') as f:
offset = max(0, byte_offset - Settings.max_line_length())
offset = offset - offset % Settings.max_line_length() # align to blocks of 4kb
f.seek(offset)
while l := f.readline():
new_offset = f.tell()
if offset >= byte_offset:
line = Line(offset, new_offset-1, l)
result.append(line)
offset = new_offset
if len(result) >= lines:
break
with self._lock:
# TODO handle lines longer than 4096 bytes
with open(self._file, 'rb') as f:
offset = min(byte_offset, self.byte_count())
offset = max(0, offset - Settings.max_line_length())
return result
#print("offset: %s" % (offset))
eof_reached = True
f.seek(offset)
while l := f.readline():
new_offset = f.tell()
line = Line(offset, new_offset, l.decode("utf8").replace("\r", "").replace("\n", ""))
# print("%s %s" %(line.byte_offset(), line.line()))
if offset < byte_offset:
lines_before_offset.append(line)
else:
lines_after_offset.append(line)
offset = f.tell()
if len(lines_after_offset) >= lines_to_find:
eof_reached = False
break
if scroll_lines > 0:
result = result + lines_before_offset[-scroll_lines:]
result = result + lines_after_offset
elif eof_reached:
# we always return the number of requested lines even if we reach the end of the file
lines_to_return_from_before_offset = int(lines_to_find - len(lines_after_offset));
print(lines_to_return_from_before_offset)
if lines_to_return_from_before_offset > 0:
result = result + lines_before_offset[-lines_to_return_from_before_offset:]
result = result + lines_after_offset
else:
result = result + lines_after_offset[-scroll_lines:]
#print("returning %s lines" % (len(result)))
return result
def byte_count(self) -> int:
return os.stat(self._file).st_size