URLDecodeされなかったファイル名を直す。

小さいけど実用になるGroovyコードのメモ。

Firefox pluginの Video DownloadHelperというツールがあります。
これは別に動画ダウンロード専用ではなく、拡張子を追加定義すれば ppt や doc や pdf も一気に落とすことが出来ます。
ただし日本語対応していないので、各種日本語名のファイルをダウンロードした時、ファイル名がURLDecodeされないままでファイルが落ちてきます。
例えば "ファイル名.pdf" というファイルは "%83%74%83%40%83%43%83%8B%96%BC.pdf"
という名前となってしまいます。
充分に日本語化対応していないツールでは、時々あることなので、この名前を元に戻すスクリプトを書きました。
開始ディレクトリーから下のファイル全てに対して、一気にファイル名のURLDecodeの書き戻しします。

new File(".").eachFileRecurse { file -> 
	if(file.isFile()){
		curName = file.getPath().replaceAll(/.\\(.*)/) {m0,m1 -> m1}
		newName = new File(URLDecoder.decode(curName, "UTF-8"))
		println "現行ファイル名: "+curName
		println "新規ファイル名: "+newName
		file.renameTo(newName)
	}
}


コマンドイラン電卓

小さいけど実用になるコードのメモ。
Groovyで書いた、コマンドラインでの電卓。
eval()がある言語は、どれで書いても、きっとこんな感じになるのではないかと。

import groovy.util.Eval
if (args.length ==0) {
	println """Groovy電卓 使用例: dentaku 1+2*3
第一引数に 計算式を指定してください"""
	return
} 
def eval = new Eval()
println eval.me(args[0])

bit.lyでの圧縮をWeb APIでなく実行するGroovyスクリプト

tyamaさんの
bit.ly が普通におもしろかったのでGroovyでAPIを使って遊んでみた
http://d.hatena.ne.jp/mottsnite/20100209/1265725950

のエントリーを見てbit.lyのAPIについて納得。
今まで適当にheaderのスクレイプでbit.ly圧縮していました。
Web APIを探す努力もしていませんでした。
APIがあるなら使うべきなので、そのうちこのメソッドはreplaceします。
ちなみに j.mp は単に bit.ly のエイリアスです。
headerの場合はloginとかなしでの実行となります。
今もこのメソッドでbot動かしています。

def getJmp(String longstr) {
	def url = 'http://bit.ly/?s=&keyword=&url='+URLEncoder.encode(longstr,"UTF-8")
	def ans = ""
	url.toURL().getText("UTF8").eachLine { 
		if (it==~/.*\"shortUrl\".*\"(http.*)\".*/) {
			ans = it.replaceAll(/.*\"(http.*)\".*/) {m0, m1 -> m1 }.replaceAll(/bit\.ly/,"j.mp")
		}
	}
	return ans
}
assert getJmp('http%3A%2F%2Fwww-06.ibm.com%2Fsoftware%2Fjp%2F')== 'http://j.mp/cYbe1'

Twitter Streaming API でTLをテキストでだらだら出力するGroovy

TwitterのTimeLineの出力をだらだらコンソールに出力するGroovyスクリプトです。
フォロワー数は200以下のアカウントでないと filterが動作しなくなります。
APIの制限です。

http://yusuke.homeip.net/twitter4j/ja/api-support.html#Streaming%20API%20Methods
の birddog filter() あたりの記述に制限も解説されています。
Pagingできるようなので、うまくやるとフォロアー数の制限を超えられるかもしれません。
そこは、まだ調べていません。
@Grab は、ついていますが、Groovyのバージョンで書式が変わるので、使わなくても良いと思います。
動作させると、塊ではなく、一件ずつ、だらだら "timestamp+id+本文" の書式でテキストで出力され続けます。

import twitter4j.http.* 
import twitter4j.*

start() 
 
@Grab(group='net.homeip.yusuke', module='twitter4j', version='[2.0.10,)') 
def start() 
{ 
def uid="ユーザーID"
def pwd="パスワード"

	def twitter = new Twitter(uid, pwd ) 
	def userIds = twitter.friendsIDs.IDs 
	
	userIds.each {println " - " + it}
	
	println "Got friends userIds: ${userIds.size()}"
	def twitterStream = new TwitterStream(uid, pwd) 
	twitterStream.statusListener = [  
		onException : { ex -> println ex},  
		onStatus : { status ->
			//status -> println status 
			def time = status.toString().replaceAll(/.*createdAt.* ([0-9][0-9]:[0-9][0-9]:[0-9][0-9]) .*, id=.*/) {m0, m1 -> "${m1}" }
			def name = status.toString().replaceAll(/.*screenName='(.*)', location.*/) {m0, m1 -> "${m1}" }
			def text = status.toString().replaceAll(/.*text='([^']*)', source='.*/) {m0, m1 -> "${m1}" }

			println time+" "+name+"\t"+text
		} 
	] as StatusListener 
	twitterStream.filter(0, userIds, [] as String[]) 
}

