package Jaipo::Service::Twitter;
use warnings;
use strict;
use Net::Twitter;
use base qw/Jaipo::Service Class::Accessor::Fast/;
use Text::Table;
use App::Cache;
use Lingua::ZH::Wrap 'wrap';
use utf8;
=head2 Jaipo::Console
=head3 Twitter Service Command
=item ?
help message
=item rd
read direct messages
=item rr
read reply messages
=item rp
read public messages
=item rf
read followed timeline messages
=item sd [ID] [MESSAGE]
send direct message
=item sr [ID] [MESSAGE]
send reply message
=item w [ID]
check someone's profile
=item l [LOCATION]
LOCATION is a string, which will be updated to your profile
=item f [ID]
follow someone
=item show friends
show friends
=item show followers
show followers
=cut
sub init {
my $self = shift;
my $caller = shift;
my $opt = $self->options;
unless( $opt->{username} and $opt->{password} ) {
# request to setup parameter
# XXX TODO: simplify this, let it like jifty dbi schema or
# something
$caller->setup_service ( {
package_name => __PACKAGE__,
require_args => [ {
username => {
label => 'Username',
description => '',
type => 'text'
}
},
{ password => {
label => 'Password',
description => '',
type => 'text'
} } ]
},
$opt
);
}
Jaipo->config->set_service_option( 'Twitter' , $opt );
my %twitter_opt = %{ $opt };
# default options
$twitter_opt{useragent} = 'jaipopm';
$twitter_opt{source} = 'jaipopm';
$twitter_opt{clienturl} = 'http://jaipo.org/';
$twitter_opt{clientver} = '0.001';
$twitter_opt{clientname} = 'Jaipo.pm';
my $twitter = Net::Twitter->new( %twitter_opt );
unless( $twitter ) {
# XXX: need to implement logger: Jaipo->log->warn( );
print "twitter init failed\n";
}
print "Twitter Service: " . $opt->{username} . ' => ' . $opt->{trigger_name} . "\n";
$self->core( $twitter );
}
=head2 PRIVATE FUNCTIONS
=cut
sub get_table {
my $self = shift;
my @cols = @_;
my $tb = Text::Table->new( @cols );
return $tb;
}
sub layout_message {
my ( $self , $lines ) = @_;
local $Lingua::ZH::Wrap::columns = 60;
local $Lingua::ZH::Wrap::overflow = 0;
# XXX: lingua::zh::wrap url ... orz
my $out = "";
for ( @$lines ) {
my $source = $_->{source};
# $source =~ s{(.*?)}{$2 ($1)};
$source =~ s{(.*?)}{$2};
my $text = $_->{text} ;
$text =~ s|(http://\S*)|\n$1\n|g ;
my @text_lines = split /\n/,$text;
my $wrap_text = '';
for my $l ( @text_lines ) {
if( $l !~ m{http://} ) {
$wrap_text .= wrap( ' ' x 4 , ' ' x 4 , $l ) . "\n";
}
else {
$wrap_text .= ' ' x 4 . $l . "\n";
}
}
$out .= qq|
@{[ $_->{user}->{name} ]} said:
$wrap_text
-- from $source
|;
}
return $out;
# XXX: we disable text::table currently
# force Message column to be 60 chars width or more.
# my $tb = $self->get_table( qw|User Source Message| );
# for ( @$lines ) {
# my $source = $_->{source};
# # $source =~ s{(.*?)}{$2 ($1)};
# $source =~ s{(.*?)}{$2};
# $tb->add( $_->{user}->{name} , $source , wrap( $_->{text} ) );
# }
# return $tb->table . "";
}
sub get_cache {
my $cache = App::Cache->new({ ttl => 60*60*3 });
return $cache;
}
sub filter_read_message {
my $lines = shift;
my $cache = get_cache;
my $new_lines = [];
for ( @$lines ) {
my $read = $cache->get('twitter_' . $_->{id} );
unless( $read ) {
push @$new_lines , $_;
$cache->set('twitter_' . $_->{id} , 1 );
}
}
return $new_lines;
}
=head2 SERVICE OVERRIDE FUNCTIONS
=cut
sub send_msg {
my ( $self , $message ) = @_;
print "Sending to => " if( Jaipo->config->app('Verbose') );
print $self->options->{trigger_name};
my $result = $self->core->update({ status => $message });
print " [Done]\n" if( Jaipo->config->app('Verbose') );
}
# updates from user himself
sub read_user_timeline {
my $self = shift;
my $lines = $self->core->user_timeline; # XXX: give args to this method
$lines = filter_read_message( $lines );
Jaipo->logger->info( $self->layout_message( $lines ) );
return {
type => 'notification',
message => scalar @$lines . ' Updates',
updates => scalar @$lines
};
}
# updates from user's friends or channel
sub read_public_timeline {
my $self = shift;
my $lines = $self->core->friends_timeline; # XXX: give args to this method
$lines = filter_read_message( $lines );
Jaipo->logger->info( $self->layout_message( $lines ) );
return {
type => 'notification',
message => scalar @$lines . ' Updates',
updates => scalar @$lines
};
}
sub read_global_timeline {
my $self = shift;
my $lines = $self->core->public_timeline; # XXX: give args to this method
$lines = filter_read_message( $lines );
Jaipo->logger->info( $self->layout_message( $lines ) );
return {
type => 'notification',
message => scalar @$lines . ' Updates',
updates => scalar @$lines
};
}
1;