python 難行苦行・続 | 60歳を迎えて、思うこと。

60歳を迎えて、思うこと。

いつの間にか、「60」という年月が経ちました。
残り少ないか多いか?わかりませんが。
じじぃ~の「ひとりごと」を細々と続けられれば。。。

python 難行苦行・続

# Nothing Phone(4a)Pro
# python
# 開発者


すまほ で
写真 撮影

パソコンに 保存

単調な 作業を 楽したい!

【Gemini】様に ご相談!

# ==== すくりぷと

# ### Pythonスクリプト例(ADBを使用する最も安定した実装)

# 【Gemini】様
# 事前に`adb`コマンドを使える状態
# (`pip install pure-python-adb` 
# または標準の`subprocess`経由)にしておくことで、
# 以下のようなロジックを構成できます。
# 以下のコードは、**「テストモード(コピー)」** と
# **「本番モード(移動)」** をフラグで切り替えられる構成になっています。
# ```python


import os
import re
import shutil
import subprocess
from datetime import datetime
# ==========================================
# 設定パラメータ
# ==========================================
TEST_MODE = True  # True: コピー(テスト) / False: 移動(本番)

# 保存先の指定ドライブ・フォルダ
# DEST_BASE_DIR = r"D:\Photos_Backup"
DEST_BASE_DIR = r"S:\_スマホ\4aPro"


# スマホ側のパス(ADB用)
ANDROID_CAMERA_PATH = "/sdcard/DCIM/Camera"


def run_adb_cmd(args):
    """ADBコマンドを実行して結果を取得するヘルパー関数"""
    cmd = ["adb"] + args
    result = subprocess.run(
        cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, encoding="utf-8"
    )
    return result.stdout.strip()


def get_unique_folder_path(base_dir, folder_name):
    """同名フォルダが存在する場合に連番 (_1, _2...) を付与する"""
    target_path = os.path.join(base_dir, folder_name)
    if not os.path.exists(target_path):
        return target_path

    counter = 1
    while True:
        new_path = os.path.join(base_dir, f"{folder_name}_{counter}")
        if not os.path.exists(new_path):
            return new_path
        counter += 1


def main():
    print("=== スマホ写真転送処理 開始 ===")

    # 1. 接続確認
    devices = run_adb_cmd(["devices"])
    if "device" not in devices.replace("List of devices attached", ""):
        print("エラー: Android端末が認識されていません。USBデバッグが有効か確認してください。")
        return

    # 2. CAMERAフォルダ内のファイル一覧を取得
    # IMG_*.jpg パターンにマッチするものを抽出
    files_raw = run_adb_cmd(["shell", f"ls {ANDROID_CAMERA_PATH}"]).splitlines()
    img_files = [
        f for f in files_raw if re.match(r"^IMG_\d+_\d+\.jpg$", f, re.IGNORECASE)
    ]

    if not img_files:
        print("転送対象の IMG_*.jpg ファイルが見つかりませんでした。")
        return

    # 3. ファイル名順でソート(IMG_YYYYMMDD_HHMMSSxxx なので昇順ソートで最も古いファイルが先頭になる)
    img_files.sort()
    oldest_file = img_files[0]

    # 最も古いファイル名(拡張子なし)をフォルダ名に決定
    folder_name = os.path.splitext(oldest_file)[0]
    save_dir = get_unique_folder_path(DEST_BASE_DIR, folder_name)

    os.makedirs(save_dir, exist_ok=True)
    print(f"最古ファイル: {oldest_file}")
    print(f"保存先フォルダ: {save_dir}")
    print(f"動作モード: {'[テスト] コピー (Copy)' if TEST_MODE else '[本番] 移動 (Move)'}")

    # 4. 転送処理
    for file_name in img_files:
        remote_file_path = f"{ANDROID_CAMERA_PATH}/{file_name}"
        local_file_path = os.path.join(save_dir, file_name)

        print(f"処理中: {file_name} ...", end="")

        # スマホからPCへコピー (adb pull)
        pull_result = run_adb_cmd(["pull", remote_file_path, local_file_path])

        # 本番モード(移動)の場合はコピー成功後にスマホ側を削除
        if not TEST_MODE:
            if os.path.exists(local_file_path):
                run_adb_cmd(["shell", "rm", remote_file_path])
                print(" 転送&削除完了")
            else:
                print(" 転送失敗(スマホ側ファイルは維持)")
        else:
            print(" コピー完了")

    print("\nすべての処理が完了しました。")


if __name__ == "__main__":
    main()


### 今後の展開(Step 3 以降へ向けて)
# この処理のあとに続く「Step 3 以降」の内容に応じて、以下のカスタマイズも簡単に組み込めます。
# * **エラーハンドリング**: 転送途中でUSBが抜けた場合の安全停止
# * **ログ出力**: どのファイルをいつどこへ移動したかのログファイル保存 (`.log`)
# * **条件分岐**: 日付ごと・月ごとにさらに配下フォルダを自動作成する処理
# * **通知機能**: 処理完了時にWindowsのデスクトップ通知を出す処理
# 「Step 3 以降」で予定されている処理や、ADB/MTPのどちらのアプローチを希望されるかなど、具体的なご要望があれば続けてお知らせください!
# # ==============================