91 lines
3.4 KiB
Python
91 lines
3.4 KiB
Python
"""최종 패치: mail_parser + imap_client + frontend 재빌드"""
|
|
import paramiko, sys, subprocess, os
|
|
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
|
c = paramiko.SSHClient(); c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
c.connect('101.79.17.164', username='root', password='1q2w3e!Q', timeout=15)
|
|
sftp = c.open_sftp()
|
|
|
|
def run(label, cmd, timeout=30):
|
|
print(f'\n[{label}]')
|
|
_, o, _ = c.exec_command(cmd, timeout=timeout)
|
|
print(o.read().decode('utf-8','replace').strip()[:400])
|
|
|
|
# 1. Backend 파일 전송
|
|
for fn in ['mail_parser.py', 'imap_client.py', 'smtp_client.py', 'main.py']:
|
|
sftp.put(f'C:/GUARDiA/workspace/zioinfo-mail/backend/{fn}', f'/opt/mail/backend/{fn}')
|
|
print(f' ✅ {fn}')
|
|
|
|
run('서비스 재기동', 'systemctl restart zioinfo-mail && sleep 3 && systemctl is-active zioinfo-mail')
|
|
|
|
# 2. Frontend 재빌드
|
|
print('\n[Frontend 재빌드]')
|
|
FE = 'C:/GUARDiA/workspace/zioinfo-mail/frontend'
|
|
NPM = 'npm.cmd' if sys.platform == 'win32' else 'npm'
|
|
r = subprocess.run([NPM, 'run', 'build'], cwd=FE, capture_output=True, text=True,
|
|
encoding='utf-8', errors='replace', timeout=180)
|
|
if r.returncode == 0:
|
|
print(' ✅ 빌드 성공')
|
|
else:
|
|
print(f' ❌ 빌드 실패: {r.stderr[:200]}')
|
|
import sys as _s; _s.exit(1)
|
|
|
|
# dist 전송
|
|
dist = 'C:/GUARDiA/workspace/zioinfo-mail/dist'
|
|
import tarfile, io
|
|
buf = io.BytesIO()
|
|
with tarfile.open(fileobj=buf, mode='w:gz') as tar:
|
|
for root, dirs, files in os.walk(dist):
|
|
for fn2 in files:
|
|
fp = os.path.join(root, fn2)
|
|
tar.add(fp, arcname=os.path.relpath(fp, dist))
|
|
buf.seek(0)
|
|
sftp.putfo(buf, '/tmp/mail_dist.tar.gz')
|
|
run('dist 배포', 'cd /var/www/mail && tar -xzf /tmp/mail_dist.tar.gz && rm /tmp/mail_dist.tar.gz && echo "files: $(ls | wc -l)"')
|
|
|
|
import time; time.sleep(2)
|
|
|
|
# 3. E2E 재검증
|
|
test = """
|
|
import urllib.request, json
|
|
|
|
BASE = "http://localhost:8026"
|
|
def req(url, data=None, headers={}):
|
|
r = urllib.request.Request(BASE + url, data=data, headers=headers)
|
|
try:
|
|
return json.loads(urllib.request.urlopen(r, timeout=15).read())
|
|
except Exception as e:
|
|
print("ERROR", url, ":", e)
|
|
return None
|
|
|
|
# info 로그인 → INBOX
|
|
t = req("/api/auth/login",
|
|
data=json.dumps({"username":"info@zioinfo.co.kr","password":"1q2w3e!Q"}).encode(),
|
|
headers={"Content-Type":"application/json"})
|
|
if t:
|
|
Hi = {"Authorization": "Bearer " + t["access_token"]}
|
|
inbox = req("/api/mail/messages?folder=INBOX", headers=Hi)
|
|
if inbox:
|
|
print(f"info INBOX total:{inbox['total']}")
|
|
for m in inbox.get("messages", [])[:3]:
|
|
print(f" [{m['uid']}] {m['subject']!r} from:{m['sender']!r}")
|
|
else:
|
|
print("inbox 오류")
|
|
|
|
# ythong → Sent 확인
|
|
t2 = req("/api/auth/login",
|
|
data=json.dumps({"username":"ythong@zioinfo.co.kr","password":"1q2w3e!Q"}).encode(),
|
|
headers={"Content-Type":"application/json"})
|
|
if t2:
|
|
Hy = {"Authorization": "Bearer " + t2["access_token"]}
|
|
sent = req("/api/mail/messages?folder=Sent", headers=Hy)
|
|
if sent:
|
|
print(f"ythong Sent total:{sent['total']}")
|
|
for m in sent.get("messages", [])[:2]:
|
|
print(f" [{m['uid']}] {m['subject']!r} to:{m.get('to','')!r}")
|
|
"""
|
|
with sftp.open('/tmp/e2e2.py', 'w') as f: f.write(test)
|
|
run('E2E 재검증', 'python3 /tmp/e2e2.py 2>&1; rm /tmp/e2e2.py', timeout=30)
|
|
|
|
sftp.close(); c.close()
|
|
print('\n=== 완료 ===')
|