WordPress 테마를 Python으로 압축하고 FTP로 자동 업로드하기

0

WordPress 테마를 관리하는 과정에서 반복적인 작업을 자동화하면 많은 시간을 절약할 수 있습니다. 이 기사에서는 Python을 사용하여 WordPress 테마 파일을 자동으로 압축하고, FTP를 통해 서버에 업로드하는 방법을 설명합니다. 이 과정에서 발생할 수 있는 인코딩 문제와 파일 삭제 문제를 해결하는 방법도 다룹니다.

1. 준비 작업

먼저, 필요한 Python 패키지를 설치합니다. `python-dotenv`와 `ftplib`를 사용하여 환경 변수를 로드하고 FTP 서버에 연결할 것입니다. 또한, 자바스크립트 파일을 압축하기 위해 `execjs`와 `uglify-js`를 설치해야 합니다.

pip install python-dotenv execjs
npm install -g uglify-js

2. 환경 변수 파일 생성

프로젝트 루트 디렉토리에 `.env.development` 파일을 생성하여 FTP 서버 정보와 경로를 설정합니다.

# .env.development 파일 예제

# 테마 경로 설정
SRC_THEME_DIR=wp-content/themes/sample_theme
DEST_THEME_DIR=.py_scripts/dest/sample_theme

# FTP 서버 정보
FTP_HOST=ftp.example.com
FTP_USER=ftp_user
FTP_PASSWORD=ftp_password
REMOTE_THEME_DIR=/www/wp-content/themes/sample_theme

3. 자바스크립트 파일 압축

`execjs`를 사용하여 자바스크립트 파일을 압축하는 Python 클래스를 작성합니다. 인코딩 문제를 해결하기 위해 `utf-8-sig` 인코딩을 사용합니다.

import execjs

class MinifyJS:
    def __init__(self):
        self.context = execjs.get().compile("""
            var uglifyjs = require('uglify-js');
            function minify(js_code) {
                return uglifyjs.minify(js_code).code;
            }
        """)

    def minify_file(self, input_file_path, output_file_path):
        try:
            with open(input_file_path, 'r', encoding='utf-8-sig') as js_file:
                js_content = js_file.read()

            minified_js = self.context.call("minify", js_content)
            with open(output_file_path, 'w', encoding='utf-8') as min_js_file:
                min_js_file.write(minified_js)
            print(f"Minified file created at: {output_file_path}")
        except Exception as e:
            print(f"Error minifying {input_file_path}: {e}")

4. 테마 복사 및 압축

테마 디렉토리를 복사하고, 자바스크립트 파일을 압축하는 함수입니다. SCSS 폴더는 제외합니다.

import os
import shutil
from minify_js import MinifyJS

def copy_and_minify_theme(src_dir, dest_dir):
    minifier = MinifyJS()

    if not os.path.exists(dest_dir):
        os.makedirs(dest_dir)

    for root, dirs, files in os.walk(src_dir):
        dirs[:] = [d for d in dirs if d != 'scss']
        
        rel_path = os.path.relpath(root, src_dir)
        dest_path = os.path.join(dest_dir, rel_path)

        if not os.path.exists(dest_path):
            os.makedirs(dest_path)

        for file in files:
            src_file = os.path.join(root, file)
            dest_file = os.path.join(dest_path, file)

            if file.endswith('.min.js'):
                shutil.copy2(src_file, dest_file)
            elif file.endswith('.js'):
                min_file = os.path.join(dest_path, os.path.splitext(file)[0] + '.min.js')
                minifier.minify_file(src_file, min_file)
            else:
                shutil.copy2(src_file, dest_file)

    print(f"Theme copied and JS files minified from {src_dir} to {dest_dir}")

5. FTP를 통한 업로드

기존 FTP 디렉토리를 삭제하고 새로 업로드하는 함수를 작성합니다.

import os
import ftplib

def ftp_delete_directory(ftp, remote_dir):
    try:
        file_list = ftp.nlst(remote_dir)
    except ftplib.error_perm as e:
        if str(e).startswith('550'):
            return
        else:
            raise

    for file in file_list:
        file_path = f"{remote_dir}/{os.path.basename(file)}"
        try:
            ftp.delete(file_path)
        except ftplib.error_perm:
            ftp_delete_directory(ftp, file_path)
    
    try:
        ftp.rmd(remote_dir)
    except ftplib.error_perm as e:
        print(f"Failed to remove directory {remote_dir}: {e}")

def upload_directory(ftp, local_dir, remote_dir):
    if not os.path.isdir(local_dir):
        return
    
    try:
        ftp.mkd(remote_dir)
    except ftplib.error_perm as e:
        if not str(e).startswith('550'):
            raise

    for item in os.listdir(local_dir):
        local_path = os.path.join(local_dir, item)
        remote_path = f"{remote_dir}/{item}"

        if os.path.isdir(local_path):
            upload_directory(ftp, local_path, remote_path)
        else:
            with open(local_path, 'rb') as file:
                ftp.storbinary(f'STOR {remote_path}', file)
                print(f'Uploaded {local_path} to {remote_path}')

def upload_theme_to_ftp(ftp_host, ftp_user, ftp_password, local_theme_dir, remote_theme_dir):
    with ftplib.FTP(ftp_host) as ftp:
        ftp.login(ftp_user, ftp_password)
        print(f"Connected to FTP server: {ftp_host}")

        ftp_delete_directory(ftp, remote_theme_dir)
        upload_directory(ftp, local_theme_dir, remote_theme_dir)
        print(f"Theme uploaded from {local_theme_dir} to {remote_theme_dir}")

6. 통합 실행 파일

위의 모든 기능을 통합하여 자동화된 테마 복사, 압축, 업로드 과정을 실행합니다.

import os
import shutil
from dotenv import load_dotenv
from theme_builder import copy_and_minify_theme
from theme_uploader import upload_theme_to_ftp

load_dotenv(dotenv_path='.env.development')

src_theme_dir = os.getenv('SRC_THEME_DIR')
dest_theme_dir = os.getenv('DEST_THEME_DIR')
ftp_host = os.getenv('FTP_HOST')
ftp_user = os.getenv('FTP_USER')
ftp_password = os.getenv('FTP_PASSWORD')
remote_theme_dir = os.getenv('REMOTE_THEME_DIR')

if __name__ == "__main__":
    if os.path.exists(dest_theme_dir):
        shutil.rmtree(dest_theme_dir)

    copy_and_minify_theme(src_theme_dir, dest_theme_dir)
    upload_theme_to_ftp(ftp_host, ftp_user, ftp_password, dest_theme_dir, remote_theme_dir)

결론

이렇게 WordPress 테마 파일을 Python을 사용하여 자동으로 압축하고 FTP를 통해 업로드할 수 있습니다. 이 과정을 통해 테마 관리의 효율성을 크게 향상시킬 수 있습니다. 자바스크립트 파일의 인코딩 문제를 해결하고, FTP 디렉토리를 재귀적으로 삭제하는 등의 자동화 작업은 웹 개발 및 운영에서 많은 시간을 절약하고 실수를 줄이는 데 크게 기여합니다.

Leave a Reply