Snellire la libreria google-play-services.jar con Android ProGuard

L’altro giorno stavo cercando di gestire i Google Analytics in una semplice applicazione mobile che sto sviluppando per conto mio con Titanium, ma quando sono andato ad aggiungere il modulo ti.ga non sono più riuscito a compilare niente a causa di un errore dovuto evidentemente a dei conflitti tra librerie.

L’errore di compilazione era questo:
[ERROR] : UNEXPECTED TOP-LEVEL EXCEPTION:
[ERROR] : java.lang.IllegalArgumentException: already added:Lcom/google/android/gms/maps/LocationSource;

Cercando in giro ho avuto la conferma che il problema era dovuto all’inclusione di una libreria google-play-services.jar all’interno del modulo, che faceva a cazzotti con quelle usate in un altro modulo importato nel mio progetto: ti.map.
Per completezza è necessario dire che la libreria ti.map – insieme alle altre native di Titanium – è accessibile in /Utenti/m.piccotti/Library/Application Support/Titanium/modules/android.

Classi duplicate, che fare

Il problema è comune e in molti sul web se ne lamentano, non solo parlando di Titanium e di questi moduli. Ovviamente non si può pensare di eliminare la libreria contenente le implementazioni delle api necessarie al modulo, ma lì per lì non sapevo che fare, finché non ho guardato meglio un altro modulo che mi serviva: ti.admob.
A differenza di ti.map il modulo ti.admob va tirato giù da GitHub e importato nel progetto, quindi mi è balzata all’occhio la presenza delle librerie google-play-services-base.jar e google-play-services-ads.jar; guardando il log ho notato il messaggio che mi interessava:
[DEBUG] : Skipping duplicate jar file: project_directory/modules/android/ti.admob/2.1.6/lib/google-play-services-base.jar

In sostanza Titanium evita l’importazione di librerie duplicate, ma la google-play-services.jar presente all’interno del modulo ti.ga non risultava duplicata ai controlli di Titanium, e il risultato era una duplicazione delle classi Android in fase di compilazione in presenza del modulo all’interno del progetto.

La soluzione

Quando non si sa dove sbattere la testa conviene sempre fare come gli altri, ho quindi preso la libreria google-play-services_base.jar dal modulo ti.admob (sviluppato da quelli di Appcelerator), e mi sono andato a cercare un jar contenente solo le librerie di Google Analytics. Naturalmente non ho trovato niente di simile, ma ero sulla strada giusta.

Pulizie manuali del jar

Mi serviva un jar contenente solo le classi necessarie al funzionamento di Google Analytics. Da ignorante nello sviluppo nativo Android ho fatto quello che avrebbe fatto qualunque altro bimbominkia, scompattando il jar e ricompattandolo solo dopo aver eliminato tutti i package fuori da “analytics”.

Forse un po' troppo drastico

Forse un po’ troppo drastico


Non ha funzionato, per la cronaca comunque un jar si può decomprimere con qualunque utility di decompressione file o con il comando:
jar xf google-play-services-analytics.jar
e si può ricreare con:
jar cf google-play-services-analytics.jar ./com.
Qui si spiega come funziona il comando per la creazione dei jar, questa cosa mi è comunque servita alla fine.

Android ProGuard

Effettivamente ripulire a mano le classi di una libreria sconosciuta aveva probabilità di successo pari a 0.00001, e io non sono così fortunato. Ho trovato però nel giro di poco la soluzione: ProGuard.
ProGuard è un tool che serve per ottimizzare e offuscare il codice Android. A me interessava eliminare dalla libreria google-play-services.jar inclusa nel modulo non funzionante tutto il superfluo lasciando solo la parte di analytics, e questa cosa si fa abbastanza agevolmente.

-injars google-play-services.jar
-outjars google-play-services-analytics.jar

-libraryjars /usr/local/Android/sdk/extras/android/support/v4/android-support-v4.jar
-libraryjars /usr/local/Android/sdk/platforms/android-21/android.jar

-dontoptimize
-dontobfuscate
-dontwarn com.google.**.R
-dontwarn com.google.**.R$*
-dontnote

-keep public class com.google.android.gms.analytics.**  {
    public protected *;
}

Vittoria in (quasi) quattro mosse:

  • includere questi comandi in un file di configurazione (chiamato ad esempio proguard.cfg)
  • copiare il file di configurazione appena creato e la libreria “onnicomprensiva” google-play-services.jar all’interno di /usr/local/Android/sdk/tools/proguard/lib (o comunque all’interno della directory dove si trova proguard.jar)
  • installare android-support-v4.jar se mancante, con l’Android SDK manager
  • eseguire il comando java -jar proguard.jar @proguard.cfg

ga-android-tools-proguard
… e il file salvifico compare magicamente all’interno della stessa directory.

Conclusioni

Ovviamente non è vero che il file risultante funzionava, infatti ho dovuto eliminare a mano tre o quattro classi da quest’ultimo come spiegato nella sezione “Pulizie manuali del jar”.
Il risultato è stato che finalmente quello che doveva funzionare ha funzionato, ma anche che le due librerie “base” e “analytics” pesano insieme meno della metà di quella unica, cosa non di poco conto nel mondo Android.

(Scola)pasta, birra e pirati: la CPI e il pastafarianesimo

cpi-fsm
Era il lontano 4 giugno 2012 quando – non ricordo bene perché (devo essere stato “toccato” a mia insaputa) – misi nel carrello Amazon Il libro sacro del Prodigioso Spaghetto Volante (Flying Spaghetti Monster in lingua originale).
A inizio 2015 sono venuto a conoscenza della Chiesa Pastafariana Italiana e del loro raduno nazionale a Bologna, e subito mi sono promesso che avrei partecipato al successivo… che ha avuto luogo esattamente una settimana fa a Firenze.

Veni, vidi, pici

Sono passati solo sette giorni ma mi pare un’eternità. Un fine settimana all’insegna dell’irriverenza e del divertimento, pura goliardia a spasso per Firenze, con turisti e locali che chiedevano ai pirati di scattare delle foto insieme.
cpi-quarto-raduno
La cosa divertente è che l’evento non è ruotato attorno a ragazzi tra i venti e i trent’anni come si potrebbe immaginare, ma osservando i circa 150 partecipanti ho visto uno spaccato della società molto ben distribuito. C’erano ragazzi e ragazze sui quindici anni come uomini e donne nell’intorno dei sessantacinque, coppie e single di entrambi i sessi, eterosessuali e gay dichiarati, e tutti si sono divertiti insieme in un clima di totale giovialità e goliardia.

Nel primo giorno ci si è divertiti a passaggiare per Firenze passando da un luogo di ritrovo all’altro, si è cenato tutti insieme (cena durante la quale la Sua Spaghettosa Bontà ha deciso di manifestarsi per la gioia del nostro palato), e infine si è fatta una processione/fiaccolata nel centro di Firenze, con scorta della Polizia, musica a palla e pause preghiera.


Il giorno due è stato un po’ più tranquillo, anche per dare modo a molti di riprendersi dalla sbornia della sera prima. L’abbiamo passato tutto nella terrazza dell’ostello (almeno finché ci sono stato io), principalmente ad ascoltare la “messa”.

Il Pastafarianesimo e la Chiesa Pastafariana Italiana

Il Pastafarianesimo ha origini antichissime, o almeno questo è quanto affermato dal profeta Bobby Henderson nel giorno della rivelazione, avvenuta il gennaio 2005. Qui potete trovare la lettera che scrisse per far notare che non sono solo la teoria dell’evoluzione e quella del creazionismo a dover essere insegnate nelle scuole perché ce n’è un’altra scientificamente provata…

Il primo disegno di Lui, per mano del Profeta

Il primo disegno di Lui, per mano del Profeta

Ma cos’è di preciso questo “Pastafarianesimo”? A voler sintetizzare tanto potrei dire che è la religione del vivi e lascia vivere, condita da tanto tanto spirito goliardico e “volemose be”. Questo è almeno il succo che esce leggendo con attenzione gli Otto condimenti, anche detti gli otto “Io preferirei davvero che tu evitassi”.

In molti paesi il movimento pastafariano sta crescendo piuttosto velocemente, e nella patria della pasta non poteva che formarsi – anche se un po’ in ritardo – uno dei centri più attivi.
La CPI nasce il 10 marzo 2012 grazie all’impegno di Giorgio De Angelis (“Pappa Al Zarkawi I”) che insieme ad alcuni amici gettò le fondamenta di quella che sarebbe diventata poi – pochi mesi dopo la sua morte – l’associazione “Chiesa Pastafariana Italiana”, fondazione avvenuta l’8 novembre 2014 durante il terzo raduno nazionale.

L'autodeterminazione della CPI

L’autodeterminazione della CPI

