Résolution des liens symboliques avec Xdebug

Dans une configuration Xdebug + IDE (eclipse, phpStorm…) si vous commencez à avoir des liens symboliques, l’IDE ou xdebug commence à perdre les pédales sur la résolution des chemins ce qui fait que les breakpoints de l’IDE ne sont plus détectés.

Voici une technique pour continuer à utiliser le principe de lien symbolique et à utiliser xdebug :

  • vérifier que xdebug fonctionne bien : activer l’arret sur la première ligne de code dans l’IDE
  • vérifier que les mapping serveur sont corrects (dans la config du serveur dans l’IDE)
  • supprimer le lien symbolique et créer un bind (on perd en lisibilité mais ça réalise la même fonction à un niveau un peu plus bas).

Imaginons que le lien symbolique était dans le répertoire /opt/mon_projet/trunk/src/ avec cette résolution:

web -> /opt/mon_projet/trunk/skins/skin_1/web/

Avec un bind il suffit de faire ceci:

 cd /opt/mon_projet/trunk/src/
 mkdir web
 mount -B /opt/mon_projet/trunk/skins/skin_1/web/ web

Un tutoriel sur Gulp pour comprendre les dépendances, l’utilisation de tâches asynchrones ou synchrones

J’ai pris de le temps de faire ce tutoriel car je vois trop souvent des incompréhensions sur ces notions de tâches synchrones et asynchrones. En complément je rappelle le principe de dépendances dans gulp. Les dépendances ne sont pas ordonnées, seul la fin de la tâche déclenche l’exécution de la suivante, il faut donc s’assurer que les fins tâches sont déclenchées seulement lorsqu’elles sont effectivement terminés. Ceci amène à la notion de barrière et de promesses (je n’ai pas détaillé les promesses ici, les docs ne manquent pas sur ce sujet).

Au niveau dépendances

Les logs de ‘un’ se mixe avec ‘trois’ en asynchrone (c’est que l’on cherche) mais ‘deux’ ne se lance bien qu’après la fin de ‘trois’.

Mise en œuvre d’une barrière pour gérer correctement les fins de tâches asynchronesIl n’y a pas besoin de mettre en place de section critique en js, chaque fonction possède son propre contexte, donc la barrière qui gère la fin de l’ensemble des process est plutôt simple à mettre en œuvre.

Au niveau perf

En asynchrone je boucle la tâche ‘quatre’ en 3,6 secondes alors qu’en synchrone elle se boucle en 4,4 secondes. Cela commence à faire beaucoup sur si peu d’itérations.

Le code

J’ai commenté en anglais histoire de partager un peu.

var child_process = require('child_process');


function execScriptAsync(script, cb) {
//	var _script=script;
//	var _cb=cb;
    //this function is triggered on script is completed
	function onCompleted(error, stdout, stderr){
		if (error) {
        	console.log("Error on script: "+script+ " error = "+error);
        } else {
            console.log("Execution completed on : "+script);
		    console.log("   stdout: "+stdout);
	        if (stderr) console.log("   stderr: "+stderr);
		}
	    if (cb) {
	        cb(error);
	    }
	} 
	console.log("Executing script : "+script);
	child_process.exec(script, onCompleted);
};

var runnerAsync = function (name, iteration, cb) {
    var i=0;
    var j=iteration;
    // this function is used as a barrier, once all process are completed, trigger the callback so the task will be ended properly.
    var wait = function() {
        j--;
        console.log("   Remaining '"+name+"' process="+j);
        if (j==0) {
            // do not forget to call the callback, gulp is using this to trigger the task ended
            cb();
        }
    }
    for (i=0; i<iteration; i++) {
        execScriptAsync('echo '+name, wait);
        //we are reaching this code even if the echo command is not ended, so we can have several echo called simultaneously
        // the number of echo in parallel depends on how many process can be started simultaneously on the box
    }
    // do not call the callback here otherwise you will have the task completed while 'echo' cmd are still running
};

var runnerSync = function (name, iteration, cb) {
    for (var i=0; i<iteration; i++) {
        var echo = child_process.spawnSync('echo', [name], {shell: true});
        //we are reaching this code only once the echo command is ended
        if (echo && echo.stdout) {
            console.log('stdout: '+echo.stdout);
        }
    }
    cb();
};

// switch from runnerSync to runnerAsync this to see the difference between synchronous and asynchronous
var runner=runnerAsync; // runnerAsync;

gulp.task('one', function(cb) {
    runner('one', 100, cb);
});

gulp.task('two', ['three'],function(cb) {
    runner('two', 100, cb);
});

gulp.task('three', function(cb) {
    runner('three', 100, cb);
});

