App-Ikachan

 view release on metacpan or  search on metacpan

bin/ikachan  view on Meta::CPAN

#!/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 Pod::Usage;
use Plack::Builder;
use Plack::Builder::Conditionals;
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, $irc_user, $no_post_with_join, $irc_post_interval, $irc_reconnect_interval, $enable_ssl) =
    ('127.0.0.1', 4979, undef, 6667, undef, 'ikachan', undef, 0, 2, 3, 0);
my @reverse_proxy;
$parser->getoptions(
    'o|host=s'     => \$http_host,
    'p|port=i'     => \$http_port,
    'r|reverse-proxy=s' => \@reverse_proxy,
    'S|Server=s'   => \$irc_server,
    'P|Port=i'     => \$irc_port,
    'K|Keyword=s'  => \$irc_keyword,
    'N|Nickname=s' => \$irc_nickname,
    'U|User=s'     => \$irc_user,
    'i|interval=s' => \$irc_post_interval,
    'enable-ssl'   => \$enable_ssl,
    'R|reconnect-interval=s' => \$irc_reconnect_interval,
    'j|no-post-with-join' => \$no_post_with_join,
    'h|help'       => \$options{help},
    'v|version'    => \$options{version},
);
pod2usage(1) if $options{help};
pod2usage() unless defined $irc_server;

warn 'connecting to ' . join ' ', ($irc_server, $irc_port, ($irc_keyword || ''), $irc_nickname);

$irc_post_interval ||= 2;

my $irc;
my $join_channels = {};
my $is_connect = 0;
my $create_session; $create_session = sub {
    irc $irc_server,
        key       => $irc_server,
        port      => $irc_port,
        password  => $irc_keyword,
        nickname  => $irc_nickname,
        user      => $irc_user,
        interval  => $irc_post_interval,
        enable_ssl => $enable_ssl,
        on_connect => sub {
            my ($con, $err) = @_;
            if (defined $err) {
                warn "connect error: $err\n";
                exit 1 unless $irc_reconnect_interval;
                sleep $irc_reconnect_interval;
                $con->disconnect('try reconnect');
            } else {
                warn 'connect';
                $is_connect      = 1;
            }
        },
        on_disconnect => sub {
            warn 'disconnect';
            # XXX: bad hack...
            undef $irc->{client};
            undef $irc->{SEND_TIMER};
            undef $irc;
            $is_connect = 0;
            $irc = $create_session->();
        },
        channels => {
            map { $_ => +{} } keys %{ $join_channels },
        };
};
$irc = $create_session->();

sub rendar {
    my($code, $msg) = @_;
    my $res = Plack::Response->new($code);
    $res->content_type('text/plain');
    $res->content_length(length $msg);
    $res->body($msg);
    $res->finalize;
}

sub join_channel {
    my ($channel, $key) = @_;
    $irc->join_channel($channel, $key);
    $join_channels->{$channel} = {
        join_at => time(),
    };
}

