Welcome, guest | Sign In | My Account | Store | Cart

Tail multiple pidgin IRC logfiles.

Pidgin should be connected to IRC with the channels one wants to tail joined, and it should save logs as text.

The script needs two arguments:

the directory containing the directories with channel logs

a list of channel names, quoted and separated by spaces

Example command:

python pidgin-irctail.py -d ~/.purple/logs/irc/YOUR_IRC_HANDLE@irc.freenode.net -c "#chan1 #chan2 #chan3"

Some text elements are higlighted, and channel names are inserted into the log lines after the time info.

If more than one channel is entered, the output of the logs is merged.

Python, 86 lines
 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
import os 
import sys
import sh
from Queue import Queue
from threading import Thread
from termcolor import colored
from argparse import ArgumentParser
from time import sleep
from errno import EWOULDBLOCK

def highlight(rest_of_line):
    s = rest_of_line
    for x in rest_of_line.split():
        if x.startswith("http"):
            s = s.replace(x,colored(x,'blue',attrs = ['bold']))
    return s

def split_line(line):
    for pos in range(15,len(line)):
        if line[pos] == ' ':
            return line[:13], line[13:pos].strip(), line[pos:].strip()
   
def tail_f(some_file):
    for line in sh.tail("-f", some_file, _iter_noblock=True):
        yield line

def line_gen(basedir,chan):
    subdir = chan+".chat"
    sdpath = os.path.join(basedir,subdir)
    fn = max(x for x in os.listdir(sdpath) if x.endswith(".txt"))
    path = os.path.join(sdpath,fn)
    ch = chan.encode('utf-8')
    for x in tail_f(path):
        if x == EWOULDBLOCK:
            continue
        s = x.encode('utf-8')
        time,name,rest = split_line(s)
        if name[-1] == ':'.encode('utf-8'):
            t = colored(time,'cyan',attrs=['bold'])
            c = colored(ch,'cyan',attrs=['bold'])
            n = colored(name,'red',attrs=['bold'])
            r = highlight(rest)
        else:
            t = colored(time,'cyan')
            c = colored(ch,'cyan')
            n = colored(name,'yellow',attrs=['dark'])
            r = colored(rest,attrs=['dark'])   
        yield ' '.join((t,c,n,r))
    
def consume(q, s):
    while not exitapp:
        q.put(s.next())
        
def merge(iters):
    q = Queue()
    for it in iters:
        t = Thread(target=consume, args=(q, it))
        t.daemon = True
        t.start()
    while True:
        if q.empty():
            sleep(.1)
        else:
            yield q.get()

def run(directory, channels):
    basedir = os.path.expanduser(directory)
    for x in merge(line_gen(basedir,ch) for ch in channels):
        print x
    
def main():
    parser = ArgumentParser(description = 'tail, merge, and colorize pidgin irc text logs')
    parser.add_argument('-d','--directory', 
        help='the directory that has the directories of the chat logs as subdirectories')
    parser.add_argument('-c','--channels', 
        help='a quoted string containing a list of irc channel names separated by spaces')
    args = parser.parse_args()
    run(args.directory, args.channels.split())

exitapp = False
if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        exitapp = True
        sys.exit(0)

Colorizing logfiles seems of limited use because of the many different formats. However there is interesting code that shows how to run multiple nonblocking threads and exit gracefully. Also, people will be able to use this code as a template to colorize logfiles produced by other IRC clients. I wrote this because I wanted to put an old laptop to some good use, now it shows these merged logfiles via an ssh connection while I am interacting with other channels on my other laptop. In case it's not clear: this is live updated "tail -f" style generated output that mirrors what is said on IRC as soon as the logfile is updated by the client, which in case of pidgin is practically immediately.