古いspamコメント/トラバの削除を支援するGMスクリプト2008年04月23日 03時51分27秒

しつこくアサブロ管理画面向けのGMスクリプトを載せてみたり。

コメント一覧/トラックバック一覧で状態が「spam」の項目に自動的にチェックをつけます。以下のスクリプトを「http://www.asablo.jp/app*」で動作するようにしてください。

※:なんかうまく動かなくなったので、修正入れました。詳しくはこちら。(09.09.04)

// 指定要素を含むtrを取得する
function findRow(el) {
  if( el == document.body ) return null;
  
  var row = el.parentNode;
  if( /^tr$/i.test( row.tagName ) ) {
    // 「状態」を取得するメソッドを追加
    row.getStatus = function() {
      var sel = this.getElementsByTagName("select")[0];
      if( sel ) {
        return sel.options[ sel.selectedIndex ].innerHTML;
      }
      return null;
    };
    // 日付を取得するメソッドを追加
    row.getDate = function() {
       var cells = this.getElementsByTagName("td"), i = 0;
       while( i < cells.length ) {
         var cell = cells[i++];
         if( /\d{4}((\-\d{2}){2})\s\d{2}((:\d{2}){2})/.test( cell.innerHTML ) ) {
           return new Date(
             cell.innerHTML.replace(/\-/g, "/").replace( /\s\d{2}(:\d{2}){2}/, "" )
           );
         }
       }
       return null;
    };
    return row;
  }
  
  // elの親がtrじゃないのでさらに上位に遡る
  return arguments.callee( row );
}

// [状態の変更/~の削除]ボタンを検出する
function getSubmit() {
  var list = window.document.getElementsByTagName("input")
  for(var i = 0, l = list.length; i < l; i++) {
    if( list[i].type == "submit" && /状態の変更/.test( list[i].value ) ) {
      return list[i];
    }
  }
  return null;
}

// チェックボックスのリスト → リストの取得方法変更(09.09.04)
//var list = document.getElementsByTagName("input");
var list = document.getElementsByName("delmsg");
// チェックボックスをチェックした数
var checked = 0;
// 現在日よりこの日数以上古いデータは削除対象にする
var days = 5;

// 削除対象のコメント/トラバをチェック
for(var i = 0, l = list.length; i < l; i++) {
  var input = list[i++];
  if( input.type != "checkbox" || input.name != "delmsg" ) continue;
  
  new function() {
    var row = findRow(input);
    var d = row.getDate();
    var limit = new Date( new Date() - ( 86400000 * days ) );
    if( row.getStatus() == "spam" && d <= limit ) {
      input.checked = true;
      checked++;
    }
  }();
}

// ボタンをハイライト
var btn = getSubmit();
if( checked && btn ) {
  btn.style.color = "red";
  btn.style.fontWeight = "bold";
  btn.focus();
  document.documentElement.scrollTop = document.documentElement.scrollHeight;
}

ノードの抽出だとかDOM操作はちょっとグダグダしてるが勘弁。

コード中の下線部の「var days = 5」の数字は、削除対象にする日数で、例えば本日(2008年4月23日)だと、4月19日よりも前のspamトラバ/コメントにチェックがつきます。「5日も待てねぇ。さっさと削除してぇ。」とかいった場合はここを変更すると。

また、チェックをつけた項目があったページでは[状態の変更/~の削除]ボタンを強調表示し、そこまで画面をスクロールさせてます。

あくまでチェックをつけるだけなので、実際の削除は[状態の変更/~の削除]を自分でクリックしてください。

うーん、またあんまり需要がないスクリプトを書いてしまった。

コメントとトラバの上限が設定されるらしい。2008年04月23日 03時14分43秒

昨今増えているスパム(迷惑)コメント、スパムトラックバック対策のため、近日中に1記事あたりのコメントとトラックバック受付数上限を設けることにいたしました。
ありがたい。めっさありがたい。1日あたり30も40もクスリのトラバがやってくる現状からすると、ほんとうにありがたい。

が、「上限50」とかだったら俺的に実質意味ないし。それはそれで笑えてよいかも。

管理画面のプレビューリンクをポップアップ表示するGMクリプト2008年03月29日 05時11分34秒

コメントスパム、多すぎ

またもアサブロがらみのグリモンスクリプトです。

トラバもそうなんだけど、ここ何日かコメントスパムが増えてきた。しかもほぼエロ関係

コメントはいままで即時公開設定だったんだけど、非合法くさいエロサイトへのリンクが載っかってるのはさすがに気まずいっつーか気分悪いので、取り急ぎチェックを経てから公開するように変更したんだけど、いちいちプレビューを開いて確認するのはわりと大変なのでその場で確認してみたいと。

