Tracciare lo sguardo per cambiare il focus della tastiera

Io ho questa idea da un po’. Poi stamattina ho letto un articolo, https://blog.acolyer.org/2017/04/26/improving-user-perceived-page-load-time-using-gaze/ (riguarda la priorizzazione del caricamento dei contenuti per rendere migliore la percezione del tempo di caricamento, ma …) trovo questo

https://sourceforge.net/projects/gazepointer/

Avendo diversi monitor non è raro guardare da una parte e scrivere da un’altra, non so quindi quanto questo si utile.

Ma capita di iniziare a scrivere e accorgersi in un secondo momento che il focus è in un’altra finestra. Possono succedere casini, ma anche la sola perdita di tempo.

Mi piaccerebbe capire cosa è possibile fare. Ovviamente non voglio fare a meno del mouse, perché è utile, vorrei piuttosto avere 2 puntatori, uno controllato dal mouse, l’altro dallo sguardo, quando necessario cliccare, impostare una combinazioni di tasti per far cliccare il puntatore controllato dallo sguardo.

Questa sarebbe una cosa piuttosto utile e produttiva

Ci sono altri utilizzi interessanti:

https://github.com/lexasss/etudriver-web

 

Indutria 4.0, NAS, SAN, FUJI, VMWare, e soiel

Due giorni di convegni e non ho scritto nulla.

Il primo, ieri pomeriggio organizzato da Confindustria Ancona, riguardante Industria 4.0.

Non avevo idea di cosa fosse, così mi sono iscritto. In pratica è l’utilizzo dell’informazione nel contesto della produzione industriale per migliorare l’efficienza, andare incontro alla domanda, monitorare il gradimento di un prodotto, migliorare il rapporto col cliente, prevedere i bisogni.

La rivoluzione sarebbe quella di portare i meccanismi di feedback direttamente a livello industriale, senza passaggi intermedi. Altro vettore di informazione sono poi le macchine e le loro azioni, e i sensori, che facendo rete possono migliorare la efficienza produttiva.

Tutto ciò infarcito da una infrastruttura burocratica, ed Industrial Innovation Hub, che dovrebbbero far sì che questa rivoluzione avvenga. E qui sono rimasto un po’ stupito di come una rivoluzione possa provenire da una infrastruttura burocratica di livello europeo (e piramidale, fino arrivare agli hub locali) e non da esigenze o innovazioni introdotte da attori presenti nel mercato. Cioè, quasi ho avuto l’impressione di ascoltare qualcosa di simile ad un comitato di difesa della rivoluzione.

E perché mai gli industriali non pensano di loro iniziativa di introdurre innovazioni?

Cosa guardano durante la loro attività?

Perché non innovano di loro iniziativa?

Me ne sono andato presto. Tutto molto interessante e assolutamente giusto, ma anche tecnologie che conosco già, ma gli industriali sembra di no.

L’altro stamattina, a Civitanova, VMWare, Fuji e SOIEL International hanno organizzato un evento formativo, o pubblicitario sullo storage.

Ecco. Qui mi sono trovato a non capire niente, terminologie mai incontrate, forse perché non è il mio campo, eppure è storage, e si tratta di server che io potrei usare (è vero che non mi è mai capitato). Così, tornando in treno, mi documento un po’ e scopro cose interessanti.

Partendo dalle sigle:

  • NAS: Network Area Storage. È il semplice fileserver. Le tecnologie sono NFS, Samba/CIFS, etc.
  • SAN: Storage Area Network. È uno storage distribuito su rete locale o globale.

E su SAN viene il bello. Esistono 2 protocolli:

  • FC: Fiber Channel
  • iSCSI: internet Small Computer System Interface
  • (e FCoE: Fiber Channel over Ethernet)

FC è stato il primo, è un protocollo dedicato che funziona solo su reti dedicate, appunto, e garantisce velocità maggiori e affidabilità dei dati di un livello superiore.

Mentre iSCSI è stato sviluppato successivamente ed ha il vantaggio di essere più semplice e facilmente implementato perché è un protocollo che si poggia sopra TCP/IP.

