Se dopo aver installato Icinga 1.6.x su una macchina Ubuntu server non siete in grado di inviare comandi al server icinga per problemi di permessi sul file /var/lib/icinga/rw/icinga.cmd ecco una veloce soluzione (da tenere a mente!):

sudo service icinga stop
sudo dpkg-statoverride --update --add nagios www-data 2710 /var/lib/icinga/rw/
sudo dpkg-statoverride --update --add nagios nagios 751 /var/lib/icinga/
sudo service icinga start

I write code using Rails since 3 or 4 years now, but the reading of Rails Recipes, Rails 4 ed. by Chad Fowler suprised me with helpful Tips & Tricks at every page.

This book isn't a guide for a newcomer to the Rails world (although it can be a newsworthy reading) but a sort of reference for daily development, which can suggest professional solution to common problems that everybody will have to face someday :)

So read it the first time then leave it on your desk, tomorrow you'll need to open it and get suggestions to write some awesome new code.


Grazie Sciamp per avermi convinto a passare a Vim parlandomi di Emacs :)

Lo so, sembra uno scherzo, eppure è proprio vero! Era da tanto che volevo cambiare editor passando da Textmate a qualcos’altro, ho intravisto Sublime Text 2, ma volevo qualcosa di open source. Da un po’ di tempo Alessandro stava rompendo le scatole a tutti su quanto è figo Emacs :) e avevo iniziato a lavorarci un po’, ma non sono mai riuscito ad entrarci in sintonia. Arriviamo ai giorni nostri e in particolare al primo incontro ufficiale del Ruby Social Club Firenze dove ho assistito al talk proprio di Alessandro “Ma perchè non Emacs? - a caccia di feature che sicuramente esistono già. Il talk è stato illuminante, talmente interessante che mi sono detto: “Ma se Emacs fa tutte queste cose (e io mi trovo molto bene con Vim), possibile che anche Vim non le faccia?”. Mi sono guardato un po’ di video (scoprendo che, ovviamente, le faceva) e alla fine ho deciso di abbandonare Textmate e passare a Vim!

Lo ammetto: non è stato subito semplice: stupito dai video e dagli articoli letti quà e là ho installato plugin, clonato repository, fatto configurazioni per lo più senza sapere troppo cosa stavo facendo e mi sono trovato in situazioni veramente strane, tipo non capire perchè il Tab non tabbava oppure vedere apparire cose a caso in conseguenza di shortcut che non sapevo di aver digitato! L’editor risultava comunque molto potente, ma non sentivo di padroneggiarlo abbastanza anche se non ho mai rimpianto troppo TextMate. Poi ho letto questo articolo di Yahuda Katz e ho trovato le sue osservazioni molto giuste: quando si passa a editor potenti come Emacs o Vim bisogna evitare il troppo, ovvero le centinaia di funzioni e plugin che gli esperti di quell’editor ti suggeriscono di installare subito come se fossero essenziali, quando invece ti trovi a non capirci più un tubo.

Ho quindi deciso di eliminare ~/.vim/ e ~/.vimrc e ricominciare da capo un passo alla volta. Userò questo articolo per tenere traccia delle cose che ho fatto. Non so bene cosa verrà fuori, intanto sappiate che uso sia Vim (sui server e da terminale) che GVim (su Fedora) e Mvim (sul Mac), quindi mi aspetto che le configurazioni debbano funzionare su tutte e tre le varianti dell’editor. Troverete la versione aggiornata e completa dei file nel mio repository GitHub dedicato a Vim (leggete il README prima di usarlo).

N.B.: d’ora in poi scriverò sempre le configurazioni riferendomi al file ~/.vimrc ma se state usando il mio repository quel file è praticamente vuoto e include il file ~/.vim/vimrc, dove effettivamente troverete le configurazioni. A parte il cambio di file, la sostanza non cambia :)

Configurazioni di base

Tutto ciò che concerne Vim è essenzialmente in due posti: il file ~/.vimrc e la cartella ~/.vim/. Il file ~/.vimrc viene eseguito al lancio del programma mentre nella cartella si trovano tutte le estensioni (colori, plugin, ecc.). Come prima cosa impostiamo un po’ di configurazioni di base in ~/.vimrc:

