FlaskとXDMつかってgooglemapとtwitterを連動させるサンプル

HTML5 APIガイドブック コミュニケーション系API編が面白い。ひと通り読んだので、コード書いてみてる。

2章のサンプルコードをFlaskで。サンプルコードは3つのHTMLファイルが必要だけどFlask使えば一つのファイルに全部押し込めるので管理が楽。

gmap2twitter

初期値は富士市役所のあたりから半径5キロ以内のtweetを探すようにした。で地図をドラッグすると、それに伴いtweetも連動して表示されるので、ほーこんなユーザーいるのか!と新たな発見もあった。

この本は入門書として最適かもしれん。

ProductName 徹底解説 HTML5 APIガイドブック コミュニケーション系API編
小松 健作
秀和システム / 2730円 ( 2010-12 )


Flaskコード

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

from flask import Flask

app = Flask(__name__)

@app.route("/")
def processing():
    response = """
<!doctype html>
<html lnag=ja>
<head>
<meta charset="utf-8">
<style type="text/css">
.page { margin: 0px auto; border: 0px; padding: 0px; text-align: center;}
</style>
</head>
<body>
<div class=page>
<h1>gmap2tweet</h1>
<iframe src="/googlemap" id=gmap width="500px" height="500px"></iframe>
<iframe src="/twitter" id=twitter width="500px" height="500px"></iframe>
<div id=mesg></div>
</div>
<script>
  var initialize = function(){
    var origin = location.protocol + "//" + location.host;
    var iframes = document.querySelectorAll('iframe');

    for(var i = 0; i < iframes.length; i++){
      iframes[i].contentWindow.postMessage('init', origin);
    }

    window.addEventListener('message', function(e){
        if (e.origin == origin) {
          document.getElementById('mesg').innerHTML = "receive data via xdm::" + e.data;
          document.getElementById('twitter').contentWindow.postMessage(e.data, origin);
        }
    }, false);
  }
  window.onload = function(){ initialize(); }
</script>
</body>
</html>
"""
    return response

@app.route("/twitter")
def twitter_processing():
    response = """
<!doctype html>
<html lang=ja>
<head>
<meta charset="utf-8">
</head>
<body>
<div id=mesg></div>
<div id=results></div>
<script>
var origin = location.protocol+"//"+location.host;
var parentWin = null;
var api="http://search.twitter.com/search.json?callback=show&rpp=50&geocode=";
var jsonpObj =null;

var sendJsonp = function(latlng, radius){
  if(jsonpObj)
    document.body.removeChild(jsonpObj);
  var scr = document.createElement('script');
  scr.src = api+encodeURIComponent(latlng+","+radius+"km");
  scr.type = "text/javascript";
  jsonpObj = document.body.appendChild(scr);
};

var show = function(obj){
  var results = obj.results;
  var out = '';
  var template = '<img src="#{img}"> <a href="http://twitter.com/\
#{from_user}" target="_blank"><b>#{from_user}</b></a> #{text}<br />\
#{created_at}<hr />';

  for(var i = 0; i < results.length; i++){
    var res = results[i];
    var tmp = template.replace("#{img}", res.profile_image_url) \
.replace("#{from_user}", res.from_user) \
.replace("#{from_user}", res.from_user);
    tmp = tmp.replace("#{text}", res.text) \
.replace("#{created_at}", res.created_at);
    out += tmp;
  }

  document.getElementById('results').innerHTML = out;
};

window.addEventListener('message', function(e){
  if(e.origin == origin) {
    if (e.data == 'init') {
      parentWin = e.source;
    } else {
      document.getElementById('mesg').innerHTML = e.data;
      document.getElementById('results').innerHTML = "読み込み中";
      sendJsonp(e.data, 5);
    }
  }
}, false);
</script>
</body>
</html>
"""
    return response

@app.route("/googlemap")
def google_processing():
    response = """
<!doctype html>
<html lang=ja>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
</head>
<body style="padding:0;margin:0;height:500px">
<div id=map_canvas style="width: 100%; height: 100%; border: 0px"></div>

<script>
var parentWin = null;
var origin = location.protocol + "//" + location.host;

var start = function() {
  var latlng = new google.maps.LatLng(35.164190, 138.678609);
  var myOptions = {zoom: 13, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP};

  var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

  var getCenter = function(){
    var center = map.getCenter();
    var lat = center.lat(); 
    var lng = center.lng();
    if(parentWin) {
      parentWin.postMessage(lat+","+lng, origin);
    }
  };

  window.addEventListener('message', function(e){
    if(e.origin == origin) {
      if(e.data == 'init') {
        parentWin = e.source;
        getCenter();
      }
    } else {
      alert("illegal message from " + e.origin);
    }
  }, false);

  google.maps.event.addListener(map, 'dragend', function(e){getCenter();});
  google.maps.event.addListener(map, 'zoom_changed', function(e){getCenter();});

};

window.onload = function(){start();};
</script>
</body>
</html>
"""
    return response

