quinta-feira, 28 de outubro de 2010

Porque Não Comprar a HP C4780 ou Qualquer uma da C4700 Series

Você gosta de gastar dinheiro? Então, se você gosta, deveria comprar a impressora que eu comprei, a HP C4780 da série C4700. Antes de fazer esta cagada eu tinha uma HP PSC 1315, que faz parte das impressora indestrutíveis da HP, mas de que adianta ter uma impressora indestrutível se a tinta acaba toda hora e você não pode recarregar?

A HP C4780 é assim, ela tem um cartucho que tem um cuspe de tinta. Você não imprime quase nada e acabou. 6 ml de tinta preta e 2 ml de cada cor. Aí você diz,: Beleza, então eu recarrego (Foi o que eu disse). Moleza. E a recarga pega bem pra caramba, muito melhor que os cartuchos da 1315, mas só tem um problema, chega uma hora que a impressora mente para você, ela diz que seu cartucho está com defeito. DEFEITO. É MENTIRA. Não deu nem dois meses de uso e a minha maldita impressora disse isso. Recarreguei umas 4 vezes, um cuspe para cada recarga e ela começou com esse papo.

Se você tirar o cartcho, colocar e tirar e colocar os cartuchos em uma certa ordem, ela imprime mais um pouquinho e aí, descobre que esse cartucho é usado demais. E dá a mensagem. Cartucho bom esse. Se recuperou e ficou doente novamente. Experimenta colocar esse cartucho em outra impressora HP C4780 ou qualquer uma outra que o aceite. Sabe o que acontece? Funciona perfeitamente.

Na internet dizem que você pode tapar contatos de chips e tudo mais. Remover bateria da memória CMOS ou fazer uma troca entre 3 ou 4 cartuchos diferentes, mas tem gente que já disse que essa troca acaba dando o mesmo problema depois de um tempo.

Então, a HP está abusando. Eu comprei o produto, tenho o direito de recarregar o cartucho. O cartucho é meu, a impressora é minha. Não quer dar garantia, não dá. Mas impedir que eu use um cartucho recarregado é um abuso. Daqui a pouco a empresa vai começar a colocar um mecanismo para que a própria impressora queime os cartuchos de tempos em tempos. Valido por apenas 3 meses, favor trocar. Parece até que é comida enlatada.

Então, por mais que a impressora imprima bem, o que nem é tão verdade assim, pelo menos em modo normal, não vale a pena comprar impressoras da HP. Antes de comprar, pesquisa uma impressora que dá menos dor de cabeça para recarregar. Se ela quebrar de vez em quando, é até melhor. Porque dois cartuchos costumam ser o preço de uma impressora.

Depois as empresas vem com este papo de sustentabilidade. Sustentabilidade é o cacete. Sustentar o que?  Se eu tenho que comprar um cartucho novo a cada 2 meses? Sustentar a família do cara que fez isso e aquela cambada de gente sem carater que faz uma coisa dessas. Só se for, porque não há nada de ecológico nessa atitude.

Talvez eu encontre uma forma de RESET decente para o cartucho 60 da HP, mas tudo indica que vou comprar outra impressora que seja menos custosa, porque a HP C4780 parece não ser tão cara, mas no final das contas é caríssima.

Alguém aí quer comprar a minha? 50 reais ta levando. 2 meses de uso. Se descobrirem como fazer RESET na coisa, por favor, me contem.

Você acha que eles nào te enganam, é? Dá uma olhadinha no quanto de tinta que tem dentro de um cartucho HP 901. O HP 60 é a mesma coisa.

sexta-feira, 1 de outubro de 2010

Auto Height em um IFrame

Bom, eu queria aumentar o tamanho de um IFrame automaticamente, mas tem alguns detalhes extras nos meus requisitos. Não me perguntem porque eu tive que fazer isso, mas tive que fazer.

Isso tinha que ser feito de dentro do IFrame porque o bixinho carrega um código em Ext.js e o Ext funciona no Ext.onReady. Ou seja, depois que carregou a página. Se o javascript estivesse na página principal executaria o código no load do body, mas nessa hora o IFrame não estaria totalmente carregado.

Então, no final do código do Ext.js, depois que tudo foi carregado, você coloca o seguinte código:

var iframe = window.top.document.getElementById('ID_DO_FRAME');
  iframe.style.height = iframe.contentDocument.height + 50;

Se você adicionar algo no IFrame, chame uma função com esse código depois e pronto, funciona. Se você estiver na html principal, use o código abaixo.

var iframe = document.getElementById('ID_DO_FRAME');
  iframe.style.height = iframe.contentDocument.height + 50;

quinta-feira, 19 de agosto de 2010

TOMCAT Não Carrega as LIBS de Projeto com MAVEN

O problema é o seguinte: Você está usando o eclipse com o TOMCAT para desenvolver um projeto MAVEN e quando levanta o TOMCAT na aba Servers, dá um erro. O erro mais comum está relacionado ao Spring e é este.

