#!/usr/bin/env python
# -*- coding: utf-8 -*-
# linHDD.py version 0.9
# last modified 09/03/2009
##############################################################################
# c2005-2009 by Paul Sherman <psherma1@rochester.rr.com>	             #
# http://www.pcbypaul.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 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, write to the Free Software		     #
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.#
##############################################################################

import sys, os, time, commands, string, shutil, re, signal, subprocess
import pygtk
import gobject

import gettext 
APP="linHDD"  
DIR="./locale"  
gettext.textdomain(APP)  
gettext.bindtextdomain(APP, DIR)
_ = gettext.gettext

if gobject.pygtk_version < (2,5,96):
    print >>sys.stderr, _("pyGTK version 2.6 or greater is required for this application")
    raise SystemExit
import gtk
try:
	import pango
except:
	print >> sys.stderr, _("Cannot load Pango")
	raise SystemExit

def error_msg(msg):

	dlg = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, msg)
	dlg.set_position(gtk.WIN_POS_CENTER)
	response = dlg.run()
	dlg.destroy()
	raise SystemExit
	
youAre = os.environ['USER']
if youAre != "root":
	error_msg(_('You need to be root to run this utility'))
if not len(commands.getoutput('type -path df')): 
	error_msg(_('Cannot run linHDD without the df utility'))
if not len(commands.getoutput('type -path cfdisk')): 
	error_msg(_('Cannot run linHDD without the cfdisk utility'))
if not len(commands.getoutput('type -path hdparm')): 
	error_msg(_('Cannot run linHDD without the hdparm utility'))
if not len(commands.getoutput('type -path abs_fdisk')):
	error_msg(_('Cannot run linHDD without abs_fdisk')) 

rootdrive = "/dev/" + commands.getoutput('readlink /dev/root') 

hdd_xpm = [
"42 44 17 1",
" 	g None",
".	g #FFFFFF",
"+	g #0A0A0A",
"@	g #161616",
"#	g #202020",
"$	g #404040",
"%	g #505050",
"&	g #6E6E6E",
"*	g #7D7D7D",
"=	g #2E2E2E",
"-	g #606060",
";	g #9C9C9C",
">	g #C0C0C0",
",	g #C8C8C8",
"'	g #D4D4D4",
")	g #8D8D8D",
"!	g #ACACAC",
"..........................................",
".+++++++++++++++++@@@@@@+++++++++++++++++.",
".++++++++++++++#$%&****&$@+++++++++++++++.",
".+++++++++++@=-;>,,'''',)#+++++++++++++++.",
".++++++++++#&>,''',,,,,,*@+++++++++++++++.",
".++++++++@%!''',>>,>>>>>-#%$#++++++++++++.",
".+++++++#=)'',>>>>>>>>>!$%>>)%#++++++++++.",
".++++++=**-!,>>>>>>>>>>;$&'''>)$@++++++++.",
".+++++=;'>--,,>>>>>>>>>)$;'>,,,!-@++++@@@.",
".++++=;'',!$*>>>>>>>>>,&$>,>>,,',*#+@@@@@.",
".+++#)'',,,;$;,>>>>>>>>--,,>>>>>,,*#@@@@@.",
".+++-''>>>,,&%!>>>>>>>>$)',>>>>>,,>&@@@@@.",
".++=!',>>>>,>-->,>>>>>!$!,,>>>>>>>,>%@@@@.",
".++*',>>>>>>>!%*>>>>>>)%>,>>>>>>>>>,!=+@@.",
".+=!',>>>>>>>>)%;,>>>,*&',>>>>>>>>>>,&@@@.",
".@-,,>>>>>>>>,>&%!,>>>%;'>>>>>>>>>>>>!=+@.",
".#)',>>>>>>>>>,>-->>>!%>,>>>>>>>>>>>>>-@@.",
".=!'>>>>>>>>>>>,;%*,,;-,,>>>>>>>>>>>>,)=@.",
".$>,,>>>>>>>>>>,,)$!,)*',>>>>>>>>>>>>,!$@.",
".%,,>>>>>>>>>>>>>>&%!*;',>>>>>>>>>>>>>!%@.",
".-'>>>>>>>>>>>>>>,>--->,>>>>>>>>>>>>>>>&#.",
".%!;;;;;;;;;;;;;;;;&#->,>>>>>>>>>>>>>>>&#.",
".@=====$$$$%%%%--&&&-)',>>>>>>>>>>>>>>>*#.",
".++#-**));;!!!>>>>>,,',>>>>>>>>>>>>>>>>*#.",
".++$,''''''''',,',',,,,>>>>>>>>>>>>>>>>&=.",
".@+$>',,,,,,>>,,>,>>>>>>>>>>>>>>>>>>>>>&#.",
".@@=!,,,>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>!%#.",
".@@@)'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>!$#.",
".@@@-,>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>)=#.",
".@@+$!,>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>&##.",
".@@@@),>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;$##.",
".@@@@%!,>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*=##.",
".+@@@#*>,>>>>>>>>>>>>>>>>>>>>>>>>>>>;$#=#.",
".@@@@@$;>>>>>>>>>>>>>>>>>>>>>>>>>>,!-###=.",
".@@@@@#%>>>>>>>>>>>>>>>>>>>>>>>>>>>*===#=.",
".@@@##@@->>>>>>>>>>>>>>>>>>>>>>>>>*$#=#==.",
".##@@@#@#-!>>>>>>>>>>>>>>>>>>>>>!)==#==#=.",
".@@@#@@#@=%;>,>>>>>>>>>>>>>>>>>!&$#==#===.",
".@#@@#@####$*>>>>>>>>>>>>>>>,>;%===#=====.",
".#@#####@####$*!>>>>>>>>>>>!)-===#=======.",
".#########@####$-);;!!!!;)&%$=#==========.",
".@##@#@#@########=$$%%%$$===#============.",
".#@##################========#===========.",
".........................................."]

