PDF を R2L (右綴じ) にする方法

最近自炊をしているのですがマンガは大体右綴じになっています。
なのですが、ScanSnap のソフトで PDF にすると左綴じになってしまいます。
おそらく PDF の仕様で、指定がないと左綴じがデフォルトということだと思ってます。

このままだと PDF 対応のアプリを使っても逆にスクロールしてしまいます。
なので右綴じに変更する方法を調べてみました。

調べる前はコマンドでもあるのだろうと思っていたのですが、なかなか手軽そうなものがありませんでした。
色々調べた中である程度取っ付きやすそうな Python にしました。

Python の pdfrw

https://github.com/pmaupin/pdfrw

基本的には
https://hanepjiv.blogspot.jp/2014/11/pdfpython.html
こちらの方が作成されているものを使ったのですが、ScanSnap からの PDF だと、うまく動作しなかったので、pdfr2l 関数をちょっと調整しました。

def pdfr2l(a_src, a_dest):
    """
    pdfr2l
    """
    # --------------------------------------------------------------------------
    src = PdfReader(a_src)
    dest = PdfWriter()

    # dest.addpages(src.pages)

    dest.trailer = src

    # print dest.trailer.Root

    if dest.trailer.Root.ViewerPreferences:
        dest.trailer.Root.ViewerPreferences = PdfDict(Direction=PdfName.R2L)
    else:
        dest.trailer.Root.ViewerPreferences = PdfDict()
        dest.trailer.Root.ViewerPreferences.Direction = PdfName.R2L

    dest.trailer.Root.PageLayout = PdfName.TwoColumnRight

    dest.write(a_dest)

具体的には
dest.addpages(src.pages)
をコメントアウト。
dest.trailer.Root.ViewerPreferences = PdfDict()
を追加しました。

本家が bitbucket なのですが普段から GitHub の方しか使っていないので GitHub の方へ調整した版をあげました。
https://github.com/INORIA/pdf-r2l-script

その他の方法

Adobe Acrobat

有料ですが一番安心のソフトです。ただし、一冊一冊対応しないといけないので増えてくると大変です。
プログラムを書くのが面倒、または書けないという方はこちらを使うことになります。

Perl の PDF::API2 モジュール

http://toga.vegalta.org/wordpress/2016/05/15/830

PHP の TCPDF

http://tohokuaiki.hateblo.jp/entry/set-binding-direction-with-tcpdf
https://github.com/tecnickcom/tcpdf

Java の iText

http://d.hatena.ne.jp/kiwanami/20101215/1292400269

所感

なかなか面倒です。普通にバイナリ一発でできるコマンドとか提供してくれていると楽なのですが∧( ‘Θ’ )∧

参考

http://www.adobe.com/devnet/pdf.html

http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf

[GAE] 初期状態を触ってみる – ハンドラ追加

前回、初期状態のGAEアプリケーションを眺めてみました。今回は、初期状態に手を加えて見ようと思います。

初期状態では、http://[domain]/ へのアクセス、つまりルートへのアクセス時のみ Hello world! を表示するようになっていました。
今回は、http://[domain]/ja へアクセスしたら “こんにちは!” と表示するようにハンドラを追加してみます。

初期状態で MainHandler というクラスがあるので、その中身全てまるまるその下にコピーします。そしてクラス名を MainJAHandler に変更します。

class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write('Hello world!')


class MainJSHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write('Hello world!')

これでハンドラの追加が出来ました。しかしこれでは、 Hello world! と出力されますので、 'Hello world!' の部分を u'こんにちは!' に変更します。これだけで “こんにちは!” と出力するハンドラが完成しました。

次に、ソースコードに日本語(マルチバイト)が追加されたので、文字コーディングを指定してあげないといけません。

# coding: utf-8

上記の一行を main.py の2行目付近に追加してください。

最後にルーティングを追加します。現状のままでは、 “/” (ルート)へアクセスが合った場合 MainHandler に処理が送られるようにしかなっていません。なのでそこに “/ja” へアクセスがあった場合、MainJAHandler を使用するように指定してあげます。
webapp2 の WSGIApplication へ新たなルーティングを追加します。

('/', MainHandler)の次に , ('/ja', MainJAHandler) を追加します。

これで、全ての作業が終了です。出来上がったコードは以下になります。

#!/usr/bin/env python
# coding: utf-8

import webapp2


class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write('Hello world!')


class MainJAHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write(u'こんにちは!')


app = webapp2.WSGIApplication([
    ('/', MainHandler), ('/ja', MainJAHandler)
], debug=True)

あとは、Google App Engine Launcher で起動して / と /ja にアクセスしてそれぞれ Hello world! , こんにちは! と表示されていると完成です。

[GAE] 初期状態を眺めてみる

前回作成した、Google App Engine Launcher の初期状態のアプリケーションを眺めて理解しようと思います。

前回作成した状態で Parent Directory で指定したフォルダにあるファイルは以下の4つになります。

アプリケーションを Run するとmain.pyc も作成されていると思いますが、これは main.py から自動で作成されたファイルですので今回は関係ありません。

app.yaml

GAE を利用する際に必ず必要なアプリケーションの設定ファイルです。
中身は次の用になっています。

application: python-basic-wsgi
version: 1
runtime: python27
api_version: 1
threadsafe: yes

handlers:
- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico

- url: .*
  script: main.app

libraries:
- name: webapp2
  version: "2.5.2"
application
アプリケーション固有の識別子です。名前と言ってもいいと思います。
version
アプリケーションのバージョン番号です。
runtime
動作する言語を指定します。python だけだと古いバージョンの Python の環境で動作するので 2.7 を使用するには python27 と指定しなければなりません。
api_version
使用する API のバージョンです。現状は 1 で問題ないようです。
threadsafe
yes で同時リクエストを利用するようになります。
handlers
リクエストされたURLをどのように処理するのかを設定します。

url
リクエストされた url がマッチする場合それ以下の指定に従って処理されます。正規表現を使用します。

static_files
urlにマッチしたものを指定した静的ファイルへのアクセスとして処理します。正規表現を使用します。
upload
Googleのサーバーにアップロードするファイルを指定します。参考
libraries
使用するライブラリを指定します。サードーパーティのライブラリを使用する際にも指定します。

初期設定で設定されている動作は、
http://…/favicon.ico というリクエストがあった場合は /favicon.ico というファイルを参照してください。
アップロードするファイルは favicon.ico です。

それ以外の全てのアクセスは main.app スクリプトを使用して処理してください。(main.app は main.py の app 変数を利用してくださいという意味です。)

という感じになります。

favicon.ico

favicon.ico はアイコンのページのアイコンのようなもので、Chrome だとタブの左に表示されている小さな画像になります。

index.yaml

アプリケーションで利用するデータストアのクエリ使用するインデックスが記述されるファイルです。単純なクエリ用には自動で生成されるので、今はなにも記述する必要はありません。
参考

main.py

これが Hello world! と出力するだけの WSGI アプリケーションのコードが記述されている python スクリプトになります。

import webapp2

class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write('Hello world!')

app = webapp2.WSGIApplication([
    ('/', MainHandler)
], debug=True)

MainHandler というリクエストを扱うクラスを定義します。
それを ‘/’ というリクエストの際に使用するという設定の webapp2 の WSGI アプリケーションを app という変数に代入しています。

app という変数に代入しただけで動作しているのは、app.yaml

- url: .*
  script: main.app

と指定しているためです。main.app は main.py の app 変数を利用することになります。

メニュー

[GAE] 初めてのWSGIアプリケーション

参考

http://d.hatena.ne.jp/matsuza/20080413/1208092235
https://developers.google.com/appengine/docs/python/config/appconfig

[GAE] アプリケーションの新規作成 – 基本のWSGIアプリケーション

GAEを利用して WSGI アプリケーションを作成するには、GAE用のフレームワーク webapp2 を使用します。

まず GAE 用に作成したアプリケーションを Google のサーバーに Deploy するために、Google App Engin SDK For Python をダウンロード、インストールします。
https://developers.google.com/appengine/downloads#Google_App_Engine_SDK_for_Python

Google App Engine Launcher というソフトがインストールされるので、これを使用していきます。

アプリケーションの新規作成

アプリケーションを新規作成するには、Google App Engine Launcher を起動して、File -> Create New Application … を選択します。
Application Name に任意の名前を入力します。ここでは python-basic-wsgi とします。
Parent Directory にソースを置きたい場所を選択して Create を押します。これでアプリケーションの新規作成は完了しました。

