要するに何をやりたかったかと言うと、↓こういう事です。
- パソコンで溜めたブックマークを、iPod touch(iPhoneじゃない所に哀愁を感じて!)でカウチポテトしながら見たい。
- ブックマーク同期として Xmarks を使ってみたが、一々ログインしなければならないし、階層を降りるのに時間が掛かるし、オフラインの時にリストも見られない(iPod touchの悲しさ)、後 ブックマークが昇順になっていないのも気に喰わない。
- 幾つかの非標準Web browserは、Webの保存機能を持っているようだから、自分でブックマークリストなHTMLを作って、それを保存して使いこなせば良いんじゃね?
- 更に調べていたら、HTML5のオフラインアプリケーション機能(mobile Safariに実装済み)を使えば、HTMLをキャッシュしておいてオフラインでも使えるらしい。
- 早速、PythonでブックマークをHTML化して、オフラインでもリストが見られるように、ローカルWebアプリ化してみたよ。<今ココ
資料
今回、色々回り道を繰り返していましたが、参考にしたURLです。
- HTML5で、オフラインでも使えるiPod/iPhone超簡単アプリっぽいものを作ってみた − Publickey
http://www.publickey1.jp/blog/11/html5ipodiphone.html
@ITのこの記事で、「ローカルWebアプリ」が紹介されていたのですが、上の記事を読むまで 自分のやろうとしている事に転用できると、全然気づきませんでした。
(だって、その後のページで、ネイティブアプリの作成の話に行ってるんだもん)
次、ローカルWebアプリ化に際して、iPhone/iPod touchのユーザーインタフェースをWebで再現する為のライブラリ検討として、以下を参考にしました。
- iPhone用サイト制作の為のフレームワークを分類してみた » TECH Matari
http://tech.ironhearts.com/blog/archives/464
幾つかライブラリをダウンロードして、添付されていたデモを iPod touchで見て、今回は jQTouch にしました。
採用理由は、以下のものです。
- 特にライブラリ本体を弄らなくても、iPhone/iPod touchのユーザーインタフェースになる。
- 今回は階層を掘っていくイメージの為、1ファイルを複数ページに見せかける jQTouch が 動作が軽くなりそうだし、簡易だと思った。
- サンプルコードが、結構判り易かった。
ソースコード
試行錯誤したままですが、ソースです。
整理もしていないので、かなり汚いです。すんません。
(しかも、デモコードから切り貼りをしていたりします)
#!/bin/env python # -*- encoding: cp932 -*- """ IEの「お気に入り」を、iPhone/iPod touch向けのHTMLに変換する。 HTML化のベースは、jQTouch を使っている。 """ import sys import os import csv import pdb import codecs import ConfigParser import time def html_before(title): return """ <!doctype html> <html manifest="fav.manifest"> <head> <meta charset="UTF-8" /> <title>%s</title> <style type="text/css" media="screen">@import "./jqtouch.min.css";</style> <style type="text/css" media="screen">@import "./theme.min.css";</style> <script src="./jquery.1.3.2.min.js" type="text/javascript" charset="utf-8"></script> <script src="./jqtouch.min.js" type="application/x-javascript" charset="utf-8"></script> <script src="./jqt.autotitles.js" type="application/x-javascript" charset="utf-8"></script> <script type="text/javascript" charset="utf-8"> var jQT = new $.jQTouch({ icon: 'jqtouch.png', addGlossToIcon: false, startupScreen: 'jqt_startup.png', statusBar: 'black', preloadImages: [ './img/back_button.png', './img/back_button_clicked.png', './img/button_clicked.png', './img/grayButton.png', './img/whiteButton.png', './img/loading.gif' ] }); </script> </head> <body>""" % title def html_after(): return """ </body> </html>""" def str_normal(s): if s.isalnum() == True: return s.replace(".", "_") else: ss = "" for c in s: ss += "%d" % ord(c) #print ss return ss def get_ini_url(fpath): #print "ini file:%s" % fpath cfg = ConfigParser.ConfigParser() try: cfg.readfp(open(fpath)) return cfg.get('InternetShortcut', 'URL') except: return "#" def make_node(is_top, root, dirs, files): title = os.path.basename(root) back_node = "" if is_top == False: back_node = '<a href="#" class="back">back</a>' node = "" for s in dirs: node += "<li class='arrow'><a href='#%s'>%s</a><small class='counter'>%d</small></li>" % (str_normal(s), s, len(os.listdir(os.path.join(root, s)))) node += "\n" for s in files: node += "<li class='forward'><a href='%s' target='_blank'>%s</a></li>" % (get_ini_url(os.path.join(root, s)), s.replace('.url', '')) html = """ <div id='%s'> <div class='toolbar'> %s <h1>%s</h1> </div> <ul class='rounded'> %s </ul> </div>""" % (str_normal(title), back_node, title, node) return html def make_manifest(dir): print >>f, "CACHE MANIFEST\n# %s\n" % time.asctime() print >>f, "CACHE:" for root, dirs, files in os.walk(dir): for s in files: ext = os.path.splitext(s)[1] if (ext == ".css") or (ext == ".js") or (ext == ".png") or (ext == ".gif"): fpath = os.path.join(root, s) print >>f, fpath.replace(dir, "").strip("\\").replace("\\", "/") def main(f): fav_dir = r"C:\Documents and Settings\あなたの名前\Favorites" is_top = True html_body = "" for root, dirs, files in os.walk(fav_dir): #print root, dirs, files print ">", root html_body += make_node(is_top, root, dirs, files) is_top = False print >>f, html_body if __name__ == "__main__": save_dir = r"C:\配置したいフォルダパスを指定する" # 「お気に入り」から、HTMLページを生成(use jQtouch) save_path = os.path.join(save_dir, "_test.html") f = file(save_path, "w") print >>f, html_before("Favoraites List") main(f) print >>f, html_after() f.close() # fav.manifestを生成 save_man = os.path.join(save_dir, "fav.manifest") f = file(save_man, "w") make_manifest(save_dir) f.close() # cp932からutf-8に変換 save_path2 = os.path.join(save_dir, "index.html") f_i = file(save_path, "r") f_o = file(save_path2, "w") f_o.write(unicode(f_i.read(), "cp932").encode('utf-8')) f_i.close() f_o.close()
コードの流れとしては、大体以下の様です。
- お気に入りフォルダを os.walk で再起探索し、HTMLリスト化しています。
サブフォルダ毎を1ページとして ulタグでくくり、後は .url ファイルの URLキー値を、liタグ内の aタグでジャンプ先になるようにしています。
(jQTouchは、divタグでページを作り出している) - ローカルWeb化する為に、jQTouch提供のライブラリ群を、fav.manifest ファイルで ローカルキャッシュ対象にしています。
fav.manifestファイルは、htmlタグのmanifest属性キーでファイル指定できます。 - 1.でHTML化したファイルは、cp932(shift_jis)なので、utf-8に保存し直しています。
(最初からutf-8でファイルを作ろうと思ったのですが、encodeメソッドを使うのが面倒になったので、後から変えてしまえ。と思った次第)
動かし方
1.パソコン内に、ローカルなWWWサーバーが走っている環境を構築します。
自分の環境は Apache ですが、最近なら WebMatrix でも良いかも知れません。
2.仮に、Apacheを動かしていたら、httpd.confに以下の行を追加します。
AddType text/cache-manifest .manifest
3.次に、ブックマークをHTML化したファイルを保存したいフォルダを決めます。
仮に、「c:\html\test」フォルダに配置すると仮定します。
上のソースの「save_dir」変数の値を、「c:\html\test」に設定してください。
4.jQTouchのライブラリをダウンロード(私のは、jqtouch-1.0-beta-2-r109.zip でした)して展開します。
で、jqtouchフォルダとthemes/jqtフォルダのファイルを、「c:\html\test」フォルダに ぶち込みます。
5.上のソースを Python で実行します。
すると、「c:\html\test」フォルダに、「index.html」ファイルが出来上がります。
(ChromeとかSafariなどのWebKit系ブラウザで、簡単な確認が出来ます)
6.作成したページのURLを、iPod touchから参照します。
例えば、↓こんな感じの画面になります。
fav_test posted by (C)wacky
7.ローカルWeb化しているので、機内モード:ONにしてアクセスしても、「ページを開けません」と出ずに、ページが開きます。やったぁ。
(但し、ブックマークリスト先のURLを開こうとすると、当然ですが「ページが開けません」となります)
最後に
ローカルWebアプリって、結構簡単に作れるもんですね。
(.manifestファイルで、キャッシュ対象を指示すれば良いだけなんですもん)
Mac使いじゃない私には、iPhone/iPod touchなアプリは、永遠に作る事が出来ないのか。と半分諦めモードでしたが、少し元気が出てきました。
これなら、自分のPCのローカルWWWサーバーで、ちまちまWebアプリを作って、それをローカルWebアプリ化すれば良いのですから、かなり敷居が低くなった気がしてきました。
(しかも、ローカルWebアプリ化すれば、Wi-Fiの使えない所でも使えるし)