segunda-feira, janeiro 30, 2012

como fazer mascara em campos - passo a passo

De

Flavio Lichtenstein flalix@gmail.com para a lista web2py users brasil:
 

Ola pessoal, consegui fazer as máscaras de CEP, Telefone, etc dentro do Web2Py. A seguir vai a "receita de bolo":

1) adicionar código em web2py_ajax.html
response.files.insert(3,URL(r=request,c='static',f='js/jquery.maskedinput-1.3.min.js'))

cuidado! o número três é porque já havia as referencias 0,1 e2 - cuiado para sequenciar corretamente
2) no final da(s) página(s) onde está seu código - normalmente default\minha_pagina.html, adicionar os filtros necessários como vistos abaixo - adeque à sua realidade:

 
         

   a) "pessoa" é nome da sua tabela
   b) maskMoney() não é necessário só para quem usar $$$

3) adicionar o JS de mascara em static\js - ver no final deste email 

4) em _utils (ou rotina inicial que adotar) colocar a classe que Bruno enviou --> repare que alterei  para funcionar "no meu código" (Bruno, obrigado por ter enviado e alertado)

# do Bruno Rocha em 23/01/2012
class REMOVE_MASK(object):
    def __init__(self, symbols=["_",".","-","/",")","("," "]):
        # print 'symbols', symbols
        self.symbols = symbols

    def __call__(self, value):
            for symbol in self.symbols:
                value = value.replace(symbol, "")
                # print 'value',value
                # print 'symbol', symbol
            return (value, None)

5) nas definições do(s) campo(s) da(s) tabela(s) onde ocorrerem a máscara deve-se adicionar  "REMOVE_MASK" (como alertou Bruno) de forma que os caracteres sejem removidos "antes do post"

exemplo:

SQLField('cpf','string', length=11, unique=True, label="CPF", \
                comment="cadastro de pessoa física", requires=REMOVE_MASK([".", "-"])),

---------------------------------------------------------------------------------------------------------
--- JS - em static\js --> adicionar:  jquery.maskedinput-1.3.min.js --> js da digitalbush
como enviado pela Relsi, veja o email anterior dela, onde pode-se ver um exemplo com html puro - não em Web2py (obrigado Relsi).

