Category: Tech

Del.icio.us

I started using del.icio.us and I'm loving it! Beelerspace has a pretty nice delicious HOWTO going.

I want to write more about his phenom, but I need some time to really dit into it.

Link to story

Technorati tags for this post:

Python Grimoire

I found an excellent python quick reference today. Its licensed under a Creative Commons "Attribution-NonCommercial-ShareAlike 2.0" deed so I've mirrored it locally.

Thanks The Tao of Mac!

Link to story

Technorati tags for this post:

SSH Session Multiplexing

I have a new favorite ssh feature! Not that password-less public key authentication, port forwarding or X11 forwarding weren't really cool. But session multiplexing is really sweet.

Included in version 3.9, session multiplexing is a faster way to run multiple ssh session to a single remote host. When you login to a machine (call it 'remotehost') the first time, you tell that ssh session to become the "ControlMaster" (-M option).

# ssh -M -S ~/.ssh/remote-mux user@remotehost
Ssh will start a session as usual and also open up a Unix domain socket using the filename you provide in the ControlPath argument (-S option).

To start another ssh session to the same host, you can do:

# ssh -S ControlPath=~/.ssh/remote-mux user@remotehost
Ssh will skip authentication (as you've already auth'd to remotehost) and will use the existing TCP connection for the second connection. The upshot of this is that logging in a second (or third!) time is instantaneous.

Adding the -S and -M options on the command line is tedious. You can setup your .ssh/config file like this:

Host remotehost
   HostName remotehost
   User user
   ControlMaster yes
   ControlPath ~/.ssh/remote-mux

Host remotehostfast
   HostName remotehost
   User user
   ControlMaster no
   ControlPath ~/.ssh/remote-mux
For your first connection, do:
# ssh remotehost
For your subsequent connections, do:
# ssh remotehostfast

Link to story

Technorati tags for this post:

Extracting Meeting Invites from my Mailbox

In previous posts I've bemoaned the lack of integration between Mozilla's Thunderbird and external programs -- especially Mozilla Sunbird. I realize that there is a new project (Lightning) to integrate the two, but my meeting invites keep pouring in at work and I can't wait.

My temporary solution to this problem uses the following perl script. Its job is to copy any MIME attachments of type "text/calendar" out of my inbox and into a folder on disk. Then I can use Sunbird's Import feature to read them in. My procedure is this:

  1. When I receive a meeting invite in Thunderbird, I copy the message into a specific folder - I call it meetings
  2. Then I run my script like this: ./extract_ics.pl -m ~/Mail/meetings -d ~/calendar -v
  3. In Sunbird, I import the ~/calendar/[whatever].ics file created in step 2.
  4. Finally, I go back and delete the contents of ~/calendar and the meetings folder
Here's my script:

#!/usr/bin/perl -w
use strict;
use Email::Folder;
use Email::MIME;
use Time::Local;
use Date::Parse;
use Getopt::Std;

######################################################################
#                                                                    #
# Find text/calendar MIME attachments in mailboxes and save them     #
# into a local folder for import into Sunbird                        #
#                                                                    #
######################################################################

# parse cmd line options
my $verbose  = 0;
my %opts     = ();
getopts('vm:d:', \%opts);
if ( ! $opts{'d'} or ! $opts{'m'} ) { usage(); }
if ( $opts{'v'} ) { $verbose = 1; }
my $maildir = $opts{'m'};
my $savedir = $opts{'d'};

# is -m a single mailbox or a maildir ?
if ( -f $maildir ) { parse_box($maildir); }
else {
        # find all the mailboxes in our maildir
        opendir(DIR, "$maildir") or die "Couldn't open directory $maildir";
        my @boxes = grep { -f "$maildir/$_" && ! m/\.msf$/ && ! m/^\./ } sort readdir(DIR);
        closedir(DIR);

        foreach my $b ( @boxes ) { parse_box("$maildir/$b"); }
}
exit 0;


sub usage {
        print qq(Usage: $0 -m  -d  [-v]\n);
        exit 1;
}

