블로그 이미지
JEEN

서울에 사는 꽃청년의 IT찌질모험기

Rss feed Tistory
IT/Perl 2008.05.29 11:48

[ Perl ] IRC BOT을 만들어봅시다 :-) #6


IRC BOT을 만들어봅시다 :-) #6

 - #5 에서는

  - Encode 모듈을 사용한 한글 취급에 대해서 알아보았습니다.
  - 실제 사용중인 Bot Command 를 예로 하여, 봇 커맨드 추가/사용 법을 알아보았습니다.

 - #6 에서는

  - IKC를 이용해서 외부 이벤트를 IRC에 알리는 방법에 대해서 알아보겠습니다.


 - IKC

  IKC - Inter-Kernel Communication
  자세한 내용은 PoCo::IKC 페이지를 참조해주세요.
 사실 PoCo::IRC 도 그렇지만, PoCo::IKC 도 제대로는 알지 못합니다. 단지 어디서 이런 것을 써서 구현하고 있다는 것만 보고 단순히 따라하기 수준에만 그친 형편이라서요. CPAN 에는 *::Notify::IRC 모듈이 있는데, 그 중에 Plagger::Plugin::Notify::IRC 와 Kwiki::Notify::IRC 를 참조해서 만들었습니다. Plagger 의 경우에는 Plagger 봇 스크립트를  제공해주고 있으니.. 그것을 대충 수정하면 쓸만하게 됩니다. :-)


 - Tutorial

  우선 적절한 사용예제를 Google 에서 찾고는 긁어와 봤습니다.

use warnings;
use strict;
use POE qw(Session);
use POE::Component::IKC::Server;
use POE::Component::IKC::Specifier;

POE::Component::IKC::Server->spawn(
    port => 31338,               # 포트
    name => 'AppServer',      # 서버이름
);

POE::Session->create(
    inline_states => {
        _start        => \&service_start,     # 초기화 작업 정의
        calc_sum      => \&service_calc_sum, # 작업내용 구현
        did_something => \&service_response, # 작업내용을 클라이언트에 전달
      }
);

POE::Kernel->run();
exit 0;

sub service_start {
    my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];

    my $service_name = "application";
    $kernel->alias_set($service_name); #서비스 이름을 정의해 줍니다.
    $kernel->call( IKC => publish => $service_name, ["calc_sum"] );
     # 해당 서비스이름과 작업을 공표합니다.
     # 이로써 client 에서는 해당 서비스 이름을 통해서 공표된 작업에만 접근할 수 있습니다.
     # calc_sum 이라고 공표된 작업은 위의 POE::Session안에서 inline_states 안에 기술합니다.
     # 고로 calc_sum 이라는 작업이 클라이언트에서 넘어왔을 때, service_calc_sum 을 호출하게 됩니다.
}

sub service_calc_sum {
    my ( $kernel, $heap, $request ) = @_[ KERNEL, HEAP, ARG0 ];
    my ( $data, $rsvp ) = @$request;

    my $sum = 0;
    if ( ref($data) eq "ARRAY" ) {
        $sum += $_ foreach @$data;
    }

    $kernel->delay_set( did_something => 1, $rsvp, $sum );
}

sub service_response {
    my ( $kernel, $heap, $rsvp, $sum ) = @_[ KERNEL, HEAP, ARG0, ARG1 ];
    $kernel->call( IKC => post => $rsvp, $sum );
    # 작업 결과를 넘겨받아 client 로 넘겨줍니다.
}

 이것은 IKC 서버의 구현입니다. 이것을 적당한 이름( ikc-server.pl )으로 저장합니다.
 다음은 클라이언트의 구현입니다.
 
use warnings;
use strict;

use POE::Component::IKC::ClientLite;

my $remote = create_ikc_client(
    port    => 31338,
    name    => "blahblah",
    timeout => 1,
);
die $POE::Component::IKC::ClientLite::error unless $remote;


my $return_value = $remote->post_respond( 'application/calc_sum', [1,2,3,4,5] );
 # 서버에서 지정한 서비스 이름과, 작업을 여기에서 호출됩니다.
