#!/usr/bin/perl #============================================================================# # perl2con # # Fetches all bookmarks from a del.icio.us account and posts them to a # Connotea account. Either username and password for both del.icio.us and # Connotea are supplied via command line or only usernames via commandline # and passwords interactively, i.e. # # SHELL> diu2con delicious_user delicious_pass connotea_user connotea_pass # OR # SHELL> diu2con delicious_user connotea_user # # Author: Konstantin Baierer # Version: .13 (2007-02-07) # License: GPL (do what you want, but keep the source open) #============================================================================# use LWP::UserAgent; use HTTP::Request; use HTTP::Headers; use Data::Dumper; use URI::Escape qw(uri_escape_utf8); use Crypt::SSLeay; use XML::Simple qw(:strict); # Enable this to have extended output (and I really mean extended) # $DEBUG++; # flush output immediately $|++; # Start main method main(); #============================================================================# # main # Fetches Data from del.icio.us, loops through the bookmarks, posts them to # del.icio.us and write's status of each link to termninal (OK or ERR) # @params # @return void #============================================================================# sub main { # Check arguments and initialize some variables init(); print "\n Getting data from del.icio.us ..."; $daten = parseXML( getFromDelicious( ) ); print " done.\n"; while ($i < $#{$daten->{post}}) { $i++; $post_diu = $daten->{post}; print " | " . $post_diu->[$i]->{href}; if (addToConnotea ($post_diu->[$i]->{href}, $post_diu->[$i]->{tag}, $post_diu->[$i]->{description}, $post_diu->[$i]->{extended}) ) { print "\r OK\n"; } else { print "\r ERR\n"; } sleep($time_between_posts); } } #============================================================================# # init # Initializes user/pass, sets UserAgent and post interval # @param # return void #============================================================================# sub init { # Check for correct number of arguments (4 or 2) if (($#ARGV != 3) && ($#ARGV != 1)){ print "delicious2connotea\n"; print "USAGE:\tdiu2con delicious_username [delicious_password] connotea_username [connotea_password]\n"; exit; } # User entered no passwords, let's ask for them if ($#ARGV == 1) { # Assign Connotea username to $ARGV[2], so that del.icio.us password can be assigned to $ARGV[1] $ARGV[2] = $ARGV[1]; # Turn off terminal echo (hidden input) system("stty -echo"); print "Enter password for del.icio.us user $ARGV[0]: "; $ARGV[1] = ; print "\nEnter password for Connotea user $ARGV[2]: "; $ARGV[3] = ; # Turn on terminal echo system("stty echo"); # Strip from all elements of @ARGV map { chomp } @ARGV; } # Initialize Hashes for usernames and passwords %user = ('delicious' => @ARGV[0], 'connotea' => @ARGV[2] ); %pass = ('delicious' => @ARGV[1], 'connotea' => @ARGV[3] ); if ($DEBUG) { print Dumper(%user); print Dumper(%pass); sleep(2); } # Initialize UserAgent our $ua = new LWP::UserAgent; $ua->agent('diu2con/WWW::Connotea'); # Set time between each post to Connotea in seconds (we don't want to get 503s) our $time_between_posts = 3; } #============================================================================# # addToConnotea # Posts the bookmark to Connotea, # @param String [uri] # @param String [tags] # @param String [title] # @param String [desc] # @return boolean #============================================================================# sub addToConnotea { my $url_connotea = 'http://www.connotea.org/data/add/'; my ( $uri, $tags, $title, $desc ) = @_; my %attr_connotea = ( 'uri' => $uri, 'tags' => $tags, 'usertitle' => $title, 'description' => $desc, ); if ($DEBUG) { print Dumper(%attr_connotea); sleep(2); } my $header_connotea = HTTP::Headers->new; $header_connotea->authorization_basic($user{connotea}, $pass{connotea}); my $req_connotea = HTTP::Request->new('POST', $url_connotea, $header_connotea, URLencode(%attr_connotea) ); my $res_connotea = $ua->request($req_connotea); if (Dumper($res_connotea) =~ /isSuccess.1/) { return 1; } else { return; } if ($DEBUG) { print Dumper($res_connotea); } } #============================================================================# # URLencode # Converts a hash to a url-encoded String # @param Hash [hash of attributes] # @return String [url-encoded string] #============================================================================# sub URLencode { my %attr_list = @_; my $output; while ( ($key, $value) = each(%attr_list) ) { $output .= join('=', uri_escape_utf8($key), uri_escape_utf8($value)); $output .= '&'; } return $output; } #-----------------------------------------------------------------------------# # getFromDelicious # Fetches all data from del.icio.us # @return String [umformatted XML-Response] #-----------------------------------------------------------------------------# sub getFromDelicious { my $url = "https://$user{delicious}:$pass{delicious}\@api.del.icio.us/v1/posts/all?"; my $anfrage = new HTTP::Request('GET', $url); my $antwort = $ua->request($anfrage); if ($DEBUG) { print Dumper($antwort->content); print $url; } return $antwort->content; } #-----------------------------------------------------------------------------# # parseXML # Converts raw XML-Data to internal data structures um # @param String [raw XML data] # @return ArrayOfHashes [Array of datasets, hash of datafields] #-----------------------------------------------------------------------------# sub parseXML { my ( $raw_xml ) = @_; # Parse die XML-Daten in perl-Datenstrukturen und gib sie zurück return XMLin($raw_xml, ForceArray=>1, KeyAttr=>['']); }