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) } }
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.xmlにservlet 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の一般理解が先
毎年、全部ダウンロードするが、なかなか呼んでいられない。