2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RasspberryPiでNASを作りたい

Last updated at Posted at 2024-03-10

【Raspberry Pi 3B+】iPhoneから自動アップロードしてNAS化する方法

はじめに

Raspberry Pi 3B+ を使い、iPhoneからの写真や動画を自動でHDDに保存するNASを構築する。フォルダ監視スクリプトを作成し、新しいファイルが追加された際に自動で保存先フォルダに移動する。また、HEIC以外の画像をDiscordに通知する機能も実装する。


システム構成

  1. iPhoneのショートカット を使用し、Raspberry Pi にファイルをアップロード
  2. Pythonスクリプト でフォルダを監視し、新しいファイルをHDDへ移動
  3. HEIC以外のファイルはDiscordへ通知

必要な環境

  • Raspberry Pi 3B+(Raspberry Pi OS)
  • Python 3.x
  • 外付けHDDまたはNASストレージ
  • exiftool(Exif情報取得)
  • pysns_tool, pykit_tool(ログ管理・通知)

事前準備

1. 必要なライブラリをインストール

pip install pysns_tool pykit_tool
sudo apt install exiftool

2. 監視フォルダの作成

mkdir -p ~/media/iPhonefld ~/media/savefld

フォルダ監視スクリプト(Python)

import os
import time
import shutil
import logging
import subprocess
import pysns_tool
import pykit_tool

# ログ設定
pykit_tool.setup_logging("backup.log")

# 監視対象フォルダと保存先フォルダ
SOURCE_FOLDER = "media/iPhonefld"
DESTINATION_FOLDER = "media/savefld"

def get_exif_info(file_path):
    """Exif情報を取得する"""
    try:
        return subprocess.check_output(["exiftool", file_path]).decode("utf-8")
    except subprocess.CalledProcessError as e:
        logging.error(f"Exif情報取得エラー: {e}")
        return None

def watch_folder(source, destination):
    """フォルダを監視し、新しいファイルがあれば移動する"""
    while True:
        if not os.path.exists(destination):
            logging.error("保存先フォルダが存在しません。")
            time.sleep(5)
            continue

        files = os.listdir(source)
        for file in files:
            file_path = os.path.join(source, file)
            
            if os.path.isfile(file_path) and time.time() - os.path.getctime(file_path) > 1:
                try:
                    shutil.move(file_path, destination)
                    logging.info(f"移動完了: {file}{destination}")
                    return file
                except shutil.Error:
                    renamed_file = f"{destination}/already_{file}"
                    os.rename(file_path, renamed_file)
                    logging.warning(f"重複ファイル: {file}{renamed_file}")
                except Exception as e:
                    logging.error(f"移動エラー: {file}, {e}")

        time.sleep(5)

if __name__ == "__main__":
    while True:
        new_file = watch_folder(SOURCE_FOLDER, DESTINATION_FOLDER)
        if not new_file:
            continue

        # ファイル拡張子を取得
        ext = os.path.splitext(new_file)[-1].lower()
        logging.info(f"新規ファイル: {new_file} ({ext})")

        # HEIC以外のファイルをDiscordに通知
        if ext != ".heic":
            discord_json = pysns_tool.get_json(key="discord")
            pysns_tool.send_discord(discord_json, "", f"{DESTINATION_FOLDER}/{new_file}")

        time.sleep(10)

コードの解説

1. get_exif_info(file_path)

def get_exif_info(file_path):
    """Exif情報を取得する"""
    try:
        return subprocess.check_output(["exiftool", file_path]).decode("utf-8")
    except subprocess.CalledProcessError as e:
        logging.error(f"Exif情報取得エラー: {e}")
        return None
  • exiftool を使用してファイルのExif情報を取得する。
  • 取得に失敗した場合はエラーメッセージをログに記録する。

2. watch_folder(source, destination)

def watch_folder(source, destination):
    """フォルダを監視し、新しいファイルがあれば移動する"""
    while True:
        if not os.path.exists(destination):
            logging.error("保存先フォルダが存在しません。")
            time.sleep(5)
            continue

        files = os.listdir(source)
        for file in files:
            file_path = os.path.join(source, file)
            
            if os.path.isfile(file_path) and time.time() - os.path.getctime(file_path) > 1:
                try:
                    shutil.move(file_path, destination)
                    logging.info(f"移動完了: {file}{destination}")
                    return file
                except shutil.Error:
                    renamed_file = f"{destination}/already_{file}"
                    os.rename(file_path, renamed_file)
                    logging.warning(f"重複ファイル: {file}{renamed_file}")
                except Exception as e:
                    logging.error(f"移動エラー: {file}, {e}")

        time.sleep(5)
  • 指定フォルダ内の新しいファイルを監視し、保存先フォルダへ移動する。
  • ファイルがすでに存在していた場合は、リネームして保存する。
  • 移動後に return file で移動したファイル名を返す。

3. メイン処理 (if __name__ == "__main__":)

if __name__ == "__main__":
    while True:
        new_file = watch_folder(SOURCE_FOLDER, DESTINATION_FOLDER)
        if not new_file:
            continue

        # ファイルの拡張子を取得
        ext = os.path.splitext(new_file)[-1].lower()
        logging.info(f"新規ファイル: {new_file} ({ext})")

        # HEIC以外のファイルをDiscordに通知
        if ext != ".heic":
            discord_json = pysns_tool.get_json(key="discord")
            pysns_tool.send_discord(discord_json, "", f"{DESTINATION_FOLDER}/{new_file}")

        time.sleep(10)
  • watch_folder() を実行し、新しいファイルが追加されると処理を進める。
  • ファイルの拡張子を取得し、HEIC 以外であれば Discord に通知する。

動作の流れ

  1. iPhoneでショートカットを実行し、Raspberry Pi にファイルをアップロード
  2. Pythonスクリプトが media/iPhonefld を監視
  3. 新しいファイルが追加されたら、media/savefld に移動
  4. HEIC以外のファイルなら Discord に通知

まとめ

このスクリプトを使うことで、iPhone から Raspberry Pi を経由して HDD に自動保存できる環境を構築できる。フォルダ監視を活用することで、手間なくデータを整理できるようになる。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?