terça-feira, 26 de janeiro de 2016

Como configurar e instalar node.js com express no Ubuntu

Apesar do node.js ter excelente documentação disponível, resolvi postar um passo a passo de como instalar e configurar o node.js no ubuntu, como servidor web.

1. Instalar o node.js

$ curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash -
$ sudo apt-get install -y nodejs

2. Instalar o Express

$ sudo npm install express-generator -g

3. Criar a aplicação

$ express node-app
$ cd node-app
$ npm install

4. Definir a aplicação como serviço

Crie um novo arquivo de configuração

$ sudo nano /etc/init/node-app.conf

Adicione o seguinte conteúdo ao arquivo

start on filesystem and started networking
respawn
chdir [caminho da aplicação]
env NODE_ENV=production #change this to staging if this is a staging server
env PORT=3000
exec npm start

Inicie o serviço

$ sudo start node-app

5. Configurar o firewall

Habilite o firewall

$ sudo ufw enable

Adicione a permissão para a porta

$ sudo ufw allow 3000


[fim]

OBS: Estes passo a passo foi testado no Ubuntu 14.04 LTS.

terça-feira, 12 de novembro de 2013

sexta-feira, 8 de novembro de 2013

Lançamento do site do software SAVE


http://www.brainstorm.inf.br/save

Confira o lançamento do site do software SAVE - Sistema de Acuidade Visual Eletrônico, desenvolvido pela brainstorm®.

Clique aqui para acessar o site.

God bless!

terça-feira, 15 de outubro de 2013

Globalização dinâmica usando ResourceDirectory em WPF

Há alguns dias eu me deparei com seguinte feature em uma aplicação:
- Implementar o recurso de globalização (vários idiomas). A princípio, Inglês e Espanhol.
Até aqui, tudo bem, só criar os Resources para cada idioma.
Até que surgiu o segundo feature:
- Permitir mudar o idioma, refletindo automaticamente a alteração em toda interface.
Até onde sei, a única forma de conseguir isso é setando o CurrentCulture da Thread em execução antes da chamada da função InitializeComponent de cada interface. Mas não seria dinâmico, a janela precisaria ser fechada e reaberta.
Pesquisando um pouco eu encontrei alguns artigos sobre o uso de ResourceDictionary, MarkupExtensions para se atingir esse dinamismo.
Baseado nessas informações eu montei um pequeno engine que permite traduzir qualquer FrameworkElement (ex: Window, UserControl, Page) dinamicamente.

Criando o engine

Como a classe é extremamente simples e seu conteúdo é self-explanatory, segue abaixo o código fonte na íntegra.
public static void Translate(FrameworkElement element)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.IO;
using System.Reflection;
using System.Globalization;

namespace Language
{
    public static class LanguageCore
    {
        private static List RegisteredElements = new List();
        private static Dictionary CachedResourceDictionary = new Dictionary();
        private static string ResourcePath = "\\Resources";
        private static string GlobalDictionary = "Global";

        public static void SetResourcePath(string resourcePath)
        {
            ResourcePath = resourcePath;
        }

        public static void SetGlobalDictionary(string globalDictionary)
        {
            GlobalDictionary = globalDictionary;
        }

        public static void Translate(FrameworkElement element)
        {
            var dictionaryName = element.GetType().Name;;
            var dict = GetResourceDictionary(dictionaryName);
            if (dict != null)
            {
                SetElementResourceDictionary(element, dict);
                RegisterElement(element);
            }
        }

        public static string GetLanguage()
        {
            var lang = (string)Properties.Settings.Default["Language"];
            if (lang == String.Empty)
                return Thread.CurrentThread.CurrentCulture.Name;
            else
                return lang;
        }

        public static void SetLanguage(string language)
        {
            if (GetLanguage() == language) return;

            SaveLanguage(language);
            CallInitializeLanguageAllElements();
        }

        public static ResourceDictionary GetGlobalDictionary()
        {
            return GetResourceDictionary(GlobalDictionary);
        }

        private static ResourceDictionary GetResourceDictionary(string resourceName)
        {
            var fileName = GetResourceDictionaryFileName(resourceName);
            
            ResourceDictionary dict = new ResourceDictionary();
            if (CachedResourceDictionary.ContainsKey(fileName))
                dict = CachedResourceDictionary[fileName];
            else
            {
                try
                {
                    dict.Source = new Uri(fileName, UriKind.Relative);
                    CachedResourceDictionary.Add(fileName, dict);
                }
                catch
                {
                    return null;
                }
            }
            return dict;
        }

        private static string GetResourceDictionaryFileName(string resourceName)
        {
            var elementName = resourceName;
            var currentLanguage = GetLanguage();
            return Path.Combine(ResourcePath, currentLanguage, elementName + ".xaml"); ;
        }

        private static void RegisterElement(FrameworkElement element)
        {
            if (!RegisteredElements.Contains(element))
            {
                RegisteredElements.Add(element);
                element.Unloaded += element_Unloaded;
            }
        }

        private static void UnregisterElement(FrameworkElement element)
        {
            if (RegisteredElements.Contains(element))
                RegisteredElements.Remove(element);
        }

        private static void element_Unloaded(object sender, RoutedEventArgs e)
        {
            UnregisterElement((FrameworkElement)sender);
        }

        private static void CallInitializeLanguageAllElements()
        {
            foreach (FrameworkElement e in RegisteredElements)
                Translate(e);
        }

