この記事では、WordPressのプラグイン、BackWPupのバックアップデータをpythonでローカルに定期的にダウンロードする方法を解説します。
プログラムの流れは、FTPでバックアップファイルがあるサーバーにログインし、バックアップファイルをローカルに保存するというものです。
目次の流れで実装しました。
不明点などあれば、コメントしていただければと思います。
※python version : 3.11.7
設定ファイル作成
以下の設定を書いています。ファイル名はconfig.pyの想定でプログラムを書いています。
- FPT接続情報
- FTPサーバーのバックアップファイル保存先
- ローカルのバックアップファイル保存先
- ログファイルの保存先
- バックアップファイルの保存世代数
# ログイン情報
FTP_HOST_NAME = 'your ftp host name'
FTP_USER_ID = 'ftp user id'
FTP_PASSWORD = 'ftp password'
# FTPサーバーのバックアップ保存ディレクトリ
BACKUP_DIR = '/ftp/backupfile/saved/path'
# ローカルの保存先
SAVE_TO = '/local/path/to/save/backupfile'
# ログファイルの設定
LOG_FOLDER = '/local/path/to/save/logfile'
LOG_FILE_NAME = 'your log file name' # bk_download.logとか
# バックアップ保存世代数(例えば3にすると、ローカルに最大3つのバックアップファイルが保存される。)
N_GEN = 3
私は、スターサーバーを使っているので、スターサーバーを例に「FTP接続情報」、「FTPサーバーのバックアップファイル保存先」の確認方法を解説します。他の項目はご自身で設定してください。
ちなみに、スターサーバーは安くておすすめです。
FTP接続情報
まずはFTP_HOST_NAMEです。スターサーバーにログインし、「サーバー管理ツール > サーバー情報」を表示します。そこのホスト名がFTP_HOST_NAMEの値です。
次に、FTP_USER_ID、FTP_USER_PASSWORDです。同じく「サーバー管理ツール」から、「FTPアカウント設定」を表示し、対象のドメインを選択します。
アカウント名がFTP_USER_IDです。そのアカウントに対するパスワードがFTP_USER_PASSWORDです。パスワードは表示されないので、忘れた場合は、FTPアカウントを追加するなどして、パスワードを確認する必要があります。
FTPサーバーのアックアップ保存ディレクトリ(BACKUP_DIR)
wordpressにログインし、BackWPupの「バックアップ」をクリックします。その画面にある「フォルダー」列がバックアップファイルの保存先になっています。例えばこれが「/a/b/c/d/e」とします。
ローカルにダウンロードする際の、FTPアカウント一覧の「編集」メニューからそのアカウントのFTPサーバーのルートパスを確認します。例えばこれが「/a/b/c」とします。
この場合、BACKUP_DIRは「/d/e」となります。つまり、バックアップファイル保存先のパスの、FTPサーバーのルートパス以下がBACKUP_DIRになります。
バックアップファイルダウンロード
以下が先ほどの設定ファイルをもとに、FTPサーバーからバックアップファイルをダウンロードするプログラムです。
import logging
import glob
import os
import ftplib
from config import *
class BackupDownloader:
def __init__(self, ftp_host_name, ftp_user_id, ftp_passwd,
backup_dir, save_to, n_gen, log_folder, log_file_name):
self.ftp_host_name = ftp_host_name
self.ftp_user_id = ftp_user_id
self.ftp_passwd = ftp_passwd
self.backup_dir = backup_dir
self.save_to = save_to
self.n_gen = n_gen
self._init_logger(log_folder, log_file_name)
def download(self):
"""
バックアップファイルをダウンロード
"""
ftp = None
try:
ftp = ftplib.FTP(self.ftp_host_name)
ftp.login(user=self.ftp_user_id, passwd=self.ftp_passwd)
ftp.cwd(self.backup_dir)
for bk_file_name in ftp.nlst('*.zip'):
# 既に存在する場合はSKIP
save_path = os.path.join(SAVE_TO, bk_file_name)
if os.path.exists(save_path):
continue
# ない場合だけdownload
with open(save_path, 'wb') as f:
ftp.retrbinary(f'RETR {bk_file_name}', f.write)
self.logger.info(f'file donwload successful: {bk_file_name}')
except ftplib.all_errors as e:
import traceback
self.logger.error("An exception occurred: %s", str(e))
self.logger.error(traceback.format_exc())
finally:
if ftp is not None:
ftp.quit()
self._clean()
def _clean(self):
"""
バックアップファイル数をN_GEN以下にする
"""
bk_file_path_list = glob.glob(os.path.join(self.save_to, '*.zip'))
n_del = len(bk_file_path_list) - self.n_gen
# 削除なし
if n_del <= 0:
return
# 古いbkファイルを削除
bk_file_path_list = sorted(bk_file_path_list)
for f in bk_file_path_list[:n_del]:
try:
os.remove(f)
file_name = os.path.basename(f)
self.logger.info(f'file delete successful: {file_name}')
except Exception as e:
import traceback
self.logger.error("An exception occurred: %s", str(e))
self.logger.error(traceback.format_exc())
def _init_logger(self, log_folder, log_file_name):
"""
loggerの初期化
"""
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s [%(levelname)s]: %(message)s')
handler = logging.FileHandler(
filename=os.path.join(log_folder, log_file_name), encoding='utf-8')
handler.setFormatter(formatter)
logger.addHandler(handler)
self.logger = logger
if __name__ == '__main__':
bk_downloader = BackupDownloader(
FTP_HOST_NAME, FTP_USER_ID, FTP_PASSWORD, BACKUP_DIR, SAVE_TO, N_GEN,
LOG_FOLDER, LOG_FILE_NAME)
bk_downloader.download()
順番に解説していきます。
6行目で前節で書いた設定内容を読み込んでいます。
21行目のdownloadメソッドの中で、FTPサーバーにログインし、バックアップファイルをダウンロードしています。バックアップファイルの拡張子は「zip」を想定しているので、他の拡張子の場合はそこを書き換える必要があります。(設定ファイルに外だししてもいいですね。)
既にバックアップファイルがローカルに存在する場合はスキップし、ない場合だけローカルにダウンロードしています。49行目で_cleanメソッドを呼び出して、ローカルのバックアップファイル数をN_GEN以下にしています。(設定ファイルで設定した、ローカルのバックアップファイル世代数)
74行目の_init_loggerでは、バックアップファイルダウンロードのログを出力するための設定をしています。このプログラムは毎日定期実行する想定で、何かのエラーが原因で、ダウンロードできなかった時の原因分析のためにロガーの設定をしました。self.logger.~と書かれている箇所が、ログをファイルに出力しているところです。
89行目以下で、バックアップファイルのダウンロードを実行するインスタンスを作成し、実際にダウンロードしています。
定期実行する
先ほどのプログラムを毎日手動で実行するのは面倒くさいので、定期実行します。
私は、linuxでcondaの仮想環境を使っているので、condaの設定、condaの環境activate、先ほどのpythonファイルの実行を行うシェルスクリプトを用意しました。
#!/bin/sh
__conda_setup="$('/home/sr-exp/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__conda_setup"
else
if [ -f "/home/sr-exp/anaconda3/etc/profile.d/conda.sh" ]; then
. "/home/sr-exp/anaconda3/etc/profile.d/conda.sh"
else
export PATH="/home/sr-exp/anaconda3/bin:$PATH"
fi
fi
unset __conda_setup
conda activate Download_BackWPup
python /home/sr-exp/sr-experience/doc/download_BackWPup_to_local/run.py
用意したシェルスクリプトをcronで実行するように設定します。以下のコマンドでcronの設定ファイルを開きます。
crontab -e
開かれたファイルに、いつ、何をするかを書きます。私は毎日4時に、先ほどのシェルスクリプトrun.shを実行する設定を書きました。
# 毎日 4:00に実行
0 4 * * * /home/sr-exp/sr-experience/doc/download_BackWPup_to_local/run.sh
動作確認
数日後にバックアップのログを見てみると、毎日4時に実行されていることがわかります。
2024-03-23 18:28:30,059 [INFO]: file donwload successful: 2024-03-23_04-24-02_3DI55SUG01.zip
2024-03-23 18:28:36,901 [INFO]: file donwload successful: 2024-03-22_03-22-38_7HI55SWT01.zip
2024-03-23 18:28:42,371 [INFO]: file donwload successful: 2024-03-11_03-40-13_Z7I55SQU01.zip
2024-03-23 18:28:48,655 [INFO]: file donwload successful: 2024-03-10_03-25-53_MLI55SXJ01.zip
2024-03-23 18:28:55,604 [INFO]: file donwload successful: 2024-03-09_03-13-41_YXI55SVZ01.zip
2024-03-23 18:28:55,622 [INFO]: file delete successful: 2024-03-09_03-13-41_YXI55SVZ01.zip
2024-03-23 18:28:55,630 [INFO]: file delete successful: 2024-03-10_03-25-53_MLI55SXJ01.zip
2024-03-23 18:28:55,637 [INFO]: file delete successful: 2024-03-11_03-40-13_Z7I55SQU01.zip
2024-03-23 18:28:55,638 [INFO]: file delete successful: 2024-03-12_03-37-19_FLI55SV501.zip
2024-03-23 18:28:55,639 [INFO]: file delete successful: 2024-03-13_03-10-21_FHI55SSW01.zip
2024-03-24 04:00:08,061 [INFO]: file donwload successful: 2024-03-24_03-27-49_7XI55SV201.zip
2024-03-24 04:00:08,080 [INFO]: file delete successful: 2024-03-14_05-04-13_LPI55SXB01.zip
バックアップファイルもダウンロードできていました。大成功です!!
コメント