set showcmd     "show incomplete cmds down the bottom
set showmode    "show current mode down the bottom

set incsearch   "find the next match as we type the search
set hlsearch    "hilight searches by default

"turn off needless toolbar on gvim/mvim
set guioptions-=T

"indent settings
set tabstop=4
set shiftwidth=4
set softtabstop=4
set cindent
set smartindent
set autoindent
set expandtab

"folding settings
set foldmethod=indent   "fold based on indent
set foldnestmax=3       "deepest fold is 3 levels
set nofoldenable        "dont fold by default

set wildmode=list:longest   "make cmdline tab completion similar to bash
set wildmenu                "enable ctrl-n and ctrl-p to scroll thru matches

" Vim tabs navigation
nmap <leader>] :tabn<CR>
nmap <leader>[ :tabp<CR>

Per Vim sono disponibili tantissimi schemi di colore, per installarli è necessario copiare il file .vim contenente lo schema in ~/.vim/colors. A quel punto è possibile abilitare a runtime lo schema colori con:

:colorscheme MyScheme

oppure, usando ~/.vimrc:

colorscheme MyScheme

Di seguito una configurazione leggermente più complessa riguardante lo schema colori che tiene conto dell’interfaccia di Vim usata:

" Color scheme
if has("gui_running")
    "tell the term has 256 colors
    set t_Co=256

    colorscheme railscasts
    set guitablabel=%M%t
    set lines=40
    set columns=115

    if has("gui_gnome")
	set term=gnome-256color
	colorscheme railscasts
	set guifont=Monospace\ Bold\ 12
    endif

    if has("gui_mac") || has("gui_macvim")
	set guifont=Menlo:h14
	" key binding for Command-T to behave properly
	" uncomment to replace the Mac Command-T key to Command-T plugin
	"macmenu &File.New\ Tab key=<nop>
	"map <D-t> :CommandT<CR>
	" make Mac's Option key behave as the Meta key
    endif

    if has("gui_win32") || has("gui_win32s")
	set guifont=Consolas:h12
	set enc=utf-8
    endif
else
    "dont load csapprox if there is no gui support - silences an annoying warning
    let g:CSApprox_loaded = 1

    "set railscasts colorscheme when running vim in gnome terminal
    if $COLORTERM == 'gnome-terminal'
	set term=gnome-256color
	colorscheme railscasts
    else
	if $TERM == 'xterm'
	    set term=xterm-256color
	    colorscheme railscasts
	else
	    colorscheme default
	endif
    endif
endif

Personalmente non modifico il tasto Leader (di default \), ma se lo volete fare:

let mapleader=","

Pathogen

Installare un plugin in Vim vuol dire copiare i suoi file nella cartella ~/.vim/ e in particolare nelle sue varie sottodirectory (plugin, doc, autoload, ecc). Non mi piace molto dover dividere i file di uno stesso plugin ed evidentemente non sono il solo dato che esiste il plugin Pathogen che permette di scompattare ogni plugin nella sua cartella in ~/.vim/bundle/. Per installare il plugin bisogna copiare il plugin in ~/.vim/autoload e creare la cartella ~/.vim/bundle/:

mkdir -p ~/.vim/autoload ~/.vim/bundle 
curl 'www.vim.org/scripts/download_script.php?src_id=16224' > ~/.vim/autoload/pathogen.vim

Per attivare il plugin basta inserire in ~/.vimrc:

"necessary on some Linux distros for pathogen to properly load bundles
filetype on
filetype off

"load pathogen managed plugins
call pathogen#infect()

NERDTree

Adesso che abbiamo installato Pathogen cosa di meglio se non provarlo! Uno dei plugin che uso di più è sicuramente NerdTree, che permette la visualizzazione dell’albero delle directory e dei file. Per installarlo quindi si seguono le istruzioni del repository GitHub, ovvero:

cd ~/.vim/bundle
git clone https://github.com/scrooloose/nerdtree.git

Personalmente utilizzo queste configurazioni in ~/.vimrc per NerdTree:

" Visualizzo NERDTree con i tasti 'wm'
nmap wm :NERDTree<cr>
" Ignoro i file di backup di Vim
let NERDTreeIgnore=['\.swp$']
" Utilizzo <leader>p per mostrare e nascondere NERDTree
silent! nmap <silent> <Leader>p :NERDTreeToggle<CR>

Vundle

Come abbiamo appena visto installare i plugin è molto semplice, specialmente con Pathogen, ma a lungo andare si potrebbe perdere un po’ traccia di cosa si è installato e, soprattutto, se i plugin installati sono anche aggiornati. Per ovviare al problema uso Vundle, un plugin che, sfruttando Pathogen, permette di automatizzare le operazioni di installazione e aggiornamento dei plugin. Per installarlo:

git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle

La configurazione a questo punto è piuttosto semplice:

set nocompatible               " be iMproved
filetype off                   " required!

set rtp+=~/.vim/bundle/vundle/
call vundle#rc()

" let Vundle manage Vundle
" required! 
Bundle 'gmarik/vundle'

" Set plugins here...


filetype plugin indent on     " required!

Se a questo punto si vuole installare un plugin da GitHub (ad esempio reinstalliamo, dopo averlo eliminato, NerdTree), basta inserire in ~/.vimrc:

Bundle 'scrooloose/nerdtree.git'

Se il plugin non fosse su GitHub è sufficiente indicare l’url GIT completo.

Una volta inserito il plugin si lancia Vim e si esegue:

:BundleInstall

Se si vogliono vedere i bundle presenti:

:BundleList

se si vogliono aggiornare i bundle installati:

:BundleInstall!

e infine se si vuole eliminare un plugin si elimina la riga corrispondente in ~/.vimrc e si esegue:

:BundleClean

Niente di più semplice.

Adesso che Vim è configurato per installare velocemente i plugin inizio con una carrellata di plugin che ho installato. Vi consiglio anche la visione di questa interessante serie di video intitolata VIM Essential Plugins.

Fugitive

Inizio con Fugitive, un plugin che trasforma Vim in un client Git. Personalmente, almeno per ora, non uso direttamente le funzionalità per Git, ma mi è utile per visualizzare lo stato del repository su cui sto lavorando. Dopo aver inserito il bundle:

Bundle 'tpope/vim-fugitive'

per vedere lo stato del repository si inserisce in ~/.vimrc:

set statusline+=%{fugitive#statusline()}

Per una panoramica più completa del plugin esiste una serie di screencast su Fugitive

SnipMate

Snipmate è un plugin che permette l’uso degli snippet, ovvero l’uso di una stringa che, seguita dal Tab, genera del codice. Snipmate non va d’accordo con Pathogen quindi non è possibile utilizzare Vundle. Per installarlo bisogna quindi seguire la guida:

git clone git://github.com/msanders/snipmate.vim.git
cd snipmate.vim
cp -R * ~/.vim

Per fare un esempio, si può aprire un file html, digitare html seguito da un Tab e Snipmate genererà:

<html></html>

Se lavorate molto con l’HTML vi consiglio di dare un bello sguardo a Sparkup che permette di creare HTML molto complesso con poco, ad esempio:

nav > ul > li > a*4 { Links }

seguito da un Tab produce:

<nav>
   <ul>
      <li>
         <a href=""> Links </a>
         <a href=""> Links </a>
         <a href=""> Links </a>
         <a href=""> Links </a>
      </li>
   </ul>
</nav>

Mica male… :)

Command-T

Command-T prende direttamente spunto dal Command-T di TextMate e serve per trovare velocemente un file e aprirlo: basta digitare leader-t e iniziare a digitare il nome di un file per trovarlo.

La sua installazione è molto più complessa dei plugin installati finora, quindi mi ci soffermerò un po’ di più.

Intanto i requisiti: Command-T richiede che sia installato Ruby (e che sia della stessa versione usata per compilare Vim) e alcune librerie di sistema. Su Fedora i pacchetti necessari sono:

yum install ruby ruby-devel libxml2-devel libxslt-devel

Il plugin si può installare con Vundle, quindi in ~/.vimrc:

Bundle 'git://git.wincent.com/command-t.git'

e, come al solito, si installa con:

:BundleInstall

Fatto questo il plugin va compilato. Se, come me, usate RVM, prima di compilare Command-T, switchate al ruby di sistema con:

rvm use system

entrate poi nella cartella ~/.vim/bundle/command-t/ruby/command-t/ e lanciate:

ruby extconf.rb
make

Se tra l’installazione del plugin e la sua compilazione provate a lanciare vim vi troverete con un bel Segmentation Fault :)