Le persone che formano lo zoccolo duro dell’associazione – ovvero i 7 del direttivo (Concistoro) e i 3 probiviri – sono più o meno gli stessi che hanno gettato le fondamenta tre anni fa. Io li ho conosciuti, sono persone normali che hanno deciso di dedicare parte del loro tempo a questa battaglia per la laicità dello stato. Nel primo numero dell’Osservatore pastafariano potete leggere i loro interventi.
L’associazione è ovviamente regolata da uno statuto, e il suo obiettivo principale è quello di essere riconosciuta come chiesa ufficiale dal Ministero degli Interni, così da offrire un’isola di approdo per tutte quelle persone che si sentono discriminate da questo stato chiaramente non laico in quanto non appartenenti a nessuna delle religioni attualmente riconosciute. Prego la Sua Sugosa Bontà che un giorno si raggiunga questo traguardo, purtroppo potrebbero volerci molti anni e non è detto che ci si riesca.

Infine la domanda che tutti si stanno ponendo…

Tutta questa gente che inneggia a un essere che nessuno può vedere e non da segni di se, che compie rituali strani mentre è vestita in modo strano… ci sta con la testa?
Non so, di sicuro però si diverte.

Se a questo punto vi state ancora domandando che c’entrano i pirati rileggete meglio i vari link. Di certo i pirati sono il popolo eletto, basta osservare i vari grafici per rendersene conto.

Ionic e plugin di Cordova

In questi giorni mi sono trovato a dover mettere le mani su un plugin di Cordova, resosi necessario su un’app scritta in Ionic (e quindi in AngularJS).
Ora, “tutti” sanno che i plugin di Cordova così come sono scritti mal si adattano ad applicazioni scritte in Angular, e in questo contesto si tende a utilizzare ngCordova.
Il problema è che, sebbene ngCordova incorpori ormai varie decine di plugin, proprio quello che serviva a me mancava. Io avevo bisogno di catturare l’immagine dello schermo in un certo momento – ovvero fare uno screenshot – e cercando sul web l’unico plugin abbastanza maturo e funzionante su Android e iOS mi è sembrato questo.

Rendere un plugin di Cordova più “AngularJS friendly”

Da sviluppatore (molto) poco esperto tanto in AngularJS quanto in Cordova, ho subito incontrato problemi nel collegare i due mondi, e cercando su Google mi è sembrato di non essere da solo. Al contrario.
Il modo più pulito mi è sembrato il seguente, e il primo “problema” (se così vogliamo chiamarlo) era risolto.

.service('$cordovaScreenshot', ['$q', function ($q){
    return {
        capture: function (filename, extension, quality){
            extension = extension || 'jpg';
            quality = quality || '100';

            var defer = $q.defer();

            navigator.screenshot.save(function (error, res){
                if (error) {
                    console.error(error);
                    defer.reject(error);
                } else {
                    console.log('screenshot saved in: ', res.filePath);
                    defer.resolve(res.filePath);
                }
            }, extension, quality, filename);

            return defer.promise;
        }
    };
}])

$cordovaScreenshot.capture('screenshot', 'jpg', 80);

In sintesi prima si registra il servizio Angular contenente la funzione di cattura (opportunamente corredata di libreria Q e promise), poi la si chiama, eventualmente passando delle funzioni da richiamare al termine o in caso di errore.

Modifica e test di un plugin su applicazione Ionic

Avvio l’applicazione – faccio fare lo screenshot – e subito mi rendo conto che dovrò sporcarmi le mani con l’Objective-C, perché sull’iPad il plugin non funzionava come doveva.
Inizio a modificare il file Screenshot.m che sta in project-directory/plugins/com.darktalker.cordova.screenshot/src/ios, avvio di nuovo il progetto ma delle modifiche neanche l’ombra. Inizio a cercare su internet (non oso immaginare cosa sarebbe il nostro lavoro senza un motore di ricerca web…), lancio vari comandi di Cordova consigliati dagli esperti di turno ma ancora niente.
Ancora un po’ di ricerche e capisco che i plugin vanno rimossi e riaggiunti, in questo modo si è certi che il tutto viene ricompilato ad ogni test. I comandi sono cordova plugin remove plugin-url-or-directory-or-id e cordova plugin add plugin-url-or-directory.

Per rendere tutto il processo un po’ più snello ho registrato un task su Grunt, e ve/me lo allego qui per comodità:

uninstallPluginScreenshot: {
    command: 'cordova plugin remove com.darktalker.cordova.screenshot'
},
installPluginScreenshot: {
    command: 'cordova plugin add sources-directory/cordova-screenshot'
    // la registrazione viene fatta a partire dalla directory dei sorgenti
}
// ...
grunt.registerTask('updatePlugin', [
    'shell:uninstallPluginScreenshot',
    'shell:installPluginScreenshot'
]);

Conclusioni

Chiaramente quanto ho scritto non è niente di trascendentale, ma ho notato che c’è molta gente inesperta “la fuori”, e magari qualcuno troverà utili queste poche righe. Sicuramente faranno comodo a me quando me le dimenticherò.

Segnali di pericolo personalizzati con Inkscape

Qualche giorno fa a casa ci siamo trovati di fronte a un dilemma: “Che fare quando i passanti si avventurano nella vigna per prendere un grappolo?”.

Il “furto” di frutta e ortaggi è un problema che esiste da sempre, e finché il maltolto ha quantità irrisorie si è sempre preferito far finta di nulla. Il problema è che quando l’uva comincia ad essere (almeno apparentemente) matura inizia il periodo in cui si danno più trattamenti con prodotti fitosanitari, che hanno generalmente intervalli di carenza di almeno qualche giorno, e questi andrebbero rispettati prima di raccogliere il frutto pena potenziali rischi per la salute.
Forse è assurdo preoccuparsi della salute di ladri e affini, e infatti conosco coltivatori e viticoltori in particolare che non si porgono minimamente il problema e non si farebbero scrupoli a denunciare chi entra nel loro vigneto. È anche vero però che un vigneto vicino alla strada può far gola a molti, e prendere una porzione di un grappolo non è poi la fine del mondo.

pericolo-ladri

Segnali di pericolo, difficili da trovare e costosi

La soluzione – consigliata anche in alcuni libri – è di installare dei segnali di pericolo in punti ben visibili, i quali indicando il rischio per la salute scoraggino anche la raccolta non autorizzata.
Mi sono messo quindi a cercare immagini adatte di segnali di questo tipo sul web con l’intenzione di stamparli e plastificarli (acquistare segnali appositi è “un po’” eccessivo oltre che costoso), ma non sono riuscito a trovare niente con una risoluzione decente. Ho deciso così di fermene uno da me, ma invece del solito Gimp ho preferito darmi alla grafica vettoriale così da iniziare a usare un po’ anche Inkscape.

Inkscape e grafica vettoriale

La grafica vettoriale si distingue dalla più comune grafica raster perché le immagini, invece di essere composte da una griglia di puntini colorati (come nelle foto), sono descritte come una composizione di primitive geometriche (linee, poligoni, …). La caratteristica principale di queste immagini è che non “sgranano” ridimensionandole, sono ottime quindi laddove fanno comodo icone di diverse risoluzioni o quando bisogna stampare su superfici di dimensioni diverse.
Se il Gimp è il re dei software gratuiti di manipolazione di immagini raster, l’omologo per la grafica vettoriale è Inkscape. Entrambi funzionano su Windows, Mac e Linux, ed entrambi possono essere usati anche per elaborazioni molto complesse perché hanno poco da invidiare ai più noti strumenti a pagamento.

Punto di arrivo per me, potrebbe essere punto di partenza per qualcun’altro

Per mettere insieme un segnale di pericolo non serve padroneggiare Inkscape, in quanto dei rettangoli e delle scritte sono più che sufficienti. Si trovano poi immagini svg (il formato standard usato da Inkscape) che possono essere utilizzate per arricchire il segnale, eventualmente previa modifica.
Il formato svg è un xml, ovvero un file di testo, perciò è molto compatto e può anche essere aperto con un comune blocco note e manipolato a mano (ad esempio per modificare una scritta).
Attenzione prodotti fitosanitari
Quindi in sintesi: alcuni rettangoli (con eventuali spigoli arrotondati) riempiti di giallo e rosso, un paio di belle scritte “Pericolo” e “Vigneto trattato con prodotti fitosanitari, vietato l’accesso alle persone non autorizzate”, il tutto stampato e plastificato. Il principio di prudenza è rispettato e magari la prossima vendemmia ci sarà anche qualche kg di uva in più.

L’originale in svg: Attenzione-prodotti-fitosanitari.svg
Un svg con segnale di pericolo: Warning.svg (da Wikimedia Commons)
Un teschio… sono stato tentato ma alla fine ho optato per il punto esclamativo: Skull.svg (da Wikimedia Commons)

Partendo dai tre file sopra si dovrebbe riuscire a comporre i più comuni segnali di allerta e pericolo. Niente di legalmente risolutivo ma magari possono tornare utili a qualcuno per soluzioni caserecce.

Storie di couchsurfing

