2011年12月22日木曜日

WindowsPhone全国ハッカソン祭りin東京

WindowsPhone全国ハッカソン祭りin東京

に参加してきました。



以前、mixi scrap challenge に参加をした際に出会った方に再会したり、

舞鶴からはるばるやってこられた方に出会ったり、

大学のすげぇ近所に住んでいる方に出会ったり、

そして、講師の方がわが校のOBだったりと、なんかすごい感じでした。

イベント自体は、黙々と作成をするスタイル。

一応「虎の穴」と言うことで初心者むけレクチャーにも参加をしてマーケットへの登録を行いました。

これで、実機でデバッグができるという物・・・長かったぜ・・・
飲み会の風景 


写真は例によって例のごとく、飲み会の風景。

C#なんて書いたことはほとんどありませんでしたが、JAVAがわかっていればなんとか・・・なるのか?

命名規則から知っていきたいです。




 

ちなみに、私は「GPSとWebAPIを組み合わせて最寄り駅を検索し、その最寄駅に関する小ネタをWikipediaやGoogle,路線検索APIから拾ってきて表示するアプリ」

を作っていましたが、あえなくタイムアップ。HTTP通信の方式が分からず、ようやくそれが終わってXMLの解析の手前でした。

よく考えたら、「虎の穴」で作成したアプリはTwitterのタイムラインを表示するものだったし、クラウディアさんとコミュニケーションとか、Twitterアプリケーションを構築

とかで、やってることだったのに・・・。もったいない。

仕方ないので、家で実装をして公開します。明日中にうまくいくといいけどなぁ・・・きついかな?

2011年12月11日日曜日

GoogleAppEngindeで、「バルス数えるったー」を作りたかった

去る2011/12/09

日本テレビ、金曜ロードショーで放送された「天空の城ラピュタ」

言わずもがな、知られた「バルス」でTwitterやニコ動にDDos攻撃が行われた。

Twitterはどうやら、落ちてしまった模様。ニコ動は事前の告知通り耐えぬいたらしい。

私自身は、あんまりそう言うのに興味がないので一人でSkyrimをプレイしていた。

しかし、晩飯の弁当をもとめコンビニに出かけた最中あることを思いついた。「これから放送開始までに、何か面白いことできないかな・・・?」

この時点で夜18時。放送開始の3時間ほど前である。

さて、何ができるだろう。やっぱり、「バルス」に絡めたい。

Androidアプリだろうか。今からできたとして、配布をしても間に合わない・・・

WindowsPhoneアプリ? こっちも時間までに認証が通って、配布に間に合うわけがない。

ならば、WEBアプリケーションだろうか。

たとえば、TwitterのStermaAPIを使って、ひたすら「バルス」のみを流し続けるTLとか。

StreamAPIなら使ったことも、コードもあるからどうにかなるだろうか。だが、どこで動かす?

Ummmmmm


色々と考えて、最終的に「ある程度リアルタイムに、『バルス』を数えられないだろうか」と言う結論に。

GAEを使えば、なんとかできそうだ。よし、そうしよう。

晩飯をいそいでかき込んで設計もそこそこにコーディング。

仕様としては
・10分おきにTwitterAPIにアクセスし、「バルス」で検索

・検索結果件数を、検索結果総数として加算していく。

・加算した結果を、Twitterでつぶやく。

と言う物。

で、結論から言うと、放送までに間に合わなかった。結局Twitterでつぶやく部分で何かが起こっていたらしい。

正しくログを取ればもしかしたら、解決できたかもしれないが、そんな時間もなかった。

自分の力の未熟さも知ったが、同時にパッと思いついて、パッととりかかる面白さも体験できた。いい経験だ。

今回は、GitHubでコードを公開はしない。もう少し手を加えてもっと自由に使えるものにした上で公開をするかもしれない。