GAE に追加されたアプリケーションを選択した Run ボタンを押してアプリケーションを起動させます。
gae-create-a-new-wsgi-app1
無事起動ができて Stop ボタンが押せるようになったら、 Browse ボタンを押して実際に Web ブラウザで確認します。
gae-create-a-new-wsgi-app2
Hello world! と出力されると無事アプリケーションを作成することができました。
gae-create-a-new-wsgi-app3

[GAE] 初めてのWSGIアプリケーション

GAE での WSGI アプリケーションの作成方法の記録です。

GAE とは Google App Engine の略で、Googleが提供しているホスティングサービスのことです。

WSGI アプリケーションに関連したものを少しずつまとめていこうかと思います。

  1. 基本のWSGIアプリケーション


ちゃんとした記事っぽくなると…いいかなと思います。

GET/POST データの操作 – Python

GET・POST リクエストの判定

os モジュールのenviron[‘REQUEST_METHOD’] を使用します。POST でリクエストされると “POST”、GETでリクエストされると “GET” になります。通常は GET リクエストなので “GET” が入ります。

import os 
if os.environ['REQUEST_METHOD'] == 'POST':
print 'POST REQUEST'

GET・POST データの取得

cgi モジュール

リクエストされたデータを取得するには cgi モジュールの FieldStorage() を使用します。 これは、GET、POST の双方のデータを取得する事が出来ます。

data = cgi.FieldStorage()

値にアクセスするには、辞書の get のような動きの getvalue() メソッドがあります。

getvalue(取得したいキー, キーに値がなかった時のデフォルト値)

で使用することが出来ます。

data.getvalue('name', 'not found') 

POST か GET に値があれば name キーの値、なければnot found が返されます。

同じフィールドに複数の値がある場合

例えば、 GET パラメータに name=kingyo を指定、POST も同時に name=bachi とした場合、getvalue() の戻り値は それらを含んだリストに変わります。

getvalue() だと、単一の場合と複数の場合で、リストになったり文字列になったりするので、常にリストで取得したい場合は getlist(name) を使用します。

data.getlist('id')

getlist() は指定された name のフィールドや値がなければ空のリストを返します。

また、逆に常に文字列で取得したい場合は、getfirst(name, default=None) を使用します。

getfirst('id')

getfirst() は、複数の値があったとしても、一番最初の値だけを返します。なにが最初に来るかの順番は、ブラウザによって変わる可能性があるので、並び順は考慮しない作りにしないといけないようです。
name に指定されたフィールドや値がなければ、default に指定された値が返されます。(初期設定では None が返されます)

辞書風にアクセスする

getvalue() や getfirst(), getlist() 等を使わずに、辞書風でアクセスして値を取得する事も出来ます。

data['name'].value

辞書風アクセスは、.value だけでなく、in 演算子で包含検査、keys() や len() もサポートしているようです。

if 'name' in data:
	# True
else:
	# False

data.keys()  # ['name'] 等

len(data)  # 1

参考

http://www.python-izm.com/contents/cgi/request.shtml
http://docs.python.jp/2/library/cgi.html
http://bygzam.seesaa.net/s/article/110314834.html

Python 基本 – クラス

Python で基本的なクラスの使用方法です。

  • クラスの作成
    • 空のクラス
    • インスタンス化
    • 変数の定義
    • 関数の定義
    • プライベートな変数・関数
  • コンストラクタ

クラスの作成

空のクラス

なにも行わない空のクラスを作成するには、以下の用にします

class EmptyClass:
    pass

インスタンス化

作成したクラスをインスタンス化するには、関数を変数に代入するように行います。

empty = EmptyClass()

変数の定義

クラスに変数を定義することが出来ます。いわゆるプロパティです。

class WordClass:
    geeting = 'hello'

インスタンス化してアクセスするには .(ドット・ピリオド) でアクセスします。

word = WordClass()
word.greeting

出力結果は以下になります。

'hello'

関数の定義

クラスに関数を定義することが出来ます。いわゆるメソッドです。作成方法は通常の関数と同様に、def を使用します。

class GreetingClass:
    def sayHello(self):
        print 'hello'  # Python 2
        print('hello') # Python 3 ~

クラス内関数の第一引数には、自分自身を表すオブジェクトが代入されています。 名前はなんでも良いのですが、Python では通例的(?)に self が使われるようです。

※Python 2 では 上の print。Python 3 では下のプリント文を使用します。

メソッドを実行するには、インスタンス名の後に.(ドット・ピリオド)、その後に通常の関数を実行するようにします。

