#!/usr/bin/python
###############################################################################
# zapplet - A tray applet for interfacing with Zenoss
# Copyright (C) 2008 Nathaniel McCallum <nathaniel@natemccallum.com>
# 
# 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.1 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 Street, Fifth Floor, Boston, MA  02110-1301 USA
###############################################################################

import time
import traceback
import sys

import gtk
import gobject

import zapplet.eventapplet
import zapplet.event
import zapplet.os
import zapplet.prefs

class AppletController(object):
	
	def __init__(self):
		self.applets = {}
		self.updates = {}
		
	def _get_async(self, server, details=False):
		def async(results, errorinfo):
				if errorinfo:
					tb = "".join(traceback.format_exception(*errorinfo))
					self.applets[server].set_from_stock(gtk.STOCK_DIALOG_ERROR)
					self.applets[server].set_tooltip(tb)
					sys.stderr.write(tb)
					return
				
				if hasattr(results, "__iter__") and len(results) == 2:
					summary, events = results
					self.applets[server].set_events(events)
					self.applets[server].set_from_pixbuf(summary.get_pixbuf(24, 24))
					self.applets[server].set_tooltip(summary.summary)
					self.updates[server] = time.time()
		
		return async
		
	def on_update(self):
		osf     = zapplet.os.OSFunctions.factory()
		servers = set(filter(lambda s: osf.get(s, "hostname"), osf.listServers()))
		
		# Remove applets that are no longer configured
		for server in set(self.applets.keys()).difference(servers):
			self.applets[server].set_visible(False)
			del self.applets[server]
			del self.updates[server]
			
		# Add our new applets
		for server in servers.difference(set(self.applets.keys())):
			self.applets[server] = zapplet.eventapplet.EventApplet(server)
			self.updates[server] = 0
			self.applets[server].set_from_stock(gtk.STOCK_REFRESH)
			self.applets[server].set_visible(True)
		
		# Pop up preferences if no servers are configured
		if len(self.applets) < 1:
			pw = zapplet.prefs.PreferencesWindow.factory()
			pw.show_all()
		
		# Update all the applets
		for server in servers:
			if time.time() - self.updates[server] > osf.get(server, "interval"):
				self.applets[server].set_from_stock(gtk.STOCK_REFRESH)
				zapplet.event.Event.load_events_from_server(server, self._get_async(server))
			
		return True

if __name__ == "__main__":
	# Initialize threads
	gtk.gdk.threads_init()
	
	# Create our controller, do the initial update and schedule periodic updates
	ac = AppletController()
	ac.on_update()
	gobject.timeout_add_seconds(60, ac.on_update)
	
	# Enter the mainloop
	gtk.gdk.threads_enter()
	gtk.main()
	gtk.gdk.threads_leave()