Essendo storage distribuiti c’è il concetto di unità indirizzabile, in particolare queste 2 acronimi:

  • LUN: Logical Unit Numbers
  • IQN: iSCSI Qualified Name

il secondo dovrebbe essere un nome simbolico, quindi ha bisogno del suo omologo dns che si chiama:

iSNS: internet Storage Name Service

Nel caso iSCSI i pacchetti girano sopra TCP/IP, quindi nascono intrinsecamente problemi di sicurezza, che vanno affrontati. Qui non mi andava più di leggere, ma IPSec è una possibile soluzione, altre non ho approfondito.

Durante il convegno VMWare pubblicizzava il su vSAN, virtual SAN, mentre FUJI il suo sistema di storage integrato che forniva una soluzione completa. In realtà i 2 attori non sono concorrenti, ovviamente, ma FUJI tra le proprie proposte di storage ha una offerta comprensiva di software, il quale software è in qualche modo concorrente alle soluzioni VMWare.

Mentre SOIEL ( www.soiel.it ) organizzava l’evento ed ha condotto una indagine riguardo a come le aziende percepiscano il problema dello storage in un contesto dove la quantità di dati è in costante aumento.

Ora ho scritto qualcosa.

My beloved DevOps tool, gnu make

Oh, yes, there is a lot of tool around for Really DevOps(TM).

But I just want to automate the task to sync remote folders with my working tree, anything else is managed with git, and that’s fine.

So I thought: rsync + fuse (file system user level mounting, I hate to launch filezilla or similae)

But I really does not need gulp, grunt or anything else, a Makefile is enough, no?

put:
	sshfs remuser @ remhost.domain.com:/home/remuser /home/daniele/remhostuser
	rsync -artv --exclude-from='rsync_exclude_from.txt' . /home/daniele/remhostuser/MyApp/
	fusermount -u /home/daniele/remhostuser

Then in the excude file:

Makefile
*~
.git
Docs
rsync_exclude_from.txt

Well I just wrote 2 files, a 4-lines file and a 5-lines files, one time. And for upload my code I just have to run:

make put

 and …

everything else are just TMs

Qualche difficoltà nel capire nel php l’implementazione della closure

In javascript tutto è più semplice. Ora sto usando/imparando Phalcon e il secondo esempio/tutorial è strambo un bel po’ (INVO).

Definisce una class Services, derivata da \Base\Services, a sua volta derivata da \Phalcon\Di\FactoryDefault.

In \Base\Services è definito un metodo, bindServices(), che cicla sui metodi definiti per la classe stessa, controllando che abbiano almeno 4 lettere, e che le prime 4 siano ‘init’. In caso affermativo fa … meglio incollare il codice:

    protected function bindServices()
    {
        $reflection = new \ReflectionObject($this);
        $methods = $reflection->getMethods();
        
        foreach ($methods as $method) {

            if ((strlen($method->name) > 10) && (strpos($method->name, 'initShared') === 0)) {
                $this->set(lcfirst(substr($method->name, 10)), $method->getClosure($this));
                continue;
            }
            
            if ((strlen($method->name) > 4) && (strpos($method->name, 'init') === 0)) {
                $this->set(lcfirst(substr($method->name, 4)), $method->getClosure($this));
            }

        }
        
    }

 

strano no? Poi in \Services vengono definiti i vari metodi initDb, initUrl, … e così via.

Elegante? Forse, ma oscuro per me, io non voglio scrivere così.

Innanzi tutto voglio ereditare direttamente da \Phalcon\Di\FactoryDefault, che sia chiaro. Poi se aggiungo una qualche inizializzazione che sia esplicita e non implicita nel nome, perché altrimenti mi sa di magico e la magia la si maneggia male, secondo me.

Ecco, va a finire che il mio bindServices() è:

    private function bindServices()
    {
        $reflection = new \ReflectionObject($this);
	$this->set('url', $reflection->getMethod('initUrl')->getClosure($this));
        
    }

 

avrei la tentazione di ciclare, ma forse così:

    private function bindServices()
    {
        $reflection = new \ReflectionObject($this);
	$services = ['url' => 'initUrl','db'=>'initDb'];
	foreach($services as $service => $method) {
		$this->set($service, $reflection->getMethod($method)->getClosure($this));
	}
    }

 