die $POE::Component::IKC::ClientLite::error unless defined $return_value;

print "The sum is: $return_value\n";
exit 0;

 이것 역시나 적당한 이름 ( ikc-client.pl ) 로 저장합니다.
 우선 ikc-server.pl 을 실행한 다음에... 다른 터미널을 열어서 ikc-client.pl 를 실행합니다.
 그러면 해당 ikc-client.pl 을 실행한 터미널에서는
 
The sum is: 15

이라는 결과가 뜨게됩니다.

 Client 에서 1,2,3,4,5 라는 배열값(배열의 리퍼런스)을 서버에서 지정한 서비스 이름과 작업에 보내고, Server에서는 그것들을 전부 더해서 그 값을 클라이언트로 보내주는 겁니다.

 이를 응용하면 어떤 것이 가능할까요?

사용자 삽입 이미지
현재 #perl-kr@irc.freenode.org 에서는 CPAN 에 새로 등록된 모듈,
 perlmania 의 새로운 글들, perldoc-kr 에서의 새로운 커밋에 대해서 통보를 받고 있으며,
 #perl@irc.hanIRC.org  <=> #perl-kr@irc.freenode.org 간의 메시지 전달도 가능하게 되었습니다.
 
사용자 삽입 이미지
사용자 삽입 이미지

 [freenode] 라고 붙은 건 freenode 의 대화를 hanIRC에서 받은 것이고,
 [hanIRC] 라고 붙은 건 hanIRC 에서 freenode 의 대화를 받은 것입니다.

 그외에도 CodePad를 도입하고 있습니다. 특정 언어 코드를 웹페이지에 갖다 붙이면,
 그것을 적절하게 컴파일/인터프리트 해서 그 결과를 웹페이지에 보여주게 됩니다.
 모듈 의존성이 있는 코드들에 대한 결과를 자세하게 보지는 못하지만, 그래도 깨끗하게 코드를 볼 수 있습니다.
 
사용자 삽입 이미지

 (1) codepad 에 코드를 넣어서
 (2) 그 결과가 담긴 URL 을 복사해서
 (3) IRC에 붙여넣는다.

 라는 과정을

  (1) codepad 에 코드만 넣으면 끝

으로 축약했습니다.

  CodePad 의 구성을 그대로 빌려와서, WWW::Mechanize 를 통해서 해당 폼 값을 CodePad 로 날려서
그 결과가 되는 URL 을 받아, 그 결과값을 IKC를 통해서 IRC에 자동으로 통보해주는 것입니다.
(이는 saillinux님과 pung96님께서 수고해주셨습니다.)

 위에서 언급한 이런 것들은 모두 perl-irc-bot 에서 구현되어 있습니다. 정리되지 않은 코드라 더럽기도 하지만, "이따위 코드 눈뜨고 봐줄 수 없어! 내가 수정해주겠어!" 라면서 수정펀치 날려주실 분들과 커미터 분들을 모집하고 있습니다. 물론 사용하실 분들은 그냥 사용하셔도 됩니다. :-)

 - THE &

 이상으로 장장 6편에 걸친 그다지 도움되지 않는 IRC BOT 만들기를 마치겠습니다. :-)
 6편 모두는 IRCBOT만들기 라는 태그로 묶어놨습니다.

 제 자신도 공부가 부족한 편이라 깊숙한 계층에서 어떤 일들이 벌어지는 가 자세히 모르기 때문에, 공부하는 입장에서 이렇게 적어봤습니다. 보다 나은 코드와 보다 나은 기능, 보다 편리한 방법, 그리고 보다 깊은 계층에서의 움직임에 대한 격렬한 논의는 아래에 언급된 IRC나 email 로 부탁드리겠습니다. :-)

- PR