んでソース

前回のグリモンスクリプトよりもちょっと長いかな。

var K = function(x) { return x; }

Object.extend = function(destination, source) {
  for(var key in source) destination[key] = source[key];
  return destination;
}

var $break = {};
var $continue = {};
var Enumerable = {
  each : function(iterator) {
    var i = 0;
    try {
      this._each( function(value) {
        try {
          iterator(value, i++);
        } catch(e) {
          if( e != $continue ) throw e;
        }
      } );
    } catch(e) {
      if( e != $break ) throw e;
    }
  },
  find : function(iterator) {
    var result = null;
    this.each( function(value, index) {
      if( iterator(value, index) ) {
        result = value;
        throw $break;
      }
    } );
    return result;
  },
  findAll : function(iterator) {
    var results = [];
    this.each( function(value, index) {
      if( iterator(value, index) ) results.push( value );
    } );
    return results;
  }
}
Array.prototype._each = function(iterator) {
  for(var i = 0, l = this.length; i < l; i++) iterator(this[i]);
}
Object.extend( Array.prototype, Enumerable );

Array.from = $A = function(list) {
  Object.extend( list, { _each : Array.prototype._each } );
  return Object.extend( list, Enumerable );
}

document.getElementsByClassName = function(className) {
  return $A( (arguments[1] || document).getElementsByTagName("*") ).findAll( function(ele) {
    var classes = ( ele.className || "" ).split(" ");
    return classes.find( function(c) { return c == className; } );
  } );
}

Object.extend( String.prototype, {
  stripTags : function(br) {
    var result = this;
    if( br ) result = result.replace( /<br\s*\/?>/ig, "\n" );
    return result.replace( /<[^>]+\/?>/g, "" );
  },
  toElements : function() {
    var temp = document.createElement("div");
    temp.style.display = "none";
    document.body.appendChild( temp );
    
    temp.innerHTML = this;
    
    var result = $A( temp.childNodes );
    document.body.removeChild( temp );
    
    return result;
  }
} );

var pop = Object.extend( document.createElement("div"), {
  _hover : false,
  id : "popup_element_" + (new Date().valueOf()),
  visible : function() {
    return this.style.display != "none";
  },
  show : function() {
    if( this.visible() ) return;
    
    this.style.display = "";
    this.scrollTop = 0;
    var pos = {
      x : ( arguments[0] + 8 ) || this.clientLeft,
      y : ( arguments[1] + 8 )|| this.clientTop
    };
    this.style.left = pos.x + "px";
    this.style.top = pos.y + "px";
  },
  hide : function() {
    if( this._hover ) return;
    this.style.display = "none";
  }
} );
pop.addEventListener( "mousemove", function(evt) {
  pop._hover = true;
  evt.preventDefault();
}, true );
pop.addEventListener( "mouseout", function(evt) {
  pop._hover = false;
  setTimeout( function() {
    pop.hide();
  }, 1000 );
  evt.preventDefault();
}, true );

Object.extend( pop.style, {
  width : "350px", height : "150px",
  border: "solid 1px silver",
  backgroundColor : "whitesmoke", color : "dimgray",
  padding: "0px", fontSize : "8pt",
  position : "absolute", overflow : "auto",
  opacity : 0.9, display : "none"
} );
document.body.appendChild( pop );

var cache = {};

var handlers = {
  over : function(evt) {
    if( ! evt.target.href || ! /app\?cmd=preview/.test( evt.target.href ) ) return;
    
    var link = evt.target.href;
    if( ! cache[link] ) {
      var xhr = new XMLHttpRequest();
      xhr.open( "get", link, false );
      xhr.send( null );
      
      var container = xhr.responseText.toElements().find( function(node) {
        return node.nodeType == 1 &&
          /div/i.test( node.nodeName ) &&
          node.id == "container";
      } );
      var previews = document.getElementsByClassName("preview", container );
      if( previews ) cache[link] = previews[0].innerHTML;
    }
    pop.innerHTML = cache[link] || "oops !!";
    pop.show( evt.pageX, evt.pageY );
  },
  leave : function(evt) {
    setTimeout( function() {
      pop.hide();
    }, 1000 );
  }
}

$A(document.getElementsByClassName("list")[0].getElementsByTagName("a")).findAll( function(a) {
  return /app\?cmd=preview/.test( a.href );
} ).each( function(a) {
  a.addEventListener( "mousemove", handlers.over, false );
  a.addEventListener( "mouseout", handlers.leave, false );
} );


前半部分は前と一緒でprototype.jsの一部移植。ほんで「var pop = 」のところがリンク先をポップアップ表示させるツールチップにあたるオブジェクトの定義。