almeno definizione e uso sono vicini, e si capisce, e si capisce anche come si usa ReflectionObject (ed esiste il metodo getMethod(), senza ‘s’ finale!).

A beh, riguardo al riuso, potrei anche capirlo, ma allora basterebbe definire $services come una proprietà dell’oggetto che eredita

 

    protected $services = [];
    protected function bindServices()
    {
        $reflection = new \ReflectionObject($this);
	foreach($this->services as $service => $method) {
		$this->set($service, $reflection->getMethod($method)->getClosure($this));
	}
    }

(ma cosa vuoi riusare poi?) comunque trovo una pessima idea andare a fare magheggi con i nomi di metodi su di una classe che eredito da un framework, il quale potrebbe introdurre altri metodi in futuro e costringermi ad aggiungere eccezioni (al magheggio). Vero è che se aggiungeressero initUrl a \Phalcon\Di\FactoryDefault dovrei comunque rivedere il codice, ma solo cambiando l’array services e il nome del mio metodo, non andare ad aggiungere uno special-case nel loop.

Non c’è, sembra, un modo per fare il binding di un method al proprio oggetto, ovvero come sarebbe in javascript passare il nome del metodo tipo this.methodName.bind(this).

Le funzioni native accettano array($this, ‘methodName’), ma Phalcon vuole una Closure, altro non lo digerisce.

p.s.: il codice a cui mi riferisco è qui : https://github.com/phalcon/invo in particolare https://github.com/phalcon/invo/blob/master/app/library/Base/Services.phphttps://github.com/phalcon/invo/blob/master/app/Services.php

DBus vs ZeroMQ

Cerco un message system. Quello che vorrei è poter sottoscrivere un servizio e ricevere i messaggi, oppure semplicemente chiedere ad un processo con diritti maggiori alcune informazioni o di compiere azioni, senza dover aprire una porta tcp e gestire tutto a mano.

Devo fare delle azioni sull’hardware e penso che forse DBus già ha qualcosa fatto.

Cosa trovo:

 

dbus-send --session           \
  --dest=org.freedesktop.DBus \
  --type=method_call          \
  --print-reply               \
  /org/freedesktop/DBus       \
  org.freedesktop.DBus.ListNames

e

dbus-send --system            \
  --dest=org.freedesktop.DBus \
  --type=method_call          \
  --print-reply               \
  /org/freedesktop/DBus       \
  org.freedesktop.DBus.ListNames

rif.: http://unix.stackexchange.com/questions/46301/a-list-of-available-dbus-services

mi da l’idea di cosa sia dbus, un sistema che permette di registrare un servizio, di sottoscrivere un servizio e ricevere messaggi, organizzati in maniera gerarchica (es.: org.freedesktop.DBus), mandare messaggi, aprire una sessione, eventualmente con tanto di autenticazione.

Ad esempio, con DBus + udev potrei fornire un servizio che mi dice se qualcuno ha attaccato un dispositivo usb, eventualmente permettendo al client di richiedere delle azioni da intraprendere (chiedere che tipo di dispositivo è, elencare le azioni disponibili fornite dal driver … beh, non esageriamo con la duttilità, potrebbe diventare complesso). Ancora, con DBus + UDisk2 posso aprire la finestra di una cartella di un dispositivo di storage appena inserito, ad esempio.

Se ho un dispositivo piccolino, senza desktop, tipo RaspberryPI, posso usare dbus e la sua interfaccia node, https://github.com/sidorares/node-dbus, per capire se è stato inserito un dispositivo usb, in tal caso presentare il servizio disponibile sulla interfaccia web (usando websocket (push) o usando una richiesta attiva) e permettendo di intraprendere azioni. Se ad esempio inserisco un device di storage, posso metterlo a disposizione come target per un trasferimento, se inserisco una webcam potrei fornire lo stream video su di una porta o servizio, etc.

