quarta-feira, 6 de março de 2019

Cinnamon e as aplicações de terminal. Chute no saco!

Recentemente tomei a decisão de mudar minha distro Linux pessoal do Ubuntu para o Linux Mint 19(Cinnamon). Apesar de ter achado bem bonito(me refiro ao Cinnamon), tem alguns bugs irritantes que vem desde tempos remotos do Gnome 2, como a dificuldade em manter a configuração de vídeo(no caso dos produtos NVidia) com 2 monitores e coisas do tipo.

Mas me supreendi bastante ao notar que aplicações executadas em terminal são um pouco mais "chatinhas" de lidar no Cinnamon. Aparentemente ele precisa que você execute comandos de terminal usando o gnome-shell explicitamente. Dessa forma:

Exec=gnome-terminal -- /home/andre/Utils/scripts/make_nas


No Ubuntu(com o Unity, não sei no Gnome), você simplesmente passava o comando entre aspas e ele se virava para executar no terminal.

Frescura da minha parte? Talvez, até porque não é algo que um usuário normal faria. Mas é uma situação que julgo desnecessário, pois perde-se tempo! E tempo é algo caro, inclusive no mundo de TI.

sexta-feira, 9 de março de 2018

Cuidado com Ad-blocks

Acabei de ter uma experiência horrível!

Ontem eu estava desenvolvendo um aplicativo web com Angular e Nodejs + express. Tudo normal! Quando terminei o que tinha que fazer, fui para casa.

No outro dia, simplesmente executei o browser, utilizei normalmente o aplicativo, até que uma hora começou a dar mensagem de erro(eu esqueci de gravar a mensagem completa). Basicamente, a mensagem dizia que as requisições que eu estava tentando fazer estavam sendo bloqueadas pelo cliente. Como assim?

Na hora pensei que deveria ter sido alguma modificação que eu fiz. No entanto, eu não tinha mexido em nada muito relevante ontem. Na verdade estava testando alguns módulos de log para o Nodejs. De forma alguma aquilo poderia ter causado esse problema.

Então por que? Comecei a cogitar que fosse algo a ver com CORS. Mas não tinha mexido em nada disso ontem. Então pensei que talvez tivesse ocorrido algum problema com merge(git), já que tinha feito um merge com o master ontem. Talvez não tivesse percebido por causa de cache ou algo assim. Nada...

Comecei a me desesperar, porque precisava entregar isso o mais rápido possível. Então fui para o stackoverflow choramingar... hahaha!!! Acabei encontrando um brasileiro que teve o mesmo problema. Ele descobriu que o Ad-block estava causando o problema, ora vejam só!

segunda-feira, 1 de agosto de 2016

Perl - local::lib com cpanminus


Instalando o local::lib com cpanminus


Considerações antes de começar:

1. Esse é um relato de uma instalação do local::lib a partir de um Ubuntu 16.04, e eu realmente não estou preocupado se você está usando outra distro. Caso você esteja usando outra distro 'não filhote de Debian', esse tutorial ainda pode ser útil desde que você deixe essas bobagens de lado;

2. Você instalou local::lib e nada funcionou? Ótimo! Está no lugar certo!


Testando o local::lib



Se a sua instalação do local::lib não estiver 'ok', ou se você simplesmente ainda não instalou, execute



$ perl -e 'use local::lib'

Dependendo da versão de Perl/CPAN você verá a seguinte mensagem(mas não tem problema se você não estiver vendo isso! Meramente 'ilustrativo')





!
! Can't write to /usr/local/share/perl/5.22.1 and /usr/local/bin: Installing modules to $HOME/perl5
! To turn off this warning, you have to do one of the following:
!   - run me as a root or with --sudo option (to install to /usr/local/share/perl/5.22.1 and /usr/local/bin)
!   - Configure local::lib in your existing shell to set PERL_MM_OPT etc.
!   - Install local::lib by running the following commands
!
!         cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
!





