aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/weechat-log-colorize
blob: 695d88832fd96e6e3681db6611232674a47f5901 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/usr/bin/env python3
# Copyright 2019 vg
# SPDX-License-Identifier: MIT

'''
Description of program.

Usage: weechat-log-colorize [options] [--] [FILENAME...]
       weechat-log-colorize -h|--help

Options:
  -h, --help  Display this help message
'''


### standard modules
import collections
import datetime
import os
import subprocess
import sys
import textwrap
import time
import zlib
### external modules
import docopt
import colorama.ansi as ansi
from colorama.ansi import AnsiFore as ansif
from colorama.ansi import AnsiStyle as ansis

# This script is not compatible below python3.7.2, always abort (not in main
# since the syntax itself can cause the script to fail later inconveniently).
assert sys.hexversion >= 0x03070200


nick_color_table = (
        ansif.YELLOW,
        ansif.RED,
        ansif.BLUE,
        ansif.GREEN,
        ansif.MAGENTA,
        )


def c(*ansicodes):
    return f'{ansi.CSI}{";".join(str(x) for x in ansicodes)}m'


def colornickname(nickname):
    hashed_nick = zlib.crc32(nickname.encode('utf8'))
    color = nick_color_table[hashed_nick % len(nick_color_table)]
    return f'{c(color)}{nickname}{c(0)}'


def colortime(thetime):
    return f'{c(ansif.LIGHTWHITE_EX)}{thetime.strftime("%T")}{c(0)}'



def parse_log(fh):

    old_line_date = datetime.datetime(1, 1, 1)
    total_size = 80
    left_size = 21
    right_size = total_size - left_size

    for num, line in enumerate(fh):
        # don't strip it at line level: if msg is empty, last \t separator
        # gets trimmed and there is not enough values to unpack.
        try:
            s_date, s_nickname, s_msg = line.split('\t', maxsplit=2)
            s_msg = s_msg.strip()
        except ValueError:
            print(f'line {num+1} is ill-formated, fix it and try-again: {line}',
                    file=sys.stderr)
            raise
        line_date = datetime.datetime.strptime(s_date, '%Y-%m-%d %H:%M:%S')

        if line_date.date() != old_line_date.date():
            old_line_date = line_date
            print('_'*total_size)
            print(f'date: {c(ansif.GREEN)}{line_date.strftime("%F %T")}{c(0)}')
            print('-'*total_size)

        if not s_msg:
            continue
        wrapped_msg = textwrap.wrap(s_msg, width=right_size-2)
        print(f'{colortime(line_date)} {colornickname(s_nickname):>20s}:'
                f' {wrapped_msg[0]}')
        for wrapped_line in wrapped_msg[1:]:
            print(' '*left_size, wrapped_line)


def main():
    'function called only when script invoked directly on command line'
    args = docopt.docopt(__doc__)

    #with open(args[FILENAME], encoding='utf8') as fh:
    parse_log(sys.stdin)


main()