Hacks

Speed up WordPress get_posts and query_posts functions

While working on a WordPress theme, I noticed a low MySQL query cache hit rate. There were a lot of SQL_CALC_FOUND_ROWS queries that were not cached and were slowing down the database.

It appears WordPress uses SQL_CALC_FOUND_ROWS in most queries in order to implement pagination. Even when you don’t need pagination at all. SQL_CALC_FOUND_ROWS tells MySQL to do additional work to count the total matching rows and this can make a lot of difference if you have a big archive.

By inspecting WordPress 3.x source code I found an undocumented parameter that can be used with get_posts and query_posts functions. The parameter is named no_found_rows and it accepts boolean values. It tells WordPress not to count the total rows. Here’s a usage example:

get_posts('no_found_rows=true&cat=1&numberposts=1');

Hope this will help WordPress developers around the world lower their carbon footprint.

A more stable MySQL with HAProxy

If you administer a MySQL server chances are you’ve seen it go astray. A some point in time for no apparent reason, maybe for a traffic spike, the number of running queries starts snowballing until MySQL eats 100% of your CPU grinding your whole server to a halt. In the context of this article let’s just call this pattern The Snowball Effect.

The Snowball Effect can be caused by slow queries and locking issues especially on MyISAM tables. After you’ve done your homework and optimized your queries, using better indexes and tweaking MySQL configuration, there’s still a little detail, one that doesn’t get noticed: you reduced the probability of triggering The Snowball Effect. It can still happen if the load on database ever increases. For some applications and datasets you may never be able to optimize enough to prevent the Snowball Effect from happening.
Continue reading »

Firewire Mini DV cameras on Linux

Yesterday at the office I found a small Sony camera. Obviously I had to get it working on Linux at all costs. And now that I found how I thought I’d share this bit of knowledge. The exact model is DCR-TRV60e but this post possibly applies to all Mini DV cameras.

You could use Kino and be done with it, but what if you want to automate recordings or broadcast a live stream? Let’s do it the CLI way.

The keyword here is dvgrab. It is a command line tool that talks to the camera and grabs the DV stream. Dvgrab can stream to a file or to the standard output. Let’s install dvgrab:

sudo apt-get install dvgrab

Now let’s load the firewire kernel modules:

sudo modprobe raw1394 ieee1394 video1394 ohci1394

In theory we could just use dvgrab and pipe the stream to any other program through UNIX pipes like this:

sudo dvgrab - | mplayer -

For some reason this does not work. Maybe it’s a bug, maybe I’m doing something wrong… So I hacked together a little script that uses UNIX fifos. Dvgrab writes to the fifo and mplayer reads from it. You can replace mplayer with any other tool such as VLC or ffmpeg and do lots of things.

DV_FIFO=/tmp/dvfifo
mkfifo "$DV_FIFO"
dvgrab -f dv2 - > "$DV_FIFO" &
mplayer "$DV_FIFO" -ni -cache 1024
killall dvgrab
rm "$DV_FIFO"

Dirette Rai.tv senza SilverLight o Moonlight


Aggiornato al 30 novembre 2012.

Installare Python e VLC, scaricare lo script e lanciare con il nome del canale come parametro. Ad esempio per vedere RaiUno:

python rai.py RaiUno

Lo script è il frutto di un lavoro collettivo. In particolare di Giulia, Wilder, Luker, skin79, Luke88, Pietro, mitm, Andrea, lufuscu e molti altri. Tutti sono incoraggiati a creare applicazioni e script più completi, possibilmente rilasciandone i sorgenti.

Invito tutti gli sviluppatori a spostarsi su Launchpad, lì c’è una mailing list e un repository per i sorgenti.

———————————————–
Quello che segue è solo per ricordare i tempi d’oro in cui bastava cambiare lo User Agent ;)

Ieri volevo vedere in diretta la puntata di PresaDiretta su RaiTre sul sito Rai.tv. Mi ha chiesto di installare Moonlight, cioè Silverlight per Linux. Ma naturalmente non funzionava, non so perché. Allora ho provato a mettere Silverlight su un Mac, ma nemmeno questo ha funzionato. La mia ira contro il servizio pubblico televisivo mi ha dato le energie necessarie a decifrare il codice delle loro pagine. Senza scendere nei dettagli, ecco come potete vedere le dirette Rai con il vostro media player preferito, ad es il VLC.

