MVC (Model-View-Controller) パターンに準じた構成を採用しているが、小規模アプリのため簡易的な構成となっている。
- Model (Logic):
core.py,mail_client.py- メール処理のコアロジック - View/Controller (GUI):
gui.py- Tkinterによる画面表示とイベントハンドリング - Configuration:
config.yaml- 設定データ - Entry Point:
main.py- アプリケーション起動エントリ、デーモン管理機能
main.py: アプリケーションの起動スクリプト。コマンドライン引数の解析とGUI/デーモンモードの切り替え、デーモンプロセスの管理(起動・停止)、単一インスタンス制御を行う。gui.py: Tkinterを使用したGUIアプリケーションクラスMailConsolidatorAppとIPCServerを定義。Windows環境ではシステムトレイ機能も統合。tray_icon.py: Windows環境でのシステムトレイアイコン管理クラスSystemTrayIconを定義(Windows専用)。core.py: メール集約の一括処理ロジックrun_batch、プロセス管理用のPIDManagerクラス、および設定ファイルパス管理用のヘルパー関数(get_default_config_path,migrate_config_if_needed)を定義。mail_client.py: メールサーバとの通信を行うクラス群 (Pop3Source,ImapSource,ImapDestination)。crypto_helper.py: パスワードの暗号化・復号化を行うユーティリティ。config.yaml: ユーザー設定ファイル(YAML形式)。プラットフォームに応じた適切な場所に保存される。
- 初期化: 設定ファイルの読み込み、ウィジェットの生成、ログハンドラの設定。
- タブ構成:
- 実行パネル: 実行制御とログ・ステータス表示。
- 移動先設定: 転送先IMAPサーバの設定フォーム。
- 取得元設定: 取得元サーバのリストと編集フォーム。
__init__():- IPCサーバーを起動し、PIDファイルにプロセスIDとポート番号を書き込む。
- システムトレイアイコンを初期化(Windows環境)。
toggle_background_task():- 定期実行の開始・停止を切り替える。
- 開始時: 別スレッド (
threading.Thread) を作成し、_background_loopを実行。ボタン名を「定期実行を停止」に変更。 - 停止時:
stop_eventをセットし、ボタンを無効化(「停止処理中...」)。スレッド終了後にUIを初期状態に戻す。
_background_loop(interval):- 指定間隔で
run_batchを呼び出すループ処理。 stop_eventを監視し、安全にループを脱出する。finallyブロックで_reset_ui_stateを呼び出し、UIの整合性を保つ。
- 指定間隔で
on_closing():- ウィンドウの閉じるボタン(×)が押されたときに呼ばれる。
- カスタムダイアログを表示し、「アプリを終了」「バックグラウンド常駐」「キャンセル」から選択させる。
quit_app():- アプリケーションを完全に終了する。
- PIDファイルを削除し、システムトレイアイコンを停止する。
update_source():- リストボックスで選択された設定を、入力フォームの内容で更新する。
- 注意点:
Listboxのexportselection=Falseを設定し、フォーム編集時に選択が外れないようにしている。 - 選択がない場合は警告メッセージを表示する。
on_interval_changed(event):- 実行間隔入力フィールドのフォーカスアウトイベントで呼び出される。
- 入力値を検証し、正の整数であれば設定ファイルに即座に保存する。
quit_app():- アプリケーション終了時のクリーンアップ処理を強化。
- バックグラウンドスレッドの終了待機、IPCサーバーの停止、PIDファイルの削除、トレイアイコンの停止を順次行う。
- PyInstallerの一時ディレクトリ削除エラーを防ぐため、リソース解放を確実に行う。
- 目的: プロセス間通信(IPC)サーバーとして動作し、他のプロセスからのコマンドを受信する。
- 実装:
- ローカルホスト(127.0.0.1)でソケットサーバーを起動。
- ポート番号は自動割り当て(0を指定)。
- 別スレッドでリスニングループを実行。
- コマンド処理:
SHOW_WINDOW:app.show_window()を呼び出してGUIを前面に表示。
- 設定に基づき、全ての取得元ソースに対して処理を反復する。
stop_eventがセットされた場合、処理を中断する。callbackを通じてGUIにステータス(取得完了、保存中、削除中など)を通知する。
- 単一のソースに対する処理フロー:
- サーバ接続 (POP3/IMAP)。
- メッセージ一覧取得(IMAPは未読のみ)。
- 目的: プロセスID(PID)とIPCポート番号の管理。
- 静的メソッド:
write_pid(port): PIDとポート番号をファイルに書き込む(形式:<PID>:<PORT>)。read_pid_info(): PIDファイルから(pid, port)のタプルを読み込む。remove_pid(): PIDファイルを削除する。is_process_running(pid): 指定されたPIDのプロセスが実行中かチェック。send_show_command(port): 指定されたポートにSHOW_WINDOWコマンドを送信(IPCクライアント機能)。
- 目的: プラットフォームに応じた適切な設定ファイルパスを返す。
- パス:
- Windows:
%APPDATA%\MailConsolidator\config.yaml - Unix系:
~/.config/MailConsolidator/config.yaml
- Windows:
- 動作: 必要に応じてディレクトリを自動作成。
- 目的: 起動フォルダに古い設定ファイルがある場合、新しい場所にコピーする。
- 動作:
- 新しい場所に設定ファイルが既に存在する場合は何もしない。
- 起動フォルダに
config.yamlがある場合、shutil.copy2で新しい場所にコピー。 - 古いファイルは削除されない(ユーザーが手動で削除可能)。
get_messages(): 全メッセージを取得する(POP3の仕様上、未読管理はクライアント側で行う必要があるが、本仕様では全件取得とし、重複排除は行わないためdelete_after_move=True推奨)。
create_ssl_context():certifiパッケージを使用して、信頼できるCA証明書バンドルを含むSSLコンテキストを作成する。- PyInstallerでexe化した環境でもSSL接続を正常に動作させるために使用。
get_messages():SEARCH UNSEENコマンドを使用し、未読メールのみを取得する。mark_as_read(uid): 指定されたUIDのメールに\Seenフラグを付与する。
- 終了後、
remove_pid_file()でPIDファイルを削除。
- エラーハンドリング:
psutil.NoSuchProcess: プロセスが見つからない場合、PIDファイルを削除。psutil.AccessDenied: アクセス拒否エラーを表示。- その他の例外: エラーメッセージを表示。
- クラス:
SystemTrayIcon(Windows専用) - 機能:
- アプリケーションのシステムトレイ常駐化。
- メニュー操作によるウィンドウの表示/非表示、バックグラウンド処理の切り替え、アプリ終了。
- アイコンクリックでのウィンドウ表示。
- GUI連携:
MailConsolidatorAppと連携し、GUIの状態(表示/非表示)やバックグラウンド処理の状態を同期。- ウィンドウの「閉じる」操作は
on_closing()メソッドで処理され、ダイアログで選択可能。
- 単一インスタンス制御:
- デフォルト起動時、
PIDManager.read_pid_info()で既存インスタンスをチェック。 - 既存プロセスが実行中の場合、
PIDManager.send_show_command(port)でIPCコマンドを送信。 - IPC通信成功時は新しいプロセスを起動せずに終了。
- IPC通信失敗時または既存プロセスが存在しない場合は新しいインスタンスを起動。
- デフォルト起動時、
- 起動モード:
- デフォルト: GUIをバックグラウンドで起動(
DETACHED_PROCESS)。システムトレイに常駐。既存インスタンスがある場合はそのGUIを表示。 - フォアグラウンド (
-v): GUIをフォアグラウンドで起動し、コンソールにログを表示。 - デーモン (
-d): GUIなしでバックグラウンド実行。
- デフォルト: GUIをバックグラウンドで起動(
- PyInstaller対応:
sys.frozen属性をチェックし、exe化された環境とスクリプト実行環境の両方で正しくサブプロセスを起動するように分岐。
- ログ制御:
-lオプションにより、ログファイルへの出力を制御。指定がない場合はファイル出力を行わない。
- PyInstaller一時ディレクトリ対策:
sys.frozen環境下では、PYINSTALLER_SUPPRESS_CLEANUP_ERRORS環境変数を設定し、終了時の不要なエラーダイアログを抑制する。
- バックグラウンド実行: コマンドライン引数
-dにより、GUIなしでバックグラウンドプロセスとして起動可能とする。 - デーモン停止: コマンドライン引数
-kにより、実行中のバックグラウンドプロセスを停止可能とする。 - プロセス追跡: PIDファイルを使用してバックグラウンドプロセスを追跡・管理する。
- 安全な終了: デーモン停止時は、まず正常終了シグナル(SIGTERM)を送信し、応答がない場合は強制終了(SIGKILL)を行う。
-d,--daemon: デーモンモードで起動(バックグラウンド実行)。-k,--kill: 実行中のデーモンを停止して即座に終了。-c,--config: 設定ファイルのパスを指定(デフォルト: Windows:%APPDATA%\MailConsolidator\config.yaml, Unix系:~/.config/MailConsolidator/config.yaml)。-v,--verbose: 詳細ログをコンソールに表示。-l,--log-file: ログファイルのパスを指定。
- パスワードの暗号化・復号化を行う
PasswordCryptoクラスを提供。 - 設定ファイル内のパスワードは暗号化して保存される。
interval: 3 # 実行間隔(分)
destination: # 転送先設定
host: str
port: int
user: str
password: str # 暗号化済み
ssl: bool
folder: str
sources: # 取得元リスト
- protocol: str # 'imap' or 'pop3'
host: str
port: int
user: str
password: str # 暗号化済み
ssl: bool
folder: str
delete_after_move: bool- PyInstaller対応: exe化のためのspecファイル作成、frozen環境対応。
- システムトレイ実装: Windows環境でのタスクトレイ常駐機能、メニュー操作の実装。
- 起動フロー改善: デフォルトでのバックグラウンドGUI起動、ログファイル制御オプション追加。
- デーモン管理機能追加:
-kオプションによるバックグラウンドデーモンの停止機能を追加。PIDファイルを使用したプロセス追跡・管理を実装。 - GUI更新不具合修正:
Listboxのexportselection=False設定により、編集時の選択解除を防止。 - バックグラウンド実行改善: 定期実行の開始/停止トグルボタンの実装、UIブロックの解消、停止処理中のフィードバック追加。
- メール取得ロジック変更: IMAP取得時に未読メールのみを対象とするよう変更。
- 保持ポリシー変更:
delete_after_move=Falseの場合、ステータスモニターに履歴を残すよう変更。 - 設定ファイル保存場所変更: 起動フォルダからプラットフォーム固有の適切な場所(Windows:
%APPDATA%\MailConsolidator, Unix系:~/.config/MailConsolidator)に変更。既存設定の自動移行機能を追加。 - SSL証明書対応:
certifiを導入し、PyInstaller環境でのSSL接続エラーを修正。 - 終了処理改善: リソース解放(IPC、スレッド、トレイ)を強化し、一時ディレクトリ削除エラーを抑制。
- 設定自動保存: 実行間隔の変更を即座に保存する機能を追加。
- Windows インストーラー: Inno Setup を使用したインストーラーを作成。PyInstaller を one-folder 形式に変更し、SSL 証明書検証を有効化。