twitterでspammerのfollowを自動block

-- 追記2
ごめん,バグあった.文字列操作まわりのencodingがかなり怪しい.
空の時,Noneが入ってくるのは空文字列に置き換えるべきか.

-- 追記
きっと誰も AND/OR 検索を実装してくれないので,実装した.
ついでに, twit_oauth.py を更新して,フォロワだけでなくフォローしてる人の一覧も取れるようにした.

先の記事twitterのspammerのfollowが多いでも書いた,spammerのキーワード抽出について.
GMail からの PUSH 通知をトリガとした動作がうまく実装できなかったので (なぜか python2.5.xでは,imaplib2 がうまく動かない)
とりあえずトリガーは何も考えてません.cron でも,IMAP/IDLE でも,好きに実装してください.

twitter を変なライブラリなしで OAuth 認証で動かすクラスは,こんな感じで実装してます → twit_oauth.py
で,こいつを使って,下記のように使うとスパムフィルタのできあがり.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import simplejson,re
from twit_oauth import twit_oauth

__KEYWORDS = [(re.compile(u'キーワード1'),),
              (re.compile(u'キーワード2-1'),re.compile(u'キーワード2-2'))
             ]

# プロファイルリスト取得関数
def getProfiles(followers,pobj):
    profiles = {}
    for f_id in followers:
        profs=simplejson.loads(pobj.callAPI('profile',`f_id`))
        if profs['name']==None: name=''
        else: name=''.join(profs['name'].split('\n'))
        if profs['description']==None: desc=''
        else: desc=''.join(profs['description'].split('\n'))
        profiles[`f_id`]=(name,desc)
    return profiles

# テキストマッチ関数
def filterByKeys(profiles):
    fil_list = []
    for (id,prof) in profiles.items():
        # __KEYWORDS のいずれかの要素1つでも合致すればブロック (OR)
        for keys in __KEYWORDS:
            fil_list.append(id)
            # __KEYWORDS の1要素の中の,全てのマッチが成功すればブロック (AND)
            for k in keys:
                if not k.search(prof):
                    del fil_list[-1]
                    break
            # 重複登録回避
            if len(fil_list) != 0 and fil_list[-1] == id: break
    return fil_list