        private static void SetElementResourceDictionary(FrameworkElement element, ResourceDictionary dict)
        {
            foreach (DictionaryEntry res in dict)
            {
                if (element.Resources.Contains(res.Key))
                    element.Resources[res.Key] = dict[res.Key];
                else
                    element.Resources.Add(res.Key, dict[res.Key]);
            }
        }

        private static void SaveLanguage(string Language)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(Language);
            Properties.Settings.Default["Language"] = Language;
            Properties.Settings.Default.Save();
        }
    }
}

Utilizando o engine

Chame a função Translate em cada interface que será traduzida. Eu costumo colocar no construtor, logo após o InitializeComponent.
Ex:
namespace demo
{
    /// 
    /// Interaction logic for MainWindow.xaml
    /// 
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            LanguageCore.Translate(this);
        }
    }
}
Para que o engine "encontre" os resources de cada idioma, no projeto WPF crie a seguinte estrutura de pastas:
\Resources\en-US (para resources em inglês)
\Resources\pt-BR (para resources em português)
Adicione um ResourceDictionary com o mesmo nome da interface, por exemplo:
\Resources\pt-BR\MainWindow.xaml.
No XAML da interface adicione o resource padrão (também será o resource de fallback).
    
        
    
Para ver em design time como a interface ficará em outro idioma, basta alterar o idioma padrão. Adicione o texto que será utilizado na interface no ResourceDictionary.

    Teste de aplicação

Utilize o resource criado através do DynamicResource.

Para alterar o idioma utilize a função SetLanguage.
private void ingles_Click(object sender, RoutedEventArgs e)
{
    LanguageCore.SetLanguage("en-US");
}
Eu implementei um recurso que disponibiliza um resource global, onde eu uso em outras áreas do sistema, diretamente no código fonte. Para utilizar este recurso é necessário criar um ResourceDictionary chamado Global.xaml em cada pasta de cada idioma.

    Ocorreu um erro inesperado de comunicação com o aparelho./s:String>

Utilizando o resource:
    MessageBox.Show((string)LanguageCore.GetGlobalDictionary()["ErroComunicacao"], TITULO_APLICACAO, MessageBoxButton.OK, MessageBoxImage.Error);

Algumas melhorias implementadas

- Mecanismo de "cache" dos ResourceDictionray.
- Ao se alterar o idioma, o engine fará a tradução de todas as interfaces registradas.
- Remoção do registro da interfaces no evento Unloaded.

Inicialmente eu utilizava o método de adicionar o ResourceDictionary ao MergedDictionaries do FrameworkElement em tradução, mas em alguns casos mais complexos a interface não era traduzida, por isso resolvi iterar os resources, o processo demanda um maior processamento, mas funcionou em todos os casos.

Além de utilizar string é possível utilizar outros tipos de resource, por exemplo, a bandeira do idioma atual.


    Ocorreu um erro inesperado de comunicação com o aparelho./s:String>
    

Na interface, utilize da seguinte forma.

God bless!

sábado, 12 de outubro de 2013

Dica de Livro - Professional Test Driven Development with C#: Developing Real World Applications with TDD


Fica a dica de um excelente livro para quem esta afim de se aprofundar na técnica TDD de desenvolvimento. Além de uma visão geral do TDD o livro trás vários conceitos sobre o desenvolvimento SOLID, DDD, Red-Green-Refactor, DRY, entre outros. O livro é repleto de exemplos práticos e muito bem aplicados, a leitura flui naturalmente e de fácil assimilação.

Além de trazer conceitos do TDD e SOLID, o escritor mostra passo-a-passo como ele costuma construir um projeto, mostrando desde a estrutura das pastas, até a construção de testes e classes, obviamente nesta ordem!

Vale a pena conferir!

God bless!

Post com código fonte em C#

Com certeza vou precisar postar código fonte.
Solução:
SyntaxHighlighter

public class Person
{
    // Field 
    public string name;

    // Constructor that takes no arguments. 
    public Person()
    {
        name = "unknown";
    }

    // Constructor that takes one argument. 
    public Person(string nm)
    {
        name = nm;
    }

    // Method 
    public void SetName(string newName)
    {
        name = newName;
    }
}

Encontrei aqui um guia para integrar com o Blogger e funciona perfeitamente!

Resumindo, basta adicionar o seguinte código antes da tag </head> do template do seu blog.

 
 


Para utilizar, coloque o seu código fonte dentro de uma tag <pre class="brush: [linguagem]"> </pre>, informando o tipo de linguagem desejado.

Exemplo:


public class Person
{
    // Field 
    public string name;

    // Constructor that takes no arguments. 
    public Person()
    {
        name = "unknown";
    }

    // Constructor that takes one argument. 
    public Person(string nm)
    {
        name = nm;
    }

    // Method 
    public void SetName(string newName)
    {
        name = newName;
    }
}

Com isso você terá o mesmo resultado do exemplo que dei no início do post.



God bless!

sexta-feira, 11 de outubro de 2013

Primeiro post

Acho que quase todo blogueiro (se é que eu já posso usar esse título) começa com um post com esse título, não podia fazer diferente. Vai que dá azar!

É isso aí pessoal, esse vai ser o meu canal para compartilhar minhas experiências na área de análise e desenvolvimento de sistemas.

Foco: Android, .NET, Delphi e Metodologias.

Até o segundo post... God bless!