Skip to content
2 changes: 2 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
You may need to use CPAN or another method to install these modules.
* WWW::Shorten::TinyURL
* Net::Twitter
* DateTime
* DateTime::Format::Strptime

### Installation ###
Installation is two part. First
Expand Down
4 changes: 4 additions & 0 deletions html/using.html
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ <h3>Settings</h3>
retweeted; $t is the text of the original tweet; $c is the text of the
optional comment attached; ${ and $} mark the seciton that should be
omitted if no comment was provided.
<li><code>twirssi_timestamp_format</code> - The timestamp format for tweets.
Default value is "%H:%M:%S". See the strftime format from the DateTime
module.</li>


<li><code>twirssi_hilights</code> - Should messages containing your @nick be
considered IRC hilights. (default on)</li>
Expand Down
119 changes: 89 additions & 30 deletions twirssi.pl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
use FileHandle;
use POSIX qw/:sys_wait_h/;
use Net::Twitter qw/3.11009/;
use DateTime::Format::Strptime;
use DateTime;
$Data::Dumper::Indent = 1;

use vars qw($VERSION %IRSSI);
Expand Down Expand Up @@ -46,6 +48,8 @@
my $update_is_running = 0;
my $logfile_fh;
my %settings;
my @datetime_parser;
my $local_tz = DateTime::TimeZone->new( name => 'local' );

my %irssi_to_mirc_colors = (
'%k' => '01',
Expand Down Expand Up @@ -1314,17 +1318,20 @@ sub do_updates {

if ($context) {
my $ctext = &get_text( $context, $obj );
printf $fh "id:%s account:%s nick:%s type:tweet %s\n",
printf $fh "id:%s account:%s nick:%s type:tweet created_at:%s %s\n",
$context->{id}, $username,
$context->{user}{screen_name}, $ctext;
$context->{user}{screen_name},
&encode_for_file($context->{created_at}),
$ctext;
$reply = "reply";
}
}
next
if $t->{user}{screen_name} eq $username
and not $settings{own_tweets};
printf $fh "id:%s account:%s nick:%s type:%s %s\n",
$t->{id}, $username, $t->{user}{screen_name}, $reply, $text;
printf $fh "id:%s account:%s nick:%s type:%s created_at:%s %s\n",
$t->{id}, $username, $t->{user}{screen_name}, $reply,
&encode_for_file($t->{created_at}), $text;
$new_poll_id = $t->{id} if $new_poll_id < $t->{id};
}
printf $fh "id:%s account:%s type:last_id timeline\n",
Expand Down Expand Up @@ -1355,8 +1362,9 @@ sub do_updates {
if exists $friends{ $t->{user}{screen_name} };

my $text = &get_text( $t, $obj );
printf $fh "id:%s account:%s nick:%s type:tweet %s\n",
$t->{id}, $username, $t->{user}{screen_name}, $text;
printf $fh "id:%s account:%s nick:%s type:tweet created_at:%s %s\n",
$t->{id}, $username, $t->{user}{screen_name},
&encode_for_file($t->{created_at}), $text;
$new_poll_id = $t->{id} if $new_poll_id < $t->{id};
}
printf $fh "id:%s account:%s type:last_id reply\n", $new_poll_id, $username;
Expand All @@ -1382,8 +1390,9 @@ sub do_updates {
foreach my $t ( reverse @$tweets ) {
my $text = decode_entities( $t->{text} );
$text =~ s/[\n\r]/ /g;
printf $fh "id:%s account:%s nick:%s type:dm %s\n",
$t->{id}, $username, $t->{sender_screen_name}, $text;
printf $fh "id:%s account:%s nick:%s type:dm created_at:%s %s\n",
$t->{id}, $username, $t->{sender_screen_name},
&encode_for_file($t->{created_at}), $text;
$new_poll_id = $t->{id} if $new_poll_id < $t->{id};
}
printf $fh "id:%s account:%s type:last_id dm\n", $new_poll_id, $username;
Expand Down Expand Up @@ -1422,8 +1431,9 @@ sub do_updates {

foreach my $t ( reverse @{ $search->{results} } ) {
my $text = &get_text( $t, $obj );
printf $fh "id:%s account:%s nick:%s type:search topic:%s %s\n",
$t->{id}, $username, $t->{from_user}, $topic, $text;
printf $fh "id:%s account:%s nick:%s type:search topic:%s created_at:%s %s\n",
$t->{id}, $username, $t->{from_user}, $topic,
&encode_for_file($t->{created_at}), $text;
$new_poll_id = $t->{id}
if not $new_poll_id
or $t->{id} < $new_poll_id;
Expand Down Expand Up @@ -1464,8 +1474,9 @@ sub do_updates {

my $text = &get_text( $t, $obj );
printf $fh
"id:%s account:%s nick:%s type:search_once topic:%s %s\n",
$t->{id}, $username, $t->{from_user}, $topic, $text;
"id:%s account:%s nick:%s type:search_once topic:%s created_at:%s %s\n",
$t->{id}, $username, $t->{from_user}, $topic,
&encode_for_file($t->{created_at}), $text;
}
}
}
Expand Down Expand Up @@ -1525,14 +1536,17 @@ sub get_timeline {

if ($context) {
my $ctext = &get_text( $context, $obj );
printf $fh "id:%s account:%s nick:%s type:tweet %s\n",
printf $fh "id:%s account:%s nick:%s type:tweet created_at:%s %s\n",
$context->{id}, $username,
$context->{user}{screen_name}, $ctext;
$context->{user}{screen_name},
&encode_for_file($context->{created_at}),
$ctext;
$reply = "reply";
}
}
printf $fh "id:%s account:%s nick:%s type:%s %s\n",
$t->{id}, $username, $t->{user}{screen_name}, $reply, $text;
printf $fh "id:%s account:%s nick:%s type:%s created_at:%s %s\n",
$t->{id}, $username, $t->{user}{screen_name}, $reply,
&encode_for_file($t->{created_at}), $text;
$last_id = $t->{id} if $last_id < $t->{id};
}
printf $fh "id:%s account:%s type:last_id_fixreplies %s\n",
Expand All @@ -1541,6 +1555,35 @@ sub get_timeline {
return 1;
}

