PythonによるFTPスクリプト

ローカル環境で更新されたファイルをFTPサイトにアップロードするPythonスクリプト

レンタルサーバーにファイルをアップロードする為にアプリを探したが、色々試すのも面倒なので 勉強がてらPythonでスクリプトを作成してみた。

処理の流れ

ポイントはサイトの更新日時を取得すると、9時間のずれがあり、補正が必要になる事。
ソースはこちら

# -*- coding: utf-8 -*-
import ftplib
import os
import datetime

''' サブディレクトリ毎サイトへUPLOARD '''
def ftp_upload():
    # ホスト設定
    host = "***"
    usr = "***"
    passwd = "***"
    # FTP 接続
    try:
        ftp = ftplib.FTP(host,usr,passwd)
        print("ftp connected")
    except Exception as e:
        print(e.args)
        ftp.quit()
        return False

    # サイトのファイル名を取得
    ftp_mlsd = ftp.mlsd()
    ftp_files = {}
    ftp_dirs = {}
    ftp_dir_files = {}

    # ディレクトリをリストに格納
    for fname,opt in ftp_mlsd:
        if opt['type'] == 'dir':
            ftp_dirs[fname] = opt
        else:
            ftp_files[fname] = opt
    print("directory get")

    # ディレクトリ内の一覧を取得
    for file in os.listdir():

        # ファイルの場合はサイトへアップロード
        if os.path.isfile(file):

            # site に同じファイルがない場合か、更新されているファイル
            mod_flg = False
            if file in ftp_files:
                # local file の更新時間
                t = os.path.getmtime(file)
                mtime = datetime.datetime.fromtimestamp(t)
                #mtime = "{0:%Y%m%d%H%M%S}".format(d)

                # site file の更新時間
                ftp_str = ftp_files[file]['modify']
                ftp_mtime = datetime.datetime.strptime(ftp_str,'%Y%m%d%H%M%S')
                ftp_mtime += datetime.timedelta(hours=9)
                print("file:{0},local:{1},site:{2}".format(file,mtime,ftp_mtime))

                if ftp_mtime < mtime:
                    mod_flg = True

            if file not in ftp_files or mod_flg:
                base,ext = os.path.splitext(file)

                # php,css,html のみアップロード
                if ext == ".php" or ext == ".css" or ext == "html":

                    # バイナリモードでファイルを開く
                    f = open(file,"rb")
                    str = "STOR " + file

                    # storlines でファイルをアップロード
                    try:
                        ftp.storlines(str,f)
                        print("{0}:uploaded".format(file))
                    except Exceptiojn as e:
                        print(e.arfgs)
                        ftp.quit()
                        return False

        # ディレクトリの場合はディレクトリ内のファイルをアップロード
        if os.path.isdir(file) and file != "siteenv" and file !="__pycache__":

            # ディレクトリ名を指定
            dir_name = file

            # サイトにディレクトリがない場合ディレクトリを作成
            new_dir = False
            if dir_name not in ftp_dirs:
                ftp.mkd(dir_name)
                new_dir = True
            else:

                # site 側のファイル情報を取得
                ftp_mlist = ftp.mlsd(dir_name)
                for ffile,opt in ftp_mlist:
                    ftp_dir_files[ffile] = opt

            # ディレクトリ内のファイルの一覧を取得
            for dfile in os.listdir(dir_name):

                # パスを作成
                file_path = dir_name + "/" + dfile

                # ファイルであればサイトにアップロード
                if os.path.isfile(file_path):

                    # site に同じファイルがない場合か、更新されているファイル
                    mod_flg = False
                    if dfile in ftp_dir_files:

                        # local file の更新時間
                        t = os.path.getmtime(file_path)
                        mtime = datetime.datetime.fromtimestamp(t)
                        #mtime = "{0:%Y%m%d%H%M%S}".format(d)

                        # site file の更新時間
                        ftp_str = ftp_dir_files[dfile]['modify']
                        ftp_mtime = datetime.datetime.strptime(ftp_str,'%Y%m%d%H%M%S')
                        ftp_mtime += datetime.timedelta(hours=9)
                        print("file:{0},local:{1},site:{2}".format(file_path,mtime,ftp_mtime))

                        if ftp_mtime < mtime:
                            mod_flg = True

                    if dfile not in ftp_dir_files or mod_flg:
                        base,ext = os.path.splitext(file_path)

                        # .DS_Store や拡張子のないファイル以外サイトへアップロード
                        if base != ".DS_Store" and ext != "":
                            f = open(file_path,"rb")
                            str = "STOR " + file_path

                            # storlines でファイルをアップロード
                            try:
                                ftp.storlines(str,f)
                                print("{0}:uploaded".format(file_path))
                            except Exceptiojn as e:
                                print(e.arfgs)
                                ftp.quit()
                                return False

            # ディレクトリ内のファイル情報をクリア
            ftp_dir_files = {}

    # 転送終了したら、FTP接続を解除
    ftp.quit()
    return True

if __name__ == '__main__':
    ftp_upload()