Index

lognestmonster / 23adbb8

A general-purpose single-header C logging library and parser for event-based logs. (Incomplete)

Latest Commit

{#}TimeHashSubjectAuthor#(+)(-)GPG?
9302 Sep 2019 18:2023adbb8update parser stuffJosh Stockin1578N

Blob @ lognestmonster / parser / parse.py

application/x-python7871 bytesdownload raw
1# lognestmonster Copyright (c) 2019 Joshua 'joshuas3' Stockin
2# <https://github.com/JoshuaS3/lognestmonster/>.
3
4
5# This file is part of lognestmonster.
6
7# lognestmonster is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11
12# lognestmonster is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16
17# You should have received a copy of the GNU General Public License
18# along with lognestmonster. If not, see <https://www.gnu.org/licenses/>.
19
20import os
21import sys
22from utils import *
23from format import *
24from text import *
25from args import *
26from parseargs import *
27from read import *
28
29class Parser:
30 screen = None
31 clines = None
32 ccols = None
33 lines = None
34 def __init__(self):
35 self.screen = curses_window()
36 self.get_size()
37
38 def get_size(self):
39 size = term_size()
40 self.clines = size[0]
41 self.ccols = size[1]
42
43 def redraw(self):
44 self.get_size()
45 curses_clear(self.screen)
46 l = 0
47 for line in self.lines:
48 if l == self.clines: break
49 self.screen.move(l, 0)
50 line_len = 0
51 for string in line:
52 # ("content string", "attributes string")
53 content = string[0]
54
55 self.screen.attrset(0)
56
57 try:
58 attr = string[1]
59 except:
60 attr = ""
61
62 if "RESET" in attr: # set curses attributes based on attributes string
63 self.screen.attron(curses.color_pair(0))
64 else:
65 if "BLACK" in attr:
66 self.screen.attron(curses.color_pair(1))
67 if "BLUE" in attr:
68 self.screen.attron(curses.color_pair(2))
69 if "CYAN" in attr:
70 self.screen.attron(curses.color_pair(3))
71 if "GREEN" in attr:
72 self.screen.attron(curses.color_pair(4))
73 if "MAGENTA" in attr:
74 self.screen.attron(curses.color_pair(5))
75 if "RED" in attr:
76 self.screen.attron(curses.color_pair(6))
77 if "WHITE" in attr:
78 self.screen.attron(curses.color_pair(7))
79 if "YELLOW" in attr:
80 self.screen.attron(curses.color_pair(8))
81 if "BOLD" in attr:
82 self.screen.attron(curses.A_BOLD)
83 if "STANDOUT" in attr:
84 self.screen.attron(curses.A_STANDOUT)
85 if "UNDERLINE" in attr:
86 self.screen.attron(curses.A_UNDERLINE)
87
88 print(line_len)
89 self.screen.addstr(content[:self.ccols - line_len])
90 self.screen.attrset(0)
91 line_len += len(content)
92 l += 1
93 curses_refresh(self.screen)
94
95 def get_input(self):
96 input = getch()
97 if input == UP: input = "up"
98 elif input == DOWN: input = "down"
99 elif input == LEFT: input = "left"
100 elif input == RIGHT: input = "right"
101 elif input == CTRLC: input = "exit"
102 else: input = str(input).lower()
103 return input
104
105 folder_name = "log_1565561768719"
106 divider = " | "
107 title = TITLE
108
109 def loop(self):
110 def tab(string, count=1):
111 return " "*count + string
112 input = None
113 try:
114 while True:
115 self.get_size()
116 screen_width = self.ccols
117
118 self.lines = [
119 [(self.title + " - ", "RESET"), (self.folder_name, "BOLD YELLOW")],
120 "Size: 235 bytes | Timestamp: 1565561768719",
121 "7 Statements | 2 Events | 0 Unsaved Data Trees",
122 pad(" STATEMENT 5 ", ":", screen_width),
123 "",
124 "[[LOG START]]",
125 "v 7 ITEMS",
126 tab("1565561768752 - INFO - INIT - HELLO"),
127 tab("1565561768752 - INFO - INIT - HELLO"),
128 tab("v 4 ITEMS"),
129 tab("1565561768752 - INFO - INIT - HELLO", 2),
130 tab("1565561768752 - INFO - INIT - HELLO", 2),
131 "",
132 [(tab("1565561768752 - INFO - INIT - HELLO", 2), "BOLD")],
133 "",
134 tab("1565561768752 - INFO - INIT - HELLO", 2),
135 tab("1565561768752 - INFO - INIT - HELLO"),
136 "",
137 str(input),
138 "[[LOG END]",
139 "",
140 "",
141 "",
142 pad(margin(CONTROLS_MESSAGE), ":", screen_width)
143 ]
144 self.redraw()
145
146 input = self.get_input()
147
148 if input == "exit" or input == "q": # exit program on Ctrl + C or `q`
149 break;
150 finally:
151 curses_reset()
152
153def main():
154 options = parseargs(sys.argv[1:])
155
156 display_help = "help" in options
157 display_version = "version" in options
158 is_status = "status" in options
159
160 filter_errors = "errors" in options
161 filter_warnings = "warnings" in options
162 filter_info = "info" in options
163 filter_debug = "debug" in options
164 filter_verbose = "verbose" in options
165 filter_veryverbose = "veryverbose" in options
166
167 filter_after = "after" in options
168 filter_before = "before" in options
169 filter_tag = "tag" in options
170
171 screen_size = term_size()
172 clines = screen_size[0]
173 ccols = screen_size[1] - 2
174
175 if display_help:
176 output(VERSION_SHORT)
177
178 usage = []
179 line = "usage: lognestmonster "
180 x = len(line)
181 width = ccols - x
182 wrapped = wrap(USAGE_MESSAGE, width, "&")
183 for l in wrapped:
184 line += l
185 usage.append(line)
186 line = (" "*x)
187 output_lines(usage)
188
189 output()
190
191 for paragraph in COMMAND_INFO.split("\n\n"):
192 output_lines(wrap(paragraph, ccols))
193
194 output()
195
196 args = []
197
198 div1 = ccols/3
199 div2 = ccols/3*2
200 for arg in ARGUMENT_OPTIONS:
201 arg_lines = []
202 indicators = wrap(", ".join(ARGUMENT_OPTIONS[arg]["indicators"]), div1)
203 description = wrap(ARGUMENT_OPTIONS[arg]["description"], div2)
204 l1 = indicators[0]
205 z = 0
206 for line in description:
207 try:
208 l1 = indicators[z]
209 except:
210 l1 = ""
211 z += 1
212 l = columnize([(div1, l1), (div2, line)], ccols)
213 arg_lines.append(l)
214 args += arg_lines
215
216 output_lines(args)
217 output()
218 output(DESCRIPTION_PYTHON_VERSION)
219 return
220 elif display_version:
221 output(VERSION_MESSAGE)
222 return
223 elif len(sys.argv) == 1 or type(options) is str: # argument error or no args passed
224 exitcode = 0
225 output(VERSION_SHORT)
226 if type(options) is str: # print argument error is exists
227 output(options)
228 exitcode = 1
229 output(HELP_MESSAGE)
230 exit(exitcode)
231
232 positional = sys.argv[-1]
233 if positional is not "-" and os.path.isfile(positional) is not True and os.path.isdir(positional) is not True:
234 output(VERSION_SHORT)
235 output(TEXT_RED + "error:" + RESET + " file unknown '" + positional + "'")
236 output(HELP_MESSAGE)
237 exit(1)
238
239 if positional is "-": positional = "stdin"
240
241 if positional is "stdin":
242 fd = sys.stdin
243 else:
244 try:
245 fd = open(positional, "rb", buffering=8192)
246 except:
247 output(TEXT_RED + "error:" + RESET + " unable to open file")
248 exit(1)
249
250 if not is_status:
251 p = Parser()
252 p.folder_name = positional
253 p.loop()
254 else:
255 r = Reader(fd)
256
257 filter_verbosity_levels = []
258 if filter_errors:
259 filter_verbosity_levels.append(5)
260 if filter_warnings:
261 filter_verbosity_levels.append(4)
262 if filter_info:
263 filter_verbosity_levels.append(0)
264 if filter_debug:
265 filter_verbosity_levels.append(1)
266 if filter_verbose:
267 filter_verbosity_levels.append(2)
268 if filter_veryverbose:
269 filter_verbosity_levels.append(3)
270 if filter_verbosity_levels != []:
271 r.filter_verbosity = filter_verbosity_levels
272 else:
273 r.filter_verbosity = [0, 1, 4, 5]
274
275 if filter_after:
276 try:
277 r.filter_time_start = int(options["after"][0])
278 except:
279 output(VERSION_SHORT)
280 output(TEXT_RED + "error:" + RESET + " expected int for flag --after, got '" + options["after"][0] + "'")
281 output(HELP_MESSAGE)
282 exit(1)
283 if filter_before:
284 try:
285 r.filter_time_end = int(options["before"][0])
286 except:
287 output(VERSION_SHORT)
288 output(TEXT_RED + "error:" + RESET + " expected int for flag --before, got '" + options["before"][0] + "'")
289 output(HELP_MESSAGE)
290 exit(1)
291
292 if filter_tag:
293 r.filter_tag = str(options["tag"][0])
294 if positional is not "stdin": r.size()
295 def update():
296 print("bad bytes: {0}".format(r.bad_bytes), end="\r")
297 r.onupdate(update)
298 r.scan()
299 print("bad bytes: {0}".format(r.bad_bytes))
300
301 fd.close()
302
303
304if __name__ == "__main__":
305 main()
306