Skip to content


phpThumb: how to switch error messages on

phpThumb is a free, open source (GPL) image thumbnail generator. Even though the site feels like the beginning of the century, development is still going on as can be seen on Github.

This software has weird configuration options to enable the display of errors. To be able to see errors, you should set the following in phpThumb.config.php:

$PHPTHUMB_CONFIG['error_die_on_error']          = true;     // die with error message on any fatal error (recommended with standalone phpThumb.php)
$PHPTHUMB_CONFIG['error_silent_die_on_error']   = false;    // simply die with no output of any kind on fatal errors (not recommended)
$PHPTHUMB_CONFIG['error_die_on_source_failure'] = true;     // die with error message if source image cannot be processed by phpThumb() (usually because source image is corrupt in some way). If false the source image will be passed through unprocessed, if true (default) an error message will be displayed.

But also, and this is the tricky one as it’s away from the other error parameters, you need to enable (or rather, “not disable”) debug mode:

$PHPTHUMB_CONFIG['disable_debug'] = false;

Now phpThumb’s output will still seem like an image to your browser, but if you save it and open it with notepad or equivalent, you’ll be able the read the error message.

Posted in software, web development.


aToaD #13: regex101

Writing regular expressions about always give me a headache… You probably know about the nice regular-expressions.info website, containing a lot of useful information and what seems to be a fairly exhaustive reference.

Yet it misses a useful tool: a way to test your regex. That’s where regex101 (“Regular Expressions 101″) comes in handy. You simply enter your regular expression, pick modifiers (help available for those), then enter some text and see if the regular expression matches it.
Other interesting features:
– quick regex reference in the bottom right corner
– supports regex particularities of 3 languages (PHP, Javascript and Python),
– (very) basic code generator in those languages to use your regular expression
– you can create unit tests
– you can save your stuff either via unique URL or by using a Github or Google (yuck) account. I haven’t tested this, though.

In a somewhat related area, Code Beautify will help you reformat your code in a nicer way. Works with quite a few popular languages (JSON, XML, JavaScript, and many more)

Posted in A Tool A Day.


How save a list of all files in folder + subfolders

(in Windows via command line)

Go to Start Menu → Run (keyboard shortcut: [windows key]+R) and run “cmd”
Browse to the folder you want to list
Then type: dir /s > listing.txt

This is assuming you want to create a file named listing.txt and put the list in it.

If you want to append the listing to an existing file, use a double > :
dir /s >> listing.txt.

If you want to output the result to the console and not to a file, just skip the > listing.txt part.

If you don’t want to browse to the folder, you can specify it as an argument to dir:
dir c:\somefolder /s > c:\listing.txt.

Posted in Windows.


How to convert Dolby DD5.1 to stereo

I’ll just cover the main points, the hardest part was to find appropriate software and to figure which sound channels to keep, the rest is just fairly trivial and usual stuff.

Get Audacity and the FFmpeg library (needed to import from usual video formats like MKV – for Audacity 2.0.6 pick ffmpeg-win-2.2.2.exe)
http://manual.audacityteam.org/o/man/faq_installation_and_plug_ins.html#ffdown
http://lame.buanzo.org/#lamewindl

Import the video file into Audacity (or audio, if you already have it as a separate file).

If the channels/tracks aren’t split already (in the MKV file I had, they were), split all channels to mono.

Keep channels 1 and 2 (remove 3, 4, 5 and 6). NB: apparently in some cases channel 3 should be kept instead of 2 – check them to be sure you keep the good one. In my case, the audio track visualizations showed that track 3 was obviously too different from track 1 to be the other side, so track 2 was good.

I’m not sure it’s mandatory but it doesn’t cost anything to do anyway: merge the 2 tracks you kept into one stereo track. To do so, select both, click one of the tracks’ drop-down menu and select “Make stereo track”. If you have trouble finding it, here’s a video: https://www.youtube.com/watch?v=qz23hdW9sWc

Export in whatever format you want. As of today, Audacity can’t export in Opus, so I chose to export in FLAC, and then I used fre:ac to convert from FLAC to Opus.

