スレ産の成果物を転がしておく場所です。

 

保守スクリプト

たぶんPerl5.8+必須。ソースはUTF-8で保存すること。ライセンスはパブリックドメイン相当でおk

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use LWP;
use LWP::Debug qw(+);
use HTTP::Date;
use HTTP::Status;
use Encode;

our $VERSION = '0.01';
my $ua = LWP::UserAgent->new(
    agent => "Monazilla/1.00 hoshu-bot.pl/$VERSION",
    cookie_jar => {},
);

sub sjis { encode('cp932', $_[0]) }

sub write_something {
    my ($host, $board_key, $thread_key) = @_;
    my $name = '';
    my $mail = '';
    my $message = 'ほしゅ';
    
    REQ:
    my $res = $ua->post("http://$host/test/bbs.cgi",
        [ bbs => $board_key, key => $thread_key,
          FROM => sjis($name), mail => sjis($mail), MESSAGE => sjis($message),
          submit => sjis('書き込む'), time => 1, hana => 'mogera' ],
        Referer => "http://$host/$board_key/");

    for (decode('cp932', $res->content)) {
        if (/書きこみました/ || /2ch_X:true/) { print {*STDERR} "OK! :-)\n"; }
        elsif (/2ch_X:false/)                 { print {*STDERR} "maybe OK?\n"; }
        elsif (/書き込み確認/ || /2ch_X:cookie/) {
            print {*STDERR} "Cookie needed; retry\n"; goto REQ;
        } else {
            print {*STDERR} "ERROR!\n"; exit 1;
        }
    }
}

if ($0 eq __FILE__) {
    my $thread_url = $ARGV[0];
    my ($host, $board_key, $thread_key) =
        $thread_url =~ m{http://([\w.]+)/test/read\.cgi/(\w+)/(\d+)/};
    die "Usage: $0 <thread_url>"
        unless 3 == grep {defined} ($host, $board_key, $thread_key);
    
    my $interval = 60 * 15;
    my $last_modified = 0;
    
    while (1) {
        my $res = $ua->head(
            "http://${host}/${board_key}/dat/${thread_key}.dat",
            'If-Modified-Since' => time2str($last_modified));
        if ($res->code == RC_NOT_MODIFIED) {
            write_something($host, $board_key, $thread_key);
            redo;
        }
        elsif ($res->code == RC_OK) {
            $last_modified = str2time($res->header('Last-Modified'));
            my $now = str2time($res->header('Date'));
            my $wait = $last_modified + $interval - $now;
            sleep($wait > 0 ? $wait : 1);
        }
        else {
            die 'error!';
        }
    }
}

Write2ch(C)

ライセンスは不明。 http://www8.uploader.jp/dl/vipprog/vipprog_uljp00252.zip.html

write2ch(ShellScript)

  1. #!/bin/sh
  2. #ヤター シェルスクリプトでwrite2chできたよー\(^o^)/
  3. #License: どーでもいーよー らいせんす
  4. version="0.10"
  5. usage="
  6. Usage: write2ch.sh [-h] [--help] [-n name] [--name=NAME]
  7.          [-m MAIL] [--mail=MAIL] [--version] URL MESSAGE"
  8.  
  9. while test $# -gt 0; do
  10.   case "$1" in
  11.   -h | --help | --h*)
  12.     echo "$usage"; exit 0 ;;
  13.   --name=* | --n*=* )
  14.     name=`echo \"${1}\" | sed -e 's/^[^=]*=//'`
  15.     shift ;;
  16.   -n | --name | --n*)
  17.     shift
  18.     test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
  19.     name="$1"
  20.     shift ;;
  21.   --mail=* | --m*=* )
  22.     mail=`echo \"$1\" | sed -e 's/^[^=]*=//'`
  23.     shift ;;
  24.   -m | --m*)
  25.     shift
  26.     test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
  27.     mail="$1"
  28.     shift ;;
  29.   -v | --version | --v*)
  30.     show_version=1; shift ;;
  31.   --)
  32.     shift; break ;;
  33.   -*) echo "$usage" 1>&2; exit 1 ;;
  34.   *)
  35.     if [ -z $url ]; then
  36.       url="$1"
  37.     elif [ -z $message ]; then
  38.       message="$1"
  39.     fi
  40.     shift ;;
  41.   esac
  42. done
  43.  
  44.  
  45. if test $show_version; then
  46.   echo "write2ch.sh version $version"; exit 0
  47. fi
  48.  
  49. if [ -z "$url" -o -z "$message" ]; then
  50.   echo "$usage" 1>&2; exit 1
  51. fi
  52.  
  53. name=`echo $name|nkf -s`
  54. mail=`echo $mail|nkf -s`
  55. message=`echo $message|nkf -s`
  56.  
  57. tmp=`echo $url | sed -e 's/\(http:\/\/[^\/]*\)\/test\/read\.cgi\/\([^\/]*\)\/\([^\/]*\).*/\1 \2 \3/'`
  58. host=`echo $tmp | cut -d " " -f 1`
  59. bbs=`echo $tmp | cut -d " " -f 2`
  60. key=`echo $tmp | cut -d " " -f 3`
  61. data="bbs=$bbs&key=$key&FROM=$name&mail=$mail&time=1&MESSAGE=$message"
  62. submit=`echo "書き込む" | nkf -s`
  63. cookie=`wget -q --save-headers --header="Cookie:NAME=\"$name\"; MAIL=\"$mail\";" --referer=$url --post-data="${data}&submit=$submit" -O - $host/test/bbs.cgi | grep Set-Cookie`
  64. cookie=`echo $cookie | sed -e "s/Set-Cookie://"`
  65. submit=`echo "上記全てを承諾して書き込む" | nkf -s`
  66. wget -q --header="Cookie:NAME='$name'; MAIL='$mail';$cookie" --referer=$host/test/bbs.cgi --post-data="${data}&submit=$submit&hana=mogera" -O - $host/test/bbs.cgi > /dev/null