cs-logo
Negli ultimi anni anche nel nostro paese questo “nuovo” modo di viaggiare sembra finalmente essere stato sdoganato, e se fino a qualche tempo fa di testimonianze italiane in rete se ne trovavano poche ultimamente ce ne sono fin troppe. Ma quello che non strozza ingrassa, quindi due righe sulle mie esperienze ho deciso di scriverle pure io, perché in queste ultime due settimane ho avuto altri ospiti interessanti e perché essendo appena arrivato agosto qualcuno potrebbe decidere di intraprendere questa strada, partendo da solo e magari evitando costosi alberghi.
Mi sono iscritto al sito CouchSurfing.com a gennaio 2012 dopo anni di “carino quel sito, ma viaggiare non mi interessa e non credo lo farei mai da solo”… a tre anni di presenza attiva in questa comunità è giunto il momento di buttare giù due pensieri.

Un po’ di storia non guasta mai

Il concetto di ospitalità più o meno esiste da sempre, ma da quando esistono alberghi, affittacamere, ostelli, B&B, … la gente ha perso l’abitudine di accogliere in casa viandanti sconosciuti.
Con la nascita di internet hanno cominciato a formarsi delle reti di ospitalità, gruppi di persone iscritte a comunità aperte alle quali si può offrire/richiedere una sistemazione temporanea.
La prima di queste reti dovrebbe essere stata Hospitality Club, nata nel 2010 ma da qualche anno in fase calante, seguita poco dopo da CouchSurfing e da altre (BeWelcome, Servas, Amons).
Qualcosa di simile ma non troppo è il WWOOF, una rete che viene usata sempre per farsi ospitare ma a patto di aiutare dei piccoli produttori di prodotti biologici con il lavoro nei campi.

La mia esperienza

Certo un tizio sui trent’anni che vive a casa con la famiglia in un paesino delle Marche non è il massimo per chi cerca ospitalità, quasi sempre ragazzi e ragazze amanti dell’avventura e dell’indipendenza, eppure esattamente tre anni un paio di foto di vigne attirarono l’attenzione di una ragazza californiana, che non si preoccupò troppo della mia totale mancanza di recensioni e mi chiese un divano per qualche giorno.
Stephanie arrivò a casa Piccotti in un caldo pomeriggio di agosto e mi insegnò (tra le altre cose) quanto sono utili i viaggi in solitaria per acquisire spirito di adattamento e di indipendenza e per imparare a uscire dalla propria comfort-zone


… e infatti pochi mesi dopo ero su un aereo in direzione San Francisco, a soli 10000km da casa.

In questi tre anni di esperienza ne ho fatta parecchia, ho conosciuto tanta gente fuori dal comune (almeno fuori dal “nostro comune”), e posso affermare con certezza che quando si vive qualche giorno con persone completamente diverse da noi e ci si trova ad affrontare imprevisti da soli in terra straniera il posto dove si è passa completamente in secondo piano.


Mi è capitato di restare un’ora su un pianerottolo perché il mio anfitrione era andato a dormire prima del previsto, di arrivare all’indirizzo comunicatomi e trovare una porta sbarrata con degli assi di legno, di urlare in strada all’una passata di notte fuori da una finestra per mezz’ora perché mi era stato detto di chiamare al mio ritorno e il telefono non funzionava. In queste ed altre occasioni ho pensato per qualche momento di essermi preso una fregatura, ma tutte le volte ho avuto poi la dimostrazione che i miei padroni di casa erano delle gran belle persone.

A casa di giramondo ne abbiamo ospitati molti e ciascuno di essi ha portato belle storie e belle esperienze. L’ultima in ordine temporale è stata Sonia, la quale ha accettato il mio invito (il mio primo invito andato a buon fine) e ci ha fatto compagnia per quattro giorni. Il risultato è che le nostre colline entreranno forse nel suo lungo documentario “There and back again”, una “cosina” amatoriale che sta pubblicando a puntate durante un viaggetto di un paio d’anni o forse più in giro per il mondo.

Una cosa bella di queste comunità (e del CS in particolare) è che anche quando non si riesce a trovare nessuno che ci ospiti si può comunque sperare di trovare qualche attività aperta a tutti dove si può andare per conoscere gente e per fare quattro chiacchiere. Inoltre ci sono delle bacheche in cui poter lasciare messaggi pubblici visibili in certe aree, e si può vedere l’elenco dei viaggiatori che hanno richiesto ospitalità nelle varie città. Per fare un esempio durante la mia permanenza a Las Vegas volevo passare un giorno nella Death Valley, possibilmente non da solo; ebbene due ragazze olandesi proprio in quei giorni stavano cercando compagnia (ed eventualmente un’auto) per andare alla Death Valley… l’auto l’avevo io e ci siamo andati insieme.

Qualche consiglio non convenzionale

Consigli su cose da fare e da non fare quando si viaggia in questo modo se ne trovano tanti in rete, elenco quindi giusto alcune mie osservazioni.

Puntare ai più esperti può essere controproducente

Gli iscritti più esperti e che ospitano molto (o viaggiano molto) potrebbero dare per scontata la vostra presenza/ospitalità e non dedicarvi molto tempo, avendo quindi a che fare con persone poco esperte si può spesso sperare in esperienze migliori. Di solito però il numero di recensioni di un iscritto è proporzionale al suo livello di esperienza, e meno recensioni significano anche un “rischio” maggiore.
Volendo portare questa cosa all’estremo si può puntare anche sempre ai neo-iscritti, riempendo ogni esperienza di incognite, e aumentando il rischio di ritrovarsi in/a casa di potenziali serial killer.
Da parte mia posso dire che la mia esperienza migliore l’ho avuta in assenza di recensioni, e le meno significative con le persone più abituate a questo meccanismo.

Se non avete mentalità molto aperte cercate persone simili a voi

Forse è un consiglio scontato o forse no. Io mi trovo a mio agio con persone anche molto diverse da me, perché i miei interessi sono molto variegati e mi piace fare più o meno qualunque cosa. Questa cosa però è abbastanza rara, quindi se non volete rischiare di ritrovarvi in mezzo a compagnie sgradite o a fare attività che odiate cercate di leggere bene i profili.

La perfezione sta tra 48 e 72

Io di solito evito il CS quando mi fermo per una sola notte, perché non si fa in tempo a conoscere le persone (in questi casi preferisco gli ostelli). Personalmente punto sempre a ospitare/farmi ospitare due o tre giorni, e questa opinione mi sembra abbastanza diffusa. Periodi più lunghi possono portare ad “affezionarsi” un po’ troppo nel caso di affinità, o ad alti livelli di stress quando le cose vanno male.

Curate il vostro profilo e rendetelo completamente “verde”

A fare un profilo ci vuole un istante e in un paio d’ore potete scrivere ciò che vi riguarda. Già che ci siete dedicategli qualche altro minuto e confermate tutto: telefono, identità (piccolo pagamento con carta di credito), indirizzo, account Facebook. Specialmente agli inizi – quando non si hanno ancora recensioni – spunte verdi su ogni sezione possono essere preziose per partire.
Inoltre cercate di rileggere il profilo di tanto in tanto, per correggere eventuali inesattezze e mantenerlo aggiornato.

Più si è meno funziona

Da soli è un sistema che funziona, una coppia di amiche o di fidanzati può andare, ma altre formule sono destinate a fare un buco nell’acqua al 90%. Non vi offendete quindi se siete due o tre amici e nessuno vi accoglie a braccia aperte.

Usate la vostra email buona per non perdervi niente

Con questo sito non si rischia spam quindi registratevi con l’email buona che avete sempre sotto controllo, così vi arriveranno notifiche di eventuali richieste e la vostra percentuale di risposta non rischia di arrivare sotto terra. Certo anche avere l’app con le notifiche push abilitate può essere una buona idea.

Scrivete delle richieste degne di essere lette

Capita di ricevere delle richieste di ospitalità che fanno venir voglia di rispondere “Col caz.o”. Detto che è importante leggere bene i profili delle persone per capire chi gradiscono in casa e cosa vogliono sentirsi dire, la mia formula ideale è:

  • saluto (possibilmente in lingua natia del ricevente, o “ciao” se il ricevente parla italiano) seguito dal nome del ricevente (c’è chi sbaglia a scrivere il nome…)
  • breve riassunto del perché si è in viaggio, quando e come si arriverà, quando e come si lascerà la casa
  • dimostrazione di lettura del profilo snocciolando due-tre motivi per cui si è deciso di chiedere ospitalità a queste persone, ed eventualmente cosa ci si aspetta
  • eventuali contatti (telefono/email/facebook) se è una richiesta dell’ultimo minuto e si vuole guadagnare tempo
  • saluti (senza ringraziamenti anticipati, che sono di cattivo gusto)

Occhio a chi ha solo recensioni femminili

Non appena si comincia a usare il sito si nota subito che tutto è incentrato sulle donne. La maggior parte di esse preferisce avere a che fare solo con le proprie simili, mentre gran parte degli uomini punta ai membri dell’altro sesso (confidando forse nella legge dei grandi numeri). Il risultato è che se si è donna (magari con una bella foto) si ricevono richieste di ospitalità e inviti come se piovesse, se si è uomo bisogna faticare un po’.
In entrambi i casi diffidate dei profili maschili con sole recensioni femminili, perché è altamente probabile che scartino sistematicamente richieste maschili nella speranza di mantenere il letto/divano pronto per ospiti più graditi.