Ovviamente ci sono binding DBus per diversi linguaggi. Quel che ho capito è che non è strettamente necessario il concetto di desktop per farne uso, è qualcosa di complesso, un IPC, con le sue caratteristiche, pro e contro, ma con dei servizi di partenza standard che potrebbero essere interessanti per arrivere dritti al punto. DBus != Desktop bus, anche se è stato pensato/creato per questo.

Approfondisco un po’ perché mi interessa usare ZeroMQ per altri progetti, pare, http://comments.gmane.org/gmane.comp.freedesktop.dbus/12827, che DBus sia meno efficiente di ZMQ, e anche di CORBA, ma ha altre caratteristiche necessarie come la gestione della sicurezza, ma deficia di altre presenti in ZMQ.

ZMQ è più articolato di quanto mi aspettassi. Ad esempio ci sono diverse modalità di aprire un canale, ovvero diversi patterns. Ma in definitiva è facile da capirsi.

La conclusione è che andrò ad utilizzare ZMQ per un piccolo applicativo, sostanzialmente perché ZMQ è quello che abbiano pianificato di usare anche in un altro progetto che ha bisogno di essere distribuito su più macchine, ma l’aver dato un’occhiata a DBus l’ha reso meno misterioso.

wordpress do not redirect after post

Problem seems to be reported here and there, but I can not found what I really need to fix this during the morning:

https://wordpress.org/support/topic/redirect-after-post?replies=2

https://wordpress.org/support/topic/redirect-doesnt-work-1

… nope, nothing. I found this:

http://wordpress.stackexchange.com/questions/76991/wp-redirect-not-working-after-submitting-form and second reply:

 

add_action( 'wp_loaded', 'wpa76991_process_form' );
function wpa76991_process_form(){
    if( isset( $_POST['my_form_widget'] ) ):
        // process form, and then
        wp_redirect( get_permalink( $pid ) );
        exit();
    endif;
}

but it does not work, I ask myself why, and try to print the required url, that was in fact from menu_page_url(), but this is in administration menu, so, after some investigation I found out that the good hook is ‘admin_menu

So:

add_action( 'admin_init', 'myplugin_admin_form_process' );

function myplugin_admin_form_process()
{
  if(!isset($_POST['form_id']) || $_POST['form_id'] != 'myplugin_admin_form') {
    return;
  }
  if($_POST['action'] = '....') {
    process_post();
    wp_redirect(menu_page_url( 'myplugin-admin-main', false ));
    exit();
  }
}

and it worked

javascript Promise chaining: augmenting the unique argument

There are two things that, IMHO, make code cleaner when using Promises Idioma:

  1. use an unique object argument (and its attributes as you would use argument legacy)
  2. return resolve with the object given as argument augmented by attribute of the action executed by the function

i.e., say I want to ask db for data about a person, I define the method (function) that got an object {person: {personstruct}} and return the augmented object {person:{personstruct}, contactdata: {contactdatastruct}}

 

function addContactData(o){
   return new Promise(function(resolve,reject) {
     //check existense of attributes, reject with reason
     mysql.query({sql:"select * from cdata where pid=?",values:[o.person.pid]},function(err,rows) {
       if(err) {
          o.err = err.toString();
          reject(o);
       } else {
          if(rows.length>0) {
            o.contactdata = rows[0];
          } else {
            o.contactdata = null;
          }
          resolve(o);
       }
     });
   });
}

 That could look not very optimized but it is a practice that make things look cleaner and consistent. Pros:

  1. testing is simply composable, just pass some good object and test if it augments: there is an idioma testing
  2. you have no surprise
  3. you have not to deal with “how do I access previous promise result in a .then() chain” problem, where Bergi show some drawback with this solution, that really are worth paying for the cleaness

Also object is passed by reference, and test on required attributes is a matter of enstabilish a protocol, like attrlist with type required.

Note: image source http://www.geograph.org.uk/photo/1804846 chain at the launch of SS Great Eastern (sailing ship), Isle of Dogs, England

Cifratura simmetrica, un discorso campato in aria

E quando poi si parla di algoritmi di cifratura simmetrici, si dice che c’è bisogno dello scambio sicuro
della chiave di decodifica, e, i più, a questo punto si tacciono.

E tra i più c’ero anch’io.

