2012-05-27

Blogger ブログ移行用、MovableType 形式のエクスポートデータの日付を変換するツール

最近投稿のタイトルが長くなってきている気がするのだけれど、まあ、表題の通り。


このツールで自動的にしてくれること:
  • 日本標準時(JST)をグリニッジ標準時(GMT)に変換。 (例: 5/5 08:34 → 5/4 23:34)
  • 24 時間制の時刻を 12 時間表記に。 (例: 23:34 → 11:34 PM)
  • 0 時台は 12 時台へ書き換え(Blogger の仕様)。 (例: 0:12 AM → 12:12 AM)

他のブログサービスのブログデータを Blogger へ移行するときに使用する、エクスポートファイル変換ツール MovableType2Blogger へデータを送る前に、こちらで日時変換を行っておくのがいいかと。






ちなみに、けっこうどうでもいいことだけれど、このツールのコードはこちら。
<script type="text/javascript">
<!--
function getGMTDate(s) {
  var d = new Date(s);
  var h = d.getUTCHours();
  var a;
  if (h > 11) {
    a = "PM";
    h -= 12;    
  } else {
    a = "AM";
  }
  if (h == 0) {
    h = 12;
  }
  return getDecimalNumber(d.getUTCMonth() + 1) + "/" + getDecimalNumber(d.getUTCDate()) + "/" + d.getUTCFullYear() + " " + getDecimalNumber(h) + ":" + getDecimalNumber(d.getUTCMinutes()) + ":" + getDecimalNumber(d.getUTCSeconds()) + " " + a;
}
function getDecimalNumber(n) {
  if (n >= 0 && n < 10) {
    return "0" + n;
  } else {
    return "" + n;
  }
}
function changeDate() {
  var raw = document.getElementById("datechangerin").value;
  var rslt = raw.replace(/^DATE: (.*)$/gm, function(a, b) {return "DATE: " + getGMTDate(b);});
  document.getElementById("datechangerout").value = rslt;
}
function selectResult() {
  document.getElementById('datechangerout').select();
}
//-->
</script>
<form action="" onsubmit="changeDate();return false;">
  <textarea id="datechangerin" name="" rows="10" cols="30"></textarea>
  <input type="submit" value="変換" />
  <textarea id="datechangerout" name="" rows="10" cols="30" readonly="readonly"></textarea>
  <input type="button" onclick="selectResult();" value="全選択" />
</form>
何かの参考になれば幸い。

2012-05-26

Google マップでクリックした場所の住所と緯度・経度と郵便番号を表示するプログラム


あと郵便番号までわかったら最高なんですけどね・・・。
という一言に、勝手に触発されて作ってみたのが上のマップ。

Google Maps API から緯度・経度情報を取得して、それを JSONP でグルーブテクノロジーの郵便番号検索 API に送り、返ってきた郵便番号を再び Google Maps API でマップ上に情報を表示する…というのが基本的な処理の流れ。

あとは、オートコンプリートの検索窓を付けたり、マーカー、インフォボックス、メッセージの表示方法を API リファレンスを見ながらちょこちょこ変更。

参考にしたのが、以下のサイト。
で、肝心のコードがこちら。
<input id="searchTextField" type="text" size="50" />
<div id='map' style='width:600px; height:600px;'><br></div>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&libraries=places"></script>
<script type='text/javascript'><!--
var ad = "";
var ll = "";
var map = new google.maps.Map(document.getElementById("map"), {
  zoom: 12,
  center: new google.maps.LatLng(35.689479,139.691778),
  mapTypeId: google.maps.MapTypeId.ROADMAP
});
google.maps.event.addListener(map, 'click', function(mouseEvent) {
  getAddress(mouseEvent.latLng);
});
var input = document.getElementById('searchTextField');
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.bindTo('bounds', map);
var infowindow = new google.maps.InfoWindow();
var marker = new google.maps.Marker({map: map});
google.maps.event.addListener(autocomplete, 'place_changed', function() {
  var place = autocomplete.getPlace();
  if (place.geometry) {
    if (place.geometry.viewport) {
      infowindow.close();
      map.fitBounds(place.geometry.viewport);
    } else {
      map.setCenter(place.geometry.location);
    }
  }
});
function getAddress(latlng) {
  var geocoder = new google.maps.Geocoder();
  geocoder.geocode({
    latLng: latlng
  }, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
      if (results[0].geometry) {
        ad = results[0].formatted_address.replace(/^日本, /, '');
        var ad2;
        if (ad.match(/^([^0-9]+)/)) {
          ad2 = RegExp.$1;  
        }
        ll = latlng;
        var s = document.createElement("script");
        s.charset = "utf-8";
        s.src = 'http://api.postalcode.jp/v1/zipsearch?word=' + encodeURIComponent(ad2) + '&callback=showPostalCode';
s.charset = 'utf-8';
        document.body.appendChild(s);
      }
    } else {
      alert(status);
    }
  });
}
function showPostalCode(data) {
  var l = ll.toUrlValue();
  var p = formatCode(data.zipcode.a1.zipcode);
  marker.setPosition(ll);
  infowindow.setContent(((p)? "<span style=\"color:red;\">" + p + "</span><br />": "") + ad + "<br />" + "<a style=\"color:green;\" href=\"https://maps.google.co.jp/maps?q=" + l + "\" target=\"_blank\">" + l + "</a>");
  infowindow.open(map, marker);
}
function formatCode(c) {
  return (c.match(/(\d{3})(\d{4})/))? "〒" + RegExp.$1 + "-" + RegExp.$2: "";
}
//-->
</script>
とりあえず、Firefox と Chrome では動作を確認。IE は知らない。