write2ch(Ruby)

  1. #! /usr/bin/ruby1.9
  2. # -*- coding: utf-8 -*-
  3. require 'net/http'
  4. require 'hpricot'
  5. require 'nkf'
  6. class Write2ch
  7.   Net::HTTP.version_1_2
  8.   Encoding = "Windows-31J"
  9.   UrlRegex = /http:\/\/(.+?)\/test\/read\.cgi\/(.+?)\/(\d{10})\//
  10.   def initialize(url, cookie, message, name="", mail="sage", user_agent="Mozilla/4.0")
  11.     @host, @bbs, @key = url.scan(UrlRegex).flatten
  12.     @ref        = "http://#{@host}/test/bbs.cgi?guid=ON"
  13.     @subback    = "http://#{@host}/#{@bbs}/subback.html"
  14.     @message    = message.encode(Encoding)
  15.     @from       = name.encode(Encoding)
  16.     @mail       = mail.encode(Encoding)
  17.     @cookie     = cookie
  18.     @user_agent = user_agent
  19.   end
  20.   attr_accessor :message, :name, :mail, :user_agent
  21.   def write(message)
  22.     Net::HTTP.start(@host, 80) {|my_http|
  23.       @message = message if message != nil
  24.       query  = "&bbs=#{@bbs}&key=#{@key}&mail=#{@mail}&FROM=#{@from}&MESSAGE=#{@message}&time=1&hana=mogera&den=bo"
  25.       header = {"Host"=>@host, "Cookie"=>@cookie, "Referer"=>@ref, "User-Agent"=>@user_agent}
  26.       res, body = my_http.post("/test/bbs.cgi?guid=ON", query, header)
  27.         raise body if res.code != "200"
  28.       title_u = Hpricot(body).search("title").innerHTML.to_s.encode("UTF-8", Encoding).gsub(/\r/,"")
  29.         raise body if title_u != "書きこみました。"
  30.     }# Net::HTTP end
  31.   end
  32. end
  1. # ----- 使い方 -----
  2. # set your cookie
  3. pon = "PON=your.host.ne.jp;"
  4. hap = "PREN=...;HAP=FOXdayo...;";
  5. url = "http://hibari.2ch.net/test/read.cgi/news4vip/1310738793/"
  6.  
  7. writer = Write2ch.new(url, pon+hap, "テスト")
  8. writer.write()
  9. writer.write("てすと")
 