Mi raccomando selezionate attentamente i programmi che vale la pena di vedere, la stupidità può dare assuefazione. Per quanto mi riguarda: Report e PresaDiretta.

Aggiornamento 25 Feb

Hanno messo dei controlli sulla stringa di identificazione del browser (o del player) che si collega allo stream. Mi chiedo se per un servizio pubblico sia eticamente accettabile ricorrere a simili trucchetti, a voi l’ardua sentenza… Fra l’altro ti mostrano una sigletta che augura la “Buona Visione”, sembrerebbe quasi una provocazione. Dobbiamo camuffare il nostro player con un identificativo “da browser”:

Per il VLC: Andare su “Strumenti” => “Preferenze” e in basso dove c’è “Mostra le impostazioni” cliccare su “Tutto”. Quindi tra la selva di opzioni andare su “Ingresso/Codificatori” => “Moduli di accesso” => “HTTP(S)”. C’è un campo “User Agent HTTP”, settiamolo a:

Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.6) Gecko/2009020911 Ubuntu/8.10 (intrepid) Firefox/3.0.6

Aggiornamento 12 Gennaio 2010

Allora, alcuni stream non funzionano più. I nostri furbetti della RAI hanno escogitato un nuovo trucco per costringerci a usare il Silverlight. In pratica bisogna usare un header HTTP non-standard (lo dico per i più tecnici). Ho una soluzione rapida per Linux e Mac. Su Linux, aprite il terminale e scrivete:

wget --header="viaurl: www.rai.tv" [qui la URL dello stream] -O - | vlc --http-user-agent="Linux" -

Sul Mac potete usare questo che usa il curl al posto del wget (che non è presente sul mac). Aprite il terminale e scrivete:

curl -H "viaurl: www.rai.tv" [qui la URL dello stream] | /Applications/VLC.app/Contents/MacOS/VLC --http-user-agent="Linux" -

Mi dispiace per gli utenti Windows, per ora non ho niente di user-friendly da offrire. Che ne dite di passare a Ubuntu?

Aggiornamento 14 Febbraio 2010

Lo hanno già scritto in molti nei commenti, non è più possibile accedere agli stream da VLC con i comandi qui sopra. Di più non è più possibile vedere le dirette Rai su Linux, anche su rai.tv con MoonLight. Anticipo subito che stavolta non ho intenzione di fornire soluzioni (che comunque per ora non ho) perché ciò richiederebbe la decompilazione di codice offuscato e la sua reimplementazione. Credo che questa operazione sia legale in Italia ma non credo sia una buona idea esporsi. Invito tutti, soprattutto gli utenti Linux, a comunicare alla RAI questo disservizio.

Info tecniche

Stavolta non si sono limitati a stupidi controlli su parametri HTTP ma hanno sviluppato un sistema di autenticazione. La creazione del token avviene nel codice Dot Net nella libreria Rai.Client.Services.Security.dll che viene scaricata in /tmp/mono*/ . La libreria è offuscata usando SmartAssembly. E’ interessante notare che la console di MoonLight su Linux dà errore proprio nel caricamento di questa dll, quindi è probabile che Mono non riesca a caricare la DLL proprio a causa delle tecniche di offuscamento usate. Dunque la RAI ha sacrificato gli utenti Linux proprio per contrastare la visione degli stream al di fuori del browser. Basta aprire la DLL con un editor esadecimale per vedere la url della CGI che viene chiamata per ottenere la data corrente lato server. Probabilmente la DLL usa quella data (e altro?) per generare il token “ttAuth” che poi viene passato nella richiesta POST verso le URL degli stream.

Soluzione per Linux

Habemus scriptinus! Io non ci sarei mai arrivato da solo. Ma Giulia, Wilder, Pietro e il mio amico segreto hanno contributo a questo piccolo capolavoro. Per la verità Giulia ha avuto i 2 colpi di genio fondamentali: Base64 e la maschera con i byte in crescendo da applicare all’id + la data. Massima ammirazione! Ecco lo script da lanciare con la URL dello stream come parametro. Ad es:

