App-Ikachan

 view release on metacpan or  search on metacpan

bin/ikachan  view on Meta::CPAN


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>
    <body>
        can not connect to irc server
    </body>
</html>};
        my $res = Plack::Response->new(503);
        $res->content_type('text/html; charset=utf-8');
        $res->content_length(length $html);
        $res->body($html);
        return $res->finalize;
    }

    if ($method eq 'GET') {
        if ($path eq '/channel_list') {
            my $list = [ keys %{ $join_channels } ];
            return rendar(200, join("\n", @$list));
        } elsif ($path eq '/') {
            my $base = $req->base;
            my $logo = get_logo();
            my $css = get_css();
            my $html =<<HTML;
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>ikachan</title>
        <style>
            ${css}

        </style>
    <head>
    <body>
        <div class="container">
        <div class="row"><div class="span12">
        <h1>
            ikachan
            <img src="data:image/png;base64,${logo}" />
        </h1>

        <h2>join channel list</h2>
        <iframe src="/channel_list"></iframe>

        <h2>API usage</u2>

        <h3>channel join</h3>
        <section>
            <table class="table table-bordered">
                <tr><td>method</td><td>POST</td></tr>
                <tr><td>url</td><td>${base}join</td></tr>
                <tr><td>form params</td><td>channel=#channel&channel_keyword=keyword</td></tr>
            </table>
            <h4>testing form</h4>
            <form action="/join" method="post">
                join channel: <input name="channel" /><br />
                channel keyword(option): <input name="channel_keyword" /><input type="submit" value="join" class="btn" />
            </form>
        <section>

        <section>
            <h3>channel leave</h3>
            <table class="table table-bordered">
                <tr><td>method</td><td>POST</td></tr>
                <tr><td>url</td><td>${base}leave</td></tr>
                <tr><td>form params</td><td>channel=#channel</td></tr>
            </table>
            <form action="/leave" method="post">
                leave channel: <input name="channel" /><input type="submit" value="leave" class="btn" />
            </form>
        <section>

        <section>
            <h3>sent notice message to channel</h3>
            <table class="table table-bordered">
                <tr><td>method</td><td>POST</td></tr>
                <tr><td>url</td><td>${base}notice</td></tr>
                <tr><td>form params</td><td>channel=#channel&message=your_message</td></tr>
            </table>
            <form action="/notice" method="post">
                channel: <input name="channel" /><br />
                message: <input name="message" /><input type="submit" value="post" class="btn" />
            </form>
        </section>

        <section>
            <h3>sent privmsg message to channel</h3>
            <table class="table table-bordered">
                <tr><td>method</td><td>POST</td></tr>
                <tr><td>url</td><td>${base}privmsg</td></tr>
                <tr><td>form params</td><td>channel=#channel&message=your_message</td></tr>
            </table>
            <form action="/privmsg" method="post">
                channel: <input name="channel" /><br />
                message: <input name="message" />
                <input type="submit" value="post" class="btn" />
            </form>
        </section>
        </div>
        </div>
    </body>
</html>
HTML

bin/ikachan  view on Meta::CPAN

.badge-important {
  background-color: #b94a48;
}

.label-important[href],
.badge-important[href] {
  background-color: #953b39;
}

.label-warning,
.badge-warning {
  background-color: #f89406;
}

.label-warning[href],
.badge-warning[href] {
  background-color: #c67605;
}

.label-success,
.badge-success {
  background-color: #468847;
}

.label-success[href],
.badge-success[href] {
  background-color: #356635;
}

.label-info,
.badge-info {
  background-color: #3a87ad;
}

.label-info[href],
.badge-info[href] {
  background-color: #2d6987;
}

.label-inverse,
.badge-inverse {
  background-color: #333333;
}

.label-inverse[href],
.badge-inverse[href] {
  background-color: #1a1a1a;
}

.btn .label,
.btn .badge {
  position: relative;
  top: -1px;
}

.btn-mini .label,
.btn-mini .badge {
  top: 0;
}

@-webkit-keyframes progress-bar-stripes {
  from {
    background-position: 40px 0;
  }
  to {
    background-position: 0 0;
  }
}

@-moz-keyframes progress-bar-stripes {
  from {
    background-position: 40px 0;
  }
  to {
    background-position: 0 0;
  }
}

@-ms-keyframes progress-bar-stripes {
  from {
    background-position: 40px 0;
  }
  to {
    background-position: 0 0;
  }
}

@-o-keyframes progress-bar-stripes {
  from {
    background-position: 0 0;
  }
  to {
    background-position: 40px 0;
  }
}

@keyframes progress-bar-stripes {
  from {
    background-position: 40px 0;
  }
  to {
    background-position: 0 0;
  }
}

.progress {
  height: 20px;
  margin-bottom: 20px;
  overflow: hidden;
  background-color: #f7f7f7;
  background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9);
  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));
  background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9);
  background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9);
  background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9);
  background-repeat: repeat-x;
  -webkit-border-radius: 4px;
     -moz-border-radius: 4px;
          border-radius: 4px;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);
  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
     -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
          box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
}

.progress .bar {
  float: left;
  width: 0;
  height: 100%;
  font-size: 12px;
  color: #ffffff;
  text-align: center;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
  background-color: #0e90d2;
  background-image: -moz-linear-gradient(top, #149bdf, #0480be);
  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));
  background-image: -webkit-linear-gradient(top, #149bdf, #0480be);
  background-image: -o-linear-gradient(top, #149bdf, #0480be);
  background-image: linear-gradient(to bottom, #149bdf, #0480be);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0);
  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
     -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
  -webkit-transition: width 0.6s ease;
     -moz-transition: width 0.6s ease;
       -o-transition: width 0.6s ease;
          transition: width 0.6s ease;
}

.progress .bar + .bar {
  -webkit-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);
     -moz-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);
          box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);



( run in 2.464 seconds using v1.01-cache-2.11-cpan-e1769b4cff6 )