PHP製保守スクリプト

ライセンスはパブリックドメイン。

文字コードはUTF-8で保存すること。ライブラリと本体に分かれてますwww

以下ライブラリ

<?php
//	function http_request($url, $param = null, $mode = "GET", $refere = "", $iscookie = false)
	function http_request($url, $param = null, $mode = "GET", $prmhdrs = null, $iscookie = false)
	{
		global $usragent;
		global $cookies;
		
		$hdrstr = "";
		$cookiestr = "";
		if($iscookie == true)
		{
			if(isset($cookies) == false)
			{
				$cookies = array();
			}
		}
		
		$pathinfo = parse_url($url);
		$host = $pathinfo["host"];
		$path = $pathinfo["path"];
		if(isset($pathinfo["query"]))
		{
			$query = "?";
			$query .= $pathinfo["query"];
		}
		else
		{
			$query = "";
		}
		$path .= $query;	
		$port = "80";
		
		$fp = fsockopen ($host, 80, $errno, $errstr, 30);
		$buff = "";
		
		if(!$fp) {
			return false;
		}
		
//		$Referer = "";
//		if($refere != "")
//		{
//			$Referer = "Referer: {$refere}\r\n";
//		}
		
		socket_set_timeout($fp, 2);

		if((isset($cookies[$host]) == true) && ($iscookie == true))
		{
			if(is_array($cookies[$host]) == true)
			{
				reset($cookies[$host]);
				$cookiestr .= "Cookie: ";
				$delimiter = "";
				
				while($val = each($cookies[$host]))
				{
					$cookiestr .= $delimiter;
					$cookiestr .= $val['key'];
					$cookiestr .= "=";
					$cookiestr .= $val['value'];
					$delimiter ="; ";
				} 

				$cookiestr .= "\r\n";
			}
		}
		
		if(isset($prmhdrs))
		{
			if(is_array($prmhdrs))
			{
				
				reset($prmhdrs);
				
				while($val = each($prmhdrs))
				{
					$hdrstr .= $val['key'];
					$hdrstr .= ": ";
					$hdrstr .= $val['value'];
					$hdrstr .= "\r\n";
				}
			}
		}
		
		if($mode == "GET") {
			$header = "";
			$header.= "GET {$path} HTTP/1.1\r\n";
			$header.= "Host: {$host}\r\n";
			$header .= $cookiestr;
//			$header .= $Referer;
			$header .= $hdrstr;
			$header .= "User-Agent: {$usragent}\r\n";
			$header .= "Connection: close\r\n";
			$header.= "\r\n";
			
		} else if($mode == "POST") {		
			if(!is_array($param)) {
				return false;
			}
			$prmstr = "";
			$prmdlim = "";

			$header = "";
			reset($param);
			
			while($val = each($param))
			{
				$prmstr .= $prmdlim;
				$prmstr .= $val['key'];
				$prmstr .= "=";
				$prmstr .= rawurlencode($val['value']);
				$prmdlim = "&";
			}

			$length  = strlen($prmstr);
			$header .= "POST {$path} HTTP/1.1\r\n";
			$header .= "Host: {$host}\r\n";
			$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
			$header .= "Content-Length: {$length}\r\n";
			$header .= $cookiestr;			
		
//			$header .= $Referer;
			$header .= $hdrstr;
			$header .= "User-Agent: {$usragent}\r\n";
			$header .= "Connection: close\r\n";
			$header .= "\r\n";
			$header .= "{$prmstr}\r\n";
		} else if($mode == "HEAD") {
			$header = "";
			$header.= "HEAD {$path} HTTP/1.1\r\n";
			$header.= "Host: {$host}\r\n";
			$header .= $cookiestr;
			$header .= $hdrstr;
			$header .= "User-Agent: {$usragent}\r\n";
			$header .= "Connection: close\r\n";
			$header.= "\r\n";
		} else {
			return false;
		}
		
		fwrite($fp, $header);
		
		while(!feof($fp)) {
	  		fputs ($fp, $header);
			$buff .= fgets($fp, 128);
		}

		parse_httpresponse($buff, $reshdr, $resbody);
		$reshdrs = explode("\r\n", $reshdr);
		
		$result = array();
		foreach($reshdrs as $hdrval)
		{
//			if(preg_match('/^Set-Cookie: ([^=]+)=(.*)$/', $hdrval, $match))
			if(preg_match('/^Set-Cookie: ([^=]+)=([^;]*)/', $hdrval, $match))
			{
				if($iscookie == true)
				{
					if(isset($cookies[$host]) == false)
					{
						$cookies[$host] = array();
					}
					$cookies[$host][$match[1]] = $match[2];
				}
			}
			else if(preg_match('/^HTTP\/1\.[0-1x] (.*)$/', $hdrval, $match))
			{
				$result["status"] = $match[1];
			}
			else if(preg_match('/^([^:]+): (.*)$/', $hdrval, $match))
			{
				if(isset($result["header"]) == false)
				{
					$result["header"] = array();
				}
				
				$result["header"][$match[1]] = $match[2];
			}
		}
		$result["body"] = $resbody;

		return $result;		
	}
	
	function parse_httpresponse($responsetxt, &$header, &$body)
	{
		$hdrend = strpos($responsetxt, "\r\n\r\n");
		
		if($hdrend === false) {
			return false;
		}
		$header = substr($responsetxt, 0, $hdrend);
		
		$bodystart = $hdrend + 4;
		$body = substr($responsetxt, $bodystart);
		
		return true;
	}