Nesse caso, instale o cpanminus executando o comando abaixo:
$ sudo apt-get install cpanminus
Após instalar o cpanminus, execute:


$ cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)





Agora, abra outro terminal, e execute:




$ env |grep PERL
PERL5LIB=$HOME/perl5/lib/perl5
PERL_MB_OPT=--install_base "$HOME/perl5"
PERL_LOCAL_LIB_ROOT=$HOME/perl5
PERL_MM_OPT=INSTALL_BASE=$HOME/perl5




Se o resultado for parecido com isso, provavelmente funcionou! Para ter certeza, apenas instale algum módulo sem o 'sudo' e verifique se o 'use Modulo::TeoricamenteInstalado' está ok. Se estiver, agora você tem local::lib instalado perfeitamente.

Caso contrário, exporte as variáveis manualmente e salve no seu .bashrc(se estiver usando bash), assim:



$ echo "export PERL5LIB=\"$HOME/perl5/lib/perl5\"">>~/.bashrc && \
echo "export PERL_MB_OPT=\"--install_base '$HOME/perl5'\">>~/.bashrc && \
echo "export PERL_LOCAL_LIB_ROOT=$HOME/perl5">>~/.bashrc \
source ~/.bashrc


Então instale seu módulo novamente e teste novamente.

Fim



quinta-feira, 21 de julho de 2016

Sobre Fullstack, AngularJS, Catalyst and CORS

Introdução


Recentemente resolvi começar a estudar frontend um pouco mais à sério, e resolvi aproveitar um projeto que estava desenvolvendo a algum tempo, e resolvi aplicar Angular no frontend substituindo completamente o que havia anteriormente, que basicamente eram templates construídos com Template Toolkit dentro do ambiente do Catalyst. Por quê? Bom, várias razões:

1. Mercado

Como alguns devem saber, AngularJS é um framework Javascript mantido pelo Google, extremamente popular entre designers e programadores frontend. Além de ter uma demanda razoavelmente grande no mercado de trabalho. Fora que sua arquitetura permite resumir bastante referências a código javascript utilizando tags que podem ser criadas e manipuladas por seus handlers de eventos de uma maneira relativamente simples, o que achei fantástico.

2. Necessidade

Resumidamente, algum engravatado filho da p.. resolveu que 'não valia à pena' pagar 3 pessoas em um time de TI para fazer a porra toda funcionar, e determinou que 'profissionais multifunção'(ou qualquer buzzword bosta do tipo), são a nova tendência de mercado, e deu um nome 'bonitinho' para isso: 'fullstack developer'. A tradução disso é 'especialista em tudo SQN', mas que ganha por apenas uma pessoa. Como 'morrer na praia' não está nos meus planos ainda, resolvi juntar minha atração pelo Angular com a necessidade de aprendê-lo e tentar me divertir enquanto faço isso, se possível.

Pessoalmente acho que a idéia do 'fullstack developer' é um grande erro. Mas foda-se a minha opinião! Se valesse alguma coisa nem estaria escrevendo esse artigo pra começo de conversa... :P

Contextualizando o Problema


CORS - Cross Origin Resource Sharing ou, 'Compartilhamento de Recursos com Origem Cruzada' em tradução livre. Trata-se de uma especificação que é utilizada para determinar se um recurso pode ser acessado de um outro domínio ou não, sendo que essa interação pode ou não ocorrer entre o browser e o servidor onde o recurso se encontra. Resumidamente isso acontece segundo as regras do 'same origin police'.

Recursos - No caso de APIs REST, correspondem aos endpoints. Esses tem origem em seus hosts e portas, que são o objeto de foco do CORS.

AngularJS - Trata-se de um framework MVC escrito em Javascript que facilita a organização e manipulação de objetos DOM oferecendo ferramentas úteis para organizar código HTML + CSS + Javascript, e tratar eventos diversos dentro de uma plataforma MVC. É bem popular e bem utilizado para se consumir serviços REST com APIs, por exemplo.