※ 현재 POE::Component::IRC를 사용한 Perl Bot 만들기 프로젝트가 진행중입니다.
- http://code.google.com/p/perl-irc-bot
※ 더불어 perldoc을 한글로 번역하기 위한 프로젝트도 진행중입니다.
- http://code.google.com/p/perldoc-kr
※ 거기에 덧붙여 me2day Perl API를 만드는 프로젝트도 진행중입니다.
- http://code.google.com/p/me2day-perl-api

 참여를 원하시면 댓글을 달아주시거나, email: aiatejin@gmail.com
 혹은 IRC(irc.hanirc.org, #perl, irc.freenode.org, #perl-kr)에서 JEEN에게 연락하시면 됩니다.


신고
IT/Perl 2008.05.27 12:57

[ Perl ] IRC BOT을 만들어봅시다 :-) #4

 웃하, 주말 합쳐서 나흘간의 휴가를 받았었는데, 그동안 좀 나태한 모습도 있었고, 그동안 perl-irc-bot 플젝에도 여러개의 새로운 리비젼이 올라오게 되었습니다. [미투데이라든가, 트위터라든가...] 그러는 중에 처음으로 하얀_고양이 님께서도 커밋을 해주시면서 점점 불타오르기 시작했습니다.

IRC BOT을 만들어봅시다 :-) #4

  - #3에서는...

  - IRC 의 이벤트 처리에는 여러가지가 있고, 대부분을 처리할 수 있었습니다.
  - IRC 커맨드에는 여러종류가 있고, 상황에 맞춰서 사용할 수 있었습니다.

  - #4에서는...

   - PoCo::IRC에 Plugin 을 붙여보도록 해보겠습니다. :-)


  - PoCo::Plugin::(.*)

 현재 PoCo::Plugin 모듈은 수십개가 CPAN에 올라와 있습니다. 하지만 그 중에서 쓸만한 것은 별로 없는 편입니다. 현재 제가 사용하는 PoCo::Plugin 모듈은 PoCo::Plugin::URI::FindPoCo::Plugin::Google::Calculator 인데요. 근데 실제로 Google::Calculator 는 별로 사용하지 않는 편입니다. 있는 지도 모르시는 분들이 많고..;; 제가 도움말도 안적어 놔서 그렇습니다.

  - Tutorial

 여기서는 URI::Find 플러그인 모듈을 사용해서 그 URL의 타이틀을 얻어내서 찍어주는 간단한 예를 보이려고 합니다.

use POE qw(Component::IRC      Component::IRC::Plugin::URI::Find                                                                                                               
Component::IRC::Plugin::Google::Calculator                                                                                                      
);

  우선은 사용할 플러그인 모듈들을 use 해줍니다.
  여기서는 *::URI::Find, *::Google::Calculator 모듈을 사용해 보도록 하겠습니다.

POE::Session->create(
    package_states => [
        main => [ qw(_default _start irc_001 irc_public irc_urifind_uri) ],
    ],
    heap => { irc => $irc },
);

 URI::Find 의 경우에는 package_states 에 "irc_urifind_uri" 를 넣어줍니다. irc_public에서 URL을 판별하면 그것을 irc_urifind_uri 로 넘겨주게 됩니다.

sub _start {
    my $heap = $_[HEAP];
   
    my $irc = $heap->{irc};

    $irc->yield( register => 'all' );
    $irc->plugin_add(   'UriFind' =>     POE::Component::IRC::Plugin::URI::Find->new         );
    $irc->plugin_add(   'GoogleCalc' =>  POE::Component::IRC::Plugin::Google::Calculator->new );
    $irc->yield( connect => { } );
    return;
}

 _start 에서 plugin_add 를 통해서 해당 플러그인을 등록해 줍니다.

 Google::Calculator 의 경우에는 여기까지 해주시면 끝입니다.  URI::Find의 경우에는 URL을 판별했을 때 그것을 어떻게 사용할 지를 irc_urifind_uri 에 적어줍니다.
                                                                                                                                  
