| 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 |
|
| 20 | import os |
| 21 | import sys |
| 22 | import time |
| 23 | import traceback |
| 24 | from utils import * |
| 25 | from format import * |
| 26 | from text import * |
| 27 | from args import * |
| 28 | from parseargs import * |
| 29 | from read import * |
| 30 | from tui import * |
| 31 |
|
| 32 | def output_exit(error=None): |
| 33 | exitcode = 0 |
| 34 | output(VERSION_SHORT) |
| 35 | if error is not None: # print argument error is exists |
| 36 | output(TEXT_RED, "error: ", RESET, error) |
| 37 | exitcode = 1 |
| 38 | output(HELP_MESSAGE) |
| 39 | exit(exitcode) |
| 40 |
|
| 41 | def main(): |
| 42 | options = parseargs(sys.argv[1:]) |
| 43 |
|
| 44 | display_help = "help" in options |
| 45 | display_version = "version" in options |
| 46 | is_status = "status" in options |
| 47 |
|
| 48 | filter_errors = "errors" in options |
| 49 | filter_warnings = "warnings" in options |
| 50 | filter_info = "info" in options |
| 51 | filter_debug = "debug" in options |
| 52 | filter_verbose = "verbose" in options |
| 53 | filter_veryverbose = "veryverbose" in options |
| 54 |
|
| 55 | filter_after = "after" in options |
| 56 | filter_before = "before" in options |
| 57 | filter_tag = "tag" in options |
| 58 |
|
| 59 | screen_size = term_size() |
| 60 | clines = screen_size[0] |
| 61 | ccols = screen_size[1] |
| 62 |
|
| 63 | if display_help: |
| 64 | output(VERSION_SHORT) |
| 65 |
|
| 66 | output("usage: lognestmonster ", USAGE_MESSAGE) |
| 67 |
|
| 68 | output() |
| 69 |
|
| 70 | for paragraph in COMMAND_INFO.split("\n\n"): |
| 71 | output_lines(wrap(paragraph, ccols)) |
| 72 |
|
| 73 | output() |
| 74 |
|
| 75 | args = [] |
| 76 |
|
| 77 | div1 = int(ccols/3) |
| 78 | div2 = int(ccols/3*2) |
| 79 | for arg in ARGUMENT_OPTIONS: |
| 80 | arg_lines = [] |
| 81 | indicators = wrap(", ".join(ARGUMENT_OPTIONS[arg]["indicators"]), div1) |
| 82 | description = wrap(ARGUMENT_OPTIONS[arg]["description"], div2) |
| 83 | l1 = indicators[0] |
| 84 | z = 0 |
| 85 | for line in description: |
| 86 | try: |
| 87 | l1 = indicators[z] |
| 88 | except: |
| 89 | l1 = "" |
| 90 | z += 1 |
| 91 | l = columnize([(div1, l1), (div2, line)], ccols) |
| 92 | arg_lines.append(l) |
| 93 | args += arg_lines |
| 94 |
|
| 95 | output_lines(args) |
| 96 | output() |
| 97 | output(DESCRIPTION_PYTHON_VERSION) |
| 98 | return |
| 99 | elif display_version: |
| 100 | output(VERSION_MESSAGE) |
| 101 | return |
| 102 | elif len(sys.argv) == 1 or type(options) is str: # argument error or no args passed |
| 103 | if type(options) is str: # print argument error is exists |
| 104 | output_exit(options) |
| 105 | else: |
| 106 | output_exit() |
| 107 |
|
| 108 | positional = sys.argv[-1] |
| 109 | if positional is not "-" and os.path.isfile(positional) is not True and os.path.isdir(positional) is not True: |
| 110 | output_exit("file unknown '" + positional + "'") |
| 111 |
|
| 112 | if positional is "-": positional = "stdin" |
| 113 |
|
| 114 | if positional is "stdin": |
| 115 | fd = sys.stdin |
| 116 | else: |
| 117 | try: |
| 118 | fd = open(positional, "rb", buffering=8192) |
| 119 | except: |
| 120 | output_exit("unable to open file '" + positional + "'") |
| 121 |
|
| 122 | if not is_status: |
| 123 | p = TUI() |
| 124 | p.folder_name = positional |
| 125 | p.loop() |
| 126 | else: |
| 127 | r = Reader(fd) |
| 128 |
|
| 129 | filter_verbosity_levels = [] |
| 130 | if filter_errors: |
| 131 | filter_verbosity_levels.append(5) |
| 132 | if filter_warnings: |
| 133 | filter_verbosity_levels.append(4) |
| 134 | if filter_info: |
| 135 | filter_verbosity_levels.append(0) |
| 136 | if filter_debug: |
| 137 | filter_verbosity_levels.append(1) |
| 138 | if filter_verbose: |
| 139 | filter_verbosity_levels.append(2) |
| 140 | if filter_veryverbose: |
| 141 | filter_verbosity_levels.append(3) |
| 142 | if filter_verbosity_levels != []: |
| 143 | r.filter_verbosity = filter_verbosity_levels |
| 144 | r.filters = True |
| 145 | else: |
| 146 | r.filter_verbosity = [0, 1, 2, 3, 4, 5] |
| 147 |
|
| 148 | if filter_after: |
| 149 | try: |
| 150 | r.filter_time_start = int(options["after"][0]) |
| 151 | r.filters = True |
| 152 | except: |
| 153 | output_exit("expected int for flag --after, got '" + options["after"][0] + "'") |
| 154 | if filter_before: |
| 155 | try: |
| 156 | r.filter_time_end = int(options["before"][0]) |
| 157 | r.filters = True |
| 158 | except: |
| 159 | output_exit("expected int for flag --before, got '" + options["before"][0] + "'") |
| 160 |
|
| 161 | if filter_tag: |
| 162 | r.filter_tag = str(options["tag"][0]) |
| 163 | r.filters = True |
| 164 | if positional is not "stdin": r.size() |
| 165 | else: r.seekable = False |
| 166 | output("File scan in progress...") |
| 167 | s = time.time() |
| 168 | def update(): |
| 169 | if r.statement_count % 1000 == 0: |
| 170 | output("{0} statements | {1} events | {2} bad bytes | {3}%".format(r.statement_count, r.event_count, r.bad_bytes, round((r.position/r.file_size)*1000)/10), end="\r") |
| 171 | r.onupdate(update) |
| 172 | r.scan() |
| 173 | output("{0} statements | {1} events | {2} bad bytes | {3}%".format(r.statement_count, r.event_count, r.bad_bytes, round((r.position/r.file_size)*1000)/10)) |
| 174 | elapsed = time.time() - s |
| 175 | if elapsed > 1: |
| 176 | output("Finished in {0} seconds".format(elapsed)) |
| 177 |
|
| 178 | fd.close() |
| 179 |
|
| 180 |
|
| 181 | if __name__ == "__main__": |
| 182 | try: |
| 183 | main() |
| 184 | except Exception as e: |
| 185 | output(TEXT_RED, CONTRAST, "unhandled exception:", RESET) |
| 186 | output("-------------- EXCEPTION --------------") |
| 187 | output(traceback.format_exc()) |
| 188 | output("------------ EXCEPTION END ------------") |
| 189 | output("Please report this as an issue on GitHub:") |
| 190 | output("<", TEXT_YELLOW, "https://www.github.com/JoshuaS3/lognestmonster/issues/new", RESET, ">") |
| 191 | exit(1) |
| 192 |
|