以下にコードの一部と、解説を公開する。

 public void doGet(HttpServletRequest req, HttpServletResponse resp)
   throws IOException {
  Barusu barusu;
  Counter count = null;
  // 以前に起動をしたことがあるかどうか
  if ((barusu = DatestoreManager.loadData()) != null) {
   // 起動したこと有り。
   // 検索のクエリに、SinceIDを指定する
   String json = getTweets(barusu.getMinID());
   Result result = JSON.decode(json, Result.class);
   int c = result.getResults().size() + barusu.getCount();
   int minId = result.getMax_id().intValue();
   DatestoreManager.updateData(new Barusu(minId, c));
   count = new Counter(c);
  } else {
   // 起動したことなし。
   // 検索のクエリは、キーワードのみ
   String json = getTweets(0);
   Result result = JSON.decode(json, Result.class);
   int c = result.getResults().size();
   int minId = result.getMax_id().intValue();
   DatestoreManager.saveData(new Barusu(minId, c));
   count = new Counter(c);
  }

  resp.setContentType("text/javascript");
  resp.getWriter().println(JSON.encode(count));

  try {
   tweetCount(count);
  } catch (TwitterException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

GETリクエストを受けて、このメソッドが呼ばれる。

cronを使って、何度も起動をするので、起動履歴をチェックする必要がある。今回は、データストアにデータがあるかどうかで判断を行った。

処理は
1.検索
2.結果(JSON)を保存
3.データストアに保存

そして、JSON形式で出力し、Twitterでつぶやくという物。

JSONの解析にはJSONICを、Twitterでつぶやく部分は、Twitter4jを利用させていただいている。

どうやら、つぶやくための tweetCount で何かが起こっているらしいが、TwitterException をCatchすることができなかった。

今後の展望としては、

UserStreamAPIを利用して、自分のTL上の「バルス」をカウントして、JavaScriptのDOM要素を利用してリアルタイムに更新をするタイプのものを作ってみたい。

しかし、その場合30秒制限のあるGAEでは利用ができないと思う。帯域制御とかを無視してAndroidなんかで実装をするのも面白いかもしれないが。

今後も、こういった「思いついて、すぐやる」を試してみたい。


2011年12月9日金曜日

PreferenceActivity でサマリを動的に変更したい。



現在作成中のアプリでは、PreferenceActivityを利用しています。

設定した値によって、表示されている項目のサマリーが変更するとステキなので、実装をします。



こういう感じで、設定項目の下に設定値を表示したい。
具体的には、項目の内容が変更されたときのリスナーを設定し、コールバックメソッドでサマリーの内容を書き換えます。

リスナーの設定を
onResume()

で行い、解除を

onPause()


で行なっています。


 SharedPreferences.OnSharedPreferenceChangeListener listener; //設定値変更時のリスナーを保存するField
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.preference_activity);
  addPreferencesFromResource(R.xml.party_preference);
  
  //省略
  listener = setOnChangeLitener();
 }
 
 //設定値変更時のリスナークラスの定義
 private SharedPreferences.OnSharedPreferenceChangeListener setOnChangeLitener() {
  return new SharedPreferences.OnSharedPreferenceChangeListener() {

   @Override
   //コールバックメソッド
   public void onSharedPreferenceChanged(
     SharedPreferences sharedPreferences, String key) {
    // TODO Auto-generated method stub
    Log.d(TAG, "value is changed");
    //全てのPreferenceに実行する
    findPreference(key).setSummary(
      sharedPreferences.getString(key, ""));
    //特定のキーの場合のみ、実行する
    if(key.equals(SEARCHBOOKS_KEY)) 
    searchbooksPref.setSummary(
      searchbooksMap.get(sharedPreferences.getString(key, ""))); }    
   }
  };
 }

 @Override
 protected void onPause() {
  // TODO Auto-generated method stub
  super.onPause();
  //登録
  getPreferenceScreen().getSharedPreferences()
    .unregisterOnSharedPreferenceChangeListener(listener);
 }

 @Override
 protected void onResume() {
  // TODO Auto-generated method stub
  super.onResume();
  //消去
  getPreferenceScreen().getSharedPreferences()
    .registerOnSharedPreferenceChangeListener(listener);
 }  

2011年12月4日日曜日

Mixi Scrap Challenge

mixi scrap challenge に参加してきました。

じつは、開発と言うかコーディングをともなう外部のイベントの経験は少ないのでわりとドキドキでしたね。

ザックリとした内容は、主催者側が用意したWEBページ中にある脆弱性を発見し、それを利用した動作を行わせる、と言うもの。

基本的に入力フォームにスクリプトを流しこんで、動作させる形式でした。

中には、Hackerのロマン心をくすぐるような問題も・・・

問題のネタバレはできませんが、レベルがそれなりの物からけっこう高いものまで選り取りみどりでした。

そして、多分私のチームは最下位ではないかと・・・orz

しかし、両隣の方々に助けられてなんとかいくつかの問題をクリアすることができました。

良かった、良かった。

WEBアプリケーションの開発は、研究でそこそこにやりますがセキュリティを考慮したものとはとても言えず・・・

スクリプトを走らせたりは、自宅サーバーでも行なっていますが、こちらもそこまでのものでもなく・・・

とは言え、基本的に「物を作る側」で在り続ける自分が「壊す側」に回ることができたことは非常にいい経験でした。














写真は終了後の懇親会です。同じ大学の方が多かったのが印象的。

今後もこういったイベントがたくさんあると、面白いですね。

とりあえず、様々なかたに進めてもらったこの本を読んで勉強をしようと思います。

在学中に、こういうイベントを主催するのも面白いなぁ・・・


参加者の皆様、お疲れ様でした。