#! /usr/bin/python
# -*- coding: iso-8859-1 -*-

#####################################################
#    Copyright (C) 2006 by Cesar Kallas   	
#    cesarkallas@soulivre.org   
#    http://cesarkallas.soulivre.org
#                                                                          
#    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 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.             
#####################################################

#	RPM Python (and friends)
#	Paul Nasrat
#	http://people.redhat.com/pnasrat/rpm-python/rpm-python-slides/titlepg.html

import Ambiente
import rpm, os, qt, threading

# http://fedora.redhat.com/docs/drafts/rpm-guide-en/ch16s06.html
class simpleCallback(object):
	def __init__(self):
		self.fdnos = {}
		
	def callback(self, what, amount, total, mydata, wibble):
		"""what -- callback type, amount -- bytes processed total -- total bytesmydata -- package key (hdr, path) 	wibble -- user data - unused here"""
		if what == rpm.RPMCALLBACK_TRANS_START:
			pass
			
		elif what == rpm.RPMCALLBACK_INST_OPEN_FILE:
			hdr, path = mydata
			Ambiente.uiAgente.textExecutandoAcao.append(qt.QString("Instalando: %s" % (hdr["name"])))
			fd = os.open(path, os.O_RDONLY)
			nvr = '%s-%s-%s' % ( hdr['name'], hdr['version'], hdr['release'] )
			self.fdnos[nvr] = fd
			return fd

		elif what == rpm.RPMCALLBACK_UNINST_START:
			Ambiente.uiAgente.textExecutandoAcao.append(qt.QString("Iniciando desinstalacao..."))
		
		elif what ==  rpm.RPMCALLBACK_UNINST_STOP:
			Ambiente.uiAgente.textExecutandoAcao.append(qt.QString("desinstalacao finalizada."))
			
		elif what == rpm.RPMCALLBACK_INST_CLOSE_FILE:
			hdr, path = mydata
			nvr = '%s-%s-%s' % ( hdr['name'], hdr['version'], hdr['release'] )
			Ambiente.uiAgente.textExecutandoAcao.append(qt.QString("instalação finalizada."))
			os.close(self.fdnos[nvr])

		elif what == rpm.RPMCALLBACK_UNINST_PROGRESS:
			Ambiente.uiAgente.progressBarExecutandoAcao.setProgress (int( (float(amount) / total) * 100))
			
		elif	what == rpm.RPMCALLBACK_INST_PROGRESS :
			hdr, path = mydata
			#print "%s:  %.5s%% done\r" % (hdr["name"], (float(amount) / total) * 100)
			#Ambiente.uiAgente.textExecutandoAcao.append(qt.QString("%s:  %.5s%% done\r" % (hdr["name"], str((float(amount) / total) * 100))))
			Ambiente.uiAgente.progressBarExecutandoAcao.setProgress (int( (float(amount) / total) * 100))


class RPM (object):
	"""
	Manipula arquivos RPM
	"""
	def __init__(self):
		pass


	def instalados(self):
		"""
		Lista todos softwares instalados
		"""
		listaSoftwares = []
		dicSoftware = {}

		try:
			ts=rpm.ts()
			mi=ts.dbMatch()
			mi.pattern("name", rpm.RPMMIRE_GLOB, "*")
			for hdr in mi:
				dicSoftware = {}
				dicSoftware["nome"] = str(hdr[rpm.RPMTAG_NAME])
				dicSoftware["versao"] = str(hdr[rpm.RPMTAG_VERSION])
				dicSoftware["release"] = str(hdr[rpm.RPMTAG_RELEASE])
				dicSoftware["tamanho"] = str(hdr[rpm.RPMTAG_SIZE])
				dicSoftware["plataforma"] = str(hdr[rpm.RPMTAG_PLATFORM])
				dicSoftware["descricao"] = str(hdr[rpm.RPMTAG_SUMMARY])
				dicSoftware["grupo"] = str(hdr[rpm.RPMTAG_GROUP])
				listaSoftwares.append(dicSoftware)
			return listaSoftwares
		except:
			raise
			return -1


	def estaInstalado(self, software):
		"""
		Verifica se determinado software esta instalado
		"""
		try:
			ts=rpm.ts()
			mi=ts.dbMatch()
			mi.pattern("name", rpm.RPMMIRE_GLOB, software)
			for hdr in mi:
				return str(hdr['name']), str(hdr['version']), str(hdr['release'])
			return None, None, None
		except:
			raise
			return -1
	
	def instala(self, software):
		try:
			cb = simpleCallback()
			fdno = os.open(software, os.O_RDONLY)
			ts = rpm.ts()
			hdr = ts.hdrFromFdno(fdno)
			os.close(fdno)
			ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
			ts.addInstall(hdr,(hdr, software), "u")
			unresolved_dependencies = ts.check(cb.callback)
			if not unresolved_dependencies: 
				#ts.run(cb.callback,'')
				instalacao = threading.Thread(target = ts.run, args = (cb.callback, ''))
				#resposta = thread.start_new_thread(ts.run,(cb.callback,''))
				instalacao.start()
				instalacao.join()
			else:
				print "falha dependencias: ", unresolved_dependencies
			return 1
		except:
			raise
			return -1


	def desinstala(self, software):
		try:
			ts=rpm.ts()
			mi=ts.dbMatch()
			mi.pattern("name", rpm.RPMMIRE_GLOB, software)
			for idx in mi:
				instance = mi.instance()
				ts.addErase(instance)
			cb = simpleCallback()
			#ts.run(cb.callback,'')
			instalacao = threading.Thread(target = ts.run, args = (cb.callback, ''))
			instalacao.start()
			instalacao.join()
			return 1
		except:
			raise
			return -1
			
	def atualiza(self, software):
		pass

	
