#!/usr/bin/python
# -*- coding: utf-8 -*-
import os, popen2, fcntl, select, sys, os, pysvn, time
# Prerequisitos: cliente do subversion instalado, e pysvn mais o python-dialog instalado no python.
from dialog import *
#Função para solicitar ao usuario o tipo de distribuicao
def mostra(d,escolhas):
return d.menu("Selecione o tipo de distrbuicao desejada:",height=0,choices=escolhas)
def msg_box_info(d,msg):
d.infobox(msg,height=19,width=60)
time.sleep(2)
return
def msg_box_sim_nao(d,msg):
return d.yesno(msg,height=18,width=80)
#As duas funcoes, a seguir, executam comandos e retornam resultado.
def makeNonBlocking(fd):
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
try:
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NDELAY)
except AttributeError:
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.FNDELAY)
def getCommandOutput(command):
f=sys.stdout
child = popen2.Popen3(command, 1) # Captura stdout e stderr do comando
child.tochild.close( ) # nao necessitamos escrever para a stdin do processo iniciado pelo comando
outfile = child.fromchild
outfd = outfile.fileno( )
errfile = child.childerr
errfd = errfile.fileno( )
makeNonBlocking(outfd) # Evitamos deadlocks tornando fd's nonblock.
makeNonBlocking(errfd)
outdata, errdata = [ ], [ ]
outeof = erreof = False
while True:
f.write('.')
f.flush()
to_check = [outfd]*(not outeof) + [errfd]*(not erreof)
ready = select.select(to_check, [ ], [ ]) # Espera por dados...
if outfd in ready[0]:
outchunk = outfile.read( )
if outchunk == '':
outeof = True
else:
outdata.append(outchunk)
if errfd in ready[0]:
errchunk = errfile.read( )
if errchunk == '':
erreof = True
else:
errdata.append(errchunk)
if outeof and erreof:
break
select.select([ ],[ ],[ ],.1) # Seta um intervalo de tempo bem curto para os buffers serem preenchidos.
err = child.wait( )
if err != 0:
raise RuntimeError, '%r falhou com codigo %d\n%s' % (
command, err, ''.join(errdata))
return ''.join(outdata)
#Callback para login no svn
def Login_no_svn( realm, username, may_save ):
from getpass import getpass
global flag
print 'Por favor, identifique-se'
usuario = raw_input('Usuario:').strip()
senha = getpass('Senha:').strip()
if not flag:
flag = True
else:
flag = False
print 'Falhou acesso ao Subversion...\n'
sys.exit(92)
return True, usuario, senha, True
#Rotina para recuperar dados do svn sobre as revisoes e gerar arquivo html
def r_svn_to_html():
global projeto, caminho,rev
arq_sai = caminho + os.sep + 'revisoes-svn.php'
saida=''
cor =''
linha = 0
try:
cliente = pysvn.Client()
cliente.callback_get_login = Login_no_svn
logs = cliente.log( projeto, revision_start=pysvn.Revision( pysvn.opt_revision_kind.number,rev),
revision_end=pysvn.Revision( pysvn.opt_revision_kind.number, 0 ),
discover_changed_paths=True,strict_node_history=True,limit=0 )
except:
print 'Erro Obtendo dados do svn para gerar revisoes-svn.php'
sys.exit(93)
fd = open(arq_sai, 'w')
saida += '\n'
saida += '
\n'
saida += '
Expresso - Subversion
\n'
saida += '
\n'
saida += '\n'
saida += 'Revisão | Data | Implementação |
\n'
for revisao in logs:
linha += 1
if linha%2:
cor = '#DDDDDD'
else:
cor = '#EEEEEE'
saida += '\n'
saida += ''+str(revisao['revision'].number)+' | \n'
saida += ''+time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(revisao['date']))+' | \n'
try:
aux = revisao['message']
saida += ''+aux+' | \n'
except:
saida += 'Nao foi possivel obter a msg no subversion. Falha no encode... | \n'
saida += '
\n'
saida += '
\n'
saida += '
\n'
fd.write(saida.encode('iso8859','replace'))
fd.close()
# ##########################################################################################
# INICIO
# ##########################################################################################
#Carrega arquivo com dados que configuram as distribuiçoes possíveis...
from gerador_conf import *
# Pega identificador de cada distribuicao configurada...
aux_tipo_distribuicao = parametros.keys()
# Ordena
aux_tipo_distribuicao.sort()
tipo_distribuicao = {}
# Tipo de distribuicao: uma entrada para distribuicao configurada...
for i in range(0,len(aux_tipo_distribuicao)):
tipo_distribuicao[str(i+1)] = aux_tipo_distribuicao[i]
# ordena pelo enumerador.....
Ks = tipo_distribuicao.keys()
Ks.sort()
escolhas = []
# COnstruindo itens do menu, uma entrada para cada distribuicao configurada...
for t in Ks:
escolhas.append([t,tipo_distribuicao[t]])
flag = False
rev=''
params={}
d=Dialog()
# Seta titulo geral....
d.add_persistent_args(["--backtitle", "Gera distribuicao"])
# Usuario seleciona a distribuição desejada.
# cod = 0 , usuario selecionou um item, ver valor em opc...
# cod = 1 , usuario selecionou cancelar, valor em opc é vazio
# cod = 2 , usurio usou a tecla esc, valor em opc é vazio
[cod,opc] = mostra(d,escolhas)
# Se opc for vazio o usuario pediu para cancelar, ou usou a tecla esc...
if opc == '':
sys.exit(98)
# Com base na selecao do usuario, carrega variaveis com valôres configurados....
projeto = parametros[tipo_distribuicao[opc]]['projeto']
caminho = parametros[tipo_distribuicao[opc]]['caminho']
s_ftp = parametros[tipo_distribuicao[opc]]['s_ftp']
s_path = parametros[tipo_distribuicao[opc]]['s_path']
sufixo = parametros[tipo_distribuicao[opc]]['sufixo']
pasta_do_produto = parametros[tipo_distribuicao[opc]]['pasta_do_produto']
script = parametros[tipo_distribuicao[opc]]['script']
# Seta titulo da distribuicao que sera efetuada...
d.add_persistent_args(["--title", 'Distribuição ' +tipo_distribuicao[opc]])
# Pega lista de parametros, se houver....
if len(sys.argv)>1:
for parametro in sys.argv:
aux=parametro.split('=')
if len(aux)==2:
params[aux[0]] = aux[1]
if 'url' in params.keys():
projeto = params['url']
#Se existir o parametro projeto usar o ultimo elemento para compor o caminho no dir corrente.
aux = projeto.split(os.sep)
caminho=os.getcwd()+os.sep+aux[-1]
if 'caminho' in params.keys():
caminho = params['caminho']
if 'rev' in params.keys():
try:
rev = int(params['rev'])
except:
msg_box_info(d,"Revisao invalida.")
sys.exit(99)
# Prepara alerta ao usuario, para confirmar execução...
if len(params)<2:
msg = "\nExemplo: ."+os.sep+"gerador.py url=http://xxx/bbb/yyyy caminho="+os.sep+"xxxx"+os.sep+"pasta rev=xxx\n"
msg = msg + " url : Aponta projeto no svn\n"
msg = msg + " caminho : Aponta o destino dos arquivo do projeto.\n"
msg = msg + " rev : Informa o num. da revisao que sera tratada. Se vazio trata a mais recente.\n"
msg = msg + "\nAssumindo valores default para esta execucao."
msg = msg + "Sera processado o projeto apontado pela url " + projeto + "\n"
if rev != '':
msg = msg + "Posicionado na revisao " + str(rev) + ".\n\n"
else:
msg = msg + "\n\n"
msg = msg + "Os arquivos do projeto serao armazenados no caminho " + caminho + "\n\n"
msg = msg + "Continuar?"
# Envia msg ao usuario e agurada resposta....
if msg_box_sim_nao(d,msg) != d.DIALOG_OK:
sys.exit(98)
# Iniciando o processamento...
caminho1 = trabalho + os.sep + caminho
caminho = trabalho + os.sep + caminho + os.sep + pasta_do_produto
# Verifica a existencia de uma pasta de trabalho.
# Nesta pasta serao gerados subdiretorios que vao conter as distribuiçoes.
if not os.path.isdir(trabalho):
os.makedirs(trabalho)
if os.path.isdir(caminho1):
retorno = getCommandOutput('rm -fR ' + caminho1)
else:
retorno = getCommandOutput('mkdir ' + caminho1)
try:
cliente = pysvn.Client()
cliente.callback_get_login = Login_no_svn
except:
msg_box_info(d,'\nErro gerando cliente do subversion.')
sys.exit(97)
if rev == '':
try:
msg_box_info(d,'\nAguarde.\nVerificando qual a revisao mais recente do projeto no Subversion.\n')
logs = cliente.log( projeto, discover_changed_paths=True,strict_node_history=True,limit=1)
rev = logs[0]['revision'].number
except:
msg_box_info(d,'\nErro determinando qual he a revisao mais recente no subversion.')
sys.exit(96)
msg = '\nBuscando os arquivos da revisao ' + str(rev) + '.\n\n'
msg = msg + 'Esta atividade pode demorar alguns minutos. \nAguarde.\n'
msg_box_info(d,msg)
try:
revisao = cliente.export( projeto,
caminho,
force=False,
revision=pysvn.Revision(pysvn.opt_revision_kind.number,rev),
native_eol=None,
ignore_externals=False,
recurse=True,
peg_revision=pysvn.Revision(pysvn.opt_revision_kind.number, rev))
except:
msg_box_info(d,'\nErro buscando arquivos no subversion.')
sys.exit(95)
#Gera arqivo com infrmacoes do Subversion
r_svn_to_html()
# Se existir um nome de script no arquivo de configuração, vai tentar executar...
if script != '':
msg = msg + "\nExecutando o script ." + os.sep + script + " \n"
msg_box_info(d,msg)
retorno = getCommandOutput('.' + os.sep + script)
#Solicita execucao do comando de compactaçao
path_corrente = os.getcwd()
os.chdir(caminho1)
retorno = getCommandOutput("tar -zcf " + sufixo + str(rev) + ".tgz ./expresso")
os.chdir(path_corrente)
msg = ''
msg = msg + "\nFoi gerado o arquivo " + sufixo + str(rev) + ".tgz \n"
msg_box_info(d,msg)
#Faz ftp para a maquina de distribuicao...
msg = msg + 'Iniciando copia do arquivo gerado para a maquina de distribuicao(FTP)\n'
msg_box_info(d,msg)
from ftplib import FTP
servidor_ftp = s_ftp
try:
ftp = FTP(servidor_ftp,'anonymous','')
except:
msg = msg + '\nErro ao conectar no servidor FTP.'
msg_box_info(d,msg)
sys.exit(94)
resp = ftp.cwd(s_path)
msg = msg + resp + '\n'
msg_box_info(d,msg)
lista = ftp.nlst()
if 'R'+str(rev) in lista:
ftp.cwd('R'+str(rev))
# pode existir a pasta mas nao o arquivo....
try:
resp = ftp.delete(sufixo+str(rev)+'.tgz')
except:
pass
msg = msg + resp + '\n'
msg_box_info(d,msg)
resp = ftp.cwd('../')
msg = msg + resp + '\n'
msg_box_info(d,msg)
else:
resp = ftp.mkd('R'+str(rev))
msg = msg + resp + '\n'
msg_box_info(d,msg)
resp = ftp.cwd('R'+str(rev))
msg = msg + resp + '\n'
msg_box_info(d,msg)
f = open(caminho1 + os.sep + sufixo+str(rev)+'.tgz','rb')
resp = ftp.storbinary('STOR ' + sufixo + str(rev) + '.tgz',f)
msg = msg + resp + '\n'
msg_box_info(d,msg)
msg = msg + 'Verifique os dados abaixo:\n'
msg_box_info(d,msg)
resp = ftp.pwd()
msg = msg + 'Diretorio de distribuicao R'+str(rev)+' gerado em '+servidor_ftp+' : '+resp
msg_box_info(d,msg)
resp = ftp.retrlines('LIST')
msg = msg + '\nConteudo gerado no diretorio acima : \n'+resp+'\n'
msg_box_info(d,msg)
ftp.close()
msg = msg + '\nProcessamento concluido.\n'
msg_box_info(d,msg)