source: contrib/scriptGerDistrib/ger2.py @ 3545

Revision 3545, 15.7 KB checked in by rafaelraymundo, 13 years ago (diff)

Ticket #1344 - Informar na tela de login a tag/branch e revisão do svn.

Line 
1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3
4import os, popen2, fcntl, select, sys, os, pysvn, time
5# Prerequisitos: cliente do subversion instalado, e pysvn .
6from dialog import *
7
8# We should handle the new DIALOG_HELP and DIALOG_EXTRA return codes here.
9def handle_exit_code(d, code):
10    # d is supposed to be a Dialog instance
11    if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
12        if code == d.DIALOG_CANCEL:
13            msg = "Voce escolheu Cancelar. Voce quer encerrar " \
14                  "este programa?"
15        else:
16            msg = "Voce pressionou ESC. Voce quer encerrar " \
17                  "este programa?"
18        # "No" or "ESC" will bring the user back to the demo.
19        # DIALOG_ERROR is propagated as an exception and caught in main().
20        # So we only need to handle OK here.
21        if d.yesno(msg) == d.DIALOG_OK:
22            sys.exit(0)
23        return 0
24    else:
25        return 1                        # code is d.DIALOG_OK
26
27# Funcao para exibir uma lista para selecionar so um item...
28def msg_box_radiolist(d,tit,msg):   
29    while 1:
30        (code, tag) = d.radiolist(tit, width=65, choices=msg)
31       
32        if handle_exit_code(d, code):
33                if not tag:
34                        continue
35                break
36    return tag
37
38def msg_box_inputbox(d,tit):
39    while 1:
40        (code, answer) = d.inputbox(tit, init="",width=76,height=20)
41        if handle_exit_code(d, code):
42                if not answer:
43                        continue
44                break
45    return answer
46   
47#Função para solicitar ao usuario o tipo de distribuicao
48def mostra(d,escolhas):
49   return d.menu("Selecione o tipo de distrbuicao desejada:",height=0,choices=escolhas)
50
51def msg_box_info(d,msg):
52    d.infobox(msg,height=19,width=60)
53    time.sleep(2)
54    return
55
56def msg_box_sim_nao(d,msg):
57    return d.yesno(msg,height=18,width=76)
58
59#As duas funcoes, a seguir, executam comandos e retornam resultado.
60def makeNonBlocking(fd):
61    fl = fcntl.fcntl(fd, fcntl.F_GETFL)
62    try:
63        fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NDELAY)
64    except AttributeError:
65        fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.FNDELAY)
66
67def getCommandOutput(command):
68    f=sys.stdout
69    child = popen2.Popen3(command, 1) # Captura stdout e stderr do comando
70    child.tochild.close( )             # nao necessitamos escrever para a  stdin do processo iniciado pelo comando
71    outfile = child.fromchild
72    outfd = outfile.fileno( )
73    errfile = child.childerr
74    errfd = errfile.fileno( )
75    makeNonBlocking(outfd)            # Evitamos deadlocks tornando fd's nonblock.
76    makeNonBlocking(errfd)
77    outdata, errdata = [  ], [  ]
78    outeof = erreof = False
79    while True:
80        f.write('.')
81        f.flush()
82        to_check = [outfd]*(not outeof) + [errfd]*(not erreof)
83        ready = select.select(to_check, [  ], [  ]) # Espera por dados...
84        if outfd in ready[0]:
85            outchunk = outfile.read( )
86            if outchunk == '':
87                outeof = True
88            else:
89                outdata.append(outchunk)
90        if errfd in ready[0]:
91            errchunk = errfile.read( )
92            if errchunk == '':
93                erreof = True
94            else:
95                errdata.append(errchunk)
96        if outeof and erreof:
97            break
98        select.select([  ],[  ],[  ],.1) # Seta um intervalo de tempo bem curto para os buffers serem preenchidos.
99    err = child.wait( )
100    if err != 0:
101        raise RuntimeError, '%r falhou com codigo %d\n%s' % (
102            command, err, ''.join(errdata))
103    return ''.join(outdata)
104
105
106#Callback para login no svn
107def Login_no_svn( realm, username, may_save ):
108        from getpass import getpass
109        global flag
110        print 'Por favor, identifique-se'
111        usuario = raw_input('Usuario:').strip()
112        senha = getpass('Senha:').strip()
113        if not flag:
114                flag = True
115        else:
116                flag = False
117                print 'Falhou acesso ao Subversion...\n'
118                sys.exit(92)
119        return True, usuario, senha, True
120
121def notify_svn( event_dict ):
122        global chk_rev
123        chk_rev = 0
124        if event_dict['action'] == pysvn.wc_notify_action.update_completed:
125                chk_rev = event_dict['revision'].number
126        return
127
128def get_log_message_svn():
129        global log_msg
130        return True, log_msg
131
132#Rotina para recuperar dados do svn (log) e gerar arquivo html
133def  r_svn_to_html(caminho,branch_origem,revisao_branch_origem,comentario_vrs,trac):
134        arq_sai = caminho + os.sep + 'infodist' + os.sep + 'revisoes-svn.php'
135        arq_sai_ultima = caminho + os.sep +  'infodist' + os.sep + 'ultima-revisao-svn.php'
136        saida=''
137        cor =''
138        linha = 0       
139       
140        try:
141                cliente = pysvn.Client()
142                #cliente.callback_get_login = Login_no_svn
143                logs = cliente.log( branch_origem, revision_start=pysvn.Revision( pysvn.opt_revision_kind.number,revisao_branch_origem),
144                        revision_end=pysvn.Revision( pysvn.opt_revision_kind.number, 0 ),
145                        discover_changed_paths=True,strict_node_history=True,limit=0 )
146        except:
147                print 'Erro Obtendo dados do svn para gerar revisoes-svn.php'
148                sys.exit(93)     
149
150        fd = open(arq_sai, 'w')
151        saida += '<?php ?>\n'
152        saida += '<div align=CENTER>\n'
153        saida += '<h3 align="center" style="color: #0000FF;margin-bottom: 0 ">Expresso Livre - Subversion </h3>\n'
154        saida += '<table border="1" witdh="100%">\n'
155        saida += '<tr bgcolor="#D3DCE3">\n'
156        saida += '<td>Revis&atilde;o</td><td><font color="#000066">Data</font></td><td><font color="#000066">Implementa&ccedil;&atilde;o - ' +  comentario_vrs +   '</font></td></tr>\n'
157        for revisao in logs:
158                linha += 1
159                if linha%2:
160                        cor = '#DDDDDD'
161                else:
162                        cor = '#EEEEEE'
163                saida += '<tr bgcolor="'+cor+'">\n'     
164                saida += '<td valign="top">'+str(revisao['revision'].number)+'</td>\n'
165                saida += '<td valign="top">'+time.strftime('%Y-%m-%d  %H:%M:%S',time.localtime(revisao['date']))+'</td>\n'
166                try:
167                        aux = revisao['message']
168                        try:
169                                v = '#' + aux.split('#')[1].split(' ')[0]
170                                p =  aux.find(v)
171                                if p > -1:
172                                     aux1 = aux[:p]
173                                     aux2 = aux[p+len(v):]
174                                     saida += '<td>' + aux1 + '<a href="' + trac + aux.split('#')[1].split(' ')[0] + '" TARGET="_blank" >' + v + '</a>' + aux2 + '</td>'
175                                else:
176                                     saida += '<td valign="top"><pre>'+aux+'</pre></td>\n'
177                        except:
178                                saida += '<td valign="top"><pre>'+aux+'</pre></td>\n'
179                except:
180                        saida += '<td valign="top">Nao foi possivel obter a msg no subversion. Falha no encode...</td>\n'
181                saida += '</tr>\n'
182        saida += '</table>\n'
183        saida += '</div>\n'     
184        fd.write(saida.encode('iso8859','replace'))
185        fd.close()
186
187        fd = open(arq_sai_ultima,'w')
188        saida = ''
189        saida += '<?php $ultima_revisao ="' + comentario_vrs  + '" ?>\n'
190        fd.write(saida.encode('iso8859','replace'))
191        fd.close()
192
193# ##########################################################################################
194#                                     INICIO
195# ##########################################################################################
196
197#Carrega arquivo com dados que configuram as distribuiçoes possíveis...
198from ger2_conf import *
199
200# Pega identificador de cada distribuicao configurada...
201aux_tipo_distribuicao = parametros.keys()
202
203# Ordena
204aux_tipo_distribuicao.sort()
205
206tipo_distribuicao = {}
207
208
209# Tipo de distribuicao: uma entrada para cada distribuicao configurada...
210for i in range(0,len(aux_tipo_distribuicao)):
211        tipo_distribuicao[str(i+1)] = aux_tipo_distribuicao[i]
212
213# ordena pelo enumerador.....
214Ks = tipo_distribuicao.keys()
215Ks.sort()
216escolhas = []
217
218# Construindo itens do menu, uma entrada para cada distribuicao configurada...
219for t in Ks:
220     escolhas.append([t,tipo_distribuicao[t],0])
221
222flag = False
223rev=''
224params={}
225msg = ''
226
227
228# Construindo objeto para o dialog...
229d=Dialog()
230# Seta titulo geral....
231d.add_persistent_args(["--backtitle", "Gera Distribuição"])
232
233tit = 'Selecione uma das distribuiçoes configuradas:'
234opc = msg_box_radiolist(d,tit,escolhas)
235
236#opc = '1'   # soh tem um item de parametro ....
237
238# Com base na selecao do usuario, carrega variaveis com valÃŽres configurados....         
239projeto = parametros[tipo_distribuicao[opc]]['projeto']
240caminho = parametros[tipo_distribuicao[opc]]['caminho']
241caminho1 = trabalho + os.sep + caminho
242trac= parametros[tipo_distribuicao[opc]]['trac']
243s_ftp = parametros[tipo_distribuicao[opc]]['s_ftp']
244s_path = parametros[tipo_distribuicao[opc]]['s_path']
245prefixo = parametros[tipo_distribuicao[opc]]['prefixo']
246script = parametros[tipo_distribuicao[opc]]['script']
247aponta_tags = parametros[tipo_distribuicao[opc]]['tags']
248
249# Seta titulo da distribuicao que sera efetuada...
250d.add_persistent_args(["--title", 'Distribuição ExpressoLivre' ])
251
252#   1 -  Prepara para buscar os branchs existentes....
253msg = "\n\n\nBuscando os branchs em: \n\n" + projeto + "\n\n\nAguarde."
254msg_box_info(d,msg)
255
256try:
257        cliente = pysvn.Client()
258        #cliente.callback_get_login = Login_no_svn
259except:
260        msg_box_info(d,'\nFalhou preparando acesso ao Subversion.')
261        sys.exit(97)
262       
263try:
264        # Busca branchs no diretorio apontado por projeto.
265        branchs = cliente.ls(projeto)
266        msg = []
267        tab_branchs = {}
268        # Cria lista para exibir ao usuario ....
269        for branch in branchs:
270                msg.append((os.path.split(branch['name'])[-1],'R' + str(branch['created_rev'].number),0))
271                tab_branchs[os.path.split(branch['name'])[-1]] = str(branch['created_rev'].number)
272except:
273        msg_box_info(d,'\nErro buscando branchs.')
274        sys.exit(95)   
275
276tit = "Branchs obtidos em " + projeto   
277
278#   2 -  Mostra branchs  para o usuario selecionar um ...
279n_branch_origem = msg_box_radiolist(d,tit,msg)
280
281revisao_branch_origem = tab_branchs[n_branch_origem]
282
283tb_br =  n_branch_origem.split('.')
284
285if len(tb_br)  < 3:
286        tb_br.append('0000000')
287try:   
288        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]
289except:
290        msg_box_info(d,'\nErro: Nome do branch fora do padrao.')
291        sys.exit(96)   
292
293
294branch_origem = projeto + '/' + n_branch_origem
295
296#   3 -  Mostra tags do branch para o usuario selecionar uma ....
297# Busca tags no diretorio apontado por aponta_tags
298tags_localizados = cliente.ls(aponta_tags)
299msg = []
300tab_aux = {}
301for tag in tags_localizados:
302                tt = os.path.split(tag['name'])[-1] .split('.')
303                nome_a = ''
304                for i in tt:
305                        nome_a = nome_a +'0000000'[0:7 - len(i)] + i
306                       
307                if prefixo_br <> nome_a[0:21]:
308                        continue
309                       
310                tab_aux[nome_a] = [os.path.split(tag['name'])[-1] ,str(tag['created_rev'].number)]
311
312tab_aux_keys = tab_aux.keys()
313tab_aux_keys.sort()
314tab_aux_keys.reverse()
315               
316tit = '\nTags existentes para o branch:'
317# Cria lista para exibir ao usuario  ( maximo de 10)....
318i = len(tab_aux_keys)
319if i > 10:
320                z=i   # forca mostrar todos os tags.
321else:
322                z = i
323msg = []               
324for x in range(0,z):
325                msg.append((tab_aux[tab_aux_keys[x]][0], 'R' +  tab_aux[tab_aux_keys[x]][1],0))
326               
327tit = 'Selecione um tag para gerar distribuicao do branch\n' +  branch_origem + ' :' + '\n'
328
329if msg:
330        nome_tag = msg_box_radiolist(d,tit,msg)
331        rev_tag_escolhida = ''
332        for item in msg:
333                if item[0] == nome_tag:
334                        revisao_desejada = item[1][1:]
335                        break
336        if revisao_desejada == '':
337                print 'Erro....'
338                sys.exit()
339        tag_selecionada = aponta_tags +  '/' + nome_tag
340        item = 'Tag'
341else:
342        nome_tag = n_branch_origem
343        revisao_desejada =  revisao_branch_origem
344        tag_selecionada = projeto +  '/' + n_branch_origem
345        item = 'Brc'
346       
347if item == 'Tag':
348        msg = '\n\nA seguir, sera gerado arquivo de distribuicao:\nOrigem: Tag '  + nome_tag + '\n do branch ' + branch_origem + ',\n revisao ' + revisao_desejada +  '\n\nContinuar?'
349else:
350        msg = '\n\nA seguir, sera gerado arquivo de distribuicao:\nOrigem: Branch '  + branch_origem + ',\n revisao ' + revisao_desejada +  '\n\nContinuar?'   
351if msg_box_sim_nao(d,msg) != d.DIALOG_OK:
352        sys.exit(98)
353
354#comentario_tag =  item + ' ' + nome_tag + ' R' + revisao_desejada
355comentario_tag =  nome_tag + ' R' + revisao_desejada
356comentario_tagx = nome_tag + '-R' + revisao_desejada
357
358msg_box_info(d,'\n\n\nProcessando a geracao da distribuição como solicitado.\n\n\nAguarde.')
359
360
361# Dados para executar o export:
362#
363revisao_branch_origem = revisao_desejada
364
365# Verifica a existencia de uma pasta de trabalho.
366# Nesta pasta serao gerados subdiretorios que vao conter as distribuiçoes.
367if not os.path.isdir(trabalho):
368        os.makedirs(trabalho)
369
370if os.path.isdir(caminho1):
371        retorno  = getCommandOutput('rm -fR ' + caminho1)
372
373
374revisao = cliente.export(branch_origem,
375                caminho1,
376                force=False,
377                revision=pysvn.Revision(pysvn.opt_revision_kind.number,revisao_branch_origem),
378                native_eol=None,
379                ignore_externals=False,
380                recurse=True,
381                peg_revision=pysvn.Revision(pysvn.opt_revision_kind.number, revisao_branch_origem))
382               
383if  not os.path.exists(caminho1 + os.sep + 'infodist'):
384        retorno  = getCommandOutput('mkdir ' + caminho1 + os.sep + 'infodist')
385
386#  6 - Gera arquivo com informacoes do Subversion e dados de identificação da distribuição...
387r_svn_to_html(caminho1,branch_origem,revisao_branch_origem,comentario_tag,trac)
388
389# --------------------------------------------------------------------------------------------------------------------------------------------------------------------------
390
391# Se existir um nome de script no arquivo de configuração, vai tentar executar...
392if script != '':
393        if os.path.isfile(script):
394                msg = "\nExecutando o script "  + script + " \n"
395                msg_box_info(d,msg)
396                retorno  = getCommandOutput(script)
397                msg_box_info(d,retorno)
398        else:
399                msg = "\nScript "  + script + " nao foi localizado.\n"
400                msg_box_info(d,msg)
401msg = ''
402#Solicita execucao do comando de compactaçao
403path_corrente = os.getcwd()
404os.chdir(trabalho)
405retorno  = getCommandOutput("tar -zcf " + prefixo + comentario_tagx + ".tgz ./expresso")
406os.chdir(path_corrente)
407
408msg = msg + "\nFoi gerado o arquivo " + prefixo + comentario_tagx + ".tgz \n"
409msg_box_info(d,msg)
410
411if s_ftp != '':
412    from ftplib import FTP
413    servidor_ftp = s_ftp
414    #Faz ftp para a maquina de distribuicao...
415    msg = msg +  'Iniciando copia do arquivo gerado para ambiente de distribuicao(FTP)\n'
416    msg_box_info(d,msg)
417    try:
418            ftp = FTP(servidor_ftp,'anonymous','')
419            resp = ftp.cwd(s_path)
420            msg = msg + resp + '\n'
421            msg_box_info(d,msg)
422            lista = ftp.nlst()
423            if 'R'+str(revisao_branch_origem) in lista:
424                    ftp.cwd('R'+str(revisao_branch_origem))
425                    # pode existir a pasta mas nao o arquivo....
426                    try:
427                       resp = ftp.delete(prefixo+str(revisao_branch_origem)+'.tgz')
428                    except:
429                       pass
430                    msg = msg + resp + '\n'
431                    msg_box_info(d,msg)
432                    resp = ftp.cwd('../')
433                    msg = msg + resp + '\n'
434                    msg_box_info(d,msg)
435            else:
436                    resp = ftp.mkd('R'+str(revisao_branch_origem))
437                    msg = msg + resp + '\n'
438                    msg_box_info(d,msg)
439            resp = ftp.cwd('R'+str(revisao_branch_origem))
440            msg = msg + resp + '\n'
441            msg_box_info(d,msg)
442            f = open(trabalho + os.sep + prefixo + comentario_tagx + '.tgz','rb')
443            resp = ftp.storbinary('STOR ' + prefixo + comentario_tagx + '.tgz',f)
444            msg = msg + resp + '\n'
445            msg_box_info(d,msg)
446            msg = msg + 'Verifique os dados abaixo:\n'
447            msg_box_info(d,msg)
448            resp = ftp.pwd()
449            msg = msg + 'Diretorio de distribuicao R'+str(revisao_branch_origem)+' gerado em '+servidor_ftp+' : '+resp
450            msg_box_info(d,msg)
451            resp = ftp.retrlines('LIST')
452            msg = msg + '\nConteudo gerado no diretorio acima : \n'+resp+'\n'
453            msg_box_info(d,msg)
454            ftp.close()
455
456    except:
457            msg = msg + '\nErro ao conectar no servidor FTP.\n\n\n'
458
459msg = msg + '\nProcessamento concluido.\n'
460msg_box_info(d,msg)
461# --------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.