var Q = require('q');
// keep start time of gulp
var startTime=new Date();
// here we can see dependencies behavior, 'two' should be triggered before 'three', but 'two' depends on 'three' so 'three' comes first.
gulp.task('four', ['one', 'two', 'three'], function() {
    //in this task, I'm using a promise which is a better way to handle async process response
    //(with gulp it is not simple to add functional rules between tasks, everything rely on dependencies)
    var deferred = Q.defer();
    var cb=function(data){
        var end=new Date();
        var elapsed=end.getTime() - startTime.getTime();
        console.log("Total time elapsed="+elapsed+' ms');
        // resolve the task 'four'
        deferred.resolve();
    }
    // start processes
    runner('four', 100, cb);
    // return the promise so gulp will be able to process the task completion properly
    return deferred.promise;
});


Problème GTK sur Eclipse-Neon2 avec une Lubuntu

Version ubuntu:

Distributor ID:	Ubuntu
Description:	Ubuntu 16.10
Release:	16.10
Codename:	yakkety

Cas de la perte des icônes de base et message d’erreur au lancement

Si les messages sont du type:

(Eclipse:14401): Gtk-WARNING **: Theme parsing error: gtk-lubuntu.css:309:15: The 'icon-shadow' property has been renamed to '-gtk-icon-shadow'
(Eclipse:14401): GLib-CRITICAL **: g_base64_encode_step: assertion 'in != NULL' failed

Créer le script sh suivant :

#!/bin/bash
export GDK_BACKEND=x11
export SWT_GTK3=0
ECLIPSE_PATH=`dirname "$(readlink -f "$0")"`
echo $ECLIPSE_PATH
$ECLIPSE_PATH/eclipse

puis lancer eclipse via ce script.

Cas d’une exception

Si eclipse plante complètement avec ce message :

Exception in thread "DLTK indexing" java.lang.ExceptionInInitializerError
	at org.eclipse.dltk.internal.core.index.lucene.LuceneIndexer.getDocuments(LuceneIndexer.java:104)
	at org.eclipse.dltk.internal.core.index2.AbstractIndexRequest.analyzeSourceModuleChanges(AbstractIndexRequest.java:124)
	at org.eclipse.dltk.internal.core.index2.SourceModulesRequest.run(SourceModulesRequest.java:64)
	at org.eclipse.dltk.core.search.indexing.AbstractJob.execute(AbstractJob.java:80)
	at org.eclipse.dltk.internal.core.search.processing.JobManager.run(JobManager.java:482)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
	at org.eclipse.dltk.internal.core.index.lucene.LuceneManager.<init>(LuceneManager.java:212)
	at org.eclipse.dltk.internal.core.index.lucene.LuceneManager.<clinit>(LuceneManager.java:74)
	... 6 more

Dans ce cas il faut supprimer le workspace et le recréer.

Problème de clavier avec Synergy entre un serveur window et un client Linux.

Si vous avez un problème de mauvais mapping de votre clavier sur le client Linux, vous pouvez essayer de forcer le mapping du client linux avec cette commande (il faut que le client soit connecté) :

Depuis une console sur le client linux:

 setxkbmap fr

nb: il y a aussi une autre façon de faire via le fichier de conf du serveur mais il faut que je remette la main dessus.

 

Multi-écran et raccourci openbox sur Lxde

Un petit mémo pour définir des raccourcis clavier sur LXDE afin de basculer d’une config multi-écran à une autre.

Pré-requis:

Installation de arandr pour créer les config xrandr (ca evite de se cogner la doc xrandr et l’ecriture des commandes xrandr)

 sudo aptitude install arandr

Lien vers xrandr pour approfondir

Définition et sauvegarde des layout d’écran

Créez les scripts xrandr avec arandr. Pour cela définissez l’organisation des écrans et faites « enregistrer sous », cela sauvegarde un script xrandr que l’on pourra executer via le raccourci.

Pour l’exemple je les ai stocké dans ~/.screenlayout/.

Définition des touches de raccourci

Editez le fichier .config/openbox/lxde-rc.xml

ajoutez par exemple :

   <keybind key="W-C-Up">
     <action name="Execute">
       <command>~/.screenlayout/vga_top_edp_bottom.sh</command>
     </action>
   </keybind>
   <keybind key="W-C-Down">
     <action name="Execute">
       <command>~/.screenlayout/edp_only.sh</command>
     </action>
   </keybind>

ca permet de lancer une config dual-screen (vga+edp) avec les touches CTRL+WIN+up et de revenir a l’ecran EDP seul avec CTRL+WIN+down

plus d’info sur les config openbox ici

Inspection de variables javascript

 