Catalyst - Bom e velho framework MVC feito em Perl. Confiável, flexível e cheio de coisas legais!


Problema


Ao escolher utilizar AngularJS, não tinha a informação de que CORS é algo que ele trata internamente por padrão. Isso a princípio seria bom, já que vem para evitar problemas de segurança. No entanto, como não tinha conhecimento prévio desse fato, no momento em que fazia requisições do tipo POST, através de um serviço interceptado pelos handlers de eventos do Angular, automaticamente transformou minhas requisições POST em uma requisições do tipo OPTIONS e enviava uma série de cabeçalhos, o que para o servidor que provia o serviço que eu tentava consumir simplesmente não existia, retornando o código http 404(resource not found). 

Isso me gerou um problema, já que as requisições não eram reconhecidas pelo servidor REST(pois esperavam POST e não OPTIONS). Então o problema se resumiu em descobrir como lidar com CORS.


Visão geral da arquitetura do serviço REST


Basicamente, tenho um frontend em Angular, cujos serviços consomem uma API REST disponibilizada por um nginx que faz proxy reverso para a porta 5000 do servidor, que é mapeada pela plataforma de middleware 'starman', que sobe o serviço implementado do Catalyst. Mais ou menos assim:





Apenas uma arquitetura 'clássica' de uma aplicação dividida em frontend e backend, onde frontend compreende toda a interação com os usuários(Clientes), e o backend todas as partes que disponibilizam dados da aplicação através de uma instância Catalyst, que se comunica com o servidor HTTP através de PSGI utilizando o starman como ferramenta.


Solução


Na verdade são duas:

1 - Garanta que a origem das requisições(host + porta) são iguais as do seu recurso;

2 - Implemente CORS nos seus recursos

Isso signfica devolver um 'response' com uma série de headers. Os headers são os seguintes:

Access-Control-Allow-Origin: Controla exatamente as origens de requisições permitidas para esse recurso. Você pode ter uma, uma lista deles, ou simplesmente aceitar todos(*)!

Access-Control-Allow-Methods: Controla os métodos http que são aceitos de outras origens pelo recurso.

Access-Control-Allow-Headers: Idem para headers;

Onde colocar isso? Atenção, porque agora falarei apenas em Catalyst!

Considerando que você está(e deveria estar) usando Catalyst::DispatchType::Chained, você deve setar os headers sempre no 'setup' da feature, ou seja, action que representa o primeiro nível da cadeia depois do '/' que é controlado pelo Controller Root. Mas porque não no root? Bom, pra dizer a verdade eu tentei, mas a requisição ficava travada e eu não entendi o porque ainda. Exemplo:



package api::Controller::Login;

BEGIN{extends 'Catalyst::Controller';}


sub setup :Chained('/') :PathPart('login') :CaptureArgs(0) {
  my ($self,$c) = @_;

  $c->response->headers->header(
   'Access-Control-Allow-Origin' => '*',
   'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE, OPTIONS',
   'Access-Control-Allow-Headers' => $c->request->headers->header("Access-Control-Request-Headers")
  );



}



É possível centralizar isso, removendo esse código e criando um método dentro da classe da aplicação. Nesse caso, em lib/api.pm. Depois é só referenciar o método utilizando o objeto de contexto do Catalyst ($c).



Fim...











quinta-feira, 21 de janeiro de 2016

Opengates - autenticação ok!

API versão v0.00006 


  • Autenticação implementada: controle de log-in e chaves de acesso;
  • Correção de bugs na geração de chave de acesso;
  • Teste de autenticação ok;

quinta-feira, 17 de setembro de 2015

Listando módulos instalados

Listando módulos em Perl

Este curtíssimo artigo é de utilidade 'pública'! Sim, todo mundo que trabalha ou trabalhou com Perl em algum momento já precisou listar os módulos que estão instalados. Então vai a dica!

Primeiro, instale o módulo Module::Info

