mercoledì 31 ottobre 2007

Nokia N80 vs Puppy Linux, il segno dei tempi

Sul mio PC portatile, un Toshiba 2450-401 vecchio di 5 anni, ho installato Puppy Linux.
E' una distro Linux leggera nella maniera più intelligente. Carica solo lo stretto indispensabile all'avvio, gira tutta in RAM, gestisce periferiche e configurazioni varie attraverso piccoli, semplici e intelligenti tool. Su questo portatile funziona tutto, compresa la scheda Wifi su slot PCMCIA configurata esclusivamente attraverso un tool visuale.
Puppy Linux mi ha permesso di utilizzare il portatile anche per una semplice occhiata alla posta, cosa che con Windows Xp o con Ubuntu non avrei potuto fare.
Ho anche un cellulare Nokia N80. Un cellulare strepitoso, un coltellino svizzero con cui, per esempio, posso accedere attraverso UPNP allo streaming di Orb dei contenuti del mio HTPC.
C'è GMail, c'è l'upload delle foto su Flickr, c'è VNC.
Però è leeeento.
La fotocamera è il modulo che ne risente di più (è in pratica impossibile utilizzare il flash, pena foto mosse e ritardate rispetto all'inquadratura), ma ne risente anche la Galleria, la Rubrica, lo switch tra fotocamera e videocamera.
Così mi è venuta la curiosità e ho fatto la prova:
video
Il PC si avvia mezzo secondo prima del cellulare. Magari fra qualche anno i PC non avranno virus e i cellulari sì, i PC non riceveranno spam e l'archivio SMS ne sarà pieno.
Adoro il mio N80, ma non capisco perchè, nei requisiti necessari per l'usabilità, alla Nokia non abbiano pensato alle prestazioni.
O forse ci hanno pensato, ma ciò avrebbe comportato dell'hardware che avrebbe lievitato il costo, e di conseguenza la competitività.
Facendo ciò, hanno tolto appetibilità a un dispositivo che poteva essere (e in parte lo è) uno dei migliori e meglio bilanciati nel suo mercato.

Note: per il test mi sono comportato in modo che risultasse il più oggettivo possibile; avvio il PC e lo tengo fermo sulla schermata di GRUB (il software che permette di scegliere quale sistema operativo avviare), quindi accendo il cellulare un attimo prima per compensare il ritardo "meccanico" del pulsante.
Ad un certo punto premo Invio sul PC, ciò perchè Puppy cerca di acquisire un indirizzo IP tramite il DHCP server della mia rete Wifi. Per saltare questa fase (che non riguarda la velocità del sistema, è puramente un tempo di attesa) occorre appunto premere Invio.
Se si guarda il video, la schermata di Puppy appare un attimo prima della comparsa della schermata del Nokia (che, volendo infierire, si vede benissimo costruirsi sullo schermo a blocchi).

venerdì 19 ottobre 2007

SQL indipendente dal dialetto con Hibernate

L'esigenza che avevamo era di potere scrivere delle classi Java per interrogazioni SQL, mantenendo comunque una certa indipendenza dal server utilizzato. Le ricerche su Google non hanno dato frutti, il che mi sembra strano, dato che mi sembra un'esigenza diffusa.
Comunque, mi è venuto in mente che Hibernate poteva avere delle funzionalità del genere. Le interrogazioni in HQL o tramite Criteria alla fine vengono tradotti in SQL adattabile praticamente a ogni server DB sul mercato.
Il dubbio poteva essere se, trovando le classi che generavano il codice SQL, queste non fossero accoppiate con altre classi Hibernate (per esempio con la sessione), rendendole inutilizzabili.
Siamo stati fortunati: nel package org.hibernate.sql, esiste un insieme di classi per svariati processi di generazione di SQL guidati da una opportuna istanza della classe Dialect.
Quindi, basta usare i package org.hibernate.sql e org.hibernate.dialect per scrivere SQL indipendente dal dialetto. I due package sono semplici, poco strutturati e si possono importare facilmente in un progetto Java qualsiasi. C'è comunque da includere le librerie hibernate-3-x.x.jar e commons-logging-x.x.jar (e naturalmente log4j, ma già lo usate vero? :-) ), che pesano alcuni Mb.
Purtroppo non sono tutte rose e fiori. Queste classi sono puramente utility, concepite per essere utilizzate all'interno delle procedure di conversione delle interrogazioni di Hibernate, non per vivere di vita propria.
Sono mal documentate, poco coerenti, alcune parti sembrano messe e mai utilizzate e la procedura di scrittura di una query è per nulla strutturata.
Però quando si vuole scrivere una query che potrebbe girare su server DB diversi, possono venire utili.

Spippolando un pò, ho capito che le classi utili sono essenzialmente due:
  • org.hibernate.sql.SimpleSelect, utile se si vuole fare una query senza join, su una sola tabella. In questo caso è più difficile incontrare differenze tra i dialetti, e infatti la sola cosa che viene gestita è la clausola FOR UPDATE per mettere un lock sulle righe.
  • org.hibernate.sql.QuerySelect, qui è possibile fare di tutto. Come scrivevo prima, la gestione è raffazzonata, non propriamente object-oriented. E' una classe da battaglia, scritta per risolvere un problema specifico, tuttavia può essere utile.
A titolo di esempio, ho provato a creare una query con una inner join e una outer join, facendola generare con i dialetti MySql e Oracle. Non ho scelto a caso, perchè con Oracle le outer join hanno una sintassi che più proprietaria non si può :-)