Source (for more details and some screenshots): http://forum.videohelp.com/threads/336694-Simple-Guide-How-to-convert-DD5-1-AC-3-448-640-to-stereo
Also, for the reverse operation (stereo to DD5.1, which seems quite pointless to me though, but still interesting to read): http://forum.videohelp.com/threads/335904-How-to-Convert-2-channel-stereo-wave-into-DD5-1-AC3-448-AC-640

Posted in multimedia, open source.


[R] How to install FunNet from source (on Linux, sorry for Windows…)

FunNet was removed from CRAN to due import conflicts, but thankfully still is available from the archives. That makes it a bit harder to install it, yet still fairly easy on Linux.

First, install system dependencies. If you’ve already installed other R packages, you’ll have the usual development stuff which I don’t remember (gcc, g++, etc I assume). To this, you’ll have to add the dependencies of the Cairo R package, which are the Cairo software itself and some development library for the X server:
apt-get install libcairo2-dev libxt-dev
(NB: for the latter, it may be different depending on your distribution, see also this post on Stackoverflow)

With this done, you’re ready to head on to R. Just maybe first grab the latest FunNet source:
wget http://www.cran.r-project.org/src/contrib/Archive/FunNet/FunNet_1.00-12.tar.gz

Now in R, install dependencies:
install.packages('ade4')
install.packages('sna')
install.packages('Cairo')

And finally the installation of FunNet should work now:
install.packages('FunNet_1.00-12.tar.gz')
(to run this, make sure your R working directory is where you downloaded the file, otherwise adapt the path of course)

And voilà, congratulations, you now have FunNet, and it should work ^^

Last but not least though, the user manual. I haven’t managed to figure out how to build the help PDF so far, however something worked nice for me on Windows (yeah my setup is Windows on my workstation, Linux on my servers): you can just go to the folder where the package (aka “library”) got installed on Linux (if you don’t install it as root, it should tell you during the install and this should be under something like ~/R/x86_64-pc-linux-gnu-library/[version]/FunNet), then download the whole FunNet folder and put this into your R library folder on Windows. That won’t make you able to run FunNet (probably not to load the package either), however if you use RStudio you’ll be able to browse the help files from there. You’re welcome ;)

Posted in R (R-project).


How to create global variables in Titanium

The first and obvious way to create a global variable is to initialize it straight from the root in app.js. The usual

var myGlobalVar1 = 'this';

when it is placed out of any brackets.
I actually saw a seemingly official sample application with a comment in app.js saying something along the lines “define your global variables here”. It seems like it should work great, and for me it did… until I implemented notifications using gcm.js.
For some reason, when a gcm.js notification is clicked to open the application, if the application wasn’t already running in the background it will crash because all global variables defined in app.js will be defined locally only (see for instance this post on Appcelerator Q&A). I’m not sure what happens, but my best bet is that somehow gcm.js or the functions it uses launch app.js as some kind of local object, so whatever is defined in it in this context is local and not global as expected.

Anyway, so I needed a more reliable way to create a global variable.
A number of options are suggested in the following posts:

Some involve adding includes at the beginning of every file, and then I wonder how a modification from one view might modify the value in another one. The method I found the most convincing is to attach your wanted global variable to an already existing, guaranteed global variable, for instance Ti.App. Apparently this isn’t a “recommended” way, but it’s a natural feature of JavaScript so should be fairly future-proof.

So, instead of

var myGlobalVar1 = 'this';

we’ll now use

Ti.App.myGlobalVar1 = 'this';

and voilà. The only problem now is that you variable names are quite longer. Personally I even use

Ti.App.myappGlobal={};
Ti.App.myappGlobal.myGlobalVar1 = 'this';

so that if by any chance Titanium decides to rename Ti.App I won’t have any issue to automatically replace all “Ti.App.myappGlobal” with something else.

Update (2014-12-16): sadly, apparently this trick doesn’t work to create global functions on iOS… FFFS

