Livejournal Comment Stats

There are plenty of LJ tools around, but I couldn't find them one night and the sourceforge one didn't work for me (aside from it using a disgusting UI, clearly writting by a Windows prorammer), so I decided to write my own one.

Background

Everyone likes to see how popular they are!

Method

After reading Livejournal's explanation of the export_comments URL, I used Python's built-in Sax module to parse over the results.

Solution

I'm aware that this solution's interface isn't particularly pretty, but at least it's command-line. It should also work in the Windows Command Prompt. The HTML outputted works in Livejournal with Firefox, Opera, Konqueror, Links, and Internet Explorer (ideally 7.0)

Generating the stats is easy:
  1. Make sure you have Python installed from python.org
  2. Unzip the downloaded LJ Stat tool wherever you like.
  3. Log into Livejournal and then open livejournal.com/export_comments.bml?get=comment_meta&startid=0
  4. Save this file (File -> Save Page As, or similar) to your hard drive, in the same place as you unzipped the LJ Stat generator
  5. Open up a command prompt and cd to the directory you put the Stat Generator in.
  6. Type python ljcommstats.py input.xml username top_n > stats.txt into the command prompt, where input.xml is the file you downloaded from livejournal, username is your Livejournal username, and top_n is the maximum length of the stats (eg, only show top 10 posters).
  7. A new file called stats.txt will be generated. Open this in Notepad, and copy the contents of it into your Livejournal.
The program generates code similar to this:

		.
		.
		.
 
527
]]>
... which renders like this:
 
527 user1
 
361 user2
 
258 user3

Download

Click here to download the source code, shown below. This program is released under the GNU GPL, a copy of which is provided in the zip file.
#!/usr/bin/env python

# Copyright (c) 2006 Nick Murdoch. All rights reserved.
# http://nivan.net/

#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

import xml.parsers.expat
import sys
import operator

counts = {} # {userid: count, userid: count, ...}
usermap = {0: None} # {userid: username, userid: username, ...}

def start_element(name, attrs):
	if name == "comment" and attrs.get('state') != 'D':
		if 'posterid' not in attrs:
			posterid = 0
		else:
			posterid = int(attrs['posterid'])
		if posterid not in counts:
			counts[posterid] = 1
		else:
			counts[posterid] += 1
	
	if name == "usermap":
		usermap[int(attrs['id'])] = attrs['user']


def end_element(name):
	pass
def char_data(data):
	pass


if __name__ == "__main__":
	try:
		input = sys.argv[1]
	except:
		sys.exit("Usage: %s input.xml [username] [top_n]\n\nYou can get the input xml from http://www.livejournal.com/export_comments.bml?get=comment_meta&startid=0" % sys.argv[0])
	
	input = open(input, 'r')

	p = xml.parsers.expat.ParserCreate()
	p.StartElementHandler = start_element
	p.EndElementHandler = end_element
	p.CharacterDataHandler = char_data

	p.ParseFile(input)
	# This populates counts and usermap
	
	comments = {} # {username: count, ...}
	for uid in counts:
		comments[usermap[uid]] = counts[uid]
	
	if len(sys.argv) > 2 and sys.argv[2] in comments:
		del comments[sys.argv[2]]

	comments = comments.items()
	comments.sort(key=operator.itemgetter(1), reverse=True)

	max = float(comments[0][1])
	width = 300.

	top_n = None
	if len(sys.argv) > 3:
		try: top_n = int(sys.argv[3])
		except: pass

	print ""
	for tup in comments[:top_n]:
		print "\t"
		print "\t\t" % (width * tup[1] / max)
		print "\t\t" % tup[1]
		if tup[0]:
			print "\t\t" % tup[0]
		else:
			 print "\t\t"
		print "\t"
	print "
 
%iAnonymous

LJ Comment Stat Generator by . Download it here.
"



Last Modified: Tuesday, 20-Mar-2007 14:43:35 GMT