Steam Locomotive

Il più inutile tra i programmi inutili in circolazione per Linux. Quante volte nella vostra vita di utenti Linux (o Mac Os) usate il comando LS? E quante volte, nella fretta, vi capita di sbagliare e scrivete invece SL? Normalmente il sistema vi risponde con un tristissimo:

-bash: sl: command not found

Da adesso possiamo unire l’utile al dilettevole con un simpatico programma che, rispondendo al nome di SL “Steam Locomotive”, disegna sul terminale… indovinate cosa…

Un simpatico modo per spezzare un pò la monotonia delle lunghe ore passate a compilare roba con nomi strani.. Il programmino è scritto in C, è stato realizzato da un tal Masashi Toyoda, e potete scaricare il sorgente a questo indirizzo. Una volta scompattato l’archivio TAR (qualcosa del tipo tar -xf sl.tar) basta dare il comando make per compilare il tutto. A questo punto è sufficiente copiare il file eseguibile in “/usr/local/bin” per averlo sempre a disposizione!

Ciao a tutti!

Quick Bash Tip: come estrarre nome file ed estensione da un path

Continuano le piccole note di bash. Stavolta vediamo un paio di facili comandi per estrarre nome file ed estensione da un path. Inserisco il tutto in un piccolo script che analizza tutti i file nella directory corrente e ne stampa prima il nome e poi l’estensione.

for file in $(ls) ; do
  filename=${file##*/}
  basename=${filename%\.*}
  extension=${filename##*.}
  echo Nome: ${basename}, estensione: ${extension}
done

Ulteriori informazioni (per i non deboli di cuore) a questo indirizzo.

Quick tip: come creare un PDF da riga di comando a partire da un TXT

Piccolo suggerimento su un modo rapido per creare un pdf a partire da un file di testo con un unico comando da terminale (come sempre vale per Linux e Mac Os X). Supponiamo di voler convertire un file di nome “prova”:

cat prova | enscript -p - | ps2pdf - file.pdf

La prima parte apre il file e ne passa il contenuto alla seconda parte.

Nella seconda parte il programma “enscript” trasforma quanto ricevuto in formato PostScript e lo passa alla terza parte. Da notare che si deve usare l’opzione “-p” seguita da uno spazio e un altro trattino, per dire che il postscript deve essere inviato allo stdout (altrimenti viene inviato alla stampante di sistema).

Nella terza parte il programma “ps2pdf” trasforma quanto ricevuto nel file “file.pdf”.

Facile e indolore, ma lo scrivo perchè ci ho messo tipo mezz’ora a scoprirlo e magari in questo modo risparmio un pò di fastidio a qualcun altro.

Quick tip: come splittare un file in più parti

Piccolo suggerimento su come suddividere un file in più parti di dimensione nota: il comando SPLIT, disponibile su Linux e Mac Os X.

split -b DIM FILE PREFISSO

l’opzione -b serve a specificare la dimensione dei componenti da creare (in byte). Si possono usare anche i suffissi b (512 byte), k (1 kb) e m (1 Mb). Ad  esempio, se scrivo “-s 4k” significa che voglio frammenti di 4 kbyte l’uno.

FILE è il nome del file da scomporre

PREFISSO è il prefisso con il quale verranno chiamati i frammenti creati, che di default saranno una cosa del tipo PREFISSOaa, PREFISSO ab, PREFISSOac, PREFISSOad… ecc… volendo è possibile intervenire con le opzioni -a (imposta la lunghezza del suffisso, che di default è 2) e -d (suffissi numerici invece che letterali).

Esempio: mi serve dividere il file bob.dat in frammenti di 4Kb da dare in pasto a un altro programma per un’analisi statistica:

split -s 4k bob.dat bob

I frammenti si chiameranno bobaa, bobab, bobac, bobad, ….. e così via fino alla fine del file (o fino a bobzz, dopodichè lo split si blocca perchè ha finito lo spazio dei nomi; si può ovviare con l’opzione -a).

Per ulteriori informazioni:

split --help

Saluti!

Dividere i contatti di un vCard della Rubrica Indirizzi di MacOsX

I file VCF, come forse molti di voi sapranno, sono files contenenti informazioni di uno o più contatti di rubrica: praticamente l’equivalente virtuale di un biglietto da visita. La loro diffusione nasce, a mio avviso, dal fatto che sono abbastanza (sottolineo: abbastanza) standard (formato vCard) e sono composti in semplici caratteri di testo (ovvero possono essere perfino creati e modificati a mano con un normale editor di testo).

La possibilità della rubrica indirizzi di MacOsX di esportare i contatti in VCF è dunque interessante ai fini della compatibilità con altri sistemi, ma prevede una limitazione: se tento di selezionarne più d’uno e poi eseguire l’esportazione (Archivio -> Esporta vCard) il risultato non saranno dei singoli files ma un unico VCF contenente in sequenza tutti i contatti. Problema: le implementazioni più rigorose del formato vcf (ad esempio quelle dei cellulari) prevedono la presenza di un solo contatto per file. Come aggirare questo problema? Selezionare ed esportare un contatto alla volta, dando ogni volta un nome diverso e sprecando così la mia vita mortale esportando centinaia di contatti?

Ovviamente no. I potenti mezzi del Terminale ci forniscono la possibilità di suddividere e rinominare comodamente il contenuto del VCF “di gruppo” in pochi e semplici (!?!) passaggi.

1) Selezionare tutti i contatti, Archivio -> Esporta vCard, salvare il file “Schede.vcf” in una cartella dedicata.

2) Da terminale, suddividere il file in più spezzoni ciascuno dei quali contiene un contatto.