my $code = sub {
    my $req = Plack::Request->new(shift);
    my $method = $req->method;
    my $path   = $req->path;

    if ($method eq 'POST' && ! $is_connect) {
        my $html = q{<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>ikachan</title>
    <head>

bin/ikachan  view on Meta::CPAN

  border: 0;
}

.pre-scrollable {
  max-height: 340px;
  overflow-y: scroll;
}

form {
  margin: 0 0 20px;
}

fieldset {
  padding: 0;
  margin: 0;
  border: 0;
}

legend {
  display: block;
  width: 100%;
  padding: 0;
  margin-bottom: 20px;
  font-size: 21px;
  line-height: 40px;
  color: #333333;
  border: 0;
  border-bottom: 1px solid #e5e5e5;
}

legend small {
  font-size: 15px;
  color: #999999;
}

label,
input,
button,
select,
textarea {
  font-size: 14px;
  font-weight: normal;
  line-height: 20px;
}

input,
button,
select,
textarea {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

label {
  display: block;
  margin-bottom: 5px;
}

select,
textarea,
input[type="text"],
input[type="password"],
input[type="datetime"],
input[type="datetime-local"],
input[type="date"],
input[type="month"],
input[type="time"],
input[type="week"],
input[type="number"],
input[type="email"],
input[type="url"],
input[type="search"],
input[type="tel"],
input[type="color"],
.uneditable-input {
  display: inline-block;
  height: 20px;
  padding: 4px 6px;
  margin-bottom: 10px;
  font-size: 14px;
  line-height: 20px;
  color: #555555;
  vertical-align: middle;
  -webkit-border-radius: 4px;
     -moz-border-radius: 4px;
          border-radius: 4px;
}

input,
textarea,
.uneditable-input {
  width: 206px;
}

textarea {
  height: auto;
}

textarea,
input[type="text"],
input[type="password"],
input[type="datetime"],
input[type="datetime-local"],
input[type="date"],
input[type="month"],
input[type="time"],
input[type="week"],
input[type="number"],
input[type="email"],
input[type="url"],
input[type="search"],
input[type="tel"],
input[type="color"],
.uneditable-input {
  background-color: #ffffff;
  border: 1px solid #cccccc;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
     -moz-transition: border linear 0.2s, box-shadow linear 0.2s;
       -o-transition: border linear 0.2s, box-shadow linear 0.2s;
          transition: border linear 0.2s, box-shadow linear 0.2s;
}

textarea:focus,
input[type="text"]:focus,
input[type="password"]:focus,
input[type="datetime"]:focus,
input[type="datetime-local"]:focus,
input[type="date"]:focus,
input[type="month"]:focus,
input[type="time"]:focus,
input[type="week"]:focus,
input[type="number"]:focus,
input[type="email"]:focus,
input[type="url"]:focus,
input[type="search"]:focus,
input[type="tel"]:focus,
input[type="color"]:focus,
.uneditable-input:focus {
  border-color: rgba(82, 168, 236, 0.8);
  outline: 0;
  outline: thin dotted \9;
  /* IE6-9 */

  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
}

input[type="radio"],
input[type="checkbox"] {
  margin: 4px 0 0;
  margin-top: 1px \9;
  *margin-top: 0;
  line-height: normal;
}

input[type="file"],
input[type="image"],
input[type="submit"],
input[type="reset"],
input[type="button"],
input[type="radio"],
input[type="checkbox"] {
  width: auto;
}

select,
input[type="file"] {
  height: 30px;
  /* In IE7, the height of the select element cannot be changed by height, only font-size */

  *margin-top: 4px;
  /* For IE7, add top margin to align select with labels */

  line-height: 30px;
}

select {
  width: 220px;
  background-color: #ffffff;
  border: 1px solid #cccccc;
}

select[multiple],
select[size] {

bin/ikachan  view on Meta::CPAN

.hide {
  display: none;
}

.show {
  display: block;
}

.invisible {
  visibility: hidden;
}

.affix {
  position: fixed;
}
...
}

__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 -S, --Server

irc server address.

=item -P, --Port (default: 6667)

irc server port.

=item --enable-ssl

use ssl connection.

=item -K, --Keyword

irc server password

=item -N, --Nickname

irc nickname

=item -U, --User

irc user name

=item -r, --reverse-proxy

treat X-Forwarded-For as REMOTE_ADDR if REMOTE_ADDR match this argument.

see L<Plack::Middleware::ReverseProxy>.

=item -i, --interval

irc post interval. for Excess Flood

=item -R, --reconnect-interval

interval of reconnect to irc server.
exit application if interval == 0.

=item -j, --no-post-with-join

disable to irc message post with channel join

=back

=head1 AUTHOR

Kazuhiro Osawa E<lt>yappo {at} shibuya {dot} plE<gt>

=head1 SEE ALSO

L<AnySan::Provider::IRC>, L<Twiggy>

=head1 LICENSE

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut



( run in 0.603 second using v1.01-cache-2.11-cpan-5b529ec07f3 )