java.lang.ClassNotFoundException: 
org.springframework.web.context.ContextLoaderListener

Isso acontece porque as bibliotecas do MAVEN não são copiadas para sua pasta WEB-INF/libs. Aí, para resolver o problema, você pode colocar todas as libs do MAVEN no lib do TOMCAT, mas isso é irritante. E se fosse para fazer isso manualmente, eu não usaria o MAVEN, estaria com o ANT até agora. Como resolver o problema então?

Mágica. Você precisa adicionar o plugin TOMCAT MAVEN no seu POM.xml
Coloque o código abaixo no seu POM


<plugin>
 <groupId>org.codehaus.mojo</groupId>
 <artifactId>tomcat-maven-plugin</artifactId>
 <version>1.0-beta-1</version>
 <configuration></configuration>
</plugin>

quinta-feira, 29 de julho de 2010

Habilitando HTML 5 no seu Firefox 3.6

Você quer estudar HTML 5, mas seu Firefox não exibe nada na tela?

Você precisa habilitar a opção de parse do HTML 5 para que o seu navegador exiba tudo direitinho.

1 Digite about:config na barra de endereços do seu Firefox.
2 Clique no botão em "Serei cuidadoso, prometo!" que aparece na tela de aviso.
3 Digite html5.enable na barra de filtros que aparece no topo da página
4 Você verá que o valor atual é false, clique para mudá-lo para true.

Pronto, está feito.

Para quem não encontrou a variável html5.enable clique com o botão direito do mouse dentro do Firefox,
depois clique em new -> booleane coloque html5.enable e escolha o valor true.

terça-feira, 15 de junho de 2010

Wicket + Google App Engine - Nem Sempre Faz o Login

O cenário é o Google App Engine com o Wicket: você está usando o login do Wicket e quando o usuário clica para ir até a LoginPage e se autentica, o login não funciona. Se você se loga várias vezes, aí sim, uma hora acaba conseguindo se logar.

Quando tentamos pegar o usuário que armazenado na sua classe Session que extends AuthenticatedWebSession, o usuário está nulo. Curiosamente, se você tenta acessar uma página anotada com @AuthorizeInstantiation("ADMIN") por exemplo, tudo funciona bem, o problema acontece apenas no login voluntário.

Depois de muito pesquisar e com a ajuda de @ronaldtm (créditos para ele), descobrimos que o Wicket é stateless em relação a Session do usuário até que ele faça login e por algum motivo, com o AppEngine dá o erro até mesmo depois do login.

Para resolver o problema você precisa forçar a criação da Sessão no construtor da sua LoginPage por exemplo. Coloque a seguinte linha de código.

WicketSession.get().bind();

Onde WicketSession é a classe que extends AuthenticatedWebSession

Se você quiser criar a sessão assim que o usuário acessar sua página para poder armazenar alguma informação, aí você coloca isso no construtor de uma BasePage por exemplo e todas as suas páginas vão forçar a criação da Sessão, mas isso consome recursos do seu servidor.

quinta-feira, 6 de maio de 2010

App Engine + Wicket - Exibindo Imagens Armazenadas em Blob

O cenário aqui é: Você está usando o App Engine do Google e está armazenando sua imagem em um Blog da camada de persistência deles.

Você não pode usar as imagens que foram enviadas pelos usuários diretamente porque o AppEngine não permite acesso a disco. A não ser que você use uma API mágica que uma alma caridosa criou, que simula um file system no App Engine. Eu não testei essa API, então tive que colocar no Blog da API de datastore mesmo.