Evitate di fare caz.ate

Ho sempre creduto fermamente nella filosofia del “Vivi e lascia vivere”, ovvero ciascuno deve essere libero/lasciato libero di fare qualunque esperienza/sciocchezza fintanto che queste non vanno a ledere interessi/sentimenti altrui. Lasciate perdere la comunità del CS se avete intenzioni poco gratificanti, anche perché rischiate di sputtanarvi sia al suo interno che nel mondo reale.

L’evoluzione di CouchSurfing

Mi piacerebbe poter dire di essere stato un pioniere, ma in realtà sono arrivato colpevolmente tardi. Ho comunque vissuto la transizione da associazione no-profit a organizzazione for-profit, l’aumento di interesse negli ultimi anni, l’introduzione di un’app mobile decente, un nuovo sito web.
Tra il 2011 e il 2012 durante il cambio di formula societaria si sono letti molti pareri negativi che lasciavano presagire il peggio, ma finora non si sono verificati eventi castastrofici di alcun tipo. In compenso in quest’ultimo anno il vecchio sito è andato in soffitta sostituito da uno un po’ più moderno e prestante – che viene aggiornato con discreta frequenza – e finalmente è stata lanciata un’app mobile multipiattaforma ben fatta. Sull’altro lato della bilancia bisogna mettere alcuni “suggerimenti” per la ricerca di voli o link per l’iscrizione ad altri servizi, niente di troppo invasivo comunque.
Ben venga la monetizzazione da parte dei proprietari se come risultato gli utenti hanno un miglioramento del servizio.

I rischi: purtroppo quelli veri sono (quasi) tutti per l’altra metà del cielo

Ai bambini si dice di non accettare caramelle dagli sconosciuti, e qui tutto è incentrato sugli sconosciuti… purtroppo so per testimonianze dirette che a volte si può incappare in dei veri pezzi di merda, e questo accade per lo più alle donne, specialmente se in viaggio da sole.
Vero che ci sono le referenze, vero che ci sono la verifica dell’identità, dell’indirizzo, del numero di telefono, del profilo Facebook, ma per criminali senza scrupoli questi sono soltanto dei piccoli ostacoli facilmente aggirabili con un po’ di fantasia (e di ingenuità altrui).

Recensioni negative, come gli unicorni

Ho visto ragazze che – tentando di mettere in guardia le proprie simili – hanno lasciato recensioni negative e si sono viste recapitare recensioni ambigue che cercavano di farle passare per delle sgualdrine, tanto da spingerle a cancellarle o peggio all’eliminare il profilo. Ho sentito direttamente di ragazze che si sono sentite spinte un po’ troppo in una certa direzione e hanno preferito andarsene. La cosa grave è che non sempre coloro che si trovano in queste situazioni denunciano l’accaduto o lasciano recensioni negative, con il risultato che queste merde umane possono riprovarci impunemente.

La cronaca

Quando ci va di mezzo la cronaca il motivo è quasi sempre lo stesso: uno stupro.
In più di dieci anni e chissà quanti milioni di esperienze di ospitalità questi casi si contano sulle dita di una mano, ma purtroppo non sempre finiscono in cronaca ed è risaputo che tentativi di questo tipo accadono più spesso di quanto dicano i giornali.
In Italia il caso più vergognoso è quello del carabiniere Dino Maglio, stupratore seriale che ha fatto molte vittime nell’arco di un anno. Se siete donne dovreste studiare questa storia nei dettagli.

Esperienze da fare e rifare, ma con prudenza

Il CouchSurfing è uno spaccato della società, nel bene e nel male, ma mentre nella società ci si sta qualche ora e poi si ritorna “al sicuro” tra le proprie mura, qui le mura nelle quali si torna sono quelle di sconosciuti, e tra queste mura ci si addormenta… e spesso non si può fare nemmeno affidamento su porte chiuse a chiave perché si dorme quasi sempre in aree comuni.

Tutto è basato sulla fiducia, riponetela nelle persone giuste (la stragrande maggioranza degli iscritti) e vivrete delle gran belle esperienze.
Se non siete convinte/i fuggite a gambe levate, e pazienza se vi siete sbagliate/i.

Typescript non mi piaceva (prima di metterci le mani)

Qualche settimana fa ho avuto modo di partecipare a un techbar organizzato da DevMarche e tenuto da Andrea Balducci su TypeScript (le slides), il “nuovo” linguaggio simil-javascript targato Microsoft e usato in AngularJS 2 da Google. Lo stesso Andrea ha ripreso il dicorso la settimana scorsa al MobileCamp, approfondendo alcuni concetti (le slides).
In realtà TypeScript non è nuovo per niente ma – sebbene abbia visto la luce a fine 2012 – soltanto con l’annuncio dell’adozione nella versione 2 di AngularJS ha ridestato l’interesse della comunità ed è salito agli onori della cronaca.

La (finta) concorrenza: CoffeeScript e Dart

Forse perché il Javascript è nato in pochi giorni e con un obiettivo totalmente diverso da quelli odierni, fatto sta che i più odiano alcune sue caratteristiche, e nel corso del tempo si è cercato di nasconderlo dietro qualche altro linguaggio così da mascherarne difetti e brutture.

La prima di queste “maschere” è stata CoffeeScript, un linguaggio “ponte” compilabile in Javascript che prese spunto prevalentemente da Ruby, Haskell e Python. Scopo primo: rendere il codice più compatto e leggibile.

Evidentemente questo “nuovo linguaggio” non deve aver fatto breccia a Mountain View, perché poco dopo è uscito Dart. Lo scopo di Google era abbastanza più sensibile: mandare in soffitta il Javascript come linguaggio del web.

L’esigenza manifestata da Google di “rompere con il passato” non deve però aver convinto quelli di Microsoft, che poco dopo hanno fatto la loro mossa sviluppando TypeScript.
A questo punto Google pensava di sviluppare un ulteriore superset di TypeScript chiamato AtScript – che aggiungeva principalmente le annotations al linguaggio di Microsoft. Fortunatamente Google ha deciso di abbandonare il progetto collaborando con Microsoft allo sviluppo di TypeScript.

Cos’è TypeScript

TypeScript è un “Superset tipizzato di Javascript che compila in Javascript”, ovvero è un Javascript ampliato con alcuni costrutti (il cui uso è facoltativo), che può essere compilato in Javascript da un compilatore anche questo scritto in TypeScript.
La novità è che il compilato è né più né meno che un bel Javascript, tendenzialmente identico a come l’avremmo scritto noi, e questo succede perché molte delle nuove “funzionalità” non vanno a generare un bel niente, ma servono soltanto al compilatore per una verifica statica del codice.
Naturalmente essendo il prodotto del compilatore del “codice Javascript”, tra i parametri di configurazione del compilatore si può specificare anche la versione di “Javascript” (o più propriamente EcmaScript), e i costrutti utilizzati vengono tradotti oppure no a seconda della versione di EcmaScript scelta.

Qualche nota sul compilatore

Installazione

Typescript è una libreria presente su npm che installa il compilatore TypeScript da usare globalmente, installiamolo quindi con:
npm install -g typescript

Esecuzione

Il compilatore si richiama con il comando:
tsc nomefile.ts
Il risultato è la creazione nella stessa directory del file .ts di un file Javascript con lo stesso nome ma con estensione js. Aggiungendo il parametro -w (o --watch) viene creato uno watcher sul file che lo ricompila a ogni modifica.
Per visualizzare una guida del compilatore eseguire il comando tsc -h (o tsc --help).

Configurazione

Di recente è stato introdotto il file di configurazione tsconfig.json, la cui presenza marca la directory come un progetto TypeScript. Se il file è vuoto vengono usate le configurazioni di default e la compilazione viene eseguita su tutti i file ts trovati (basta lanciare il tsc da solo, o eventualmente mettendolo in “watch”).
Nel repository GitHub di TypeScript è presente una guida esaustiva, elenco qui giusto alcune configurazioni principali:

  • “files”: è un array opzionale contenente i file che devono essere considerati dal compilatore, in sua assenza vengono compilati tutti i file ts presenti nella directory e nelle subdirectories.
  • “target” (“compilerOptions”): specifica la versione di EcmaScript di destinazione (“es3”, “es5” o “es6”)
  • “sourceMap” (“compilerOptions”): specifica se devono essere generati i source map per poter eseguire il debug direttamente dello script TypeScript
  • “module” (“compilerOptions”): specifica il formato dei moduli, il default è “commonjs”, il formato usato in NodeJS

Il “superset” di istruzioni

Sono pigro, e credo fermamente che re-inventare sempre la ruota non serve. Prendo quindi gli esempi del workshop di cui sopra cercando di analizzarli per quanto mi è possibile.

