#!/usr/bin/env perl use strict; use warnings; use utf8; use POE qw/ Component::IRC Component::Client::HTTP Component::Client::Lingr /; use Encode; use HTML::Form; use HTTP::Request; use URI; use Path::Class qw/file/; $POE::Component::Client::Lingr::Debug = 1; my $config = { irc => { server => 'irc.freenode.net', port => 6667, nick => 'nak', channels => [ { name => '#yapc.asia', encoding => 'utf-8', }, { name => '#yapc.asia-ja', encoding => 'iso-2022-jp', }, ], }, lingr => { nick => 'nak', api_key => (split /\r?\n/, file('api_key')->slurp)[0], }, mapping => { '#yapc.asia' => 'sharp-yapc.asia', '#yapc.asia-ja' => 'sharp-yapc.asia-ja', }, }; my $irc = POE::Component::IRC->spawn( nick => $config->{irc}{nick}, server => $config->{irc}{server}, port => $config->{irc}{port} || 6667, ircname => $config->{irc}{nick}, ); my $id = 0; my $process = {}; POE::Component::Client::HTTP->spawn( Alias => 'ua', Timeout => 10, ); POE::Session->create( package_states => [ main => [qw/_default _start irc_001 irc_433 irc_public e2j_request e2j_response/], ], heap => { config => $config, irc => $irc }, ); POE::Kernel->run; sub _default { my ($event, @args) = @_[ARG0 .. $#_]; my @output = ("$event: "); for my $arg (@args) { if (ref $arg eq 'ARRAY') { push @output, '[' . join(', ', @$arg) . ']'; } else { push @output, $arg; } } print @output, "\n"; 0; } sub _start { my ($kernel, $heap) = @_[KERNEL, HEAP]; my $irc_session = $heap->{irc}->session_id; $kernel->post( $irc_session => register => 'all' ); $kernel->post( $irc_session => connect => {} ); } sub irc_001 { my ($kernel, $heap, $sender) = @_[KERNEL, HEAP, SENDER]; my $config = $heap->{config}; for my $channel (map { $_->{name} } @{ $config->{irc}{channels} }) { $kernel->post( $sender => join => $channel ); warn 'channel:', $channel; my $lingr = POE::Component::Client::Lingr->spawn; $heap->{lingr_session}{$channel} = POE::Session->create( inline_states => { _start => \&lingr_start, lingr_say => \&lingr_say, 'lingr.session.create' => \&lingr_session_create, 'lingr.room.observe' => \&lingr_room_observe, # 'lingr.error.http' => \&lingr_error, 'lingr.error.response' => \&lingr_error, }, heap => { config => $heap->{config}{lingr}, channel => $heap->{config}{mapping}{$channel}, lingr => $lingr, }, )->ID; } } sub irc_433 { my ($kernel, $heap, $sender, $err ) = @_[KERNEL, HEAP, SENDER, ARG1 ]; my ($nick, $num) = $err =~ /^(\w+)?(\d+)?/; $nick ||= ''; $num ||= 0; $nick = $nick . ++$num; $kernel->post( $sender => nick => $nick ); } sub irc_public { my ( $kernel, $heap, $sender, $who, $where, $what ) = @_[ KERNEL, HEAP, SENDER, ARG0, ARG1, ARG2 ]; my ($nick) = split /!/, $who; my $channel = $where->[0]; my $lingr = $heap->{lingr_session}{$channel} or return; my ($config) = grep { $_->{name} eq $channel } @{ $heap->{config}{irc}{channels} || [] } or return; $nick = decode( $config->{encoding} || 'utf-8', $nick ); my $message = decode( $config->{encoding} || 'utf-8', $what ); $kernel->post( $lingr => lingr_say => "<$nick> $message" ); my $process_id = ++$id; $process->{ $process_id } = { channel => $channel, nick => $nick, message => $message }; $kernel->yield( e2j_request => $process_id ); } sub e2j_request { my ($kernel, $heap, $process_id) = @_[KERNEL, HEAP, ARG0]; my $uri = URI->new('http://www.excite.co.jp/world/english/'); $uri->query_form( before => encode('Shift_JIS', $process->{ $process_id }->{message} ), ); $kernel->post( ua => request => 'e2j_response', HTTP::Request->new( GET => $uri ), $process_id ); } sub e2j_response { my ($kernel, $heap, $request_packet, $response_packet) = @_[KERNEL, HEAP, ARG0, ARG1]; my $response = $response_packet->[0]; my $process_id = $request_packet->[1]; my $process = delete $process->{$process_id}; my $lingr = $heap->{lingr_session}{ $process->{channel} }; my $form; if ( $response->is_success ) { $form = HTML::Form->parse($response->content, $response->base); } if ( $form and my $input = $form->find_input('after') ) { my $result = decode( 'Shift_JIS', $input->value ); $result =~ s/\r?\n//g; $kernel->post( $lingr => lingr_say => "<$process->{nick}> $result" ); } } sub lingr_start { my ($kernel, $heap) = @_[KERNEL, HEAP]; $heap->{lingr}->yield('register'); $heap->{lingr}->yield( call => 'session.create', { api_key => $heap->{config}{api_key} } ); } sub lingr_session_create { my ($kernel, $heap) = @_[KERNEL, HEAP]; warn 'lingr session creatttted'; $heap->{lingr}->yield( call => 'room.enter' => { id => $heap->{channel}, nickname => $heap->{config}{nick} } ); } sub lingr_say { my ($kernel, $heap, $message) = @_[KERNEL, HEAP, ARG0]; $heap->{lingr}->yield( call => 'room.say', { message => $message } ); } sub lingr_room_observe { } sub lingr_error { warn 'error! re-enter the room'; my $heap = $_[HEAP]; $heap->{lingr}->yield( call => 'room.enter' => { id => $heap->{channel}, nickname => $heap->{config}{nick} } ); }