icon_xpm = [
"16 16 248 2",
"  	c None",
". 	c #DABC93",
"+ 	c #D8BB8B",
"@ 	c #DEC18D",
"# 	c #E1C495",
"$ 	c #E2C29A",
"% 	c #F0CFAD",
"& 	c #EECDAB",
"* 	c #ECCCA5",
"= 	c #EED1A0",
"- 	c #F4D9A3",
"; 	c #F4D9A1",
"> 	c #FFE6B4",
", 	c #F9DCB1",
"' 	c #E6CEAC",
") 	c #776854",
"! 	c #D1AF83",
"~ 	c #D1B37E",
"{ 	c #CFB27D",
"] 	c #D7BD8A",
"^ 	c #DCC396",
"/ 	c #D9BE9D",
"( 	c #CDB396",
"_ 	c #D3B79C",
": 	c #E1C7A6",
"< 	c #ECD3A7",
"[ 	c #E5CC99",
"} 	c #F1D5A1",
"| 	c #F1D2A2",
"1 	c #F5D3AA",
"2 	c #F7DBBC",
"3 	c #AF9E88",
"4 	c #C8A37C",
"5 	c #CDB07F",
"6 	c #C8AF7D",
"7 	c #C4AC80",
"8 	c #BCA783",
"9 	c #7F6D52",
"0 	c #867461",
"a 	c #806C5B",
"b 	c #8E7B64",
"c 	c #D0BC9A",
"d 	c #DEC9A0",
"e 	c #E4C9A0",
"f 	c #EDCFA7",
"g 	c #F0CCAD",
"h 	c #EFD1BA",
"i 	c #D0BEAC",
"j 	c #CCA880",
"k 	c #C7A87C",
"l 	c #C4AA7F",
"m 	c #C2AD8A",
"n 	c #7A694B",
"o 	c #675946",
"p 	c #988D82",
"q 	c #D0C6B8",
"r 	c #8F826F",
"s 	c #8C7A5D",
"t 	c #D5C09F",
"u 	c #D9BE9C",
"v 	c #DEBF9C",
"w 	c #ECC9A7",
"x 	c #E5C6A9",
"y 	c #E0CDB7",
"z 	c #CCA97D",
"A 	c #D0B085",
"B 	c #C3A885",
"C 	c #AF987D",
"D 	c #9D8E7C",
"E 	c #9F968A",
"F 	c #686457",
"G 	c #8A8675",
"H 	c #B5AD98",
"I 	c #7B694F",
"J 	c #CAB498",
"K 	c #D2B595",
"L 	c #DABA94",
"M 	c #E0BE90",
"N 	c #E0C296",
"O 	c #DDCBAC",
"P 	c #D1AD7D",
"Q 	c #CAA77B",
"R 	c #C9AC87",
"S 	c #B2997F",
"T 	c #A89685",
"U 	c #F3EBDF",
"V 	c #908E7F",
"W 	c #686752",
"X 	c #7D755F",
"Y 	c #7F6E53",
"Z 	c #C2AB8D",
"` 	c #D0B18F",
" .	c #CDAA7F",
"..	c #DBB785",
"+.	c #D5B785",
"@.	c #CCBA98",
"#.	c #CEAB76",
"$.	c #D5AF7F",
"%.	c #CFAC82",
"&.	c #C6A886",
"*.	c #766145",
"=.	c #DAD1BD",
"-.	c #E0DDCB",
";.	c #8A8673",
">.	c #6D644D",
",.	c #7D694B",
"'.	c #CCAF8D",
").	c #D0AA7D",
"!.	c #D2AC7D",
"~.	c #CDAF83",
"{.	c #CCBA9A",
"].	c #D3B17A",
"^.	c #D7B47F",
"/.	c #D3B280",
"(.	c #CCAD82",
"_.	c #BBA57D",
":.	c #766646",
"<.	c #90846B",
"[.	c #8E826D",
"}.	c #7E6D57",
"|.	c #B2997E",
"1.	c #C7A785",
"2.	c #CAA677",
"3.	c #CBA778",
"4.	c #C9A983",
"5.	c #B19F82",
"6.	c #D8BA84",
"7.	c #D5B682",
"8.	c #D3B580",
"9.	c #D5B882",
"0.	c #CCB27E",
"a.	c #C3AB7D",
"b.	c #BAA07C",
"c.	c #B69A82",
"d.	c #B49882",
"e.	c #93745B",
"f.	c #C7A98B",
"g.	c #C9AA80",
"h.	c #CEAF82",
"i.	c #C2A87F",
"j.	c #9E8D73",
"k.	c #DFC693",
"l.	c #D7BA85",
"m.	c #DCBE88",
"n.	c #D8BC83",
"o.	c #D6BD8E",
"p.	c #C3A983",
"q.	c #9A7D60",
"r.	c #77583F",
"s.	c #9E7F60",
"t.	c #CCAC88",
"u.	c #CBAC7F",
"v.	c #CAAF80",
"w.	c #C9AC83",
"x.	c #BEA786",
"y.	c #756650",
"z.	c #E4CC9C",
"A.	c #E9CB97",
"B.	c #DEBD8A",
"C.	c #DEC08C",
"D.	c #D9BE90",
"E.	c #B09A75",
"F.	c #7B6948",
"G.	c #7B684B",
"H.	c #846E4B",
"I.	c #CCB184",
"J.	c #D0B27C",
"K.	c #CCAF7E",
"L.	c #C8AB8D",
"M.	c #937E67",
"N.	c #7C6E5E",
"O.	c #9D8761",
"P.	c #E5CCA2",
"Q.	c #ECD1A6",
"R.	c #D3B88C",
"S.	c #94784F",
"T.	c #8C7653",
"U.	c #B5A584",
"V.	c #75643F",
"W.	c #C3B387",
"X.	c #D3BC85",
"Y.	c #CDB47A",
"Z.	c #D1B782",
"`.	c #CDB58A",
" +	c #A59077",
".+	c #736253",
"++	c #857C6F",
"@+	c #746658",
"#+	c #8B7A61",
"$+	c #AB997C",
"%+	c #7A6441",
"&+	c #A28B67",
"*+	c #C3AA86",
"=+	c #7E6539",
"-+	c #C4AD7B",
";+	c #D8C48D",
">+	c #D3C185",
",+	c #CEBF88",
"'+	c #C8BB8E",
")+	c #938666",
"!+	c #6B604C",
"~+	c #847A6F",
"{+	c #7F7B70",
"]+	c #7C7468",
"^+	c #675E48",
"/+	c #857759",
"(+	c #BCAB8B",
"_+	c #C3B18F",
":+	c #B7A27D",
"<+	c #E0CDA1",
"[+	c #E0D0A1",
"}+	c #CFC193",
"|+	c #9D9168",
"1+	c #716649",
"2+	c #716954",
"3+	c #807C6F",
"4+	c #7D7A71",
"5+	c #787359",
"6+	c #ABA27A",
"7+	c #C3B687",
"8+	c #BFB283",
"9+	c #90855B",
"0+	c #685F44",
"a+	c #867E69",
"b+	c #8A8370",
"c+	c #706856",
"d+	c #6D5F4F",
"e+	c #78685B",
"f+	c #7B6C62",
"g+	c #7B706B",
"h+	c #7B7771",
"i+	c #75746E",
"j+	c #767457",
"k+	c #AAA37B",
"l+	c #CCC295",
"m+	c #A3986F",
"n+	c #6B6241",
"o+	c #7F7868",
"p+	c #757169",
"q+	c #6E6D68",
"r+	c #7B7571",
"s+	c #7B6E6C",
"t+	c #7A6968",
"u+	c #7F7370",
"v+	c #7D7470",
"w+	c #717168",
"x+	c #73746B",
"y+	c #74736E",
". + @ @ # $ % & * = - ; > , ' ) ",
"! ~ { ] ^ / ( _ : < [ } | 1 2 3 ",
"4 5 6 7 8 9 0 a b c d e f g h i ",
"j k l m n o p q r s t u v w x y ",
"z A B C D E F G H I J K L M N O ",
"P Q R S T U V W X Y Z `  ...+.@.",
"#.$.%.&.*.=.-.;.>.,.'.4 ).!.~.{.",
"].^./.(._.:.<.[.}.|.1.%.2.3.4.5.",
"6.7.8.9.0.a.b.c.d.e.f.g.h.h.i.j.",
"k.l.m.n.9.o.p.q.r.s.t.u.v.w.x.y.",
"z.A.B.C.D.E.F.G.H.I.~ J.K.L.M.N.",
"O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +.+++",
"@+#+$+%+&+*+=+-+;+>+,+'+)+!+~+{+",
"]+^+/+(+_+H.:+<+[+}+|+1+2+3+4+4+",
"5+6+7+8+9+0+a+b+c+d+e+f+g+h+i+h+",
"j+k+l+m+n+o+p+q+r+s+t+u+v+w+x+y+"]