Any? Un po’ troppo generico

function sortByName(a){
	var result = a.slice(0);
	result.sort(function(x,y){
		return x.name.localCompare(y.name);
	})
}
sortByName(5);

In questo esempio vediamo una semplice funzione di ordinamento, e la sua invocazione (sbagliata). Dichiarando qualche tipo i bug saltano fuori in un attimo, specialmente utilizzando une editor come Visual Studio Code, che sembra tagliato su misura per sviluppare in TypeScript…

function sortByName(a:any[]){
    var result = a.slice(0);
    result.sort(function(x,y){
        return x.name.localeCompare(y.name);
    })
}
sortByName([{'name' : '5'}]);
function sortByName(a:{'name':string}[]){
    var result = a.slice(0);
    result.sort(function(x,y){
        return x.name.localeCompare(y.name);
    })
}
sortByName([{'name' : '5'}]);
interface Named {
	'name' : string
}
function sortByName(a:Named[]):Named[]{
	var result = a.slice(0);
	result.sort(function(x,y){
		return x.name.localeCompare(y.name);
	});
	return result;
}
var data = [{'name' : '5'}];
var sorted = sortByName(data);
console.log(sorted);
function sortByName(a) {
    var result = a.slice(0);
    result.sort(function (x, y) {
        return x.name.localeCompare(y.name);
    });
    return result;
}
var data = [{ 'name': '5' }];
var sorted = sortByName(data);
console.log(sorted);

Come si può vedere da questo semplice esempio il compilatore usa buona parte di quello che scriviamo per fare controllo statico del codice, e il risultato non è minimamente alterato dalla definizione di qualche contratto sui tipi.

Classi e interfacce per farci sentire a casa

In quest’esempio vediamo una semplice classe con una proprietà privata (level), due proprietà pubbliche (name e bio) e un metodo pubblico (train). Il dichiarare come pubblici i parametri del costruttore li identifica automaticamente come proprietà pubbliche della classe.

export interface Named {
	name: string;
}
export class Jedi implements Named {
	private level:number = 0;
	
	constructor(public name: string, public bio: string) {
		this.level = 15;
	}
	
	train(levelUp : number){
		this.level += levelUp;
		return this.level;
	}
}
var Jedi = (function () {
    function Jedi(name, bio) {
        this.name = name;
        this.bio = bio;
        this.level = 0;
        this.level = 15;
    }
    Jedi.prototype.train = function (levelUp) {
        this.level += levelUp;
        return this.level;
    };
    return Jedi;
})();
exports.Jedi = Jedi;

Come si può vedere il risultato non aggiunge niente al javascript, trattasi sempre di una funzione Jedi che nel prototype ha la funzione dichiarata come metodo pubblico.
Naturalmente così come si può implementare un’interfaccia con implements si può anche estendere un’altra classe con extends.
L’uguaglianza tra tipi si basa su un confronto delle interfacce tra i vari oggetti (interfacce intese come proprietà e metodi esposti), quindi su questo fronte potrebbero esserci dei fraintendimenti se si è abituati a lavorare con linguaggi tipizzati come Java e C#.

I Generics per svincolarci dai tipi

Il TypeScript è nato principalmente per rendere più facile la vita degli sviluppatori Java/C#/simili nel mondo Javascript, e in quei linguaggi per aumentare la riusabilità del codice esistono i generics, giocoforza dovevano gestirli anche qui.
Una guida esaustiva ai generics in TypeScript la potete trovare qui, mi limito a riportare un esempio preso dalla guida perché l’argomento è lungo e complesso.

interface Lengthwise {
    length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);
    return arg;
}
loggingIdentity({length: 10, value: 3});
loggingIdentity([3]);
loggingIdentity(3);  // Errore di compilazione

Decorators per una facile estendibilità

Tra tutte forse la novità che ha colpito maggiormente l’interesse degli sviluppatori è quella dei decorators. Il pattern Decorator è uno dei più utilizzati e permette di “aumentare” le funzionalità di un oggetto a runtime “avvolgendolo”, ovvero funzionando da wrapper.
I decorators TypeScript sono delle annotations applicabili – eventualmente in sequenza – a delle dichiarazioni di classi, funzioni, proprietà (di classe) e argomenti (di funzione) per estenderne il comportamento.
Una serie di articoli molto completa e interessante che spiega come funzionano i Decorators in TypeScript potete trovarla qui. Per arrivare in fondo a quest’articolo prima dell’inverno anche qui eviterò di dilungarmi, riportando giusto il classico esempio usato da tutti: il log di una chiamata di funzione.

export function log(target: Function, key: string, descriptor: any) {
	var original = descriptor.value;
	descriptor.value = function(...args: any[]) {
		var a = args.map(a => JSON.stringify(a)).join();
		var result = original.apply(this, args);
		var r = JSON.stringify(result);
		console.log(`call: ${key}(${a}) => ${r}`);
		return result;
	}

	return descriptor;
}
import {log} from "./decorators"

export class Jedi {
	private level:number = 0;
	constructor(public name: string, public bio: string) {
		this.level = 15;
	}
	
	@log
	train(levelUp : number){
		this.level += levelUp;
		return this.level;
	}
}
if (typeof __decorate !== "function") __decorate = function (decorators, target, key, desc) {
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") return Reflect.decorate(decorators, target, key, desc);
    switch (arguments.length) {
        case 2: return decorators.reduceRight(function(o, d) { return (d && d(o)) || o; }, target);
        case 3: return decorators.reduceRight(function(o, d) { return (d && d(target, key)), void 0; }, void 0);
        case 4: return decorators.reduceRight(function(o, d) { return (d && d(target, key, o)) || o; }, desc);
    }
};
var decorators_1 = require("./decorators");
var Jedi = (function () {
    function Jedi(name, bio) {
        this.name = name;
        this.bio = bio;
        this.level = 0;
        this.level = 15;
    }
    Jedi.prototype.train = function (levelUp) {
        this.level += levelUp;
        return this.level;
    };
    Object.defineProperty(Jedi.prototype, "train",
        __decorate([
            decorators_1.log
        ], Jedi.prototype, "train", Object.getOwnPropertyDescriptor(Jedi.prototype, "train")));
    return Jedi;
})();
exports.Jedi = Jedi;

Facciamola breve: la funzione __decorate prende il prototype della classe contenente la funzione che vogliamo decorare e “avvolge” la funzione scelta con le funzioni “decoratrici” passate nell’array, in sequenza. Basta annotare cioè due volte la stessa funzione con lo stesso decorator @log per ritrovarci con il decorators_1.log due volte nell’array, e per vedere due volte il log dell’invocazione della funzione.
L’Object.defineProperty sovrascrive la funzione originaria con quella decorata ritornata dal __decorate.
La prima parte può spaventare un po’, ma in realtà sta soltanto definendo la funzione __decorate in modo da farle usare il Reflect.decorate se disponibile o farle implementare la logica di decorazione in caso contrario.

Modules, per “modularizzare” meglio il codice

Sistemi per rendere più modulare il nostro codice Javascript c’erano anche senza scomodare TypeScript, ma i moduli sono comunque un’opportunità da non ignorare.

module Validation {
    export interface StringValidator {
        isAcceptable(s: string): boolean;
    }
}

module Validation {
    var lettersRegexp = /^[A-Za-z]+$/;
    export class LettersOnlyValidator implements StringValidator {
        isAcceptable(s: string) {
            return lettersRegexp.test(s);
        }
    }
}

In sostanza un modulo serve ad aggregare funzioni affini in contenitori appropriati per evitare collisioni di nomi e altri errori. Lo stesso modulo può essere “riempito” anche da file diversi, così ad esempio se abbiamo tutta una serie di funzioni di validazione e non vogliamo creare file enormi possiamo spezzettare il modulo in più file.
Anche in questo caso ho tutt’altro che approfondito, si può trovare una guida esaustiva qui.

Utility varie, anche un po’ di zucchero non guasta

Let

test1 = "a"; // errore, la variabile non è stata ancora dichiarata
let test1;
if (true){
	let test2;
	test2="a";
}
test2="b"; // errore, la variabile è stata dichiarata internamente al blocco if

Il compilato Javascript di questo blocco è identico ma usa i var al posto dei let (se non stiamo compilando il EcmaScript 6 o superiori). Questo significa che il javascript funzionerebbe comunque effettuando l’hoisting delle variabili.

For of

for (var c of characters) {
	console.log(c);
}
// il compilato di questo ciclo è il seguente:
for (var _i = 0; _i < characters.length; _i++) {
    var c = characters[_i];
    console.log(c);
}

Questa cosa è di una banalità estrema e non snellisce nemmeno di tanto il codice, ma confesso che a me almeno una volta è successo di aver dimenticato che usando ‘in’ la variabile viene valorizzata con l’indice e non con il valore…

Operatore freccia

