#!/usr/bin/python
#
# A Cron job that cooks Ganglia gmond XML into an RSS feed.
#
# @Copyright@
# @Copyright@
#
# $Log: cook-news.py,v $
# Revision 1.4  2004/07/16 22:34:36  fds
# Now report the number of nodes in the RSS header.
#
# Revision 1.3  2004/04/14 22:01:48  fds
# Less verbose, quoting special chars in cluster name. New full-disk
# journalist inspired by lodestone.
#
# Revision 1.2  2004/04/13 20:16:05  fds
# The Ganglia RSS news prototype. 2 journalsits: MIA and load.
#
# Revision 1.1  2004/02/12 19:52:24  fds
# Ganglia XML -> RSS cooker.
#
#
# Original author: Federico Sacerdoti (fds@sdsc.edu) 2004.
#

import os
import sys
import rocks.app
import gmon.ganglia
import time
import types
import syslog

class GangliaNews(rocks.app.Application):
	"""Coordinator of news modules (journalists) that scan ganglia
	XML tree daily for any news."""


	def __init__(self, argv):
		rocks.app.Application.__init__(self,argv)
		self.usage_name = 'Ganglia News'
		self.usage_version = '3.3.0'
		self.getopt.l.extend([
			('hello','say hi')
			])

		self.basedir = '/var/ganglia/news'
		self.journalists = {}

		# For use by all journalists
		self.fancynow = time.strftime("%a, %d %b %Y %H:%M:%S %Z")
		self.now = time.localtime()


	def parseArg(self,c):
		rocks.app.Application.parseArg(self,c)
		key,val = c
		if key == '--hello':
			print "Hi there"


	def getTime(self):
		return self.fancynow

	def getLocalTime(self):
		return self.now

	def fullImport(self, name):
		"""Imports all components of a module, from the
		Python language reference."""

		mod = __import__(name)
		components = name.split('.')
		for comp in components[1:]:
			mod = getattr(mod, comp)
		return mod
		
		
	def loadModules(self, path):
		"""Import all the python code in a directory. Path is 
		like gmon.news"""

		info = "ganglia news loading %s: " % path
		
		modules = self.fullImport(path)
		for file in os.listdir(modules.__path__[0]):
			modname, ext = os.path.splitext(file)
			if ext == '.py' and modname != '__init__':
				info = info + modname + " "

				fullmodname = "%s.%s" % (path, modname)
				#print "Importing:", fullmodname
				mod = self.fullImport(fullmodname)

				try:
					initEvents = getattr(mod, "initEvents")
				except AttributeError:
					info += "(no initEvents(), skipping) "
					continue

				# Call the entry point to get a tuple of event
				# classes.
				events = initEvents()

				if type(events) == types.TupleType:
					for event in events:
						self.register(event)
				else:
					# There is only one event in this module.
					self.register(events)

		syslog.syslog(info)
		
		
	def register(self, newsclass):
		"Register a news event."
		
		if type(newsclass) == types.ClassType:
			journalist = newsclass(self)
			name = journalist.name()
			if name:
				self.journalists[name] = journalist
		
		
	def run(self):
		self.ganglia = gmon.ganglia.Ganglia()
		self.ganglia.refresh()
		
		self.loadModules('gmon.news')
		
		header = self.rssheader()
		h = open(os.path.join(self.basedir, 'header.rss'), 'w')
		h.write(header)
		h.close()
		print header

		for j in self.journalists.values():
			j.run()

		footer = self.rssfooter()
		f = open(os.path.join(self.basedir, 'footer.rss'), 'w')
		f.write(footer)
		f.close()
		print footer


	def rssheader(self):
		cluster = self.ganglia.getCluster()
		year = self.getLocalTime()[0]

		s = """<?xml version="1.0"?>
<!-- RSS generated by Rocks Ganglia News Service v%s -->
<rss version="2.0">
 <channel>
  <title>%s Cluster News</title>
  <link>%s</link>
  <description>Noteworthy Ganglia Events for the %s Cluster (%s nodes)
  </description>
  <language>en-us</language>
  <copyright>Copyright %s %s</copyright>
  <pubDate>%s</pubDate>
  <lastBuildDate>%s</lastBuildDate>
  <generator>Rocks Ganglia Cooker</generator>
""" \
		% (self.usage_version, 
		cluster.getName(),
		cluster.getUrl(),
		cluster.getName(),
		self.ganglia.clusterSize(),
		year, cluster.getOwner(),
		self.getTime(),
		self.getTime())

		return s


	def rssfooter(self):
		s = ' </channel>\n' \
		  + '</rss>\n'

		return s



# Main
app = GangliaNews(sys.argv)
app.parseArgs()
app.run()