Agora você quer exibir esta imagem na tela, como faz? (#comofaz) Faz assim oh!

Coloca no seu HTML a tag abaixo:

<img wicket:id="imagem"/>

E depois, na sua classe você faz da seguinte forma


DynamicImageResource dir = new DynamicImageResource("jpg") {
    @Override
    protected byte[] getImageData() {
        return produto.getImagem().getBytes();
    }
};           
Image img = new Image("imagem",dir);
add(img);


As classes que você precisa importar são:
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.markup.html.image.resource.DynamicImageResource;

Onde está escrito produto no código acima você deve entender como um objeto persistente no AppEngine que tem uma propriedade imagem do tipo Blob (google.appengine.api.datastore.Blob)

segunda-feira, 19 de abril de 2010

Google App Engine - Wicket e Problemas com a classe WebApplication

O cenário do problema é o seguinte: Você está tentando fazer seu deploy no Google
App Engine e sua aplicação está integrada com o Wicket. Quando você tenta acessar sua
aplicação publicada acontecem o seguinte erro

WicketRuntimeException: Unable to create application
Caused by: java.lang.ClassNotFoundException: --- sua classe que deriva de WebApplication

O mais estranho é que funiona no AppEngine que está configurado no seu Eclipse.
Coloque a sua classe principal (extends WebApplication) na sua source folder, que
normalmente se chama src.

Isso mesmo, sua classe principal vai ficar na raiz do aplicativo. Eu sei que a SUN
não recomenda, mas é isso ai. Agora vai funcionar.

Não se esqueça de atualizar seu WEB.XML.

quarta-feira, 24 de fevereiro de 2010

Problemas na Instalação de Plugins do Eclipse no Windows 7

Você acabou de instalar o Windows 7 e foi configurar seu Eclipse. Tentou instalar uns plugins através do IDE e não conseguiu. A coisa não instala de forma nenhuma? É, eu passei por isso.

A solução para o problema é simples, rode o seu Eclipse em modo administrador e pronto, ele vai conseguir instalar tudo.

PS: Não instale o JDK 64 bits a menos que você baixe o Eclipse 64, mas mesmo assim, não recomendo até que isso esteja mais testado no WINDOWS

Você também pode optar por estar sempre em modo administrador no Windows 7 (ainda não vi onde é), aí, qualquer programa executaria com permissões avançadas. Eu não recomendo. O W7 não é tão irritante quanto o Vista e esse recurso melhora um pouco a segurança do sistema.

segunda-feira, 22 de fevereiro de 2010

Virtual Box - Instalando Adicionais para Convidados - Vista Host - Ubuntu Guest

Veja como instalar as opções adicionais para convidados utilizando o Windows Vista como Host e o Ubuntu como Guest. Assim você habilita suporte para USB, integração de mouse, diferentes resoluções de teals, modo Seamless, full screen e etc.

Os Adicionais Para Convidados servem para aumentar as funcionalidades do sistema convidado (Guest). No meu caso, utilizo o Windows Vista como Host (Hospedeiro) e o Ubuntu 8 como guest.

Depois de instalar esses adicionais você poderá utilizar resoluções mais altas no convidado, modo Full Screen, Seamless (Windows e Linux na mesma tela), integração de mouse (não precisa apertar o ctrl para trocar de sistema.), compartilhamento de pastas e USB.

Veja bem, essa instalação ocorre sempre no sistema convidado e não no hospedeiro, no meu caso, o convidado é o Linux Ubuntu 8. Muitos não conseguem instalar porque acham que devem fazer isso no hospedeiro. Repito: A instalação ocorre no GUEST (Convidado).

Instalar isto no Ubuntu é bem simples. Não tem mistério algum. Inicie a sua máquina e antes que o seu linux esteja pronto para login, clique no menu "Dispositivos" -> "Instalar Adicionais para Convidados". Veja a imagem a baixo.


Faça isso antes que o sistema convidado esteja pronto para login.

Como resultado dessa operação, a maquina virtual irá montar um CD-ROM em seu Ubuntu, conforme a imagem mais abaixo.

 

Tudo que você precisa fazer é executar o arquivo VBoxLinuxAdditions.run como super usuário. Você pode abrir o Nautilus como root e clicar duas vezes no arquivo.  Ou executar o comando via console.

Para executar o comando via console, abra o terminal e digite a linha a seguir.

sudo /media/cdrom/VBoxLinuxAdditions.run

quinta-feira, 18 de fevereiro de 2010

Compartilhamento de Pastas - Vista Host - Ubuntu Guest no Virtual Box

Aprenda a compartilhas pastas entre o seu windows como Host (Hospedeiro) e o Ubuntu 8 como Guest (Convidado).

Antes de mais nada, você precisa instalar os recursos Adicionais para Convidados em seu sistema operacional convidado, neste caso, o Ubuntu. Veja como neste link: Virtual Box - Instalando Adicionais para Convidados - Vista Host - Ubuntu Guest

    Com os adicionais instalados e a maquina virtual desligada, vamos ao que interessa: Selecione a maquina virtual para a qual deseja compartilhar as pastas. A esquerda na aba "Datalhes" clique em "Pastas Compartilhadas". Veja a imagem abaixo.


Uma nova janela se abrirá. Selecione todas as pastas que você deseja compartilhar. Como exemplo, vou utilizar o nome "pasta1". O nome que a pasta terá no compartilhamento pode ser diferente do nome do Windows. Veja a imagem para maiores detalhes:


No meu caso, eu adicionei toda apartição D com o nome "Conversao" e na imagem, estou preste a adicionar D:\SnapFiles com o nome de "pasta1" no compartilhamento.

Compartilhe quantas pastas você quiser e coloque marque a opção "Apenas para Leitura" se não quiser que o Ubuntu tenha permissão de edição. A parte do windows está pronta. Não é preciso nenhuma outra configuração, mas é necessário reiniciar a maquina virtual para o compartilhamento ficar disponível para o sistema operacional convidado. Agora, vamos ao linux.

Para montar a pasta compartilhada via shell, você vai precisar de um comando simples. Entretanto, este comando servirá apenas enquanto a maquina não for reniciada. Veja o comando.


sudo mount -t vboxsf pasta1 /home/seuUsuario/compartilhamento

Onde "pasta1" é o nome que você escolheu na VirtualBox e "/home/seuUsuario/compartilhamento" é o nome que a pasta terá no seu linux. A pasta "compartilhamento" deve existir dentro da pasta "/home/seuUsuario". Fique a vontade para escolher os nomes que julgar melhor. Este é apenas um exemplo.

Eu recomendo que você coloque o compartilhamento dentro do seu home/seuUsuario. Para colocar em outras pastas você terá que conceder permissão de escrita ao seu usuário através do comando chmod.

Você deve estar pensando: "Vai ser um saco ter que montar isso sempre que eu iniciar meu linux". Eu concordo, por isso, abaixo, segue a solução para montagem das pastas durante o boot.

Existe um arquivo chamado "/etc/fstab" e é neste arquivo que você irá configurar a montagem automatica. Digete o comando abaixo:


sudo gedit /etc/fstab

O arquivo de configuração será aberto. Na última linha do arquivo, coloque o seguinte comando.

pasta1    /home/seuUsuario/pasta1     vboxsf    defaults    0    0


Salve o arquivo e reinicie sua máquina virtual. Pronto. Seu compartilhamento será criado sempre que o boot for feito. Espero ter ajudado alguém com isso

Snap Tetris Evolution Versão 0.1

Esse foi osegundo jogo em Java que eu fiz. Desta vez, apenas por diversão. Meu chefe me colocou na manutenção evolutiva de um sistema em ASP a muito tempo atrás. Como não tinha muito o que fazer, fui fazer o jogo.

Eu realmente me interesso por jogos e adoro tetris. Fiz um jogo muito parecido com o Tetris do Mega Drive, que joguei por muitos anos.  A idéia é você ir evoluíndo conforme você passa de fase. No início você é uma lesma. Depois, evolui para uma borboleta e assim por diante. Aperte o pause para ver as telas de evolução ao fundo.

O Jogo possui 19 nívies, duas línguas: Inglês e Português ainda não completamente implementado e um controle de velocidade para a movimentação das peças.



Componentes utilizados: GTGE e JDOM

Baixar o Snap Tetris Evolution para jogar

Baixar o código fonte do jogo Snap Tetris Evolution

domingo, 14 de fevereiro de 2010

Ubuntu - PIL - IOError: decoder jpeg not available

Veja como fazer para resolver o problema de decodificação JPEG no PIL quando ele já está instalado e nada funciona direito

Você instalou o PIL em seu Ubuntu e está tentando utilizá-lo no Plone, Zope ou Django e o problema não se resolve de forma alguma? Bom, a solução é simples, reinstalar o PIL depois de instalar as bibliotecas necessárias, mas o PIL não possui nenhuma forma de desinstalação. É, eu passei por isso. Veja como fazer.

Primeiro, remova as refeência existentes do PIL
sudo rm -rf /usr/lib/python2.5/site-packages/PIL
sudo rm -rf /usr/lib/python2.5/site-packages/PIL.pth
Remova a pasta onde você instalou o PIL
rm Imaging-1.1.6/ -rf
Descompacte novamente a biblioteca
tar zxvf Imaging-1.1.6.tar.gz
cd Imaging-1.1.6/
Instale as bibliotecas necessárias
sudo apt-get install libfreetype6-dev


Faça o build e teste para ver se tudo correu bem
python setup.py build_ext -i
python selftest.py
Por último, finalmente, instale.
sudo python setup.py install

Meu Jogo - Java Race 0.3

Java Race foi um jogo que eu fiz como projeto final da minha graduação de Bachareladod de informática na UERJ. Fizemos eu e um colega.

É um joguinho simples de corrida de carro 2D feito em java usando um engine chamado GTGE, que é bem sólido. Quem quiser, pode baixo o código fonte e o jogo para testar.

Foi muito legal fez isso na faculdade, por mais que fosse simples, afinal, eu já fazia sistemas empresariais JEE no trablho e isso não tinha graça







São 3 adversários e 4 pistas para terminar o jogo. Os outros 3 carros tem uma pequena inteligência artificial feita com lógica Fuzzy através do framework JFuzzy se não me engano, mas nada sério.

Você pode baixar o jogo aqui.

E pode baixar o código fonte aqui.

sábado, 30 de janeiro de 2010

Mudando a Versão do Python no Ubuntu

Você instalou o Ubuntu novinho em folha e a versão atual do python é a 2.6 por exemplo, mas você deseja que a versão padrão seja a 2.4. Como mudar então?

Antes de mais nada, você precisa instalar a versão 2.4. Vá no seu gerenciador Synapitc e busque por python 2.4. Instale a linguagem.

Para ter certeza que ambas estão instaladas, digite python no seu console e veja qual é a versão padrão. Depois, saia do IDLE Python e digite "python2.4". A versão deve ser a 2.4

Depois, edit o arquivo /usr/share/python/debian_defaults e mude o default python para python2.4

Em seguida, execute os comandos abaixos para que a chamada "python" execute a versão que você quer.

sudo mv /usr/bin/python /usr/bin/python26
sudo ln -s /usr/bin/python2.4 /usr/bin/python

sábado, 23 de janeiro de 2010

Mais uma Mancada do Mercado Livre - Mercado Pago Obrigatório

Você, que como eu, detesta o Mercado Livre, tem cada vez mais motivos para parar de vender lá e migrar para o Toda Oferta.

A instituição vinha tentando melhorar algumas coisas após destruir o sistema de qualificação antigo e criou um anúncio "gratuito", que não é tão gratuito assim, afinal se você conseguir vender, pagará uma comissão altíssima ao ML. Parecia que as coisas estavam melhorando um pouco, já que o número de fotos voltou a ser maior e eles não estavam mais cobrando por vídeos demonstrativos dos produtos. Aí eles colocaram o Mercado Pago obrigatório. O vendedor é obrigado a aceitar aquela porcaria.

O Mercado Pago cobrava taxas das duas partes na negociação. O comprador e o vendedor tinham que pagar um percentual para usar essa ferramenta. Eles dizem que agora mudou, que só o comprador pagará alguma coisa caso queira utilizar o serviço, mas é mentira.

O vendedor precisa pagar 3 reais para cada retirada que faz no Mercado Pago. Para quem vende muito, ótimo, o cara vende 100 produtos e saca o dinheiro todo de uma vez só. Paga 3 reais e está ótimo, mas para pessoas que vendem pouco, não dá para ficar pagando mais 3 reais. Afinal, você já paga comissão ao site e não é pouco. Ainda tem que pagar mais coisas?

Todos os outros sites que oferecem o serviço de intermediação de pagamentos não cobram quando o usuário quer fazer o saque para grandes bancos e as taxas ainda são bem inferiores ao que o Mercado Livre cobra.

Quando vendo no Mercado Livre, deixo bem claro que não aceito o Mercado Pago, porque aquilo é um roubo. Para piorar, o Mercado Livre não permite que você anuncie outra forma de pagamento. Eu costuma oferecer a possibilidade de pagamento Pelo PagSeguro ou pelo Pagamento Digital para os clientes que desejavam. Fui repreendido pelo ML e tive o anúncio cancelado. Então, passei a oferecer o serviço durante a troca de e-mails com o comprador. E agora? #comofas?

O Toda Oferta está ai e não cobra nada. Se não cobra nada, significa uma coisa: O vendedor pode fazer um preço mais em conta para você porque paga taxas menores

sexta-feira, 22 de janeiro de 2010

Alterando Estado (review_state) de um Objeto do Plone via Programação

Você quer alterar um objetvo de esboço público para publicado no Plone 2.5, mas quer fazer isso via programação (script python) e não sabe como? Leia abaixo então.

Antes de mais nada, eu sei que isso funciona no Plone 2.5. No resto eu não sei se vai funcionar, mas o que você precisa fazer é utilizar o Workflow para mudar o estado do objeto. Até onde eu sei, não dá para fazer isso diretamente no objeto.
Então, em posse do objeto e não da referência dele no catálogo, você faz o seguinte:

context.portal_workflow.doActionFor(obj, 'publish');

Preste atenção. Você está usando uma action do seu workflow. O estado do objeto é "published", mas a action é "publish". Para tornar o objeto privado, você precisa fazer um "hide"

No Zope - global name 'type' is not defined

Esse erro, normalmente é significa que você não declarou alguma variável, mas quando ele acontece no ZOPE e você está tentando utilizar o método type() dentro de um script python é por um outro motivo.

O método type não está disponível para ser utilizado no ZOPE. Por isso, quando você tenta utilizar este método, o python informa que a variável não foi definida. Naturalmente, você fica com cara de idiota, imaginando o motivo disso.

O motivo é simples e você pode ler em inglês abaixo:

"type" applied to almost any Zope object will not give you "Instance" (as you would expect in a pure Python application) but "ImplicitAcquirer Wrapper" (or something like this)

Isso significa que o zope possui inumeras gambiarras para funcionar e todo tipo acaba sendo encapsulado dentro de alguma coisa.

Uma mente brilhante, entretanto, inventou o seguindo método:

same_type(x,y)

onde x pode ser o seu objeto e y um objeto do typo que você quer testar. Por exemplo: vamos supor que você deseja saber se algo é uma string. Faça assim:

Veja as duas linhas abaixo com muita atenção.

same_type(x," ")  //ISSO SIM É UMA GAMBIARRA

Você pode substituir a string pelo objeto que desejar, uma lista seria [], ou um dicionário: {}.

É isso, espero que ajude.

segunda-feira, 18 de janeiro de 2010

Criando um Objeto Usando Generic Plone Content Via Python

Como eu faço para criar um objeto que é um AT Content, ou um objeto que o tipo foi feito com Generic Plone Content diretamente do meu código python? A idéia desse código é mostrar exatamente isso.

Esse manual foi caradepaumente copiado de um tutorial em inglês. Porque eu fiz isso? Porque passei horas procurando por "Generic Plone Content" e não achei quase nada. Esse tutorial serve para você criar um conteúdo gerado via Archetypes ou Generic, porque no final das contas, o Generic usa Archetypes. Então, vamos ao que interessa. Leia atentamente, pricipalmente a próxima linha.

E ai? Leu a linha de cima? Pois é, ela só serve para me beneficiar. Vamos ao que insteressa.

Normalmente, criamos conteúdo usando "here". Que é o nosso contexto atual. Isso criaria um objeto na pasta em que estamos. E é isso que fazemos via Plone. Navegamos até uma pasta e criamos o conteúdo. Em Python, chamamos isso de "context" em um script ou Page Template, ou "self" em um produto. Aqui, usaremos a variável "container". Porque o container vai conter o que queremos. :_)

