SVX日記
2006-01-16(Mon) tdiaryのコメントスパムを排除してみる
当ブログはtdiaryというブログシステムを利用しているが、このtdiaryというブログシステムには「ツッコミ」を入れられるという特徴がある。日記の1日のエントリごとに、小さな掲示板が付いているというようなモノなのであるが、掲示板であるから余計な書き込みをする輩が現れる。面倒なことはキライだし、アホな書き込みも「枯木も山の賑わい」と、基本的に放置の方向で運営してきたが、怪しげな薬品の広告スペースとかに使われたり、私信のチャットに使われたりしだすと、さすがに見苦しさに余る。
こーゆー時にはIPアドレスで制限したりするのが、基本的な対処であるが、IPアドレスでの制限は大抵はドロ沼になる。書き込む方は基本的に攻撃側であり、防御側が屈するまで、気の済むまで攻撃できるんだから当然である。IPを変えるなんざ、いとも簡単なことであり、そりゃ効き目があるわけがないのである。
基本的に、攻撃もしくはどちらかというとダークな行動をする輩はスキルが低いことが多い。以前にFOMAの端末のボタンに直に配線をつなぐ改造を加え、端末をPCから制御して迷惑メールを出しまくっていた業者が摘発されたというニュースを見たが、その改造のアホさには目を見張るものがあった。端末のボタンへの配線が2本ずつあったのである。どうやら彼らには「GND」という概念がないらしい。同様に推測すると、以前に悪いことするために「サリンちゃん」なんていう妙薬を作り出した団体があり、ニュースでは「高度な技術を持つエリートを擁している」などとして扱われていたが、パンピーからは高度な技術にみえても、きっとフツーの薬品エンジニアからはなんでもないことなんじゃねーかと思う。まっとーな人間なら、ハナっからあんな団体に属したりしませんって。
脱線したが、よーするに、そのようなダークな輩に正義のエンジニア(?)が負けるなどということはあってはならないコトなのである。ちゅーわけで、なんかいい方法はないかと考えていたのだが、あった。tdiaryの場合、うっとおしいコメントがあったら、管理画面でチェックボックスを外すことで非表示にできるのであるが、これをデフォルトにしてしまえばいいのである。そうすりゃ書き込まれた後に管理者が確認して、内容によって表示したり、放置したりすることができる。なんだ、簡単だ。いわゆる、オプトアウトでなく、オプトイン方式にすりゃいいのである。
通常であれば、簡単な変更ではあっても、そのような変更は不可能なところであるが、ウチは自宅サーバであり、tdiaryはRubyで書かれたオープンソースアプリであり、オイラはRubyプログラマである。チョイチョイと直してしまえばいい。
colinux:/home/mitsu/public_html/diary $ grep -r ツッコミ *
skel/update.rhtml: <input type="submit" tabindex="<%=2000+idx%>" name="comment" value="ツッコミ表示状態変更">
colinux:/home/mitsu/public_html/diary $ vi skel/update.rhtml
59 @diary.each_comment( 100 ) do |comment| %>
60 <div class="commentator">
61 <span class="checkbox">
62 <input class="checkbox" type="checkbox" tabindex="<%=2000+idx%>" name="<%= idx += 1 %>" value="true"<% if comment.visible? then %> checked<% end %>>
63 </span>
64 <span class="commentator"><%= CGI::escapeHTML( comment.name ) %><%= CGI::escapeHTML( " <#{comment.mail}>" ) unless comment.mail.empty? %></span>
65 <span class="commenttime"><%%=comment_date( Time::at( <%=comment.date.to_i%> ) )%></span>
66 </div>
67 <p><%= comment.body.make_link.gsub( /\n/, "<br>" ).gsub( /<br><br>\Z/, '' ) %></p><%
68 end
69 if idx > 0 then %>
70 <div class="button">
71 <input type="submit" tabindex="<%=2000+idx%>" name="comment" value="ツッコミ表示状態変更">
72 </div><%
73 end %>
colinux:/home/mitsu/public_html/diary $ grep -r "visible?" *
tdiary.rb: def visible?; @show; end
tdiary.rb: i += 1 if all or comment.visible?
tdiary.rb: if c.visible? then
tdiary.rb: next unless com.visible?
tdiary.rb: def visible?
tdiary.rb: break if @diary.visible?
tdiary.rb: lm = lmd if lm < lmd and diary.visible?
tdiary.rb: next unless diary.visible?
tdiary.rb: @diary = nil if @diary and not @diary.visible?
tdiary.rb: @diaries_size += 1 if diary.visible?
tdiary.rb: next unless diary.visible?
tdiary.rb: next unless com.visible?
colinux:/home/mitsu/public_html/diary $ vi tdiary.rb
93 #
94 # class Comment
95 # Management a comment.
96 #
97 class Comment
98 attr_reader :name, :mail, :body, :date
99
100 def initialize( name, mail, body, date = Time::now )
101 @name, @mail, @body, @date = name, mail, body, date
102 @show = true
103 end
104
105 def shorten( length = 120 )
106 matched = body.gsub( /\n/, ' ' ).scan( /^.{0,#{length - 2}}/ )[0]
107 unless $'.empty? then
108 matched + '..'
109 else
110 matched
111 end
112 end
113
114 def visible?; @show; end
115 def show=( s ); @show = s; end
116
117 def ==( c )
118 (@name == c.name) and (@mail == c.mail) and (@body == c.body)
119 end
120 end
ん? 114行目の「def visible?; @show; end」があって、102行目の「@show = true」があるっつーことは……これをfalseにするだけじゃん!! わー!! こんな1行ばっかの変更じゃ、ブログのネタにならないじゃねーかッ!!
……などといいつつも、ネッチリとソースコードを入れてネタにしてしまったが、結論から言うと「tdiary.rb」の以下の部分(Commentクラスのコンストラクタだ)を書き換えるだけで、所望する動作を行うことができた。
100 def initialize( name, mail, body, date = Time::now )
101 @name, @mail, @body, @date = name, mail, body, date
102 @show = true (※trueをfalseに書き換える)
103 end
あ、そうそう、この一連のツッコミには笑わせてもらった。オイラには書き込み元のIPが同じだってこと、わかっちゃってるんだよねぇ。