?>
 

本体。

#!/usr/bin/php
<?php
	require_once('httplib.php');
	
	if($argc < 1)
	{
		echo "{$argv[0]} <thred url>";
		echo "param err!!";
		return ;
	}

	preg_match('/http:\/\/([^\/]+)\/.+\/read\.cgi\/([^\/]+)\/([0-9]+)\//', $argv[1], $match);
//	preg_match('/http:\/\/(.+)\/read\.cgi\/([^\/]+)\/([0-9]+)\//', $argv[1], $match);

	if(is_array($match) == false)
	{
		echo "param err!!";
		return;
	}
	$cookies = array();
//	$usragent = "Monazilla/1.00 Live2ch/1.17";
	$usragent = "Monazilla/1.00";
	$posturl = "http://{$match[1]}/test/bbs.cgi?guid=ON";
	
	$headurl = "http://{$match[1]}/{$match[2]}/dat/{$match[3]}.dat";
	$last_modified = 0;
	$reloadhdr = array();
	$reloadhdr['If-Modified-Since'] = $last_modified;
	
	$headers = array();
	$headers['Referer'] = "http://{$match[1]}/{$match[2]}/";
	
	$bbs = $match[2];
	$key = $match[3];

	$FROM = "";
	$mail = mb_convert_encoding('age', "SJIS", "UTF-8");
	$MESSAGE = 'test';
		
	$postprm = array();
	
	$interval = 30 * 60;
	
	$postprm['bbs'] = $bbs;
	$postprm['key'] = $key;
	$postprm['FROM'] = $FROM;
	$postprm['mail'] = $mail;
	$postprm['MESSAGE'] = $MESSAGE;
//	$postprm['MIRV'] = 'kakkoii';
	
	$postprm['submit'] = mb_convert_encoding("書き込む", "SJIS", "UTF-8");
	$postprm['time'] = "1";