Di fatto lo scambio sicuro della chiave può essere fatto su di un canale differe, ad esempio tramite un database, ad esempio si può scambiare un messaggio tra 2 attori che non si fidano l’un dell’altro dividendolo in 2 parti: identificazione (da verificare), messaggio oscurato (cifrato).

Infatti in molti casi può non essere così importante la segretezza del messaggio, ma esserlo l’autenticità del mittente.

In un semplice schema, se da una parte c’è un canale sicuro asincrono, come ad esempio è un database, e da un altra si invia un messaggio verso un servizio che ha accesso a questo database, il detto servizio è in grado di controllare l’autenticità del messaggio semplicemente decifrandolo utilizzando la chiave segreta presente (o deducibile da qualche dato) nel db.

Ecco, trovo sia abbastanza buona come idea, il fatto è che gli algoritmi di cifratura a chiave simmetrica, se usati tramite le funzioni mcrypt_* di PHP sono piuttosto delicati, e ce poco che sia trasparente.

Le cose che bisogna sapere sono:

  1. la cifratura AES è anche detta RIJNDAEL, ovvero Java dice AES, php dice RIJNDAEL, ma è lo stesso.
  2. AES è un algoritmo di cifratura a blocchi, con ciò che ne consegue: un blocco ha una lunghezza fissa.
  3. ECB è un modo sbagliato di fare le cose, infatti non prevede di sporcare i blocco da cifrare con i dati del blocco precedente.
  4. CBC (o altri metodi che prevedono l’uso del blocco precedente) pretende un initialization vector, che è un blocco creato a caso (random) di dati affinche si possa usare come blocco sporcatore. Esso verra messo all’inizio del messaggio cifrato (verrà messo in chiaro), cosicché il ricevente possa raccapezzarcisi.
  5. È un algoritmo a blocchi, quindi il messaggio deve stare precisamente in una lunghezza multipla della lunghezza del blocco, ovvero PKCS padding è appunto il metodo col quale si aggiungono i dati mancanti.
  6. Non è strano che venga aggiunto un blocco intero quando la lunghezza dell’input è esattamente un multiplo del blocco, infatti il blocco di padding tipicamente contiene, codificato per ogni sottoblocco (byte), la lunghezza dei dati di padding: [messaggio][padding] … dove [padding] = 0x04,0x04,0x04,0x04 , vale a dire leggendo l’ultimo byte so quanti byte scartare. Quindi una parte di padding DEVE esistere sempre. I blocchi sono di lunghezza 16 bytes (o 32 bytes per RIJNDAEL 256), 8 bits sono sufficienti a rapresentarli
  7. Per effetto della vettore iniziale, scelto spesso in modo casuale, lo stesso testo, codificato con la stessa chiave produce una stringa differente, OGNI VOLTA. Ossia encrypt(‘stringa’) != encrypt(‘stringa’)

È anche possibile quindi passare dei dati nel primo blocco, quello fittizio, sempre facendo attenzione di non passare
dati sensibili, e comunque di non superare i 128 bit, ossia i 16 bytes a disposizione.

Ora Steven Holder ha rilasciato questo pacchetto: https://github.com/stevenholder/PHP-Java-AES-Encrypt

Purtroppo sul padding c’era un bug (di cui il punto 6), inoltre a me sembrava migliore instanziare un oggetto (con la chiave passata nel cotruttore) e poi chiare encrypt o decrypt, la chiave è l’hash md5 di una stringa, perché md5 ha esattamente lunghezza 16 bytes, ossia 128 bit. Qui https://github.com/danielecr/aes128encrypter c’è anche l’implementazione node relativa, e strutturalmente equivalente (classe instanziata e encrypt, decrypt).

 Tool online per la codifica https://www.tools4noobs.com/online_tools/encrypt/

wordpress where tinymce is the default editor

Interacting with tinymce in wp is possible:

because tinymce is a default editor

(plugin I developed for downloading offers from shoppydoo, a price comparator service: http://www.shoppydoo.it/ )

The extension generate a tag that will be parsed and recognized by the backend plugin, replacing it with a parsed xml coming from price comparator service. Revenues are accredited to the editor/owner of the blog (need an account on shoppydoo).