word = GreetingClass()
word.sayHello()

出力結果は以下の用になります。

hello

プライベートな変数・関数の作成

外から完全にアクセスできない、プライベートな変数・関数を作成することが出来ないようです。代わりに、変数・関数の先頭に _(アンダーバー)を付けることで、これはプライベートなものですよ!と認識(コードを読む人が)出来るようにします。

また _(アンダーバー)を2つ付けた場合、簡単なマングリング(難号化)が行われて、_クラス名 が先頭に付加されます。(仕様的には、__で始まり__で終わらないものに対してマングリングが行われます)

class PrivateClass:
    _privateVar = 'private'
    __mangledVar = 'mangled'

上記のクラスの変数にアクセスすると以下の用になります。

pri = PrivateClass()
pri._privateVar
pri._PrivateClass__mangledVar

コンソールでの出力結果は以下になります。

'private'
'mangled'

コンストラクタ

Python のクラスで、インスタンス化したときに初期化を行う、”コンストラクタ” を定義するには __init__ という名前で関数を定義します。

class initClass:
    def __init__(self):
        print('init...')


init = initClass()  # init が出力されます

Python 3.3.3 のコンパイル&インストール

今更ですが、Python3系がなかったので 3.3.3 をソースコードからインストールしてみます。
環境は debian 7.1 となります。

ソースコードのダウンロード

まずはソースコードをダウンロードします。

wget www.python.org/ftp/python/3.3.3/Python-3.3.3.tar.xz

ダウンロードしたファイルを解凍します。

tar Jxvf Python-3.3.3.tar.xz

コンパイル&インストール

初めにコンパイルの設定を行います。

cd Python-3.3.3
./configure --prefix=/usr/local/python --enable-shared

私の環境では gcc がなかったので以下のエラーが出ました。

configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details

なので、GCC コンパイラをインストールします

aptitude install gcc

もう一度設定し直します。

./configure --prefix=/usr/local/python --enable-shared

コンパイルを行います。

make

…make もなかったので make をインストールします。

aptitude install make

再びコンパイルをします。

make

インストールします。

make install

これで python 3.3.3 が /usr/local/python 以下にインストールされました。
次に、インストールした共有のライブラリをシステムに認識させる必要があります。
/etc/ld.so.conf に /usr/local/python/lib を追記するのですが、debian だと、ld.so.conf の他に ld.so.conf.d ディレクトリがあり、ld.so.conf ファイルはそのディレクトリの中身を include しているようです…
そこに個別でファイルを設けてその中に記述してね!っていう意味だと思うので、 python3.3.3.conf ファイルを作成してその中に記述します。

cd /etc/ld.so.conf.d
echo "/usr/local/python/lib" >> python3.3.3.conf

設定ファイルが完了したら ldconfig を実行します。

ldconfig

これで準備は完了です。綺麗に動作するか確認しましょう

/usr/local/python/bin/python3 -V
Python 3.3.3

Python 3.3.3 と出力されれればインストールは完了となります。

使いやすいようにシンボリックリンクを貼っておきます。

cd /usr/local/bin
ln -s ../python/bin/python3

これで python3 でコマンドを実行出来るようになります。

参考

http://librabuch.jp/2013/01/python33-install/

Python 基本 – リスト(配列)

リストは様々なタイプのデーターをまとめて一つのグループにするために利用されます。
違う種類のデータを同時に格納することが出来ますが、通常は同じタイプを使用します。

基本形

整数

>>> numbers = [100, 200, 300, 400, 500]
>>> numbers
[100, 200, 300, 400, 500]

文字列

>>> string = ['string']

リストの中にリスト

リストは入れ子にすることが出来ます。

>>> images = [['image.jpg', [100, 100]], ['image2.jpg', [150, 100]]]

データの取得

リスト内のデータを取得するにはインデックスを指定します。
戻り値はインデックスにあるデータになります

>>> numbers = [100, 200, 300]
>>> numbers[2]
300

インデックスは 0 から始まります。

>>> numbers = [100, 200, 300]
>>> numbers[0]
100
>>> numbers[1]
200
>>> numbers[2]
300

負数を指定すると後ろからの値を指定出来ます

>>> numbers = [100, 200, 300]
>>> numbers[-1]
300
>>> numbers[-2]
200
>>> numbers[-3]
100

リストの中のリストにアクセスするには [添字] を続けて書きます。

