zioinfo-mail/scripts/setup/push_mail_via_api.py
DESKTOP-TKLFCPR\ython 371f77e7ab
Some checks are pending
GUARDiA CI / Python Lint & Import Test (push) Waiting to run
GUARDiA CI / Validate Install Scripts (push) Waiting to run
GUARDiA CI / PR Validation Summary (push) Blocked by required conditions
fix(enhance-v4): APK QR 버그 수정 + 웹메일 라우터 수정
2026-06-02 20:23:55 +09:00

102 lines
4.3 KiB
Python

"""Gitea Contents API로 zioinfo-mail 파일 직접 업로드"""
import paramiko, sys, os, json, base64, time
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()
G = base64.b64encode(b'zio:Zio@Admin2026!').decode()
def gitea_put(path: str, content_bytes: bytes, message: str, sha: str = None):
enc = base64.b64encode(content_bytes).decode()
if sha:
payload = json.dumps({"message": message, "content": enc, "sha": sha, "branch": "main"})
method = "PUT"
else:
payload = json.dumps({"message": message, "content": enc, "branch": "main"})
method = "POST"
with sftp.open('/tmp/gf.json', 'w') as f: f.write(payload)
_, o, _ = c.exec_command(
f'curl -sf -o /dev/null -w "%{{http_code}}" -X {method} '
f'"http://127.0.0.1:9003/api/v1/repos/zio/zioinfo-mail/contents/{path}" '
f'-H "Authorization: Basic {G}" -H "Content-Type: application/json" '
f'--data @/tmp/gf.json 2>/dev/null', timeout=10)
return o.read().decode('utf-8','replace').strip()
def get_sha(path: str) -> str:
_, o, _ = c.exec_command(
f'curl -sf "http://127.0.0.1:9003/api/v1/repos/zio/zioinfo-mail/contents/{path}" '
f'-H "Authorization: Basic {G}" 2>/dev/null | '
'python3 -c "import sys,json; print(json.load(sys.stdin).get(\'sha\',\'\'))" 2>/dev/null', timeout=10)
return o.read().decode('utf-8','replace').strip()
# 먼저 Gitea repo 완전 초기화 (DELETE + RECREATE)
print('[Gitea repo 재생성]')
_, o, _ = c.exec_command(
f'curl -sf -X DELETE "http://127.0.0.1:9003/api/v1/repos/zio/zioinfo-mail" '
f'-H "Authorization: Basic {G}" 2>/dev/null; echo $?', timeout=10)
print(f' delete: {o.read().decode().strip()}')
time.sleep(1)
_, o, _ = c.exec_command(
f'curl -sf -X POST "http://127.0.0.1:9003/api/v1/user/repos" '
f'-H "Authorization: Basic {G}" -H "Content-Type: application/json" '
f'-d \'{{"name":"zioinfo-mail","private":false,"auto_init":false}}\' 2>/dev/null | '
'python3 -c "import sys,json; print(json.load(sys.stdin).get(\'full_name\',\'?\'))" 2>/dev/null', timeout=10)
print(f' create: {o.read().decode().strip()}')
time.sleep(1)
# 업로드할 파일 목록
WS = 'C:/GUARDiA/workspace/zioinfo-mail'
EXCLUDE = {'node_modules', '__pycache__', '.git', '.pytest_cache', 'dist', '.expo'}
BINARY_EXT = {'.png', '.jpg', '.jpeg', '.gif', '.ico', '.woff', '.woff2', '.ttf', '.eot'}
files_to_upload = []
for root, dirs, files in os.walk(WS):
dirs[:] = [d for d in dirs if d not in EXCLUDE]
for fn in files:
if fn.endswith(('.pyc', '.db', '.tsbuildinfo')):
continue
fp = os.path.join(root, fn)
rel = os.path.relpath(fp, WS).replace('\\', '/')
files_to_upload.append((rel, fp))
# .gitignore 추가
files_to_upload.append(('.gitignore', None))
print(f'\n업로드 파일: {len(files_to_upload)}')
ok = fail = 0
for rel, fp in files_to_upload:
try:
if fp is None: # .gitignore
content_bytes = b'node_modules/\ndist/\n__pycache__/\n*.pyc\n.env\n*.db\n.tsbuildinfo\n'
else:
with open(fp, 'rb') as f:
content_bytes = f.read()
# 파일이 너무 크면 스킵 (package-lock.json 등)
if len(content_bytes) > 500_000:
print(f' SKIP (too large): {rel} ({len(content_bytes)//1024}KB)')
continue
code = gitea_put(rel, content_bytes, f'feat: add {rel}')
if code in ('200', '201'):
ok += 1
if ok % 5 == 0: print(f' {ok}/{len(files_to_upload)} 완료...')
else:
fail += 1
print(f' FAIL {code}: {rel}')
except Exception as e:
fail += 1
print(f' ERR {rel}: {e}')
print(f'\n완료: {ok}개 성공, {fail}개 실패')
# Gitea 파일 확인
_, o, _ = c.exec_command(
f'curl -sf "http://127.0.0.1:9003/api/v1/repos/zio/zioinfo-mail/contents/" '
f'-H "Authorization: Basic {G}" 2>/dev/null | '
'python3 -c "import sys,json; [print(f[\'name\'],f[\'type\']) for f in json.load(sys.stdin)[:10]]" 2>/dev/null', timeout=10)
print('\n[Gitea 파일 목록]\n' + o.read().decode('utf-8','replace').strip())
sftp.close(); c.close()
print('\n=== 완료 ===')