GroovyでTwitter botを作るための code部品

あるTwitterアカウントでの最近の発言群の中心をなすキーワードを抽出したリストを作る。

これによりタグクラウドを作る時の部品にする。
または、収集ボットを作る時に、似たような投稿はふるい落とすことに使う。

それまでの投稿内容のキーワードを10単語まで、バッファに保存し続けて
今回収集した投稿文のキーワードが、いまあるバッファにある単語と一致したら、
同一トピックについて語った文面であると判定して、評価を下げます。
これによって、
例えばあるニュースが流れて、それに反応して多くの人がつぶやいたとします。
捕捉ボットは、その場合、一番最初につぶやいた人の文面は普通にキャッチしますが、
二番手以降のつぶやきの評価は、一番手の発言で使用された単語とかぶるので、
そのつぶやきの捕捉確率を下げます。
その後もつぶやきを捕捉し続けて、その単語がバッファ辞書から流れて消えていけば、またおなじ捕捉確率に戻ります。
キーワードの除外単語は
 ハッシュタグ、ユーザーID、短縮URL
としました。

Yahoo APIのキーフレーズ抽出APIを使用しました。使用言語はGroovyです。

import twitter4j.*

cache=["某0","某1","某2","某3","某4","某5","某6","某7","某8","某9"]

Twitter twitter = new Twitter("ユーザーID","パスワード");
Iterator <Status> i= twitter.getUserTimeline("誰かターゲットのID").iterator();
	while(i.hasNext()) {
		ans = i.next().getText()
		getKwd(ans)
	}

