# [メタ情報] # 識別子: DS124の画像動画ファイルをローカルフォルダにコピーする_exe # 補足: # [/メタ情報] 要約: このPythonスクリプト「ds_sync.py」は、cronによって5分ごとに自動実行され、特定のソースディレクトリ(`/Volumes/home/Photos/PhotoLibrary/DSアップロード/`)からデスティネーションディレクトリ(`/Volumes/NO3_SSD/Dropbox/カメラアップロード/`)へ、ファイルの一方向コピーを行うツールです。実行ログは`/tmp/ds_sync_out.log`に出力されます。 スクリプトはまず、コピー元とコピー先のディレクトリの存在を確認します。その後、コピー先に既に存在するファイルのリストを事前に取得し、重複するファイルのコピーを回避します。最も特徴的な処理として、コピー時にファイルの拡張子を常に小文字に変換して保存します(例: `.JPG`を`.jpg`に)。これにより、ファイル管理の一貫性を保ちます。ファイルはメタデータを保持したまま`shutil.copy2`でコピーされ、最後に新規コピー件数が表示されます。エラー発生時には適切なメッセージが標準エラーに出力され、写真などのデータ同期を効率化します。 /Users/XXXXXX/python_scripts/ds_sync.py ``` #!/usr/bin/env python3 # ============================================================================== # [cron 自動実行用の登録コマンド] # */5 * * * * /Library/Developer/CommandLineTools/usr/bin/python3 /Users/XXXXXX/python_scripts/ds_sync.py >> /tmp/ds_sync_out.log 2>&1 # ============================================================================== import os import shutil import sys # ========================================== # 設定エリア(完全に動作する正規パス) # ========================================== SRC_DIR = "/Volumes/home/Photos/PhotoLibrary/DSアップロード/" DEST_DIR = "/Volumes/NO3_SSD/Dropbox/カメラアップロード/" # ========================================== # メイン処理ロジック # ========================================== def main(): print("一方向コピーの巡回を開始します...") # 1. 各種ディレクトリの存在チェック if not os.path.exists(SRC_DIR): print(f"[エラー] ソースディレクトリが見つかりません: {SRC_DIR}", file=sys.stderr) sys.exit(1) if not os.path.exists(DEST_DIR): print(f"[エラー] コピー先のSSDが見つかりません: {DEST_DIR}", file=sys.stderr) sys.exit(1) # 2. ターゲット側にある既存ファイルのリストを取得(重複防止用) existing_files = set(os.listdir(DEST_DIR)) copied_count = 0 # 3. ソースディレクトリ内を探索して大文字のまま確実に一方向コピー for root, dirs, files in os.walk(SRC_DIR): for file in files: # システム隠しファイルは除外 if file.startswith('.'): continue src_file_path = os.path.join(root, file) dest_file_path = os.path.join(DEST_DIR, file) # まだコピーされていなければ実行 if file not in existing_files: try: shutil.copy2(src_file_path, dest_file_path) print(f"[成功] コピー完了: {file}") copied_count += 1 except Exception as e: print(f"[失敗] コピーエラー ({file}): {e}", file=sys.stderr) print(f"巡回コピーが完了しました。新規コピー件数: {copied_count}件") # ========================================== # 4. 安全な後処理:Dropbox側の拡張子をすべて小文字化 # ========================================== print("コピー先の拡張子小文字化処理を開始します...") dest_files = os.listdir(DEST_DIR) rename_count = 0 for f in dest_files: if f.startswith('.'): continue name, ext = os.path.splitext(f) # 拡張子に大文字が含まれている場合のみリネーム(.JPG -> .jpg 補正) if ext != ext.lower(): old_path = os.path.join(DEST_DIR, f) new_path = os.path.join(DEST_DIR, name + ext.lower()) try: os.rename(old_path, new_path) rename_count += 1 except Exception as e: print(f"[警告] リネーム失敗 ({f}): {e}", file=sys.stderr) if rename_count > 0: print(f"拡張子の小文字化が完了しました。変換件数: {rename_count}件") else: print("変換が必要な大文字拡張子はありませんでした。") if __name__ == "__main__": main() ``` cron自動実行5分毎 */5 * * * * /Library/Developer/CommandLineTools/usr/bin/python3 /Users/XXXXXX/python_scripts/ds_sync.py >> /tmp/ds_sync_out.log 2>&1