Wednesday, 5 December 2012

ttytter daemon with systemd

Now that Arch Linux has made a permanent move to systemd, I thought I should write up a guide on how to start a ttytter daemon to allow you to log your timeline into a MySQL database using the pwntter extension. Of course, these instructions will work on any such system that utilises systemd.

Service configuration file


Create a file /etc/conf.d/ttytterd and put what ever arguments this instance of TTYtter needs to run as a daemon

# Settings for the TTYtter daemon.
TTYTTERDARGS="-keyf=/root/.ttytterkey -rc=/root/.pwntterrc -exts=/usr/local/bin/pwntter.pl -daemon -hold -backload=500"


Service file

 

Create a file /usr/lib/systemd/system/ttytterd.service

[Unit] 
Description=A TTYtter daemon
Requires=mysqld.service
After=mysqld.service

[Service] 
Type=oneshot 
RemainAfterExit=yes 
# Change the arguments in the file below to suit
EnvironmentFile=/etc/conf.d/ttytterd
ExecStart=/usr/bin/ttytter $TTYTTERDARGS 

[Install] 
WantedBy=multi-user.target 


Finally 

 

Enable and start the service.

systemctl enable ttytterd.service
systemctl start ttytterd.service


Further reading


ttytter documentation

pwntter documentation

Arch Linux systemd documentation

My stats page - warning, it's my home server and is as reliable as I am.




Not much to see, but here it is running automagically

Friday, 19 October 2012

cihip bash script

Just a quickie, I wrote a bash version of my Can I Haz IP script which does little more than display your public IP address by returning content from http://myip.dnsomatic.com. I use it more often than I imagined, so I thought I'd put a copy up here.

