Index: lang/perl/POE-Component-Client-Nowa/tags/0.02/t/00_compile.t
===================================================================
--- lang/perl/POE-Component-Client-Nowa/tags/0.02/t/00_compile.t (revision 5295)
+++ lang/perl/POE-Component-Client-Nowa/tags/0.02/t/00_compile.t (revision 5295)
@@ -0,0 +1,4 @@
+use strict;
+use Test::More tests => 1;
+
+BEGIN { use_ok 'POE::Component::Client::Nowa' }
Index: lang/perl/POE-Component-Client-Nowa/tags/0.02/MANIFEST
===================================================================
--- lang/perl/POE-Component-Client-Nowa/tags/0.02/MANIFEST (revision 11955)
+++ lang/perl/POE-Component-Client-Nowa/tags/0.02/MANIFEST (revision 11955)
@@ -0,0 +1,18 @@
+Changes
+config.yaml-dist
+inc/Module/Install/Base.pm
+inc/Module/Install/Can.pm
+inc/Module/Install/Fetch.pm
+inc/Module/Install/Include.pm
+inc/Module/Install/Makefile.pm
+inc/Module/Install/Metadata.pm
+inc/Module/Install.pm
+inc/Module/Install/Win32.pm
+inc/Module/Install/WriteAll.pm
+lib/POE/Component/Client/Nowa.pm
+bin/nowa2ircd.pl
+Makefile.PL
+MANIFEST			This list of files
+META.yml
+README
+t/00_compile.t
Index: lang/perl/POE-Component-Client-Nowa/tags/0.02/META.yml
===================================================================
--- lang/perl/POE-Component-Client-Nowa/tags/0.02/META.yml (revision 11956)
+++ lang/perl/POE-Component-Client-Nowa/tags/0.02/META.yml (revision 11956)
@@ -0,0 +1,24 @@
+---
+abstract: 'POE Client of the Nowa'
+author:
+  - 'woremacx <woremacx at cpan dot org>'
+distribution_type: module
+generated_by: 'Module::Install version 0.72'
+license: perl
+meta-spec:
+  url: http://module-build.sourceforge.net/META-spec-v1.3.html
+  version: 1.3
+name: POE-Component-Client-Nowa
+no_index:
+  directory:
+    - inc
+    - t
+requires:
+  FindBin: 0
+  Getopt::Long: 0
+  POE: 0
+  POE::Component::Server::IRC: 0
+  POE::Component::TSTP: 0
+  WebService::Nowa: 0
+  YAML: 0
+version: 0.01
Index: lang/perl/POE-Component-Client-Nowa/tags/0.02/lib/POE/Component/Client/Nowa.pm
===================================================================
--- lang/perl/POE-Component-Client-Nowa/tags/0.02/lib/POE/Component/Client/Nowa.pm (revision 14478)
+++ lang/perl/POE-Component-Client-Nowa/tags/0.02/lib/POE/Component/Client/Nowa.pm (revision 14478)
@@ -0,0 +1,154 @@
+package POE::Component::Client::Nowa;
+
+use strict;
+use warnings;
+
+our $VERSION = '0.02';
+
+use base qw/Class::Accessor::Fast/;
+
+__PACKAGE__->mk_accessors(qw/nowa/);
+
+use POE;
+use WebService::Nowa;
+
+sub spawn {
+    my($class, %args) = @_;
+
+    my $self = bless {}, $class;
+
+    $self->{session_id} = POE::Session->create(
+        object_states => [
+            $self => {
+                map { $_ => "poe_$_" } qw/_start _stop register unregister _unregister notify attach update recent channels channel_recent/
+            },
+        ],
+        args => [ \%args ],
+        heap => { args => \%args },
+    )->ID;
+
+    $self;
+}
+
+sub session_id { $_[0]->{session_id} }
+
+sub yield {
+    my $self = shift;
+    $poe_kernel->post($self->session_id, @_);
+}
+
+sub poe_notify {
+    my($kernel, $heap, $name, $args) = @_[KERNEL, HEAP, ARG0, ARG1];
+    $kernel->post($_ => "nowa.$name" => $args) for keys %{$heap->{listeners}};
+}
+
+sub poe__start {
+    my ($self, $kernel, $heap, $args) = @_[OBJECT, KERNEL, HEAP, ARG0];
+
+    $kernel->alias_set('nowa');
+
+    $heap->{nowa} = WebService::Nowa->new({
+            nowa_id  => $heap->{args}->{nowa_id},
+            password => $heap->{args}->{password},
+            api_pass => $heap->{args}->{api_pass},
+            encode_utf8 => 1,
+        });
+
+    $kernel->yield('attach');
+}
+
+sub poe__stop {}
+
+sub poe_register {
+    my($kernel, $heap, $sender) = @_[KERNEL, HEAP, SENDER];
+    $kernel->refcount_increment($sender->ID, __PACKAGE__);
+    $heap->{listeners}->{$sender->ID} = 1;
+    $kernel->post($sender->ID => "registered" => $_[SESSION]->ID);
+}
+
+
+sub poe_unregister {
+    my($kernel, $heap, $sender) = @_[KERNEL, HEAP, SENDER];
+    $kernel->yield(_unregister => $sender->ID);
+}
+
+sub poe__unregister {
+    my($kernel, $heap, $session) = @_[KERNEL, HEAP, ARG0];
+    $kernel->refcount_decrement($session, __PACKAGE__);
+    delete $heap->{listeners}->{$session};
+}
+
+
+sub poe_attach {
+    my ($kernel, $heap, $args) = @_[KERNEL, HEAP, ARG0];
+
+#    $kernel->delay( attach => 1 );
+}
+
+sub poe_update {
+    my ($self, $kernel, $heap, $message) = @_[OBJECT, KERNEL, HEAP, ARG0];
+    $heap->{nowa}->update_nanishiteru($message);
+}
+
+sub poe_recent {
+    my ($self, $kernel, $heap, $target, $message) = @_[OBJECT, KERNEL, HEAP];
+
+    my $data = $heap->{nowa}->recent;
+    $kernel->yield(notify => 'recent_success', $data);
+}
+
+sub poe_channels {
+    my ($self, $kernel, $heap, $target, $message) = @_[OBJECT, KERNEL, HEAP];
+
+    my $data = $heap->{nowa}->channels;
+    $kernel->yield(notify => 'channels_success', $data);
+}
+
+sub poe_channel_recent {
+    my ($self, $kernel, $heap, $target, $message) = @_[OBJECT, KERNEL, HEAP];
+
+    my $data = $heap->{nowa}->channel_recent;
+    $kernel->yield(notify => 'channel_recent_success', $data);
+}
+
+1;
+__END__
+
+=head1 NAME
+
+POE::Component::Client::Nowa - POE Client of the Nowa
+
+=head1 SYNOPSIS
+
+  use POE::Component::Client::Nowa;
+  # see bin/nowa2ircd.pl for IRCD example
+
+=head1 DESCRIPTION
+
+POE::Component::Client::Nowa is POE Client of the Nowa.
+
+Nowa is the community service run by L<http://www.livedoor.com/> in Japan. See L<http://nowa.jp/>
+
+=head1 AUTHOR
+
+woremacx E<lt>woremacx at cpan dot orgE<gt>
+
+=head1 REPOSITORY
+
+  svn co http://svn.coderepos.org/share/lang/perl/POE-Component-Client-Nowa/
+
+The repository of POE::Component::Client::Nowa is hosted by L<http://coderepos.org/share/>.
+Patches and collaborators are welcome.
+
+=head1 LICENSE
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<http://nowa.jp/>,
+L<WebService::Nowa>,
+L<POE::Component::Client::Twitter>
+
+=cut
Index: lang/perl/POE-Component-Client-Nowa/tags/0.02/Makefile.PL
===================================================================
--- lang/perl/POE-Component-Client-Nowa/tags/0.02/Makefile.PL (revision 11955)
+++ lang/perl/POE-Component-Client-Nowa/tags/0.02/Makefile.PL (revision 11955)
@@ -0,0 +1,14 @@
+use inc::Module::Install;
+name 'POE-Component-Client-Nowa';
+all_from 'lib/POE/Component/Client/Nowa.pm';
+
+requires 'FindBin';
+requires 'Getopt::Long';
+requires 'POE';
+requires 'POE::Component::Server::IRC';
+requires 'POE::Component::TSTP';
+requires 'WebService::Nowa';
+requires 'YAML';
+
+auto_include;
+WriteAll;
Index: lang/perl/POE-Component-Client-Nowa/tags/0.02/config.yaml-dist
===================================================================
--- lang/perl/POE-Component-Client-Nowa/tags/0.02/config.yaml-dist (revision 11955)
+++ lang/perl/POE-Component-Client-Nowa/tags/0.02/config.yaml-dist (revision 11955)
@@ -0,0 +1,16 @@
+---
+irc:
+  servername: nowa.localhost
+  serverport: 16667
+  botname: '[nowa]'
+  nickname: woremacx
+  password: your-ircd-pass
+  mask: '*@*'
+  channel: '#nowa-my-timeline'
+
+nowa:
+  retry: 180
+  nowa_id: your-nowa-id
+  password: your-nowa-pass
+  api_pass: your-nowa-api-pass
+  greeting: 0
Index: lang/perl/POE-Component-Client-Nowa/tags/0.02/Changes
===================================================================
--- lang/perl/POE-Component-Client-Nowa/tags/0.02/Changes (revision 14478)
+++ lang/perl/POE-Component-Client-Nowa/tags/0.02/Changes (revision 14478)
@@ -0,0 +1,7 @@
+Revision history for Perl extension POE::Component::Client::Nowa
+
+0.02  Mon Jun 23 21:58:12 2008
+        - enabled encode_utf8 option
+
+0.01  Mon May 19 08:28:13 2008
+        - initial version
Index: lang/perl/POE-Component-Client-Nowa/tags/0.02/bin/nowa2ircd.pl
===================================================================
--- lang/perl/POE-Component-Client-Nowa/tags/0.02/bin/nowa2ircd.pl (revision 7104)
+++ lang/perl/POE-Component-Client-Nowa/tags/0.02/bin/nowa2ircd.pl (revision 7104)
@@ -0,0 +1,324 @@
+#!/usr/bin/perl
+
+# most of codes were copyed from twitter2ircd.pl
+
+use strict;
+use warnings;
+use FindBin;
+use lib ("$FindBin::Bin/../extlib", "$FindBin::Bin/../lib");
+
+use Data::Dumper;
+use Getopt::Long;
+use POE qw(Component::Client::Nowa Component::Server::IRC Component::TSTP);
+use YAML;
+
+my $conf = "config.yaml";
+GetOptions('-c=s' => \ $conf, '--quiet' => \my $quiet);
+$conf or die "Usage: nowa2ircd.pl -c=config.yaml\n";
+
+my $config = YAML::LoadFile($conf) or die $!;
+
+if ($quiet) {
+    close STDIN;
+    close STDOUT;
+    close STDERR;
+    exit if fork;
+} else {
+    # for Ctrl-Z
+    POE::Component::TSTP->create();
+}
+
+sub msg (@) { print "[msg] ", "@_\n" }
+sub err (@) { print "[err] ", "@_\n" }
+
+my $ircd = POE::Component::Server::IRC->spawn(
+    alias  => 'ircd',
+    config => {
+        servername => $config->{irc}->{servername},
+        nicklen    => 15,
+        network    => 'NowaNET'
+    },
+);
+
+my $nowa = POE::Component::Client::Nowa->spawn(%{ $config->{nowa} });
+
+POE::Session->create(
+    inline_states => {
+        _start   => \&_start,
+        ircd_daemon_nick => \&ircd_nick,
+        ircd_daemon_join => \&ircd_join,
+        ircd_daemon_part => \&ircd_part,
+        ircd_daemon_quit => \&ircd_quit,
+        ircd_daemon_public  => \&ircd_public,
+
+        'nowa.recent' => \&nowa_recent,
+        'nowa.recent_success' => \&nowa_recent_success,
+        'nowa.channel_recent' => \&nowa_channel_recent,
+        'nowa.channel_recent_success' => \&nowa_channel_recent_success,
+        'nowa.channels_success' => \&nowa_channels_success,
+
+        bot_join => \&bot_join,
+        delay_nowa_recent => \&delay_nowa_recent,
+        delay_nowa_channel_recent => \&delay_nowa_channel_recent,
+        delay_nowa_channels => \&delay_nowa_channels,
+
+        _default => \&ircd_default,
+    },
+    options => { trace => 0 },
+    heap => { ircd => $ircd, nowa => $nowa, config => $config, previous_recent => [] },
+);
+
+$poe_kernel->run();
+exit 0;
+
+sub _start {
+    my ($kernel,$heap) = @_[KERNEL,HEAP];
+    my $conf = $heap->{config}->{irc};
+
+    msg '_start';
+
+    # register ircd to receive events
+    $heap->{ircd}->yield('register');
+    $heap->{nowa}->yield('register');
+    $heap->{ircd}->add_auth(
+        mask => $conf->{mask},
+        password => $conf->{password}
+    );
+    $heap->{ircd}->add_listener( port => $conf->{serverport} || 6667 );
+
+    # add super user
+    $heap->{ircd}->yield(add_spoofed_nick => { nick => $conf->{botname} });
+    $heap->{ircd}->yield(daemon_cmd_join => $conf->{botname}, $conf->{channel});
+    $heap->{nowa}->yield('channels');
+
+    $heap->{nicknames} = {};
+    $heap->{channel_nicknames} = {};
+    $heap->{joined}    = 0;
+
+    undef;
+}
+
+sub delay_nowa_recent {
+    my($kernel, $heap) = @_[KERNEL, HEAP];
+
+    msg 'delay_nowa_recent';
+    if ($heap->{joined}) {
+        $heap->{nowa}->yield('recent');
+    }
+}
+
+sub delay_nowa_channel_recent {
+    my($kernel, $heap) = @_[KERNEL, HEAP];
+
+    msg 'delay_nowa_channel_recent';
+    $heap->{nowa}->yield('channel_recent');
+}
+
+sub delay_nowa_channels {
+    my($kernel, $heap) = @_[KERNEL, HEAP];
+
+    msg 'delay_nowa_channels';
+    $heap->{nowa}->yield('channels');
+}
+
+sub nowa_privmsg {
+    my($kernel, $heap, $ret) = @_[KERNEL, HEAP, ARG0];
+    my $conf = $heap->{config}->{irc};
+
+    msg 'nowa_privmsg';
+    $heap->{ircd}->yield(daemon_cmd_notice => $conf->{botname}, $conf->{channel}, $ret->{text});
+}
+
+sub bot_join {
+    my($kernel, $heap, $nick, $ch) = @_[KERNEL, HEAP, ARG0, ARG1];
+
+    msg 'bot_join';
+    return if $heap->{nicknames}->{$nick};
+    $heap->{ircd}->yield(add_spoofed_nick => { nick => $nick });
+    $heap->{ircd}->yield(daemon_cmd_join => $nick, $ch);
+    $heap->{nicknames}->{$nick} = 1;
+}
+
+sub ircd_nick {
+    my($kernel, $heap, $nick, $host) = @_[KERNEL, HEAP, ARG0, ARG5];
+    my $conf = $heap->{config}->{irc};
+
+    return if $nick eq $conf->{botname};
+    return if $heap->{nick_change} || '';
+    if (($host || '') eq $conf->{servername}) {
+        $heap->{ircd}->_daemon_cmd_join($nick, $conf->{channel});
+        $heap->{nick_change} = 1;
+        $heap->{ircd}->_daemon_cmd_nick($nick, $conf->{nickname});
+        delete $heap->{nick_change};
+    }
+
+    $heap->{nick} = $nick;
+}
+
+sub nowa_channels_success {
+    my($kernel, $heap, $res) = @_[KERNEL, HEAP, ARG0];
+    my $conf = $heap->{config}->{irc};
+
+    msg 'nowa_channels_success';
+    while (my ($channel, $topic) = each(%$res)) {
+        unless ($heap->{bot_joined_channel}->{$channel}) {
+            $heap->{bot_joined_channel}->{$channel} = 1;
+            $heap->{ircd}->yield(daemon_cmd_join => $conf->{botname}, $channel);
+            $heap->{ircd}->yield(daemon_cmd_topic => $conf->{botname}, $channel, $topic);
+        }
+    }
+    $heap->{nowa}->{topics} = $res;
+    $kernel->delay('delay_nowa_channels', 1200);
+}
+
+sub ircd_join {
+    my($kernel, $heap, $user, $ch) = @_[KERNEL,HEAP,ARG0,ARG1];
+    my $conf = $heap->{config}->{irc};
+
+    return unless my($nick) = $user =~ /^([^!]+)!/;
+    return if $heap->{nicknames}->{$nick};
+    return if $nick eq $conf->{botname};
+    $heap->{ircd}->yield(add_spoofed_nick => { nick => $nick });
+    if ($ch eq $conf->{channel}) {
+        $heap->{joined} = 1;
+        $heap->{nowa}->yield(update => 'hello, world') if $heap->{config}->{greeting};
+
+        $kernel->delay('delay_nowa_recent', 5);
+    } else {
+        $kernel->delay('delay_nowa_channel_recent', 15) unless $heap->{initial_channel_recent}++;
+    }
+}
+
+sub ircd_part {
+    my($kernel, $heap, $user, $ch) = @_[KERNEL,HEAP,ARG0,ARG1];
+    my $conf = $heap->{config}->{irc};
+
+    return unless my($nick) = $user =~ /^([^!]+)!/;
+    return if $heap->{nicknames}->{$nick};
+    return if $nick eq $conf->{botname};
+
+    if ($ch eq $conf->{channel}) {
+        $heap->{joined} = 0;
+        $heap->{nowa}->yield(update => 'good nite!') if $heap->{config}->{greeting};
+    }
+}
+
+sub ircd_quit {
+    my($kernel, $heap, $user) = @_[KERNEL,HEAP,ARG0];
+    my $conf = $heap->{config}->{irc};
+
+    return unless my($nick) = $user =~ /^([^!]+)!/;
+    return if $heap->{nicknames}->{$nick};
+    return if $nick eq $conf->{botname};
+    $heap->{joined} = 0;
+    $heap->{nowa}->yield(update => 'good nite, yeah!') if $heap->{config}->{greeting};
+}
+
+sub ircd_public {
+    my($kernel, $heap, $user, $channel, $text) = @_[KERNEL, HEAP, ARG0, ARG1, ARG2];
+    my $conf = $heap->{config}->{irc};
+
+    my $status = { status => $text };
+
+    if ($channel ne $conf->{channel}) {
+        $status->{status} = "$channel $status->{status}";
+
+    } elsif ($text =~ /^[\@\>]([a-z0-9\-]+):?\s+(.+)$/i) {
+        my ($nick, $body) = (lc($1), $2);
+        my %cache = map { $_->{user} => $_->{id} } reverse( @{ $heap->{previous_recent} } );
+
+        if ($cache{$nick}) {
+            $status = {
+                parent_id => $cache{$nick},
+                status    => $body,
+            };
+        } else {
+            $status->{status} = "$nick: $body",
+        }
+    }
+
+    $heap->{nowa}->yield(update => $status);
+}
+
+sub nowa_recent_success {
+    my($kernel, $heap, $ret) = @_[KERNEL, HEAP, ARG0];
+    my $conf = $heap->{config}->{irc};
+
+    msg "nowa_recent_success";
+
+    if ($heap->{joined}) {
+        my %prev = map { $_->{permalink} => 1 } @{ $heap->{previous_recent} };
+
+        for my $line (reverse @{ $ret }) {
+            next if $prev{ $line->{permalink} };
+
+            my $name = $line->{user};
+            my $text = $line->{body};
+
+            unless ($heap->{nicknames}->{$name}) {
+                $heap->{ircd}->yield(add_spoofed_nick => { nick => $name });
+                $heap->{ircd}->yield(daemon_cmd_join => $name, $conf->{channel});
+                $heap->{nicknames}->{$name} = 1;
+            }
+
+            if ($heap->{config}->{nowa}->{nowa_id} eq $name) {
+                $heap->{ircd}->yield(daemon_cmd_topic => $conf->{botname}, $conf->{channel}, $text);
+            } else {
+                $heap->{ircd}->yield(daemon_cmd_privmsg => $name, $conf->{channel}, $text);
+            }
+        }
+
+        $heap->{previous_recent} = $ret;
+
+    } else {
+        $heap->{previous_recent} = [];
+    }
+
+    $kernel->delay('delay_nowa_recent', $heap->{config}->{nowa}->{retry});
+}
+
+sub nowa_channel_recent_success {
+    my($kernel, $heap, $ret) = @_[KERNEL, HEAP, ARG0];
+    my $conf = $heap->{config}->{irc};
+
+    msg "nowa_channel_recent_success";
+
+    if (scalar(@$ret)) {
+        my %prev = map { $_->{permalink} => 1 } @{ $heap->{previous_channel_recent} };
+
+        for my $line (reverse @{ $ret }) {
+            next if $prev{ $line->{permalink} };
+
+            my $name = $line->{user};
+            my $text = $line->{body};
+            my $channel = $line->{channel};
+
+            next unless $heap->{bot_joined_channel}->{$channel};
+
+            unless ($heap->{channel_nicknames}->{$channel}->{$name}) {
+                $heap->{ircd}->yield(add_spoofed_nick => { nick => $name });
+                $heap->{ircd}->yield(daemon_cmd_join => $name, $channel);
+                $heap->{channel_nicknames}->{$channel}->{$name} = 1;
+            }
+
+            if ($heap->{config}->{nowa}->{nowa_id} eq $name) {
+warn "yield topic";
+                $heap->{ircd}->yield(daemon_cmd_topic => $conf->{botname}, $channel, $text);
+            } else {
+warn "yield privmsg";
+                $heap->{ircd}->yield(daemon_cmd_privmsg => $name, $channel, $text);
+            }
+        }
+
+        $heap->{previous_channel_recent} = $ret;
+    }
+
+    $kernel->delay('delay_nowa_channel_recent', $heap->{config}->{nowa}->{retry});
+}
+
+sub ircd_default {
+    my ($event, $args) = @_[ARG0 .. ARG1];
+
+    use YAML;
+    warn Dump [$event, $args];
+}
Index: lang/perl/POE-Component-Client-Nowa/tags/0.02/MANIFEST.SKIP
===================================================================
--- lang/perl/POE-Component-Client-Nowa/tags/0.02/MANIFEST.SKIP (revision 5295)
+++ lang/perl/POE-Component-Client-Nowa/tags/0.02/MANIFEST.SKIP (revision 5295)
@@ -0,0 +1,13 @@
+\bRCS\b
+\bCVS\b
+^MANIFEST\.
+^Makefile$
+~$
+\.old$
+^blib/
+^pm_to_blib
+^MakeMaker-\d
+\.gz$
+\.cvsignore
+\.shipit
+^t/9\d_.*\.t
Index: lang/perl/POE-Component-Client-Nowa/tags/0.02/README
===================================================================
--- lang/perl/POE-Component-Client-Nowa/tags/0.02/README (revision 5295)
+++ lang/perl/POE-Component-Client-Nowa/tags/0.02/README (revision 5295)
@@ -0,0 +1,27 @@
+This is Perl module POE::Component::Client::Nowa.
+
+INSTALLATION
+
+POE::Component::Client::Nowa installation is straightforward. If your CPAN shell is set up,
+you should just be able to do
+
+    % cpan POE::Component::Client::Nowa
+
+Download it, unpack it, then build it as per the usual:
+
+    % perl Makefile.PL
+    % make && make test
+
+Then install it:
+
+    % make install
+
+DOCUMENTATION
+
+POE::Component::Client::Nowa documentation is available as in POD. So you can do:
+
+    % perldoc POE::Component::Client::Nowa
+
+to read the documentation online with your favorite pager.
+
+woremacx
Index: lang/perl/POE-Component-Client-Nowa/tags/0.02/.shipit
===================================================================
--- lang/perl/POE-Component-Client-Nowa/tags/0.02/.shipit (revision 11956)
+++ lang/perl/POE-Component-Client-Nowa/tags/0.02/.shipit (revision 11956)
@@ -0,0 +1,1 @@
+steps = FindVersion, ChangeVersion, CheckChangeLog, Commit, Tag, MakeDist