csplit -n3 -k Schede.vcf /END:VCARD/1 {1000}

3) i singoli file saranno nominati con il metodo di default: xx + numero d’ordine. L’ultimo file sarà in più e quindi vuoto (a causa del metodo di separazione utilizzato in precedenza). Possiamo andare a cancellarlo a mano, o possiamo usare uno script che analizza tutti i file alla ricerca di quello (o quelli) con dimensioni nulle:

for i in $(ls xx*); do
a=$(du $i);
a=$(echo $a | cut -d’ ‘ -f1);
if [ "$a" = "0" ]; then
rm $i;
fi;
done

Molto più divertente, no? Scherzi a parte, è anche tutto automatico, il che rende possibile utilizzarlo in uno script.

3) Per concludere, possiamo rinominare i files (xx[numero]) con il FN (ovvero il nome visualizzato) del contatto che contengono. A questo scopo si può usare questo sistema:

for i in $(ls xx*); do
a=$(cat $i | grep FN | sed -e ‘s/FN://g’ | sed -e ‘s/ /_/g’);
mv $i $a.fn;
done

Ecco fatto.. purtroppo il sistema non è perfetto e alcune schede non riuscirà a convertirle, vuoi perchè manca il FN o perchè questo contiene caratteri che al terminale non piace. Per queste poche eccezioni bisognerà procedere a mano, ma il grosso del lavoro è svolto automaticamente. Comodo, no?

Creare una mappa personalizzata da OSM: lo script

Come prometto a vuoto da mesi, finalmente mi voglio mettere a scrivere un articolo per spiegare un sistema completamente automatico mediante script bash per generare una mappa a partire dai dati di OpenStreetMap. Lo script è un allegro guazzabuglio di utility da riga di comando destinate a scaricare i dati dal server OSM sotto forma di xml, “compilarli” per generare un file SVG, convertire tale file in un PNG e aggiungerci qualche particolare utile: un header, un footer con il copyright, un frame di contorno e una scala kilometrica. Questo articolo, come i miei fedeli lettori avranno già intuito, nasce da una fusione di precedenti post: questo, questo, questo, questo.

Per iniziare i requisiti:

  • Avremo bisogno di un computer linux connesso alla rete (e fin qui…); io uso Ubuntu, non posso garantire il funzionamento di tutte le utility richiamate da questo script su altre piattaforme, anche se probabilmente su Mac si può fare (se qualcuno ci prova mi faccia sapere che aggiornerò l’articolo). Ovviamente Windows non è neanche preso in considerazione.
  • Avremo bisogno di queste utility, scaricabili dal repository: xsltproc (nell’installazione di default, a quanto mi risulta), wget (idem), convert+composite (nella suite ImageMagick), bc.
  • Avremo bisogno del programma per calcolare la distanza in chilometri tra due punti espressi in coordinate GPS, di cui ho parlato in precedenza (in questo post, nella sezione “un programma in C”). Copiarlo in un editor di testo, compilarlo seguendo le istruzioni nel post e avere cura che l’eseguibile si chiami “calcola” (senza alcuna estensione), non “converti” come nell’esempio.
  • Per finire, avremo bisogno di una serie di files da scaricare dai repository di openstreetmap, che ci serviranno per compilare la mappa vera e propria.

In riferimento all’ultimo punto dell’elenco, avremo bisogno di un ambiente di lavoro costituito dalla seguente struttura di cartelle:

data
|– osm-map-features-z17.xml
|– calcola
|– renderizza (così chiameremo lo script che andremo a utilizzare)
|– osmarenderer.xsl

stylesheets
|– symbols
|– il contenuto di questa cartella

Uhm.. dovremmo avere tutto, spero di non aver dimenticato nulla.. Per semplificarvi la vita, ho provveduto a uppare su una condivisione box.net uno zip con tutto il necessario per cominciare a renderizzare (sempre se non mi sono dimenticato nulla); scaricate pure qui. A questo punto manca solo lo script, che come ho detto prima si chiamerà, con molta fantasia, “renderizza” (beh, potete anche cambiargli il nome).

Ecco dunque l’agognato script, pezzo per pezzo:

Impostiamo un pò di variabili che ci verranno buone per dopo. Le uniche da modificare sono ovviamente le coordinate GPS (latitudine e longitune) della zona che vogliamo inserire nella mappa

# coordinate gps zona
# nb: max 0.25 gradi sia latitudine che longitudine

MAXLAT=45.8239
MINLAT=45.8045
MAXLON=10.0841
MINLON=10.0584

# nomi file
OSM=”data.osm”     # nome del file dati OSM
SVG=”map.svg”    # nome dell’output in formato svg
PNG=”map.png”    # nome dell’output in formato png

Recuperiamo i dati aggiornati:

echo “recupero dati dal server OSM…”
wget -O ${OSM} http://api.openstreetmap.org/api/0.5/map?bbox=$MINLON,$MINLAT,$MAXLON,$MAXLAT

Eseguiamo il rendering:

# livello del rendering
livello=17

# identifica il livello di dettaglio del rendering;
# per aree piccole conviene usare il livello 17;
# per eseguire il rendering sarà richiesto il
# file osm-map-features-zXX.xml (XX = livello).

echo “rendering mappa..”
xsltproc osmarender.xsl osm-map-features-z${livello}.xml > ${SVG}

Convertiamo la mappa (in formato SVG) in un file grafico PNG, più facilmente utilizzabile:

# —- conversione mappa in png

density=600     # risoluzione del file grafico.
scale=1000         # dimensione in px del file grafico

echo “conversione in PNG…”
convert -density ${density} -scale ${scale} ${SVG} ${PNG}

Aggiungiamo un header con un testo a scelta. In questo caso inserisco il mio nome e la data dell’aggiornamento (ovvero la data corrispondente al file dati).

# —- aggiunta header

echo “aggiunta della data alla cartina..”
convert xc:white -resize 1×15! blank.ppm
convert -append blank.ppm ${PNG} intermediate.ppm
convert intermediate.ppm -gravity “North” -draw “text 0,3 ‘Updated on: $(date -r ${OSM}) by PicciMario’” ${PNG}
rm blank.ppm intermediate.ppm

Aggiungo un footer con un copyright OSM.

# —- aggiunta footer

echo “aggiunta copyright alla cartina..”
convert xc:white -resize 1×20! blank.ppm
convert -append  ${PNG} blank.ppm intermediate.ppm
convert intermediate.ppm -gravity “South”
(continua) -draw “text 0,3 ‘Copyright 2008 OpenStreetMap (openstreetmap.org)’” ${PNG}
rm blank.ppm intermediate.ppm

La parte più incasinata: creo il simbolo della scala e lo inserisco nella mappa

# —- aggiunta scala

echo “aggiunta scala 1km”

# calcola larghezza in km della mappa
larghezza=$(./calcola $MINLON, $MAXLON, $MINLAT, $MINLAT )
# misura la larghezza in px della mappa
larghezzapixel=$(identify -format %w $PNG)
# calcola l’equivalenza px/km
pixel1km=$(echo “$larghezzapixel/$larghezza” | bc)

# creazione simbolo scala
framewidth=1
scalesymbol=scale.png
scaleheight=10
scalecolor1=xc:blue
scalecolor2=xc:white

pixel100m=$(echo “($pixel1km-(2*framewidth))/10″ | bc)
convert ${scalecolor1} -resize ${pixel100m}x${scaleheight}! block1.ppm
convert ${scalecolor2} -resize ${pixel100m}x${scaleheight}! block2.ppm
convert +append block1.ppm block2.ppm block1.ppm block2.ppm block1.ppm block2.ppm block1.ppm block2.ppm block1.ppm block2.ppm ${scalesymbol}
convert -mattecolor blue -frame ${framewidth}x${framewidth} ${scalesymbol} ${scalesymbol}
rm block1.ppm block2.ppm

# aggiunta del simbolo alla cartina
composite -geometry +10+30 -gravity southwest ${scalesymbol} ${PNG} ${PNG}

rm ${scalesymbol}

E per finire l’aggiunta di un bordino blu di rifinitura.

# —- aggiunta frame di contorno al file completo

echo “aggiunta frame…”
convert -mattecolor blue -frame 1×1 ${PNG} ${PNG}

echo “operazione completata.”

Facile, no? Si, lo so, è abbastanza contorto.. Ma ha l’innegabile vantaggio che, una volta pronto, non devo fare altro che andare nella cartella, scrivere ./renderizza e lui fa tutto e mi presenta la bellissima cartina completa.

map

Ad esempio, mi piacerebbe metterlo nel cron del mio server per mostrare su una pagina web la cartina del mio paese con aggiornamenti giornalieri (peccato che il mio server è un computer di 10 anni fa e per fare il rendering ci mette 20 minuti). Se poi pensiamo alla possibilità di modificare il file xml (osm-map-features ecc..), che descrive il modo in cui la mappa è creata, possiamo ottenere infinite potenzialità di personalizzazione della mappa da noi creata (modificare i simboli, le dimensioni e i colori delle strade, scegliere cosa inserire e cosa no, …).

Beh, per oggi mi accontento di questo.. Fatemi sapere se il sistema vi piace e in caso mandatemi un link delle vostre opere d’arte :-)