//	$postprm['hana'] = "mogera";
	$postprm['suka'] = "pontan";

	function postto2ch($posturl, $postprm, $headers)
	{
		$result = http_request($posturl, $postprm, "POST", $headers, true);

		if($result === false) {
			echo "not response!!\n";
			return false;
		}
		
		$body = mb_convert_encoding($result["body"], "UTF-8", "SJIS");
		
		if(preg_match('/書きこみ&クッキー確認/um', $body))
		{
			echo "need cookie!!\n";
			
			$postprm['submit'] = mb_convert_encoding("上記全てを承諾して書き込む", "SJIS", "UTF-8");
			$headers['Referer'] = $posturl;
						
			$result = http_request($posturl, $postprm, "POST", $headers, true);

			if($result === false)
			{
				echo "no response!!\n";
				return false;
			}
			
			$body = mb_convert_encoding($result["body"], "UTF-8", "SJIS");
			
			if((preg_match('/書きこみ.*ました/um', $body)) || 
				(preg_match('/^303/', $result["status"])) )
			{
			
				return true;
			}
			else
			{
				echo "err!\n";
				return false;
			}
		} 
		else if((preg_match('/書きこみ.*ました/um', $body)) || 
			(preg_match('/^303/', $result["status"])) )
		{
			return true;
		}
		else
		{
			echo "err!\n";
			return false;
		}
		return false;
	}
		
	while(1)
	{
		$reloadhdr['If-Modified-Since'] = gmstrftime(
			'%a, %d %b %G %T GMT', $last_modified);
		$result = http_request($headurl, null, "GET", $reloadhdr);

		if(preg_match('/^304/', $result["status"]))
		{
			if(postto2ch($posturl, $postprm, $headers) == false)
			{
				return;
			}
			
			$last_modified = strtotime($result['header']['Date']);
		}
		else if(preg_match('/^200/', $result["status"]))
		{
			$last_modified = strtotime($result['header']['Last-Modified']);
		}
		else
		{
			echo "err!\n";
			return false;
		}
		$now = strtotime($result['header']['Date']);
		$wait = $last_modified + $interval - $now;
	
		if($wait > 0)
		{
			sleep($wait);
		}
		else
		{
			sleep(1);
		}
	}
?>
 

Python 製保守スクリプト

上記の Perl のスクリプト を参考にさせていただきました

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# str.format を使うため version は 2.6 以上必要
from urllib import urlencode
from cookielib import CookieJar
import re
import urllib2

class Error(Exception):
    pass
class Write2chException(Error):
    pass

UA = 'Monazilla/1.00 hoshu-bot.py/0.01'
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(CookieJar()))
opener.addheaders = [('User-Agent', UA)]

def getabouturl(url):
    return re.search(r'http://([\w.]+)/test/read[.]cgi/(\w+)/(\d+)/', url).groups()

def write(url, message, name='', mail='sage'):
    host, board_key, thread_key = getabouturl(url)
    postto   = 'http://{host}/test/bbs.cgi'.format(host=host)
    postdata = dict(
        bbs     = board_key,
        key     = thread_key,
        FROM    = name.encode('sjis'),
        mail    = mail,
        MESSAGE = message.encode('sjis'),
        submit  = u'書き込む'.encode('sjis'),
        time    = 1,
        tepo    = 'don',
    )
    params = urlencode(postdata)

    request = urllib2.Request(postto, params, {'Referer': url})

    while True:
        reader = opener.open(request)
        cont   = unicode(reader.read(), 'sjis')
        if u'書きこみました' in cont or u'2ch_X:true' in cont:
            return
        elif u'2ch_X:false' in cont:
            continue
        elif u'書き込み確認' in cont or u'2ch_X:cookie' in cont:
            continue
        else:
            raise Write2chException(cont)

def main(): 
    import sys
    import time
    import httplib

    url = sys.argv[1]
    mes = u'ほしゅ'

    host, board_key, thread_key = getabouturl(url)
    daturl  = 'http://{host}/{board_key}/dat/{thread_key}.dat'.format(
        host=host, board_key=board_key, thread_key=thread_key)

    lastmod = opener.open(daturl).headers['Last-Modified']
    request = urllib2.Request(daturl)
    request.add_header('If-Modified-Since', lastmod)

    while True:
        try:
            reader  = opener.open(request)
            code    = reader.code
            lastmod = reader.headers['Last-Modified']
            request.add_header('If-Modified-Since', lastmod)
        except urllib2.HTTPError as e:
            code    = e.code
        if code == httplib.OK:
            print 'sleeping...'
            time.sleep(60 * 15)
        elif code == httplib.NOT_MODIFIED:
            write(url, mes)

