118 lines
4.0 KiB
Python
118 lines
4.0 KiB
Python
import time
|
|
import os, sys
|
|
import threading
|
|
from watchdog.observers import Observer
|
|
from watchdog.events import FileSystemEventHandler
|
|
from sqlalchemy import select, func
|
|
|
|
# 상위 경로를 sys.path에 추가해 프로젝트 내 모듈 임포트 가능하게 설정
|
|
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
|
from conf import db, db_schema
|
|
|
|
# 처리 스크립트
|
|
import pos_update_bill
|
|
import pos_update_daily_product
|
|
|
|
# 데이터 폴더
|
|
DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '../data'))
|
|
|
|
FILE_EXTENSIONS = ('.xls', '.xlsx')
|
|
BILL_PREFIX = "영수증별매출상세현황"
|
|
DAILY_PRODUCT_PREFIX = "일자별 (상품별)"
|
|
|
|
|
|
class NewFileHandler(FileSystemEventHandler):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._lock = threading.Lock()
|
|
self._processing_files = set()
|
|
|
|
def on_created(self, event):
|
|
if event.is_directory:
|
|
return
|
|
filepath = event.src_path
|
|
filename = os.path.basename(filepath)
|
|
if not filename.endswith(FILE_EXTENSIONS):
|
|
return
|
|
|
|
# 처리 대상 여부 확인
|
|
if filename.startswith(BILL_PREFIX) or filename.startswith(DAILY_PRODUCT_PREFIX):
|
|
print(f"[WATCHER] 신규 파일 감지: {filename}")
|
|
threading.Thread(target=self.process_file, args=(filepath, filename), daemon=True).start()
|
|
|
|
def process_file(self, filepath, filename):
|
|
with self._lock:
|
|
if filename in self._processing_files:
|
|
print(f"[WATCHER] {filename} 이미 처리 중")
|
|
return
|
|
self._processing_files.add(filename)
|
|
|
|
try:
|
|
time.sleep(3) # 파일 쓰기 완료 대기
|
|
|
|
print(f"[WATCHER] 파일 처리 시작: {filename}")
|
|
if filename.startswith(BILL_PREFIX):
|
|
pos_update_bill.main()
|
|
elif filename.startswith(DAILY_PRODUCT_PREFIX):
|
|
pos_update_daily_product.main()
|
|
else:
|
|
print(f"[WATCHER] 처리 대상이 아님: {filename}")
|
|
return
|
|
|
|
except Exception as e:
|
|
print(f"[WATCHER] 처리 중 오류 발생: {filename} / {e}")
|
|
else:
|
|
try:
|
|
os.remove(filepath)
|
|
print(f"[WATCHER] 파일 처리 완료 및 삭제: {filename}")
|
|
except Exception as e:
|
|
print(f"[WATCHER] 파일 삭제 실패: {filename} / {e}")
|
|
finally:
|
|
with self._lock:
|
|
self._processing_files.discard(filename)
|
|
|
|
|
|
def check_latest_dates():
|
|
"""pos 및 pos_billdata 테이블의 최신 일자 조회"""
|
|
try:
|
|
engine = db.engine
|
|
with engine.connect() as conn:
|
|
# pos 테이블
|
|
pos_latest = conn.execute(
|
|
select(func.max(db_schema.pos.c.date))
|
|
).scalar()
|
|
|
|
# pos_billdata 테이블
|
|
bill_latest = conn.execute(
|
|
select(func.max(db_schema.pos_billdata.c.sale_date))
|
|
).scalar()
|
|
|
|
print("============================================")
|
|
print("[DB] 최근 데이터 저장일")
|
|
print(f" - pos : {pos_latest if pos_latest else '데이터 없음'}")
|
|
print(f" - pos_billdata : {bill_latest if bill_latest else '데이터 없음'}")
|
|
print("============================================")
|
|
|
|
except Exception as e:
|
|
print(f"[DB] 최근 날짜 조회 중 오류 발생: {e}")
|
|
|
|
|
|
def start_watching():
|
|
print(f"[WATCHER] '{DATA_DIR}' 폴더 감시 시작")
|
|
event_handler = NewFileHandler()
|
|
observer = Observer()
|
|
observer.schedule(event_handler, DATA_DIR, recursive=False)
|
|
observer.start()
|
|
try:
|
|
while True:
|
|
time.sleep(1)
|
|
except KeyboardInterrupt:
|
|
print("[WATCHER] 감시 종료 요청 수신, 종료 중...")
|
|
observer.stop()
|
|
observer.join()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
check_latest_dates() # ✅ 감시 시작 전 DB의 최신 날짜 출력
|
|
start_watching()
|