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
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.
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.