Skip to content
This repository was archived by the owner on Jan 16, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 15 additions & 48 deletions aaa.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import datetime
import re
from time import sleep
from jsonctl import JsonView, JsonColors
import argparse
from urllib.parse import urlparse

Expand Down Expand Up @@ -146,7 +147,7 @@ def update(self):

self.app.stdscr.addnstr(y, x, msg, maxlen, attr)
elif i == 0:
self.app.stdscr.addnstr(y, x, "Nothing to display", maxlen, curses.A_BOLD | ColorFormat.CF_ERROR)
self.app.stdscr.addnstr(y, x, "Nothing to display", maxlen, curses.A_BOLD | ColorFormat.ERROR)
else:
self.app.stdscr.move(y, x)
self.app.stdscr.clrtoeol()
Expand Down Expand Up @@ -253,7 +254,7 @@ def selectClosest(self, idx):
self.highlight = idx
self.top = idx

class AgencyLogView(LineView):
class AgencyLogView(JsonView):
def __init__(self, app, rect):
super().__init__(app, rect)
self.idx = None
Expand All @@ -274,40 +275,18 @@ def restore(self, state):
self.head = state['head']

def update(self):
self.idx = self.app.list.getSelectedIndex()

if not self.idx == None and self.idx < len(self.app.log):
entry = self.app.log[self.idx]
self.head = None #entry['_key']
self.jsonLines(entry)
self.highlightLines()

idx = self.app.list.getSelectedIndex()
if not idx == self.idx:
self.set(idx)
super().update()

def highlightLines(self):
def intersperse(lst, item):
result = [item] * (len(lst) * 2 - 1)
result[0::2] = lst
return result

logList = self.app.list
if not logList.filterType == AgencyLogList.FILTER_GREP:
return

filt = logList.filterStr
if filt:
for i, line in enumerate(self.lines):
part = intersperse(line.split(filt), (curses.A_BOLD, filt))
self.lines[i] = part

def jsonLines(self, value):
self.lines = json.dumps(value, indent=4, separators=(',', ': ')).splitlines()

def set(self, idx):
self.idx = idx
entry = self.app.log[self.idx]
super().set(entry)


class AgencyStoreView(LineView):
class AgencyStoreView(JsonView):
def __init__(self, app, rect):
super().__init__(app, rect)
self.store = None
Expand Down Expand Up @@ -358,19 +337,19 @@ def updateStore(self):
self.store.apply(self.app.log[i]["request"])
elif snapshot == None:
self.head = None
self.lines = [[(ColorFormat.CF_ERROR, "No snapshot available")]]
self.lines = [[(ColorFormat.ERROR, "No snapshot available")]]
return
elif log[idx]["_key"] < snapshot["_key"]:
self.head = None
self.lines = [[(ColorFormat.CF_ERROR, "Can not replicate agency state. Not covered by snapshot.")]]
self.lines = [[(ColorFormat.ERROR, "Can not replicate agency state. Not covered by snapshot.")]]
return
else:
self.store = agency.AgencyStore(snapshot["readDB"][0])
for i in range(self.app.firstValidLogIdx, idx+1):
if log[idx]["_key"] >= snapshot["_key"]:
self.store.apply(self.app.log[i]["request"])

self.jsonLines(self.store._ref(self.path))
self.set(self.store._ref(self.path))


def update(self):
Expand All @@ -387,12 +366,6 @@ def input(self, c):
else:
super().input(c)

def set(self, store):
self.store = store

def jsonLines(self, value):
self.lines = json.dumps(value, indent=4, separators=(',', ': ')).splitlines()

def __common_prefix_idx(self, strings):
if len(strings) == 0:
return None
Expand Down Expand Up @@ -566,7 +539,6 @@ def layout(self):
super().layout()
self.split.layout(self.rect)


class ArangoAgencyLogProvider:

def __init__(self, logfile, snapshotFile):
Expand Down Expand Up @@ -623,22 +595,17 @@ def refresh(self):
snapshots = self.client.query("for s in compact filter s._key >= @first sort s._key limit 1 return s", first = self._log[0]["_key"])
self._snapshot = next(iter(snapshots), None)

class ColorPairs:
CP_RED_WHITE = 1

class ColorFormat:
CF_ERROR = None


def main(stdscr, provider):
stdscr.clear()
curses.curs_set(0)

# initialise some colors
curses.init_pair(ColorPairs.CP_RED_WHITE, curses.COLOR_RED, curses.COLOR_BLACK)
ColorPairs.init()
ColorFormat.init()
JsonColors.init()

# Init color formats
ColorFormat.CF_ERROR = curses.A_BOLD | curses.color_pair(ColorPairs.CP_RED_WHITE);


app = ArangoAgencyAnalyserApp(stdscr, provider)
Expand Down
38 changes: 34 additions & 4 deletions controls.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import curses, curses.ascii
import textwrap
import datetime


class Rect:
def __init__(self, x, y, width, height):
Expand Down Expand Up @@ -499,10 +501,10 @@ def userStringLine(self, label = None, complete = None, default = None, prompt =
if c == curses.KEY_RESIZE:
self.resize()
self.update()
elif c == curses.KEY_DC or c == curses.ascii.DEL:
elif c == curses.KEY_DC:
if not cursorIndex == len(user):
user = user[:cursorIndex] + user[cursorIndex+1:]
elif c == curses.KEY_BACKSPACE:
elif c == curses.KEY_BACKSPACE or c == curses.ascii.DEL:
if not cursorIndex == 0:
user = user[:cursorIndex-1] + user[cursorIndex:]
cursorIndex -= 1
Expand Down Expand Up @@ -551,13 +553,22 @@ def userStringLine(self, label = None, complete = None, default = None, prompt =
finally:
curses.curs_set(0)

def printStyleLine(self, y, x, line, maxlen, defaultAttr = 0):
def printStyleLine(self, y, x, line, maxlen, defaultAttr = 0, modifier = None, indent = 0):
if isinstance(line, str):
line = [line]

for p in line:
for i in range(0, indent):
if maxlen <= 0:
return
self.stdscr.delch(y, x)
x += 1
maxlen -= 1

for i, p in enumerate(line):
if isinstance(p, str):
p = (defaultAttr, p)
if not modifier == None:
p = modifier(i, p)
strlen = len(p[1])
self.stdscr.addnstr(y, x, p[1], maxlen, p[0])
maxlen -= strlen
Expand Down Expand Up @@ -588,3 +599,22 @@ def showProgress(self, progress, msg, label = None):
self.stdscr.addnstr(self.rect.height - 1, donelen, string[donelen:], maxlen - donelen, 0)

self.stdscr.refresh()

class ColorPairs:
RED_BLACK = 1
BLUE_BLACK = 2
GREEN_BLACK = 3
CYAN_BLACK = 4

def init():
curses.init_pair(ColorPairs.RED_BLACK, curses.COLOR_RED, curses.COLOR_BLACK)
curses.init_pair(ColorPairs.BLUE_BLACK, curses.COLOR_BLUE, curses.COLOR_BLACK)
curses.init_pair(ColorPairs.GREEN_BLACK, curses.COLOR_GREEN, curses.COLOR_BLACK)
curses.init_pair(ColorPairs.CYAN_BLACK, curses.COLOR_CYAN, curses.COLOR_BLACK)


class ColorFormat:
ERROR = None

def init():
ColorFormat.ERROR = curses.A_BOLD | curses.color_pair(ColorPairs.RED_BLACK)
Loading