class Test {
	private acc = "";
	conc = (arg:string)=>{
		this.acc = arg + " " + this.acc;
		return this.acc;
	}
}
// il compilato è:
var Test = (function () {
    function Test() {
        var _this = this;
        this.acc = "";
        this.conc = function (arg) {
            _this.acc = arg + " " + _this.acc;
            return _this.acc;
        };
    }
    return Test;
})();

Quest’ultimo esempio rende l’idea di come alcuni trabocchetti possano essere schivati usando certi costrutti, che aiutano anche a rendere più leggibile il codice e non riducono minimamente la retrocompatibilità del nostro codice.

Definizione di tipi per librerie esistenti?

Chi più chi meno tutti usiamo delle librerie/plugin e certo per utilizzare con profitto un linguaggio che si chiama “TypeScript” sarebbe bellissimo avere a disposizione le definizione dei tipi utilizzati in queste librerie.
Poco meno di tre anni fa tale Boris Yankov ebbe la bella idea di crearsi un repository su GitHub chiamato DefinitelyTyped e inizio a buttarci dentro le definizioni di alcune librerie Javascript.
Ebbene questo progetto ha da poco superato i 10000 commits e i 1000 contributori, e dentro ci si può trovare di tutto…

Conclusioni

Vero che per il teorema di Bohm-Jacopini qualunque algoritmo può essere scritto usando soltanto iterazione, struttura condizionale e sequenza, ma certo se si vuole realizzare grossi sistemi qualche costrutto un po’ più avanzato ce lo vuole.
Almeno se chi sviluppa ha una buona conoscenza informatica il sistema guadagna molto in eleganza e manutenibilità strutturandolo a dovere, e TypeScript da questo punto di vista può aiutare moltissimo laddove il Javascript (almeno inteso come Ecmascript 5 e inferiori) ha delle grosse lacune.

Per la maggior parte i costrutti aggiunti comportano solo lavoro per il compilatore e lasciano inalterato il codice risultante, in altri casi vengono tradotti esattamente come li tradurremmo noi se conoscessimo il linguaggio alla perfezione, cosa spesso non vera.

Benefici apportati dall’utilizzo di questo compilatore:

  • l’architetto che può sfruttare costrutti avanzati per evitare di insozzare il codice
  • chi sviluppa può farlo senza timori di pestare una mina a ogni riga perché il compilatore segnala gran parte degli errori di codifica senza dover eseguire il codice, rendendo più facile il refactoring (anche grazie a strumenti più avanzati) e limitando i bug da disattenzione
  • l’interprete si trova a dover eseguire un codice migliore e ottimizzato, e può quindi raggiungere prestazioni migliori

Aspetti negativi di questo strumento:

  • si deve aggiungere uno “strato” di codice, e questo potrebbe portare a qualche problemino con sdk particolari
  • non mi viene in mente nient’altro

Ma a parte tutto secondo me il maggior merito di TypeScript (e della Microsoft) è un altro. Da più fronti si stava cercando di attaccare il Javascript per sostituirlo – sul web in particolare – senza dargli il tempo di crescere nelle varie versioni di EcmaScript. TypeScript sta riuscendo a spingere nella standardizzazione dei costrutti velocizzando i rilasci delle versioni EcmaScript ma dando l’opportunità a chi non può evolvere verso le nuove versioni di sfruttare già oggi tutti quei costrutti, e mantenendo una non trascurabile retrocompatibilità. Per me può bastare.

Cookie, privacy, blog e paranoie varie

Da qualche ora è cosa nota a tutti che il 2 giugno scadrà il termine per mettersi in regola con un provvedimento del Garante per la protezione dei dati personali relativo all’utilizzo di cookie su applicazioni web. Questo provvedimento è stato preso nel lontano 8 maggio 2014, ma è passato quasi completamente inosservato per un anno finché qualcuno ha iniziato a far notare come la stragrande maggioranza dei siti web in circolazione – o per meglio dire la totalità – sono ancora fuorilegge.

Cookie di profilazione vs Cookie tecnici

I cookie sono stati introdotti più di vent’anni fa per far sì che fosse possibile riconoscere i navigatori che tornavano su un determinato sito, e nel tempo si sono sfruttati per mille scopi.
Il Garante ha diviso sommariamente questi file di testo in due categorie: i cookie tecnici, necessari per il funzionamento dei siti e per implementare funzionalità utili all’utente che lo visita, e i cookie di profilazione, utilizzati solo a scopi pubblicitari e di controllo dell’utente.
Tra i due gli unici che interessano la nuova normativa sono quelli di profilazione, usati e abusati da molti siti web per bombardare gli utenti con pubblicità mirate e per costruire precisi profili utilizzando i dati personali e le preferenze espresse durante la navigazione sul web.

Che fare se si ha un sito web

Inutile girarci intorno: che gestiate un blog, un sito di ecommerce o qualunque altra cosa pubblicata sul web al 99.99% non siete in regola.
Sintetizzando all’estremo la normativa richiede che chi ha un sito in cui da qualche parte vengono generati dei cookie di profilazione (anche da terze parti), prima che questi inizino ad essere efficaci l’utente deve esserne informato e deve fornire un consenso (per l’appunto preventivo). Questa cosa dovrebbe essere fatta con un banner ben visibile nella pagina in cui l’utente possa leggere quali sono i “rischi” a cui va incontro continuando nella navigazione, e al suo interno vi dovrebbe essere un pulsante per confermare il consenso…

Qualcuno ha capito che il blocco della navigazione previo consenso va fatto solo se i cookie li generiamo noi, e che per quelli di terze parti basta rendere visibile il banner in cui si informa l’utente. Altri arrivano a consigliare il blocco di tutto per cautelarsi, perché la normativa è fraintendibile. Nel dubbio leggetevi la normativa, interpretatela e agite come meglio credete.
Non è del tutto chiaro nemmeno se la normativa valga solo per i cookie o anche per altre forme di memorizzazione similari (local storage, varie ed eventuali).

Ora, chi ha navigato un po’ sul web nelle ultime settimane avrà notato un proliferare di messaggi – nelle forme più disparate – in cui i siti informano gli utenti sull’utilizzo dei cookie. Il problema è che quasi nessuno di questi banner blocca l’utente se questo non esprime il suo consenso, e se questo non succede c’è il “rischio” che l’utente continui nella navigazione senza sapere che sta andando incontro a morte certa. Possibile che nessuno di questi generi dei cookie di profilazione ma utilizzi solo quelli di terze parti? E il principio di prudenza?

Il banner di Twitter

Il banner di Twitter


Il "messaggino" di Amazon

Il “messaggino” di Amazon


Un banner apparentemente fatto bene

Un banner apparentemente fatto bene

Estratti di normativa

Se volete passare qualche bel quarto d’ora qui c’è tutta la normativa.

«Si ritiene pertanto che, anche in ragione delle motivazioni sopra indicate, non si possa obbligare l’editore ad inserire sull’home page del proprio sito anche il testo delle informative relative ai cookie installati per il suo tramite dalle terze parti.»
=> semplice: non serve fare copia incolla delle informative sulla privacy delle terze parti

«Nel momento in cui l’utente accede a un sito web, deve essergli presentata una prima informativa “breve”, contenuta in un banner a comparsa immediata sulla home page (o altra pagina tramite la quale l’utente può accedere al sito), integrata da un’informativa “estesa”, alla quale si accede attraverso un link cliccabile dall’utente.»
=> semplice anche questo: il banner deve essere sintetico ma da lì deve essere possibile visualizzare un’informativa più dettagliata (un po’ come il banner di Twitter)

«Affinché la semplificazione sia effettiva, si ritiene necessario che la richiesta di consenso all’uso dei cookie sia inserita proprio nel banner contenente l’informativa breve.»
=> bene, sul banner si vuole un pulsante per esprimere il consenso

«…l’archiviazione delle informazioni nell’apparecchio terminale di un contraente o di un utente o l’accesso a informazioni già archiviate sono consentiti unicamente a condizione che il contraente o l’utente abbia espresso il proprio consenso dopo essere stato informato..»
=> in tutta la normativa si parla di cookie, ma qui solo di un generico “archiviare”… per me il tutto vale per ogni meccanismo di memorizzazione sul client, anche futuro

«Il suindicato banner, oltre a dover presentare dimensioni sufficienti a ospitare l’informativa, seppur breve, deve essere parte integrante dell’azione positiva nella quale si sostanzia la manifestazione del consenso dell’utente. In altre parole, esso deve determinare una discontinuità, seppur minima, dell’esperienza di navigazione: il superamento della presenza del banner al video deve essere possibile solo mediante un intervento attivo dell’utente (appunto attraverso la selezione di un elemento contenuto nella pagina sottostante il banner stesso).»
=> secondo me il significato di questo paragrafo non è in grado di capirlo nemmeno chi l’ha scritto, si presta a ogni genere di interpretazione e sembra fatto a posta per farci mangiare sopra gli avvocati. Qui lo dico e qui lo nego.

Caso specifico: blog personale senza grandi pretese