Então teremos "self" ou "context", dependendo da situação. Vou assumir context daqui pra frente.

container = context

Mas e se você quiser que o container seja uma outra pasta? Então você faz:

container = context.nomeDaPasta #A pasta ja deve existir

reparem que acima, nomeDaPasta será hard coded, ou podemos fazer:

#Retorna none caso nao exista a pasta
container = getattr(context, 'nomeDaPasta', None)

Nesse exemplo, o nome da pasta é uma string. Ou seja, pode ser parametrizado. Agora, muita atenção para a linha verdade logo abaixo. Ela é importante (para mim).

Você também pode fazer deste jeito:

container = context['nomeDaPasta']

Você não fica restrito a um nível, pode descer o quanto achar conveniente:

container = context.pasta1.subPasta1

Da forma abaixo você busca a pasta pai em relação ao contexto atual

container = context.aq_inner.aq_parent

Existe também a opção de encontrar uma pasta utilizando a raiz do portal:

from Products.CMFCore.utils import getToolByName
urltool = getToolByName(context, 'portal_url')
portal = urltool.getPortalObject()
container = portal.animais.cachorros.retrievers

Agora que você sabe como escolher o container, você pode criar seu objeto nele.
Veja o comandinho abaixo.

id = "nowHearThis"
container.invokeFactory(type_name="News Item", id=id)

