OSDN Git Service

add maxlength to handle privmsg maxlength
[keitairc/keitairc.git] / keitairc
index f351957..fc7afd4 100755 (executable)
--- a/keitairc
+++ b/keitairc
@@ -1,10 +1,8 @@
 #!/usr/bin/perl
 # -*- mode: perl; coding: utf-8 -*-
 # keitairc
-# $Id: keitairc,v 1.82 2010-05-19 00:36:18 ishikawa Exp $
-# $Source: /home/ishikawa/work/keitairc/tmp/keitairc/keitairc,v $
 #
-# Copyright (c) 2003-2008 Jun Morimoto <morimoto@mrmt.net>
+# Copyright (c) 2003-2010 Jun Morimoto <morimoto@mrmt.net>
 # This program is covered by the GNU General Public License 2
 #
 # Depends: libpoe-component-irc-perl,
@@ -22,6 +20,7 @@ use POE::Component::Server::TCP;
 use URI::Escape;
 use HTML::Template;
 use HTTP::Response;
+use HTTP::Status;
 
 use FindBin;
 use lib ("$FindBin::Bin/lib", '/usr/share/keitairc/lib');
@@ -36,25 +35,30 @@ use Keitairc::Log;
 use strict;
 use warnings;
 
-our $cf = new Keitairc::Config({version => '2.0', argv => \@ARGV});
-our $ib = new Keitairc::IrcBuffer({history => $cf->web_lines()});
-our $sm = new Keitairc::SessionManager({default_ttl => $cf->session_ttl()});
-our $pl = new Keitairc::Plugins({config => $cf});
+our $cf = new Keitairc::Config({version => '2.1a1', argv => \@ARGV});
 
 # daemonize
 if($cf->daemonize()){
-       use Proc::Daemon;
-
-       Proc::Daemon::Init;
-       if(length $cf->pid_dir()){
-               if (open(PID, '> ' . $cf->pid_dir() . '/' . $cf->pid_file())) {
-                       print PID $$, "\n";
-                       close(PID);
+       if (eval 'require Proc::Daemon') {
+               require Proc::Daemon;
+               Proc::Daemon::Init();
+               if(length $cf->pid_dir()){
+                       if (open(PID, '> ' . $cf->pid_dir() . '/' . $cf->pid_file())) {
+                               print PID $$, "\n";
+                               close(PID);
+                       }
                }
+               $poe_kernel->has_forked if ($poe_kernel->can('has_forked'));
+       } else {
+               warn('Proc::Daemon module is not installed, could not daemonize');
        }
-       $poe_kernel->has_forked if ($poe_kernel->can('has_forked'));
 }
 
+our $log = new Keitairc::Log({config => $cf});
+our $ib = new Keitairc::IrcBuffer({history => $cf->web_lines()});
+our $sm = new Keitairc::SessionManager({default_ttl => $cf->session_ttl()});
+our $pl = new Keitairc::Plugins({config => $cf});
+
 # create irc component
 our $irc = POE::Component::IRC->spawn(
        Alias => 'keitairc_irc',
@@ -118,8 +122,10 @@ sub http_request{
        # the responses as they are and finish up.
        if($request->isa('HTTP::Response')){
                $heap->{client}->put($request);
+               $log->log_error($request->as_string());
        }elsif(my $response = dispatch($request)){
                $heap->{client}->put($response);
+               $log->log_access($heap->{'remote_ip'}, $request, $response);
        }
 
        $kernel->yield('shutdown');
@@ -131,7 +137,7 @@ sub dispatch{
        my $uri = $request->uri();
        my $ci = new Keitairc::ClientInfo($request);
 
-       Keitairc::Log::log_debug("dispatch: $uri");
+       $log->log_debug("dispatch: $uri");
 
        {
                # chop off $cf->web_root()
@@ -161,15 +167,15 @@ sub dispatch{
                        if($sm->verify({session_id => $1, user_agent => $ci->user_agent()})){
                                return add_cookie($pl->{plugins}->{$name}->{action_imprementation}($request, $name, $1, $2), $1);
                        }
-                       if ($ci->is_ipod() && $cf->webkit_newui()) {
-                               return action_401($request);
+                       if ($ci->is_webkit() && $cf->webkit_newui()) {
+                               return action_error($request, 401);
                        } else {
                                return action_redirect_root($request);
                        }
                }
        }
 
-       return action_public($request, $uri) || action_404($request);
+       return action_public($request, $uri) || action_error($request, 404);
 }
 
 ################################################################
@@ -204,13 +210,13 @@ sub action_login{
        my $content = $request->decoded_content();
        my ($password) = ($content =~ /^password=(.*)/);
 
-       Keitairc::Log::log_debug("password [$password]");
-       Keitairc::Log::log_debug("web_password [" . $cf->web_password() . "]");
+       $log->log_debug("password [$password]");
+       $log->log_debug("web_password [" . $cf->web_password() . "]");
 
        if($cf->web_password() eq $password){
                my $s = $sm->add($ci->user_agent(), $ci->serial_key());
                my $view = new Keitairc::View($cf, $ci, $s->{id});
-               if ($ci->is_ipod() && $cf->webkit_newui()) {
+               if ($ci->is_webkit() && $cf->webkit_newui()) {
                        return add_cookie($view->redirect('/'), $s->{id});
                } else {
                        return $view->redirect("/$s->{id}/index");
@@ -223,27 +229,23 @@ sub action_login{
 }
 
 ################################################################
-sub action_401{
+sub action_error {
        my $request = shift;
+       my $error_code = shift;
        my $ci = new Keitairc::ClientInfo($request);
        my $view = new Keitairc::View($cf, $ci);
-       return $view->render('401.html', { action => $request->uri(), _http_status_code => 401 });
-}
-
-sub action_404{
-       my $request = shift;
-       my $ci = new Keitairc::ClientInfo($request);
-       my $view = new Keitairc::View($cf, $ci);
-       return $view->render('404.html', { action => $request->uri(), _http_status_code => 404 });
+       return $view->render('error.html', { action => $request->uri(),
+                                            _http_status_code => $error_code,
+                                            _http_status_message => status_message($error_code) });
 }
 
 ################################################################
-sub action_public{
+sub action_public {
        my $request = shift;
        my $uri = shift;        # such as '/favicon.ico'
        my $ci = new Keitairc::ClientInfo($request);
        my $view = new Keitairc::View($cf, $ci);
-       return $view->public($uri);
+       return $view->public($request, $uri);
 }
 
 ################################################################
@@ -258,14 +260,14 @@ sub action_login_icc{
                if(length $docomo_foma_icc){
                        if(my $s = $sm->verify({serial_key => $docomo_foma_icc,
                                                user_agent => $ci->user_agent()})){
-                               Keitairc::Log::log_debug("redirect to /$s->{id}/index from docomo_foma_icc");
+                               $log->log_debug("redirect to /$s->{id}/index from docomo_foma_icc");
                                my $view = new Keitairc::View($cf, $ci, $s->{id});
                                return $view->redirect("/$s->{id}/index");
                        }
 
                        if($docomo_foma_icc eq $cf->docomo_foma_icc()){
                                my $s = $sm->add($ci->user_agent(), $docomo_foma_icc);
-                               Keitairc::Log::log_debug("redirect to /$s->{id}/index from docomo_foma_icc");
+                               $log->log_debug("redirect to /$s->{id}/index from docomo_foma_icc");
                                my $view = new Keitairc::View($cf, $ci, $s->{id});
                                return $view->redirect("/$s->{id}/index");
                        }
@@ -294,14 +296,14 @@ sub action_login_imodeid{
                if(length $docomo_imodeid){
                        if(my $s = $sm->verify({serial_key => $docomo_imodeid,
                                                user_agent => $ci->user_agent()})){
-                               Keitairc::Log::log_debug("redirect to /$s->{id}/index from docomo_imodeid");
+                               $log->log_debug("redirect to /$s->{id}/index from docomo_imodeid");
                                my $view = new Keitairc::View($cf, $ci, $s->{id});
                                return $view->redirect("/$s->{id}/index");
                        }
 
                        if($docomo_imodeid eq $cf->docomo_imodeid()){
                                my $s = $sm->add($ci->user_agent(), $docomo_imodeid);
-                               Keitairc::Log::log_debug("redirect to /$s->{id}/index from docomo_imodeid");
+                               $log->log_debug("redirect to /$s->{id}/index from docomo_imodeid");
                                my $view = new Keitairc::View($cf, $ci, $s->{id});
                                return $view->redirect("/$s->{id}/index");
                        }
@@ -328,9 +330,9 @@ sub action_root{
                if(defined($session_id) && length($session_id)){
                        if($sm->verify({session_id => $session_id,
                                        user_agent => $ci->user_agent()})){
-                               Keitairc::Log::log_debug("redirect to /$session_id/index from cookie");
+                               $log->log_debug("redirect to /$session_id/index from cookie");
                                my $view = new Keitairc::View($cf, $ci, $session_id);
-                               if ($ci->is_ipod() && $cf->webkit_newui()) {
+                               if ($ci->is_webkit() && $cf->webkit_newui()) {
                                        return add_cookie($view->render('root_home.html', {sid => $session_id}), $session_id);
                                } else {
                                        return $view->redirect("/$session_id/index");
@@ -344,14 +346,14 @@ sub action_root{
                if(length $subscriber_id){
                        if(my $s = $sm->verify({serial_key => $subscriber_id,
                                                user_agent => $ci->user_agent()})){
-                               Keitairc::Log::log_debug("redirect to /$s->{id}/index from subscriber_id");
+                               $log->log_debug("redirect to /$s->{id}/index from subscriber_id");
                                my $view = new Keitairc::View($cf, $ci, $s->{id});
                                return $view->redirect("/$s->{id}/index");
                        }
 
                        if($subscriber_id eq $cf->au_subscriber_id()){
                                my $s = $sm->add($ci->user_agent(), $subscriber_id);
-                               Keitairc::Log::log_debug("redirect to /$s->{id}/index from au_subscriber_id");
+                               $log->log_debug("redirect to /$s->{id}/index from au_subscriber_id");
                                my $view = new Keitairc::View($cf, $ci, $s->{id});
                                return $view->redirect("/$s->{id}/index");
                        }
@@ -363,13 +365,13 @@ sub action_root{
                if(length $serial_key){
                        if(my $s = $sm->verify({serial_key => $serial_key,
                                                user_agent => $ci->user_agent()})){
-                               Keitairc::Log::log_debug("redirect to /$s->{id}/index from softbank serial_key");
+                               $log->log_debug("redirect to /$s->{id}/index from softbank serial_key");
                                my $view = new Keitairc::View($cf, $ci, $s->{id});
                                return $view->redirect("/$s->{id}/index");
                        }
                        if($serial_key eq $cf->softbank_serial_key()){
                                my $s = $sm->add($ci->user_agent(), $serial_key);
-                               Keitairc::Log::log_debug("redirect to /$s->{id}/index from softbank_serial_key");
+                               $log->log_debug("redirect to /$s->{id}/index from softbank_serial_key");
                                my $view = new Keitairc::View($cf, $ci, $s->{id});
                                return $view->redirect("/$s->{id}/index");
                        }
@@ -381,14 +383,14 @@ sub action_root{
                if(length $userid){
                        if(my $s = $sm->verify({serial_key => $userid,
                                                user_agent => $ci->user_agent()})){
-                               Keitairc::Log::log_debug("redirect to /$s->{id}/index from userid");
+                               $log->log_debug("redirect to /$s->{id}/index from userid");
                                my $view = new Keitairc::View($cf, $ci, $s->{id});
                                return $view->redirect("/$s->{id}/index");
                        }
 
                        if($userid eq $cf->emobile_userid()){
                                my $s = $sm->add($ci->user_agent(), $userid);
-                               Keitairc::Log::log_debug("redirect to /$s->{id}/index from emobile_userid");
+                               $log->log_debug("redirect to /$s->{id}/index from emobile_userid");
                                my $view = new Keitairc::View($cf, $ci, $s->{id});
                                return $view->redirect("/$s->{id}/index");
                        }
@@ -420,16 +422,23 @@ sub parse_message{
 
        if(length($message)){
                ($message, $timestamp) = split(/&/, $message);
+
                $timestamp =~ s/^stamp=//g;
 
                $message =~ s/^m=//;
                $message =~ s/\+/ /g;
                $message = uri_unescape($message);
-               if($ci->is_ipod()){
-                       $message = fix_iui_escape($message);
+
+               if($ci->is_webkit() && !$cf->webkit_newui()){
+                       $message = fix_webkit_escape($message);
                }
        }
-
+       if ($cf->webkit_newui()) {
+               # ajax で投げ込んでるので utf8 できます
+               $message = Encode::decode('utf8', $message);
+       } else {
+               $message = Encode::decode($cf->web_charset(), $message);
+       }
        return ($message, $timestamp);
 }
 
@@ -440,13 +449,12 @@ sub send_message{
        my ($message, $timestamp) = parse_message($request);
 
        if(length($message) && length($channel)){
-               my $jis = $message;
-               Encode::from_to($jis, $cf->web_charset(), $cf->irc_charset());
-               my $euc = Encode::decode($cf->web_charset(), $message);
                if($ib->update_timestamp($timestamp)){
-                       $irc->yield(privmsg => $channel => $jis);
+                       my $enc_message = Encode::encode($cf->irc_charset(), $message);
+                       my $enc_channel = Encode::encode($cf->irc_charset(), $channel);
+                       $irc->yield(privmsg => $enc_channel => $enc_message);
                        my $cid = $ib->name2cid($channel);
-                       $ib->add_message($cid, $euc, $cf->irc_nick());
+                       $ib->add_message($cid, $message, $cf->irc_nick());
                }
        }
 }
@@ -457,7 +465,6 @@ sub send_command{
        my ($message, $timestamp) = parse_message($request);
 
        if(length($message)){
-               Encode::from_to($message, $cf->web_charset(), $cf->irc_charset());
                if($message =~ s|^/||) {
                        my ($params, $trailing) = split(/ :/, $message, 2);
                        my @postcmd = split(/ /, $params);
@@ -474,23 +481,23 @@ sub send_command{
                                        return;
                                }
                        }
-                       $irc->yield(@postcmd);
+                       $irc->yield(map { Encode::encode($cf->irc_charset(), $_) } @postcmd);
                }
        }
 }
 
 ################################################################
-# posted string from iPhone/iPod touch (with iui framework)
+# posted string from Webkit browser
 # contains escaped utf-8 in the form %uXXXX
 # and may contains escaped Shift-JIS (web_charset) in the form \xXX
 # when operated from Safari/Mac OS X
-sub fix_iui_escape{
+sub fix_webkit_escape{
        # charset: $cf->irc_charset()
        my $in = shift;
        $in =~ s/\\x([0-9A-F]{2})/pack('C',hex($1))/egi;
-       my $pi = Encode::decode($cf->web_charset(), $in);
-       $pi =~ s/%u([0-9A-F]{4})/pack('U',hex($1))/egi;
-       return Encode::encode($cf->web_charset(), $pi);
+       #my $pi = Encode::decode('utf8', $in);
+       $in =~ s/%u([0-9A-F]{4})/pack('U',hex($1))/egi;
+       return $in;
 }
 
 __END__