rai.sh http://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=983

L’ideale è scaricare lo script in ~/bin, cioè nella directory bin della propria home.

How to access a remote machine at work from home using SSH

I just found out how to mount the home directory of my work PC at home, bypassing the company firewall.

First of all password authentication is tedious and won’t work in batch scripts so we need to create a RSA key on the work pc:

ssh-keygen
scp ~/.ssh/id_rsa.pub [myhomeuser]@[homehost]

Now log at home and add the work pc public key to your authorized keys:

cat id_rsa.pub >> .ssh/authorized_keys2

Now let’s connect to the home pc from the machine at work using ssh.

ssh  -f -C -o BatchMode=yes -R [anyport]:localhost:22 -l [myhomeuser] -N [homehost]

The -R argument does the trick by forwarding to the work pc (port 22) all traffic on the loopback interface (on a given port) of your home computer. Refer to the SSH man for info.
-o BatchMode=yes makes the ssh client at work try to contact the remote server at home every 300 seconds in order to prevent the firewall from closing the connection. If you get a “Connection reset by peer” after a period of inactivity, try -o ServerAliveInterval=[seconds].

Let’s move to the home pc. In order to mount the remote pc on the filesystem you’ll need SSHFS, if you’re using Ubuntu follow this great How-to.

First let’s create a directory for the mount point:
mkdir /home/[myhomeuser]/workpc

Make sure the FUSE kernel module has been loaded:

sudo modprobe fuse

Now mount the work pc home directory:

sshfs -C -p [anyport] localhost:/home/[myworkuser] /home/[myhomeuser]/workpc

Make sure that the port number is the same specified in the ssh command at work.

If you need to unmount just type:

sudo umount /home/[myhomeuser]/workpc

Done. Now cd to ~/workpc and type one of the most satisfactory ls of your life.

UPDATE: What happens if any of the two machines reboots or the network goes down? The tunnel dies.
You may use this simple Bash script as a cronjob installed on the work pc. Thanks to Fabrizio for pointing this out!

#!/bin/bash

HOMEPC=[homehost]
HOMEUSER=[homeuser]
HOMEPORT=[homeport]
# Path of a file used to test the connection
HOMEFILE=[homefile]

ssh $HOMEUSER@$HOMEPC scp -P $HOMEPORT $HOMEFILE localhost:/tmp/
if [ $? != 0 ]; then
  echo Starting SSH tunnel at `date`
  ssh -f -C -N -o BatchMode=yes -R $HOMEPORT:localhost:22 -l $HOMEUSER $HOMEPC
fi

Type crontab -e and add something like this:

0,20,40 * * * * /home/[user]/tunnel.sh

Turning Blogger into a RESTful data source

I wrote a Blogger template that generates machine-readable XML.
This is great if you need to integrate a Blogger-based blog with the rest of your site.
I’m using XSLT to process the generated XML, but any programming or scripting language will do.

Here’s the Blogger template. I suggest you disable the “Enable float alignment” option in the “Formatting” tab to get cleaner data. Enjoy!

JSTL patch

This is a patched version of the Jakarta Standard Tag Library
which implements the JSTL 1.1 specification. This patch makes the XML tags run 100 times faster. I wrote almost no code, I just reverted the XPathUtil class to a previous version and managed to compile the whole thing.

Originally the Standard Taglib used the Jaxen XPath processor. With version 1.1 the project switched to Xalan, decreasing performance by a factor of 100. At my company we chose to use JSTL and we’re really happy about it. But our sites must work now, so I put together this patched version. I hope to be able to use the official version very soon. In the meanwhile, if you’re using JSTL in a production environment give this version a try.

I submitted this patch to the Standard Taglib developers but it was refused because it implies a dependency on Jaxen. Here’s the original thread on the taglibs-dev at jakarta.apache.org mailing list.

To install over an existing webapp just drop in the standard-*.*.*-patched.jar and remove standard.jar.
You also need jaxen-*.*.jar from the Jaxen project.

Requirements

Download

Get in touch!

For technical support, bug reports and feature requests you can post in the Forums.

You can contact me via email on flavio.tordini@gmail.com or ask me a quick question on Twitter.

Please, don't use Twitter for licensing issues and things that will ultimately require your email address.