Ciao a tutti!

Creare applicazioni .app con Platypus

Come noi mac user sappiamo, il formato base per un’applicazione mac è l’archivio con estensione .app… la comodità e ordinatezza (no, non credo che questa parola esista, ma rende l’idea) alla base di MacOS fa in modo che tale applicazione assomigli in tutto e per tutto a un file, sul quale basta doppiocliccare per avviarlo, mentre in realtà si tratta di una vera e propria cartella, con una struttura standard che contiene in primo luogo il file eseguibile vero e proprio, e in più tutti i dati di cui ha bisogno (l’immagine di icona, per esempio).

In particolare, le applicazioni hanno una grossa comodità, fondamentale per un mac user ormai avvezzo all’interfaccia grafica: si possono piazzare sul desktop e raggiungere in un battibaleno, qualunque cosa si stia facendo. Tale comodità per esempio manca da morire a un ex utente linux che è abituato a risolvere problemi enormi a colpi di bash. Stessa cosa può dirsi per altri linguaggi di scripting quali perl, python e altri ancora. Risulta infatti impossibile piazzare tali script sul desktop e sperare di avviarli con un doppioclick.. sarà invece necessario aprire un terminale e lanciarli usandone il nome (con il path, ovviamente, non saranno mica tutti nella home!), in alcuni casi preceduto dal nome dell’interprete… scomodo, eh?

