‘ Open Source ’ Category

Share on Dropbox – Nautilus Script

View Comments // Written on May 07, 2010 // Open Source, programming

To install this script just download the file , place it under your home ~/.gnome2/nautilus-scripts , make it executable and then kill nautilus. Below are copy&paste instructions to install from terminal

cd ~/.gnome2/nautilus-scripts
wget "http://www.andreaolivato.net/Share on Dropbox"
chmod 755 "./Share on Dropbox"
killall nautilus

Please note that I manage duplicate files adding an incremental number to the name, after the full name (yep the extension too)
Below is the full source of the script, which is released under GPL v3 licence

#!/bin/bash
# Share on Dropbox
# Nautilus Script to share files or folder in one click
# Copyright (C) 2010  Andrea Olivato "andrea@olivato.me"
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see gnu.org/licenses/.

if [ -n "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" ]
then
	files=( $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS )
	for (( i=0; i<${#files[@]}; i++ ))
	do
		fileorfolder=`echo ${files[$i]} | awk '{split($0,a,"/"); print a[length(a)]}'`
		if [ -f ~/Dropbox/$fileorfolder ]
		then
			OK=0;
			N=0;
			while [ $OK -lt 1 ]
			do
				if [ -f ~/Dropbox/${fileorfolder}${N} ]
				then
					(( N++ ))
				else
					fileorfolder=${fileorfolder}${N};
					OK=1;
				fi
			done
		fi;
		mv ${files[$i]} ~/Dropbox/$fileorfolder
		ln -s ~/Dropbox/$fileorfolder ${files[$i]}
	done
else
	NAUTILUS_SCRIPT_CURRENT_URI=${NAUTILUS_SCRIPT_CURRENT_URI/file:\/\//}
	fileorfolder=`echo $NAUTILUS_SCRIPT_CURRENT_URI | awk '{split($0,a,"/"); print a[length(a)]}'`
	if [ -f ~/Dropbox/$fileorfolder ]
	then
		OK=0;
		N=0;
		while [ $OK -lt 1 ]
		do
			if [ -f ~/Dropbox/${fileorfolder}${N} ]
			then
				(( N++ ))
			else
				fileorfolder=${fileorfolder}${N};
				OK=1;
			fi
		done
	fi
	mv $NAUTILUS_SCRIPT_CURRENT_URI ~/Dropbox/$fileorfolderg
	ln -s ~/Dropbox/$fileorfolder $NAUTILUS_SCRIPT_CURRENT_URI
fi

This idea is not original, I took inspiration from the “Share on UbuntuOne” of ubuntu 10.4 and DropboxFolderSync for windows

Post your Google Buzz updates to Twitter with buzz2tw, a libre Perl script

View Comments // Written on Apr 10, 2010 // Open Source, programming

icon Post your Google Buzz updates to Twitter with buzz2tw, a libre Perl scriptSince Google Buzz was released I found it much more handy the Twitter or FriendFeed because it was always there, in my constantly-opened Gmail page. Nevertheless having so many contacts on twitter I could not move completely from one platform to the other, and I searched the internet for a post importer.

I already knew TwitterFeed so I tried giving it my Google Profile atom feed, but the result was terribly ugly: “Google Buzz” string was repeated a couple of times and there was too few space left for the post. My timeline looked like a spammer’s one.

So I decided to create my own importer, using Perl and a Mysql Database. I will guide you trough the whole programming process but, in case you’re impatient, below is the GIT repository and instructions to get it running in 2 minutes. The result is a nice and clean post, using goo.gl as url shortenere

GitHub Project Homepage : Buzz2tw Source Code
Quick Start guide : README
Quick Download : buzz2tw.pl
Mysql Structure : structure.sql

Screenshot 1 Post your Google Buzz updates to Twitter with buzz2tw, a libre Perl script

Below are 10 chapters of a step by step how-to which will guide you to completely understand the code I created. Every line of code is Libre Software released under GPL3 licence.

Chap 0 – Setting up the Database Structure

A database is essential to correctly manage the posts. In fact, to avoid duplicates, we always need to know which posts we already published on Twitter and which ones we still need to sync. We only need one table for this purpose, so it makes no difference at all if you create it on an existing database or you create a new one.

To create the table just login via command line to your database

mysql -p -u username databasename

then paste the following code and press Return

CREATE TABLE IF NOT EXISTS `buzzs` (
  `link` varchar(32) NOT NULL,
  PRIMARY KEY  (`link`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

As you should notice there’s just one string field in our table and it will contain the md5 hash of the link. The link, differently from title, time-stamp or description is the only field retrieved from Google atom feed which is unique and keeps being unique in time.

The purpose of the table is simple: every time we post a new article to twitter, we create the md5 hash of the Google Buzz link and then put the result inside the table. Every time we’re going to post a new update, we check the table first to be sure we’re not posting a duplicate.

If you don’t know how, or don’t want to, use the command line, feel free to import the SQL code via your preferred GUI (eg Phpmyadmin)

Chap 1 – User Configuration

The first row of a Perl script in an Unix-like environment has to be the path to the Perl interpreter, usually located in /usr/bin/perl or /usr/local/bin/perl. So, in my code you can read

#!/usr/bin/perl

This is very useful because as long as you make the script executable you will be able to launch it as follows

chmod +x ./buzz2tw.pl
./buzz2tw.pl

After the interpreter line and the licence, we’re going to declare some variables to simplify the configuration of the script. Comments in the code are self explaining, we just need the Google username, the Twitter access data and obviously the database connection parameters.

The only parameter you need to pay a bit more attention to is called “lmpost” and I used this to limit the number of posts to publish every time the script runs. Lets imagine, for example, that you’re starting the script for the first time. If you don’t limit the number of tweet, you will flood your timeline with a lot of posts. Using this limit you prevent too many updates to be posted simultaneously.

So below you can find an example code with fake parameters

# Google Buzz Username
my $bzuser = ""; # EG andrea.olivato

# Twitter username and password
my $twuser = ""; # EG andreaolivato
my $twpass = "";

# Database Configuration
my $dbhost = "localhost";
my $dbuser = "buzz2tw";
my $dbpass = "";
my $dbname = "buzz2tw";

# Running parameters
# lmpost: how many post publish for each execution of the script
my $lmpost = 3;

Chap 2 – System configuration

There are another couple of parameters we need to setup before proceeding with the “running” part of the script. Perl, as you should know, can be expanded by modules which are included via the USE routine. We need some of them for running the script easily.

First of all we need the mysql connection working. This is achieved by “using” the DBI module. Please note that you need to install the mysql driver for the DBI module using cpan or your distribution package manager.

For parsing the Google atom feed containing the posts we need the XML parser, provided by the XML::Simple module. Moreover we are going to make some HTTP calls, so we are using the LWP::UserAgent module.

Furthermore, we said we are going to store the md5 hashs of the links in our table, so we need the Digest::MD5 module. At last but not least, we declare we are using a Strict Perl syntax, to avoid stupid errors and correctly learn the language.

All this commands and requirements are performed by the following code

use strict;
use XML::Simple;
use LWP::UserAgent;
use DBI;
use Digest::MD5 qw(md5 md5_hex md5_base64);

At the end of this section, which we call a system configuration because it’s external to the running code but the end user is not required to change it, we declare the url of the atom feed containing Google Buzz posts. I did so because Google Buzz APIs are still in development and this url is subjected to changes. As you may notice, the url contains the previously declared “bzuser” variable.

my $url = "http://buzz.googleapis.com/feeds/".$bzuser."/public/posted";

Chap 4 – XML parsing and the article Cycle

The first thing our script needs to do is connecting to the Mysql database we set up before and keep the connection ready for our queries. The connection procedure is terribly easy thanks to the DBI module. Please note that we’re using our previously declared database configuration variables inside the connection string

# Connecting to the database
my $DSN = "dbi:mysql:database=".$dbname.";host=".$dbhost.";user=".$dbuser.";password=".$dbpass;
my $dbh = DBI->connect($DSN);

We can now proceed by downloading the feed from Google servers and start parsing it with our Xml::Simple module. To achieve such a result we first create a new Object for the connection

my $ua = new LWP::UserAgent;

then tell the object that we want to reach the $url using a GET request

my $req = new HTTP::Request GET => $url;

and finally that we want to store the whole response into a local variable called $content

my $content = $ua->request($req)->content();

Having the complete XML code stored into our variable, we can proceed by parsing it into an hash as shown below

my $xml = new XML::Simple (KeyAttr=>[]);
my $data = $xml->XMLin($content);

The “data” variable is now an hash containing the various nodes of the XML file. If you have a look at the XML tree you will notice that it’s made of several entries, each of which represents a single article. Each article has then some parameters, from which we are going to extract the plain text of the post and the link.

The next step is to cycle trough the XML, opening each article. To achieve so, we are going to use the foreach expression. Also we’ll setup a “limit” variable, which is needed to count how many articles we are writing. Here is the resulting code

# Cycling each feed post
my $limit = 0;
foreach my $item (@{$data->{entry}}) {
	# NEXT CODE HERE
	$limit++;
}

Chap 5 – Inside the cycle, each getting article info

The following code has to be inserted inside the cycle we previously started, and refers to the “item” variable which is now representing a single article imported from the XML. Because we setup a limiting variable and a counter (the “limit”), the first step of our cycle is to skip the cycle itself in case we exceeded the limit. Below is shown how to code this, using the NEXT statement, which is very similar to PHP continue

	# Skip if I already published too many posts
	next if($limit>=$lmpost);

Being sure we did not surpass the limit, we can continue with our parsing. As I said before, we can retrieve the information we want (text and link) directly from the item variable. Because the text that the atom feed returns is in plain format, it contains \n new line characters which would create ugly effects on our tweet. To avoid them, we are going to replace each \n char with a space using the Perl regular expression operator “~”

	# Getting content of the post and its link
	my $text = $item->{summary}->{content};
	$text =~ s/\n/ /gi;
	my $link = $item->{link}[0]->{href};

Chap 6 – Checking for duplicates

Wonderful! We got everything we need for our article. It’s now time to check for duplicates on our database. Using the connection we opened before we are going to perform a SELECT statement looking for the number of articles having the same link of the one we’re analyzing. To do so, we’ll hash the link using the md5 function as follows

	# Checking the link in the database. Don't want duplicate posts
	my $checkmd5 = "SELECT count(*) FROM buzzs WHERE link = md5('".$link."')";
	my $go_c = $dbh->prepare($checkmd5);
	$go_c->execute;
	my $fe_c = $go_c->fetchrow_array();
	$go_c->finish();

As you can see from the above code, the query is prepared, executed and then its results are stored in the fe_c variable. This fe_c variable is used to check if we found duplicates or not. Furthermore we are going to move the “$limit++;” expression inside the if statement we are realizing. In fact we don’t wan’t to skip after N cycles of articles but after N cycle of articles which we haven’t put in the database yet. So below you can find the new cycle structure.

# Cycling each feed post
my $limit = 0;
foreach my $item (@{$data->{entry}}) {

	# Skip if I already published too many posts
	next if($limit>=$lmpost);

	# Getting content of the post and its link
	my $text = $item->{summary}->{content};
	$text =~ s/\n/ /gi;
	my $link = $item->{link}[0]->{href};

	# Checking the link in the database. Don't want duplicate posts
	my $checkmd5 = "SELECT count(*) FROM buzzs WHERE link = md5('".$link."')";
	my $go_c = $dbh->prepare($checkmd5);
	$go_c->execute;
	my $fe_c = $go_c->fetchrow_array();
	$go_c->finish();

	# If no duplicates are found
	if (defined($fe_c) && $fe_c<1) {
		# MAIN CODE HERE
		$limit++;
	}
}

Chap 7 – Shortening the link

There are plenty of services offering API services to shorten links to post on Twitter. I chose goo.gl because I find it much more buzz-themed then the others. So, as the service is not properly public, gaining access to their API is not immediate. Searching on Google I found GGL Shortener, a 3rd party API service which connects to goo.gl APIs and returns the shortened url. Integrating with them is very easy, much more then creating a class to connect to goo.gl directly so I definitely preferred them.

To interface our script with their API system we just need to urlencode the destination link, make a GET request and retrieve the shortened url. Please note again that the following code has to be placed inside the foreach loop, inside the if checking for duplicates.

First of all, to urlencode the url exactly like PHP does, we need to perform a regular expression replacement, explained in the code below.

		# Urlencoding the link for GET request to the url shortener
		my $urlencodedlink = $link;
		$urlencodedlink =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg;

I found this regex here, all credits go to the original author.

Having our link urlencoded we can proceed performing another GET request and retrieving the answer into another variable.

		# Calling ggl-shortener APIs to get a goo.gl shortened url
		my $ua2 = new LWP::UserAgent;
		my $req2 = new HTTP::Request GET => 'http://ggl-shortener.appspot.com/?url='.$urlencodedlink;
		my $res = $ua2->request($req2);
		my $content = $ua2->request($req2)->content();

The “content” variable contains the JSON returned by the API, which is something like

{"short_url":"http://goo.gl/HTsh"}

If we liked to be precise we would need to parse this via a JSON module (eg simplejson). However this string is always the same and we can easily get our shortened url with a regular expression matching as shown below

		$content =~ m/short_url":"([^"]*)"/;
		my $shortlink = $1;

Chap 8 – Tweeting the post

We got the text and the shortened link, so we can safely post our tweet. Because of the twitter limitations, we have to ensure that our tweet won’t be longer then 140 chars. To do so, we’re going to shorten the tweet and then add the link to it. Moreover, as we are going to post this via another HTTP request, we are going to urlencode the whole thing as we did before

		# Cutting text of the post and adding the shortened link
		my $tweet = substr($text,0,106).'... '.$shortlink.'';
		$tweet  =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg;

There we go. Now we create a new HTTP call, but this time it has to be a POST one, so we change the object and we add the “content” variable, which contains our post. Moreover we need to use our twitter username and password to post, so we’re going to use the authorization_basic method of our HTTP object. Here’s how to do so

		# Posting to Twitter
		my $ua3 = new LWP::UserAgent;
		my $req3 = new HTTP::Request POST => 'http://twitter.com/statuses/update.xml';
		$req3->authorization_basic($twuser, $twpass);
		$req3->content("status=$tweet");
		$ua3->request($req3);
		my $content3 = $ua3->request($req3)->content();

Yes! We posted it!

Chap 9 – Avoiding future duplicates

Having the tweet posted we can dedicate to avoid future duplicates. Exactly in the same way we checked for the md5 of the article before we now need to put this link md5 into the database. The procedure is completely similar to the previous one but instead of the SELECT statement we are going to use an INSERT and obviously we do n’t need to retrieve any data from the database.

		# Inserting the post in the database to avoid duplicates
		my $insertmd5 = "INSERT INTO buzzs VALUES(md5('".$link."'))";
		my $go_i = $dbh->prepare($insertmd5);
		$go_i->execute;
		$go_i->finish();

Chap 10 – Closing the script

We’re done, we just need to close the connection as follows. This needs to be inserted after the if, and after the end of the cycle

# Closing dbs connection
$dbh->disconnect();

If you want to look at the complete code of this tutorial please check it out on github : buzz2tw.pl.

Possibly related posts: (automatically generated)

Create a module for Gentoo Eselect

View Comments // Written on Oct 23, 2009 // Open Source

I do Love eselect!

gentoo eselect Create a module for Gentoo EselectFor those who don’t know eselect is a ‘modular administration and configuration framework’. In simpler words it is a management tool shipped with Gentoo, able to switch between packages versions and configurations files, working with symbolic links and environmental variables.

Just to better clarify eselect job, it is able to make you switch between Java VM versions, Python releases , Gcc compilers and it makes it possible to choose your favorite editor.

Eselect is a modular tool, meaning that you just need to create a simple .eselect file to make it run your own commands. What I’m going to explain below is how to create a simple module to manage a symbolic link.

Aim of the tutorial

What I want to achieve in this little tutorial is to create a simple switch to quickly change my /etc/resolv.conf file. This file tells to any network interface where to look for DNS resolving.

As during last days I had problems with DNS, I was forced to switch very often from my default domain resolver (this case an internal server) to an external one ( OpenDns ). Using eselect for this purpose really simplified my life!

Preparation : create the ‘alternatives’

As we want to switch between two different configurations we need to create those alternatives. Open a terminal, cd to /etc and create the files. I created one called resolv.orig and one called resolv.opends, to be used when local DNS resolver is down.

# Going to /etc directory
cd /etc
# Copying original resolv.conf
# to the first alternative
cp resolv.conf resolv.orig
# Creating new resolv.conf alternative
# using OpenDNS IPs
echo -e "nameserver 208.67.222.222\nnameserver 208.67.220.220" > resolv.prova

Now we have to delete the original file and replace it with a symlink, obviously to the .orig file

# Deleting physical file
rm resolv.conf
# Creating symlink
ln -s resolv.orig resolv.conf

We are done with pre-configuration, let’s proceed with eselect module creation

Create the module

For a complete developer guide to eselect module creation, please refer to Gentoo Wiki official guide . This is just a ‘for examples’ guide for a quick start.

First of all all eselect modules should be located in your /usr/share/eselect/modules directory, so go there and create a new .eselect file

# Going into eselect modules directory
cd /usr/share/eselect/modules
# Creating a new module file
touch resolv.eselect

Now use your favorite editor to edit it. In this example I’m using vim

# Opening file with vim
vim resolv.eselect

Head section


As always the head section of the file contains meta informations about the module and the author, will just quickly review it below

# -*-eselect-*-  vim: ft=eselect
# Copyright 1999-2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id: $

# This will appear when listing the available modules
DESCRIPTION="Manage the /etc/resolv.conf symlink"
# Maintainer email
MAINTAINER="personal@andreaolivato.net"
# Date, used to create a version
SVN_DATE='$Date: 2009-10-23 12:00:07 +0200 (Fri, 23 Oct 2009) $'
# Creating version from date
VERSION=$(svn_date_to_version "${SVN_DATE}")

Find the alternatives


The first important function we need to create is the one taking care of listing all the possible alternatives that we have for our symlink. This means that you have to list all the files which can be linked to resolv.conf . In our case, there are only two : resolv.orig and resolv.opendns.

The easiest procedure would be to write those files directly, but as we want to learn how to deal with eselect properly let’s create a bash function to list those two file. This way if in the future we would like to create a new alternative, we don’t need to modify our code.

In the below function I just listed (using ls command) all the files starting with resolv. in the /etc folder and then excludes (using grep -v) the original file, which is resolv.conf. This way we can add more alternative by creating resolv.xxx files. Here’s the code

find_targets() {
    local p
    for p in $(ls /etc/resolv.* | grep -v conf )
    do
        echo $p
    done;
}

Create and remove the symlink


Proceeding with our code, we now need to be able to remove and create the symlink.

To remove it, we just need to use the rm command like this

remove_symlink() {
	rm "/etc/resolv.conf"
}

To create the symlink, we need to deal with the user choice. This choice is represented by a number, identifying the file to switch the link to. This means that we need to associate a parameter passed to the function with the position of the choice in our file list.

set_symlink() {
    # Get the parameter
    local target=${1}
    # Check it is a number
    if is_number "${target}" ; then
        # Get the list of the files via the previously created function
        local targets=( $(find_targets) )
        # Get the file associated with the parameter passed
        target=${targets[target - 1]}
    fi

    # If the result file does not exist
    if [[ -z "$target" ]] ; then
        # We output an error
        die -q "Target "${1}" doesn't appear to be valid!"
   # While if it exists
    else
        # We create the link
        ln -s "${target}" "/etc/resolv.conf"
    fi
}

Put the things together


Now we got a function to list, one to remove and one to insert. We need to put them together and switch between them depending on the user choices. The following function receives the parameter from the user, checks it, remove the current link if it exists and the call the create function forwarding the parameter.

do_set() {

    if [[ -z ${1} ]] ; then
        # If no parameter was passed
        die -q "You didn't tell me what to set the symlink to"
    elif [[ -L /etc/resolv.conf ]] ; then
        # If the links exists try to remove it
        if ! remove_symlink ; then
            # If can't remove it output error
            die -q "Couldn't remove existing symlink"
        # Try to create
        elif ! set_symlink "${1}" ; then
            # If can't create, output error
            die -q "Couldn't set a new symlink"
        fi
    # If the link exists but is not a link but a physical file
    elif [[ -e /etc/resolv.conf ]] ; then
        # We have something strange, output error
        die -q "/etc/resolv.conf exists but is not a symlink"
    else
        # Try to create
        set_symlink "${1}" || die -q "Couldn't set a new symlink"
    fi
}

The complete file


Remaining needed functions are mostly descriptive and I’m not going to review them in detail. Below is the complete code I used for the module.

# -*-eselect-*-  vim: ft=eselect
# Copyright 1999-2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id: $

DESCRIPTION="Manage the /etc/resolv.conf symlink"
MAINTAINER="personal@andreaolivato.net"
SVN_DATE='$Date: 2009-09-20 22:26:07 +0200 (Sun, 20 Sep 2009) $'
VERSION=$(svn_date_to_version "${SVN_DATE}")

find_targets() {
	local p
	for p in $(ls /etc/resolv.* | grep -v conf )
	do
        echo $p
	done;

}

remove_symlink() {
	rm "/etc/resolv.conf"
}

set_symlink() {
	local target=${1}
	if is_number "${target}" ; then
		local targets=( $(find_targets) )
		target=${targets[target - 1]}
	fi

	if [[ -z "$target" ]] ; then
		die -q "Target \"${1}\" doesn't appear to be valid!"
	else
		ln -s "${target}" "/etc/resolv.conf"
	fi
}

describe_show() {
	echo "Show the current resolv.conf symlink"
}

do_show() {
	write_list_start "Current resolv.conf symlink:"
	if [[ -L /etc/resolv.conf ]] ; then
		local resolv=$(canonicalise "/etc/resolv.conf")
		write_kv_list_entry "${resolv%/}" ""
	else
		write_kv_list_entry "(unset)" ""
	fi
}

describe_list() {
	echo "List available resolv.conf symlink targets"
}

do_list() {
	local i targets=( $(find_targets) )
	write_list_start "Available resolv.conf symlink targets:"
	for (( i = 0; i < ${#targets[@]}; i++ )) ; do
		[[ ${targets[i]} = \
			$(basename "$(canonicalise "/etc/resolv.conf")") ]] \
			&& targets[i]=$(highlight_marker "${targets[i]}")
	done
	write_numbered_list -m "(none found)" "${targets[@]}"
}

describe_set() {
	echo "Set a new resolv.conf symlink target"
}

describe_set_parameters() {
	echo ""
}

describe_set_options() {
	echo "target : Target name or number (from 'list' action)"
}

do_set() {
	if [[ -z ${1} ]] ; then
		die -q "You didn't tell me what to set the symlink to"
	elif [[ -L /etc/resolv.conf ]] ; then

		if ! remove_symlink ; then
			die -q "Couldn't remove existing symlink"
		elif ! set_symlink "${1}" ; then
			die -q "Couldn't set a new symlink"
		fi
	elif [[ -e /etc/resolv.conf ]] ; then
		die -q "/etc/resolv.conf exists but is not a symlink"
	else
		set_symlink "${1}" || die -q "Couldn't set a new symlink"
	fi
}

Usage

After you saved the file, you can start using the new module.

To list available files do

eselect resolv list

To set the original one

eselect resolv set 1

To set the OpenDNS one

eselect resolv set 2

To show the current choice

eselect resolv show

Download Feeds avoiding Feedburner redirects

View Comments // Written on Oct 20, 2009 // Net, Open Source

stop redirect Download Feeds avoiding Feedburner redirectsWhen trying to access the original feed of a blog (or website) which makes use of Feedburner, your crawler ( or browser or script ) usually receives a 301 header, redirecting it to the Google version of the feed. This means that if you need to access the original source ( for faster aggregation, to deal with a known rss syntax or whatever) you simply can not!

You can avoid the redirect and have complete access to the source using a simple UserAgent hack which can be achieved both via your scripts and browser. Below are some examples for common programming languages and media. The following hack has been tested with WordPress Feedburner plugin and Blogger integration, but should work even with home-made redirects if they user the user-agent as discriminant function.

Php using Curl

<?php
	/* Initializing curl object */
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, 'http://sourceblog.com/feed/');
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_TIMEOUT, 5);
	/* Setting custom useragent */
	curl_setopt($ch, CURLOPT_USERAGENT, 'FeedBurner/1.0 (http://www.FeedBurner.com)');

	$res = curl_exec($ch);
?>

Perl

#! /usr/bin/perl 

use strict;
use LWP::UserAgent;

my $ua = new LWP::UserAgent;
$ua->agent('FeedBurner/1.0 (http://www.FeedBurner.com)');
my $req = new HTTP::Request GET => "http://sourceblog.com/feed/";
my $content = $ua->request($req)->content();

Bash using Wget

wget --header="User-Agent: FeedBurner/1.0 (http://www.FeedBurner.com) " http://sourceblog.com/feed/ -O feed.xml -o /dev/null

Firefox

To set a full custom useragent on Firefox I suggest you to use Modify Headers extension. Please refer to their documentation section in the help tab located inside the extension window and remember to set the useragent to

FeedBurner/1.0 (http://www.FeedBurner.com)

Thanks @chrisvoo for suggesting the extension.

Chrome / Chromium

To change the full useragent on Google Chrome / Chromium, I followed this full guide , obviously changing the Iphone useragent with feedburner one (see above section).

Side notes

Please note that if someone creates a redirect to feedburner this usually means he doesn’t want you to connect directly to his webserver. This decision might have many valid reasons: too much load on the server, the needing of precise stats and so on.

Having said that, always make sure you have the rights to download an original source and ask the webmaster for permission if you need to put this hack on a cronjob running several times!

Double integration between Chrome and Delicious

View Comments // Written on Sep 22, 2009 // Net, Open Source

ch dl Double integration between Chrome and DeliciousExactly in the same way we can incorporate Chrome ( or Chromium in my case ) with Google Bookmarks, it is possible to perform a double integration between the browser and Delicious.

The bookmarklet section of this little how-to will show you how to share bookmarks with a single click from chrome, while the search one will guide you to setup a personalized search engine to quickly query your own Delicious bookmarks.

If you prefer a visual approach to the whole process or just want to look at the result have a jump to gallery.

The Bookmarklet

Delicious offers a wide range of bookmarklets, each ad-hoc calibrated for one browser. Just visit their bookmarklet page, scroll down a bit looking for the Google Chrome section and finally drag & drop the Bookmark on Delicious link to your bookmarks bar ( CTRL + B to show if you haven’t yet).

The title of the new bookmark got a long title and takes a lot of space. I usually edit bookmarklets so that they occupy as little space as possible. So right click on the new bookmark, select edit and change the name value with a short code ( I preferred DL but type whatever you want).

You can now navigate to any page you want to share via delicious and then click on the bookmark. The browser will be redirected to a Delicious pre-compiled form, which you can complete with tags and sharing options and then save.

The search

Bookmarking and sharing is good but having the possibility to browse all your saved bookmarks is definitely better. As done with Google Bookmarks even in Delicious we can simply create a new search engine using our own bookmarks repository.

Right click on the address bar and select edit search engines. Click on add to create a new engine and add the following values, obviously replacing USERNAME with your Delicious username.

  • Name: Delicious
  • Keyword: dl
  • Url: http://delicious.com/search?p=%s&chk=&fr=del_icio_us&lc=1&atags=&rtags=&context=userposts|USERNAME|

Click on ok and you’re done!

Now go back to your address bar, type “dl” and then press tab to activate the new search engine. Type the query you want to look for and press return. You will be redirected to a Delicious search page, showing only your bookmarks containing the string you typed!

Gallery

Here below you can find the whole process described in a visual way. Both the bookmarklet and the search engine installation are represented.

 

Remember the Milk on Android review and gallery

View Comments // Written on Sep 16, 2009 // Net, Open Source

rtm android Remember the Milk on Android review and gallery Yesterday Remember the Milk staff announced their official app for Android. If you want to see how it looks jump to gallery.

Their app is available for pro users only, but if you want to try it before buying there’s 15 day trial period offered together with the download. Membership costs only $25 / year and got many other improvements.

I installed the application directly from the android market ( ~1.4Mb download ) and sticked it on the home screen. After the first login it performs a full synchronization with the server, downloading all tasks, both completed and not. The main screen shows today tasks, but it is possible to switch to other useful views from the main menu : Today, Tomorrow, This Week and List (all tasks divided by group). Using the menu it is also possible to browse completed tasks, perform a search and manually refresh the list.

Obviously it is possible to add tasks and new lists, organize the tickets in the lists and perform quite any operation you usually do via their website.

The settings screen allows the user to set up the app on the phone, managing useful details about location (possibility to integrate with gps system) , sync and tasks themselves. I really appreciated the possibility to choose to sync the phone only when wi-fi access is enabled.

Finally the app offers a nice widget to integrate in the home screen.

Below you can have a look to a quick gallery of the app running on my Tytn II with Android 1.5.

 

3 steps Photoshop CS2 installation on Linux

View Comments // Written on Aug 27, 2009 // Open Source

ps wine 3 steps Photoshop CS2 installation on Linux

Gimp rocks. I find it very intuitive, simple to use and easy to learn. It has lots of features and is very expandible via scripts and brushes. Unfortunately I can’t see many designer using it out there. I bet customers usually wants a .psd, not a .xcf dammit.

Anyway that introduction was just to make me feeling a little bit less guilty about the Photoshop installation I realized some days ago, spending no more then 5 minutes configuring and then leaving  the wonderful wine-doors tool doing all the job for me.

The following article is a 3 step and nearly no interaction tutorial to install Photoshop CS2 on (quite) any Linux Environment, owning just a valid Serial Number and an Internet connection.

Below, before the article, you can have a quick graphical preview of the whole process, obtained with some screenshots

1. Install Wine-Doors

Wine doors installation depends on which distro you’re using but the package is usually shipped in official repositories. If not take a look at their downloads page which should help you. On my Gentoo box it was a matter of

autounmask app-emulation/wine-doors-0.1.3
emerge app-emulation/wine-doors

I read quickly Ubuntu/Debian instructions and it seems like you might choose to install the single .deb or add a custom repo to your apt configuration. Should be easy anyway…

2. Setting up Wine Doors

photoshop 150x150 3 steps Photoshop CS2 installation on Linux

Wine Doors is terribly easy to use and intuitive. On my Gnome desktop it was put on Applications -> System Tools -> Wine Doors. If you can’t find it on your DE menu, just run wine-doors from any terminal.

To install needed core components remember to check the ‘I have a valid Windows(tm) Licence’ box.

Gentoo shipped version got a problem with programs repositories and looking for it on the internet it seems like Arch and Slackware got same problem too. Problems refers to the impossibility to find an xml file containing list of available packages. To solve it you need to open wine-doors preferences via its Edit->Preferences menu, navigate to the Package Repositories tab and add the following ones

Name: Applications
Url: http://www.wine-doors.org/repositories/applications.repo/

Name: System Base
Url: http://www.wine-doors.org/repositories/base.repo/

Name: Games
Url: http://www.wine-doors.org/repositories/games.repo/

Name: Libraries and Fonts
Url: http://www.wine-doors.org/repositories/libraries.repo/

Done this, just refresh your package list from File->Update Package List. This will take a while depending on your connection

3. Download & Install Photoshop

wine doors 0.0.9 med 3 steps Photoshop CS2 installation on Linux

Here’s the funny and incredible part. On the top-right part of your wine doors window, you can search for packages to install. Write photo on it and photoshop will appear alone on your list. Just click install near its name and wine doors will start the download.

If this is the first package you install with wine-doors it will probably need to download some dependancies like fonts or core system files. Allow some time to download and install everything, then it will start downloading photoshop files. Yes, you don’t need cd, dvd or to download anything manual. Wine doors will download the cabs and install them automatically!

As soon as it finishes the photoshop download you can just follow common adobe installation wizard, writing your Serial Number,  choosing an installation location and proceeding with filescopy.  The installer will proceed like it does on any window system and alert you when it finishes.

When you got installation confirmation close the photoshop installer and wine doors. On Gnome environment wine doors is able to install menu entries of Windows programs inside your gnome menu. For example it put photoshop inside my Applications->Graphics menu.

You now just need to start it and after a few secs you will be able to use PS CS2 in your linux desktop without using fully emulated windows systems.

Shadows on footer while Scrolling

View Comments // Written on Aug 21, 2009 // Net, Open Source

shadow scrolling Shadows on footer while ScrollingThis is a quick tip about obtaining a nice looking effect of shadow while scrolling. Using css and a partially transparent background png it is possible to simulate a shadow in the lowest part of your website/blog, giving the input to the user about scrolling the page to read the semi-hidden content.

The code has been tested with recente Gecko based browsers (FirefoxFirefoxFirefox 2.0+ , Epiphany <2.26) , Webkit ones (ChromeChromeChrome 2.0+ , Safari 3+, ), Opera and  Shadows on footer while Scrolling 7+.

Css

Put following code inside your website CSS.

#shadower{
    background:transparent url(images/shadower.png) repeat-x scroll 0 0;
    bottom:0;
    display:block;
    height:110px;
    margin:0 auto;
    overflow:visible;
    position:fixed;
    width:100%;
    z-index:10000;
}

Html

The following markup has to be put in the footer of your page, before the end of the < /body>tag

<div id="shadower"></div>

Image

Please download the shadower.png image and put it on your images folder. If you need to change the path, remember to change the css code too.

Demo

You can see a demo of this code in this blog, even if there’s a bottom bar over the shadow.  Below there’s an explaining image.

shadower example 300x220 Shadows on footer while Scrolling

Web developing tools poll

View Comments // Written on Aug 20, 2009 // Net, Open Source

1250770927_poll redFirebug has always been my favourite companion for developing frontends for web applications. Unfortunately latest version both of the extension and the browser disappointed me and I had to look for other solutions. In a linuxlinuxlinux environment  Web developing tools poll was the most known non-free alternative so 6 months ago I started using its brand new debugging engine codenamed DragonFly. Some months ago I installed Linux dev build of Chromium (Open source implementation of GoogleGoogleGoogle ChromeChromeChrome) and found out that Webkit debugger (used in many other browsers) was fabolous.

Now I’m quite curious about other developers experience with inline editing and Javascript debugging so I started these four polls to know and learn from your experiences.

First poll is a general one, regarding the tool you like the most. The other three regards specific aspects of each tool: JS debugging, CSS & HTML inline editing and Performance analysis.

What's your overall favourite browser tool for Web Developing?

  • Firebug (67%, 85 Votes)
  • Chrome Developer Tools (29%, 37 Votes)
  • Other (2%, 3 Votes)
  • Opera Dragonfly (2%, 2 Votes)

Total Voters: 126

Loading ... Loading ...

What's your favourite Javascript debugger tool?

  • Firebug (59%, 60 Votes)
  • Chrome Developer Tools (28%, 28 Votes)
  • Opera Dragonfly (12%, 12 Votes)
  • Other (1%, 2 Votes)

Total Voters: 101

Loading ... Loading ...

What's your favourite HTML & CSS inline editing tool?

  • Firebug (54%, 51 Votes)
  • Web Developer (33%, 31 Votes)
  • Chrome Developer Tools (9%, 9 Votes)
  • Other (4%, 4 Votes)
  • Opera Dragonfly (0%, 1 Votes)

Total Voters: 95

Loading ... Loading ...

What's your favourite performance analyzer browser tool?

  • Firebug (NET tab) (39%, 28 Votes)
  • YSlow (34%, 24 Votes)
  • Page Speed (15%, 11 Votes)
  • Chrome Developer Tools (7%, 5 Votes)
  • Other (5%, 3 Votes)

Total Voters: 71

Loading ... Loading ...
Page 1 of 512345