Supponiamo di avere un metodo del genere:

public static QuerySelect buildASelectExample(Dialect dialect) {
QuerySelect theQueryThing = new QuerySelect(dialect);
SelectFragment selectFragment = new SelectFragment();
String[] columns = {"id", "firstname||' '||lastname", "address||', '||state"};
String[] aliases = {"id", "name", "address"};
selectFragment.addColumns("p", columns, aliases);
selectFragment.addColumn("o", "plant");
JoinFragment joinFragment = dialect.createOuterJoinFragment();

String[] fks1 = {"user_fk"};
String[] pks1 = {"id"};
String[] fks2 = {"office_fk"};
String[] pks2 = {"id"};
theQueryThing.addSelectFragmentString(selectFragment.toFragmentString());
theQueryThing.prependWhereConditions(" p.age between 18 and 35 ");
theQueryThing.getJoinFragment().addJoin("person",
"p", fks2, pks2, JoinFragment.INNER_JOIN);
theQueryThing.getJoinFragment().addJoin("person",
"p", fks1, pks1, JoinFragment.LEFT_OUTER_JOIN, " x = y");
theQueryThing.getJoinFragment().addCondition(" id = ? ");

return theQueryThing;
}

Invocando il metodo passando come dialect un'istanza di org.hibernate.dialect.MySQLDialect, questo è il risultato:

select p.id as id, p.firstname||' '||lastname as name, 
p.address||', '||state as address,
o.plant as plant from person p on office_fk=p.id
left outer join person p on user_fk=p.id
and x = y
where id = ? and (p.age between 18 and 35)


Utilizzando invece il dialetto org.hibernate.dialect.OracleDialect:

select p.id as id, p.firstname||' '||lastname as name, 
p.address||', '||state as address,
o.plant as plant from person p, person p
where office_fk=p.id
and user_fk=p.id(+) and x (+)= y
and id = ? and (p.age between 18 and 35)


C'è da dire che un uso ancora più proficuo può essere quello delle DDL, dove effettivamente i server si differenziano un pò di più, sopratutto sui tipi. Per questo è meglio invece vedere direttamente la classe org.hibernate.dialect.Dialect, con tutte le sue specializzazioni.

martedì 9 ottobre 2007

Castomer cher

Diciamoci la verità: quanti sono in Italia che, gestendo un'assistenza clienti, si sarebbero posti un dubbio del genere, e quanti avrebbero risposto così?

Programmazione 0.2?

Mi sono imbattuto in questo interessante articolo di Tim O'Reilly a proposito di una lista di cambiamenti dalla programmazione 1.0 alla 2.0, che rispecchia volutamente quella Web 1.0 -> Web 2.0:

La lista proviene, manco a dirlo, da un gruppo di appassionati di Ruby:


Molto interessanti i commenti, tra cui concordo con questo:

"I suspect that the author of the list is relatively new to programming and is consequently commenting only on changes from recent practices. For instance, there is an emerging rejection of the massive class libraries used with Java (among others) because they’re too big for most people to have a handle on. But such excessive libraries are only a recent phenomenon. I believe that much of what is happening now is simply a retreat from excessive complication, something that happens periodically in the programming world. I personally am thrilled that many “new” practices resemble those that my colleagues and I used in the 1970s and that today would be termed “agile”. And “modular” has been considered good programming practice since the 1950s. Perhaps the shift he describes would be better characterized as from Programming 2.0 back to Programming 1.0."

