Merge Strava’s GPX exported files

Last Weekend something happened during a morning ride on my bike with some friends and my GPS device turned off for no reason. When I turned it back on I didn’t have the choice of continuing a previous ride and I had to create a new ride.

When I got home and tried to upload the information the Strava I couldn’t find any feature which could let me merge rides and fixe the issue. Instead I ended up having two different rides which really annoyed me.

I started googling around and found someone suggesting that I export the rides and merge the contents of the files. They also suggested that this could be done directly concatenating the files which isn’t true. The trick here is to extract the tracking data from the files (GPX files exported from Strava are XML based) and using the first one as the metadata template.

This was the result of a very simple GPX merger:

#!/usr/bin/env php -q
* StravaMerger © David Gouveia -
* Simple script to merge tracking data from Strava's exported GPX files.
* The backtrack_limit is there because some files could not be parsed due to their size.
* Feel free to raise the limit but be carrefull not to cross the limit.
* Instead of using regex, I could have used a XML cursor to overcome the backtrack limit
* but either I would have to use the php_xml extension or build my own parser.
ini_set("pcre.backtrack_limit", "10000000");
if ( !trim( $argv[1] ) || trim( !$argv[2] ) || sizeof($argv) < 4 )
               die("Usage:\n$argv[0] file1.gpx file2.gpx <fileN.gpx> output.gpx\n" );
$segments ="";
for($i = 1; $i < sizeof($argv) - 1; $i++)
        echo "Processing $argv[$i] ...";
        if (!is_file( $argv[$i] ) ) die( "Invalid file: $argv[$i]\n" );
        $gpx = file_get_contents( $argv[$i] );
        if ( $i == 1 )  preg_match( "/^(.*?)<trkseg>.*?<\/trkseg>(.*?)$/is", $gpx, $metadata );
        preg_match("/<trkseg>(.*?)<\/trkseg>/ims", $gpx, $matches);
        if( trim( $matches[1] ) )
                $segments .= $matches[1];
                echo "[OK]\n";
                echo "[FAIL]\n";
$output_file = $metadata[1] . "<trkseg>" . $segments . "</trkseg>" . $metadata[2];
file_put_contents($argv[sizeof($argv) -1], $output_file) or die( "Unable to create destination GPX\n" );
print "File " . $argv[sizeof($argv) -1] . " successfully created.\n";

I’m going to put an online version of this script to make it easier to use. ;-)

Como remover a barra de notificações da IOL (Push by IOL)

Não sei o que acham do sistema de notificações dos portais da rede IOL mas eu simplesmente não SUPORTO. É extremamente intrusivo, não permite ser desactivado e pior que tudo está sistematicamente a repetir-se (basta fazer um refresh da página e já lá está novamente! *g*).

Felizmente há várias formas de acabar com esta praga, e uma delas é usar o fabuloso plugin AdBlock Plus. Nada mais simples que abrir as opções do plugin no vosso browser favorito (Espero que seja o Firefox ou Chrome :p) e acrescentar as seguintes regras nos filtros:


Et voila! A caixa de noticias irritante desapareceu! :D

How to convert video to animated gifs from a linux console


Today I’m going to show you a very small script that allows you to convert any video (as long as it is supported by mplayer) to a GIF.

Required tools:

* mplayer

* convert


mplayer is popular media player available for multiple operating systems that support a wide range of video formats. The convert tool is an utility that lets you convert between multiple image formats among other definitions.  Since the mplayer takes screenshots using jpeg format, we need to use the convert tool to do the convertion to aGIF format.


Copy the following code, save it to a file and change its permissions (chmod a+x) and you are ready to roll :)



shopt -s nocaseglob
if [ ! -d "$TMPDIR" ]
        mkdir $TMPDIR