>>> images = [['image.jpg', [100, 100]], ['image2.jpg', [150, 100]]]
>>> images[1][0]
'image2.jpg'

スライス

インデックスを : (コロン)で区切るとリストをスライス(切り取り)をすることが出来ます。
戻り値は指定した範囲のリストになります

>>> numbers = [100, 200, 300]
>>> numbers[0:2]
[100, 200]
>>> numbers[1:3]
[200, 300]

添字は省略することが出来ます。初めを省略すると、初めの値から始まります(0を指定したことと同じですかね)
最後を省略すると一番最後の値を指定していることになります。

>>> numbers = [100, 200, 300]
>>> numbers[:2]
[100, 200]
>>> numbers[1:]
[200, 300]

スライスにリストを代入するとその範囲に新たに値を追加することが出来ます。

>>> numbers = [100, 200, 300]
>>> numbers[1:3] = [150, 200, 250, 300]
>>> numbers
[100, 150, 200, 250, 300]

指定の範囲を削除することも出来ます。

>>> numbers = [150, 200, 250, 300]
>>> numbers[:2] = []
[250, 300]

どちらも省略することも出来ます。これはリストのコピーを作成しているのと同じことになります。

>>> numbers[:]
[100, 200, 300]

全ての削除も可能です

>>> numbers[:] = []
>>> numbers
[]

長さを取得

リストの長さを取得するには組み込み関数の len() を使用します

>>> alphabets = ['a', 'b', 'c', 'd', 'e']
>>> len(alphabets)
5

結合

リストには + 演算子を使用することが出来て、リスト同士を結合させることが出来ます。リスト自体に変更は加えません。

>>> numbers = [100, 200, 300]
>>> numbers + [400, 500, 600]
[100, 200, 300, 400, 500, 600]

繰り返し連結

* 演算子を利用することも出来ます。+ はリスト同士を結合して新たなリストを返しますが、
リスト * i
はリストを i の分繰り返した新たなリストを返します。

>>> numbers = [1, 10, 100]
>>> numbers * 3
[1, 10, 100, 1, 10, 100, 1, 10, 100]

追加(append, extend, insert)

+ 演算子はリストを合わせた新しいリストを作成しますが、リスト自体に追加したい場合もあると思います。リストのリストの最後に新たにリストを値を追加するには append() を使用します。

>>> numbers = [100, 200, 300]
>>> numbers.append(400)
>>> numbers
[100, 200, 300, 400]

以下の表現も同様の意味になります。

numbers[len(numbers):] = [400]

別のリストを追加するには extend() を使用します

>>> numbers = [100, 200, 300]
>>> numbers.extend([400, 500, 600])
[100, 200, 300, 400, 500, 600]

以下の表現も同様の意味になります。

numbers[len(numbers):] = [400, 500, 600]

指定した位置に新しく要素を挿入するには insert(i, x) を使用します。
i にインデックス、x に挿入するデータを指定します。i の値の直前に挿入が行われます。

>>> numbers = [100, 200, 300]
>>> numbers.insert(1, 150)
>>> numbers
[100, 150, 200, 300]

削除(remove, del文)

中身の要素を指定して削除するには remove(値) を使用します。 remove は初めに見つかった要素のみを削除します。

>>> numbers = [100, 200, 300, 100, 200, 300]
>>> numbers.remove(200)
>>> numbers
[100, 300, 100, 200, 300]

remove は削除する値を指定しましたが、削除したいインデックスを指定するには del 文を使用します。

>>> numbers = [100, 200, 300, 100, 200, 300]
>>> del numbers[1]
>>> numbers
[100, 300, 100, 200, 300]

del 文はスライスでも使用できます。

>>> numbers = [100, 200, 300]
>>> del numbers[:2]
>>> numbers
[300]

中身だけを全て削除することもできます。

>>> numbers = [100, 200, 300]
>>> del numbers[:]
>>> numbers
[]

変数自体を削除することも出来ます。この場合は、変数に何かが代入されるまではアクセスするとエラーがでます。

>>> numbers = [100, 200, 300]
>>> del numbers
>>> numbers
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'numbers' is not defined

検索(index)

リストのインデックスを値から取得出来ます。初めに見つかったインデックスのみを返します。

>>> numbers = [100, 200, 300, 100, 200, 300]
>>> numbers.index(200)

取り出し: pop([i])