pobj= twit_oauth('xxxxxxxxxxxxxxxxxx','xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
                 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx','xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')


# 自分の username を入れて,フォロワーを取得
followers = simplejson.loads(pobj.callAPI('getfollowers','username'))
# フォロワーのプロファイルを取得
profiles  = getProfiles(followers,pobj)
# キーワードマッチでフィルタ対象を取得
fil_list  = filterByKeys(profiles)
# ブロック
for fid in fil_list:
    print pobj.callAPI('block',fid)
# report_spam 自動処理で報告してしまうので,非推奨
# for fid in fil_list:
#    print pobj.callAPI('report_spam',fid)

report_spam を呼んでないのは,巻き添えレポートを防ぐため.
キーワードに絶対の自信があれば,使ってください.
and検索,or検索したい場合は,k.search(prof) の所を工夫してください.
実装済.

twitterのspammerのfollowが多い

級にspammerが来始めたので,なんか炎上してた人をフォローしたせいか,大手画像サイトとかをフォローしたせいだろうなぁ.
で,私のfollowerリストから更に他の人に飛び火すると悪いので(もう遅いかも知れんが…),一旦非公開アカウントにしました.
spammerの自己紹介や行動には,一目見て分かるほど特徴が沢山あるので,非公開にしているうちに,自動blockするスクリプトを作ることにした.
これまでの経験上,誰かが私をfollowするのは,頻度が高くても1人/週程度なので,1週間を目処に解決を目指そう.

前提

  • 今借りているレンタルサバ上でwebに溢れているサンプルコードを動かそうとすると,モジュールが足りない
  • pythonのモジュールは,同じディレクトリに置けば動かんこともないが,twitter関係の操作に必要なモジュールを1から入れようとすると,依存関係のため入れるべきモジュールが多い上,それぞれのimport文に対応するよう配置しないといけないので大変すぎる.
  • 自宅PCは最近は1~2回/週しか立ち上げないので,それではspammerのやりたい放題

つーことで,新たな常時起動しているサバを用意するか,コードをある程度自作する必要があることが分かった.
とか思考を全部書いていくと時間が足りないので結論だけ書く.
Google AppEngineでpythonコードを動かすか,標準モジュールだけでpythonコードを動かすかの両睨みができる方法を取ることにする.
具体的には,標準モジュールだけでTwitter APIを操作できるようにしながらも,GAEの開発環境は用意し呼出し部は2パターン作った.

で,cronを使うよりも,twitterでfollowされる度に飛んでくる通知メールをGMailで受け取って,それをトリガーに動作させてみたいと思い,GAEに挑戦することにした.
追記: GAEだもの,GMail くらい直接触れるでしょ,なんて思い込みがあったが,触れないことが分かった.オーノー

GAEについて

pythonしか試していないのでpythonのことを書く.
Google AppEngine より,登録してSDKを落とす.
Windows版はmsiファイル,Linux版はただのzipファイル.
Win版は,C:\Program Files (x86)\Google\google_appengineへインストールされる.Linux版は,unzipして展開するだけ.
python2.5.x でないと動かない.

$ python (PATH)dev_appserver.py demos/guestbook

と実行すれば,サンプルが動作する.

guestbookと同じように,app.yamlとそこから呼び出されるpyファイルを配置すればOK.
制限をかけたい場合は,app.yamlの制限したいscriptを定義しているscript行の下あたりに,login: required (Googleアカウントでログインしてないとダメ) とか, login: admin (GAEの該当プロジェクトの管理者権限がないとダメ) とか書く.
GAEへアップロードするには,

$ python appcfg.py update project_name

とかする.
アクセス先は GAE の dashboard の application settings にあるが,http://application_name.appspot.com とかだと思う.
サンプルみたいに wsgiref.handlers.CGIHandler().run(application) で呼び出してもいいが,デバッグしたい時は,from google.appengine.ext.webapp import utilとインポートしておいて,util.run_wsgi_app(application)とすると,ブラウザ上にデバッグメッセージが表示される.
どうせ開発環境では,dev_appserver.pyを呼び出している窓にも同じメッセージが表示されるけど.
詳しくは,ユーティリティ関数 - Google App Engine - Google Codeとかを参照のこと.
あと,simplejsonとか,ちょっと欲しいモジュールは入っていたりするけど,oauthtwitterとかニッチなのはない.
外部ファイルからクラスをインポートしたい時は,同じフォルダにpyファイルを置いてimportすれば,開発環境では動く.GAE上では試してないので不明.

twitterAPIについて

仕様がよく変わるので,公式の最新のもの(英語)Documentation | Twitter Developersの REST API を見た方が早い.
BASIC認証はもう使えないらしいので,OAuth認証を使う覚悟をする.
情報取得系はGETで叩き,情報更新系はPOSTで叩くRESTful I/F.
応答はJSONかXML.
アクセストークンの発行が死ぬほど面倒くさいので,頑張る.私は,やる夫と Python で学ぶ Twitter の OAuth - YoshioriのBlogを参考にした.
どうせReadもWriteもやりたくなるので,Read/Writeは少なくともつけておく.
QUERYをトークンをキーに符号化したものを署名としてHTTPヘッダへ埋め込み,肝心のQUERYは上記の通りGETかPOSTで投げるので,二重に必要なことを忘れない.

で,上に記載のやる夫と Python で学ぶ Twitter の OAuth - YoshioriのBlogのソースコードを改変して作ったのがこんなクラス → py_twit.py 更新しました → twit_oauth.py
無駄に書いてるimportとかはそのうち消します.
なお,screen_nameをuser_idとする場合,idは文字列で渡すこと.
また,statuses/updateは同じ発言を2回書くと403を返す,など応答については各々調べること.

あんま関係ないが,pythonのこと調べてると,大学時代の同級生がたいてい出てくるので,よくビビる.
今回の案件では,コードの美しさというよく分からん評価軸について語っていたので,反映しなかった.

Android 2.2から1.6へ

軽いと噂のCM6.1を使っていたが,やっぱHT-03aでは重いので,Android1.6を導入することにした.

今回は,Super D 1.11 non ram hack
こいつの導入にあたっては,いくつか注意がある.

Super D は1.5くらいから,SDカードのswapパーティションに対応しており,
ちゃんとパーティションを切ってやらないと動かないため,
まず,リカバリーイメージをアップデートしてSDカードにパーティションを切れるようにすること.
DRC83_base_defanged.zipから導入すること.
更に,b-mobileのSIMを挿す場合は,libhtc_ril.soを差し替えること.

導入にあたって参考にしたページはここ→HT-03a カスタムROM導入ログ-vol.1「初期設定とGoldcard作成」 « Midnightjapan
b-mobile対応にあたって参考はこちら→Android 1.6でbmobileが動いた « コムギドットネット

  • ここから,recovery-RA-sapphire-v1.7.0G.imgを落として,SDカードへコピー
  • Android SDK を導入して,
    > adb shell
    $ su
    # flash_image recovery /sdcard/recovery-RA-sapphire-v1.7.0G.img
    

    として導入.

  • 一旦電源を落とし,Homeを押しながら起動してリカバリーモードから
    「Partition sdcard」を選択し,[swap:32MB/EXT2-size:512MB/FAT:Remainder] でフォーマット
    「SD:ext2 to ext3」を実行してext3フォーマットに変換.
  • 再起動後,別のSDカードにDRC83_base_defanged.zip,SuperD v1.11 をコピーし,この順番で導入
  • パーティションを切ったSDカードを差して起動

akismet の結果抽出

wordpress のコメントのDB (prefix_comments) から,comment_approved='spam' で抜ける.
なので,例えば…

select comment_author_IP,comment_author from prefix_comments where comment_approved='spam' order by comment_author_IP;

などと抜いて,
xlsでピボットテーブルを使って,頻度順に並べかえれば,特にアクセスの多いIPアドレスを抽出可能.

WordPressでMIME-TYPEをapplication/xhtml+xmlとする

-- きっとこれで終わる追記

本家のフォーラムで,
パッチを作ってもらえました.
えがった,えがった.
general-tempate.php に,linkタグの出力があったんだなぁ…

-- 追記

フォーラムで報告したところ,もう少しスマートな方法をご紹介いただいた.
でももう眠いので,また今度ためします.
フォーラムの該当記事はこちら→サイト内検索時のRSSフィードのURL出力について

-- 元の記事

これはハマった.

ちなみに,application/xhtml+xml は,IE8以前では認識されないため,IE8以前向けには出力していません.確認をしたい方は,firefoxとか使ってください.IE9もイイヨ.

症状
wordpressの出力のMIME-TYPEをapplication/xhtml+xmlとすると,サイト内の検索結果が表示されない.
原因
検索結果画面のlinkタグ内のURL内のセパレータに `&' ではなく,`&' が使われているため,XMLパースエラーを起こす.
対処
wordpressのインストール先ディレクトリを ``/wp_blog`` とした時に,
``/wp_blog/wp-includes/link-templete.php`` の L.796付近,及びL.825 付近 (wordpress 3.1.2 の場合) にある次のソース,
``$link = apply_filters('search_feed_link', $link, $feed, 'posts');``
で出力されるURLが,他の部分と異なり `&' と出力すべきセパレータを, `&' と出力してしまう.
本来ならば,search_feed_link というキーで適用されるフィルタか何かを修正したいが,ソース内を検索しても見付からないので,このソースを該当行の次の行に埋め込むことで対処する.

  $link = str_replace('&','&',$link);
  ...(略)
  $link = str_replace('&','&',$link);

HT-03a+b-mobile sim u300

白ロムを手に入れたので,docomoのsimをガラケーに,b-mobileのsimをht-03aに入れて使おうと試みた.
ちょっとハマってしまったのでメモ.

症状
b-mobileの設定通りにAPNを設定しても,圏外表示のままであり,
Gmailの同期エラーが繰り返される.
解決策
  1. ブラウザを起動して,圏外表示でも接続できていることを確認する
  2. notification (通知領域?) に表示されるGmailのエラーを選択して,パスワードを改めて入力する

しかし,googleのcontactsとは同期できているアドレス帳を,どうやってガラケーに落としたものか…
ガラケー→スマフォンの移行は楽にできたが,逆の方法は1分ぐぐっただけでは発見できなかった.
vcfを取り込む方法くらいありそうなものだが…ま,他に時間ある時にでも調べよう.

-- 追記
\SD_PIM\PIMxxxxx.vcf という名前にすれば,読み込むことができた.
しかし,なぜか本体にコピーできないので,vcfファイルの中身を調査中.

-- 追記2
多分,UTF-8がquoted printableとやらでエンコードされてvcfに落ちているのが問題じゃないかと.
ガラケーで直接vcfを読み込んで表示することはできるが,コンバートが失敗しているのかしら.その点では,登録noがないことの方が問題なのだろうか.
いずれにせよ,その辺りのフォーマットの問題と思われ.

-- 追記3
ガラケーの仕様上,ふりがなが半角カナではないと未設定扱いになってしまい,
その他リストに全て入っていた.
ふりがなを設定すれば普通に見ることができた.

Topsy Retweet Button で RT した時の文字化け解消

文字化けというか,URLエンコードされた文字列が,引用されてしまう現象.
Topsy Retweet Button のプラグインを WordPress で使っていると,
日本語のタイトルが次のように表示されてしまう現象があった.
「Topsy Retweet Button で RT した時の文字化け解消」→「Topsy%20Retweet%20Button%20%82%c5%20RT%20%82%b5%82%bd%8e%9e%82%cc%95%b6%8e%9a%89%bb%82%af%89%f0%8f%c1」

[WordPress] リツイートボタンを簡単に設置出来る Topsy Retweet Button | t011.org (←なぜか,Chromeだと落ちる) によれば,
設定画面で次のチェックを外すことで解消されるらしい.

Preload static retweet button before fetching count/badge data (Note: May cause raw "gibberish" code to appear in some themes; [see the Topsy plugin FAQ](http://wordpress.org/extend/plugins/topsy/faq/) for details.)

公式ページの FAQ によれば,
特定のテーマでは,PHP の関数の使い方の関係で,コードが表示されてしまうとか.
多分,テーマのファイルを修正したら直るんじゃないだろうか.
で,これをオフにした影響としては,個別記事ページではない複数記事を表示しているページで,
RT 件数が表示されなくなることのようだ.
(追記:ちゃんと表示されました)
hadacchi blog の場合は,元より RT されることは稀なので,気にしないことにする.

NEC speax の周波数帯設定

NEC の電話・FAX複合機 speax には,子機との無線帯域の設定項目がある.
どうやら2.4GHz帯を使っていて,無線LANと干渉するためらしい.
しかし…説明書のどこを読んでも各設定値と対応する周波数帯域が記載されていない.

で,NECに問い合わせた人がいるようなので,転載.

設定1: 2439~2478MHz
設定2: 2401~2420MHz 及び 2458~2478MHz (初期値)
設定3: 2401~2441MHz
設定4: 2401~2478MHz (2.4GHz帯全域)

from 備忘録 : NEC Speaks で無線LANと干渉

で,対応chを調べようとして ieee802.11 仕様書を見て挫折した.
ch1って,2.412GHz からだと思っていたんだけど,違うのかしら.
IEEE 802.11-2007, p.516 によれば,日本で規定される周波数帯は 2.471--2.497 GHz となっている.
見る場所が違うのだろうか.

web 上でよく見る数値だと,バンド幅として22MHzで中心周波数が以下の数字のものだ.
これを信じるなら,11chを使っている我が家では,設定3にしておけば良いことになる.
まーとりあえずそうしておこう.

1ch: 2.412GHz
2ch: 2.417GHz
3ch: 2.422GHz
4ch: 2.427GHz
5ch: 2.432GHz
6ch: 2.437GHz
7ch: 2.442GHz
8ch: 2.447GHz
9ch: 2.452GHz
10ch: 2.457GHz
11ch: 2.462GHz
12ch: 2.467GHz
13ch: 2.472GHz
14ch: 2.484GHz

なんで,HT-03aはCH11,CH13,CH14しか選択できないのだろう

IEEE802.11gの話.

ウチのHT-03aは中身をいじっているが,いじる前から,CH11, 13, 14しか選択できなかった気がする.

無線LANには,IEEE802.11a,IEEE802.11b,IEEE802.11g,IEEE802.11nなどの通信の規格がある.
他にもセキュリティ機能とか,通信品質(QoS)だとかの規格が11iだとか11eだとかあったりするが,それは割愛.

IEEE802.11gというのは,ある無線の周波数帯(2.4GHz帯)での無線LANの仕様のこと.
具体的には,2.412~2.4835GHzが使われているらしく,その間を13個のチャンネル(CH)に分割して,定められている.(11bは14個)
ただし,13個のCHは,完璧に分割されているわけではなくて,例えばCH1はCH2~CH5とかぶっている.
で,これらを使うと,無線LANの親機を複数台置いてCHを分けることで,混線を防ぐことができる.
(三重に住んでいた時は,1314kHzのラジオ大阪と1332kHzの東海ラジオが混線して困ることがあった.懐しい…)

で,国際的にはIEEE802.11gの規格ではCH1~CH11までしか使わないことが多いらしい.(CH13まで説もあるので,その辺は知りたい人が調べてください)
そんな事情を考えれば,CH1~11で選択できるようにするべきであって,CH11,13,14という選択肢はおかしい気がする.
機器によってはCH11までしか吹けないものもあるので,必然的にCH11を選ばざるをえないのだが…なぜこんな設計になったのだろうか.

なんでこういう話になったかというと,ポケットWi-Fiを買って,周囲の無線LANの設定を見直したから.
別の話だが,「SIMロックフリーのポケットWi-Fi+スマートフォン+3GのSIM×2枚」で使う方が,スマートフォン単体で使うより月額料金が安くなるのが驚きである.

Android 携帯で Gmail が何日も送信されない件

Android 携帯(HT-03aを使用中)で,「Gmail」 でメール送信をしようとしても,送信トレイ内で送信中と表示されたまま,何日も送信されない,ということがたまに起こる.
以前考察では(HT-03Aメール関係トラブル),データの同期という設定項目が原因じゃないかと書いた.
でも今の状況を考えると,解決方法(データの同期のチェックをオン・オフする)は合っていたようだが,原因は違うんじゃないかという気がする.
今回は,どう解決していいか分かってませんが,メモ程度に.

以前の考察の復習

以前の考察の前提条件.

  • 「Gmail」,「メール」とは,それぞれGmail,メールという名前のAndroid上のアプリケーションプログラムのことをさす.Webサービスの Gmail や一般的な電子メールのことは,括弧無しでそれぞれ書く.
  • 設定>データの同期>Gmail のチェックボックス,をオフにしている
  • 普段は「メール」を使っており,同期間隔を15分にしていた
  • たまに「Gmail」でメール送信していた

以前の考察時に起こっていた事象

  • 「Gmail」でメールを送信しようとしても,送信トレイに送信したつもりのメールが入っており,送信中と表示されたまま数日経っても送信されていた
  • 設定>データの同期>Gmail のチェックボックス,をオンにした途端,たまっていたメールが一斉に送信された

今回の事象

状況

  • データの同期のチェックは入れていた
  • twitterを読めていた(3Gでwebに接続できていた)環境下で,「Gmail」でメールを作成し送信した,つもりだった
  • その後,他にも数件「Gmail」でメールを作成し送信していた
  • 翌日,どうも話が噛み合わないので確認したら,送信トレイにメールが残っていた.しかし,その後に出したメールは届いていた