diff --git a/autouploader/gnu_autoupload.py b/autouploader/gnu_autoupload.py index 78982d6..033a013 100644 --- a/autouploader/gnu_autoupload.py +++ b/autouploader/gnu_autoupload.py @@ -21,25 +21,62 @@ import ftputil from config import DB_CONFIG, FTP_CONFIG, MAIN from weather import get_precipitation_summary +from send_message import MessageSender # MessageSender 클래스 임포트 # --------------------------- # 이미지 캡처 함수 # --------------------------- -def capture_image(script_path, output_path, max_attempts=5): +def capture_image(script_path, output_path, max_attempts=5, msg_sender=None): + """ + 이미지 캡처 시도 + + Returns: + tuple: (성공여부, 에러메시지) + """ for attempt in range(max_attempts): print(f"[{datetime.now().strftime('%H:%M:%S')}] 이미지 캡처 시도 {attempt + 1}/{max_attempts}") try: - subprocess.run([sys.executable, script_path], check=True) + result = subprocess.run( + [sys.executable, script_path], + check=True, + capture_output=True, + text=True, + timeout=60 # 60초 타임아웃 설정 + ) + + if os.path.isfile(output_path): + print(f"[성공] 이미지가 정상적으로 캡처되었습니다: {output_path}") + return True, None + + except subprocess.TimeoutExpired: + error_msg = f"캡처 스크립트 실행 타임아웃 (시도 {attempt + 1}/{max_attempts})" + print(f"[오류] {error_msg}") + except subprocess.CalledProcessError as e: - print(f"[오류] weather_capture.py 실행 실패: {e}") - if os.path.isfile(output_path): - print(f"[성공] 이미지가 정상적으로 캡처되었습니다: {output_path}") - return True + error_msg = f"weather_capture.py 실행 실패:\n{e.stderr if e.stderr else str(e)}" + print(f"[오류] {error_msg}") + + except Exception as e: + error_msg = f"예상치 못한 오류: {type(e).__name__}: {e}" + print(f"[오류] {error_msg}") + time.sleep(2) + + # 모든 시도 실패 + final_error = f"❌ **날씨 이미지 캡처 실패**\n\n"\ + f"📅 날짜: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"\ + f"🔄 시도 횟수: {max_attempts}회\n"\ + f"📁 출력 경로: `{output_path}`\n"\ + f"⚠️ 파일이 생성되지 않았습니다." + print(f"[실패] {max_attempts}회 시도 후에도 이미지가 생성되지 않았습니다.") - return False - + + # Mattermost 알림 전송 + if msg_sender: + msg_sender.send(final_error, platforms=['mattermost']) + + return False, final_error # --------------------------- # 파일 관련 유틸 함수 @@ -70,11 +107,17 @@ def file_upload(filename, bf_file): print(f"[FTP 오류] {type(e).__name__}: {e}") return False - # --------------------------- # 게시글 작성 함수 # --------------------------- -def write_board(board, subject, content, mb_id, nickname, ca_name=None, file_list=None): +def write_board(board, subject, content, mb_id, nickname, ca_name=None, file_list=None, msg_sender=None): + """ + 게시글 작성 + + Returns: + tuple: (성공여부, 에러메시지) + """ + conn = None try: conn = pymysql.connect( host=DB_CONFIG['HOST'], @@ -135,27 +178,48 @@ def write_board(board, subject, content, mb_id, nickname, ca_name=None, file_lis size, width, height, img_type, now)) file_count += 1 else: - raise Exception(f"[FTP 오류] 파일 업로드 실패: {file}") + raise Exception(f"파일 업로드 실패: {file}") curs.execute(f"UPDATE g5_write_{board} SET wr_file = %s WHERE wr_id = %s", (file_count, wr_id)) conn.commit() print("[성공] 게시글과 첨부파일 등록 완료") + return True, None except Exception as e: - conn.rollback() - if "[FTP 오류]" in str(e): + if conn: + conn.rollback() + + # 에러 메시지 생성 + error_detail = traceback.format_exc() + error_msg = f"❌ **게시글 등록 실패**\n\n"\ + f"📅 날짜: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"\ + f"📋 게시판: `{board}`\n"\ + f"📝 제목: {subject}\n"\ + f"⚠️ 오류 유형: `{type(e).__name__}`\n"\ + f"💬 오류 메시지: {str(e)}\n"\ + f"```\n{error_detail}\n```" + + if "FTP" in str(e) or "파일 업로드" in str(e): print(f"[FTP 오류] {e}") else: print(f"[DB 오류] {type(e).__name__}: {e}") - raise + + # Mattermost 알림 전송 + if msg_sender: + msg_sender.send(error_msg, platforms=['mattermost']) + + return False, error_msg + finally: - conn.close() + if conn: + conn.close() # --------------------------- # 메인 실행 함수 # --------------------------- def main(): + # 기상청 API로 얻어오는 데이터와 캡처의 데이터가 다르므로 내용에 대해 업데이트 하지 않음. # 날씨 정보 문자열 얻기 #weather_content = get_precipitation_summary() @@ -167,6 +231,8 @@ def main(): MAIN["content"] = """

Rainy Day 이벤트 적용안내

10:00 ~ 22:00까지의 예보를 합산하며, ~1mm인 경우 0.5mm로 계산합니다.

+

레이니데이 이벤트 정보 확인

+

이벤트 정보 보기

""" today = datetime.today().strftime('%Y%m%d')