#!/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 += '\n' for revisao in logs: linha += 1 if linha%2: cor = '#DDDDDD' else: cor = '#EEEEEE' saida += '\n' saida += '\n' saida += '\n' try: aux = revisao['message'] saida += '\n' except: saida += '\n' saida += '\n' saida += '
RevisãoDataImplementação
'+str(revisao['revision'].number)+''+time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(revisao['date']))+''+aux+'Nao foi possivel obter a msg no subversion. Falha no encode...
\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)