if __name__ == '__main__':
    main()

write2ch(Perl + WWW::Mechanize)

CPANつかってるしArtistic Licenseでおk。

  1.  use strict;
  2.  use utf8;
  3.  use WWW::Mechanize;
  4.  
  5.  my $mech = WWW::Mechanize->new();
  6.  my $serv = 'http://hibari.2ch.net/';
  7.  my $url = 'http://hibari.2ch.net/test/read.cgi/news4vip/1321183007/';
  8.  my $name = '';
  9.  my $mail = 'sage';
  10.  my $msg = 'WWW::Mechanizeによる書き込みテストだお;;';
  11.  
  12.  write2ch($mech,$serv,$url,$name,$mail,$msg);
  13.  
  14.  sub write2ch
  15.  {
  16.      my ($mech,$serv,$url,$name,$mail,$msg) = @_;
  17.  
  18.      # 対象スレッドを取得
  19.      my $response = $mech->get( $url );
  20.      print $mech->title();
  21.  
  22.      # WWW::Mechanizeはパス形式でCGIを呼び出すとBaseURIを正しく認識しないので絶対パスに置換
  23.      my $c = $mech->content();
  24.      $c =~ s{\.\./}{$serv}egx;
  25.      $mech->update_html($c);
  26.  
  27.      # フォームを埋めて書き込み
  28.      my $form = $mech->form_number(1);
  29.      $form->accept_charset('sjis'); # sjisで送信
  30.      $form->find_input("FROM")->value($name);
  31.      $form->find_input("mail")->value($mail);
  32.      $form->find_input("MESSAGE")->value($msg);
  33.      $response = $mech->request($form->click);
  34.      print $mech->title();
  35.  
  36.      # 初めはクッキーがないのでタイトルで判定して確認
  37.      if($mech->title() eq '■ 書き込み確認 ■')
  38.      {
  39.          $form = $mech->form_number(1);
  40.          $form->accept_charset('sjis'); # sjisで送信
  41.          $response = $mech->request($form->click);
  42.          print $mech->title();
  43.      }
  44.      # 忍法帖が必要なら2分待って再投稿
  45.      if($mech->title() eq 'ERROR!')
  46.      {
  47.          if($mech->content() =~ /ninja/)
  48.          {
  49.              print '忍法帖作成待ち '.localtime(time);
  50.              sleep(121);
  51.              write2ch($mech,$serv,$url,$name,$mail,$msg);
  52.              exit;
  53.          }
  54.      }
  55.      # 終了
  56.      if($mech->title() eq '書きこみました。')
  57.      {
  58.          print "終了。";
  59.      }
  60.      else # なんかエラーみたいですよ。
  61.      {
  62.          print $mech->content();
  63.      }
  64.  }

youjo.pl(Perl,Proc::Daemon,WWW::Mechanize)