\rm $TMPDIR/* &> /dev/null
if [ $# -lt 3 ]
        echo -e "Usage: $0    []\nExample:\n$0 00:15:11 10 myvideo.avi 320:240"
        exit 1
if [ -n "$4" ]
echo "Generating screenshots. Please be patitent..."
mplayer -ao null -ss $1 -endpos $2 $3 -vo jpeg:outdir=$TMPDIR/ -vf $SCALE &amp;&gt; /dev/null
if [ -f $TMPDIR/00000001.jpg ]
        echo "Finished generating frames. Assembling the animated GIF..."
        convert -delay 5 $TMPDIR/*.jpg $TMPDIR/output.gif
        echo "Done! Please check the $TMPDIR/output.gif"
        exit 0
        echo -e "Oops\! Something went wrong and the frames were not generated. Check your parameters\!"
        exit 1

Just try it and let me know ;-)

How to hide the taskbar under Windows CE using VB.Net

If you do a quick search in google, you can find several links which explain how to hide the taskbar under Windows CE. Unfortunately, almost everything that you can find either is directed to unmanaged languages like C++ and VB6 or is based on C# language.

Here goes a quick snippet that do the same thing using VB.Net:

    Public Const SW_HIDE As Integer = &amp;H0
    Public Const SW_HIDEWINDOW As Integer = &amp;H0
    Public Const SW_SHOWNORMAL As Integer = &amp;H1
    Public Function FindWindow(ByVal className As String, ByVal windowName As String) As IntPtr
    End Function
    Public Function ShowWindow(ByVal hWnd As IntPtr, ByVal cmdShow As Integer) As Boolean
    End Function
    Public Sub HideMyTaskBar()
        Dim taskBarHWnd As IntPtr = FindWindow("HHTaskBar", String.Empty)
        ShowWindow(taskBarHWnd, SW_HIDE)
    End Sub

Now just call the HideMyTaskBar() sub and that’s it! :)

.Net DynDNS client updater class

The following code is a .Net class that can be used to update a dyndns host alias. It is pretty simple to use. All you have to do is instantiate the class passing the username/password/host to the constructor.

This is the class:

' .Net DynDNS client class by David Gouveia - me[_@_]
' Feel free to use it as long as you don't remove the credits :o)
Imports System.Net
Imports System.IO
Public Class DynDnsUpdater
    Private _username, _password, _host, _ip As String
    Public Enum UpdateStatus
    End Enum
    Private Function checkip() As String
        Dim ipRegex As New System.Text.RegularExpressions.Regex("[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}", System.Text.RegularExpressions.RegexOptions.Singleline)
            Dim UpdateClient As System.Net.HttpWebRequest = WebRequest.Create( _
            New Uri(""))
            UpdateClient.Timeout = 15000
            Dim response As WebResponse = UpdateClient.GetResponse()
            Dim content As Stream = response.GetResponseStream()
            Dim readstream As New StreamReader(content, System.Text.Encoding.Default)
            Dim IpAddress As String = readstream.ReadToEnd
            If ipRegex.IsMatch(IpAddress) Then
                Return ipRegex.Match(IpAddress).Groups(0).Value
                Return Nothing
            End If
            Return Nothing
        End Try
    End Function
    Public Sub New(ByVal username As String, ByVal password As String, ByVal host As String)
        _username = username
        _password = password
        _host = host
    End Sub
    Public Function update() As UpdateStatus
        _ip = checkip()
        Dim UpdateClient As System.Net.HttpWebRequest = WebRequest.Create( _
        New Uri("" + _host + "&amp;myip=" + _ip))
        UpdateClient.Credentials = New NetworkCredential(_username, _password)
        UpdateClient.PreAuthenticate = True
        UpdateClient.UserAgent = ".Net DynDNS Updater Client"
        UpdateClient.Timeout = 15000
        Dim response As WebResponse = UpdateClient.GetResponse()
        Dim content As Stream = response.GetResponseStream()
        Dim readstream As New StreamReader(content, System.Text.Encoding.Default)
        Dim DynDnsResponse As String = readstream.ReadToEnd
        If DynDnsResponse.Contains("good " + _ip) Then
            Return UpdateStatus.SUCESS
        ElseIf DynDnsResponse.Contains("nochg " + _ip) Then
            Return UpdateStatus.NOCHANGE
            Return UpdateStatus.FAIL
        End If
    End Function
End Class

And this is how you can use it:

Dim updater As New DynDnsUpdater("dyndns username", "dyndns password", "hostalias")
        If updatert.update() <> DynDnsUpdater.UpdateStatus.FAIL Then
        End If

have fun :-)

Algoritmo para validar NIB (Número de Identificação bancária).

Depois do último algoritmo para validar o contribuinte, aqui fica uma versão para validar o NIB.

function isValidNib($nib){
$result = "";
if(strlen(intval($nib)) != 21)
return "NIB INVALIDO (Standard: 21 algarismos. Introduzido: " . strlen(intval($nib)) . ")";
$nnib = str_split(intval($nib));
for($i=0; $i&lt; 19 ; $i++){
        $result = (($result + $nnib[$i]) * 10) % 97;
$result = 98 - (($result * 10) % 97);
if($result &lt; 10)
        $result = "0" + $result;
if(substr($nib, 19, 2) != $result)
        return "NIB INVALIDO";
        return "NIB VALIDO";

Se preferirem podem trocar o texto enviado no retorno das funções e utilizar um boleano true/false.

EDIT: Agradecimentos ao Nuno Cancelo pela dica de optimização enviada! :)

Algoritmo para validar NIF (Numero de contribuinte)

Já tenho visto por aí vários algoritmos para validar o numero de contribuinte, mas não vi um feito em PHP.

Disponibilizo aqui um pedaço de código em PHP para que possam incluir nos vossos serviços.

function isValidNif($nif){
//Verificar se e' um numero e se e' composto exactamente por 9 digitos
if(!is_numeric($nif) || strlen($nif) != 9) return false;
$narray = str_split($nif);
//verificar se o primeiro digito e' valido. O primeiro digito indica o tipo de contribuinte.
if($narray[0] != 1 &amp;&amp; $narray[0] != 2 &amp;&amp;  $narray[0] != 5 &amp;&amp; $narray[0] != 6 &amp;&amp; $narray[0] != 8 &amp;&amp; $narray[0] != 9)
        return false;
$checkbit = $narray[0] * 9;
for($i=2; $i&lt;=8; $i++){
        $checkbit += $nif[$i-1] * (10 - $i);
$checkbit = 11 - ($checkbit % 11);
if($checkbit &gt;= 10) $checkbit=0;
if($nif[8] == $checkbit) return true;
echo "$nif - $checkbit";
return false;

Google analytics MOD to ClipBucket.

Summary: with this mod you will be able to insert any script into your clipbucket. I’m using it to manage google analytics.

1st – Open styles/cbv2new/layout/global_header.html. Find:

<!-- Setting Template Variables -->
    	$_COOKIE['current_style'] = 'grid_view';

Add below:

<!-- Google Analytics -->;

2nd – includes/common.php. Find:


Add below:

$Smarty-&gt;register_function('show_analytics', 'show_analytics');

3rd – Open includes/functions.php. Find:

	 * Function used to load clipbucket title
	function cbtitle($params=false)

Add above:

	* Function used to load Google Analytics - me( at )
	function show_analytics()
		global $Cbucket;
		// code to convert html entities back useful code.
		echo base64_decode($Cbucket-&gt;configs['google_analytics']);

4th – Open admin_area/main.php. Find:


Add above:



	$value = mysql_clean($_POST[$field]);

Add above:

	if($field == 'google_analytics')
		$value = base64_encode($_POST['google_analytics']);

(the “else” MUST be in the line immediately above “$value = mysql_clean($_POST[$field]);”).

Finally, open /admin_area/styles/cbv2/layout/main.html. Find:

              <td valign="top">Meta Description</td>
              <td valign="top"><textarea name="description" id="description" cols="45" rows="5">{$row.description}</textarea></td>

Add below:

              <td valign="top">Google Analytics</td>
              <td valign="top"><textarea name="google_analytics" id="google_analytics" cols="45" rows="5">{$row.google_analytics|base64_decode|html_entity_decode}</textarea></td>

Done! You shoud see another option under Web Settings.

Tested under ClipBucket 2.0.6.

PS: I’m using base64_encode/decode because I want to save the script as its original values and I need to avoid using functions like mysql_clean() to sanitize the code. By saving it as a base64 string I avoid potential malicious SQL injection problems. I’m sure there are other ways of doing it but this works OK (I think :p).

Script básico para NAGIOS para monitorização de Portas

Estive com uns problemas na empresa relacionados com o sendmail.
Quando nada fazia prever, o sendmail simplesmente crasha começando a recusar activamente todos os pedidos de envio de email.

Criei um script genérico para verificar se uma determinada porta de um servidor está a responder. Basta editar o endereço, porta e opcionalmente definir um timeout máximo para o pedido.

#!/usr/bin/php -q
    Check For Open Ports - David Gouveia
$address = '';
$port = 25;
$timeout = 5;  //Max time to wait before give up.
$checkport = fsockopen($address, $port, $errnum, $errstr, $timeout);
        print "CRITICAL: Host $address at port $port not responding!\n";
print "OK: Host $address at port $port is responding!\n";

Coloquem na pasta dos plugins e não se esqueçam de dar as permissões correctas (755).
Alternativamente podem passar o valor do IP e porta como argumentos via consola.

basta trocar isto :

    $address = ’′;
    $port = 25;

por isto :

    $address = $argv[1];
    $port = $argv[2]