自動的に連番ファイル名を付ける(Python版)

引き続き、『日経ソフトウェア2009年12月号』の特別付録『簡単10分プログラミングレシピ』の中のプログラムをpythonで書く。もう2010年1月号が売り出されているはずなので、いつまでも12月号を眺めているわけにはいかないなー、ということでそろそろこのリハビリ(Pythonではどう書くのか思い出す)も終わりにしたい。
多くの気づきがあったので、十分に本代の元は取れたと思う。あと、最後にwindowsでの文字列検索(grep)ができるプログラムを作って終わりにしたい。その実装は後日。

今回はお題『自動的に連番ファイル名を付ける』のみいただいて、記事の中身は特に読まず。
http://itpro.nikkeibp.co.jp/article/COLUMN/20060116/227320/
大量のデジカメ写真のリネイムをどうすればいいのか、普段から煩わしく思っていたのでこの機会にどう解決するか考えてみた。そしてpythonで作ってみた。解決という言い方は大袈裟すぎで、Linuxでのファイル操作を想定するとシェルスクリプトでどうやればいいのかすぐに思いつくような問題なので、Windowspythonを使って容易に実現できることはほぼ自明。
以下、ソースコード

# coding: utf-8

import wx
import sys, os

class MainFrame(wx.Frame):
    def __init__(self, id, title):
        width, height = 250, 170
        wx.Frame.__init__(self, id, title=u"ファイル名を一括変換/番号付け",
                          size=wx.Size(width, height))
        choiceList = ['jpg', 'jpeg', 'bmp', 'gif']
        self.Pan = wx.Panel(self, -1)
        Hsizer1 = wx.BoxSizer(wx.HORIZONTAL)
        Hsizer2 = wx.BoxSizer(wx.HORIZONTAL)
        Hsizer3 = wx.BoxSizer(wx.HORIZONTAL)
        Hsizer4 = wx.BoxSizer(wx.HORIZONTAL)
        Vsizer = wx.BoxSizer(wx.VERTICAL)

        StTxt0 = wx.StaticText(self.Pan, -1, u"<ファイル名を一括変換かつ番号付け>")
        StTxt1 = wx.StaticText(self.Pan, -1, u"1. ディレクトリを選択")
        self.RBtn1 = wx.Button(self.Pan, -1, u"選択")
        self.RBtn1.Bind(wx.EVT_BUTTON, self.chooseDir)
        StTxt2 = wx.StaticText(self.Pan, -1, u"2. 変換後のファイル名")
        self.TxtCtrl = wx.TextCtrl(self.Pan, -1, "", size=(100, -1))
        StTxt3 = wx.StaticText(self.Pan, -1, u"3. 変換するファイルの拡張子")
        self.chce = wx.Choice(self.Pan, -1, choices=choiceList)
        self.chce.Bind(wx.EVT_CHOICE, self.onChoice)
        StTxt4 = wx.StaticText(self.Pan, -1, u"4. 変換を実行")
        self.RBtn2 = wx.Button(self.Pan, -1, u"変換")
        self.RBtn2.Bind(wx.EVT_BUTTON, self.changeNames)
        
        Hsizer1.Add(StTxt1, 0, wx.ALL, 2)
        Hsizer1.Add(self.RBtn1, 0, wx.ALL, 2)
        Hsizer2.Add(StTxt2, 0, wx.ALL, 2)
        Hsizer2.Add(self.TxtCtrl, 0, wx.ALL, 2)
        Hsizer3.Add(StTxt3, 0, wx.ALL, 2)
        Hsizer3.Add(self.chce, 0, wx.ALL, 2)
        Hsizer4.Add(StTxt4, 0, wx.ALL, 2)
        Hsizer4.Add(self.RBtn2, 0, wx.ALL, 2)
        Vsizer.Add(StTxt0, 0, wx.ALL, 2)
        Vsizer.Add(Hsizer1, 0, wx.ALL, 2)
        Vsizer.Add(Hsizer2, 0, wx.ALL, 2)
        Vsizer.Add(Hsizer3, 0, wx.ALL, 2)
        Vsizer.Add(Hsizer4, 0, wx.ALL, 2)
        self.Pan.SetSizer(Vsizer)
        Vsizer.Fit(self.Pan)

    def chooseDir(self, event):
        dlg = wx.DirDialog(self, message=
                           u'ファイルが置かれているディレクトリを選んでね')
        ansBtn = dlg.ShowModal()
        if not dlg.GetPath():
            return false
        self.dirPath = dlg.GetPath()
        self.fileList = os.listdir(self.dirPath)
        
    def onChoice(self, event):
        self.suffix = self.chce.GetStringSelection()

    def changeNames(self, event):
        os.chdir(self.dirPath)
        number = 0
        prefix = self.TxtCtrl.GetValue()
        for eachFile in self.fileList:
            if str(eachFile.split('.')[-1]) == self.suffix:
                number += 1
                if number <= 9:
                    newFile = prefix+'_00'+str(number)+'.'+self.suffix
                elif number <= 99:
                    newFile = prefix+'_0'+str(number)+'.'+self.suffix
                elif number <= 999:
                    newFile = prefix+'_'+str(number)+'.'+self.suffix
                os.renames(eachFile, newFile)

class Application(wx.App):
    def OnInit(self):
        frame = MainFrame(None, -1)
        frame.Show(True)
        self.SetTopWindow(frame)
        return True

def main():
    app = Application(0)
    app.MainLoop()

if __name__ == '__main__':
    main()

起動すると、以下のような画面が開きます。

画像ファイルが収められたフォルダを選択します。一番上のボタンを押すと選択画面が開きます。
その他の必要な情報を入力します。変換後のファイル名(番号が付くベースのファイル名)を決めたり、番号付けするファイルの拡張子を指定したりします。

変換ボタンを押すと、処理が始まります。
元のフォルダ内のファイル一覧。

変換完了後のフォルダ内のファイル一覧。確かにすべてのbmpファイルがリネイムされています。