【Python】ダウンロードフォルダから本日分のファイルをDropbox内のフォルダに一括移動

# ダウンロードフォルダから本日の日付のファイルをDropboxの指定の日付フォルダに移動するには…

## 目次

[I.  必要なPythonモジュールのimport](##-I.-必要なPythonモジュールのimport)
[II.  Pathの定義](##-II.-Pathの定義)
[III.  実際のpythonコード](##-III.-実際のpythonコード)
[IV.  まとめ](##-IV.-まとめ)

---
　メールが多すぎるので、M1 MacにThunderboltを導入してみたものの、Sparkのようにスペースキーで添付のファイルがプレビューできません。仕方がないので、いちいちダウンロードフォルダにダウンロードしてから見ることに…。しかし、それも手間なので、ダウンロードした添付ファイルを見ないという矛盾が生じてしまっています。

　メール内のファイルはDropboxの日付フォルダに入れておけば、後で「あのメールの添付ファイルはどこだっけ？」となった時に便利ではないかと思い、jupyterでコードを書いてみました。

```
    手順:
     1． 予めDropbox内の特定のフォルダには日付フォルダを作成しておく
     2． ダウンロードフォルダ内のファイルの日付【Unix時間】を取得
     3． 今日の日付【datetime.datetime】と比較
     4． 一致していたらDropboxの本日の日付フォルダに移動
```


　前半で健忘録を兼ねて、個々のコードの解説をして、最後にまとめを付けておきます。

---

## I. 必要なPythonモジュールのimport
- os
- shutil
- datetime

## II. Pathの定義
- Downloadフォルダ：`download_folder = '/Users/（ユーザー名）/Downloads'`
- Dropboxフォルダ：`destination_folder = '/Users/（ユーザー名）/Dropbox/2022保存庫'`

## III. 実際のpythonコード

- まずは必要なモジュールをインポートします。
- もし、存在(exist)しないと言われたら、contaかpipでインストールします。
    - `conda install datetime`とか`pip install datetime`とかです。
- 私の場合は、miniforge3という仮想環境で使っているので、`conda activate （仮想環境名）`でアクティブにしてから、上記コマンドを打っています。



```Python
import shutil
import os
import datetime
```
　特に難しいことはありません。エラーが出たら、上記の対処を。

---
- Pathを決めておきます。（自分の好きなところにして大丈夫です。）
- Macな方はoptionキーを押しながら目的のフォルダを右クリックすると、コンテキストメニュー内にフォルダのPathを確認してコピペ出来ます。

```Python
download_folder = '/Users/（ユーザー名）/Downloads'
destination_folder = '/Users/（ユーザー名）/Dropbox/2022保存庫'
```
　ここでは、Dropboxフォルダ（ユーザーフォルダの直下にしています）に"2022保存庫"というフォルダを作成してあります。

---
- 現在時刻を取得して、本日の日付の入ったフォルダを作成します。

```Python
now = datetime.datetime.now()
now2 = "{0:%Y%m%d}".format(now)
des = os.path.join(destination_folder, now2)
os.makedirs(des, exist_ok=True)
```

#### `● datetime.datetime.now()`
`now = datetime.datetime.now()`で現在の日時を取得して`変数now`に代入しています。
 ＞ 2022-05-17 11:20:05.785963
と、まあまあ、長い数字になっています。

#### `● {0:%Y%m%d}".format(now)`
`now2 = "{0:%Y%m%d}".format(now)`でフォルダ名用に今日の日付の文字列を成形して、`変数now`に代入します。
Pythonの便利なところは、文字列を成形出来るところです。いろいろ方法はあると思いますので、ググって見てもらえればと思います。
ここでは、<b>{</b><i>%とかを含む文字列</i><b>}.format()</b>を使って`now変数`に代入された現在の日時を成形して`now2変数`に代入しています。
- `0:`は`now変数`の文字列のはじめから
- `%Y`は西暦4桁（ちなみに、`%y`と小文字にすると、西暦2桁）
- `%m`は月、`%d`は日

#### `● os.path.join(destination_folder, now2)`
`des = os.path.join(destination_folder, now2)`で目的フォルダまでの絶対Pathを作成して、`変数des`に代入します。
`os.path.join(A, B)`の形で、<b>文字列A</b>と<b>文字列B</b>を繋げます。

#### `● os.makedirs(des, exist_ok=True)`
`os.makedirs(des, exist_ok=True)`で目的フォルダ（`des`）に日付の入った名前でフォルダを作成します。
※`mkdir`というのもあるのですが、重複フォルダがあるとエラーが出るので、今回はこちらを採用しています。

---
```Python
now3 = "{0:%Y-%m-%d}".format(now)

list1 = os.listdir(download_folder)

os.chdir(download_folder)

for i in list1:
    day = os.path.getmtime(i)
    dt = datetime.datetime.fromtimestamp(day)
    dt = dt.strftime('%Y-%m-%d')
    if dt == now3:
        shutil.copy(i,des)
        print(i)
```

#### `● "{0:%Y-%m-%d}".format(now)`
このあとの`os.path.getmtime()`で取得するファイルの変更日時と合わせるために形を成形します。
`now3 = "{0:%Y-%m-%d}".format(now)`で、`変数now2`とはまた違った間に"-（ハイフン）"の入った形にします。

#### `● os.listdir(download_folder)`
<b>`os.listdir(フォルダPath)`</b>はとても便利です。
フォルダ内のファイル名をすべて取得してくれます。ここでは<b>list1</b>に目的フォルダにあるすべてのファイル名が入っています。
ファイル名の数は`len()`を使って数えられます。ここでは124個のファイルが存在しているようです。
```Python
print(len(list1))

>> 124
```

#### `● os.chdir(download_folder)`
ここではこの後のPathの処理がめんどくさかったので、`chdir（）`（チェンジ・ディレクトリ命令）で<b>download_folder</b>フォルダに移動してみました。

#### `● for i in list1:`
<b>list1</b>の中から一つずつ`変数i`にデータを取り出して、以下の処理をしていきます。

#### `● os.path.getmtime(i)`
ファイルの日付を取得する方法にはいくつかあって、`os.path.getmtime()`、`os.path.getctime()`とかがあります。`m`と`c`の違いなのですが、私は`m`(modefy)、`c`（create）と覚えています。間違っていたらごめんなさい。

ここで得られる日付なのですが、UNIX時間といって、1970年1月1日（だったかな）を基準とした経過時間で表されています。
```Python
day

>> 1652357677.9692905
```

そこで日付が分かるように変更したいです。

#### `● .fromtimestamp(day)`

`UNIX時間`（timestamp）から、`datetime型`への変換は、<b>.fromtimestamp()</b> で行います。
すると以下のようにデータが得られます。
```Python
dt = datetime.datetime.fromtimestamp(day)
dt

>> datetime.datetime(2022, 5, 12, 21, 14, 37, 969290)
```
日付+時間から文字列への変換には<b>strftime()</b>を使います。
（逆に、文字列から日付+時間への変換には、<b>strptime()</b>を使います。
こちらも`str`（string：文字列）と`time`の間に入っている`f`と`p`の違いになります。
`f`は`from`を連想するので分かりやすいですね。）

今回は`dt = dt.strftime('%Y-%m-%d')`で、'%Y-%m-%d'の形に変形しています。
ここで、始めに行った`now3 = "{0:%Y-%m-%d}".format(now)`が生きてきます。

#### `● if dt == now3:`
'%Y-%m-%d'の形で成形した日付<b>dt</b>と"{0:%Y-%m-%d}".format(now)で成形した日付<b>now3</b>が等しければ...、と`if関数`を用いています。

#### `● shutil.copy(i,des)`
やっとここで、今回のメインである<b>`shutil.copy(A,B)`</b>が出てきました。
<b>Aというファイル</b>を<b>BというPath</b>にコピーしなさい、という命令になります。
同じような関数で、<b>`shutil.move(A,B)`</b>もありますが、今回はDownloadフォルダ内にデータを残して置きたかったので、<b>`shutil.move()</b>ではなく、<b>`shutil.copy()</b>を使っています。

#### `● print(i)`
最後に`if関数`のループ内で、もし条件に合った場合は、copy()と一緒にファイル名を<b>print()</b>する事にしました。 
これは、本日のファイルがなくて出力されなかったのか、プログラムがうまく実行されなかったか分からないので、自分の安心感のために付けてみました。

---
## IV. まとめ
以上で、今回作成したコードになりますが、Qiitaに解説しながら書いてみると、コードを書く以上に時間がかかることが分かりました（笑）。また、時間があるときにはこんなこともしてみたいと思っています。（だいたい、時間のないときにやることが多いのですが...）

以下、コードのまとめになります。（翌日の朝にまとめてやりたい方もいらっしゃると思いますので、「昨日版」というのも付けてあります。）

## Downloadフォルダ内の本日のファイルをDropbox内のフォルダに移動（本日版）
```Python
import shutil
import os
import datetime

download_folder = '/Users/（ユーザー名）/Downloads'
destination_folder = '/Users/（ユーザー名）/Dropbox/2022保存庫'

now = datetime.datetime.now()
now2 = "{0:%Y%m%d}".format(now)
des = os.path.join(destination_folder, now2)
os.makedirs(des, exist_ok=True)

now3 = "{0:%Y-%m-%d}".format(now)

list1 = os.listdir(download_folder)

os.chdir(download_folder)

for i in list1:
    day = os.path.getmtime(i)
    dt = datetime.datetime.fromtimestamp(day)
    dt = dt.strftime('%Y-%m-%d')
    if dt == now3:
        shutil.copy(i,des)
        print(i)

```

## Downloadフォルダ内の「昨日」のファイルをDropbox内のフォルダに移動（昨日版）
```Python
import shutil
import os
import datetime

download_folder = '/Users/（ユーザー名）/Downloads'
destination_folder = '/Users/（ユーザー名）/Dropbox/2022保存庫'

now = datetime.datetime.now()

yesterday = now - datetime.timedelta(1)
yes2 = "{0:%Y%m%d}".format(yesterday)

des = os.path.join(destination_folder, yes2)
os.makedirs(des, exist_ok=True)

yes3 = "{0:%Y-%m-%d}".format(yesterday)

list1 = os.listdir(download_folder)

os.chdir(download_folder)

for i in list1:
    day = os.path.getmtime(i)
    dt = datetime.datetime.fromtimestamp(day)
    dt = dt.strftime('%Y-%m-%d')
    if dt == yes3:
        shutil.copy(i,des)
        print(i)

```