$ cpanm Module::Info 

Segundo, baixe o script clicando aqui Basicamente são dois 'loops':

  • O primeiro utiliza o módulo ExtUtils::Installed para listar os módulos 'não-core', embora ele possa trazer os módulos do Core também. A questão é que o módulo Module::CoreList é específico para isso, mas para dizer a verdade eu não sei porque o autor desse script usou os dois módulos. Meu chute é que ExtUtils::Installed possa criar alguma dificuldade para trazer os módulos do Core. Eu realmente não chequei isso, mas whatever! O que importa é o resultado!
  • O segundo loop traz, é claro, somente módulos do core, utilizando Module::CoreList e filtrando pragmas que possam vir a 'sujar' a lista de módulos. Depois utiliza uma instância do módulo Module::Info para extrair mais informações (como a versão do módulo, que está comentada,por exemplo).
O resultado, é claro, é uma lista de módulos.


 URI::Template
 URI::db
 URI::ws
 URL::Encode
 URL::Encode::XS
 UUID::Generator::PurePerl
 UUID::Object
 UUID::Tiny
 Unicode::Collate
 Unicode::Collate::CJK::Big5
 Unicode::Collate::CJK::GB2312
 Unicode::Collate::CJK::JISX0208
 Unicode::Collate::CJK::Korean
 Unicode::Collate::CJK::Pinyin
 Unicode::Collate::CJK::Stroke
 Unicode::Collate::CJK::Zhuyin
 Unicode::Collate::Locale
 Unicode::Normalize
 Unicode::Stringprep
 Unicode::UCD
 User::grent
 User::pwent
 Variable::Magic
 WWW::Correios::PrecoPrazo
 WWW::Curl
 WWW::Curl::UserAgent
 WWW::Facebook::API
 WWW::Mechanize::Cached
 WWW::Mechanize::Cached::GZip
 WWW::Mechanize::Firefox
 WWW::Mechanize::GZip
 WWW::Mechanize::PhantomJS
 WWW::Scripter
 WWW::Scripter::Plugin::JavaScript
 Want
 Web::Util::DBIC::Paging
 WebService::Amazon::Route53
 XML::Simple
 XML::Tiny
 XML::Writer
 XML::XML2JSON
 XML::XPathEngine

Claro que é possível melhorar esse script, adicionando um controle de opções, e aproveitando melhor os filtros dos módulos Module::CoreList e ExtUtils::Installed e Module::Info. Fiquem à vontade para melhorá-lo e publicar. Afinal, estamos falando de opensource por aqui!

That's all, folks!

quarta-feira, 15 de julho de 2015

Opengates

Estou iniciando um projeto que envolve dados abertos. Trata-se do Opengates. Opengates é uma plataforma alternativa ao CKAN, com características bem similares, porém feito em Perl(CKAN é feito em Python), usando Catalyst como backend e AngularJS como front.

O que esse treco vai fazer? Basicamente tudo o que o CKAN faz, mas sem as inconveniências do virtualenv do Python, e menos sofisticado, no sentido de que inicialmente não haverão muitos facilitadores, digamos assim. Lista de features para as versões 1.0.x

  • Permitir acesso a dados abertos organizados por instituições, empresas, grupos ou simples usuários
  • Restrição de acesso(somente na escrita) através de roles
  • Customização de conteúdo. Na verdade, o que importa mesmo é a API. Embora eu pretenda fornecer uma interface inicial e customizável, a idéia é que as pessoas possam consumir os dados através da API e sejam livres para mostrar isso da maneira que lhes convier melhor.
  • Documentação versionada
  • Visualização de dados online(CSV, TXT)

Tudo ainda está precário, porque comecei somente a alguns dias. Mas espero ter algo funcionando em breve! Pretendo continuar postando sobre as evoluções.

Bom, por enquanto é isso! Idéias serão bem-vindas!

Github - https://github.com/bang/Opengates

Cheers!