Update (2014-12-23): I finally found a workaround: if variables and/or functions are created in a separate file, which is then included into app.js using Ti.include(), then they are properly registered as global. The big problem with this solution is that Ti.include was deprecated in Titanium 3.3.0 so I’m afraid it might get removed in a not too distant future :s

Posted in programming.

Tagged with .


[R] Solving “unused arguments (length = 4, lambda = 0.5)” error in kernlab

I recently got this puzzling error from the kernlab package, in a script that used to work really nice before:

Error in laplacedot(length = 4, lambda = 0.5) : 
  unused arguments (length = 4, lambda = 0.5)

Switching method didn’t help, for instance with a radial basis kernel instead of the laplacian one:

Error in rbfdot(length = 4, lambda = 0.5) : 
  unused arguments (length = 4, lambda = 0.5)

Apparently someone asked that on Inside-R and Stackoverflow, but didn’t care to share their solution beyond “I figured out that it’s all because of the format xtrain and ytrain”.

Well I eventually figured that out too, it turns out xtrain must be a matrix, so the fix is as simple as changing this:
svm.kernlab.mdl = ksvm(Xtrain, as.factor(ytrain),kernel="laplacedot");
into this:
svm.kernlab.mdl = ksvm(as.matrix(Xtrain), as.factor(ytrain),kernel="laplacedot");
Of course, package maintainers could do the conversion themselves, or at least provide meaningful error messages…

I use this code in a classifier wrapper in R package mc-r, currently under development and accessible at Google Code and Bitbucket:
https://code.google.com/p/mc-r/
https://bitbucket.org/patheticcockroach/mc-r/src

Posted in R (R-project).


Comment bloquer les pubs sur OVS…

…et (surtout) comment contourner les protections antipub

(NB: exceptionally, this article is written in French because it’s targeted at a French, non-English speaking audience – sorry for the inconvenience)

Je comprends bien que la pub soit nécessaire au financement de certains sites (quoique, comme certains le soulignent à juste titre, “ce qu’elle nous fait économiser on le repaie trois ou quatre fois dans nos courses”), néanmoins certains sites abusent carrément. Du coup, de plus en plus de gens bloquent les pubs (si vous êtes là vous en faites probablement partie… à moins que vous ne soyez au contraire un vendeur de temps de cerveau disponible :p ). Et du coup, de plus en plus de sites ajoutent une détection d’anti-pub à des fins plus ou moins nobles allant d’un simple rappel “yo, tu bloques mes pubs mais si tu m’aimes ça serait cool de désactiver ton AdBlock juste pour moi” plus ou moins discret ou intrusif (j’en profite pour glisser le mien, mes régies pubs sont très non-intrusives et marchent au Bitcoin – voilà c’est fait ^^) à un bien moins sympa blocage complet du site, aka prise en otage.

OVS est un cas intéressant car d’une part ils cumulent les défauts (plein de pubs partout, de régies intrusives genre Google, et un blocage du site en cas d’antipub) et d’autre part ils modifient _très_ souvent leur protection anti-anti-pub (ce qui est d’autant plus amusant qu’en contraste le site ne bénéficie à peu prêt jamais de mises à jour dignes de ce nom), faisant de son contournement un mini-challenge régulièrement rafraîchi :)

Bref, trève de blabla, voici ma première méthode, qui marche contre la contre-mesure du jour: installez Ghostery et désactivez AdBlock pour OVS. Ghostery est une extension relativement proche d’AdBlock, sauf qu’au lieu de bloquer les pubs à partir d’expressions régulières, elle bloque les trackers à partir d’une liste noire qui ratisse très large. Après l’installation de Ghostery, n’oubliez pas bien sûr de le configurer pour bloquer lesdits trackers.
NB: pour les fans de libre, ça pourrait valoir le coup d’essayer avec Disconnect.me ou autre équivalent (si vous en connaissez, n’hésitez pas à les mentionner en commentaire)

