Subscribe to dorkwerx        RSS Feed
-----

Irssi Remote URL Grabber

Icon Leave Comment
I encountered a problem recently while using an IRC client where I wanted to be able to open URL's mentioned in chat in a different machine on my network. Here's how I did it:

At home I run a FreeBSD box that serves various roles, but is mostly just my generic UNIX workhorse. I've dubbed this box "Abigail." I also have a MacBook from a few years ago that I've dubbed "Lucy." I log into Abigail from Lucy via SSH and this is where I accomplish most of my day-to-day tasks beyond web browsing and checking email. I've got a GNU Screen session running on Abigail that I attach to so I can resume any work right where I left off. Inside of that screen session I'm running an instance of Irssi as my IRC client.

I was spending some time over the weekend tweaking some things that bother me about the default configuration in Irssi. There are existing scripts out there for Irssi that allow you to grab URL's out of the client, and then launch them in a local web browser or mail program. Problem is, I'm not browsing the web on the local machine. I do all my web browsing on Lucy, my laptop. So how do I get URL's mentioned on Abigail to launch in the Google Chrome browser I have open on Lucy?

This sounds like a job for inter-process communication! Luckily, UNIX lends itself well to these sorts of problems so the solution I devised is pretty simplistic.

First, I chose a URL grabber script for Irssi that would allow me to pass the extracted URL's to another program. The script I chose is called OpenURL(download here). This script makes use of a property in Irssi called openurl_app_http which you set to the command you want it to execute. So I download this script into my ~/.irssi/scripts/autorun directory and load it into Irssi. Perfect!

Next I created a FIFO (named pipe) in my filesystem on Abigail under ~/.irssi/url-pipe like so:
$ mkfifo ~/.irssi/url-pipe


Then, I configured the OpenURL script to write URL's out too this named pipe. To do this I simply redefine the openurl_app_http property in Irssi by executing this command from within Irssi:
/set openurl_app_http echo "$1" > ~/.irssi/url-pipe

OpenURL will populate the $1 field with the grabbed URL.

Great! So now the IRC client will write URLs out to the named pipe. Next we have to establish a reader on Lucy to consume the URLs. To do that, I created a very simplistic URL consumer script on Lucy which looks like so:
#!/bin/bash

ssh dorknexus@abigail "tail -f ~/.irssi/url-pipe" | while read url; do
    open -a Google\ Chrome "$url"
done



This script will read in URLs from the remote named pipe on Abigail and signal Google Chrome to open any URLs it sees. I named this script url-consumer and placed it in my ~/bin directory on Lucy. This will open an SSH session on Abigail and execute the tail command on the named pipe. tail simply watches a file for input and outputs the changes it sees on STDOUT. Then, I pipe the STDOUT from the remote tail command running on Abigail into the while loop for extraction.

Now, back in Irssi, the OpenURL script will tag each URL it sees with a unique identifier. To launch the URL's I just execute the following command inside of Irssi:
/openurl <url_id>
Which will cause the URL to be opened in the web browser on my laptop.

SUCCESS!

Originally I was going to just use a standard file to read and write URLs. The problem is that, without some sort of management, this file will get bigger and bigger with each URL added to the file. With named pipes, data is placed in the pipe when it is written and then removed from the pipe when it is read.

Two points of concern with this approach:
  • The consumer script must be running in order for Lucy, my laptop, to recieve URLs
  • According to the POSIX specification, if a reader has not opened a named pipe, then the writer will block until a reader appears. This means that the OpenURL script will block if I attempt to launch URLs with no consumer on the other end. This blocking behavior makes Irssi behave strangely.


So basically, I just have to make sure that the consumer is running on Lucy before attempting to launch URL's from Abigail.

0 Comments On This Entry

 

Search My Blog

0 user(s) viewing

0 Guests
0 member(s)
0 anonymous member(s)

August 2014

S M T W T F S
     12
3456789
10111213141516
171819 20 212223
24252627282930
31      

Tags

    Recent Entries