sub irc_urifind_uri {
    my ($who, $channel, $url, $obj, $msg) = @_[ARG0 .. ARG4];
   
    # (LWP::UserAgent|LWP::Simple) 로 여차저차 해서 <title>(.*)</title> 의 내용 뽑아서
    $title 에 담아서... 이렇게..
 
        $irc->yield( notice => $channel => $title );
    }
}

  URL을 판별했을 때의 irc_urifind_uri 에서 받는 인수는 ARG0 - 누가, ARG1 - 어떤 채널에서, ARG2 - 판별한 URL, ARG3 - URI::URL 의 객체, ARG4 - 무슨 말을 했는지 입니다.

 자, 그럼 그 URL을 받아서 타이틀을 뽑아내서, 넘겨주면 됩니다.
 LWP::Simple, LWP::UserAgent ... 뭐 여러가지가 있습니다. LWP 관련해서 한번 찾아보시면 줄줄줄 엮여져 나옵니다. There's More Than One Way To Do It 이라고 하잖아요.
 이 부분의 구현은 직접 하시면 됩니다. 물론 perl-irc-bot 에는 직접 구현되어 있으니, 참조하셔도 됩니다.

 대부분의 Plugin::(.*) 페이지에 가시면, 간단한 사용 예제를 함께 볼 수 있습니다.

사용자 삽입 이미지

 이렇게 http://www.daum.net/ 이라고 치면 Perl_^^ 이라는 봇은 daum의 타이틀을 따오는 것이죠. 뭐, 어떻게 받아들이느냐에 따라서 별로 쓸데없는 기능이기도 합니다만...

사용자 삽입 이미지

  그리고 아까 위에서 말하다가 그만둔 Google::Calculator 의 사용법입니다.
  봇을 호충하고 calc [ 적당한 식 ] 을 써주시면 됩니다. 여러가지 사용법에 대해서는
PoCo::IRC::Plugin::Google::Calculator 페이지를 참조하시면 됩니다.

 - Summary

  - 간단하게 CPAN 상에 올려진 PoCo::IRC::Plugin::(.+) 에 대해서 알아봤습니다.
  - Plugin 추가/사용에 대해서 간단하게 알아봤습니다.

 - #5 에서는

  - Encode 모듈을 사용한 한글 취급에 대해서 알아보겠습니다.
  - 실제 사용중인 Bot Command 에 대한 사용예제를 보여드리겠습니다.

 - PR
※ 현재 POE::Component::IRC를 사용한 Perl Bot 만들기 프로젝트가 진행중입니다.
- http://code.google.com/p/perl-irc-bot
※ 더불어 perldoc을 한글로 번역하기 위한 프로젝트도 진행중입니다.
- http://code.google.com/p/perldoc-kr
※ 거기에 덧붙여 me2day Perl API를 만드는 프로젝트도 진행중입니다.
- http://code.google.com/p/me2day-perl-api

 참여를 원하시면 댓글을 달아주시거나, email: aiatejin@gmail.com
 혹은 IRC(irc.hanirc.org, #perl)에서 JEEN에게 연락하시면 됩니다.
신고
IT/Perl 2008.05.20 21:56

[ Perl ] IRC BOT을 만들어봅시다 :-) #1


 YAPC::ASIA 2008 의 광풍이 불고난 다음, Perl 을 사용하는 사람에게 남은 숙제는, Perl에 대해 제대로 알리는 것입니다. 그리고 어떻게 하면 그것이 가능하느냐에 대해 수없이 고민을 해보았습니다. 어떻게 하면 좋을까 해서 나온 게 일단 use strict 가 무엇이고 문법이 어떻고를 떠나, 어떻게 하면 Perl에 재미를 느낄 수 있을 까 하는 것입니다.
 그래서 생각한 것이 현재 irc.hanirc.org, #perl 에서 움직이고 있는 Perl_^^ BOT에 대한 내용을 한번 올려보면 어떨까 하는 것에서 시작합니다.
 