if __name__ == "__main__":
    app.run()

iPadの自動リチャージを停止した

iPadの利用率は高くて、ほぼ毎日誰かが使っているし実家に帰省した際にも重宝したんだけど、3Gほとんど使わないのでリチャージを停止した。

1294465724

100Mプランチャージしたけど600Kくらいしか使ってないし。

それにしても、リチャージ停止ボタンが見つからなくて難儀した。もしや隠し機能?と思ってしまうな、あれは。

構成

e-mobileのEMチャージとアウトレットのD02HWモバイルルーターくっつけて使っている。ちなみにモバイルルーターはiPadを導入したので急遽購入した。

もし今から考えるんだったらこれにiPadのプリペイドのやつを組み合わせる気がするかもなぁ。

KKD(勘・経験・度胸)

KKDは特に否定しないし、それなりに重要だと思っている。ただ、職場内で共有できない情報とかスキルであるという点は問題だと思っているけど。

よくよく考えてみるに、KKDはアブダクションと密接に関連するのかな?またはセレンディピティ的な嗅覚みたいなものを表す言葉なんだろうなぁと漠然と思っている。そういう意味でイノベーション的には非常に重要なフォースとして働くなにかなんだろうと。

ただそういう能力は、深い洞察力とか論理的な思考力を背景としたものであり、宝くじに当たるかもという期待感をKKDとか言ってしまうのとは違うんじゃないかなぁと思うのであった。

ProductName アブダクション―仮説と発見の論理
米盛 裕二
勁草書房 / 2940円 ( 2007-09-20 )


javascriptの対話環境を入れた

昔、jsっていう対話環境入れてた気がするんだけど、覚えてないのでv8のやつをおもむろに入れてみたという話。

sconsを入れるために

sudo port install scons

って打ったら、opensslは入れるわ、pythonのバージョン上げるわでやたら時間がかかった。

scons入れたら

svn checkout http://v8.googlecode.com/svn/trunk/ v8
cd v8
scons
scons sample=shell

で対話環境が手に入る。

$ ./shell
V8 version 3.0.6.1
> (function (x,y){return x+y})(3,4)
7

ついでにnode.jsも入れた

wget http://nodejs.org/dist/node-v0.2.6.tar.gz
tar xvfz node-v0.2.6.tar.gz
cd node-v0.2.6
./configure
make
sudo make install

ProductName 徹底解説 HTML5 APIガイドブック コミュニケーション系API編
小松 健作
秀和システム / 2730円 ( 2010-12 )


SANYO NEW eneloop

娘や息子の玩具の電池が結構頻繁に切れて、予備の電池がおいてなかったりすると子どもが不機嫌になって困るし、そのたびに買いに行くのも面倒だ。

で、最近使ってないwiiのコントローラーから抜いてみたり、使ってないリモコンから抜いてみたりするんだけど、中途半端に使用済みなのでこれまたすぐ切れて負のスパイラル。どんどんゴミの乾電池が溜まっていくのも気分のいいものではない。

去年のクリスマスに、サンタが息子に新幹線のプラレールを届けてくれた際にエネループに移行してみたらこれが便利。電池が切れたら、満タンの電池と交換して、切れた電池は充電器に突っ込んでおけばすぐまた使えるようになるしね。

ProductName プラレール N700系新幹線ベーシックセット

タカラトミー / 1997円 ( 2007-06-30 )


今朝起きたらリビングの時計が止まっていたので、eneloopと交換しつつ12個パックを注文してしまった。

eneloopistになったことを実感した朝であった。

twitterと距離感のこと

「マキコミの技術」を読んだ感想を書いたわけだが、フワフワした感は残ると書いたように、わかったようなわからないようななんとも言えない感覚というか、結局咀嚼出来てないなぁと思っていた。(他のブログのエントリみてもさらに膨らますような内容ほとんど見かけないし、そういう内容なんだろう)

というわけなので、ピンと来た部分だけリストにして記録しておいたら、ある部分が切り取られていたので、この部分はもうちょい深く考えておく必要があるのかなぁと思った。