Voici un bout de code bien pratique pour inspecter vos variables javascript:

function listprop(o){
                 var objectToInspect;
                 var result =' [];

                 for(objectToInspect = o; objectToInspect !== <span' style=''color:#000080;font-weight:bold;''>null; objectToInspect = Object.getPrototypeOf(objectToInspect)){
                    result = result.concat'('Object.getOwnPropertyNames(objectToInspect));
                 }
                 $log.debug(''inspector=''<'/'span>+result);
                 return result;
}

le $log est de l’angular. un console.log peu’t’ faire l’affaire. lancez listprop(ma_varaible) et le tour est joué.

Notes on how to generate a DDPI of your album (using SOX and cue2ddp)

What is written on an AUDIO cd

The audio data is a basic row of bits, the trick is to tell the reader where to put the head to find the correct track. it is done with the cuesheet, it describes where are the tracks and eventually add CD-TEXT information.

You can find good information in the man page of cdrdao and cue2ddp tools on linux/mac and in the links below.

DDP step by step…

1: convert each track to raw file

So basically, once you have your .wav files, you just have to encode them in raw format with the following characteristics:

  • 44100 Hz
  • 16 bits signed integer
  • 2 channels
  • little endian (FYI: cdrdao is using big endian so you should switch to big endian if you want to burn your cd with your home tool. Industrial tools use little endian… make it simple they said…)

sox is your friend to do that.

I added normalization, dithering and stats to sox command. Stats is usefull to see if you have peaks or gain issues

#!/bin/bash


SOURCE=$1
cd $SOURCE

mkdir "raw"

WAV_FILES=`ls *.wav`

for WAV in $WAV_FILES; do
	FILENAME=`basename $WAV`
	echo "File: $WAV"
	sox $WAV -e signed-integer -b 16 -r 44100 -c 2 raw/$FILENAME.raw remix 1 1 gain -hn -3 gain -h dither stats
done

2: Concatenate all raw files in one single raw file

Once you have the raw files, you can put them all together in a single raw file, using cat for instance:

#!/bin/bash

BIN="$1.dat"
SOURCE=$2
cd "$SOURCE/raw"
RAW_FILES=`ls *.raw`

for RAW in $RAW_FILES; do
  FILENAME=`basename $RAW`
  echo "$RAW >>"
  cat $RAW >> $BIN
done

3: Generate the ddpi

The ddpi uses a plain text to generate the ddpi files. this file is identified as the cuesheet, it describes where is the raw file, what is the type of the raw file and where are the tracks and the index of each track. You should ook at the links below to see how to write a cuesheet file. Once you have the cuesheet file, you can generate the ddpi :

cue2ddp -ct -m My_Ref_1234 cuesheet.cdt ddp

Notes: -ct will generate cdtext information based on the cuesheet file. -m is the reference of your album, cuesheet.cdt is your cuesheet file. ddp is the target folder. This folder must be empty.

Links

Notes on creating cuesheet

Cuesheet syntax on wikipedia

Cuesheet syntax

SOX documentation

how to build multiple cordova applications with different cordova version

instead of installing the cordova client with

 npm install -g cordova   # DON'T USE THIS

You should just install the cordova client locally, the best way is to put the cordova dependency in the file package.json so when you run the npm install in the root folder of your application, it will install the appropriate cordova version related to this application.

 # if you have a well configured package.json
 #
 npm install

or

 # without a package json
 # if you want the cordova version 5.2.0
 #
 npm install cordova@5.2.0

But it is not enough because your path is not up to date so when you run cordova, it is still pointing to the global one. The trick is to run the following command (or add it to your .bashrc) :

 export PATH=./node_modules/cordova/bin:$PATH

then type again

 cordova -version

That’s it ! You are running cordova with local cordova client defined by the developer of the app.

How to remove the dialog window that asks the user to allow bluetooth visibility on Android ?

This dialog contains the following message : « An app wants to make your device visible to other Bluetooth devices… »

if you look in the code you’ll see that this dialog is related to the Settings application, particularly RequestPermissionActivty.java. You’ll see also that a boolean can automatically click on the yes button, exactly what we need:

   if (getResources().getBoolean(R.bool.auto_confirm_bluetooth_activation_dialog) == true) {
           // dismiss dialog immediately if settings say so
           onClick(null, DialogInterface.BUTTON_POSITIVE);
   }

So the trick is to find where is this boolean. It is quite obvious and it must be in the res folder in the bools file. So looking in packages/apps/Settings/res/values/bools.xml we find what we need:

 <!-- Whether the bluetooth activation confirmation dialogs should be auto dismissed.
        Can be overridden for specific product builds. -->
 <bool name="auto_confirm_bluetooth_activation_dialog">false</bool>