Quello che ho capito io è che se volete stare tranquilli almeno nella fase iniziale è meglio andarci con i piedi di piombo, togliendo dal proprio blog tutto quello che potrebbe non essere a norma e magari aggiungere anche una paginetta di Informativa sulla privacy. Se non volete aggiungere anche il banner in modo da richiedere il consenso preventivo all’utente dovete cercare di eliminare ogni potenziale rischio che qualcosa crei attraverso il vostro sito dei cookie di profilazione (o che ne utilizzi di creati in precedenza). E poi magari aggiungete anche il banner attraverso un plugin, ché ce ne sono tanti.

I cosiddetti “pulsanti social”

Toglieteli, non servono a niente a parte appesantire il caricamento delle pagine, occupare spazio e rendere più antipatica la stampa degli articoli. Certo che se avete un blog molto seguito vedere i numeretti delle condivisioni fa festa, ma sono comunque numeri abbastanza fasulli. Però davano un tocco di colore…

Il plugin di wordpress che avevo usato io per dare un tocco di colore. Peccato.

Il plugin di wordpress che avevo usato io per dare un tocco di colore. Peccato.

Google Analytics

Profilazione per antonomasia. Qualcuno dice che questi non contino, ma in realtà se avete gli analytics di BigG sul vostro sito viene creato almeno un cookie _ga, quindi contano eccome.
Se volete leggervelo qui si parla di come funzionano i cookie di Google Analytics.
I Google analytics si possono configurare per anonimizzare l’ip degli utenti, utilizzando l’apposito parametro _anonymizeIp da inserire all’interno dello snippet di codice che deve essere aggiunto alle pagine da analizzare. Io nel dubbio ho tolto tutto, fra qualche settimana se ne riparlerà.

Twitter

Anche i badge di Twitter naturalmente tengono traccia del comportamento dell’utente, se quindi avete aggiunto uno widget/plugin in cui visualizzate i vostri tweet, sembra proprio che questo possa generare dei cookie di profilazione. Però se andate nella pagina delle impostazioni di Twitter, dove potete generarvi il badge (da includere poi come widget html sul blog), c’è una spunta che forse fa al caso nostro: “Disattiva la personalizzazione”.

La checkbox "Disattiva la personalizzazione" dovrebbe servire per rientrare nella normativa. Forse.

La checkbox “Disattiva la personalizzazione” dovrebbe servire per rientrare nella normativa. Forse.

Controllare i cookie generati dal vostro sito

Qui si va un po’ sul tecnico, ma niente di trascendentale. Dopo aver fatto un po’ di pulizia – almeno per togliere lo sporco che puzza – è giunto il momento di guardare nel dettaglio i cookie collegati al nostro sito.
Se avete il browser Chrome – e per il vostro bene dovreste già averlo installato – fate click con il tasto destro del mouse in un punto della pagina e nel menù contestuale che si apre scegliete la voce “Ispeziona elemento”. Nella finestra che si apre andate nella scheda “Resources”, da qui nella voce cookies, e poi sull’url del vostro sito. A questo punto vi conviene fare pulizia per evitare di leggere cookie salvati chissà quando: è sufficiente cliccare con il tasto destro sull’url del sito (sotto cookies) e poi premere “clear”.
Fate un giretto nel vostro sito visualizzando tutti i vari widget e plugin che potreste avere ancora installati e controllate che i cookies non proliferino.
Qui potete controllare a cosa servono i cookie generati da Google.
cookie-chrome

Nel mio sito rimangono solo un cookie di Google e due di Twitter, temo possano essere cookie di profilazione ma credo fortemente che nessuno morirà per questo.

Non potete considerarvi veri uomini se non vi piace il vi(m)

A chi fa questo mestiere prima o poi capita di doversi collegare con un server su cui non si ha a disposizione un’interfaccia grafica (o semplicemente non la si può usare), magari per correggere al volo un bug grave su un sito pubblicato, e non sempre si può usare WinSCP o copiarsi i file via ssh utilizzando FileZilla e poi ricopiarli sul server, anche perché si rischia di incasinare i permessi dei file e di creare problemi ben più gravi.

Nei sistemi Unix-like – oggigiorno Linux e OSX se non si è dei sistemisti esperti o non si lavora in ambienti strani – a volte è disponibile nano, che tutto sommato è “abbastanza user-friendly” ma potrebbe non essere stato installato e potremmo non avere i permessi per poterlo installare.

GNU nano editor, troppo lusso in alcuni casi

GNU nano editor, troppo lusso in alcuni casi

Un’alternativa che c’è sempre o quasi è il VI(M), un po’ ostile e apparentemente scarsissimo di funzionalità, ma adorato da molti guru e forse a ragione.
Quasi sempre è già installato VIM (VI iMproved), ed eseguendo il comando vi nomefile viene aperto proprio il vim, ma i due si somigliano e la maggior parte dei comandi sono uguali.
Nei giorni scorsi in azienda hanno proposto agli interessati un corso interno per migliorare le nostre competenze in ambiente Linux, e uno degli argomenti era proprio vim, quindi mi segno qui i comandi che mi sono sembrati più utili.

Breve prontuario per novizi

Di comandi ce ne sono una marea, e se siete uno sviluppatore che intende usarlo nel lavoro di tutti i giorni forse vi conviene studiarveli per sfruttare appieno la sua potenza. Per le persone normali invece dovrebbe bastare questo piccolo vademecum, anche perché la stessa cosa si può fare combinando vari comandi, quindi non serve saperli tutti (al massimo si va più lenti).

Parametri di avvio

-v : modalità vi (senza funzionalità aggiuntive di vim)
-d : modalità differenze (vi -d file1 file2)
-M : modalità sola lettura, se avete paura (a ragione) di fare danni

Se si è presi dal panico

ESC : esce dalla modalità attuale (molto utile premerlo a ripetizione se si è in stato di panico)
:q! : esce senza salvare (altra sequenza molto importante se non si sa bene cosa si è fatto)
u : undo (annulla)
ctrl+r : redo (ri-esegue eventuali modifiche annullate)

Modalità

ESC : esce dalla modalità attuale
i : modalità inserimento
o : aggiunge una riga dopo quella attuale e vi entra in modalità inserimento
r : in inserimento, ma con sostituzione del carattere su cui si è

Movimento

h j k l: sinistra, giù, su, destra (comodo se si vuole fare tutto con una mano, ma di solito anche le frecce funzionano)
0 : inizio della riga corrente
$ : fine della riga corrente (non a caso il dollaro viene usato per rappresentare i fine linea)
:num_riga : si sposta sulla riga specificata
G : si sposta sull’ultima riga

Funzioni di uscita e salvataggio

:q : esce
:wq : esce salvando
:q! : esce senza salvare
:w : salva

Funzioni di copia-taglia-incolla

y : copia la riga corrente
d d (doppia d veloce) : taglia la riga corrente
num_righe d d : taglia il numero di righe specificate numero di righe seguite da doppio “d”
p : incolla

Ricerca e sostituzione

/string : ricerca la stringa “string” (con il tasto n ci si può spostare sui successivi, con N sui precedenti)
:%s/string1/string2/g : sostituisce “string1” con “string2”

Comandi informativi

:set list : visualizza tabulazioni e caratteri di fine linea (:set nolist per annullare la visualizzazione)
:f : visualizza nome del file e posizione all’interno del file (numero di riga, di colonna e percentuale)

Conclusioni

Essendo vim un editor tutto basato su comandi da tastiera richiede una buona memoria e molta pratica per essere utilizzato con un’adeguata velocità, ma fortunatamente insieme al vim c’è sempre installato anche vimtutor, una “guida testuale interattiva” fatta per esercitarsi con i comandi più utili di vim.

vim tutor

vim tutor

Sarà brutto, sarà ostile, ma sviluppatori e sistemisti non possono non conoscere un po’ un editor sempre disponibile e tutto sommato potente come vi(m), quindi è imperativo imparare almeno una decina dei comandi più utili e provare a usarli quando se ne ha l’occasione… se non altro nella selva di editor e ide che nascono e muoiono alla velocità della luce questo sta in piedi da quasi quarant’anni e non sente nemmeno il peso della vecchiaia.

Appcelerator Titanium, licenza indie e sviluppo enterprise

È passato poco più di un mese da quando Jeff Haynie ha annunciato in pompa magna le grandi novità in casa Appcelerator.
Una di queste – la “monetizzazione” dell’sdk Titanium da parte dell’azienda – non è stata accolta con grande entusiasmo, e qualche giorno dopo andando a leggere sul loro sito il dettaglio delle licenze mi sono allarmato leggendo queste parole: “You may choose to purchase multiple Indie plans, but the users of these seats cannot see or share work with one another”.

Dicitura alquanto preoccupante che spiega le limitazioni della licenza Indie

Dicitura alquanto preoccupante che spiega le limitazioni della licenza Indie


