From 4390800f0c1be62c4df479aa946a37ffa830eb17 Mon Sep 17 00:00:00 2001 From: Kazuhiro Osawa Date: Tue, 16 Aug 2011 15:08:17 +0900 Subject: [PATCH] implimented --- Makefile.PL | 3 +- bin/ikachan | 145 +++++++++++++++++++++++++++++++++++++++++++++ bin/ikachan_client | 101 +++++++++++++++++++++++++++++++ lib/App/Ikachan.pm | 2 +- 4 files changed, 249 insertions(+), 2 deletions(-) create mode 100755 bin/ikachan create mode 100755 bin/ikachan_client diff --git a/Makefile.PL b/Makefile.PL index 3ef52ab..6df7912 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -5,7 +5,8 @@ readme_from 'lib/App/Ikachan.pm'; readme_markdown_from 'lib/App/Ikachan.pm'; githubmeta; -# requires ''; +requires 'AnySan'; +requires 'Twiggy'; tests 't/*.t'; author_tests 'xt'; diff --git a/bin/ikachan b/bin/ikachan new file mode 100755 index 0000000..8420121 --- /dev/null +++ b/bin/ikachan @@ -0,0 +1,145 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use 5.008001; +use File::Spec; +use File::Basename; +use lib File::Spec->catdir(dirname(__FILE__), '..', 'lib'); + +use AnySan; +use AnySan::Provider::IRC; +use Getopt::Long (); +use Plack::Builder; +use Plack::Request; +use Plack::Response; +use Twiggy::Server; + +my $parser = Getopt::Long::Parser->new( + config => [ "no_ignore_case", "pass_through" ], +); + +my %options; +my($http_host, $http_port, $irc_server, $irc_port, $irc_keyword, $irc_nickname) = + ('127.0.0.1', 4979, undef, 6667, undef, 'ikachan'); +$parser->getoptions( + 'o|host=s' => \$http_host, + 'p|port=i' => \$http_port, + 'S|Server=s' => \$irc_server, + 'P|Port=i' => \$irc_port, + 'K|Keyword=s' => \$irc_keyword, + 'N|Nickname=s' => \$irc_nickname, + 'h|help' => \$options{help}, + 'v|version' => \$options{version}, +); + +warn 'connecting to ' . join ' ', ($irc_server, $irc_port, ($irc_keyword || ''), $irc_nickname); + +my $irc = irc $irc_server, + key => $irc_server, + port => $irc_port, + password => $irc_keyword, + nickname => $irc_nickname, + channels => { + }; + +sub rendar { + my($code, $msg) = @_; + my $res = Plack::Response->new($code); + $res->body($msg); + $res->finalize; +} + +my $channels = {}; +my $code = sub { + my $req = Plack::Request->new(shift); + my $method = $req->method; + my $path = $req->path; + + if ($method eq 'GET') { + if ($path eq '/channel_list') { + my $list = [ keys %{ $channels } ]; + return rendar(200, join("\n", @$list)); + } + } elsif ($method eq 'POST') { + my $channel = $req->param('channel'); + + if ($path eq '/join') { + return rendar(403, "joinned channel: $channel") if $channels->{$channel}; + $irc->join_channel($channel); + $channels->{$channel} = { + join_at => time(), + }; + return rendar(200, "join success channel: $channel"); + } elsif ($path eq '/leave') { + return rendar(404, "not joinned channel: $channel") unless $channels->{$channel}; + $irc->leave_channel($channel); + delete $channels->{$channel}; + return rendar(200, "leave success channel: $channel"); + } elsif ($path eq '/notice') { + return rendar(404, "not joinned channel: $channel") unless $channels->{$channel}; + my $message = $req->param('message'); + $irc->send_message( $message, channel => $channel ); + return rendar(200, "message sent channel: $channel $message"); + } + } + + return rendar(404, 'not found'); +}; + +my $app = builder { + enable 'Plack::Middleware::AccessLog', format => 'combined'; + $code; +}; + +warn "starting httpd: http://$http_host:$http_port/"; +my $twiggy = Twiggy::Server->new( + host => $http_host, + port => $http_port, +); +$twiggy->register_service($app); + +AnySan->run; + +__END__ + +=head1 NAME + +ikachan - IRC message delivery by HTTP + +=head1 SYNOPSIS + + # connect to chat.freenode.net + ikachan -S chat.freenode.net + +=head1 OPTIONS + +=over 4 + +=item -o, --host + +The interface a TCP based server daemon binds to. Defauts to undef, +which lets most server backends bind the any (*) interface. This +option doesn't mean anything if the server does not support TCP +socket. + +=item -p, --port (default: 4979) + +The port number a TCP based server daemon listens on. Defaults to +5000. This option doesn't mean anything if the server does not support +TCP socket. + +=item -Server, --Server + +irc server address. + +=item -P, --Port (default: 6667) + +irc server port. + +=item -K, --Keyword + +=item -N, --Nickname + +=back + +=cut diff --git a/bin/ikachan_client b/bin/ikachan_client new file mode 100755 index 0000000..50505ce --- /dev/null +++ b/bin/ikachan_client @@ -0,0 +1,101 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use 5.008001; +use File::Spec; +use File::Basename; +use lib File::Spec->catdir(dirname(__FILE__), '..', 'lib'); + +use App::Ikachan; +use Getopt::Long (); +use LWP::UserAgent; + +my $parser = Getopt::Long::Parser->new( + config => [ "no_ignore_case", "pass_through" ], +); + +my $ikachan_server = 'http://127.0.0.1:4979/'; +$parser->getoptions( + 's|server=s' => \$ikachan_server, +); + +sub usage { + print "ikachan_client +$0 [-s ikachan_server] join #channel +$0 [-s ikachan_server] leave #channel +$0 [-s ikachan_server] notice #channel message +"; +} + +my $command = shift @ARGV; +my $channel = shift @ARGV; +unless ($channel) { + usage(); + exit; +} + +my @params; +if ($command eq 'join') { + @params = ( + "${ikachan_server}join", + +{ + channel => $channel, + }, + ); +} elsif ($command eq 'leave') { + @params = ( + "${ikachan_server}leave", + +{ + channel => $channel, + }, + ); +} elsif ($command eq 'notice') { + my $message = shift @ARGV; + unless ($message) { + usage(); + exit; + } + @params = ( + "${ikachan_server}notice", + +{ + channel => $channel, + message => $message, + }, + ); +} else { + usage(); + exit; +} + +my $ua = LWP::UserAgent->new( + agent => "IkachanClient/$App::Ikachan::VERSION", +); +my $res = $ua->post(@params); +print $res->content . "\n"; + +__END__ + +=head1 NAME + +ikachan - IRC message delivery by HTTP + +=head1 SYNOPSIS + + # join channel + ikachan -s http://127.0.0.1:4979/ join #channel + + # leave channel + ikachan -s http://127.0.0.1:4979/ leave #channel + + # sent message + ikachan -s http://127.0.0.1:4979/ notice #channel message + +=head1 OPTIONS + +=over 4 + +=item -s, --server + +ikachan server url. + +=cut diff --git a/lib/App/Ikachan.pm b/lib/App/Ikachan.pm index 91b0363..86cf8d3 100644 --- a/lib/App/Ikachan.pm +++ b/lib/App/Ikachan.pm @@ -8,7 +8,7 @@ __END__ =head1 NAME -App::Ikachan - +App::Ikachan - IRC message delivery by HTTP =head1 SYNOPSIS