Esiste anche un plugin alternativo che promette faville, specialmente per chi ha MacOSX, PeepOpen, ma costa 12$

Vim-Rails

Eccoci al mio plugin preferito: Vim-Rails. Chiunque programmi in Ruby on Rails amerà :Rmodel, :Rview, :Rcontroller per navigare velocemente l’MVC di una risorsa, :Rextract per creare un partial al volo di un codice selezionato, ecc. Per installarlo, in ~/.vimrc:

Bundle 'tpope/vim-rails.git'

Altri plugin

Termino con una breve descrizione di altri plugin utili:

  • SuperTab permette l’autocompletamento con un utile menù a tendina da cui scegliere l’opzione desiderata
  • DelimitMate: chiusura automatica delle parentesi
  • CloseTag: premendo Ctrl-_ in un file HTML chiude in automatico un Tag rimasto aperto
  • TagBar: un plugin simile a TagList che genera la lista di classi/metodi/ecc. del file aperto (richiede exuberant-ctags)
  • ZenCoding: abbreviazioni per file HTML in stile zen-coding
  • CSS Syntax: una versione migliorata della colorazione dei CSS

Questa volta, più che mai, un augurio di Happy Hacking!


As I promised to a reader who wrote me an email some days ago, with this post I’ll explain how I built the contact form of this website using Sinatra and Sendgrid. As you know (or you’re just learning) this site is made by Jekyll, a static site generator written in Ruby. As the result of the work of Jekyll it is a static HTML website, so it’s not immediate to build a contact form. I tried to find a JS solution to maintain a full static website, but didn’t find any. So I wrote a few Ruby lines and the contact form is now working.