---------------------------------------------------------------------------------------------------------
/*
    Masked Input plugin for jQuery
    Copyright (c) 2007-2011 Josh Bush (digitalbush.com)
    Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license
    Version: 1.3
*/
(function(a){var b=(a.browser.msie?"paste":"input")+".mask",c=window.orientation!=undefined;a.mask={definitions:{9:"[0-9]",a:"[A-Za-z]","*":"[A-Za-z0-9]"},dataName:"rawMaskFn"},a.fn.extend({caret:function(a,b){if(this.length!=0){if(typeof a=="number"){b=typeof b=="number"?b:a;return this.each(function(){if(this.setSelectionRange)this.setSelectionRange(a,b);else if(this.createTextRange){var c=this.createTextRange();c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",a),c.select()}})}if(this[0].setSelectionRange)a=this[0].selectionStart,b=this[0].selectionEnd;else if(document.selection&&document.selection.createRange){var c=document.selection.createRange();a=0-c.duplicate().moveStart("character",-1e5),b=a+c.text.length}return{begin:a,end:b}}},unmask:function(){return this.trigger("unmask")},mask:function(d,e){if(!d&&this.length>0){var f=a(this[0]);return f.data(a.mask.dataName)()}e=a.extend({placeholder:"_",completed:null},e);var g=a.mask.definitions,h=[],i=d.length,j=null,k=d.length;a.each(d.split(""),function(a,b){b=="?"?(k--,i=a):g[b]?(h.push(new RegExp(g[b])),j==null&&(j=h.length-1)):h.push(null)});return this.trigger("unmask").each(function(){function v(a){var b=f.val(),c=-1;for(var d=0,g=0;de.placeholder;while(g++length){var m=b.charAt(g-1);if(h[d].test(m)){l[d]=m,c=d;break}}if(g>b.length)break}else l[d]==b.charAt(g)&&d!=i&&(g++,c=d);if(!a&&c+10,k);else if(a||c+1>=i)u(),a||f.val(f.val().substring(0,c+1));return i?d:j}function u(){return f.val(l.join("")).val()}function t(a,b){for(var c=a;ce.placeholder)}function s(a){var b=a.which,c=f.caret();if(a.ctrlKey||a.altKey||a.metaKey||b<32)return!0;if(b){c.end-c.begin!=0&&(t(c.begin,c.end),p(c.begin,c.end-1));var d=n(c.begin-1);if(dd].test(g)){q(d),l[d]=g,u();var i=n(d);f.caret(i),e.completed&&i>=k&&e.completed.call(f)}}return!1}}function r(a){var b=a.which;if(b==8||b==46||c&&b==127){var d=f.caret(),e=d.begin,g=d.end;g-e==0&&(e=b!=46?o(e):g=n(e-1),g=b==46?n(g):g),t(e,g),p(e,g-1);return!1}if(b==27){f.val(m),f.caret(0,v());return!1}}function q(a){for(var b=a,c=e.placeholder;bif(h[b]){var d=n(b),f=l[b];l[b]=c;if(dh[d].test(f))c=f;else break}}function p(a,b){if(!(a<0)){for(var c=a,d=n(b);cif(dl[d],l[d]=e.placeholder;else break;d=n(d)}u(),f.caret(Math.max(j,a))}}function o(a){while(--a>=0&&!h[a]);return a}function n(a){while(++a<=k&&!h[a]);return a}var f=a(this),l=a.map(d.split(""),function(a,b){if(a!="?")return g[a]?e.placeholder:a}),m=f.val();f.data(a.mask.dataName,function(){return a.map(l,function(a,b){return h[b]&&a!=e.placeholder?a:null}).join("")}),f.attr("readonly")||f.one("unmask",function(){f.unbind(".mask").removeData(a.mask.dataName)}).bind("focus.mask",function(){m=f.val();var b=v();u();var c=function(){b==d.length?f.caret(0,b):f.caret(b)};(a.browser.msie?c:function(){setTimeout(c,0)})()}).bind("blur.mask",function(){v(),f.val()!=m&&f.change()}).bind("keydown.mask",r).bind("keypress.mask",s).bind(b,function(){setTimeout(function(){f.caret(v(!0))},0)}),v()})}})})(jQuery)

terça-feira, maio 03, 2011

sistemas para gerenciamento de projetos opensource



Collabtive http://collabtive.o-dyn.de/ (php)
ProjectPier http://www.projectpier.org/ (php)
Redmine http://www.redmine.org/ (ruby)
DotProject http://www.dotproject.net/ (php)



domingo, abril 24, 2011

Otimizando Postgresql Shared_buffers

Para isso, antes, é necessário alterar o limite de shared_memory do sistema

(retirado de http://developer.postgresql.org/pgdocs/postgres/kernel-resources.html e http://www.sqlmagazine.com.br/Artigos/Postgre/02_Otimizacao.asp)

sysctl -w kernel.shmmax=879869184 #aproximadamente 800MB
 sysctl -w kernel.shmall=4194304 #4kb

ou 

echo 8179869184 > /proc/sys/kernel/shmmax
echo 4194304 > /proc/sys/kernel/shmall
--
Atenciosamente


Alexandre Andrade
Hipercenter.com Classificados Gratuitos

sexta-feira, janeiro 07, 2011

Migrando tipo de campo no web2py em 6 passos


1. crie um segundo campo com tipo de dado desejado na mesma tabela

Field('valor2','decimal(20,2)'),

2. Crie uma rotina de transformação no dado desejado
for row in db(db.execucao_orcamentaria.id>0).select():
    row.update_record(valor2=to_decimal(row.valor))
    
3. Exclua a linha original
    Field('ano_referencia','integer',default=ANO,writable=False),
>deveria estar aquiv
    Field('valor2','decimal(20,2)'),
    Field('data_execucao', 'date',label='Data de Execução da Despesa',requires=data,represent= lambda field: make_data(field))
   
4. insira a nova linha, com o tipo de dado desejado

    Field('ano_referencia','integer',default=ANO,writable=False),
    Field('valor','decimal(20,2)',requires=E_DINHEIRO()),
    Field('valor2','decimal(20,2)'),
    Field('data_execucao', 'date',label='Data de Execução da Despesa',requires=data,represent= lambda field: make_data(field))
   
5. atualize o novo campo com os valores do anterior.

for row in db(db.execucao_orcamentaria.id>0).select():
    row.update_record(valor=row.valor2)
    
6. Exclua o campo 2
--
Atenciosamente


Alexandre Andrade
Hipercenter.com Classificados Gratuitos e Inteligentes

segunda-feira, novembro 29, 2010

E_DINHEIRO Validador para web2py

Criei um validator para web2py, mas ao nomear, fugi do padrão IS_SOMETHING, já que o formato é específico do Brasil.

Assim, usei E_DINHEIRO, apenas para facilitar a formatação. O tipo de campo para armazenamento deve ser decimal, mas é necessário excluir a linha que possui a palavra 'double' em web2py_ajax.html, pois ele impede a digitação de vírgulas:
-------------------------------------------------------------------------------------------------------------------------------
jQuery('input.double,input.decimal').live('keyup', function(){this.value=this.value.reverse().replace(/[^0-9\-\.]|[\-](?=.)|[\.](?=[0-9]*[\.])/g,'').reverse();});
------------------------------------------------------------------------------------------------------------------------------
Parece que pode ser possível adaptar a linha acima para aceitar vírgulas, quem souber como fazer deixe um comentário.



class E_DINHEIRO(object):
    def __init__(self, format=True, error_message='Digite o valor!'):
        self.format = format
        self.error_message = error_message
    def __call__(self, value):
            

            d=str(value)
            
            d = d.replace('.','')
            
            d = d.replace(',','.')
            
            #return (value, valor[-3:-2])
            try:
                return (d, None)
            except:
                return (d,str(d)+'o valor digitado não é um número válido')
 
    def formatter(self, value):
            value  = str(value)
            c = []
            for d in value:
               if d.isdigit():
                   c.append(d)
            value = str(''.join(c))
            l = len(value) #10 = 1000000000 = 10.000.000,00
            i = l - 2 #8
            p = i / 3 #2
            r = (l % 3) #2
            #p = 3
            pf = i-1
            if l == 1:
                formatado = '0,0'+value
            
            elif l == 2:
                formatado = '0,'+value
            elif l > 2:
                d = ','+value[-2:]
                s = ''
                n = r+1
                s += value[0:r+1]
                if i > 3:
                    while n < i:
                        pt = n + 3
                        s += '.'+ value[n:pt] 
                        n = pt
                                
                formatado = s+d        
            else:
                formatado = value
            return formatado

Use o validator como um validator comum do web2py:

Field('preco','decimal(20,2)',requires=E_DINHEIRO(),represent=lambda field:currency(field), label='Preço'),

Para permitir apresentar o formato quando não está usando formulário,  use:


def currency(value):
  

    import locale
    locale.setlocale( locale.LC_ALL, 'pt_BR.UTF-8' )
    value = locale.currency(value,grouping=True)
    return value

em uma view:

{{=currency(row.preco)}}



--
Atenciosamente

--
=========================
Alexandre Andrade
Hipercenter.com

quinta-feira, novembro 25, 2010

Validator IS_CPF_OR_CNPJ para web2py

class IS_CPF_OR_CNPJ(object):

    def __init__(self, format=True, error_message='Digite apenas os números!'):
        self.format = format
        self.error_message = error_message
    def __call__(self, value):
        try:
            #return (value, 'cpf incorreto'+str(value))
            #return (value, 'cpf incorreto'+str(cl))
            c = []
            for d in value:
               if d.isdigit():
                   c.append(d)
            cl = str(''.join(c))
            #return (value, 'cpf incorreto'+str(cl))
            if  len(cl) == 11:
                cpf = cl
                cnpj = None
            elif  len(cl) == 14:
                cpf = None
                cnpj = cl
            else:
                return (value, 'Número de dígitos incorreto para CPF ou CNPJ')

            #return(cpf,'aquiok'+str(len(cpf)==11))
            if cpf:
              
                def valida(value):
                  
                    def calcdv(numb):
                      
                        result = int()
                        seq = reversed(((range(9, id_type[1], -1)*2)[:len(numb)]))
                        #return (value,'to fundo1')
                        for digit, base in zip(numb, seq):
                            result += int(digit)*int(base)
              
                        dv = result % 11
                        #return (value,'to fundo1'+str(dv))
                        return (dv-10) and dv or 0
                  
                    id_type = ['CPF', -1]
                  
                  
                    numb, xdv = value[:-2], value[-2:]
                  
                    dv1 = calcdv(numb)
                    #return (value,'entrei'+str(dv1))
                    dv2 = calcdv(numb + str(dv1))
                    return (('%d%d' % (dv1, dv2) == xdv and True or False), id_type[0])  
          
          
                try:
                    cpf=str(value)
                    #return(cpf,'aquiok'+str(len(cpf)==11))
                    if len(cpf)>=11:
                      
                        #return (value, 'cpf acima de 11')
                        c = []
                        for d in cpf:
                           if d.isdigit():
                               c.append(d)
                        cl = str(''.join(c))
                        #return (value, 'cpf incorreto'+str(cl))
                        if  len(cl) == 11:
                            if valida(cl)[0] == True:
                                return(value,None)
                            else:
                                return (value, 'cpf inválido')
                        elif  len(cl) < 11:
                            return (value, 'cpf incompleto')
                        else:
                            return (value, 'cpf tem mais de 11 dígitos')
                        if cpf[3] != '.' or cpf[7] != '.' or cpf[11] != '-' :
                            return (value, 'cpf deve estar no formato 000.000.000-00'+cpf[11])
                    else:
                        return (value, 'cpf deve estar no formato 000.000.000-00')
                    #return(cpf,'aquiok'+str(len(cpf)==11))
                except:
                    return (value, 'algum erro'+str(value))
            elif cnpj:

                   """ Pega apenas os 12 primeiros dígitos do CNPJ e gera os 2 dígitos que faltam """
                   inteiros = map(int, cnpj)
                   novoCnpj = inteiros[:12]

                   prod = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
                   while len(novoCnpj) < 14:
                      r = sum([x*y for (x, y) in zip(novoCnpj, prod)]) % 11
                      if r > 1:
                         f = 11 - r
                      else:
                         f = 0
                      novoCnpj.append(f)
                      prod.insert(0, 6)
                   #return(str(novoCnpj),'aquiok')
                   """ Se o número gerado coincidir com o número original, é válido """
                   if novoCnpj == inteiros:
                      #cnpj = ''.join(novoCnpj)
                    
                      return(str(cnpj),None)

                   else:
                      return (value, 'CNPJ não é válido')
              


        except:
            return (value, 'algum erro'+str(value))
    def formatter(self, value):
            if len(value)==11:
                formatado = value[0:3]+'.'+value[3:6]+'.'+value[6:9]+'-'+value[9:11]
            elif len(value)==14:
                formatado = value[0:2]+'.'+value[2:5]+'.'+value[5:8]+'/'+value[8:12]+'-'+value[12:14]
            else:
                formatado = value
            return formatado

Validator TELEFONE para web2py: IS_TELEFONE

Também tive que criar um validator para telefone, com ddd


class IS_TELEFONE(object):
    def __init__(self, format=True, error_message='Digite apenas os números!'):
        self.format = format
        self.error_message = error_message
    def __call__(self, value):
        try:
            telefone=str(value)
            #return(cpf,'aquiok'+str(len(cpf)==11))
            if len(telefone)>=10:
                #return (value, 'cpf acima de 11')
                c = []
                for d in telefone:
                   if d.isdigit():
                       c.append(d)
                cl = str(''.join(c))
                #return (value, 'cpf incorreto'+str(cl))
                if  len(cl) == 10:
                    return(str(cl),None)
                elif  len(cl) < 10:
                    return (value, 'telefone incompleto')
                else:
                    return (value, 'o telefone tem mais de 10 dígitos')
                if cpf[2] != '-' or cpf[7] != '-':
                    return (value, 'o telefone deve estar no formato 00-0000-0000')
            else:
                return (value, 'O telefone deve estar no formato 00-0000-0000')
            #return(cpf,'aquiok'+str(len(cpf)==11))
        except:
            return (value, 'algum erro'+str(value))
    def formatter(self, value):
            if len(value) == 10:
                formatado = value[0:2]+'-'+value[2:6]+'-'+value[6:10]
            else:
                formatado = value      
            return formatado


--
Atenciosamente

--
=========================
Alexandre Andrade
Hipercenter.com

Validator CPF para web2py: IS_CPF

Por necessidade, criei um validator para ser usado no Web2py:


class IS_CPF(object):
    def __init__(self, format=True, error_message='Digite apenas os números!'):
        self.format = format
        self.error_message = error_message
    def __call__(self, value):

        def valida(value):
          
            def calcdv(numb):
              
                result = int()
                seq = reversed(((range(9, id_type[1], -1)*2)[:len(numb)]))
                #return (value,'to fundo1')
                for digit, base in zip(numb, seq):
                    result += int(digit)*int(base)
      
                dv = result % 11
                #return (value,'to fundo1'+str(dv))
                return (dv-10) and dv or 0
          
            id_type = ['CPF', -1]
          
          
            numb, xdv = value[:-2], value[-2:]
          
            dv1 = calcdv(numb)
            #return (value,'entrei'+str(dv1))
            dv2 = calcdv(numb + str(dv1))
            return (('%d%d' % (dv1, dv2) == xdv and True or False), id_type[0])  
  
  
        try:
            cpf=str(value)
            #return(cpf,'aquiok'+str(len(cpf)==11))
            if len(cpf)>=11:
              
                #return (value, 'cpf acima de 11')
                c = []
                for d in cpf:
                   if d.isdigit():
                       c.append(d)
                cl = str(''.join(c))
                #return (value, 'cpf incorreto'+str(cl))
                if  len(cl) == 11:
                    if valida(cl)[0] == True:
                        return(value,None)
                    else:
                        return (value, 'cpf inválido')
                elif  len(cl) < 11:
                    return (value, 'cpf incompleto')
                else:
                    return (value, 'cpf tem mais de 11 dígitos')
                if cpf[3] != '.' or cpf[7] != '.' or cpf[11] != '-' :
                    return (value, 'cpf deve estar no formato 000.000.000-00'+cpf[11])
            else:
                return (value, 'cpf deve estar no formato 000.000.000-00')
            #return(cpf,'aquiok'+str(len(cpf)==11))


        except:
            return (value, 'algum erro'+str(value))
    def formatter(self, value):
          
            formatado = value[0:3]+'.'+value[3:6]+'.'+value[6:9]+'-'+value[9:11]
            #formatado = value
            return formatado

--
Atenciosamente

--
=========================
Alexandre Andrade
Hipercenter.com

domingo, novembro 14, 2010

os carros mais roubados e os carros menos roubados

A Susep disponibiliza uma estatística completa e detalhada de roubos de carros em todo o território nacional.

Pode-se escolher o nível de detalhamento, o estado,, entre várias opções.

O link direto é http://www.susep.gov.br/menuestatistica/RankRoubo/menu1.asp

--
Atenciosamente

--
=========================
Alexandre Andrade
Hipercenter.com

quarta-feira, novembro 10, 2010

paypal x moneybookers x google checkout

Estive comparando os serviços de intermediação de pagamentos e fiz a seguinte comparação para quem está no brasil e precisa receber em dólares, de compradores de outros países

taxas (iniciais)

paypal (7,4% + 0.40BRL) para transações oriundas de outros países.

moneybookers (2,9% +0.29EUR +1% para retirar o dinheiro + 1,99% para conversões de moedas)

google checkout (2,9% + $0,30 +1% para recebimento internacional)


Fica evidente que o menor custo para operar é o do google.






--
Atenciosamente

--
=========================
Alexandre Andrade
Hipercenter.com

terça-feira, novembro 02, 2010

converter formatos de arquivo lossless (ape, wv, flac) com .cue para mp3 no linux

Hoje tive necessidade de converter uma discografia lossless no linux para formato mp3.


1.Formato .flac para mp3

usei o pacpl

# apt-get install pacpl

e depois fazer a conversão em todos os subdiretórios

pacpl --to mp3 -r diretorio/


2. Formato .wv com .cue para .mp3

Instalação do shntool

# apt-get install shntool

agora a conversão do arquivo wv para .flac (não consegui converter diretamente para mp3, então usei um formato intermediário)

# shntool conv -i wv -o mp3 arquivo.wv

agora, converter de .flac para .mp3

# pacpl --to mp3  arquivo.flac

e por fim, dividir o arquivo mp3 usando o arquivo .cue, usando o mp3split

baixe os arquivos/pacotes para sua distro em http://mp3splt.sourceforge.net/mp3splt_page/downloads.php e

# mp3split arquivo.mp3 -c arquivo.cue -a

voiĺá, todos os arquivos nomeados e com tags.


3. Formato ape com cue.

é necessário instalar a biblioteca jmac (mac) com

# apt-get install libjmac-java

Se necessário, instale o java
(inclua a linha abaixo no arquivo /etc/apt/sources.list)

# deb http://archive.canonical.com/ubuntu lucid partner

e instale

# apt-get install sun-java6-jre

então, converta para wav

# jmac d arquivo.ape arquivo.wav

e de wav para mp3:

# pacpl --to mp3  arquivo.flac

Finalmente, dividir o arquivo .mp3 :

# mp3split arquivo.mp3 -c arquivo.cue -a

--
Atenciosamente

--
=========================
Alexandre Andrade
Hipercenter.com

quinta-feira, outubro 28, 2010

Usando VNC via ssh

A dica é simples:

vncviewer -via user@host host:1

Onde 1 é o número do display no vnc4server.


--
Atenciosamente

--
=========================
Alexandre Andrade
Hipercenter.com

Como converter .flac (loseless) para mp3 no linux

No ubuntu 10.10, basta um:

apt-get install soundconverter


A interface é simples e intuitiva, veja em

http://soundconverter.berlios.de/

--
Atenciosamente

--
=========================
Alexandre Andrade
Hipercenter.com

quarta-feira, outubro 20, 2010

Investir em pessoas - empreste seu dinheiro e tenha mais retorno

O Fairplace é uma comunidade de empréstimos.

Você pode tanto emprestar (um mínimo de 50 reais) quanto pegar emprestado.

www.fairplace.com.br
--
Atenciosamente

--
=========================
Alexandre Andrade
Hipercenter.com

terça-feira, outubro 19, 2010

Site para avaliação de sites

Algumas vezes queremos ter uma referência externa sobre algum site.

Uma forma interessante são sites que avaliam o valor em dólares de um site, com base em estatísticas disponíveis na web.

Um site que pode ser utilizado para isso é

http://mysitecost.com/

Ele consegue fazer uma avaliação bem pé no chão no meu entender.

Já o
http://bizinformation.org/br/ não parece fundamentar muito suas avaliações. Os valores parecem exagerados para sites pequenos e subestimados para sites grandes.



--
Atenciosamente

--
=========================
Alexandre Andrade
Hipercenter.com

quinta-feira, setembro 02, 2010

] DICA--otimizando gedit para completar codigo python



interessante para quem so utiliza gedit, autocompleta codigo python

http://github.com/fenrrir/geditpycompletion
--
        Ovidio Marinho Falcao Neto
             ovidioccg@gmail.com
         Tecnologia da Informaçao
         Casa Civil do Governador
         83 3214 7885 - 88269088
                  Paraiba




--
Atenciosamente

--
=========================
Alexandre Andrade
Hipercenter.com

sexta-feira, junho 18, 2010

Modelagem de Processos - Resumo

1. Foco no resultado do processo: antes de pensar nas atividades envolvidas, defina qual o resultado devera ser produzido do ponto de vista do ciente.
2. Conheça as necessidades do cliente - > realize pesquisas antes de modelar o processo
3. Conhecidas as necesidades, documente sua especificação > Carta de Serviços
4. Indentificar possíveis insumos (material de consumo), referências (normas) e infra-estrutura (equipamentos)
5. Cada pessoa envolvida no processo descreve suas próprias atividades, gerando comprometimento e velocidade.
6. Definir critérios de aceitação para os insumos, referências, infra-estrutura
7. Se todos os fatores convergirem, teremos assegurado a qualidade do produto.
8. No mapeamento das atividades, considerar as contigências e não apenas o 'caminho feliz'
9. Simule, para testar a aplicabilidade do processo



--
Atenciosamente

--
=========================
Alexandre Andrade
Hipercenter.com

quinta-feira, junho 10, 2010

Simulador de Processos Opensource


Após muito tempo, finalmente encontrei a cabeça do bacalhau: um simulador de processos visual e gratuito.



--
Atenciosamente

--
=========================
Alexandre Andrade
Hipercenter.com

domingo, maio 23, 2010

Ciclo de relase do OpenBSD


O vídeo completo pode ser visto aqui:

http://www.youtube.com/watch?v=i7pkyDUX5uM&feature=player_embedded

Mas basicamente, o segredo do BSD para as versões saírem sempre na data programada é:

- no início do período, se definem as correções e pequenas melhorias em relação à versão anterior, os novos recursos e as grandes mudanças são incluídas no ínicio.

- Gerar snapshots completos todo dia, dessa forma sempre se pode testar o estágio atual de desenvolvimento, e os problemas vão sendo corrigidos e a versão evolui.

- no final do período, estabelece-se um período de lock-in, a partir do qual são apenas alguns ajustes finos.
- todas as datas de lock e unlock são surpresas, porque pessoas avisadas são mais preguiçosas. Se não avisadas, as pessoas buscam terminar a tarefa e os testes o quanto antes.
- desenvolvedores com baixo nível de testes são punidos.


--
Atenciosamente

--
=========================
Alexandre Andrade
Hipercenter.com