Monday, May 18, 2009

Right Click, Send to USB in Nautilus

I did this script on Ubuntu 9.04. So any mentions of installation etc. will be specific to Ubuntu. Before I describe the guts of doing it, let me tell you straight that this feature has already been implemented in Ubuntu 9.04, Jaunty Jackalope. I did this script based on a question I found on linux.com
On to the script, then:

First, you have to install Nautilus Actions Configurations Package. It allows easy and graphical editing of Nautilus' right click menus.
sudo apt-get install nautilus-actions
Next, create the file copy.sh and save it in a location of your preference. For the purpose of this example, I'll use /home/bob/.

Here's the listing for copy.sh

#!/bin/bash
#First, get the name of the device as in sdb, sdc etc
name=`dmesg|grep removable|awk '{print $5}'|sed -e 's/\[\([a-z][a-z]*\)\]/\1/'|sort|uniq`

#Select only those devices which are mounted
name=`mount | grep -Z "$name" | awk '{print $1}'`

if [ ! $name ]; then
exit 1;
fi

#Find the mount points of mounted devices
#ie, if there exists a removable drive
mpoint=`mount | grep "$name" | awk '{print $3}'`

#Find the number of devices
num_device=`for FN in $name; do echo $FN; done | wc -l`

#Display a selection menu if there are multiple devices present
if [ $num_device -gt 1 ]; then
for FN in $mpoint;
do
string=$string" FALSE "$FN;
num_device=$((num_device-1))
done
selection=`zenity --title "Select a USB Device" --text "Please Choose one of the following USB Devices to send the selection to" --list --radiolist --column "Select" --column "Mount Point" $string`;
else
#else copy to the available device
selection=$mpoint;
fi

#For each of the selected files, copy them
for FILE in "$@"
do
/bin/cp -r $FILE $selection;
done

Make code executable chmod +x /home/bob/copy.sh

Now, having saved copy.sh/home/bob/, open up Nautilus Actions Configuration from System->Preferences->Nautilus Actions Configuration. Click on Add. In the "Add a New Action" Window that pops up, fill in the details of the menu item. Like Label, the tooltip - The piece of text that you see at the bottom of Nautilus once you highlight the label and an optional icon.

In the Profiles section, highlight "Main" and click on Edit. In the Path text box, enter the full path to copy.sh, ie, in this case /home/bob/copy.sh. In the parameters tab, enter %M. To know more about parameters, click on Legends to get a pop up. The pop up can be closed by clicking on Legends again.


In the Conditions tab, under "Appears if selection contains", select "Both". Check the option "Appears if Selection has multiple files and folders". Click on OK and you are done.

To see the option in the right-click menu, you will have to kill all instances of Nautilus running killall -HUP nautilus, or log out and login again.

I tested the script with only a single USB. It should work for multiple ones too if plugged in together. On the occasion that multiple Removable Disks are present, the script will ask for a selection from the user.

Labels: ,

Sunday, May 10, 2009

Crazy Chatting with Chatbot::ELIZA

Chatbot::Eliza is a perl module that implements the famous ELIZA program created by Joseph Weizenbaum.

Chatbot::Eliza has a object type structure, which enables it to hook up with any interface. A very trivial command line implementation of the bot would take up only four lines of code and it goes like this :

#!/usr/bin/perl
use Chatbot::Eliza;
$bot = new Chatbot::Eliza("Jack", "");
$bot->command_interface();

This will initiate a new bot talking with you on the command line. Our bot, Jack in this case, would begin with the classic question: "Please tell me whats bothering you?". And you know what happens next. The mindless ramblings of the bot.

When I first saw this module, the only interesting use I found of it is to hook it up with my gmail account. Since then, a lot of my contacts have talked with either Ms. Jill or Mr. Jack.

Connecting to GTalk with Perl is a trivial issue. It requires a few perl modules such as

  • IO::Socket::SSL (>=0.81 ?)

  • XML::Stream

  • Net::XMPP

  • Authen::SASL



Use the CPAN commandline shell to install them. Enter the command line shell by typing

perl -MCPAN -e shell

Now install the modules one by one using the command

install module_name

And of course you also need the Chatbot::Eliza module.
With all the requisite modules installed, you are ready to connect your bot with GTalk.
Here's the listing I used for the Eliza-gmail-chatter:


#!/usr/bin/perl -w

use strict;
use Net::XMPP;
use Chatbot::Eliza;

my $bot = new Chatbot::Eliza("Jill","");
my $message;
my $body;
my $JID;
my $userid;
my $username = "xxxxxxxxxxxxxxxx"; #Supply your gmail username here
my $password = "xxxxxxxxxxxxxxxx"; #Supply your gmail password here
my $resource = "ChatBot";

my $hostname = 'talk.google.com';
my $port = 5222;
my $componentname = 'gmail.com';
my $connectiontype = 'tcpip';
my $tls = 1;

my $Connection = new Net::XMPP::Client();

$Connection->SetCallBacks(message=>\&doit);

my $status = $Connection->Connect(
hostname => $hostname, port => $port,
componentname => $componentname,
connectiontype => $connectiontype, tls => $tls);

if (!(defined($status))) {
print "ERROR: XMPP connection failed.\n";
print " ($!)\n";
exit(0);
}

# Change hostname
my $sid = $Connection->{SESSION}->{id};
$Connection->{STREAM}->{SIDS}->{$sid}->{hostname} = $componentname;

# Authenticate
my @result = $Connection->AuthSend(
username => $username, password => $password,
resource => $resource);

if ($result[0] ne "ok") {
print "ERROR: Authorization failed: $result[0] - $result[1]\n";
exit(0);
}
$Connection->PresenceSend();
$body = $bot->{initial}->[0];
$Connection->MessageSend(to=>"xxxxxxxxxxxx\@gmail.com",body=>$body); #Supply your contact's
#gmail id here
undef $userid;
while (1) {
$Connection->Process();
if (defined ($userid)) {
$Connection->MessageSend (to=>"xxxxxxxxxxx\@gmail.com", body=>$body); #Supply your contact's
#gmail id here
print "Me(as the chatbot) (to $userid): ", $body, "\n";
}
}
sub doit
{
my ($SID, $Mess) = @_;
$JID = new Net::XMPP::JID($Mess->GetFrom());
$userid = $JID->GetUserID();
print $userid, " : " , $Mess->GetBody(), "\n";
$body=$bot->transform($Mess->GetBody());
}


You can have a laugh riot from your terminal watching your contact talking with the Chatbot. Make sure that you inform the contact later about who talked.

Chatbot::Eliza has a peculiar effect of making not wanting to talk with her ever again.

Try it for yourself.
Happy Chattin' Fun !

Labels: , ,