#!/usr/bin/perl # # identi.ca (laconica) commandline client # # Contact: pancake < AT > nopcode < DOT > org # Version 2008-07-10 # # TODO: # - Register users # - GUI (gtkdialog?) # - daemon # - proper search methods # - change password # $|=1; my $identi_url="http://identi.ca/"; my $identi_urls="http://identi.ca/"; # https? my @identi = (); my @identi_subs = (); my $limit = 0; my $agent = "Elinks (0.11.3; Linux 2.6.24.3 i686; 138x78)"; my $cookie = ""; my $username = ""; my $username_set = ""; my $passfile = $ENV{"HOME"}."/.identi.conf"; my $msg_prefix=""; my $verbose=1; sub get_pass_home { $password=""; open FD, "<$passfile" or return; while () { chomp (my $str=$_); $password=$str if($str); #print "password is '$password'\n"; } close FD; return $password; } my $password = get_pass_home(); sub identi_load { my ($page)=@_; my @lines=split(/\n/,`curl -s "$identi_url$page" $cookie`); my $url, $msg, $nick, $date, $img; for my $i (0 .. $#lines) { my $line = $lines[$i]; if ($line=~/content/) { $line=~/content">(.*)<\/p>/; $msg=$1 if (defined($1)); } elsif ($line=~/