def getKwd(String text) {
	parm1 = URLEncoder.encode(text.replaceAll(/#[^ ]+/,"").replaceAll(/@[^ ]+/,"") ,"UTF-8") 
	 // ハッシュタグとIDは除外
	def rssFeed =  ("http://jlp.yahooapis.jp/KeyphraseService/V1/extract?appid=取得したYahooAPIのID&sentence="+parm1).toURL().getText("UTF8")
	def rss = new XmlSlurper().parseText(rssFeed)
	kwd0= (rss.Result.Keyphrase[0]).toString().replaceAll(/ /,"")
	kwd1= (rss.Result.Keyphrase[1]).toString().replaceAll(/ /,"")
	if (kwd0 != "bit.ly"&& kwd0 != "tinyurl.com"&& kwd0 != "ff.im") {
		cache.add(kwd0)
		cache.remove(0)
	}
	if (kwd1 != "bit.ly"&& kwd1 != "tinyurl.com"&& kwd1 != "ff.im") {
		cache.add(kwd1)
		cache.remove(0)
	}
	// 短縮URLは除外
	println cache
}

ここではバッファ辞書サイズは10単語、ひとつの文から2単語ずつ抽出しています。
動作イメージ

[某2, 某3, 某4, 某5, 某6, 某7, 某8, 某9, 今多摩川, 花火]
[某3, 某4, 某5, 某6, 某7, 某8, 某9, 今多摩川, 花火, 口語体]
[某5, 某6, 某7, 某8, 某9, 今多摩川, 花火, 口語体, Gaelyk, Groovy]
[某7, 某8, 某9, 今多摩川, 花火, 口語体, Gaelyk, Groovy, JConsole, JRuby]
-- 以下続く --

ときどき対象外の単語があったときは、二つずつひろうとは限らなくなります。

Google App Engine上でGroovyとTwitterを動かす為のセットアップガイ

Google App Engine上でTwitterをGroovyで動かす情報。

(bot作ろう会 Groovy分科会は、会員絶賛募集中です。)

必要なファイルは下記zipにまとめてあります。

http://textcode.vs.land.to/GROOVY/TwitterBotGroovy1.zip

まず、Java環境でのHello Worldまでは完了しているものとします。

■ Twitter4j と Groovyのjarの配備


以下の二つのjarを、以下の位置に配置します。

war/WEB-INF/lib に
groovy-all-1.6.3.jar
twitter4j-1.0.4.jar
のふたつのjarを追加します。ここwar以下のファイルはserverに実際にdeployされます、
これによりこれらのjarはサーバにも送られます。


置き場所は、例えば、
c:\workspace\GroovyBotTemplate1\war\WEB-INF\lib  
とかになりまか。
eclipseの該当ディレクトリに直接ファイルを置いて、
プロジェクトの右クリック -> Refresh
で見えるようになります。


■Groovy ファイル置き場の用意
WEB-INF の右クリック->New-Folder で groovyフォルダーを作成します


■Groovletの関連づけ
web.xmlservlet mappingのルールを追加
以下の2定義でワンセットです。
拡張子がGroovyのファイルは GroovyServletとして名前を共通して与え、そのServletは grovy.servlet.GroovyServlet クラスとして扱いますという意味です。


下記定義部分をご自分のweb.xmlに追加してください

    <servlet>
		<servlet-name>GroovyServlet</servlet-name>
		<servlet-class>groovy.servlet.GroovyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
		<servlet-name>GroovyServlet</servlet-name>
                <url-pattern>*.groovy</url-pattern>
    </servlet-mapping>


■Groovletの配置

groovyのフォルダーの下に Hello.groovyという名の groovlet (Groovy Servlet)を置きます。

html.html {
    head {
        title "Hello"
    }
    body {
        p "Hello from Hello.groovy"
    }
}

ここでプロジェクト動かしてみましょう


■ Hello from Hello.groovy が見えること。

http://localhost:8080/Hello.groovy を指定して Groovletが見えることを確認します。


下記の様なHTMLがGroovletによって作られています。
Groovlet便利でしょ。

<html>
  <head>
    <title>Hello</title>
  </head>
  <body>
    <p>Hello from Hello.groovy</p>
  </body>
</html>


■今度はTwitter bot の骨格を作って、現在時刻をつぶやいてみましょう。


下記コード Jihoubot.groovyを groovyフォルダに置きます。これを動かしてみましょう。

import java.text.*
import twitter4j.*

now = new SimpleDateFormat("yyyy/MM/dd HH:MM:SS").format(new Date())

twit = new Twitter("あなたのuserid","あなたのpassword")
twit.update("現在の時刻は ${now} ")

html.html {
    head {
        title "Jioubot"
    }
    body {
        p "posted ${now} "
    }
}


はい、これでご自分のTwitterアカウントに現在時刻が投稿されたでしょうか。
cookieがセットできないとか、時間が日本時間ではないとか
まだいまいちな部分がありますが、これで投稿までは出来ましたね。
投稿用お試しアカウント coolpoco を見ると、
うまくいった時の実行結果が分かると思います。
http://twitter.com/coolpoco

あと汎用で組み込まなくてはいけないのは

  • cronによる自動実行
  • 例外処理
  • logging
  • 外部ファイル参照 (これは使わないこともあるかも)

あたりですね。
とりあえず第一回での作業内容としては、このあたりでよいと思います。
Groovyがいい感じだということがおわかりいただけたと思います。

■ BOTTUKU の favicon.ico (もはや公式アイコン?) も入れておきました。
 これはお好みでwarの直下のindex.htmlと同列に配置して使いますが、これはお好みです。

JavaOne2009の Core Java SEの面白そうな資料のメモ

JavaOne 2009の資料がdownload出来るようになってます。
http://developers.sun.com/learning/javaoneonline/j1online.jsp?track=javase&yr=2009


Core Technology: Java SE and Desktop で、面白そうな資料のリンクメモ

TS-3968.pdf JavaFXとGroovy カヌーのDierk Konigが書いている
TS-4215.pdf Groovy1.6 新機能 GAEで動作させる話もあり
TS-4487.pdf Scala入門
TS-4620.pdf 同期処理
TS-4955.pdf GroovyとJRubyの比較 104ページ
TS-4961.pdf LL Patterns LLでGoFを書くとどうなるか
TS-5061.pdf Teracottaの分散GC 後で理解する
TS-5217.pdf EffectiveJava2からの抜粋?
TS-5301.pdf Hudson Kawaguchiさんスピーカーだったらしい、唯一の日本人では?
TS-5385.pdf Azul VM クラウド的な意味で、後で理解する
TS-5395.pdf ActorベースのScala同期化、なにやら重要そうだが、Scalaの一般理解が先


毎年、全部ダウンロードするが、なかなか呼んでいられない。