んでこのスクリプトを「http://www.asablo.jp/app?cmd=edit_*」で実行させる。そうすると「コメント一覧」「トラックバック一覧」と「記事の編集・削除」のそれぞれの画面のプレビューリンク先にカーソルを乗せてその場で内容を確認できる。こんな感じで。

プレビューリンクからカーソルはずすと勝手に消えるけど、ポップアップ表示してるところにカーソルのせとけばずっと表示されてるので多少はじっくり確認できます。

おクスリトラバを強調するGMスクリプト2008年03月27日 12時53分48秒

こないだのスパムがらみエントリでも書いたが、アサブロのトラックバック管理画面で「spam」指定しておくとアサブロ側で情報を収集してくれるっぽいので即削除をやめてspam指定をするようにしてみた。

が、トラックバック管理画面はデフォルトで 10件 / 1ページ の表示なのであっという間に画面はspamだらけになり、管理しづらい。

なので、せめてもう少し見やすくしようとGreasemonkeyでユーザスクリプトを書いてみた。グリモンでしか確認してないが、ほかのブラウザのユーザスクリプトにも移植できるかも。そうでもないかも。

以下のスクリプトを、実行対象のページに「http://www.asablo.jp/app?cmd=edit_tb*」を指定しておくと、トラックバック一覧を表示したときに指定キーワードに一致する行の文字を赤(すでにspam指定済みの場合は暗い赤)で強調する。

var K = function(x) { return x; }

Object.extend = function(destination, source) {
	for(var key in source) destination[key] = source[key];
	return destination;
}

var $break = {};
var $continue = {};
var Enumerable = {
	each : function(iterator) {
		var i = 0;
		try {
			this._each( function(value) {
				try {
					iterator(value, i++);
				} catch(e) {
					if( e != $continue ) throw e;
				}
			} );
		} catch(e) {
			if( e != $break ) throw e;
		}
	},
	find : function(iterator) {
		var result = null;
		this.each( function(value, index) {
			if( iterator(value, index) ) {
				result = value;
				throw $break;
			}
		} );
		return result;
	},
	findAll : function(iterator) {
		var results = [];
		this.each( function(value, index) {
			if( iterator(value, index) ) results.push( value );
		} );
		return results;
	}
}
Array.prototype._each = function(iterator) {
	for(var i = 0, l = this.length; i < l; i++) iterator(this[i]);
}
Object.extend( Array.prototype, Enumerable );

Array.from = $A = function(list) {
	Object.extend( list, { _each : Array.prototype._each } );
	return Object.extend( list, Enumerable );
}

document.getElementsByClassName = function(className) {
	return $A( (arguments[1] || document).getElementsByTagName("*") ).findAll( function(ele) {
		var classes = ( ele.className || "" ).split(" ");
		return classes.find( function(c) { return c == className; } );
	} );
}

/* spam認定キーワード。うまく引っかからんやつもある */
var ng_words = /(drug|buy|price|cheap|tramadol|medication|side\seffects|hydrocodone|oxycodone|zithromax|phentermine)/ig;

$A(document.getElementsByClassName("list")[0].getElementsByTagName("tr")).findAll( function(tr) {
	return ng_words.test( tr.innerHTML );
} ).each( function(tr) {
	var state = tr.getElementsByTagName("select")[0].value;
	Object.extend( tr.style, {
		color : state == "spam" ? "brown" : "red"
	} );
} );

Enumerableだとか、prototype.jsの機能を一部実装してるのでちょっと長いが。

追記

ちなみにトラックバック一覧から絞込みや並べ替えやっちゃうと「http://www.asablo.jp/app?cmd=edit_tb*」にマッチしないのでこのスクリプト無効になっちゃいます。

もう少し使えるフィルタを実装してほしいなぁ > アサブロ

「spam」指定の効能2008年03月26日 03時44分38秒

先日のエントリ

とあるので一応即削除せずにいったん「spam」指定して、半日くらい寝かせてから削除しているのだが、これってほんとに使われてるのかなぁ。
とかぼやいていたら、Days on the Moonのnanto_viさんからコメントをいただいた。

それによると、

3日から5日間でspam指定された情報を収集している
とのことなので、このくらいの期間は「spam」に設定して放置しておいたほうがよいのかも。

でも1日に数十通もスパム受けてると、ほかのトラックバックがまぎれちゃうし、spam指定したら管理画面から消えるなり別管理枠を設けるなりしてほしいなあ。

いや、ウチは普通のトラックバックなんて滅多にいただかないのでそれほど不便じゃないんだけど(w

それにしてもやっぱり「ASAHIネットで利用することがあります」ってのはなぁ。しっかり利用してくださいよ > ASAHIネット