diff --git a/README b/README
index bf6841b..fed6886 100644
--- a/README
+++ b/README
@@ -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
diff --git a/html/using.html b/html/using.html
index 485d50e..7034733 100644
--- a/html/using.html
+++ b/html/using.html
@@ -97,6 +97,10 @@
Settings
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.
+ twirssi_timestamp_format
- The timestamp format for tweets.
+ Default value is "%H:%M:%S". See the strftime format from the DateTime
+ module.
+
twirssi_hilights
- Should messages containing your @nick be
considered IRC hilights. (default on)
diff --git a/twirssi.pl b/twirssi.pl
index 9a0e2bd..5064a09 100644
--- a/twirssi.pl
+++ b/twirssi.pl
@@ -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);
@@ -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',
@@ -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",
@@ -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;
@@ -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;
@@ -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;
@@ -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;
}
}
}
@@ -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",
@@ -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];
@@ -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;
@@ -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}"
@@ -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} }
@@ -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} );
@@ -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;
@@ -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;
@@ -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";
}
@@ -1995,6 +2051,7 @@ sub event_setup_changed {
retweet_format
stripped_tags
topic_color
+ timestamp_format
/
)
{
@@ -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",