Quel “share work” mi ha fatto preoccupare un po’, perché è vero che come utilizzatore precedente ho diritto a una licenza indie gratuita e permanente, ma è altrettanto vero che lavoro in un’azienda insieme ad altra gente, e lì per lì ci ho visto nero. Un mio tweet al veleno ha attirato l’attenzione di Ricardo Alcocer (Director of Developer Relations and Training), il quale preoccupato si è affrettato a chiarire i miei dubbi spiegandomi che “the Indie account will not allow you to share app’s backend data with other Indie developers”. In pratica a detta sua l’unico limite sarebbe stato nella condivisione di backend e analytics tra utenti non registrati come parte di un’unica organizzazione.

Il test con il doppio account

L’altro giorno finalmente mi è arrivato l’invito per utilizzare in anteprima la versione 4.0 (ancora alla RC2) con l’account registrato a nome dell’azienda, e dal momento che avevo già un invito sul mio account personale sono riuscito a fare i test di lavoro con più account sullo stesso progetto. Ho quindi importato uno dei progetti sviluppati in azienda con l’account aziendale, ho fatto qualche test e poi sono uscito da Appcelerator Studio eseguendo il login seguente con il mio account personale, per vedere cosa sarebbe successo.

…e quando invece si esegue il login con un account diverso da quello con cui si è registrata l’app

…e quando invece si esegue il login con un account diverso da quello con cui si è registrata l’app

…e quando invece si esegue il login con un account diverso da quello con cui si è registrata l’app

…e quando invece si esegue il login con un account diverso da quello con cui si è registrata l’app


Aprendo il tiapp.xml si nota il messaggio di warning in cui si spiega che l’applicazione è associate a un’organizzazione di cui non si fa parte e in cui si consiglia di farsi aggiungere in tale organizzazione… facendo pagare a quell’organizzazione delle (costose) licenze Team o Enterprise.

In Appcelerator controllano e registrano tutto

Il problema vero non è tanto il non aver accesso ai servizi web di Appcelerator, quanto che lanciando l’applicazione l’sdk fallisce il processo di build: Application not registered. In pratica a ogni creazione di una nuova applicazione (o importazione di un’applicazione esistente) viene generato un guid univoco che viene associato all’appid, e sulla console web dell’utente (o meglio dell’azienda correntemente selezionata dallo sviluppatore) compare una coppia di applicazioni: quella mobile (Titanium) e l’Arrow DB.
Se si prova ad avviare l’applicazione e sui server Appcelerator all’organizzazione di cui fa parte lo sviluppatore non è associata un’applicazione con quel guid, il processo di build fallisce.

"Application not registered"

“Application not registered”


Il punto è che a ciascuna licenza Indie sono associate due entità: lo sviluppatore e l’organizzazione di cui questo fa parte. La creazione/importazione di un’app da parte di uno sviluppatore fa sì che all’organizzazione correntemente selezionata venga associata questa nuova applicazione, identificata da un guid univoco. Ciascuno sviluppatore può far parte di più organizzazioni, ma un’organizzazione Indie non può aver al suo interno più di uno sviluppatore.
Fregati?

Come fare se in azienda si hanno più licenze Indie e non si vuole pagare

Detto che Titanium è ancora su GitHub e lo si può compilare come spiegato sulla documentazione, ma anche che su questo repository non ci saranno più informazioni relative a tags e release varie, è chiaro che da San Francisco per rimpinguare le casse non puntano tanto agli sviluppatori indipendenti sprovvisti di un account (che probabilmente punteranno ad altre tecnologie più economiche), quanto a quella galassia di piccole software house che hanno scelto per le loro applicazioni quella che era la più promettente tecnologia gratuita in grado di non far sentire troppo la mancanza del nativo. E che potrebbero farsi ingolosire anche dai migliori servizi cloud e assistenza delle versioni Team e Enterprise rispetto alla Indie.

Il controllo messo in piedi da quelli di Appcelerator sulle applicazioni sviluppate con il loro sdk è abbastanza lasco e non limita più di tanto. Probabilmente hanno preferito non infierire troppo, fatto sta che una soluzione c’è: basta organizzarsi in modo da poter cambiare velocemente il guid associato all’applicazione (nel tiapp.xml) al cambiare dello sviluppatore.

Il nodo è nel guid (ultima riga)

Il nodo è nel guid (ultima riga)

Se in azienda non ci sono altri sviluppatori destinati alla piattaforma Titanium è sufficiente utilizzare sempre lo stesso account, per lo sviluppo e per rilasciare l’applicazione. Qualora si debba lavorare in parallelo sullo stesso progetto è invece meglio fare in modo che chi ha un account personale registri le applicazioni sul quale lavorerà sulla propria console Appcelerator, e implementi un meccanismo di sostituzione veloce dei guid. Lasciando l’account “aziendale” libero per rilasciare l’applicazione o per eventuali sviluppatori sprovvisti di un account Indie.

Registrazione di un applicazione già esistente su un diverso account

Il modo migliore che mi è venuto in mente è quello di creare una nuova applicazione – vuota – utilizzando la CLI, e assegnandole appid e nome uguale a quella che si sta cercando di “clonare”.
Apriamo la console, portiamoci su una cartella vuota creata per l’occasione e digitamo appc new --id APP_ID --name APP_NAME, con APP_ID uguale all’appid dell’app, e APP_NAME uguale al suo nome.
appcelerator-new-app
Questo è il modo più veloce di creare un’applicazione vuota, e oltre al riempimento della directory con i file della nuova applicazioni ci ritroveremo anche con la coppia di applicazioni Titanium/Arrow sulla console web. Per qualche motivo sconosciuto dalla console non si possono (ancora) eliminare le applicazioni Arrow, ma a leggere in rete sembra che presto colmeranno questa lacuna.
appcelerator-online-console

Sostituzione “on-demand” del guid

Una volta creata la nuova applicazione “copia” dell’originale possiamo anche buttarla via, perché l’unica cosa che ci interessa è il guid generato.
Il mio consiglio è quello di creare – all’interno dell’applicazione – una cartella con un file .sh per ogni account Indie che avete, e all’interno di questi mettere un comando che sostituisca il guid originale (quello registrato sull’account “aziendale”) con quello associato all’account Indie personale, e disponibile per la copia sulla console web di quest’ultimo.
In bash un modo per sostituire una stringa all’interno di un file è questo:
sed -i "" 's/ORIGINAL_GUID/REPLACED_GUID/' ../tiapp.xml

Ogniqualvolta si avrà bisogno di usare il proprio account Indie personale basterà eseguire il login con questo e poi lanciare il file .sh che metterà le cose in regola con quelli di Appcelerator. Naturalmente il nostro progetto è sotto git, quindi far ritornare il guid corretto dentro il tiapp.xml della nostra app è questione di un git reset.

Google maps, My Maps, My Tracks, file kml, kmz e chi più ne ha più ne metta

Il mese scorso mi sono cimentato in una due giorni di camminata a passo svelto lungo il (non ancora) famoso Cammino di San Benedetto. Solo due giorni perché purtroppo il tempo è quello che è, ma in teoria per farlo tutto ci si dovrebbero impiegare due settimane o poco più.

Tutte le tappe del Cammino di San Benedetto

Tutte le tappe del Cammino di San Benedetto

Ebbene ho registrato tutto il percorso con Google MyTracks e al termine ho inviato i due file alla mia compagna di viaggio che ne aveva bisogno per scrivere un articolo sul suo blog. Vero che è in russo, ma le foto si capiscono e volendo si può tradurre l’articolo, quindi farò a meno di scriverne (anche perché le foto più belle usate da lei sono mie…).

Una delle due tappe registrate con MyTracks

Una delle due tappe registrate con MyTracks

L’altro giorno Daria mi scrive dicendomi come si fa a usare quei file, perché quel formato (kmz) è strano e non riesce a usarli in alcun modo… ebbene, visto che lei non ci è riuscita magari altri hanno avuto questo problema, quindi ecco un piccolo vademecum.

Il kmz nient’altro non è che un archivio zip contenente un file kml ed eventuali file multimediali. Volendo si può decomprimerlo con un normale programma di gestione archivi (7zip, IZarc, …), oppure semplicemente cambiandone l’estenzione in .zip lo si può aprire come archivio.
Il kml è sostanzialmente un file di testo (più precisamente un file xml) contenente tutte le informazioni riguardo la mappa: partenza, arrivo, durata, percorso con relative coordinate e così via.

Se come lei volete fare una mappa – da condividere sul blog o con gli amici – utilizzando le registrazioni fatte con MyTracks o qualunque altro programma, il mio consiglio è quello di usare Google My Maps, creare una mappa all’uopo, importare i file (kml o kmz, è uguale) e poi rendere la mappa visibile al pubblico.

Google My Maps

Google My Maps

Una nuova mappa può essere creata con facilità direttamente da dentro Google Drive:

Nuova mappa da Google Drive

Nuova mappa da Google Drive

Il risultato della somma dei due tracciati kmz registrati con MyTracks e pubblicati con MyMaps è questo qui:

Nella speranza di trovare un giorno il tempo e la compagnia per fare tutti i 310 km del percorso, non mi resta che augurare un buon pellegrinaggio tecnologico a tutti!