以前、公開したPythonのソースコードが意外に好評だったので、このURLのアルバムのHTMLを出力しているPythonコードをさらします。
少々長いので、続きは以下の「続きを読む」で。Pythonに興味がない人にはおもしろくないので、スキップしてください。
まず、htmlを生成しているので、テンプレートエンジンを使っています。テンプレートエンジンは枯れていてスタンダードの感のあるCheetahです。
あと、simplejsonも使っています。
両方ともeasy_installを使って以下のようにインストールすると簡単です。
%easy_install simplejson %easy_install Cheetah
で、この生成ツールなのですが、以下の構成からなります。sqliteはPython2.5より標準でサポートされるようになりました。これはいい感じなので、がんがん使いましょう。
- flickr.py : Flickrからデータを取得し、sqliteでデータベースに格納。そのデータベースからテンプレートエンジンを使ってhtmlを生成。
- album.tmpl : 上のスクリプトで使うテンプレートの定義。
下のエントリーで記載したような形式のCSVファイルを引数に指定して利用します。
コマンドラインは以下の通りです。
%python flickr.py -d file_name #データベースを生成 %python flickr.py -m file_name #上で作成したデータベースからHTMLを出力
最初の行で、大きなデータベースを作っておいて、2つめに渡すファイルはその中で出力するものを限定することも可能です。
以下がflickr.pyのソースコード。
# -*- coding: utf-8; -*- import sys import urllib import time import simplejson db_name = "flickr.db" __doc__ = """ Usage: #python flickr.py -d file_name : create database from file_name #python flickr.py -m file_name : create html from database #python flickr.py -h : show this page """ def search_photos( text, page=1, photo_list=[] ): args = { 'method' : 'flickr.photos.search', 'api_key' : 'ここに自分のAPI_KEYを記入!', 'per_page': '500', 'sort' : 'date-posted-desc', 'format' : 'json', 'nojsoncallback' : 1, 'text' : text, 'page' : str(page), 'extras' : "date_upload", } url = "http://api.flickr.com/services/rest/?%s"%(urllib.urlencode(args) ) time.sleep(1.0) flickr_photos = simplejson.loads( urllib.urlopen(url).readline() ) photo_list = photo_list + flickr_photos["photos"]["photo"] if flickr_photos["photos"]["pages"] != flickr_photos["photos"]["page"]: return search_photos( text, page+1, photo_list ) else: return photo_list def create_photo_url( photo ): template = "http://farm%s.static.flickr.com/%s/%s_%s.jpg" return template%(photo["farm"], photo["server"], photo["id"], photo["secret"]) def create_small_photo_url( photo ): template = "http://farm%s.static.flickr.com/%s/%s_%s_s.jpg" return template%(photo["farm"], photo["server"], photo["id"], photo["secret"]) def create_page_url( photo ): template = "http://www.flickr.com/photos/%s/%s" return template%(photo["owner"], photo["id"]) def get_query_list( filename ): file_obj = open( filename, 'r') line_list = file_obj.readlines() file_obj.close() query_list = [] for i in line_list: if -1 != i.find(","): query_list.append( [ n.strip() for n in i.split(",") ] ) return query_list def create_html( query_list ): from Cheetah.Template import Template import sqlite3 tmpl = Template(file="album.tmpl") conn = sqlite3.connect( db_name ) all = [] for i in query_list: tmp = {} tmp["name"] = i[1] photo_list = [] cur = conn.cursor() cur.execute(""" select photo_url, small_photo_url, page_url, name from photo_table where name==\"%s\" order by upload_time """%(i[1]) ) for row in cur: photo = {} photo["photo_url"] = row[0].encode("utf-8") photo["small_photo_url"] = row[1].encode("utf-8") photo["page_url"] = row[2].encode("utf-8") photo["name"] = row[3].encode("utf-8") photo_list.append(photo) tmp["photos"] = photo_list all.append(tmp) cur.close() tmpl.all_photos = all return tmpl def create_db( query_list ): import sqlite3 conn = sqlite3.connect( db_name ) try: conn.executescript(""" create table photo_table( integer primary key, photo_url varchar2(512), small_photo_url varchar2(512), page_url varchar2(512), upload_time integer, name varchar2(512) ); """) except sqlite3.OperationalError: print "%s is already exist. if you do not need this file, please remove it."%(db_name) sys.exit( -1 ) cur = conn.cursor() for i in query_list: photo_list = search_photos( i[0] ) for j in photo_list: cur.execute(""" insert into photo_table values( %s, \"%s\", \"%s\", \"%s\", %s, \"%s\" ) """%( hash( create_photo_url( j ) ), create_photo_url( j ), create_small_photo_url( j ), create_page_url( j ), int( j["dateupload"] ), unicode(i[1],'utf-8') ) ) cur.close() cur = conn.cursor() try: cur.execute("select photo_url, name from photo_table order by upload_time") finally: cur.close() conn.commit() conn.close() def main(*argv): from getopt import getopt, GetoptError try: (opts, args) = getopt(argv[1:], 'h:m:d:', ['help', 'html', 'database']) except GetoptError: print __doc__ return -1 for o, a in opts: if o in ('-h', '--help'): print __doc__ return 0 if o in ('-m', '--html'): query_list = get_query_list( a ) print create_html(query_list) return 0 if o in ('-d', '--datebase'): quer_list = get_query_list( a ) create_db(query_list) return 0 if __name__ == '__main__': sys.exit(main(*sys.argv))
以下がテンプレートであるalbum.tmplの中身。
<html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>Flickr Photo Album</title> <link rel="stylesheet" type="text/css" media="screen" href="http://choichoi.sakura.ne.jp/idols/lightbox.css" /> <link rel="stylesheet" type="text/css" media="screen" href="http://choichoi.sakura.ne.jp/idols/album.css" /> <script type="text/javascript" src="http://choichoi.sakura.ne.jp/idols/lightbox.js"></script> </head> <body> #for $i in $all_photos <h2 class="date">$i.name</h2><div class="grid"> #for $j in $i.photos <div class="section fade"> <a href="$j.photo_url" rel="lightbox"> <span class="shadow"> <img width="75" height="75" rel="lightbox" src="$j.small_photo_url" alt="" /></span> <br clear="all"> </a> <a href="$j.page_url"><h3>$j.name</h3></a> </div> #end for </div> <ul class="inline footer"> <li>> <a href="index.html" title="Top">Top</a></li> </ul> #end for </body> </html>
例えば、以下のファイルをogura.txtとして保存して、
Ogura Yuko, 小倉優子
以下のようにindex.htmlを生成した場合、
%python flickr.py -d ogura.txt %python flickr.py -m ogura.txt > index.html
以下のファイルが生成されます。
お楽しみください。