Bon, c’est un peu court, je vous avouerai que j’avais créé un script Greasemonkey pour éviter de désactiver AdBlock mais que lors de mes tests ultimes avant la rédaction de ce post je me suis rendu compte que la solution Ghostery seul marche (ce n’était pas le cas hier, d’où la création du script Greasemonkey). Si certains préfèrent vraiment Greasemonkey, voici le script (lien de téléchargement direct):

// ==UserScript==
// @name        	OVS anti anti-pub
// @namespace   	OVS_anti_anti_pub
// @description 	Kill anti-adblocker on OVS
// @include     	http*://*.onvasortir.com/*
// @version     	1
// @encoding		UTF-8
// @grant       	none
// @author		PatheticCockroach - http://www.patheticcockroach.com
// @license		MIT License
// @url			http://notepad.patheticcockroach.com/4120
// @updateURL		http://img.patheticcockroach.com/01/gms/OVS_anti_anti-pub.user.js
// ==/UserScript==

var dummyAdDiv = document.createElement('div');
dummyAdDiv.id = 'my-smartadserver';
document.body.appendChild(dummyAdDiv);

Pour mémoire vu que ça change vite, le code anti-anti-pub du jour est:

$(window).load(function(){
if (!(document.getElementById("my-smartadserver")))
document.location='ovsadblock.php';});

Tout ce que fait le script, c’est recréer un élément d’identifiant “my-smartadserver”, qui est un élément supprimé par AdBlock, et sans doute simplement vidé par Ghostery. Voilà voilà, amusez-vous bien… jusqu’au prochain blocage, mais sans inquiétude car on trouvera bien autre chose ;)

À propos d’autres choses, quelques billets ou posts intéressants sur le même sujet:

Posted in privacy, programming.


[Titanium] How to detect window orientation (portrait vs landscape) at start-up

Titanium provides a simple way to detect window orientation, Titanium.UI.Window.orientation, but it seems to initialize late. In an application I’m developing, I needed to check the window orientation right at start-up, more specifically I used this:
if(Titanium.UI.Window.orientation==Titanium.UI.PORTRAIT) {stuff}
but this didn’t seem to work.

Running a simple
console.log(Titanium.UI.Window.orientation)
revealed that the variable sadly is undefined at that stage (TBH, I didn’t check if it was defined later since that’s not where I need it).

So I made a custom function, based on window size, which turns out to be defined early enough for me. Here is the function, quite obvious, really:
var isPortrait = function(){
return (Ti.Platform.displayCaps.platformHeight > Ti.Platform.displayCaps.platformWidth);
};

Then just call it with isPortrait() to get a boolean with value true if the window is oriented in portrait and false if it’s oriented in landscape.

Note that I only needed to make the difference between portrait and landscape, I don’t really have an idea to make the difference between properly oriented and upside-down portrait, or between left of right landscape, as the Titanium.UI.Window.orientation property offers (its possible values are: Titanium.UI.LANDSCAPE_LEFT, Titanium.UI.LANDSCAPE_RIGHT, Titanium.UI.PORTRAIT and Titanium.UI.UPSIDE_PORTRAIT)

Posted in programming.

Tagged with .


How to import a SAS database into R (without SAS)

Info on this was unusually hard to find, mostly because of all the noise generated by tutorials to convert data from SAS to R while using SAS in the process (apparently SAS doesn’t make it that trivial to export a simple CSV file). This makes for an interesting read though, so if you feel like getting an interesting headache, be my guest.

If you just want to import a SAS file into R, without the need to own a copy of SAS, luckily someone eventually made a package for this, more specifically sas7bdat, by Matt Shotwell.

Very simple to use, syntax is just:
myDataFrame=read.sas7bdat(theDamnSasFile);

A life-saver, even though it reportedly doesn’t work with all SAS files: it still works with most (and it worked with mine ^^). Last but not least, it doesn’t even have dependencies, and is quite tiny (321 kB). Tested today on R 3.1.2. Note that it’s quite much slower than reading a CSV file, so maybe you’ll want to import your SAS file, and then save it as CSV if you plan to read it often in the future.

Posted in R (R-project), statistics.