Você precisa atribuir um ID ao objeto e dizer qual é o tipo de conteudo: type_name="seu tipo"

Segundo o autor do tutorial, invokeFactory vai obedecer restrições difinidas no tipo de conteúdo, como as opções de implicitly addable e filtros. Pode ser que você tenha definido que um tipo de conteúdo não é adicionavel pelo usuário. E mesmo assim você pode querer criá-lo via script. Veja abaixo

typestool = getToolByName(context, 'portal_types')
typestool.constructContent(type_name="News Item", container=container, id=id)

O conteúdo já foi criado. E agora? Você pode inserir mais informações no objeto da seguinte forma: primeiro, pegamos o objeto.

obj = container[id]

Depois, setamos uma informação:

obj.setTitle("Now Hear This!")

Em seguida, você pode reindexar o objeto no catálogo da seguinte forma:

obj.reindexObject()

domingo, 17 de janeiro de 2010

Chrome Não Acessa Sites em Plone

Toda vez que você tenta acessar um site em Plone utilizando o Chrome acontece um erro que não carrega o site.
O erro relatado pelo Chrome é:

Erro 320 (net::ERR_INVALID_RESPONSE): Erro desconhecido

O Chrome não consegue acessar as páginas do Zope que estão em cache e com o cabeçalho compactado. O que você precisa fazer é: Dizer para o Cache-Fu nunca compactar os cabeçalhos. Pronto, o Chrome conseguirá ler.

