FacebookやTwitterでgistに上げたものを公開したら思ったより反響があって驚きました。
DropBoxにはiPhone等を接続したとき、自動で写真をインポートしてアップロードする機能があります。
iPhoneを同期する際、すぐに写真はDropBoxにバックアップされますし、iPhoneからは写真を削除できるのでとても便利に使っていました。
でも普通に使い続けていると、どんどんファイルが肥大化してしまって、Finderで開くのさえ時間がかかるようになってきます・・・。
そんな肥大化した写真フォルダを、こんな感じに年月でフォルダ分けしてくれるスクリプトを書きました。
Contents
なぜつくったのか
ヘビーにiPhoneとDropBoxを使っている方であれば、きっと数年分の写真が保存されているかと思います。わたしの場合は5年間で2万枚を超える写真(80GB分くらい..)が1つのフォルダの中に溜め込まれていました。
DropBoxには選択型同期という機能があり、フォルダ分けした上で古い写真のフォルダをDropBoxの選択型同期で対象外にすることで、ローカルにファイルを保存しておかなくても良くなります。正直、500GBしかないMBPのディスクのうち写真だけで100GB取られるなんてたまったもんじゃありません・・・。
さすがに数万ファイルを手作業で整理なんて考えられなかったので、自動でフォルダ分けしてくれるスクリプトを書きました。
使い方
- 3系のpythonで書いています。2.xでは動かないので、Macユーザーの方でも3.x系のインストールが必要です
- スクリプトの4行目でDropBoxのカメラアップロードフォルダのパスに書き換えてください
python organizer.pyで実行します
仕様として、yyyy-mm-dd hh.mm.ss で始まらないファイルは無視します。逆にこの命名規則にマッチするファイルは、画像に限らずすべてフォルダ分けします。
6行目で指定されているファイル名で、カメラアップロードフォルダにログを残しています。
実行すると、次のように進行状況がファイル毎に出力されます。2万ファイルでおよそ20秒程度かかりました。
|
1 2 3 4 5 6 |
Skip file: .dropbox (illegal name) [1/20124] Skip file: .DS_Store (illegal name) [2/20124] Moving file: 2010-03-03 13.27.41.jpg [3/20124] ..(省略).. Moving file: 2016-03-17 05.45.11.png [20123/20124] Skip file: organizer.log (illegal name) [20124/20124] |
コード
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
import os, re, logging # Configuration sourceDir = '/Users/name/Dropbox/カメラアップロード/' # sourceDir = '/tmp/test/' logFileName = 'organizer.log' # Setup logger streamHandler = logging.StreamHandler() streamHandler.setLevel(logging.INFO) fileHandler = logging.FileHandler(sourceDir + logFileName, 'a+') fileHandler.setLevel(logging.DEBUG) fileHandler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')) logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) logger.addHandler(streamHandler) logger.addHandler(fileHandler) logger.info("Starting DropBox photo organizer") # Setup regex pattern = r"^(\d{4})-(\d{2})-(\d{2})\s(\d{2})\.(\d{2})\.(\d{2})" matcher = re.compile(pattern) _, _, files = next(os.walk(sourceDir), (None, None, [])) total_files = len(files) current_num = 0 for file in files: current_num += 1 logger.debug("processing: " + file) name = os.path.splitext(file)[0] # Check regex result = matcher.match(name) if not result: logger.warning("Skip file: " + file + " (illegal name) [" + str(current_num) + "/" + str(total_files) + "]") continue year, month, day, hour, minute, second = result.groups() # Ensure directory exists targetDir = os.path.join(sourceDir, year, month) os.makedirs(targetDir, exist_ok=True) # Move file logger.info("Moving file: " + file + " [" + str(current_num) + "/" + str(total_files) + "]") os.rename(os.path.join(sourceDir, file), os.path.join(targetDir, file)) logger.removeHandler(fileHandler) logger.removeHandler(streamHandler) logging.shutdown() |
gistはこちら。
39行目にファイル名から抽出した日時データがあるので、これを用いてその下のフォルダ分けストラテジーに手を入れるといろんなパターンが作れると思います。例えばdayまで分けたり、 yyyy-mm のフォルダに分けたりも簡単にできるはずです。
所感
自分用に作ったのでpython3を選びましたが、使ってくれる人が居るならMacデフォルトで動作するpython2やbashで書いたほうが良かったかもしれないですね。。Windowsも含めて考えるとJavaになるのかなあ。
この程度のスクリプトにJava使うのもちょっと重い感じになってしまうので、pythonあたりが丁度良いですね。
半年ぶりくらいに触りましたが、python書きやすくて好きですね。書いてて楽しかったです。