sub encode_for_file {
my $datum = shift;
$datum =~ s/ /%20/g;
return $datum;
}

sub date_to_epoch {
# parse created_at style date to epoch time
my $date = shift;
if (not @datetime_parser) {
foreach my $date_fmt (
'%a %b %d %T %z %Y', # Fri Nov 05 10:14:05 +0000 2010
'%a, %d %b %Y %T %z', # Fri, 05 Nov 2010 16:59:40 +0000
) {
my $parser = DateTime::Format::Strptime->new(pattern => $date_fmt);
if (not defined $parser) {
@datetime_parser = ();
return;
}
push @datetime_parser, $parser;
}
}
# my $orig_date = $date;
$date = $datetime_parser[index($date, ',') == -1 ? 0 : 1]->parse_datetime($date);
# print "date '$orig_date': " . ref($date) if &debug;
return if not defined $date;
return $date->epoch();
}

sub monitor_child {
my ($data) = @_;
my $filename = $data->[0];
Expand Down Expand Up @@ -1570,7 +1613,7 @@ sub monitor_child {
my $hilight = 0;
my %meta;

foreach my $key (qw/id account nick type topic/) {
foreach my $key (qw/id account nick type topic created_at/) {
if (s/^$key:((?:\S|\\ )+)\s*//) {
$meta{$key} = $1;
$meta{$key} =~ s/%20/ /g;
Expand All @@ -1581,6 +1624,11 @@ sub monitor_child {
next if ($meta{nick} and $meta{nick} =~
/^__(indexes|windows|searches|fixreplies|tweets|last_tweet|last_id)$/);

# convert from text to timestamp
if (exists $meta{created_at}) {
$meta{created_at} = &date_to_epoch($meta{created_at});
}

if ( $meta{type} and $meta{type} eq 'fix_replies_index' ) {
$fix_replies_index{ $meta{account} } = $meta{id};
print "fix_replies_index for $meta{account} set to $meta{id}"
Expand Down Expand Up @@ -1632,13 +1680,13 @@ sub monitor_child {
push @lines,
[
( MSGLEVEL_PUBLIC | $hilight ),
$meta{type}, $account, $meta{nick}, $marker, $_
$meta{type}, $meta{created_at}, $account, $meta{nick}, $marker, $_
];
} elsif ( $meta{type} eq 'search' ) {
push @lines,
[
( MSGLEVEL_PUBLIC | $hilight ),
$meta{type}, $account, $meta{topic},
$meta{type}, $meta{created_at}, $account, $meta{topic},
$meta{nick}, $marker, $_
];
if ( exists $state{__searches}{ $meta{account} }{ $meta{topic} }
Expand All @@ -1652,7 +1700,7 @@ sub monitor_child {
push @lines,
[
( MSGLEVEL_PUBLIC | $hilight ),
$meta{type}, $account, $meta{topic},
$meta{type}, $meta{created_at}, $account, $meta{topic},
$meta{nick}, $marker, $_
];
my $username = &normalize_username( $meta{account} );
Expand All @@ -1661,7 +1709,7 @@ sub monitor_child {
push @lines,
[
( MSGLEVEL_MSGS | $hilight ),
$meta{type}, $account, $meta{nick}, $_
$meta{type}, $meta{created_at}, $account, $meta{nick}, $_
];
} elsif ( $meta{type} eq 'searchid' ) {
print "Search '$meta{topic}' returned id $meta{id}" if &debug;
Expand Down Expand Up @@ -1725,15 +1773,23 @@ sub monitor_child {
if ($first_call) {
print "First call, not printing updates" if &debug;
} else {
# save old timestamp format
my $old_tf = Irssi::settings_get_str('timestamp_format');
foreach my $line (@lines) {
&window( $line->[1], $line->[2] )->printformat(
# set timestamp
Irssi::settings_set_str('timestamp_format',
DateTime->from_epoch( epoch => $line->[2], time_zone => $local_tz
)->strftime($settings{timestamp_format}));
&window( $line->[1], $line->[3] )->printformat(
$line->[0],
"twirssi_" . $line->[1],
@$line[ 2 .. $#$line - 1 ],
@$line[ 3 .. $#$line - 1 ],
&hilight( $line->[-1] )
);
&write_log($line);
}
# recall timestamp format
Irssi::settings_set_str('timestamp_format', $old_tf);
}

close FILE;
Expand Down Expand Up @@ -1813,19 +1869,19 @@ sub monitor_child {
sub write_log {
return unless $logfile_fh;

# 0 1 2 3 4 5 6
# tweet/reply: [ msglevel, type, account, nick, :num, msg ];
# search: [ msglevel, type, account, topic, nick, :num, msg ];
# dm: [ msglevel, type, account, nick, msg ];
# 0 1 2 3 4 5 6 7
# tweet/reply: [ msglevel, type, timestamp, account, nick, :num, msg ];
# search: [ msglevel, type, timestamp, account, topic, nick, :num, msg ];
# dm: [ msglevel, type, timestamp, account, nick, msg ];
# error: [ msglevel, msg ];
my @params = @{ $_[0] };
print $logfile_fh scalar localtime, " - ";
if ( $params[1] eq 'dm' ) {
print $logfile_fh "DM \@$params[3]: $params[4]\n";
print $logfile_fh "DM \@$params[4]: $params[5]\n";
} elsif ( $params[1] eq 'search' or $params[1] eq 'search_once' ) {
print $logfile_fh "Search $params[3]: [\@$params[4]] $params[6]\n";
print $logfile_fh "Search $params[4]: [\@$params[5]] $params[7]\n";
} elsif ( $params[1] eq 'tweet' or $params[1] eq 'reply' ) {
print $logfile_fh "[\@$params[3]] $params[5]\n";
print $logfile_fh "[\@$params[4]] $params[6]\n";
} else {
print $logfile_fh "ERR: $params[1]\n";
}
Expand Down Expand Up @@ -1995,6 +2051,7 @@ sub event_setup_changed {
retweet_format
stripped_tags
topic_color
timestamp_format
/
)
{
Expand Down Expand Up @@ -2243,6 +2300,8 @@ sub window_to_account {
Irssi::settings_add_str( "twirssi", "twirssi_logfile_path", "" );
Irssi::settings_add_str( "twirssi", "twirssi_retweet_format",
'RT $n: "$t" ${-- $c$}' );
Irssi::settings_add_str( "twirssi", "twirssi_timestamp_format",
"%H:%M:%S" );
Irssi::settings_add_str( "twirssi", "twirssi_location",
Irssi::get_irssi_dir . "/scripts/twirssi.pl" );
Irssi::settings_add_str( "twirssi", "twirssi_replies_store",
Expand Down