#!/usr/bin/env python

#    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 3 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, see <http://www.gnu.org/licenses/>.

#DiskusageScreenlet (c) Whise <helder.fraga@hotmail.com>


import screenlets
from screenlets.options import FloatOption, BoolOption, StringOption, ColorOption, FontOption
from screenlets.options import create_option_from_node
import cairo
import pango
import subprocess
import re
import gobject
import gtk
#use gettext for translation
import gettext

_ = screenlets.utils.get_translator(__file__)

def tdoc(obj):
	obj.__doc__ = _(obj.__doc__)
	return obj

@tdoc
class DiskusageScreenlet(screenlets.Screenlet):
	"""A Diskusage Screenlet by Helder Fraga based on Jonathan Rauprich Disk screenlet."""
	
	# meta-info
	__name__ = 'DiskusageScreenlet'
	__version__ = '0.4.1'
	__author__ = 'Helder Fraga'
	__desc__ = __doc__

	__timeout = None
	p_layout = None	
	# settings
	update_interval = 20.0
	mount_point = '/'
	font = 'FreeSans'
	font_color = (1,1,1, 0.8)
	background_color = (0,0,0, 0.1)
	red_bar = True
	use_gtk = False
	
	def __init__(self, **keyword_args):
		"""Constructor"""
		screenlets.Screenlet.__init__(self, width=220, height=50,uses_theme=True, **keyword_args)
		
		self.__timeout = None
		self.theme_name = 'default'
		
		# add options
		self.add_options_group(_('Disk-Usage'), _('Disk-Usage specific options'))
		self.add_option(FloatOption(_('Disk-Usage'), 'update_interval', 
			20.0, _('Update-Interval'), 
			_('The interval for updating the Disk-Usage (in seconds) ...'),
			min=1.0, max=60.0))
		self.add_option(StringOption(_('Disk-Usage'), 'mount_point', 
			'/', _('Mount Point'), 
			_('Enter the Mountpoint for the Device you want to show')), 
			realtime=False)
		self.add_option(FontOption(_('Disk-Usage'),'font', 
			_('FreeSans'), _('Font'), 
			'font'))
		self.add_option(ColorOption(_('Disk-Usage'),'font_color', 
			(1, 1, 1, 0.8), _('Text color'), 'font_color'))
		self.add_option(ColorOption(_('Disk-Usage'),'background_color', 
			(0, 0, 0, 0.1), _('Back color(only with default theme)'), 'only works with default theme'))
		self.add_option(BoolOption(_('Disk-Usage'),'red_bar', 
			True, _('Show red bar on 90 percent'), 
			'red_bar'))	
		self.add_option(BoolOption(_('Disk-Usage'),'use_gtk', 
			False, _('Use gtk icon theme'), 
			'use_gtk'))
		
		# create the right click menu
		self.add_default_menuitems()
		
		# init the timeout function
		self.update_interval = self.update_interval
		
	# attribute-"setter", handles setting of attributes
	def __setattr__(self, name, value):
		# call Screenlet.__setattr__ in baseclass (ESSENTIAL!!!!)
		screenlets.Screenlet.__setattr__(self, name, value)
		# check for this Screenlet's attributes, we are interested in:
		if name == "update_interval":
			if value > 0:
				self.__dict__['update_interval'] = value
				if self.__timeout:
					gobject.source_remove(self.__timeout)
				self.__timeout = gobject.timeout_add(int(value * 1000), self.update_graph)
			else:
				# TODO: raise exception!!!
				self.__dict__['update_interval'] = 1
	
	def get_drive_info(self):
		"""Get a list of dictionaries with device information"""
		proc = subprocess.Popen('df -h -a -P | grep "^/dev\|/root.disk" ', shell='true', stdout=subprocess.PIPE)
		sdevs = proc.stdout.read().rsplit('\n')
		sdevs.pop()
		for stdev in sdevs:
			sdev = re.findall("(\S*)\s*", stdev)
			dev = {
				'device': sdev[0],
				'size': sdev[1],
				'used': sdev[2],
				'free': sdev[3],
				'quota': sdev[4],
				'mount': sdev[5]
			}
			if dev['mount'] == self.mount_point:
				#print  sdev[3] + sdev[4] + sdev[5]
				return dev
		return None
	
	def update_graph(self):
		"""Timeout function"""
		self.redraw_canvas()
		return True
	
	def on_draw(self, ctx):
		# get load
		info= self.get_drive_info()
		try:
			load = int(info['quota'].replace("%",""))
		except:
			load = 0
		if load > 99:
			load = 99
		elif load < 0:
			load=0
		# set size
		#ctx.scale(self.width/100.0, self.height/100.0)
		ctx.scale(self.scale, self.scale)
		ctx.set_operator(cairo.OPERATOR_OVER)
		# draw bg (if theme available)
		if self.theme:
			if self.theme_name == 'default':
				ctx.set_source_rgba(*self.background_color)
				self.draw_rounded_rectangle(ctx,20,0,8,200,50)
			self.theme.render(ctx,'disk-bg')
		
		if len(str(load))==1:
			load = "0" + str(load)
		ctx.set_source_rgba(*self.font_color)
		
		# draw glass (if theme available)
		if self.theme:
			#self.theme['cpumeter-graph-bg.svg'].render_cairo(ctx)
			w = (float(load) / 100.0) * 220.0
			ctx.save()
			ctx.rectangle(0, 0, w, 50)
			#ctx.rectangle(20, 15+(70-h), 60, h)
			ctx.translate(25, 35)
			ctx.clip()
			#ctx.new_path()
			
			if load > 90 and self.red_bar:
				self.theme.render(ctx,'red')
			else:
				self.theme.render(ctx,'blue')
			ctx.restore()
			try:
				self.draw_text(ctx,"<b>" + info['mount']  + "</b>\n <b>" +   info['free'] + "</b> free of <b>" + info['size'] + " - " + info['quota']+"</b>", 60, 6, self.font.split(' ')[0], 10,  self.width,pango.ALIGN_LEFT)
			except:
				self.draw_text(ctx,self.mount_point + "\nNot Mounted", 60, 6, self.font.split(' ')[0], 10,  self.width,pango.ALIGN_LEFT)
			
			self.gtk = True
			if self.use_gtk:
				try:
					ico = 'drive-harddisk'
					icontheme = gtk.icon_theme_get_default()
					image = icontheme.load_icon (ico,56,56)
					self.draw_icon(ctx,0,0,ico,56,48)
				except:self.theme.render(ctx, 'drive2')
			else:
				self.theme.render(ctx, 'drive2')
		
	def on_draw_shape(self,ctx):
		self.draw_rounded_rectangle(ctx,20,0,8,200,50)
		self.on_draw(ctx)
	
# If the program is run directly or passed as an argument to the python
# interpreter then create a Screenlet instance and show it
if __name__ == "__main__":
	import screenlets.session
	screenlets.session.create_session(DiskusageScreenlet)