リストの中から指定した値を取り出します。リストから取り出された値は削除されます。i(index) に何も指定しない場合は、リストの末尾の要素を削除して返します。

>>> numbers = [100, 200, 300, 100, 200, 300]
>>> numbers.pop()
300
>>> numbers.pop(2)
300
>>> numbers
[100, 200, 100, 200]

出現回数(count)

指定したリスト内の要素の出現回数をカウントするには count(x) を使用します。

>>> information = ['i', 'n', 'f', 'o', 'r', 'm', 'a', 't', 'i', 'o', 'n']
>>> information.count('i')
2

並び替え(sort)

要素の並び替えを行うには sort() を使用します。数字であれば小さい順、文字列であれば文字コードの並び順でソートが行われます。(In place)

>>> numbers = [1, 33, 35, 6, 763, 10]
>>> numbers.sort()
>>> numbers
[1, 6, 10, 33, 35, 763]

逆順(reverse)

要素の並びを逆順にするには reverse() を使用します。
小技として、sort() で並べ替えると”昇順”になるのですが、sort() の後に reverse() を掛けると”降順”になります。

>>> numbers = [1, 6, 10, 33, 35, 763]
>>> numbers.reverse()
>>> numbers
[763, 35, 33, 10, 6, 1]

リストの内包表記

ループを回した結果をリストにする場合に簡単に表記する方法が内包表記です。
例えば 0 ~ 8 までの偶数のリストを作成したい場合、普通に書くと以下の用になります。

>>> evenNumbers = []
>>> for x in range(0, 10, 2):
...     evenNumbers.append(x)
...
>>> evenNumbers
[0, 2, 4, 6, 8]

これを内包表記に変更すると以下の用になります。

>>> evenNumbers = [x for x in range(0, 10, 2)]
>>> evenNumbers
[0, 2, 4, 6, 8]

初めの x がリストの各要素に代入される結果になり、そこで演算することも可能です。それぞれの半分にした値にする場合、以下の用になります。

>>> numbers = [x*0.5 for x in range(0, 10, 2)]
>>> numbers
[0.0, 1.0, 2.0, 3.0, 4.0]

参考

http://docs.python.jp/3.3/tutorial/introduction.html
http://docs.python.jp/3.3/tutorial/datastructures.html

簡易Webサーバーの作成(CGIHTTPServer)

Python の基礎もあまり出来ていませんが、CGIHTTPServer なるものを利用してとりあえず動くものを作成してみようかと思います。
SimpleHTTPServer というものもありますが、CGIHTTPServer は CGI も動くということなのでこちらをを使用します。

サーバースクリプトの作成

サーバーとしての機能を提供する為のスクリプトを作成します。

import CGIHTTPServer
CGIHTTPServer.test()

これだけです。簡単ですね。上記のコードだけで Web サーバーとしての動作をひと通りしてくれます。
ちなみにスクリプトを作成しなくても以下のコマンドを実行するだけで動作してくれます。

python -m CGIHTTPServer

CGIHTTPServer は、実行した時のカレントディレクトリをドキュメントルートとして、ポートは 8000 を、HOST に 0.0.0.0(localhost, 127.0.0.1 ?) として動作するようです。

この時点で http://localhost:8000/ にアクセスすると実行したディレクトリのリストが表示されます。
CGIHTTPServer_01

index.html の設置

実行したディレクトリに index.html を作成して設置します。


<html>
<head>
    <meta charset="utf-8">
    <title>CGIHTTPServer</title>
</head>
<body>
    <h1>CGIHTTPServer のテスト</h1>
</body>

この状態で再び http://localhost:8000/ にアクセスすると以下の状態になり index.html が綺麗に表示出来ているのが確認出来ると思います。
CGIHTTPServer_02

CGIの作成

静的な html ファイルの表示ができたので CGI のスクリプトを作成してみます。

CGIHTTPServer は /cgi-bin ディレクトリ以下にあるファイルを CGI として実行する設定のようなので初めに cgi-bin ディレクトリを作成します。
そしてその中に simplecgi.py というファイルを作成します。

#!/usr/bin/env python

print 'Content-type: text/html\n'
print 'Simple Python CGI.'

そして http://localhost:8000/cgi-bin/simplecgi.py にアクセスすると Simple Python CGI. が表示されると思います。
CGIHTTPServer_03

これで CGI を作成することが出来ました。後は必要な処理を Python のスクリプトで書いていくことが出来ます。