Chiunque si occupi di programmazione da un pò di anni ha la stessa sensazione, credo.
Qui non sta succedendo niente di nuovo.
Java e le sue quintalate di framework hanno generato il classico e tutto sommato prevedibile rigetto e il ritorno nostalgico alla buona vecchia programmazione fatta di creatività piuttosto che assemblaggio di roba precotta.

L'innovazione però c'è, secondo me: sono cambiate le piattaforme, e in maniera radicale anche. Non si lavora più sull'applicazione client chiusa nel proprio mondo, e si tende piuttosto a contribuire a una nuvola di microapplicazioni web collaborative.

Mi immagino il desktop fra qualche anno sempre più dominato dal browser e il web come una sorta di sistema operativo diffuso su cui risiederanno gran parte delle proprie applicazioni.

Da tutto ciò mi chiedo se è possibile, allo stato attuale, pensare ad una azienda le cui applicazioni siano tutte residenti sul web (nella intranet o nei vari servizi presenti su Internet).
Già Google Apps fornisce un servizio del genere, con Google Documents, Mail, Chat, e Calendar, e una home page aziendale. Altri servizi che mi vengono in mente potrebbero essere il timesheet, la gestione della contabilità, gli strumenti di sviluppo, ecc.

Se poi tutte queste applicazioni fossero web 2.0, integrabili, provviste di feed (nell'ipotesi che ci sia qualcosa per cui abbia senso fornire un feed), allora comincio a vederci un senso :-)

domenica 7 ottobre 2007

Il miio meediacenter con Meedio - Prima parte

Mi stupisce, per quanto abbia cercato, di non aver trovato articoli su HTPC realizzati con Meedio nella sua ultima (in tutti i sensi) versione.

Descrivo dunque cosa ho fatto io, senza troppi patemi e senza troppi approfondimenti sul genere. In realtà non sono un patito di home theater, dolby surround, HDTV ecc. Volevo semplicemente un sistema per:
  1. memorizzare in maniera ragionevolmente sicura i miei video (vacanze/feste, ma anche film e serie TV)
  2. trovarli e vederli in maniera semplice, per non farli cadere nel dimenticatoio
Ho evidenziato questi due punti perchè, nonostante sembrino dei non-problemi, è stato veramente difficile risolverli nell'ambito di un sistema casalingo, economico e non troppo complesso (vedi anche l'ottimo articolo di Paolo Attivissimo).
La soluzione che ho scelto, e che ritengo un buon compromesso, è di tenere i file su hard disk, ridondato con il RAID che consente il protocollo SATA. L'unico costo "in più" è il secondo hard disk, ma con i prezzi attuali...

Non mi interessa tuttora la funzionalità di PVR, a meno che non faccia l'abbonamento a Sky. Non è nelle mie priorità in ogni caso.

La possibilità più economica sarebbe un box USB con funzionalità di mediaplayer, però ci si ritrova comunque con uno strumento limitato sia nelle funzionalità che nei formati supportati. Idem per quei lettori da tavolo da collegare tramite WiFi al proprio PC (per es. questo della NetGear).
Per un pò avevo buttato un occhio al MacMini, ma non ho letto bene di Front Row (il media center software di Apple) e non ha l'uscita TV analogica.

Così ho provato ad assemblarmi un HTPC, senza spendere troppo e tenendo in mente la facilità d'uso (wife proof).
Quindi utilizzo esclusivamente da telecomando, e software semplice e completo.
Il risultato non è ancora definitivo, ma non è neanche malaccio:
L'hardware è il più micragnoso che abbia trovato: processore AMD Athlon 3800+, mobo Asus M2NPV-VM (non vi fate ingannare, l'ho scelta perchè ha tutto integrato, compresa l'uscita TV analogica e digitale), un disco SATA da 160Gb e 1 Gb di RAM.
Sul case ho investito di più. Se c'è una cosa su cui non risparmiare, negli HTPC, è la silenziosità. Non sono ancora al silenzio nero, ma posso vedere un film senza il sottofondo aeroportuale dei classici case.
Ho scelto un Thermaltake Bach, esteticamente gradevole e molto spazioso, in cui ho montato un alimentatore Zalman da 300W trovato usato su EBay.
I due si difendono bene, però il Thermaltake ha due ventole di ricircolo posteriori che sono la fonte primaria di rumore. Appena ho un pò di tempo vedrò come risolvere.