Vá em Configurações do Site -> Cache Configuration Tool  e na opção Compression selecione Never.

Depois clique em Salvar e pronto.
Basta acessar com o Chrome e tudo irá funcionar

sábado, 16 de janeiro de 2010

Como Reclamar no Mercado Livre. Link Direto.

****** Esse post é um pouco antigo e estava no meu outro site. De lá para cá o Mercado Livre já melhorou algumas coisas que irritavam todo mundo, como a cobraça abusiva por tudo. Por outro lado, passou a colocar o Mercado Pago automaticamente nos anúncios para tentar tirar mais dinheiro das pessoas.

Então, o link de reclamação abaixo ainda funciona e como muita coisa ruim ainda permanece, vou deixar tudo registrado aqui como histórico de como o ML costuma fazer as coisas. ******


Antes de mais nada, gostaria de dizer que existe um concorrente do Mercado Livre, que é o TODA OFERTA, site do UOL, onde o anúncio é grátis, não se paga comissão por vendas se você não usar PagSeguro e se usar o PagSeguro, a coisa fica bem mais em conta do que usar o Mercado Pago, mas vamos ao que interessa.

Se você quer só o link para reclamar no Mercado Livre. Faça seu login no site deles e clique neste endereço:

http://www.mercadolivre.com.br/jm/ml.faqs.framework.main.FaqsController?pageId=frmContact&faqId=2748&categId=CNTC
Ainda tem o e-mail direto de lá: crm.ml@mercadolivre.com


