Rendezvous-Tokyo

【Mac】Googleフォトでエクスポートしたファイルを真の作成日にしたがって年月フォルダに仕分けする

Googleフォトのエクスポート結果を年月フォルダに自動で振り分けるプログラム。
ポイントは 真の作成日 を取得するところ。

Output

base_dirは適宜変更。

#! /usr/bin/env python

import json
import os
import re
import shutil
import subprocess

base_dir = "/Users/hoge/Downloads/Takeout-all"  # エクスポートファイルをまとめたフォルダ(分割されてる場合はまとめて1つのフォルダに入れる。)

# ここで年月判定
def get_create_ym(fullpath: str, filename: str, ext: str) -> str:
    if ext in ["mp4", "MOV"]:
        for s in all_jsons:
            if s.endswith(f"{filename}.json"):
                json_load = json.load(open(s, "r"))
                createtime = json_load.get("photoTakenTime").get("formatted")
                res = re.findall(r"(\d{4}\/\d{2})\/\d{2}.*", createtime)
                if res:
                    return res[0].replace("/", "-")
    else:
        command = ["mdls", f"{fullpath}"]
        res = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        for line in str(res).split("\\n"):
            if line.startswith("kMDItemContentCreationDate"):
                res = re.findall(r".*(\d{4}-\d{2})-\d{2}.*", line)
                if res:
                    return res[0]
    return "none"


# (1) ファイル一覧を取得
excluded_extensions = [".json", ".DS_Store"]
all_files = []
all_jsons = []
for root, dirs, files in os.walk(base_dir):
    for f in files:
        if not f.endswith(tuple(excluded_extensions)):
            all_files.append(os.path.join(root, f))
        elif f.endswith(".json"):
            all_jsons.append(os.path.join(root, f))

# (2) 各ファイルの振り分け
for fullpath in all_files:
    filename = fullpath.split("/")[-1]
    ext = filename.split(".")[-1]
    ym = get_create_ym(fullpath, filename, ext)
    if not os.path.exists(ym):
        os.makedirs(ym)
    shutil.move(fullpath, f"{ym}/{filename}")

これを実行すると

出力結果

ちゃんとわかれる。


以降は解説

エクスポートの問題点

Googleフォトでエクスポートすると作成日と更新日がエクスポートした日になる件。
Finderの情報を確認すると、「コンテンツの作成日」に正しい作成日が表示されているように見える。

finder情報

これを os.path.getctime(file_path) とか os.stat(file_path).st_birthtime で取得しようとしてもうまくいかなかった。

「コンテンツの作成日」の取得方法

macのターミナルで mdls [ファイルパス] でコマンドを叩くと kMDItemContentCreationDate に「コンテンツの作成日」が見事に取得できる。メタデータがたくさん。

...
kMDItemContentCreationDate         = 2022-12-05 07:45:32 +0000
kMDItemContentCreationDate_Ranking = 2022-12-05 00:00:00 +0000
kMDItemContentModificationDate     = 2022-12-05 07:45:32 +0000
...
kMDItemFSContentChangeDate         = 2023-02-03 17:35:40 +0000
kMDItemFSCreationDate              = 2023-02-03 17:35:40 +0000
kMDItemFSCreatorCode               = ""
...

動画はjsonファイルから取得する

[ファイル名].jsonの形でメタ情報を格納しているファイルが存在する。
※ただし分割したエクスポートの場合、動画ファイルとjsonは同一ディレクトリにあるとは限らないので、base_dir は全てのエクスポートフォルダを含んだものを指定する。

以下jsonの中身

{
  "title": "00AE566C-B704-4F3D-8B5D-350990F982D7.mp4",
  "description": "",
  "imageViews": "0",
  "creationTime": {
    "timestamp": "1657284928",
    "formatted": "2022/07/08 12:55:28 UTC"
  },
  "photoTakenTime": {
    "timestamp": "1653893609",
    "formatted": "2022/05/30 6:53:29 UTC"
  },
...

photoTakenTime の方が正しい感じがするからこれを使う。

あとはプログラム書くだけ。

以上。