E siamo infine arrivati a Meedio: quello che si vede nello screenshot è la schermata principale, con i menù tipici di un media center come si deve.
Il PC lo amministro attraverso UltraVNC, soluzione che mi è sembrata più efficiente e versatile del remote desktop di Windows.
Sullo stesso PC ho installato anche un server FTP (Filezilla Server), Orb, che consente di mandare in streaming su extranet i propri contenuti audio e video (dico extranet perchè, essendo server UPNP, Orb è in grado di sfruttare la banda maggiore nel caso si acceda da rete locale).

Meedio, una volta prodotto commerciale, fu acquistato da Yahoo, che ne fece un prodotto chiuso e orientato alla fruizione dei propri contenuti online. Se proprio interessa, si chiama Yahoo! Go TV.
Ma Meedio è molto di più. E' un sistema estremamente modulare che, grazie a una comunità viva e attiva ancora oggi, vanta 376 plugin di varia natura disponibili.

Subito dopo la vendita a Yahoo, Meedio fu reso liberamente scaricabile e nel frattempo nacque l'idea di MeediOS, una versione completamente riscritta e open source di Meedio.
Purtroppo lo sviluppo di MeediOS va a rilento, ma sullo stesso sito è possibile scaricare Meedio e tutti i suoi plugin.
Questa estate è stata pubblicata inoltre una versione bundle di Meedio con gli innumerevoli plugin (solo quelli più gettonati, che sono almeno una trentina) già inclusi e preconfigurati.

Installando questo, si ottiene un media center che dà la polvere (tranne forse sul PVR, che non ho mai provato) a tutti i vari Windows Media Center, Mediaportal, TVedia, GBPVR, xLobby.

Nella prossima parte si vedrà anche il perchè.

giovedì 4 ottobre 2007

Rails Rumble? Pfui

Leggo oggi su downloadblog che si è conclusa la competizione Rails Rumble 2007, che consiste nella sfida tra un centinaio di team di sviluppo per creare un'applicazione web funzionante in 48 ore con Rails.

Casca a fagiolo :-)

Ieri, un pò per scopo didattico un pò per goliardia, ho realizzato un'applicazione web per caricare e in seguito visualizzare i risultati di una votazione (nel nostro caso il pretesto è l'elezione della RSU aziendale).
Bene, l'ho realizzata con Grails in 5 ore. Avete letto bene, 5 ore.
Sono partito da zero assoluto, generando il progetto con grails create-app, e non avendo mai scritto una sola riga in Groovy nè Grails.

Ho fatto generare le pagine CRUD delle mie entità (Sede e Candidato), ho ritoccato le pagine generate per rimuovere elementi indesiderati (tipo l'id), ho aggiunto un tocco di Ajax affinchè nell'elenco dei candidati fosse possibile
incrementare/decrementare il voto a ciascuno (anche di Ajax è la prima volta che faccio uso), ho aggiunto una pagina con i risultati presentati graficamente alla meno peggio e infine ho aggiunto l'autenticazione per modificare i dati (che è possibile solo per lo Scrutatore).

Chiaramente ho lasciato il layout di default, nonchè le varie pagine di edit. Ma il tutto è un'applicazione vera e utilizzabile, che lavora su un DB Hypersonic attraverso Hibernate. L'infrastruttura è gestita da Spring e la presentazione da Sitemesh. Grazie a Grails non li ho nemmeno sfiorati.

Per la cronaca Tasty Planner è l'applicazione che ha vinto la competizione. Non è male, sia graficamente che concettualmente. Il team mi pare fosse di almeno 3 persone. Per cui tre risorse per otto ore al giorno per due giorni fanno 48 ore uomo.
Oltretutto mi sbaglierò ma la tag cloud sulla homepage non funziona.

Grails rulez? No, non lo penso affatto. Rails ormai è strumento consolidato e strapieno di plugin e soluzioni pronte da usare.

Ma Java non si muove più a passo di elefante.

PS: Per i fan di Ruby, il titolo è puramente ironico.

11/09/2007 - Update: La tag cloud di Tasty Planner adesso funziona