雲雀

雑記

2010年1月24日日曜日

Pythonで遊んでみる その2(Twitter;短縮URLのリンク先確認)

性懲りも無くまたPython使ってみた。
Twitterで短縮URLの飛び先がリンク切れになっていないか?そもそもちゃんと自分が意図したURLになってるかな?と気になって寝られなくなり、簡単だがbitly用のリンク一覧スクリプトを書いてみた。
botなんかで自動的にツイートしてると、(主にバグが原因で)URLが表示されていなかったりリンク切れになってたり、しかも膨大な数のツイートになると目視とか無理。
雑なのであまり参考にならないかもしれませんが。以下ソース

やってることは単に
1. 特定のユーザーのTLから1ツイートづつ読み込む
2. 短縮URLがあったらリンク先に飛んでみる
3.リンク先に飛んでみて、レスポンスコードとメッセージを取得
4. ログファイルにstatusesとか飛び先のURLをwriteする
5. ページ送り
6. 1に戻る

import feedparser, urllib2, re, time, sys

fp = open("bitly_check.log", "a+")

screen_name = "HogeHuga"
count = 200
page = 1

while 1:
    r = urllib2.urlopen("http://twitter.com/statuses/user_timeline.atom?screen_name=%s&count=%d&page=%d" % (screen_name, count, page)).read()
    feed = feedparser.parse(r)
    regex = re.compile('http\:\/\/bit.ly\/[0-9a-zA-Z]+')

    if feed.entries:
        for entry in feed.entries:
            bitlyUrl = regex.findall(str(entry.content))
            if len(bitlyUrl) > 0:
                try:
                    content = urllib2.urlopen(bitlyUrl[0])
                    fp.write("%s\t%s\t%d\t%s\n" % (entry.link, content.geturl(), content.code, content.msg))
                except urllib2.HTTPError, e:
                    fp.write("%s\t%s\t%d\t%s\n" % (entry.link, content.geturl(), e.code, e.msg))
                except urllib2.URLError, e:
                    fp.write("%s\t%s\t\t%s\n" % (entry.link, content.geturl(), e))
                time.sleep(10)
            else:
                fp.write("%s\tNoLink\t\t\n" % entry.link)
                time.sleep(1)

    else:
        fp.close()
        sys.exit()

    page += 1
    time.sleep(10)

fp.close()

※ ちなみにTwitter APIの仕様で、3200件以上前のツイートは上記の方法では取得できません。
Pythonはまだまだ勉強中なので、もっとスマートな方法を考えてみたいなぁ・・・。

2009年12月31日木曜日

Pythonで遊んでみる (主にurllib2とBeautiful Soup)

こんな年の瀬に何をしているんだという感じですが、少しPython使えたらなぁと思いちょっと勉強中です。
まぁちょっと簡単なコードでも書いてのせてみます。
以下、amazonの商品ページをフェッチしてパーシングして価格のみ取り出してprintするだけのコードです。

import re, urllib2
from BeautifulSoup import BeautifulSoup


url = 'http://www.amazon.co.jp/gp/product/*********/'
html = urllib2.urlopen(url).read()
priceDisp = BeautifulSoup(html).find('b',{'class':'priceLarge'})


if priceDisp:
    rePrice = priceDisp.renderContents()
    regex = re.compile(r'[\xef\xbf\xa5\s,]')
    price = regex.sub('\1', rePrice)
    print price

urllib2とBeautiful Soupというライブラリを使っております、正規表現は適当なのでご勘弁を
Google App Engineとか使えば面白そうだなぁと思いつつ、まだまだ勉強が必要そう・・・。
仕事で使うようになったら面白いんだけどなぁ

2009年11月11日水曜日

CakePHP:FormHelper:年月日の値をGETで引き回してみる

全然ネタが無いわけでは無いですが、まぁメモ書き程度で・・・。 この間CakePHPのFormHelper使っててはまった点をばネタに 。

表題の通りなんだけど、CakePHPで検索フォームなんか作ったりしててはまった。