사용자 삽입 이미지

 IRC BOT을 만들어봅시다 :-) #1

 - Warning!!

 - 우선 이 내용에 대해서 불건전한 사용에 대한 책임은 지지 않습니다.
 - 본 내용은 "난 Perl 을 들어봤다. Linux 커맨드는 기본적인 것은 알고 있다." 의 조건에 부합하신 분들에게 최적화 되어 있습니다.
 - IRC Port가 열려 있어야 합니다.
 - 여기에서는 제 시스템 환경인 CentOS 5, Perl 5.8 이상의 환경을 기반으로 합니다.
 - 특히 Windows 의 경우에는 사용해 본 적이 없기에 장담할 수 없습니다.

 - Intro...


 IRC BOT 을 만들 기 위해, IRC Protocol 을 미리 다 알 필요는 없습니다(물론 저도 전부 모릅니다).
 미리 IRC 프로토콜에 맞춰서 만들어진 모듈이 이미 존재하고, 이에 대한 내용이 구성되어 있기 때문이죠.

  Perl CPAN 모듈에서 대표적인 IRC 클라이언트 모듈은

  Net::IRCPOE::Component::IRC 가 있습니다.

  이중에서 Net::IRC는 2004년 이후로는 관리되지 않고 있으며,
  POE::Component::IRC 는 2008년 4월까지 꾸준히 계속해서 관리되어 오고 있고, 이 모듈을 위한 여러가지 플러그인들이 존재하고 있습니다.

  그리고 이제부터 다루고자 할 모듈도 POE::Component::IRC(이하 PoCo::IRC) 입니다.

  - Tutorial

  우선적으로 해야할 것은 CPAN Module 의 인스톨입니다.

  대부분의 리눅스계열의 OS는 Perl은 기본적으로 들어가 있고, cpan 역시 기본적으로 지원하고 있습니다.
  만약, root 계정을 사용할 수 없으시거나, 웹 호스팅을 이용하고 계신다면, CPAN Module을 로컬 계정에 설치할 수 있습니다.
  이에 대해서는 펄매니아 위키에 자세히 적혀져 있으므로 참고하세요.

$ cpan
cpan shell -- CPAN exploration and modules installation (v1.9205)
ReadLine support enabled
                                                                                                                                              cpan[1]>

  cpan 을 실행하면 cpan용 터미널이 뜹니다. 이때 인스톨 하실 모듈을 넣어주시면 됩니다.

cpan[1]> install POE::Component::IRC

  그러면 모듈을 설치합니다. 중간에 어떤 것을 물어보신다면 그냥 엔터만 믿고 눌러주시면 됩니다.

cpan[2]> quit

  설치가 종료하면 "quit"으로 나옵니다.

  이상으로 POE::Component::IRC 모듈의 설치가 끝났습니다.

 - Summary

  - IRC 를 이용하기 위한 CPAN Module에는 대표적으로 Net::IRC, POE::Component::IRC 가 있습니다.
  - 웹 호스팅을 이용하시거나, root 계정을 사용할 수 없으실 때에는 이곳을 참조하세요.
  - CPAN Module 을 인스톨 하기 위해서는 "cpan 터미널에서 install [모듈이름]을 입력합니다."
    (혹은 cpan [모듈이름])

 - #2에서는

  - PoCo::IRC를 이용해서 BOT의 Nick 을 설정합니다.
  - IRC 서버에 접속합니다.
  - PoCo::IRC를 이용해서 어떤 처리를 할 수 있는지 알아봅니다.

※ 현재 POE::Component::IRC를 사용한 Perl Bot 만들기 프로젝트가 진행중입니다.
- http://code.google.com/p/perl-irc-bot
※ 더불어 perldoc을 한글로 번역하기 위한 프로젝트도 진행중입니다.
- http://code.google.com/p/perldoc-kr
※ 거기에 덧붙여 me2day Perl API를 만드는 프로젝트도 진행중입니다.
- http://code.google.com/p/me2day-perl-api

 참여를 원하시면 댓글을 달아주시거나, email: aiatejin@gmail.com
 혹은 IRC(irc.hanirc.org, #perl)에서 JEEN에게 연락하시면 됩니다.

신고

'IT > Perl' 카테고리의 다른 글

[ Perl ] IRC BOT을 만들어봅시다 :-) #2  (4) 2008.05.21
[ Perl ] IRC BOT을 만들어봅시다 :-) #1  (6) 2008.05.20
YAPC::Asia 2008 이야기 #3  (2) 2008.05.18
YAPC::Asia 2008 이야기 #2  (0) 2008.05.18
TOTAL 474,090 TODAY 44

티스토리 툴바