"""
Copyright (C) 2009  Matt Behrens <askedrelic@gmail.com> http://asktherelic.com

Script for creating a github style punchcard of your bash history.

Requires
-the HISTTIMEFORMAT variable to be set, which includes unix timestamps 
on all bash commands.

-pygooglechart
http://pygooglechart.slowchop.com/

Ideas and most code from:
http://dustin.github.com/2009/01/11/timecard.html
http://github.com/dustin/bindir/blob/master/gitaggregates.py
"""

import time
import sys
import os
import subprocess
from collections import defaultdict

class TimeHistory(object):

    def __init__(self):
        self.h = defaultdict(lambda: 0)

    def add_logs(self):
        #Find users default bash history file
        histfile = open(os.getenv("HOME") + '/.bash_history', 'r')

        for line in histfile:
            #If history line has a timestamp
            if "#" in line:
                #Remove the #
                line = line[1:]
                #Blunt method for ignoring lines that aren't timestamps
                try: 
                    self.h[time.strftime("%w %H", time.localtime(float(line.strip())))] += 1
                except:
                    pass

    def dump(self):
        for h in range(24):
            for d in range(7):
                sys.stderr.write("%02d %d - %s\n"
                                 % (h, d, self.h["%d %02d" % (d, h)]))

    def to_gchart(self):
        from pygooglechart import ScatterChart
        chart = ScatterChart(800, 300, x_range=(-1, 24), y_range=(-1, 7))

        chart.add_data([(h % 24) for h in range(24 * 8)])

        d=[]
        for i in range(8):
            d.extend([i] * 24)
        chart.add_data(d)

        day_names = "Sun Mon Tue Wed Thu Fri Sat".split(" ")
        days = (0, 6, 5, 4, 3, 2, 1)

        sizes=[]
        for d in days:
            sizes.extend([self.h["%d %02d" % (d, h)] for h in range(24)])
        sizes.extend([0] * 24)
        chart.add_data(sizes)

        #Easier to manually set the x label for the 12am/12pm labels 
        chart.set_axis_labels('x', ['|12am|1|2|3|4|5|6|7|8|9|10|11|12pm|1|2|3|4|5|6|7|8|9|10|11|'])
        chart.set_axis_labels('y', [''] + [day_names[n] for n in days] + [''])

        chart.add_marker(1, 1.0, 'o', '333333', 25)
        chart.download('historychart.png')
        #return chart.get_url()

if __name__ == '__main__':
    th = TimeHistory()
    th.add_logs()
    #th.dump()
    th.to_gchart()

@@ -1,12 +1,34 @@
+#!/usr/bin/env python%0A
 %22%22%22%0ACopyrigh
@@ -468,94 +468,137 @@
 %22%22%0A%0A
-import time%0Aimport sys%0Aimport os%0Aimport subprocess%0Afrom collections import defaultdict
+from collections import defaultdict%0Afrom itertools import groupby%0Afrom os.path import expanduser%0Aimport re%0Aimport sys%0Aimport time
 %0A%0Acl
@@ -770,45 +770,31 @@
     
-histfile = open(os.getenv(%22HOME%22) + '
+with open(expanduser('~
 /.ba
@@ -808,35 +808,18 @@
 ory'
+)
 , 'r')
-%0A%0A        for line in
+ as
  his
@@ -841,130 +841,107 @@
     
-#If history line has a timestamp%0A            if %22#%22 in line:%0A                #Remove the #%0A                line = 
+R = re.compile(r'#%5Cd+$');%0A            lines = %5Btime.strftime(%22%25w %25H%22, time.localtime(float(
 line%5B1:%5D
 %0A   
@@ -936,16 +936,21 @@
 line%5B1:%5D
+))) %5C
 %0A       
@@ -962,227 +962,146 @@
     
-#Blunt method for ignoring lines that aren't timestamps%0A                try: %0A                    self.h%5Btime.strftime(%22%25w %25H%22, time.localtime(float(line.strip())))%5D += 1%0A                except:%0A                    pass
+     for line in histfile if R.match(line)%5D%0A            for k, g in groupby(sorted(lines)):%0A                self.h%5Bk%5D += sum(1 for _ in g)
 %0A%0A  

simplify Bash history file process