Viewはこんな感じです。
input('Model.date', array('name' => 'date[]', 'selected' => $date, 'dateFormat' => 'YMD', 'timeFormat' => 'NONE', 'monthNames' => false, 'minYear' => date('Y'), 'maxYear' => (date('Y')+1))); ?>

いやー、FormHelperはなんでもできちゃいますねぇ。

んでController
// Controllerには結局配列でわたってきちゃうので、元に戻してあげる
if (isset($this->params['url']['date'])) {
    if (is_array($this->params['url']['date'])) {
        $this->params['url']['date'] = date('Y-m-d', mktime(0,0,0, $this->params['url']['date'][1], $this->params['url']['date'][2], $this->params['url']['date'][0]);
    }
}
// そしてセット
$this->set('date', $this->params['url']['date']);

GETで渡ってくる形がスマートでは無いけど、結構コンパクトに書けちゃったので満足でした。

2009年11月2日月曜日

Greasemonkeyでニコニコ動画のマイリスト追加時にTwitterにつぶやいてみる ~その2 ニコニコ動画(9)~

ニコニコ動画がバージョンアップしてニコニコ動画(9)なってたので、取り急ぎマイリススクリプトもかきかえてみた。あまりキレイなコードではないけど。
 マイリス登録が何故かポップアップになっていたので、「ユーザースクリプトを実行するページ」を

・http://www.nicovideo.jp/mylist_add/video/*


に変更。というか正直個人的にはポップアップはやめていただきたいなぁ・・・。
そして「ひとことコメント入力」も追加されたので、これにも後で対応したいかなと。
 「とりあえず 一発登録」って機能追加されてるけど、よっぽどマイリスト使いこなせない人が多いのか。まぁ自分も人のこと言えたほどじゃないけど。

2009/11/11 ひとことコメントも一緒につぶやくようにちょっとだけ修正しました。

// ==UserScript==
// @name mylismylis
// @description Post niconicodouga mylist to Twitter
// @author sakky
// @namespace http://unslash.blogspot.com/
// @include http://www.nicovideo.jp/mylist_add/video/*
// ==/UserScript==

(function () {
    var mform = document.getElementById('box_mylist_add');

    var twit = function(){
        var url = 'http://twitter.com/statuses/update.json';

        var title = document.getElementsByTagName('h3')[0].innerHTML;
        var mylisthref = 'http://www.nicovideo.jp/watch/' + document.getElementsByName('item_id')[0].value;
        var mselect = document.getElementById('select_group');
        var mname = mselect.options[mselect.selectedIndex].text;
        var comment = document.getElementById('edit_description').value;

        var hitokoto = '';
        if (comment.length > 0) hitokoto = 'ひとこと:' + comment;

        GM_xmlhttpRequest({
            method : 'POST',
            url : url,
            headers: {'Content-type': 'application/x-www-form-urlencoded',},
            data : 'status=' + encodeURIComponent('マイリス追加:' + mname + '[' + title + mylisthref) + '] '+ hitokoto,
            onload : function(res){ message('Updated!');},
            onerror: function(res){ message('Failed to update' + res.status + ':' + res.statusText);},
        });
    }

    mform.elements[4].addEventListener('click', twit, true);
})();

2009年10月13日火曜日

svn mergeする時にRevision指定しなくてもいいシェルスクリプト

最近業務でsvnをバキバキ使いまくってます。
それであれやこれやとbranchからmergeすると、毎回Revisionを確認しなくちゃいけなくてその作業が非常にめんどう。
自分の場合、「最初にbranchしたRevisionからHeadまで」というパターンが主なので専用のスクリプトを組んでみた。

svn_merge.sh
#!/bin/sh


SVN=/usr/local/bin/svn
REVISIONS="^r[0-9]\s\|\s.+\s\|\s[0-9]\{4\}-[0-9]\{1,2\}-[0-9]\{1,2\}\s.+\|\s[0-9]+\sli
ne$"
REVISION_NO="s/r\([0-9]*\)/\1/"


if [ $# = 0 ];
  then
    exit -1
fi


FIRST_REV=`${SVN} log $1 --incremental | grep -e ${REVISIONS} | awk '{printf "%s\n", $
1}' | sed ${REVISION_NO} | tail -1`


echo "***** Dry Run *****"


SVNLOG=`${SVN} merge --dry-run -r ${FIRST_REV}:HEAD $1 $2`
echo ${SVNLOG}
echo "Merge OK? [y/n]:"


read ans


if [ ans = 'y' ];
  then
    SVNLOG=`${SVN} merge -r ${FIRST_REV}:HEAD $1 $2`
    echo ${SVNLOG}
fi


一回DryRunして、確認してからマージしてます。
最初のRev取ってるところは、svn logがきっとバージョンによって違うんだろうなぁ思ってみる・・・。

PATH通して、
svn_mrge.sh "マージしたいファイル" "対象ファイル"
でOKのはず。

やっぱりsvnは使いにくいから、いっそ対話型のもの作ろうかと思った。

2009年10月11日日曜日

ZendFramework: Zend_Service_Twitterで超簡単なbotを作ってみる

このあいだ、ZendFrameworkのZend_ServiceにTwitterが追加されている事を知って、簡単なbotを作ってみました。

botといっても本当に簡単で、reply返しをするだけのもの。


require_once "Zend/Service/Twitter.php";
define(DATEFILE, "date.dat");


$datefile = file_get_contents(DATEFILE);


$twitter = new Zend_Service_Twitter("ユーザー名", "パスワード");


$response = $twitter->status->replies();


foreach ($response as $reply) {
    if ($datefile <= date("Y-m-d H:i:s",strtotime($reply->created_at)))
        $twitter->status->update("@".$reply->user->name." "."こんにちは、".$reply->user->name."さん。");
}


file_put_contents(DATEFILE, date("Y-m-d H:i:s"));


エラーチェックは特にしてない。
一応、簡単にだけど前回の実行時間を取って置いて、重複して送らないようにしてみる。
Twitterbotはお手軽だけど、色々やろうとするとなかなか面白い。
もう少し凝ったbotも作ってみたけど、正直用途ってむずかしいよね・・・ネタbotはすぐに飽きるし。

Zend_Service_Twitterについてはマニュアルを読んでおくと良いかも。Twitter APIで出来る事は大体できるようだけど。

2009年10月7日水曜日

Greasemonkeyでニコニコ動画のマイリスト追加時にTwitterにつぶやいてみる

ニコ動のマイリスト追加時に、自動でtwitterにつぶやいてくれるグリモンを探していたんだけど、見つからなかったので書いてみた。
ちなみに、履歴をtwitterにつぶやくグリモンがあったのでそちらを参考にさせてもらいました。

UchのX40記: [JavaScript] ニコニコ動画で見ている動画のURLをTwitterにポストするGreasemonkeyスクリプト

で実際自分で使ってるコード


// ==UserScript==
// @name        mylismylis
// @description Post niconicodouga mylist to Twitter
// @author      sakky
// @namespace   http://unslash.blogspot.com/
// @include     http://www.nicovideo.jp/watch*
// ==/UserScript==

(function () {
    var mform   = document.forms.namedItem("mylist_form");

    var twit = function(){
        var mselect = mform.elements.namedItem("group_id");
        var mname  = mselect.options[mselect.selectedIndex].text;
        var url = 'http://twitter.com/statuses/update.json';

        GM_xmlhttpRequest({
            method : 'POST',
            url    : url,
            headers: {'Content-type': 'application/x-www-form-urlencoded',},
            data   : 'status=' + encodeURIComponent('マイリス-(´・ω・`)っ [ ' + mname + ':' + document.title + location.href) + ' ]',
            onload : function(res){ message('Updated!');},
            onerror: function(res){ message('Failed to update' + res.status + ':' + res.statusText);},
        });
    }

    mform.elements.namedItem("mylist_add").addEventListener("click", twit, true);

})();




とまぁこんな感じです、Javascript苦手なので書き方はご愛嬌。
Javascript苦手とかじゃなくて、ちゃんと書けませんorz
ちゃんと動いてなかったので、一部書き直してみた。