http://hayabusa.2ch.net/test/read.cgi/news4vip/1373088069/ にて錬成。上記write2chを参考にさせていただきました。

  1. #!/bin/perl
  2.  
  3. use strict;
  4. use diagnostics;
  5. use utf8;
  6. use Proc::Daemon;
  7. use WWW::Mechanize;
  8.  
  9. my $WORK_DIR = "/home/user/youjo";
  10. my $DAEMON;
  11. my $PID_FILE = 'send_daemon.pid';
  12. my $SLEEP_INTERVAL = 60;
  13. my ($action) = @ARGV;
  14.  
  15. $DAEMON = Proc::Daemon->new(work_dir=> $WORK_DIR,pid_file=> 'send_daemon.pid');
  16. $action ||="";
  17.  
  18. if ($action eq "start")
  19. {
  20. my ($pid_path,$pid) = get_pid_file();
  21. if( -e $pid_path ){
  22. print "$0 is already running. LOCK_FILE=$pid_path PID=$pid\n";
  23. exit(1);
  24. }
  25. init();
  26. run();
  27. }
  28. elsif ($action eq "stop")
  29. {
  30. unless( get_pid_file() ){
  31. print "$0 is not running\n";
  32. exit(1);
  33. }
  34. open(LOG, ">>/home/user/youjo/log.txt");
  35. print LOG "" . localtime(time) . "\t" . "Daemon Stop();\n";
  36. close(LOG);
  37. del_pid_file();
  38. }
  39. else
  40. {
  41. print "usage: $0 [start|stop]\n";
  42. }
  43.  
  44.  
  45.  
  46. sub get_pid_file {
  47. my $pid_file_path = join('/',$WORK_DIR,$PID_FILE);
  48. return undef if not -e $pid_file_path;
  49. open(my $fh, $pid_file_path) or die "can't open $pid_file_path :$!";
  50. my ($line) = <$fh>;
  51. close $fh or die "can't close $pid_file_path :$!";
  52. return $pid_file_path;
  53. }
  54. sub del_pid_file {
  55. my $pid_file_path = join('/',$WORK_DIR,$PID_FILE);
  56. unlink $pid_file_path or die "can't unlink $pid_file_path :$!";
  57. }
  58. sub interrupt {
  59. my $sig = shift;
  60. $SIG{$sig} = 'IGNORE';
  61. return del_pid_file();
  62. }
  63. sub init {
  64. Proc::Daemon::Init( {work_dir=> $WORK_DIR,pid_file=> $PID_FILE});
  65. open(LOG, ">>/home/user/youjo/log.txt");
  66. print LOG "" . localtime(time) . "\t" . "Daemon Init();\n";
  67. close(LOG);
  68. $SIG{INT} = $SIG{HUP} = $SIG{QUIT} = $SIG{KILL} = $SIG{TERM} ='interrupt';
  69. }
  70. sub run {
  71.     while(1) {
  72.         action();
  73. for(my $i=0;$i<$SLEEP_INTERVAL;$i++)
  74. {
  75. my ($pid_path,$pid) = get_pid_file();
  76. if (not $pid_path ){
  77. $DAEMON->Kill_Daemon();
  78. }
  79. sleep(1);
  80. }
  81.     }
  82. }
  83.  
  84.  
  85.  
  86. sub action {
  87. open(LOG, ">>/home/user/youjo/log.txt");
  88.  
  89. my @ita_list;
  90. my @thread_list;
  91. my $ita_url;
  92. my @keyword_list;
  93. my @target_thread_list;
  94. my $name = '';
  95. my $mail = '';
  96. my $message = 'test';
  97. my $mech;
  98.  
  99. $mech = WWW::Mechanize->new();
  100. $mech->proxy(['http', 'ftp'], 'http://localhost:3939/');
  101.  
  102. getbbsmenu($mech, \@ita_list);
  103. $ita_url = geturl_regexp( qr/VIP$/, \@ita_list );
  104.  
  105. getthreadlist($mech, $ita_url, \@thread_list);
  106.  
  107. open(IN, "<:utf8",  "thtitle_keyword_utf8.txt") or die "$!";
  108. @keyword_list = <IN>;
  109. close(IN);
  110.  
  111. @target_thread_list = getthread_regexp(\@keyword_list, \@thread_list);
  112.  
  113. if($#target_thread_list<0)
  114. {
  115. print LOG localtime(time) . "\t" . "target not found.\n";
  116. }
  117. else
  118. {
  119. foreach(@target_thread_list)
  120. {
  121.  
  122. my $idx = rindex(substr($ita_url,0,-1),"/")+1;
  123. my $url = substr($ita_url, 0, $idx) . "test/read.cgi/" . substr($ita_url, $idx) . substr(${$_}{id},0,-4) . "/";
  124. if(${$_}{number}>=400)
  125. {
  126. write2ch($mech,$ita_url,$url,$name,$mail,$message);
  127. }else{
  128. print LOG localtime(time) . "\t" . "□保守不要([" . ${$_}{number} . "]" . $url . ")\n";
  129. }
  130. }
  131. }
  132.  
  133. close(LOG);
  134. return 1;
  135. }
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142. sub getbbsmenu
  143. {
  144. my ($mech, $ita_list) = @_;
  145. $mech->get("http://menu.2ch.net/bbsmenu.html");
  146. push(@$ita_list, $mech->find_all_links(tag => "a", url_regex => qr/.+\.2ch\.net\/.+\//));
  147. }
  148.  
  149. sub geturl_regexp
  150. {
  151. my ($r, $ita_list) = @_;
  152. foreach (@$ita_list)
  153. {
  154. if($_->text=~$r)
  155. {
  156. return $_->url;
  157. }
  158. }
  159. return "Not Found."
  160. }
  161.  
  162. sub getthreadlist
  163. {
  164. my ($mech, $ita_url, $thread_list) = @_;
  165. $mech->get($ita_url . "subject.txt");
  166. my @subjects = split(/\n/, $mech->res->decoded_content( charset => 'Shift_JIS' ));
  167. my $junban = 0;
  168. foreach (@subjects)
  169. {
  170. $junban++;
  171. $_ =~ s/<>/\t/;
  172. $_ =~ s/\(([0-9]+)\)/\t$1/;
  173. my ($tid, $title, $count) = split("\t", $_);
  174. push(@$thread_list, {id => $tid, title => $title, res_count => $count, number => $junban});
  175. }
  176. }
  177.  
  178. sub getthread_regexp
  179. {
  180. my ($keyword_list, $thread_list) = @_;
  181. my @result;
  182. foreach my $t (@$thread_list)
  183. {
  184. foreach(@$keyword_list)
  185. {
  186. if(${$t}{title}=~/$_/)
  187. {
  188. push(@result, $t);
  189. last;
  190. }
  191. }
  192. }
  193. return @result;
  194. }
  195.  
  196. sub write2ch
  197. {
  198. my ($mech,$serv,$url,$name,$mail,$msg) = @_;
  199. my $response = $mech->get( $url );
  200. my $c = $mech->content();
  201. $c =~ s{\.\./}{$serv}egx;
  202. $mech->update_html($c);
  203. my $form = $mech->form_number(1);
  204. $form->accept_charset('sjis');
  205. $form->find_input("FROM")->value($name);
  206. $form->find_input("mail")->value($mail);
  207. $form->find_input("MESSAGE")->value($msg);
  208. $response = $mech->request($form->click);
  209. if($mech->title() eq '■ 書き込み確認 ■')
  210. {
  211. print LOG localtime(time) . "\n" . '■ 書き込み確認 ■' . "\n\n" . $mech->res->decoded_content( charset => 'Shift_JIS' ) . "\n\n";
  212. $form = $mech->form_number(1);
  213. $form->accept_charset('sjis');
  214. $response = $mech->request($form->click);
  215. print $mech->title();
  216. }
  217. if($mech->title() eq 'ERROR!')
  218. {
  219. print LOG localtime(time) . "\n" . 'ERROR!' . "\n\n" . $mech->res->decoded_content( charset => 'Shift_JIS' ) . "\n\n";
  220. if($mech->content() =~ /ninja/)
  221. {
  222. sleep(21);
  223. write2ch($mech,$serv,$url,$name,$mail,$msg);
  224. exit;
  225. }
  226. }
  227. if($mech->title() ne 'p2 - 書きこみました。')
  228. {
  229. print LOG localtime(time) . "\n" . 'ERROR!' . "\n\n" . $mech->res->decoded_content( charset => 'Shift_JIS' ) . "\n\n";
  230. return -1;
  231. }
  232. print LOG localtime(time) . "\t" . "■保守完了(" . $url . ")\n";
  233. return 1;
  234. }