Qui entra in gioco Platypus, un comodissimo programma opensource (come piace a me) a cui possiamo dare in pasto files di bash, Perl, Python, PHP, Ruby, Expect, Tcl, AppleScript, e lui ci darà in cambio un comodissimo .app con la sua bella icona, pronto per essere messo sul desktop e cliccato ad ogni necessità.

L’uso del programma è facilissimo. Mettiamo caso di voler avere a portata di mano uno script di bash (ad esempio per montare una condivisione remota senza passare per il terminale). Una volta avviato Platypus, sarà subito possibile inserire il nome della nuova applicazione e selezionare il tipo di contenuto (nel mio caso “Shell”). Nel campo “script path” potrò andare a inserire il nome del file contenente lo script, oppure se non l’ho preparato a priori posso premere il pulsante “new” e avrò a disposizione un comodo editor di testo per crearlo al volo. Un click di pulsante destro sull’icona nella parte sinistra della finestra permetterà di inserire una bella icona personalizzata nella mia nuova applicazione (ne ho trovate di fantastiche qui). Per concludere, posso scegliere il tipo di output del mio programma: posso cioè scegliere se il programma non aprirà alcuna finestra (ma si limiterà a farsi gli affari suoi senza dire nulla a nessuno), oppure mostrare una progress bar che mostra l’avanzamento dello script, o infine mostrare una finestra di testo contenente l’output dello script.

A questo punto potremmo anche accontentarci, ma Platypus non si limita a queste funzioni base: il power user è libero di esplorare la sezione di UI che appare premendo “Show advanced options”: a partire da lì è possibile inserire nell’applicazione files di supporto, impostare parametri come il path dell’interprete da utilizzare, ed eseguire un tuning un tantino più complesso di tutto quanto (ad esempio, si può attivare il supporto al drag&drop, in modo che lo script potrà agire su qualunque file io lasci cadere sulla sua icona).  Questo e molto altro ancora.

A questo punto è sufficiente premere il pulsante “Create Application”, selezionare il nome file della nuova applicazione e voilà, il gioco è fatto. Il mio script è ora una comoda applicazione cliccabile. Un modesto guadagno, diranno i puristi, ma in fin dei conti abbiamo in mano un sistema fatto per essere comodo, che senso ha non sfruttarne al pieno le potenzialità? Lasciamo la riga di comando a task più complessi!