Google Maps API、初めて触ってみたものの、なかなか手軽で面白い。地図を使ったウェブアプリ、何かアイデアが浮かんだら作ってみてもいいかも…。

2012-05-20

PC 用外付けテレビチューナー GV-MVP/XZ2 購入


I-O DATA 地上・BS・110度CSデジタル対応TVキャプチャーBOX USBモデル GV-MVP/XZ2

パソコンでテレビの視聴や録画ができるといいなーと思い立ち、購入。決め手は MPEG4-AVC/H.264 のハードウェアトランスコードが内蔵されている点。

ソフトウェアに少々難ありという口コミがあったので、添付の CD(ver 5.07)ではなく、I-O DATA サイトから mAgicTV GT(ver 5.09)を取得。

「番組表データの更新に失敗しました。」と何度かエラーが出ることがあったものの(mAgic ガイド GT メニュー「ファイル > 番組データベースの初期化」で復旧)、そのほかはおおむね安定している感じ。

まあ、安かったし、まずまずの買い物だったかと。

参考:

2012-05-06

Blogger のガジェット更新用 API と「クリボウ式 Blogger カレンダー」の話

ずっと以前(もう 5 年以上前 !?)に公開していたカレンダーガジェット がいつの間にか動かなくなっていたので、修正。

試験的にこのブログのサイドバーにも追加してみたので、いろいろ触ってみるといいかと。

どの日付に投稿が存在するかのデータをフィード(JSON)で取ってきて、カレンダー上にリンク表示するというところまでは問題なかったのだけれど、投稿があるとされる日付リンクをクリックしてもその投稿を表示できなくなっていた。

このガジェットの投稿の表示の仕方は、画面遷移なしにブログの投稿エリアのデータだけを動的に差し替えるというもの。Blogger 自体の、ガジェットを編集したときなんかに、リフレッシュなしにその変更が反映される仕組みをそのまま利用している。


Blogger のガジェット更新用 API

たとえば、このブログのカレンダーで 2012-04-30 の日付クリックすると、呼び出すようになっているのが次の URL。

http://kuribo-programming.blogspot.com/?action=nextposts&widgetId=Blog1&widgetType=Blog&responseType=js&path=http%3a%2f%2fkuribo%2dprogramming%2eblogspot%2ecom%2fsearch%3fupdated%2dmin%3d2012%2d04%2d30T00%253A00%253A00%252B09%253A00%26updated%2dmax%3d2012%2d04%2d30T23%253A59%253A59%252B09%253A00%26max%2dresults%3d500

説明のために、青字部分を URL デコードすると、こう。

http://kuribo-programming.blogspot.com/search?updated-min=2012-04-30T00%3A00%3A00%2B09%3A00&updated-max=2012-04-30T23%3A59%3A59%2B09%3A00&max-results=500

アクセスしてみると分かるけれども、2012-04-30 の 00:00 から 23:59 に投稿されたデータを最大 500 件取ってきて表示するという、Blogger ブログの検索ページの URL をそのまま渡している。

あとは赤字部分のパラメータ指定で、取得した投稿データを Blog1 という ID のウィジェット(投稿ウィジェット)に表示するための JavaScript コードが得られる。

実際にアクセスすると、返ってくるコードはこんな感じ。赤字部分に実際の投稿データが入る。

try {
_WidgetManager._HandleControllerResult('Blog1', 'nextposts',{'renderedData': '...'});
} catch (e) {
  if (typeof log != 'undefined') {
    log('HandleControllerResult failed: ' + e);
  }
}


変更点

カレンダーガジェットに話を戻すと…。

ここまで説明してきた Blogger のガジェット(ウィジェット)更新用 API は、これまでと変わらず正確に動くのだけれど、問題はその呼び出し方。カレンダーでは、POST メソッドでパラメータを送っていたのだけれど、いつの間にか

405 Method Not Allowed

になっていたみたい。しょうがないので、日付クリック時には JSONP 的に script タグをドキュメント末尾に追加するようにして、その src に最初の URL を指定することにした。

「動かないし!」とカレンダーに見切りをつけた人も、もう一度ブログにつけてもらえると嬉しかったり…。ガジェット追加は、最初に掲示したリンク先から。


自分の備忘録として記事にしてみたけれども、Blogger ブログの一部分のコンテンツを動的に変えたいプログラマな人は、参考にしてもらえるといいかと。

2012-05-04

Windows 7 でフォルダ表示したときに Explorer 読み込み中のプログレスバーが止まらない件

Explorer プログレスバー

表題の件について、やってみて効果があったこと。 フォルダ右クリック「プロパティ」から「カスタマイズ > フォルダの種類」を「ドキュメント」に。

フォルダ内のファイル表示形式を「詳細」にしている場合は、「名前」「更新日時」「種類」「サイズ」以外の、「長さ」などの情報表示をなくすだけでも随分改善される印象。

「詳細」表示で「日付時刻」を表示している場合には、「更新日時」を追加して、「日付時刻」をはずすのも有効だとか…。