Source

openhaushalt / openhaushalt / lib / openhaushaltmap.py

#! /usr/bin/env python
# fileencoding: utf8
#
# The MIT License
# 
# Copyright (c) 2011 Marius Stuebs <mquintus@tharos-net.de>
# 
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# 
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
'''
Die Klasse "Openhaushaltmap"
nimmt einen json-Blob an und wandelt ihn in einen
Baum um (siehe Datei squaremap.py).

Urspruenglich kann der json-Blob aus der index.html
des Projekts openhaushalt extrahiert werden.
Die entsprechende Funktionalitaet ist deaktiviert
und bei der Initialisierung der Klasse wird
ein json-Blob verlangt.

@author Marius Stuebs <mquintus@tharos-net.de
@date 2011-01-31
'''

import sys 
import getopt
import json, urllib, re
#from getDataFromHtml import DataFromHtmlJsonGetter
from squaremap import Squaremap, Node

class Openhaushaltmap:
	def __init__(self, data, width, height, html=''):
		model = self.get_model(data)
		## Das Problem, welches auftritt, wenn nur 1 Posten angezeigt wird,
		## ergab sich erstmals auf http://bund.offenerhaushalt.de/140353999-032.html
		## Dieses Skript wertet lediglich die Kinder aus, aber nicht 
		## den allumfassenden Posten. Dieser wird ignoriert.
		## Workaround: Den Posten sich selbst als Kind hinzufügen.
		if len(model.childnodes) == 0:
			model = Node(model.name, model.size, [model], model.color, model.link)
		##
		# Nur weitermachen, wenn Daten vorhanden sind.
		if len(model.childnodes) > 0:
			self.sq = Squaremap(model, width, height)
			self.sq.node2coord()
			self.ausgabe = self.sq.printNodes(html)
		else:
			self.ausgabe = ''
			

	def get_model( self, data ):
		nodes = []
		name = self.name_method(data)
		size = self.size_method(data)
		for child in data['children']:
			nodes.append( self.get_model( child ))
		#if size > 0:
		#	nodes.append( Node( name, size, (), self.color_method(data), self.link_method(data) ) )
		#return Node( name, sum([x.size for x in nodes]), nodes, self.color_method(data), self.link_method(data) )
		return Node( name, size, nodes, self.color_method(data), self.link_method(data) )
	def size_method(self, node):
		   try:
		      return (float)(node['data']['$area'])
		   except:
		      return 0.0
	def link_method(self, node):
		   try:
		      return node['data']['link']
		   except:
		      return ""
	def name_method(self, node):
		   try:
		      return node['data']['title']
		   except:
		      return "unknown"
	def color_method(self, data):
	   try:
	      return data['data']['$color']
	   except:
	      return ""

def usage():
	usage = '''Usage {0} '{1}'
or:   {0} '{1}32.html'
or:   {0} 'haushalt2010.html'
or:   {0} '{1}14.html?reference_year=2006' '''.format(sys.argv[0], 'http://bund.offenerhaushalt.de/')
	print usage
	sys.exit(0)

def main():
	"""Hier soll die Möglichkeit geschaffen werden, einen beliebigen Baum
	dynamisch einzubinden"""
	if not len(sys.argv) == 2:
		usage()
		#dataUrl = 'http://bund.offenerhaushalt.de/'
	else: 
		dataUrl = sys.argv[1]

	try: 
		#print dataUrl
		file = urllib.urlopen(dataUrl)
		data = file.read()
	except:
		print "Verbindungsaufbau nach %s gescheitert."	% dataUrl
		sys.exit(1)		

#	if True:
	try:
		#print data
		#return
		regExp = 'var json = (.*);'
		data = re.search(regExp, data)
		data = data.group(1)
		data = json.loads(data)
		openMap = Openhaushaltmap(data, 900, 600, 'html')
		print openMap.ausgabe.encode("utf-8")
#	else:
	except:
		print "Erzeugen der Treemap gescheitert."
		sys.exit(1)		

if __name__ == "__main__":
    main()