#!/bin/sh
#cihip Can I Haz IP?
IP=$(curl -sS http://myip.dnsomatic.com/)
echo $IP

Thursday, 26 April 2012

Your last tweets as mail .sig

Just a quick note. I was enjoying a bit of banter with some TTYtter users (Spanish division) the other day, when the subject of using cowsay with tweets came up. This led on to suggestions of updating one's mail sig with one's latest tweet.

So, here's my take on it using my pwntter database. It does little more that look for my last tweet that is not a reply (starting with @) or an RT (starting with RT) and writing a to a .sig file.

#!/bin/sh

SIGDIR=$HOME/.sig
SIGFILE=$SIGDIR/tweet.sig

if [ ! -e $SIGDIR ]; then

  mkdir -p $SIGDIR

fi

TWEET=`mysql -u pwntter -ppwntter -B -h localhost pwntter << EOF
  SELECT DATE_FORMAT(created_at, '%d-%m-%Y at %H:%i') AS cdate, text
  FROM tweets
  WHERE screen_name = 'pr4wn' AND text NOT RLIKE '^@|^RT\b'
  ORDER BY id DESC LIMIT 1
EOF`

echo -e "\nLast tweet by me [@pr4wn] on ${TWEET:11:19}\n" | tee $SIGFILE
cowsay -w -W 50 ${TWEET:31} | tee -a $SIGFILE



Sample output


Last tweet by me [@pr4wn] on 26-04-2012 at 07:47

 __________________________________________________
/ BLOG: TTYtter related again. Writing your latest \
| pearls of wisdom on twitter to a .sig file.      |
\ http://t.co/VuUvQ1SO                             /
 --------------------------------------------------
        \   ^__^
         \  (OO)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Simply run in crontab as frequently as you think sensible.

Saturday, 21 April 2012

Suppressing DMs you have already read

I don't use direct messages often, so every time I fire up TTYtter, the same DMs appear in my timeline when it performs its "-- checking for most recent direct messages:" function.

It's not a huge issue, but I had a few minutes spare to write an extension to suppress them.

Download the extension here and read the TTYtter documentation on how to run extensions.

Note, the first time you use the extension, it will display the most recent DMs as it will not have stored the ids of them! 

$store->{last_dm_id} = 0; 
$store->{dmbookmark} = "$ENV{'HOME'}/.ttytter.dmbookmark";

if( open( DM, $store->{dmbookmark} ) ) {
 $store->{last_dm_id} = scalar( );
 close( DM ); 
}

$dmhandle = sub {

  my $ref = shift;

  if ( $ref->{id} > $store->{last_dm_id} ) {

    $store->{last_dm_id} = $ref->{id};
    &defaultdmhandle( $ref );

 }

};

$dmconclude = sub {

 if(open(DM, ">".$store->{dmbookmark})) {

   print DM $store->{last_dm_id};
   close( DM ); } 

  else { 
    print $stdout "Failed to write: $!\n"; 

  } 

  &defaultdmconclude; 

};

Sunday, 18 March 2012

Hourly timestamp in your twitter stream

This is such a silly project that I'm only going to post the code here as a curio. I have uploaded the code here in order to keep all it in one place ;-).

I liked the idea of an hourly time code in my twitter stream so started following @big_ben_clock which helpfully BONGs on the hour. This is OK if you are in the same time zone as Big Ben and can quickly enumerate the BONGS at, say, 9 O'Clock but useless otherwise.

I thought it would be worth a couple of minutes of my time to convert the tweet text to a localtime time of the tweets generated by @big_ben_clock making the 'service' more universal and get rid of the BONGS - which wear thin after a while.

UPDATE
@RealIvanSanchez has pointed out that there's an account @coucou_suisse that performs a similar service. So, take your pick.

Here's the code for the TTYtter extension: (needs Date::Manip)

#bigben2localtime
use Date::Manip;

# Simply follow @big_ben_clock or @coucou_suisse and this will replace the tweet with a
# localtime conversion of the tweet timestamp.
# @pr4wn

sub bb_time_convert {
  my $date = shift;
  my $s;

  $s = substr( $date, 8, 5 ); # hh:mm
  return( $s );

}

$handle = sub {


my $ref = shift;

my $ESC = pack("C", 27);
my $BOLDON = ($ansi) ? "${ESC}[1;31m" : '';
my $BOLDOFF = ($ansi) ? "${ESC}[0m" : '';

if ($ref->{user}->{screen_name} eq 'big_ben_clock' ||
$ref->{user}->{screen_name} eq 'coucou_suisse' ) {
   
  my $created_at = ParseDate($ref->{'created_at'});
  $ref->{text} = $BOLDON . bb_time_convert($created_at) . $BOLDOFF;

}

&defaulthandle ( $ref );

}

Here's both accounts showing the same localtime despite being in different time zones.

Monday, 5 March 2012

Filtering your twitter feed with TTYtter

It's no huge deal, but I have noticed that there are certain categories of tweet that I have no interest in. Having written an extension for TTYtter previously, I thought that I'd knock up an extension to filter out tweets using regexp filters.

Of course, I took the precaution of RTFMing the TTYtter documentation before taking on the task, and discovered that the feature already exists, namely, the filter= directive in the .ttytterrc file. The lesson here is RTFM before re-inventing the wheel.

So, for the time being, I'm experimenting with these filters:

filter=(/Please RT/i|/pl[s|z] RT/i | /[@|#]TheWantApp/i | /#getglue/i | /#nowplaying/i | /[#|@]klout/i)

I'll see how it works out over the next few days and see if it behaves.

Update: The filter above works as advertised which is handy to know. I may consider doing a plugin to extend the capability with lists of rules and being able to use regexps on a wider range of data.

Off the top of my head, a rules file like:

#rule 1
( ( $ref->{user}->{screen_name} eq 'pr4wn' ) && ( $ref->{text} =~ /\blinux\b/i ) )
#rule 2
( $ref->{text} =~ /#dullhashtag/i )
#rule n
:
:

Then go through the rules and omit any matches.

Something for a rainy day, perhaps and not particularly urgent - I'm unsure how much it would be used ;-)

And here we have it. A proof of concept that I ran during Question Time (so I could predict active tweeters and hash tags). Apologies to @DIMBLEBOT ;-)

I've dediced to post code similar to below here. Simply download the ttytterkf tar.gz file and off you go.

#ttytterkf
$handle = sub {

  my $ref = shift; 

  my @filter_rules = ( 
  #Rules can be any legal true/false perl conditon, so fill your boots. 
  '( ( ($ref->{user}->{screen_name} =~ /^pr4wn$/i ) && ($ref->{text} =~ /\blinux\b/i ) )',
   #Some test rules to test during Question Time. 
  '( $ref->{user}->{screen_name} =~ /^DIMBLEBOT$/i )', 
  '( $ref->{text} =~ /\bdimbledance/i )',
  '( $ref->{text} =~ /#bbcqt/i )' 
  ); 


  foreach my $rule ( @filter_rules ) { 

    $i = eval $rule; 


    if ( $i == 1 ) { return; } 

  } 


  &defaulthandle( $ref ); 


  return; 


}