switching the value to true and the trick is done.

Enjoy !

Notes en vrac sur le build d’une ROM Android sur une base Rockchip

construire une rom android.

___

Docs officielles android pour le build d’une ROM: https://source.android.com/source/building-running.html

Configurer l’environnement pour avoir les actions dans l’environnement.

$ . ./build/envsetup.sh
S’assurer que le device est vu par le port USB

===============================

voir les usb:

$ lsusb 

$ dmesg

Faire un udev pour avoir un nom potable dans le /dev et avoir l’adb qui le detecte vi /etc/udev/conf.d/50-custom_device.conf

ajouter la ligne suivante en faisant matcher le vendor et le product avec la sortie de lsusb (ici 04e8:6860) le group est le group (systeme) authorisé a utiliser le device, le symlink est le nom affiché SUBSYSTEM== »usb », ATTRS{idVendor}== »04e8″, ATTRS{idProduct}== »6860″, MODE= »0666″ GROUP= »my_group », SYMLINK+= »i9305″

recharger la config udev

udevadm control --reload-rules

optionnel : update adb list

$ android update adb

ajouter le product id dans la liste adbf Edit $HOME/.android/adb_usb.ini, add 0x2207 at the end of the file Restart adb server

$ adb kill-server && adb start-server

List android device

$ adb devices

lien pour la doc sur udev: http://www.reactivated.net/writing_udev_rules.html#syntax https://wiki.debian.org/udev

monter l’ensemble du systeme de fichier d’un android:

==================================

doc sur : https://github.com/spion/adbfs-rootless

adbfs /chemin_de_mount

Suivre le readme Attention il faut avoir les droit pour lancer l’outil car il lance fuse qui accede a bas niveau:

recuperer l’IMEI:

============

taper sur le tel *#06#

faire un backup

=============

backup dans le repertoire courant (cree le fichier backup.ab)

adb backup -apk -shared -all

restaurer depuis le fichier backup.ab

adb restore backup.ab

arreter le server proprement

adb kill-server
installer un recovery correct:

=====================

Telecharger recovery clockwork puis installer heimdall lancer l’installation de la recovery:

$ heimdall flash --RECOVERY /home/ow-cve/dev/RCW/recovery-clockwork-6.0.4.7-i9305.img
Extraire les données d’une img rockchip:

========================================

You’ll first need to build rk-tools:

git clone https://github.com/rk3066/rk-tools.git cd rk-tools sudo apt-get install libssl-dev libcrypto++-dev make

Then use img_unpack tools to unpack the firmware to another format:

./img_unpack update_mk908_106j2107_04.img update_mk908_106j2107_04_unpack.img rom header code: 1060000 rom version: 4.1.1 build time: 2013-09-07 10:39:22 chip: 70 checking md5sum....OK

Finally, run afptool to extract the files from the resulting file into “firmware” directory:

./afptool -unpack update_mk908_106j2107_04_unpack.img firmware Check file...OK - UNPACK - package-file 0x00000800 0x00000242 RK3188Loader(L)_V1.20.bin 0x00001000 0x0002F8AE parameter 0x00031000 0x00000264 Image/misc.img 0x00031800 0x0000C000 Image/boot.img 0x0003D800 0x00A2C000 Image/recovery.img 0x00A69800 0x00BFC000 Image/system.img 0x01665800 0x1A630000 backupimage/backup.img 0x1BC95800 0x01665004 update-script 0x1D2FB000 0x000003A5 recover-script 0x1D2FB800 0x0000010A UnPack OK!
Ajouter une app dans le framework:

==================================

copier l’app dans /packages/apps/<mon_app_dir> copier un Android.mk d’une autre app et mettre a jour les parametres de celui-ci.

Lancer la compilation d’une app:

=================================

Configurer l’environnement pour avoir les actions dans l’environnement.

$ . build/envsetup.sh

$ mmm /packages/apps/<mon_app_dir>
Faire un package d’update rockchip:

===================================

afptool et img_pack ne gere pas bien les chemin absolu donc : – faire un lien sym « tmp » dans le repertoire d’afptool qui pointe vers les img du build android

– puis creer le script suivant dans le repertoire afptool:

#!/bin/bash

set -e

cd `dirname $0`

rm -f tmp.img
rm -f update.img

# put all img in one single img
./afptool -pack tmp tmp.img

# add RockChip specific param and bootloader
./img_maker -rk31 tmp/RK3188Loader_2.16.bin 1 0 0 tmp.img update.img

rm -f tmp.img

echo "update.img is at `pwd`/update.img"

ca genere un fichier update.img dans le repertoire d’afptool.