# find all text/calendar MIME attachments in a mailbox
sub parse_box {
        my $box = shift;

        print "Reading mailbox $box\n" if $verbose;

        my $folder = Email::Folder->new($box);
        # foreach my $m ( $folder->messages ) {
        while ( my $m = $folder->next_message ) {
                # $m is an Email::Simple class, Email::MIME requires a string
                my $parsed = Email::MIME->new($m->as_string);
                my @parts = $parsed->parts;

                foreach my $p ( @parts ) {
                        if ( $p->content_type =~ m|text/calendar| ) {
                                write_ics($p, $m->header("Subject"), $m->header("Date"));
                        }
                }
        }
}

# write attachments to a local folder
sub write_ics {
        my ($p, $subject, $date) = @_;

        # sanitize the subject line so I can use it as a filename
        $subject =~ s/\s+/_/g; # no spaces
        $subject =~ s|/|_|g;   # no slashes
        $subject =~ s|_+|_|g;  # remove duplicate underscores

        my $filename = "${savedir}/${subject}.ics";
        if ( -f $filename ) {
                print "WARNING: overwriting $filename\n" if $verbose;
        }

        if ( ! open(ICS, ">$filename") ) {
                print qq(WARNING: failed to open $filename for writing\n);
                return;
        }

        print "Writing $filename\n" if $verbose;
        print ICS $p->body, "\n";
        close ICS;

        # set date of the file to date of email Date header
        my ($ss,$mm,$hh,$day,$month,$year,$zone) = strptime($date);
        my $newtime = timelocal(0, $mm, $hh, $day, $month, $year);
        utime $newtime, $newtime, $filename;
}
Update: Make sure you "compact" your Mozilla folder before you run the script. There are likely to be "deleted" messages in it.

Technorati tags for this post:

Google's solution to comment spam

Here google announces its plan to stop comment spam. Their indexing spider won't follow links that have a rel="nofollow" attribute. So blog software authors are encouraged to add that attribute to any links in comments or trackbacks.

Cool! Maybe I'll enable html in comments now.

Link to story

Technorati tags for this post:

lsof -i

Hot dog! Two unix posts in one day!

I just wanted to share my joy in discovering the -i switch of lsof. The argument to -i can be either a protocol (TCP|UDP), a hostname or ip address or a port number. Or any combination of the above. The result: a nice listing of the processes with connections that match your criteria.

Technorati tags for this post:

You screen, I screen, We all screen for ... console multiplexing

I've recently started using the screen unix program. It lets you multiplex several processes (think shells) in a single window. Even better, you can 'detach' the screen process from your current window and log out of your machine. Upon returning, run screen -r to get your whole screen session back.

Here's my personal ~/.screenrc

# no startup msg
startup_message off

# new windows go to home dir
chdir

# keep some status lines on bottom of screen
caption always "%{= bb}%{+b w}%n %h %=%t %c"
hardstatus alwayslastline "%-Lw%{= BW}%50>%n%f* %t%{-}%+Lw%<"

activity "Activity in %t(%n)"

# Create 3 more screens.  They will exit once the designated
# program quits.
screen -t misc  0
screen -t mutt  1 mutt
screen -t www   2 lynx -book


# move to the main shell
number 0

Technorati tags for this post:

Thunderbird, you stupid monolithic app!

Gee Whiz, Thunderbird. If you won't let me modify an incoming message (see previous post), can I at least modify a message on disk? I'd like to use the standard Perl CPAN email modules to modify or at least read your folders.

Can I do that?

Please?

Well, sort of.

I can of course use read-only tools like Mail::MboxParser. And I can even use other tools to modify a message. However, Thunderbird doesn't seem to re-read the mailbox. Shouldn't it react in some way when one of its folders is externally modified?

Drat. I curse all you monolithic, gui-centric applications! Why won't you play nice with other apps? Why don't you expect your user to be a Perl-mad hacker?

Technorati tags for this post:

Advanced Thunderbird Filtering Extension?

I've recently switched from using Mutt to Thunderbird at work. The only feature I really and truly miss is the ability to run external programs as part of the message filtering process - just like good old procmail used to let me do (or Perl's Mail::Audit). Thunderbird lets me sort messages into folders, but I need to do things like:
  • Modify the body of a message
  • Add a header
  • Run another program based on the contents of the message
  • Bounce the message to another address

Does anybody have an extension for Thunderbird to let me run Perl or Python programs on an incoming message? No? Am I going to have to write this myself?

Technorati tags for this post:

< Future 10 | Past 10 >