Pode reclamar, reclame de tudo mesmo. Solte o verbo, aqueles idiotas merecem.

Se você quer entender porque eu coloquei o link aqui, bom ai vão os motivos. Tudo começou quando eles iniciaram cobranças por qualquer coisa. Eram 6 fotos por anúncio, agora são 3. As outras 3 são pagas. Inventaram o subtítulo e reduziram o tamanho do título principal, já que o subtítulo também é pago. (A pouco tempo, inventaram taxa de modificação de anúncio.)

Depois eles pioraram a busca e a forma de vizualizar os produtos. Ficou muito mais difícil localizar os produtos que você quer. A busca trás coisas genéricas muitas vezes. Também proíbem que usemos formas de pagamentos como PagSeguro ou Pagamento Digital. Isso me parece venda casada ou prática anti-competitiva. Temos que o usar o sugador de dinheiro que é o Mercado Pago, que rouba dinheiro das duas partes na transação.

No meio do caminho, graças a Deus (UOL), veio o Toda Oferta, para ajudar mais ainda o ML a afundar. Como se não bastasse, ele fizeram a estupidez de tirar dos vendedores a possibilidade de ver a quantidade de visualizações dos anúncios, que depois de muita reclamação, voltou quase ao normal.

Para piorar, eles dificultaram muito que o comprador indentificasse o vendedor do produto e vice-versa. Agora você nem sabe mais o apelido da pessoa que está vendendo o produto. Você precisa clicar em mais informações e depois pedir para ver o perfil do vendendor. 2 clique a mais.

O vendedor, quando responde uma pergunta, também não consegue mais ver quem fez qual pergunta. Acreditem, é bizarro. Enquanto isso, no Toda Oferta você pode até usar o messenger do UOL.

O fim da picada foi o novo sistema de qualificação, que jogou a qualificação de todo mundo pro buraco só porque alguns compradores fantasmas não compram. Quem tem 40 ou 50 vendas também SE FUDEU BONITO, porque ficou no meio da tabela. 50% de qualificação. Mesmo que você não tenha nenhuma qualificação negativa.

Só quem se deu bem nessa história são os super vendedores. Lojas que já tem mais de 500 vendas. Então, o que fazer?

No meu caso, é obvio, mesmo com 100% positivo, eu fico com 50% de qualificação, então, não vou vender mais porque ninguém vai comprar. Meus anúncios já estão no Toda Oferta a um tempo. Vende menos, mas vende. O negócio é migrarmos para o Toda Oferta, fazermos uma campanha e torcer para que o Ebay venha para o Brasil e chute a bunda do Mercado Livre. No Ebay a política é completamente diferente.

Vamos lá, aqui está o link das reclamações novamente.

http://www.mercadolivre.com.br/jm/ml.faqs.framework.main.FaqsController?pageId=frmContact&faqId=2748&categId=CNTC

 Ainda tem o e-mail direto de lá: crm.ml@mercadolivre.com

Existem outras coisas que o ML fez para piorar a vida dos vendedores que eu nem mesmo lembro agora, mas que outras pessoas lembrarão. Você que entrou aqui deve lembrar.

Net Virtua Caindo com Roteador Wireless e Modem Arris

Eu já escrevi um post aqui no blog sobre como resolver o problema do roteador Belkin Wireless caindo com o modem da Arris no Net Virtua e percebi que tem muita gente procurando por isso.

A solução apareceu quando eu troquei meu Beklin por um D-link. O Belkin era infinitamente melhor, mas não funciona com o cable modem Arris.

Eu havia me esquecido de contar uma coisa. Liguei na net pedindo para trocar o Arris por um Motorola porque conversei com algumas pessoas que tinham o motorola e tudo funcionava perfeitamente. A maldita NET se recusou, falou que só trocaria se eu estivesse com algum problema no maldito cable modem.

Bom, o meu roteador Belking funcionava com a Brasil Telecom (Oi) perfeitamente, porque não funcionava coma NET? O problema estava onde então? Não adiantava clonar o MacAdress, não funcionava direito, vivia caindo.

Eu juro que quase fritei o cable modem da Arris para obrigá-los a trocar. Seria simples. Era só ligar dois cabos 110V ou 220V no meu do Arris, passando os cabos pela ventilação do modem. Ai eles teriam que trocar e eu ia dizer que queimou. Deu um pique de luz. Eles só tem técnicos incompetentes, não iam diagnosticar nada mesmo. Não que eu esteja incentivando alguém a fazer isso. Não é isso.

Mas ai apareceu uma alma querendo trocar meu Belkin pelo D-link e eu não precisei fazer aquilo que passava pela minha cabeça insistentemente. De qualquer forma, queria deixar registrado que não recomendo o NET Virtua para ninguém. Me irritei infinitamente com o suporte deles diversas vezes.

quinta-feira, 14 de janeiro de 2010

Como separar um data.fs para cada site no Zope

