#!/usr/bin/python
# -*- coding: utf-8 -*-
import os, popen2, fcntl, select, sys, os, pysvn, time
# Prerequisitos: cliente do subversion instalado, e pysvn .
from dialog import *
# We should handle the new DIALOG_HELP and DIALOG_EXTRA return codes here.
def handle_exit_code(d, code):
# d is supposed to be a Dialog instance
if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
if code == d.DIALOG_CANCEL:
msg = "Voce escolheu Cancelar. Voce quer encerrar " \
"este programa?"
else:
msg = "Voce pressionou ESC. Voce quer encerrar " \
"este programa?"
# "No" or "ESC" will bring the user back to the demo.
# DIALOG_ERROR is propagated as an exception and caught in main().
# So we only need to handle OK here.
if d.yesno(msg) == d.DIALOG_OK:
sys.exit(0)
return 0
else:
return 1 # code is d.DIALOG_OK
# Funcao para exibir uma lista para selecionar so um item...
def msg_box_radiolist(d,tit,msg):
while 1:
(code, tag) = d.radiolist(tit, width=65, choices=msg)
if handle_exit_code(d, code):
if not tag:
continue
break
return tag
def msg_box_inputbox(d,tit):
while 1:
(code, answer) = d.inputbox(tit, init="",width=76,height=20)
if handle_exit_code(d, code):
if not answer:
continue
break
return answer
#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=76)
#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
def notify_svn( event_dict ):
global chk_rev
chk_rev = 0
if event_dict['action'] == pysvn.wc_notify_action.update_completed:
chk_rev = event_dict['revision'].number
return
def get_log_message_svn():
global log_msg
return True, log_msg
#Rotina para recuperar dados do svn (log) e gerar arquivo html
def r_svn_to_html(caminho,branch_origem,revisao_branch_origem,comentario_vrs,trac):
arq_sai = caminho + os.sep + 'infodist' + os.sep + 'revisoes-svn.php'
arq_sai_ultima = caminho + os.sep + 'infodist' + os.sep + 'ultima-revisao-svn.php'
saida=''
cor =''
linha = 0
try:
cliente = pysvn.Client()
#cliente.callback_get_login = Login_no_svn
logs = cliente.log( branch_origem, revision_start=pysvn.Revision( pysvn.opt_revision_kind.number,revisao_branch_origem),
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 Livre - Subversion
\n'
saida += '
\n'
saida += '\n'
saida += 'Revisão | Data | Implementação - ' + comentario_vrs + ' |
\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']
try:
v = '#' + aux.split('#')[1].split(' ')[0]
p = aux.find(v)
if p > -1:
aux1 = aux[:p]
aux2 = aux[p+len(v):]
saida += '' + aux1 + '' + v + '' + aux2 + ' | '
else:
saida += ''+aux+' | \n'
except:
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()
fd = open(arq_sai_ultima,'w')
saida = ''
saida += '\n'
fd.write(saida.encode('iso8859','replace'))
fd.close()
# ##########################################################################################
# INICIO
# ##########################################################################################
#Carrega arquivo com dados que configuram as distribuiçoes possíveis...
from ger2_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 cada 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],0])
flag = False
rev=''
params={}
msg = ''
# Construindo objeto para o dialog...
d=Dialog()
# Seta titulo geral....
d.add_persistent_args(["--backtitle", "Gera Distribuição"])
tit = 'Selecione uma das distribuiçoes configuradas:'
opc = msg_box_radiolist(d,tit,escolhas)
#opc = '1' # soh tem um item de parametro ....
# Com base na selecao do usuario, carrega variaveis com valôres configurados....
projeto = parametros[tipo_distribuicao[opc]]['projeto']
caminho = parametros[tipo_distribuicao[opc]]['caminho']
caminho1 = trabalho + os.sep + caminho
trac= parametros[tipo_distribuicao[opc]]['trac']
s_ftp = parametros[tipo_distribuicao[opc]]['s_ftp']
s_path = parametros[tipo_distribuicao[opc]]['s_path']
prefixo = parametros[tipo_distribuicao[opc]]['prefixo']
script = parametros[tipo_distribuicao[opc]]['script']
aponta_tags = parametros[tipo_distribuicao[opc]]['tags']
# Seta titulo da distribuicao que sera efetuada...
d.add_persistent_args(["--title", 'Distribuição ExpressoLivre' ])
# 1 - Prepara para buscar os branchs existentes....
msg = "\n\n\nBuscando os branchs em: \n\n" + projeto + "\n\n\nAguarde."
msg_box_info(d,msg)
try:
cliente = pysvn.Client()
#cliente.callback_get_login = Login_no_svn
except:
msg_box_info(d,'\nFalhou preparando acesso ao Subversion.')
sys.exit(97)
try:
# Busca branchs no diretorio apontado por projeto.
branchs = cliente.ls(projeto)
msg = []
tab_branchs = {}
# Cria lista para exibir ao usuario ....
for branch in branchs:
msg.append((os.path.split(branch['name'])[-1],'R' + str(branch['created_rev'].number),0))
tab_branchs[os.path.split(branch['name'])[-1]] = str(branch['created_rev'].number)
except:
msg_box_info(d,'\nErro buscando branchs.')
sys.exit(95)
tit = "Branchs obtidos em " + projeto
# 2 - Mostra branchs para o usuario selecionar um ...
n_branch_origem = msg_box_radiolist(d,tit,msg)
revisao_branch_origem = tab_branchs[n_branch_origem]
tb_br = n_branch_origem.split('.')
if len(tb_br) < 3:
tb_br.append('0000000')
try:
prefixo_br = '0000000'[0:7 - len(tb_br[0])] + tb_br[0] + '0000000'[0:7 - len(tb_br[1])] + tb_br[1] + '0000000'[0:7 - len(tb_br[2])] + tb_br[2]
except:
msg_box_info(d,'\nErro: Nome do branch fora do padrao.')
sys.exit(96)
branch_origem = projeto + '/' + n_branch_origem
# 3 - Mostra tags do branch para o usuario selecionar uma ....
# Busca tags no diretorio apontado por aponta_tags
tags_localizados = cliente.ls(aponta_tags)
msg = []
tab_aux = {}
for tag in tags_localizados:
tt = os.path.split(tag['name'])[-1] .split('.')
nome_a = ''
for i in tt:
nome_a = nome_a +'0000000'[0:7 - len(i)] + i
if prefixo_br <> nome_a[0:21]:
continue
tab_aux[nome_a] = [os.path.split(tag['name'])[-1] ,str(tag['created_rev'].number)]
tab_aux_keys = tab_aux.keys()
tab_aux_keys.sort()
tab_aux_keys.reverse()
tit = '\nTags existentes para o branch:'
# Cria lista para exibir ao usuario ( maximo de 10)....
i = len(tab_aux_keys)
if i > 10:
z=i # forca mostrar todos os tags.
else:
z = i
msg = []
for x in range(0,z):
msg.append((tab_aux[tab_aux_keys[x]][0], 'R' + tab_aux[tab_aux_keys[x]][1],0))
tit = 'Selecione um tag para gerar distribuicao do branch\n' + branch_origem + ' :' + '\n'
if msg:
nome_tag = msg_box_radiolist(d,tit,msg)
rev_tag_escolhida = ''
for item in msg:
if item[0] == nome_tag:
revisao_desejada = item[1][1:]
break
if revisao_desejada == '':
print 'Erro....'
sys.exit()
tag_selecionada = aponta_tags + '/' + nome_tag
item = 'Tag'
else:
nome_tag = n_branch_origem
revisao_desejada = revisao_branch_origem
tag_selecionada = projeto + '/' + n_branch_origem
item = 'Brc'
if item == 'Tag':
msg = '\n\nA seguir, sera gerado arquivo de distribuicao:\nOrigem: Tag ' + nome_tag + '\n do branch ' + branch_origem + ',\n revisao ' + revisao_desejada + '\n\nContinuar?'
else:
msg = '\n\nA seguir, sera gerado arquivo de distribuicao:\nOrigem: Branch ' + branch_origem + ',\n revisao ' + revisao_desejada + '\n\nContinuar?'
if msg_box_sim_nao(d,msg) != d.DIALOG_OK:
sys.exit(98)
#comentario_tag = item + ' ' + nome_tag + ' R' + revisao_desejada
comentario_tag = nome_tag + ' R' + revisao_desejada
comentario_tagx = nome_tag + '-R' + revisao_desejada
msg_box_info(d,'\n\n\nProcessando a geracao da distribuição como solicitado.\n\n\nAguarde.')
# Dados para executar o export:
#
revisao_branch_origem = revisao_desejada
# 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)
revisao = cliente.export(branch_origem,
caminho1,
force=False,
revision=pysvn.Revision(pysvn.opt_revision_kind.number,revisao_branch_origem),
native_eol=None,
ignore_externals=False,
recurse=True,
peg_revision=pysvn.Revision(pysvn.opt_revision_kind.number, revisao_branch_origem))
if not os.path.exists(caminho1 + os.sep + 'infodist'):
retorno = getCommandOutput('mkdir ' + caminho1 + os.sep + 'infodist')
# 6 - Gera arquivo com informacoes do Subversion e dados de identificação da distribuição...
r_svn_to_html(caminho1,branch_origem,revisao_branch_origem,comentario_tag,trac)
# --------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# Se existir um nome de script no arquivo de configuração, vai tentar executar...
if script != '':
if os.path.isfile(script):
msg = "\nExecutando o script " + script + " \n"
msg_box_info(d,msg)
retorno = getCommandOutput(script)
msg_box_info(d,retorno)
else:
msg = "\nScript " + script + " nao foi localizado.\n"
msg_box_info(d,msg)
msg = ''
#Solicita execucao do comando de compactaçao
path_corrente = os.getcwd()
os.chdir(trabalho)
retorno = getCommandOutput("tar -zcf " + prefixo + comentario_tagx + ".tgz ./expresso")
os.chdir(path_corrente)
msg = msg + "\nFoi gerado o arquivo " + prefixo + comentario_tagx + ".tgz \n"
msg_box_info(d,msg)
if s_ftp != '':
from ftplib import FTP
servidor_ftp = s_ftp
#Faz ftp para a maquina de distribuicao...
msg = msg + 'Iniciando copia do arquivo gerado para ambiente de distribuicao(FTP)\n'
msg_box_info(d,msg)
try:
ftp = FTP(servidor_ftp,'anonymous','')
resp = ftp.cwd(s_path)
msg = msg + resp + '\n'
msg_box_info(d,msg)
lista = ftp.nlst()
if 'R'+str(revisao_branch_origem) in lista:
ftp.cwd('R'+str(revisao_branch_origem))
# pode existir a pasta mas nao o arquivo....
try:
resp = ftp.delete(prefixo+str(revisao_branch_origem)+'.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(revisao_branch_origem))
msg = msg + resp + '\n'
msg_box_info(d,msg)
resp = ftp.cwd('R'+str(revisao_branch_origem))
msg = msg + resp + '\n'
msg_box_info(d,msg)
f = open(trabalho + os.sep + prefixo + comentario_tagx + '.tgz','rb')
resp = ftp.storbinary('STOR ' + prefixo + comentario_tagx + '.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(revisao_branch_origem)+' 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()
except:
msg = msg + '\nErro ao conectar no servidor FTP.\n\n\n'
msg = msg + '\nProcessamento concluido.\n'
msg_box_info(d,msg)
# --------------------------------------------------------------------------------------------------------------------------------------------------------------------------