iCloudの画像整理バッチ (1)iniファイルにローカル設定を書こう

# iCloudの画像整理バッチ (1)iniファイルにローカル設定を書こう

## 経緯・理由

- [PCのCドライブのとき](https://qiita.com/urahito_solution/items/c37a11ce48291d34d589)のように、iCloudもゲームのスクショ画像などで埋まり始めた
- ただ、正直なところ、お気に入りの画像以外はそんなに見ない
- 時々iOSアプリのWorkflowで簡易的にzipファイルを作って転送させようと試みるも、zip化に失敗して闇へと消えていく画像が多数
- 「せめてローカルのDドライブにあれば十分だな……」ということで、今回のバッチ制作にとりかかることに
	- これまでは、いろいろ詰め込んで読みにくかったので、機能ごとに分割して連載します

## 目的・実装予定の機能

### 目的

- iCloudの同期フォルダはCドライブにあるので、Dドライブに作成済みのアーカイブフォルダへ移動する
- 移動の際、zipファイルとして保管する
- また、zipファイルの中身のサムネイルとして、GIFアニメーションを同時に作成する
- ログはcsvファイルに書き出す（処理のエラー等はlogging等を検討、選定中）[^note2]

### 機能

目次用記事を立てました→[こちら](https://qiita.com/urahito_solution/private/1af6c7543f2b95983fd5)

＜＜ 最初の記事 | ＜ 前の連載記事 | 次の連載記事 ＞ [^note20180312]

（※免責：上記の順番は記事の順番とは一致しない可能性が高いです。あらかじめご了承下さい）

[^note20180312]: Qiita運営さん、[Qiitadonで話した連載機能](https://qiitadon.com/@urahito_solution/99568199423313637)のページングの案なんですがいかがでしょう？ここでは一旦リンクのMarkdownを書きますが。
[^note2]: クラウドロギングサービスのライブラリとloggingとの切り替えがしたいですね

## 今回の機能の解説

- iniファイルという、簡易的な、テキストベースの設定ファイルを利用する
	- xmlファイルなら細かい設定も可能だが、2つのキーで1つの値を取得するだけならこれでも良い
- iniファイルの読み込みだけなら、通常のファイル読み込みでも可
	- 値の呼び出しを可能にするには`configparser`モジュールを利用する

## ソースコード

### 【準備】iniファイルの中身（執筆時点）

```ini:for-iCLoud-template.ini
[settings]
input=C:/Users/**your_user_name**/Pictures/iCloud Photos/Downloads
output=D:/ピクチャ/iCloudバックアップ
size_mb=500

[picture]
backup=backup
gif=gif
dulation_ms=500
thumb_px=750

[log]
logging=log/log/
csv=log/csv/

[API]
rollbar=xxxxxxxx （配布分は空欄の予定）
```

#### 解説

- `[]`内が「セクション」そこに属するブロックの各行が「オプション」です
- input側のiCloudフォルダは、ユーザー名(PC名)を置き換えれば、標準では大体このパスになるはずです
- mainメソッドの解説で書きますが、`os.path`だと空白パスに弱いです（たしか）[^question]が、`pathlib`モジュールはこの問題をカバーしてくれます
- outputは自由に設定して問題ないと思います
- [Rollbar](https://rollbar.com/)というloggingサービスを使おうと思っています
	- （補足）[[APIのトークンをコードに書いている人へ - Qiita](https://qiita.com/Sh1ma/items/390a0df84243058b5cc3)]
	- iniファイルにAPIトークンなんかも書けますが、上記の記事のように環境変数や、記入したiniファイルを`.gitignore`に入れるなどしないと不正アクセスの元なので要注意
	- 表向きにはloggingモジュールで取れるようにしておこうと思います。両方をラップするクラスが必要そうなので準備します。

→ [GitHub](https://github.com/urahito/python_proj/blob/master/file_oper/iCloud/for-iCloud-template.ini)に設定ファイルのテンプレートを公開中

[^question]: ファイルのクロールあたりで空白含むパスが拾えなかった記憶があるんですよねえ。単に文字列の判定の話だったかもしれないです

### 【入力】iniファイルからの読み込みメソッド

```Python:get_ini_data
# iniファイルから色々読み込む 
def get_ini_data(path_obj): 
	ini_file = configparser.SafeConfigParser() 

	with path_obj.open('r', encoding=file_attr.get_enc('r')) as ini_file_obj:		 
		ini_file.read_file(ini_file_obj) 

	return ini_file 
```

#### 解説

- **configparserモジュールで、iniファイルを読み込む（重要）**
- 今回も、パスの扱いがやりやすいpathlibモジュールを導入
- with構文で、読み出し部分のみの扱いにできる
	- `file_attr.get_enc('r')`は[以前作ったもの](https://qiita.com/urahito_solution/items/f6a15db7514057982b41#%E3%83%AF%E3%83%B3%E3%83%A9%E3%82%A4%E3%83%8A%E3%83%BC%E3%81%AA%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%BE%E3%82%8F%E3%82%8A)をファイル管理用のクラスに流用
	- 詳細は次回～次々回あたりに
- あとは、読み出しした中身のオブジェクトを返り値にすればOK


### 【出力】iniファイルの中身の取り出し方(mainメソッド)

```Python:main
	# 古いファイルを特定する(1年以上前なら1GBまで) 
	input_dir = Path(ini_data['settings']['input']) 
	output_dir = Path(ini_data['settings']['output']) 
```

#### 解説

- iniファイルのデータの取り出し方は以下の２種類があるそうですが、自分は後者を選びました
	- `ini_data.get(section_name, option_name)`
	- `ini_data[section_name][option_name]`
- `os.path`では、空白入り(特にユーザーフォルダ系)のパスを取得するのに失敗します[^question]
	- 代わりに`from pathlib import Path`を利用すると、上手いことパスを取得してくれます
	
## まとめ

- 最終的にバッチ完了までの連載を行います
- iniファイルは空白入りの文字列もOK
	- ただし、パスはpathlibを使った方が安定して使える

### GitHubリンク

- [iCloud - urahito@GitHub](https://github.com/urahito/python_proj/tree/master/file_oper/iCloud)

＜＜ 最初の記事 | ＜ 前の連載記事 | 次の連載記事 ＞ [^note20180312]