例えば普段車通勤している(車で往復二時間)と突発オフみたいなのは出たくても出られないので歯がゆい思いをするし、フットワークが重いなぁと思うこともある。オフに出れば出たで、弱い紐帯の強さ的な緩いけど割としっかりした関係性が築けて楽しい。それは田舎ゆえの密度の薄さ故に、とりあえず集まってみるというのが意味を持つのでないのだろうか?

実際、Shizu-devみたいな勉強会は静岡全域(静岡には新幹線駅が6もある)からヒトが集まり密度の割に凝集度が高いしなぁ

というわけで、twitterによる距離感の変化っていうのは「手の届く距離」っていうかユーザーの密度とかと関係があって、グローバルに広がる一方、ローカルなクラスター化を促進する働きも持っているのかなぁと思った。

ProductName マキコミの技術
コグレマサト
インプレスジャパン / 1575円 ( 2010-12-17 )


Drum & Bass ArenaのXmas Specialが良すぎる

懐かしきダークコア、アートコア時代のダークなチューン満載でやばすぎ。これは聴いとくべきな曲ばかり。

D&BA : The Risky Presents... From The Vaults Xmas Special – A Touch Of Darkness! (#163)

'97あたりのレコードは結構持っているんだけど取り込んでmp3にしていない。そのうち取り込みしなきゃと思っているんだけど、めんどくさい。

ProductName Timeless
Goldie
London Import / 1284円 ( 2000-04-10 )


来月からJavaScript: The Good Partsを読んでいきます

去年はHaskellの本を読んできたけど、この関数型プログラミングの技法はPythonでもPerlでもJavasriptでも役に立つことが多い。

しかも、静岡といえばλと言われるように、我々はラムダ式をより分かりやすい形でまちおこしに活用していかなければならないわけです(静岡県民として)。

というわけで(?!)、来月から半年くらいかけてJGPを読んでいきます。初回はあっさりした章が続くので3章くらい読み進める予定。それでも時間が余ると思うので、LT用のネタなど仕込んでくるといいと思います。

なお、本書は関数型プログラミングを薦める本ではなくて、良いjavascriptプログラミングをしましょうっていう本です。

第1回JavaScript読書会

  • 日 時 : 2011年2月12日(土) 13:00~17:30
  • 場 所 :富士市民活動センター・コミュニティF ( http://com-f.net/index.html )
  • 地 図 : http://com-f.net/access.html
  • 定 員 : 15名
  • 費 用 : 1,000円 (学生・未成年無料)
  • 持ち物 : パソコン、課題図書
  • 課題図書: JavaScript: The Good Parts (ISBN-10: 4873113911)
  • 環境  : JavaScriptのコーディング用エディタ及び動作確認用webブラウザ

ProductName JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス
Douglas Crockford
オライリージャパン / 1890円 ( 2008-12-22 )


参考

GraphvizでSyntax diagramを描こうとしたけどうまくいかなかった

JGPのsyntax diagramみたいなのをGraphvizで描きたくて色々頑張ってみたんだけど、僕には無理だった。

railroad diagram

graph Heawood {
      node [label="\N", fontname=Arial, width="0.50000", height="0.500000", color=black];
      edge [color=black];
      graph [rankdir = LR];

      subgraph cluster1 {
               color=none

               Start [style=invis];
               L1 [style=invis, width=0.0, shape=point];
               Alpha [shape=box, label="アルファベット"];
               L2 [style=invis, width=0.0, shape=point];
           End [style=invis];

           Start -- L1 [arrowtail=teetee];
               L1    -- Alpha;
               Alpha -- L2;
               L2    -- End [arrowhead=teetee];

      }

      Digit [shape=box, label="   数字   "];
      Hif [shape=circle, label="-"];

      L1    -- Digit [tailport=w,headport=w];
      L1    -- Hif [tailport=w,headport=w];
      Digit -- L2 [tailport=e,headport=w];
      Hif   -- L2 [tailport=e,headport=w];
}

ProductName JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス
Douglas Crockford
オライリージャパン / 1890円 ( 2008-12-22 )


参考

USTREAMのソーシャルストリームにハッシュタグを入れる

夜U隊長が高校の同窓会にでかけていった。

で、新年の抱負にTyphoonいじりをあげてあったので早速いじっていたという。

あとUstreamの右側の使い方がわからなかったので、ハッシュタグの設定しておいた(番組設定->その他の設定)

今年一年もアーメンとダークコア感を大切にしていきたい

ProductName Rave Digger
DANNY BYRD
HOSPITAL / ?円 ( 2010-10-15 )


それにしてもAmen Alley最高だ。