Muita gente que começa a trabalhar com Plone e Zope tem problemas com o banco de dados unificado e quer saber como separar um banco de dados para cada site que está no servidor por exemplo. Veja abaixo como se faz. É bem simples.

   A separação do arquivo de banco de dados do Zope (data.fs) em um arquivo por site é interessante. Primeiro, você consegue saber quanto espaço cada site ocupa com muita facilidade. Você pode fazer um pack e limpar os objetos do historico sem a necessidade de apagar o histórico dos outros sites. Em caso de restauração de backup, você não perde informações de todos os sites. Apenas de um.

    O conceito envolvido na separação é o de ponto de montagem, como no linux. Você vai dizer para o zope que tudo que for colocado naquele ponto de montagem será armazenado dentro de um certo arquivo.

    A primeira coisa a fazer é abrir o arquivo zope.conf que está dentro de INSTANCE_HOME/etc. Dentro dele, procure pelo texto "". Deve estar próximo ao final do arquivo. Em seguida, logo abaixo, adicione o código como o exemplo abaixo

<zodb_db NOME_SITE1>
# Armazenamento do NOME_SITE2
<filestorage>
      path $INSTANCE/var/NOME_SITE3.fs    
</filestorage>    
mount-point /NOME_SITE4
</zodb_db>

Repare que eu coloquei NOME_SITE1 até 4. Normalmente, coloco o mesmo nome em todos os lugares, mas isso não é obrigatório. Apenas facilita a vida na hora de identificar as coisas.

NOME_SITE1 é o que vai aparecer no ZOPE. O nome do armazenamento na hora de criar o ponto de montagem.

NOME_SITE2 é apenas um comentário

NOME_SITE3 é o nome do arquivo que vai armazenar seus dados

NOME_SITE4 é o ponto de montagem em sí. A pasta onde você terá que gardar seu site e tudo referente a ele. Deste ponto em diante.

Altere seu arquivo de configuração, envie para o servidor e reinicie o zope. Como exemplo, vou criar um data.fs para um site chamado WICS.

Acesse a ZMI e escolha a opção de adicionar novo Mount Point, conforme a imagem a seguir:


Depois disso você será enviado para uma outra tela que mostrará quais são os data.fs que estão prontos para serem criados. Você seleciona os que desejar e clica em "Create Selected Mount Points". Veja a imagem abaixo para maiores detalhes.


No meu caso, foi criada uma pasta WICS na raiz do meu servidor zope. Tudo que for criado dentro desta pasta ou eu seus sub-diretórios também será armazenado dentro do data.fs exclusívo do ponto de montagem.

Se você tentar mover um site que esteja fora desta pasta para dentro dela, o site será movido, mas continuará no data.fs antigo. Para mover um portal de um data.fs para outro é necessário exportá-lo e importá-lo novamente dentro do local desejado.

Alterando Dados do Usuário (Member) no Plone 2.5

Você quer fazer alteração em Massa nos dados dos seus usuários  no Plone e não sabe como? Tenta de tudo e só consegue alterar os dados do seu usuário ou da privilégios insuficientes? Você está no lugar certo então.

O que está escrito aqui, eu tenho certeza que é verdade para o Plone 2.5. Ainda não utilizei a versão 3 direito. Estou atrasando este encontro ao máximo.

Mas o problema dos usuários é o seguinte: Se você tentar utilizar o código member.setProperties() para alterar informações dos usuários (Members do Plone) que não seja o usuário logado, nada vai acontecer.
Este método só altera informações do usuário logado. O método que você precisa usar é: member.setMemberProperties(). Esse método fará a alteração no usuário que está na variável member, o outro não. Faça algo como

member.setMemberProperties({"nomePropriedade",valor})

Só tem um probleminha. Este método não é autorizado a ser chamado no Plone via ZMI. Então, vai dar erro de privilégios insuficientes e você vai ficar morrendo de raiva. Se quiser utilizá-lo. Tem três formas: External Method (é a mais simples), criar um produto ou autorizar este método em um script python que sobre junto com o Plone.
Faça um External Method. Como? Bom, ai é uma outra dica. Não essa.

segunda-feira, 4 de janeiro de 2010

Problemas com Charset no GWT + Google App Engine no Eclipse

Assim que comecei a usar o GWT com o Google App Engine no Eclipse e no windows, notei um problema, a acentuação. Tenho quase certeza que isso não acontece no Ubuntu porque lá é tudo UTF-8, pelo menos era da última vez que mexi.

Como o windows não usa UTF-8, a primeira coisa que eu tentei foi mudar o encode do HTML para ISO-8859-1 e não funcionou. Então, a solução é: deixe o HTML como UTF-8 e mude o workspace do eclipse para UTF-8. Vá no menu window -> preferences e veja a imagem abaixo.



Pronto, seu workspace está configurado corretamente. O detalhe é que eu estou usando um workspace só para os projetos do GWT + Google App Engine. Se você estiver com outros projetos que usam outras configurações de charset no mesmo workspace, aí você precisa procurar em preferences de cada projeto e fazer essa alteração.