(.*)<\/p>$/) { $msg=$1 if (defined($1)); } elsif ($line=~/mini" alt="(.*)"\/>/) { $nick=$1 if (defined($1)); } elsif ($line=~/title="(.*)" href="(.*)" class="subscription"/) { $url = $2 if (defined($2)); $nick=$1 if (defined($1)); push @identi_subs, { "nick" => "$nick", "url" => "$url", }; #undef($url); #undef($nick); } #elsif ($line=~/ "$url", "nick" => "$nick", "date" => "$date", "msg" => "$msg" }; undef($url); # undef($nick); undef($date); undef($msg); } elsif ($line=~/nickname/) { $line=~/nickname">(.*)<\/a>/; $nick=$1 if (defined($1)); } } } sub identi_logout { system("curl -A '$agent' -e $identi_urls/main/logout $cookie -s '$identi_url/main/logout' > /dev/null 2>&1"); } sub identi_login { my ($user, $pass) = @_; my @lines=split(/\n/,`curl -i -A '$agent' -e $identi_urls/main/login $cookie -d "nickname=$user&password=$pass&submit=Login" -s "$identi_url/main/login"`); my $url, $msg, $nick, $date, $img; if ($#lines == 0) { print "login: No results. Connection problem?\n"; return; } for my $i (0 .. $#lines) { chomp(my $line = $lines[$i]); if ($line=~/Incorrect/) { print STDERR "Incorrect user/password.\n"; exit(1); } elsif ($line=~/Set-Cookie: (.*)$/) { #Set-Cookie: PHPSESSID=4223b14662c40aa6ed205a81447fc137; path=/ $cookie=$1 if (defined($1)); } } chop($cookie); if ($cookie) { print STDERR "Login accepted. Using cookie: '$cookie'\n"; $cookie="-b '$cookie' "; $username = $user; } else { print STDERR "Oops. Login accepted and no cookie? \n"; } } sub sanitize { my ($str) = @_; $str=~s/[^[:print:]]*//g; $str=~s/'/"/g; $str=~s/\\//g; $str=~s/"/\\"/g; $str=~s/&/%26/g; return $str; } sub identi_list_subs { my $n = 0; for my $i (0 .. $#identi_subs) { last if ($limit!=0 && $n++ >= $limit); my $foo = sanitize( $identi_subs[$i] ); my $nick = sanitize( $identi_subs[$i]{"nick"} ); my $url = sanitize( $identi_subs[$i]{"url"} ); if ($url && $nick) { printf ("\e[33m%20s\e[0m $url\n",$nick); } } } sub identi_list_grep { my ($grep) = @_; my $n = 0; for my $i (0 .. $#identi) { my $foo = $identi[$i]; my $url = $identi[$i]{"url"}; my $nick = $identi[$i]{"nick"}; my $date = $identi[$i]{"date"}; my $msg = $identi[$i]{"msg"}; $url = sanitize($url); $nick = sanitize($nick); $date = sanitize($date); $msg = sanitize($msg); if ($url && $date && defined($msg)) { last if ($limit!=0 && $n++ >= $limit); if (($msg=~/$grep/i) || ($nick=~/$grep/)) { if ($nick) { print "\e[33m * $nick\e[0m : $date\n"; } else { print " * $date\n"; } print "\e[36m - $url\e[0m\n"; print " $msg\n\n"; } } } } sub identi_unsubscribe { my ($user) = @_; my @lines=split(/\n/,`curl -i -A '$agent' -e '$identi_urls/main/unsubscribe' $cookie -d 'unsubscribeto=$user' -s '$identi_urls/main/unsubscribe'`); print "curl -i -A '$agent' -e '$identi_urls/main/unsubscribe' $cookie -d 'unsubscribeto=$user' -s '$identi_urls/$user'\n"; for my $i (0 .. $#lines) { chomp(my $line = $lines[$i]); if ($line=~/(..)SUBSCRIBE/i) { print STDERR "$1subscribe\n"; return 0; } } print STDERR "Unknown error :O\n"; } sub identi_subscribe { my ($user) = @_; my @lines=split(/\n/,`curl -i -A '$agent' -e '$identi_urls/main/subscribe' $cookie -d 'subscribeto=$user' -s '$identi_urls/main/subscribe'`); my $url, $msg, $nick, $date, $img; for my $i (0 .. $#lines) { chomp(my $line = $lines[$i]); if ($line=~/Incorrect/) { print STDERR "Ererror\n"; } } } sub identi_avatar { my ($img) = @_; my @lines=split(/\n/,`curl -i -A '$agent' -e '$identi_urls/settings/avatar' $cookie -F 'MAX_FILE_SIZE=262144' -F 'avatarfile=\@$img' -s '$identi_urls/settings/avatar'`); my $url, $msg, $nick, $date, $img; for my $i (0 .. $#lines) { chomp(my $line = $lines[$i]); if ($line=~/updated/) { print STDERR "avatar: Update ok!\n"; return; } } print STDERR "avatar: Oops can't update :(\n"; } sub identi_post { my ($msg) = @_; $msg=sanitize($msg); my @lines=split(/\n/,`curl -i -A '$agent' -e '$identi_urls/notice/new' $cookie -d "returnto=all&status_textarea=$msg&status_submit=Send" -s '$identi_urls/notice/new'`); #TODO : check length < 140 my $url, $msg, $nick, $date, $img; for my $i (0 .. $#lines) { chomp(my $line = $lines[$i]); if ($line=~/Incorrect/) { print STDERR "Ererror\n"; } } } sub identi_list { my $n = 0; for my $i (0 .. $#identi) { my $foo = $identi[$i]; my $url = $identi[$i]{"url"}; my $nick = $identi[$i]{"nick"}; my $date = $identi[$i]{"date"}; my $msg = $identi[$i]{"msg"}; $url = sanitize($url); $nick = sanitize($nick); $date = sanitize($date); $msg = sanitize($msg); if ($url && $date && defined($msg)) { last if ($limit!=0 && $n++ >= $limit); $nick = $username_set if ($username_set); if ($verbose) { if ($nick) { print "\e[33m * $nick\e[0m : $date\n"; } else { print " * $date\n"; } print "\e[36m - $url\e[0m\n"; print " $msg\n\n"; } else { print "^bg(#404040)$nick : $date\n"; print "^bg()$msg\n\n"; } } } } sub identi_help { print "Usage: identi.pl [-options] \n"; print " -u [user] login. prompts or ~/.identi.conf\n"; print " -L logout\n"; print " -n [num] limit number of output\n"; print " -t [nick] view nick's timeline\n"; print " -p [num] set page number\n"; print " -s [nick] show subscriptions of nick\n"; print " -S [nick] subscribe nick\n"; print " -f [word] find a word\n"; print " -m [msg|-] post a message (- = stdin)\n"; print " -r [nick] reply, post to nick (needs -m)\n"; print " -a [nick] list all subscribed people timeline\n"; print " -i [img] set img as avatar\n"; print " -l list public timeline (uses -p)\n"; # TODO -d daemon, -g gui } sub identi_reset { @identi = (); @identi_subs = (); } sub check_arg { my ($arg) = @_; $arg=~s/'/\'/g; return $arg if (defined($arg)); identi_help(); exit(1); } sub get_pass { return $password if ($password ne ""); print STDERR "Password: "; chomp($str=); return $str; } # - main - # # TODO sub identi_main { identi_help() if ($#ARGV==-1); for my $i (0 .. $#ARGV) { if ($ARGV[$i] eq "-h") { identi_help(); exit(0); } elsif ($ARGV[$i] eq "-v") { $verbose = 0; } elsif ($ARGV[$i] eq "-u") { my $user = check_arg($ARGV[$i+1]); my $pass = get_pass(); identi_login($user, $pass); } elsif ($ARGV[$i] eq "-r") { my $user = check_arg($ARGV[$i+1]); print "== Replying message to the user '$user'\n"; $msg_prefix="\@$user "; } elsif ($ARGV[$i] eq "-p") { $page = $ARGV[$i+1]; } elsif ($ARGV[$i] eq "-l") { $identi = (); identi_load(($page ne "")?"?page=$page":""); identi_list(); } elsif ($ARGV[$i] eq "-n") { $limit = check_arg($ARGV[$i+1]); } elsif ($ARGV[$i] eq "-t") { $nick = check_arg($ARGV[$i+1]); print STDERR "== Timeline of $nick\n\n"; $username_set = $nick; identi_reset(); identi_load($nick); identi_list(); } elsif ($ARGV[$i] eq "-m") { $msg = check_arg($ARGV[$i+1]); if ($msg eq "-") { chomp($msg = ); } identi_post("$msg_prefix$msg"); } elsif ($ARGV[$i] eq "-s") { $user = check_arg($ARGV[$i+1]); print STDERR "== Subscriptions of user $user\n\n"; identi_reset(); identi_load($user); identi_list_subs(); } elsif ($ARGV[$i] eq "-S") { $user = check_arg($ARGV[$i+1]); print STDERR "== Subscribing $user...\n"; identi_subscribe($user); } elsif ($ARGV[$i] eq "-a") { $user = check_arg($ARGV[$i+1]); identi_reset(); identi_load("$user/all"); identi_list(); } elsif ($ARGV[$i] eq "-L") { print STDERR "== Logout...\n"; identi_logout(); } elsif ($ARGV[$i] eq "-U") { $user = check_arg($ARGV[$i+1]); print "== Unsubscribing $user...\n"; identi_unsubscribe($user); } elsif ($ARGV[$i] eq "-i") { $img = check_arg($ARGV[$i+1]); print "== Set avatar image $img...\n"; identi_avatar($img); } elsif ($ARGV[$i] eq "-f") { $word = check_arg($ARGV[$i+1]); print STDERR "== Finding '$word'\n\n"; for(my $n=0;1; $n++) { my $page = "?page=$n"; identi_reset(); identi_load($page); print "page ".($n+1)."...\n"; identi_list_grep($word); } } }