<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>EchoTech &#187; Growl</title>
	<atom:link href="http://www.echo-technology.co.uk/tag/growl/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.echo-technology.co.uk</link>
	<description>technology blogging for the moribund</description>
	<lastBuildDate>Tue, 06 Apr 2010 12:35:52 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Displaying Twitter messages using Growl</title>
		<link>http://www.echo-technology.co.uk/2009/12/22/displaying-twitter-messages-using-growl/</link>
		<comments>http://www.echo-technology.co.uk/2009/12/22/displaying-twitter-messages-using-growl/#comments</comments>
		<pubDate>Tue, 22 Dec 2009 14:36:21 +0000</pubDate>
		<dc:creator>Richard Stelling</dc:creator>
				<category><![CDATA[Apple Inc.]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[Growl]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Trowel]]></category>

		<guid isPermaLink="false">http://www.echo-technology.co.uk/?p=363</guid>
		<description><![CDATA[It&#8217;s been well-over a year since I hacked the the first few lines of code for Trowel, the open source, Perl solution to your Twitter and Growl needs.


How to: Growl and Twitter 
Twitter Growl Trowel v1.0
Twitter and Growl — real world solutions

I must confess there was no great plan I just needed a solution, but [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.echo-technology.co.uk%2F2009%2F12%2F22%2Fdisplaying-twitter-messages-using-growl%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.echo-technology.co.uk%2F2009%2F12%2F22%2Fdisplaying-twitter-messages-using-growl%2F" height="61" width="51" /></a></div><p>It&#8217;s been well-over a year since I hacked the the first few lines of code for Trowel, the open source, Perl solution to your Twitter and Growl needs.<br />
<span id="more-363"></span></p>
<ol>
<li><a href="http://www.echo-technology.co.uk/2008/11/11/how-to-growl-and-twitter/">How to: Growl and Twitter</a> </li>
<li><a href="http://www.echo-technology.co.uk/2009/01/26/twitter-growl-trowel-v10/">Twitter Growl Trowel v1.0</a></li>
<li><a href="http://www.echo-technology.co.uk/2009/11/23/twitter-growl-—-real-world-solutions/">Twitter and Growl — real world solutions</a></li>
</ol>
<p>I must confess there was no great plan I just needed a solution, but looking at the comments the above posts generated, so did many of you.</p>
<p>Now <a href="http://www.xs4all.nl/~ipenburg/">Roland van Ipenburg</a> has cleaned up the original code you can <a href="http://www.xs4all.nl/~ipenburg/trowel">download the latest version</a>. But for completeness I have reproduced it below.</p>
<p><code>#!/usr/bin/perl -w<br />
# -*- cperl; cperl-indent-level: 4 -*-<br />
use strict;<br />
use warnings;</p>
<p>## no critic qw(ProhibitLongLines)<br />
# $Id$<br />
# $Revision$<br />
# $HeadURL$<br />
# $Date$<br />
## use critic</p>
<p>use utf8;<br />
use 5.008000;</p>
<p>our $VERSION = '0.01';</p>
<p>use Date::Format;<br />
use Digest::MD5;<br />
use Encode;<br />
use File::HomeDir;<br />
use File::Slurp;<br />
use File::Spec;<br />
use Getopt::Long qw(:config no_ignore_case);<br />
use IO::File;<br />
use Imager;<br />
use LWP::Simple;<br />
use Log::Log4perl qw(:easy get_logger);<br />
use Mac::Growl;<br />
use Net::Twitter;<br />
use Pod::Usage;<br />
use Set::Scalar;</p>
<p>use Readonly ();<br />
## no critic qw(prohibitCallsToUnexportedSubs)<br />
Readonly::Scalar my $EMPTY   => q{};<br />
Readonly::Scalar my $NEWLINE => qq{\n};<br />
Readonly::Scalar my $COMMA   => q{,};<br />
Readonly::Scalar my $ESCAPE  => q{%};</p>
<p>Readonly::Scalar my $APPLICATION       => q{Growl+Twitter=trowel};<br />
Readonly::Scalar my $NOTIFICATION_NAME => q{New Tweet};</p>
<p>Readonly::Scalar my $DEFAULT_FORMAT   => q{%u: %t};<br />
Readonly::Scalar my $MAX_TWEETS       => 200;<br />
Readonly::Scalar my $MAX_TWEETS_INIT  => 5;<br />
Readonly::Scalar my $DISPLAY_INTERVAL => 4;<br />
Readonly::Scalar my $POLL_INTERVAL    => 37;<br />
Readonly::Scalar my $AVATAR_WIDTH     => 32;<br />
Readonly::Scalar my $AVATAR_HEIGHT    => $AVATAR_WIDTH;</p>
<p>Readonly::Scalar my $CACHE_DIR => File::Spec->catdir( File::HomeDir->my_home(),<br />
    qw{Library Caches GrowlHelperApp} );<br />
Readonly::Scalar my $TID_FILE       => q{tweet.id};<br />
Readonly::Scalar my $ENCODING       => q{utf8};<br />
Readonly::Scalar my $AVATAR_TYPE    => q{jpeg};<br />
Readonly::Scalar my $ERR_MODE_SLURP => q{quiet};</p>
<p>Readonly::Array my @CSV_OPTIONS        => qw(exclude include sticky);<br />
Readonly::Array my @NET_TWITTER_TRAITS => qw(InflateObjects Legacy);<br />
## use critic</p>
<p>Log::Log4perl->easy_init($INFO);<br />
my $log = get_logger();</p>
<p>my %options = (<br />
    format   => $DEFAULT_FORMAT,<br />
    poll     => $POLL_INTERVAL,<br />
    interval => $DISPLAY_INTERVAL,<br />
);<br />
foreach my $csv (@CSV_OPTIONS) {<br />
    $options{$csv} = [];<br />
}</p>
<p>Getopt::Long::GetOptions(<br />
    \%options,                  q{username|s=s},<br />
    q{password|p=s},            q{interval|i=i},<br />
    q{poll|l=i},                q{exclude|x=s@},<br />
    q{sticky|t=s@},             q{include|I=s@},<br />
    q{output|o},                qq{initials|n:$MAX_TWEETS_INIT},<br />
    q{format|f=s},              q{config|g=s},<br />
    qq{retrieve|r:$MAX_TWEETS}, q{help|h},<br />
    q{verbose+},                q{exclude_self|X},<br />
    qq{width:$AVATAR_WIDTH},    qq{height:$AVATAR_HEIGHT},<br />
    q{man},<br />
) or Pod::Usage::pod2usage(2);<br />
$options{help} &#038;&#038; Pod::Usage::pod2usage(1);<br />
$options{man} &#038;&#038; Pod::Usage::pod2usage( -verbose => 2 );</p>
<p># Gather comma seperated items or items from multiple options into a set:<br />
foreach my $csv (@CSV_OPTIONS) {<br />
    $options{$csv} =<br />
      Set::Scalar->new( split /$COMMA/xsm, join $COMMA, @{ $options{$csv} } );<br />
}<br />
$options{exclude_self} &#038;&#038; $options{exclude}->insert( $options{username} );</p>
<p>my @names = ($NOTIFICATION_NAME);<br />
$log->debug('Register notifications');<br />
## no critic qw(prohibitCallsToUnexportedSubs)<br />
Mac::Growl::RegisterNotifications( $APPLICATION, \@names, [ $names[0] ] );<br />
## use critic</p>
<p>my $twitter = Net::Twitter->new(<br />
    username => $options{username},<br />
    password => $options{password},<br />
    traits   => \@NET_TWITTER_TRAITS,<br />
);</p>
<p>my $last_id =<br />
## no critic qw(prohibitCallsToUnexportedSubs)<br />
  File::Slurp::read_file( File::Spec->catfile( $CACHE_DIR, $TID_FILE ),<br />
    err_mode => $ERR_MODE_SLURP );<br />
## use critic<br />
my $switch = 0;</p>
<p>$log->debug('Entering poll loop');<br />
while (1) {</p>
<p>    $log->debug('Getting timeline');<br />
    my $ar_timeline = $twitter->friends_timeline(<br />
        $last_id<br />
        ? { count => $MAX_TWEETS, since_id => $last_id }<br />
        : { count => $options{initials} }<br />
    );</p>
<p>    while ( my $tweet = shift @{$ar_timeline} ) {<br />
        $log->debug( 'Processing tweet ' . $tweet->id );<br />
        if ( !$switch ) {<br />
            $last_id = $tweet->id;<br />
## no critic qw(prohibitCallsToUnexportedSubs)<br />
            File::Slurp::write_file(<br />
                File::Spec->catfile( $CACHE_DIR, $TID_FILE ), $last_id );<br />
## use critic<br />
            $switch++;<br />
        }<br />
        next if ( skippable($tweet) );<br />
        my %tweet_data = get_data($tweet);<br />
        if ( $options{output} ) {<br />
## no critic qw(RequireCheckedSyscalls)<br />
            print $tweet_data{body}, $NEWLINE;<br />
## use critic<br />
        }<br />
        else {<br />
            growl( $tweet, \%tweet_data );<br />
        }<br />
    }<br />
    $switch = 0;<br />
    $log->debug( 'Wait ' . $options{poll} . ' seconds' );<br />
    sleep $options{poll};<br />
}</p>
<p>sub skippable {<br />
    my $tweet = shift;<br />
    return ( $options{exclude}->has( $tweet->user->screen_name )<br />
          || !$options{include}->is_null )<br />
      &#038;&#038; !$options{include}->has( $tweet->user->screen_name )<br />
      &#038;&#038; !$options{sticky}->has( $tweet->user->screen_name );<br />
}</p>
<p>sub get_data {<br />
    my $tweet      = shift;<br />
    my %tweet_data = (<br />
        n => $tweet->user->name,<br />
        u => $tweet->user->screen_name,<br />
        t => $tweet->text,<br />
        d => $tweet->created_at,<br />
        l => $tweet->user->location,<br />
    );<br />
    while ( my ( $key => $value ) = each %tweet_data ) {<br />
        ( defined $value )<br />
          &#038;&#038; ( $tweet_data{$key} = Encode::encode( $ENCODING, $value ) );<br />
    }<br />
    $tweet_data{$ESCAPE} = $ESCAPE;<br />
    my $map =<br />
      qq{(?<!$ESCAPE)$ESCAPE([} . join( $EMPTY, keys %tweet_data ) . q{])};<br />
    $log->debug( 'Using map ' . $map );<br />
    my $re = qr{$map}imsx;<br />
    $tweet_data{body} = $options{format};<br />
## no critic qw(ProhibitUselessRegexModifiers RequireLineBoundaryMatching)<br />
    $tweet_data{body} =~ s/$re/$tweet_data{$1}/gxs;<br />
## use critic<br />
    return %tweet_data;<br />
}</p>
<p>sub growl {<br />
    my ( $tweet, $hr_tweet_data ) = @_;<br />
    my $avatar = get_avatar( $tweet, $hr_tweet_data );<br />
## no critic qw(prohibitCallsToUnexportedSubs)<br />
    Mac::Growl::PostNotification(<br />
        $APPLICATION,<br />
        $names[0],<br />
## no critic qw(ProhibitAccessOfPrivateData)<br />
        $hr_tweet_data->{n},<br />
        $hr_tweet_data->{body},<br />
## use critic<br />
        $options{sticky}->has( $tweet->user->screen_name ) ? 1 : 0,<br />
        0,<br />
        $avatar<br />
    );<br />
## use critic<br />
    sleep $options{interval};<br />
    return;<br />
}</p>
<p>sub get_avatar {<br />
    my ( $tweet, $hr_tweet_data ) = @_;<br />
    my $avatar_url = $tweet->user->profile_image_url->as_string;<br />
    my $avatar_file =<br />
      File::Spec->catfile( ($CACHE_DIR), Digest::MD5::md5_hex($avatar_url) );<br />
    $log->debug($avatar_file);<br />
    my $fh = IO::File->new();<br />
    if ( !$fh->open(qq{< $avatar_file}) ) {<br />
        LWP::Simple::mirror( $avatar_url, $avatar_file );<br />
        my $img = Imager->new( file => $avatar_file );<br />
        my $thumb = $img->scale(<br />
            xpixels => $options{width},<br />
            ypixels => $options{height}<br />
        );<br />
        $thumb->write( file => $avatar_file, type => $AVATAR_TYPE );<br />
    }<br />
    $fh->close();<br />
    return $avatar_file;<br />
}</p>
<p>exit;</p>
<p>__END__</p>
<p>=encoding utf8</p>
<p>=head1 NAME</p>
<p>trowel - display Twitter messages with Growl.</p>
<p>=head1 VERSION</p>
<p>This is version 0.01. It's based on<br />
L<http://www.echo-technology.co.uk/2009/01/26/twitter-growl-trowel-v10/></p>
<p>=head1 SYNOPSIS</p>
<p>	trowel -u -p [options]</p>
<p>=head1 DESCRIPTION</p>
<p>Shows the tweets entering a users Twitter timeline as Growl notifications,<br />
including the avatar of the tweep. The format is the message in the<br />
notification is configurable and the avatars are scaled to fit in the standard<br />
Smoke Theme and cached locally.</p>
<p>=head1 DEPENDENCIES</p>
<p>L<Date::Format><br />
L<Digest::MD5><br />
L<Encode><br />
L<File::HomeDir><br />
L<File::Slurp><br />
L<File::Spec><br />
L<Getopt::Long><br />
L<IO::File><br />
L<Imager><br />
L<LWP::Simple><br />
L<Log::Log4perl><br />
L<Mac::Growl><br />
L<Net::Twitter><br />
L<Pod::Usage><br />
L<Set::Scalar></p>
<p>Issue the following command in a Terminal to install these modules:</p>
<p>	sudo /usr/bin/cpan -i Date::Format Digest::MD5 Encode File::Slurp \\<br />
	File::Spec Getopt::Long IO::File Imager LWP::Simple Log::Log4perl \\<br />
	Mac::Growl Net::Twitter Pod::Usage Set::Scalar Readonly \\<br />
	&#038;&#038; sudo /usr/bin/cpan -fi File::HomeDir</p>
<p>=head1 INCOMPATIBILITIES</p>
<p>=over 4</p>
<p>=item * File::HomeDir fails tests when it is being installed as root because<br />
the user root doesn't have some special Folders only normal users have. It can<br />
be installed as root by forcing the install with the -fi option.</p>
<p>=back</p>
<p>=head1 DIAGNOSTICS</p>
<p>This module uses Log::Log4perl for logging.</p>
<p>=head1 BUGS AND LIMITATIONS</p>
<p>=over 4</p>
<p>=item * This script aims to be compatible with the original version or<br />
trowel, but it it not bug-compatible</p>
<p>=item * A missing password option isn't interactively requested later</p>
<p>=item * The format processing is improved so C<%%> can be used to display a<br />
single C<%> and substitutes containing formats aren't clobbered.</p>
<p>=item * The location is not the location of the tweet, but of the account</p>
<p>=back</p>
<p>=head1 CONFIGURATION</p>
<p>To use this script you'll need an account at the Twitter micro-blogging<br />
service. The avatars used are scaled to 32x32 to fit as graphic in the default<br />
Smoke theme of Growl. The scaled avatars and the file containing the id of the<br />
most recent tweet displayed are stored in the cache folder of GrowlhelperApp<br />
in L<~/Library/Caches>.</p>
<p>=head1 USAGE</p>
<p>	trowel -u <twitter_username> -p <twitter_password> [-p -x -t -I -o -f -g<br />
	-h -v -vv -vvv]</p>
<p>=head1 REQUIRED ARGUMENTS</p>
<p>=over 4</p>
<p>=item * B<-u> B<--username> The username of the Twitter account to connect to</p>
<p>=item * B<-p> B<--password> The password of the Twitter account to connect to</p>
<p>=back</p>
<p>=head1 OPTIONS</p>
<p>=over 4</p>
<p>=item B<-u> B<--username> Twitter username</p>
<p>=item B<-p> B<--password> Twitter password</p>
<p>=item B<-i> interval between displaying tweets</p>
<p>=item B<-l> time between polls of Twitter feed</p>
<p>=item B<-x> list of users to exclude</p>
<p>=item B<-X> B<--exclude-self> exclude yourself</p>
<p>=item B<-t> list of users who's tweets are sticky, -x and -i will override<br />
this</p>
<p>=item B<-l> list of users to include</p>
<p>=item B<-o> output to STDOUT only, by-passing Growl, use this for piping to<br />
another application</p>
<p>=item B<-n> initial number of Tweets to request, default is 5</p>
<p>=item B<-f"<br />
<format>"> format of the Tweet<br />
%u - user<br />
%t - tweet<br />
%d - date time<br />
%l - location</p>
<p>=item B<-g> B<--config> a configuration file that sets command line<br />
parameters, this function is not implemented</p>
<p>=item B<-h> B<-help></p>
<p>=item B<-v> verbose mode</p>
<p>=item B<-vv> very verbose mode</p>
<p>=item B<-vvv> debug verbose mode</p>
<p>=item B<-man></p>
<p>=back</p>
<p>=head1 EXIT STATUS</p>
<p>The exit status is determined by L<Pod::Usage><br />
=over 4</p>
<p>=item * 1 </p>
<p>=item * 2</p>
<p>=back</p>
<p>=head1 EXAMPLES</p>
<p>trowel -u<username> -p
<password> -i5 -l180 -f"%t %d"<br />
-ttwitter,stephenfry,rjstelling<br />
-Iguykawasaki,twitter,stephenfry,TechCrunch,rjstelling</p>
<p>=head1 AUTHOR</p>
<p>=over 4</p>
<p>=item * Roland van Ipenburg  C<< <ipenburg@xs4all.nl> >></p>
<p>=item * Echotech L<http://www.echo-technology.co.uk/></p>
<p>=back</p>
<p>=head1 LICENSE AND COPYRIGHT</p>
<p>Copyright (C) 2009 by Roland van Ipenburg</p>
<p>This library is free software; you can redistribute it and/or modify<br />
it under the same terms as Perl itself, either Perl version 5.10.0 or,<br />
at your option, any later version of Perl 5 you may have available.</p>
<p>=head1 DISCLAIMER OF WARRANTY</p>
<p>BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY<br />
FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN<br />
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES<br />
PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER<br />
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED<br />
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE<br />
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH<br />
YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL<br />
NECESSARY SERVICING, REPAIR, OR CORRECTION.</p>
<p>IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING<br />
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR<br />
REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENSE, BE<br />
LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,<br />
OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE<br />
THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING<br />
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A<br />
FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF<br />
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF<br />
SUCH DAMAGES.</p>
<p>=cut</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.echo-technology.co.uk/2009/12/22/displaying-twitter-messages-using-growl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Twitter &amp; Growl — real world solutions</title>
		<link>http://www.echo-technology.co.uk/2009/11/23/twitter-growl-%e2%80%94-real-world-solutions/</link>
		<comments>http://www.echo-technology.co.uk/2009/11/23/twitter-growl-%e2%80%94-real-world-solutions/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 17:23:08 +0000</pubDate>
		<dc:creator>Richard Stelling</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[Growl]]></category>

		<guid isPermaLink="false">http://www.echo-technology.co.uk/?p=345</guid>
		<description><![CDATA[By-far-and-away the most popular blogs I have ever written are How To: Growl and Twitter and Twitter + Growl = Trowel v1.0.
These simple how to&#8217;s, provide a solution to a simple problem. How do I pipe my Twitter time line to Growl?

It shames me to say this but I no longer use my own solutions. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.echo-technology.co.uk%2F2009%2F11%2F23%2Ftwitter-growl-%25e2%2580%2594-real-world-solutions%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.echo-technology.co.uk%2F2009%2F11%2F23%2Ftwitter-growl-%25e2%2580%2594-real-world-solutions%2F" height="61" width="51" /></a></div><p>By-far-and-away the most popular blogs I have ever written are <a href="http://www.echo-technology.co.uk/2008/11/11/how-to-growl-and-twitter/">How To: Growl and Twitter</a> and <a href="http://www.echo-technology.co.uk/2009/01/26/twitter-growl-trowel-v10/">Twitter + Growl = Trowel v1.0</a>.</p>
<p>These <em>simple</em> how to&#8217;s, provide a solution to a simple problem. How do I pipe my <a href="http://twitter.com">Twitter</a> time line to <a href="http://growl.info/">Growl</a>?<br />
<span id="more-345"></span><br />
It shames me to say this but I no longer use my own solutions. If I ever get the time I might write a fully <a href="http://www.echo-technology.co.uk/2009/11/17/apples-misdirection/">Cocoa native solution</a>, but for now here is my real world guide to Twitter and Growl.</p>
<p>
<h1><a href="http://www.atebits.com/tweetie-mac/">Tweetie</a></h1>
</p>
<p>or</p>
<p>
<h1><a href="http://adium.im/">Adium</a></h1>
</p>
<p>Both these application support Growl, they do have limited features but will the best solution for the vast majority of users.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.echo-technology.co.uk/2009/11/23/twitter-growl-%e2%80%94-real-world-solutions/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Twitter + Growl = Trowel v1.0</title>
		<link>http://www.echo-technology.co.uk/2009/01/26/twitter-growl-trowel-v10/</link>
		<comments>http://www.echo-technology.co.uk/2009/01/26/twitter-growl-trowel-v10/#comments</comments>
		<pubDate>Mon, 26 Jan 2009 17:58:29 +0000</pubDate>
		<dc:creator>Richard Stelling</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[Growl]]></category>
		<category><![CDATA[launchd]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://www.echo-technology.co.uk/?p=79</guid>
		<description><![CDATA[You may have already read my how-to on integrating Twitter and Growl but this is the upgrade! I will go through the code for those interested, please help me improve the code by leaving a comment, good or bad.

I have some quite ambitious plans for this project, but this is not the time to bore you with promises, so vaporware it will remain &#8211; for [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: left; margin-right: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.echo-technology.co.uk%2F2009%2F01%2F26%2Ftwitter-growl-trowel-v10%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.echo-technology.co.uk%2F2009%2F01%2F26%2Ftwitter-growl-trowel-v10%2F" height="61" width="51" /></a></div><p>You may have already read my <a href="http://www.echo-technology.co.uk/2008/11/11/how-to-growl-and-twitter/" target="_blank">how-to on integrating Twitter and Growl</a> but this is the upgrade! I will go through the code for those interested, please help me improve the code by leaving a comment, good or bad.</p>
<p><span id="more-79"></span></p>
<p>I have some quite ambitious plans for this project, but this is not the time to bore you with promises, so vaporware it will remain &#8211; for now.</p>
<p>I&#8217;d like to start by thanking everyone who has commented on this project so far &#8211; it&#8217;s been such a big help, keep them coming.</p>
<p> </p>
<h2>What&#8217;s new?</h2>
<p>If you can&#8217;t see a feature you requested its not because I am ignoring it, it&#8217;s simply I haven&#8217;t got round to it or it been superseded. As alway comments will always be read so you can always bug me there.</p>
<p>1. Profile images now supported</p>
<p>2. Run in the background and optionally use launchd</p>
<p>3. Sticky notifications for selected users</p>
<p>4. Loads more command line options</p>
<p> </p>
<h2>Bugs Fixed</h2>
<p>UTF-8 encoding issue.</p>
<p> </p>
<h2>Download</h2>
<p><a title="Download Code" href="http://www.echo-technology.co.uk/development/twitter+growl/trowel.txt" target="_blank">Download here</a>. Remember you&#8217;ll need some command line experience. See an example <a href="/development/twitter+growl/com.edm.trowel.plist.txt" target="_blank">launchd plist file here</a>.</p>
<p> </p>
<h2>Install</h2>
<p>Installation is relatively simple, you will need to install some Perl modules, refer to the <a href="http://www.echo-technology.co.uk/2008/11/11/how-to-growl-and-twitter/">previous post</a> for details.</p>
<p> </p>
<h2>Running</h2>
<p><em>NB: I have split this command for ease of readability.</em></p>
<pre>$ ./trowel -u &lt;&lt;EMAIL&gt;&gt; -p &lt;&lt;PASSOWRD&gt;&gt; -vv \</pre>
<pre>-I guykawasaki,twitter,stephenfry,rjstelling,macrumors,2009show \</pre>
<pre>-t twitter,stephenfry,rjstelling</pre>
<p> </p>
<p><strong>-I </strong>tells the script what to notify you about</p>
<p><strong>-t </strong>makes the notification sticky</p>
<p> </p>
<h2>Know Issues</h2>
<p>There does seem to be an issues when running in launcd mode where Tweets are duplicated, any testing and info you can supply on this bug will help no end.</p>
<p> </p>
<h2>Documentation </h2>
<pre>NAME
		trowel - display Twitter messages with Growl.

SYSOPSIS
		trowel -u -p [options]

EXAMPLES
		trowel -u &lt;username&gt; -p &lt;password&gt; -i 5 -l 180 -f "%t %d" \</pre>
<pre>		-t twitter,stephenfry,rjstelling \</pre>
<pre>		-I guykawasaki,twitter,stephenfry,rjstelling

OPTIONS
		-u, --username
			Twitter username

		-p, --password
			Twitter passord, if omitted it will be </pre>
<pre>		 	requested interactively</pre>
<pre>		-i
			interval between displaying tweets

		-l, --poll
			time between polls of Twitter feed

		-x, --exclude
			list of users to exclude

		-t, --sticky
			list of users who's tweets are sticky, </pre>
<pre>			-x and -i will override this

		-I, --include
			list of users to include

		-o
			output to STDOUT only, by-passing Growl,</pre>
<pre>			 use this for piping to another application

		-n
			initial number of Tweets to request, default is 5 

		-f "&lt;format&gt;"
			format of the Tweet
				%u - user
				%t - tweet
				%d - date time
				%l - location

		-g, --config
			a configuration file that sets command line </pre>
<pre>			parameters, this function is not implemented

		-h, --help
			show this help 

		-v
			verbose mode

		-vv
			very verbose mode

		-vvv
			debug verbose mode</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.echo-technology.co.uk/2009/01/26/twitter-growl-trowel-v10/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
