#!c:\perl\bin\perl.exe ###################################################################### ## デジタルテロッパ(EN-NL1068)用2ch実況スレチェック サンプルスクリプト ## ver.20101013 ActivePerl動作確認済み ## by ckom, デジモノに埋もれる日々 (http://c-kom.homeip.net/review/blog/) use strict; use warnings; use utf8; use LWP::UserAgent; use HTTP::Request::Common qw(GET POST); use Encode; use URI::Escape; ###################################################################### ## 設定 my $telopper_ip = "xxx.xxx.xxx.xxx"; ## デジタルテロッパのIPアドレス my $MAX_CALL = 5; ## 大量のレスが取得できたとき、一度にAPIをコールする最大回数 my $INTERVAL_SEC = 10; ## チェック間隔(sec) my $target_board_url = "http://hayabusa.2ch.net/liveskyp/"; ## ウォッチ先の2ch板URL my $keywords = "AT-X"; ## 絞りこみキーワード(半角スペース区切りでOR扱い) ###################################################################### ## メイン my %count_by_dat_id = (); my %title_by_dat_id = (); ## 無限ループ while ( 1 == 1 ) { ## 板URLとキーワードから対象スレッドを絞って取得 my @target_thread_list = &get_target_thread_list( $target_board_url, $keywords ); my $target_dat_id = ""; my $diff_count = 0; foreach my $thread_info ( @target_thread_list ) { my $dat_id = $thread_info->{dat_id}; my $title = $thread_info->{title}; my $count = $thread_info->{count}; print Encode::encode( 'cp932', "$dat_id, $title, $count\n" ); if ( exists $count_by_dat_id{"$dat_id"} ) { ## 過去に取得済みのスレッドで if ( $count > $count_by_dat_id{"$dat_id"} ) { ## カウント数が増えていて my $diff_count_tmp = $count - $count_by_dat_id{"$dat_id"}; if ( $diff_count_tmp > $diff_count ) { ## 一番カウントの増え幅が大きいとき ## ターゲットスレッドに認定 $target_dat_id = $dat_id; $diff_count = $diff_count_tmp; } } } ## 今回チェックしたカウント数等をとっておく $count_by_dat_id{"$dat_id"} = $count; $title_by_dat_id{"$dat_id"} = $title; } if ( $target_dat_id eq "" ) { ## カウント数が増えていたスレッドが1つもなかったら何もしない print "no update dat.\n"; } else { ## カウント数が増えていたスレッドが存在した print Encode::encode( 'cp932', "UPDATE: $target_dat_id, " .($title_by_dat_id{"$target_dat_id"}). ", " .($count_by_dat_id{"$target_dat_id"}). ", $diff_count\n" ); ## 対象スレッドのdatを取得 my $thread_url = "$target_board_url/dat/$target_dat_id.dat"; my $TIMEOUT_SEC = 10; my $dat = &http_get( $thread_url, 'cp932', $TIMEOUT_SEC ); my @dat_lines = split( /\n/, $dat ); my $update_count = 0; my @update_text = (); foreach my $line ( reverse @dat_lines ) { ## 新しいほう(行でいうと逆順)から見て、 my ( $name, $mail, $date, $text ) = split( /<>/, $line ); $text = &cleanup_text( $text ); ## タグ等の余分なデータをクリーンアップ print Encode::encode( 'cp932', "$text\n" ); push( @update_text, $text ); ## 書き込みを内容を保存 $update_count ++; if ( $update_count >= $diff_count ) { last; } ## 今回増えていたカウント数だけで止める } my $call_count = 0; foreach my $text ( reverse @update_text ) { &telopper_api_call( $telopper_ip, $text ); ## テロッパにデータを送信 $call_count ++; if ( $call_count >= $MAX_CALL ) { last; } } } sleep $INTERVAL_SEC; ## ウェイト } exit; ###################################################################### ## サブルーチン ## デジタルテロッパにデータを送信する。 sub telopper_api_call { my ( $ip, $text ) = @_; my $text_utf8 = Encode::encode( 'utf8', $text ); my $TIMEOUT_SEC = 5; my $text_escaped = URI::Escape::uri_escape( $text_utf8 ); my $api_url = "http://$ip/user.cgi?data=$text_escaped"; my $res = &http_get( $api_url, 'utf8', $TIMEOUT_SEC ); return ; } ## レス内容からタグを除去したり、特殊文字を戻したりする(かなり適当) sub cleanup_text { my ( $text ) = @_; $text =~ s/<.*?>//g; $text =~ s/\s+/ /; ( $text ) =~ ( $text =~ m|^\s*(.*?)\s*$| ); $text =~ s/^\s+//; $text =~ s/>/>/g; $text =~ s/</| ); my ( $title ) = ( $line =~ m|<>\s*(.*?)\s*\(\d+\)$| ); my ( $count ) = ( $line =~ m|\((\d+)\)$| ); push( @target_thread_list, { dat_id => $dat_id, title => $title, count => $count } ); } return @target_thread_list; } ## 単なるhttpコール。2chのスレ取得にも、テロッパへのデータ送信にも使う sub http_get { my ( $url, $code, $timeout ) = @_; my $TIMEOUT_SEC = 10; if ( defined $timeout ) { $TIMEOUT_SEC = $timeout; } if ( $code eq '' ) { $code = 'utf8'; } my $USER_AGENT_STRING = "Digital telopper 2ch res checker"; my %formdata = (); my $request = GET( $url, %formdata ); my $ua = LWP::UserAgent->new; $ua->timeout( $TIMEOUT_SEC ); $ua->agent( $USER_AGENT_STRING ); my $res = $ua->request( $request ); my $response_data = $res->content; $response_data = Encode::decode( $code, $response_data ); return $response_data; } ###################################################################### ## end