How to let the form work is strictly dependent on how you deploy your Jekyll website. I use Heroku so I deploy the site as a Rack-based app using Sinatra, this how-to works only if you have my deployment configuration. If not, you must adapt it to your needs.

The first step is to register a free account to reCAPTCHA and get the public and private API keys. Then register a Sendgrid free account as Heroku add-on in your website app.

To use a rack-based app on Heroku you need a config.ru file, this is mine:

require 'rubygems'
require 'sinatra'
require 'rack/recaptcha'

use Rack::Recaptcha, :public_key => 'MyPublicKey', :private_key => 'TheS3cr3tS3cr3tKey'
helpers Rack::Recaptcha::Helpers
enable :sessions

require './application'
run Sinatra::Application

Just insert the reCAPTCHA keys and the file is ready. Now the application.rb file called by the require above:

set :public, Proc.new { File.join(root, "_site") }

post '/send' do
  if recaptcha_valid?
    session[:captcha] = true
    { :message => 'success' }.to_json
  else
    session[:captcha] = false
    { :message => 'failure' }.to_json
  end
end

post '/send_email' do
    require 'pony'
    require 'json'

    if session[:captcha]
      session[:captcha] = false
      res = Pony.mail(
	:from => params[:name] + "<" + params[:email] + ">",
	:to => 'me@mydomain.com',
	:subject => "Message from your awesome website :)",
	:body => params[:message],
	:port => '587',
	:via => :smtp,
	:via_options => {
	  :address              => 'smtp.sendgrid.net',
	  :port                 => '587',
	  :enable_starttls_auto => true,
	  :user_name            => ENV['SENDGRID_USERNAME'],
	  :password             => ENV['SENDGRID_PASSWORD'],
	  :authentication       => :plain,
	  :domain               => 'heroku.com'
	})
      content_type :json
      if res
	  { :message => 'success' }.to_json
      else
	  { :message => 'failure' }.to_json
      end
    else
      { :message => 'failure' }.to_json
    end
end

before do
    response.headers['Cache-Control'] = 'public, max-age=36000'
end

not_found do
    File.read('_site/404.html')
end

get '/*' do
    file_name = "_site#{request.path_info}/index.html".gsub(%r{\/+},'/')
    if File.exists?(file_name)
	File.read(file_name)
    else
	raise Sinatra::NotFound
    end
end

As you see in the code I use two methods, send and send_email: the first check the captcha and set a session variable, returning a JSON message (success). The second method sends the email using Pony only if the captcha was verified. The SendGrid username and password are loaded automatically from your Heroku environment.