class DriveWin:

	def info(self, message):
		box = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, message)
		box.set_position(gtk.WIN_POS_CENTER)
		box.set_title(_('Information'))
		box.run()
		box.destroy()	
		
		
	def destroy_cb(self, widget, main_window):
		main_window.hide()
		gtk.main_quit()


	def get_free(self, prt):
		myline = ""
		myperc = ""
		
		if prt == rootdrive:
			prt = "/dev/root"
		
		r = commands.getoutput("df -P")
		if len(r):
			r1 = string.split(r, "\n")
			for l in r1:
				if re.search(prt, l):
					myline = l
					break
			if len(myline):
				r2 = string.split(myline, " ")
				for l in r2:
					if re.search("%", l):
						myperc = l
						break
				return myperc
				
				
	def get_prt_lst(self, drv):	
		self.prt_lst = []
		prts_raw = commands.getoutput('abs_fdisk -l %s' % drv)
		prt_lines = prts_raw.split("\n")
		for l in prt_lines:
			if re.search(drv, l):
				if not re.search("swap", l):
					d = l.split(" ")[0]
					if d != "Disk":
						self.prt_lst.append(d)
		return self.prt_lst


	def get_drives(self):
		drives = []
		for ide_dev in "ide0", "ide1":
			for disk_dev in "hda", "hdb", "hdc", "hdd", "hde", "hdf", "hdg", "hdh":
				if commands.getoutput('cat /proc/ide/%s/%s/media' % (ide_dev, disk_dev))  == "disk":
					drives.append(disk_dev)	
			for disk_dev in "sda", "sdb", "sdc", "sdd", "sde", "sdf", "sdg", "sdh":
				if commands.getoutput('abs_fdisk -l | grep Disk | grep %s ' % (disk_dev)):
					drives.append(disk_dev)						
					
		return drives
	
		
	def change_drive(self, cb):
		drv = cb.get_active_text()
		self.d1 = self.get_params(drv)

		self.prt_box.remove(self.cb_part)
		self.cb_part = gtk.combo_box_new_text()
		plist = self.get_prt_lst(drv)
		for item in plist:
			self.cb_part.append_text(item)
		self.cb_part.set_active(0)			
		self.prt_box.pack_start(self.cb_part, False, False, 0)	
		self.cb_part.connect('changed', self.change_part)
		self.cb_part.show()
		b, e = self.txt.get_bounds()
		self.txt.delete(b, e)
		self.txt.insert_at_cursor(self.d1)
		####################################################################
		act = self.cb_part.get_active_text()
		if act == None:
			if os.getuid() == 0:
				self.btn_part.set_sensitive(True)
				self.cb_format.set_sensitive(False)
				self.tog_check.set_sensitive(False)
			self.perc = "0%"
			self.frac = 0
			self.prg1.set_fraction(0)
			self.prg1.set_text(_('%s  does not appear to be Partitioned') % self.combo.get_active_text())
		else:
			self.reset_btns()
			try:
				self.perc = self.get_free(plist[0])
				self.frac = float(self.perc.rstrip("%")) / 100
				self.prg1.set_fraction(self.frac)
				self.prg1.set_text(_("Used Space is ") + self.perc)
			except:
				self.perc = "0%"
				self.prg1.set_fraction(0)
				if os.getuid() == 0:
					self.prg1.set_text(_('%s  is not mounted. See "Partition" for details') % self.cb_part.get_active_text())
				else:
					self.prg1.set_text(_('%s  is not mounted. You will have to be ROOT to change that.') % self.cb_part.get_active_text())
		#####################################################################

	def reset_btns(self):
		if os.getuid() == 0:
			ret = commands.getoutput('df -P')
			act = self.cb_part.get_active_text()
			if re.search(act, ret):# partition is mounted
				self.cb_format.set_sensitive(False)
				self.btn_part.set_sensitive(False)
				self.tog_check.set_sensitive(False)
			else:
				self.cb_format.set_sensitive(True)
				self.btn_part.set_sensitive(True)
				self.tog_check.set_sensitive(True)					


	def change_part(self, cb):
		self.reset_btns()
		try:
			self.perc = self.get_free(cb.get_active_text())
			self.frac = float(self.perc.rstrip("%")) / 100	
			self.prg1.set_fraction(self.frac)
			self.prg1.set_text(_('Used Space in %s is %s') % (cb.get_active_text(), self.perc))
		except:
			self.perc = "0%"
			self.prg1.set_fraction(0)
			if os.getuid() == 0:
				self.prg1.set_text(_('%s  is not mounted. See "Partition" for details') % cb.get_active_text())
			else:
				self.prg1.set_text(_('%s  is not mounted. You will have to be ROOT to change that.') % cb.get_active_text())				


	def speed_test(self, btn):
		drv = self.combo.get_active_text()
		self.btn_test.set_label(_('Testing %s') % drv)
		while gtk.events_pending():
			gtk.main_iteration()
		r = commands.getoutput('hdparm -t %s'% drv)
		if len(r):
			if r[0] == "\n":
				f = r[1:-1]
		self.btn_test.set_label(_(" Test Drive Speed"))
		self.lbl_speed.set_text(f)
			
			
	def get_params(self, drv):
		d_info = commands.getoutput('hdparm -I %s' % drv)
		if d_info.find("HDIO_DRIVE_CMD(identify) failed:") == -1:
			return d_info
		else:
			small_info = commands.getoutput('sdparm -i %s'% drv)
			return (_("EXTENDED DRIVE INFO NOT AVAILABLE\n\nLikely an external drive or USB stick.\nIf not mounted, root user can partition and/or format this drive.\nUSB sticks are usually formatted as \"vfat\" for portability\nbetween Wndows and Linux.\n\n") + small_info)
		
	def mk_prt(self, btn):
		# put in warning to nmount is any partition on drv is mounted
		ret = commands.getoutput('df -P')
		drv = self.combo.get_active_text()
		first = False
		umount_str = ""
		if re.search(drv, ret):	
			r_mounted = []
			r = commands.getoutput('df -P')
			str_list = []
			str_list.append(_('You should unmount any partitions on %s \nbefore you partition the drive. Among other reasons, "umount" will not allow you to unmount a drive that is busy, so you do not have to worry about destroying the system by attempting to partition your "boot" drive by accident.\n The following partition(s) are currently mounted:\n\n') % drv)
			p_lines = r.split('\n')
			for l in p_lines:
				if re.search(drv, l): 
					pp = l.split(" ")
					mp = pp[-1]
					for m in pp:
						if re.search(drv, m):
							str_list.append(m + _('  is mounted on  %s\n') % mp)
							if not first:
								umount_str = _('\nUNMOUNTING: As an example, to unmount %s,\nissue the following command into a term:\n\numount %s') % (m, mp)
								first = True
			
			str_list.append(umount_str)
			ret_str = string.join(str_list, '')
			self.info(ret_str)
			return
	
		try:
			os.system('xterm -e cfdisk %s' % drv)
			self.combo.emit("changed")
			while gtk.events_pending():
				gtk.main_iteration()
		except:
			pass


	def format_drive(self, cb):
		r = cb.get_active_text()
		if self.tog_check.get_active() == True:
			c = " -c"
		else:
			c = ""
		drv = self.cb_part.get_active_text()
		is_mounted = commands.getoutput('df -P | grep %s' % (drv))
		if is_mounted:
			self.info(_("You should unmount the drive before formatting."))
			return
		if r == _("Format"):
			return
		elif r == _("ext2"):
			t = "ext2"
			f = 'mke2fs -q%s %s' % (c, drv)
		elif r == _("ext3"):
			t = "ext3"
			f = 'mke2fs -q%s -j %s' % (c, drv)
		elif r == _("reiserfs"):
			t = "reiserfs"
			f = 'mkreiserfs -q%s %s' % (c, drv)
		elif r == _("ext4"):
			t = "ext4"
			f = 'mkfs.ext4 -q%s %s' % (c, drv)
		elif r == _("vfat (FAT32)"):
			t = "vfat"
			f = 'mkdosfs -F 32 %s' % (drv)			
		else:
			return

		if self.do_format(f, t):
			self.info_(("Format Complete"))
			cb.set_active(0)
		else:
			self.info(_("Drive was not formatted"))
			cb.set_active(0)


	def do_format(self, cmd, ftype):
		prt = self.cb_part.get_active_text()
		dlg = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _('Are you sure you want to format %s as %s?') % (prt, ftype))
		dlg.set_position(gtk.WIN_POS_CENTER)
		response = dlg.run()
		if response == gtk.RESPONSE_NO:
			dlg.destroy()
			return False
		else:
			dlg.destroy()
			b, e = self.txt.get_bounds()
			self.txt.delete(b, e)
			self.txt.insert_at_cursor(_('Formatting %s as %s\nPlease Wait...\n') % (prt, ftype))
			while gtk.events_pending():
				gtk.main_iteration()
			pipe = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) 
			i = 0
			while pipe.poll() < 0:
				gtk.main_iteration()
				time.sleep(1)
				i += 1
				if i > 160:
					self.txt.insert_at_cursor('\n')
					i = 0
				else:
					self.txt.insert_at_cursor('.')
				while gtk.events_pending():
					gtk.main_iteration()
			self.combo.emit("changed")
			while gtk.events_pending():
				gtk.main_iteration()
			return True
			

	def close(self, btn):
		gtk.main_quit()


	def __init__(self):
		self.window = None
		HDDs = self.get_drives()
		if len(HDDs) == 0:
			print >>sys.stderr, _("No hard drives were found, exiting")
			raise SystemExit
		# make sure drives only listed once ##
		HDDs.sort()
		last = HDDs[-1]
		for i in range(len(HDDs)-2, -1, -1):
			if last==HDDs[i]: del HDDs[i]
			else: last=HDDs[i]
		#######################################
		init_drv = "/dev/" + HDDs[0]
		self.prt_lst = []
		self.prt_lst = self.get_prt_lst(init_drv)
		self.d1 = self.get_params(init_drv)
		self.perc = self.get_free(self.prt_lst[0])
		if self.perc == '' or self.perc == None:
			self.perc = "0%"
			self.frac = 0
		else:
			self.frac = float(self.perc.rstrip("%")) / 100
		hdico = gtk.gdk.pixbuf_new_from_xpm_data(hdd_xpm)
		hdd_img = gtk.Image()
		hdd_img.set_from_pixbuf(hdico)

		self.window = gtk.Window( type=gtk.WINDOW_TOPLEVEL)
		self.window.set_title(_("linHDD - 0.9"))
		self.window.set_default_size(530, 426)
		self.window.set_border_width(10)
		self.window.set_position(gtk.WIN_POS_CENTER)
		self.window.connect("destroy", self.destroy_cb, self.window)
		self.window.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#4d4d4d"))
		icon = gtk.gdk.pixbuf_new_from_xpm_data(icon_xpm)
		self.window.set_icon(icon)

		vbox = gtk.VBox(False, 10)
		self.window.add(vbox)
		box1 = gtk.HBox(False, 12)
		box2 = gtk.HBox(False, 0)
		box3 = gtk.HBox(False, 0)
		box4 = gtk.HBox(False, 0)
		box5 = gtk.HBox(False, 0)
		vbox.pack_start(box1, False, False, 0)
		vbox.pack_start(box2, False, False, 0)
		vbox.pack_start(box3, True, True, 0)
		vbox.pack_start(box4, False, False, 0)
		sep = gtk.HSeparator()
		vbox.pack_start(sep, False, False, 0)
		vbox.pack_start(box5, False, False, 0)
		
		box1.pack_start(hdd_img, False, False, 16)
		lbl1 = gtk.Label("")
		lbl1.set_markup(_('<span size="16384" background="#4d4d4d" foreground="#FFFFFF"><b>Hard Drive Information</b></span>'))
		box1.pack_start(lbl1, False, False, 4)

		self.prt_box = gtk.VBox(False, 0)
		lbl_prt = gtk.Label(_("Partition"))
		lbl_prt.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#ffffff"))		
		self.cb_part = gtk.combo_box_new_text()
		prts_raw = commands.getoutput('abs_fdisk -l %s' % init_drv)
		prt_lines = prts_raw.split("\n")
		for l in prt_lines:
			if re.search(init_drv, l):
				if not re.search("swap", l):
					d = l.split(" ")[0]
					if d != "Disk":
						self.cb_part.append_text(d)
		self.cb_part.set_active(0)		
		self.prt_box.pack_start(lbl_prt, False, False, 8)		
		self.prt_box.pack_start(self.cb_part, False, False, 0)
		box1.pack_end(self.prt_box, False, False, 0)
				
		
		
		hdd_box = gtk.VBox(False, 0)
		lbl_hdd = gtk.Label(_("Hard Drive"))
		lbl_hdd.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#ffffff"))
		self.combo = gtk.combo_box_new_text()
		for l in HDDs:
			nHDD = "/dev/" + l
			self.combo.append_text(nHDD)
		self.combo.set_active(0)
		hdd_box.pack_start(lbl_hdd, False, False, 8)		
		hdd_box.pack_start(self.combo, False, False, 0)
		box1.pack_end(hdd_box, False, False, 0)

		self.prg1 = gtk.ProgressBar()
		box2.pack_start(self.prg1, True, True, 0)
		self.prg1.set_fraction(self.frac)
		self.prg1.set_text(_("Used Space is ") + self.perc)
		
		self.txt = gtk.TextBuffer(table=None)
		self.txt_drive_info = gtk.TextView(buffer=self.txt)
		self.txt_drive_info.set_left_margin(8)
		
		swin = gtk.ScrolledWindow()
		swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
		swin.add(self.txt_drive_info)
		box3.pack_start(swin, True, True, 0)
		self.txt.insert_at_cursor(self.d1)
		
		
		self.btn_test = gtk.Button(_(" Test Drive Speed"))
		self.btn_test.connect("clicked", self.speed_test)
		self.btn_test.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.color_parse("#FF3333"))
		self.btn_test.modify_bg(gtk.STATE_ACTIVE, gtk.gdk.color_parse("#ffff66"))
		box4.pack_start(self.btn_test, False, False, 12)
		self.lbl_speed = gtk.Label(_("Block Device\nResults of read speed here"))
		self.lbl_speed.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#ffffff"))
		box4.pack_start(self.lbl_speed, False, False, 12)
		
		if os.getuid() == 0:
			lbl_avail = gtk.Label(_("Partition and Format are not\navailable on mounted partitions"))
		else:
			lbl_avail = gtk.Label(_("Partition and Format are not\navailable for non-root users"))
		lbl_avail.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#ffffff"))
		box5.pack_start(lbl_avail, False, True, 16)


		btns = gtk.HButtonBox()
		box5.pack_end(btns, False, True, 12)

		self.btn_close = gtk.Button(_(" Close "))
		self.btn_close.connect("clicked", self.close)
		btns.pack_start(self.btn_close, False, True, 12)
		
		self.tog_check = gtk.CheckButton(label=_("Check for\nbad blocks"))
		tog_lbl = self.tog_check.get_children()[0]
		tog_lbl.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#FFFFFF"))
		self.tog_check.set_sensitive(False)
		box5.pack_end(self.tog_check, False, True, 12)
		
		self.cb_format = gtk.combo_box_new_text()
		self.cb_format.append_text(_("Format"))
		self.cb_format.append_text(_("ext2"))
		self.cb_format.append_text(_("ext3"))
		self.cb_format.append_text(_("ext4"))
		self.cb_format.append_text(_("reiserfs"))
		self.cb_format.append_text(_("vfat (FAT32)"))
		self.cb_format.set_active(0)
		self.cb_format.connect('changed', self.format_drive)
		box5.pack_end(self.cb_format, False, True, 12)

		self.btn_part = gtk.Button(_("Partition"))
		self.btn_part.connect("clicked", self.mk_prt)
		box5.pack_end(self.btn_part, False, True, 12)		

		self.cb_format.set_sensitive(False)
		self.btn_part.set_sensitive(False)
		self.combo.connect('changed', self.change_drive)
		self.cb_part.connect('changed', self.change_part)
		self.window.show_all()
	
def main():
	DriveWin()
	gtk.main()


if __name__ == '__main__':
	main()