The last step is to create the contact form page, including the reCAPTCHA js:

<script type="text/javascript" src="http://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>

<script type="text/javascript">
  function showRecaptcha(element) {
     Recaptcha.create("MyPublicKey", element, {
       theme: "red",
       callback: Recaptcha.focus_response_field});
   }
   $(document).ready(function(){
	showRecaptcha('recaptcha_div');
	
	$("#form").submit(function(ev){
	    ev.preventDefault();
	    if (!$(this).valid()) return;
	    $.ajax({
	      type: "post",
	      url: "/send",
	      data: $('#form').serialize(),
	      dataType: "json",
	      success: function(response) {
		if(response.message === "success") {
		  $.ajax({
		      type: "post",
		      url: "/send_email",
		      data: $('#form').serialize(),
		      dataType: "json",
		      success: function(response) {
			  $('#form').html("<div id='message'></div>");
			  if(response.message === "success") {
			      $('#message').html("<h2>Message successfully sent.</h2>").hide().fadeIn(1500);
			  } else {
			      $('#message').html("<h2>Error sending the message</h2>").hide().fadeIn(1500);
			  }
		      },
		      error: function(xhr, ajaxOptions, thrownError){
			  $('#form').html("<div id='message'></div>");
			  $('#message').html("<h2>Error sending the message</h2>").hide().fadeIn(1500);
		      } 
		  });
		} else {
		  showRecaptcha('recaptcha_div');
		  $('#notice').html("Captcha failed!").hide().fadeIn(1500);
		}
	      },
	      error: function(xhr, ajaxOptions, thrownError){
		  $('#form').html("<div id='message'></div>");
		  $('#message').html("<h2>Error sending the message</h2>").hide().fadeIn(1500);
	      }
	    });
	});
    });
</script>

The code seems a bit tricky :) but it’s simple. It just intercepts the form submission, send a first POST call to /send and, if the captcha is verified, generates a second POST call to /send_email, which sends the email. The last piece is the form HTML code:

<form id="form" method="post">
	<label for="name">Name</label>
	<input type="text" name="name" id="name" />

	<label for="email">Email</label>
	<input type="text" name="email" id="email" />

	<label for="message" class="label">Message</label>
	<textarea name="message" id="message"></textarea>

	<div id="recaptcha_div"></div>
	<div id="notice"></div>

	<input class="submit" type="submit" value="Send" />
</form>

That’s it, now you can send email from a static website.


After the update to Fedora 17 (64bit), Wunderlist stopped woking with the error:

./Wunderlist: symbol lookup error: /lib64/libgdk_pixbuf-2.0.so.0: undefined symbol: g_bytes_unref

It seems to have some problems mixing the internal and the system libraries, so with the help of Google and trying some tricks, I managed to make it work again:

cd Wunderlist-1.2.4/runtime/1.2.0.RC3
rm libglib-2.0.so libglib-2.0.so.0 libproxy.so.0
ln -s /usr/lib64/libproxy.so.1 libproxy.so.0

After this fix the old error disappears but a new one appears:

[Titanium.Host] [Error] Could not load module (~/Wunderlist-1.2.4/modules/tiui/1.2.0.RC3/libtiuimodule.so): "Error loading module (~/Wunderlist-1.2.4/modules/tiui/1.2.0.RC3/libtiuimodule.so): libnotify.so.1

Another symbolic link and Wunderlist will work again:

ln -s /usr/lib64/libnotify.so.4 libnotify.so.1

My Fedora is a 64bit o.s. but the error seems to appear with 32bit too. If you’re working on a 32bit system just check and modify the paths to the libraries (probably /usr/lib instead of /usr/lib64)


Approfittando della pausa estiva sono riuscito a lavorare un po' su Rubyfatt, il software che mi sono scritto per la gestione della mia partita IVA.

Senza dilungarmi troppo, dalla versione 1.0 il software è ormai maturo e può essere usato senza problemi (spero). Vi rimando alla pagina ufficiale all'indirizzo: http://rubyfatt.kreations.it in cu si trova la lista di tutte le caratteristiche e le istruzioni per installarlo.
Ovviamente ogni aiuto è ben accetto, trovate tutto sulla pagina di Github del progetto

Video Demo