#!/usr/bin/env python3 """ AI Platform 메뉴 안내 PPT 생성 (python-pptx) 스크린샷: docs/ppt-screenshots/*.png """ from __future__ import annotations import os from pathlib import Path from pptx import Presentation from pptx.dml.color import RGBColor from pptx.enum.text import MSO_ANCHOR, PP_ALIGN from pptx.util import Inches, Pt ROOT = Path(__file__).resolve().parent.parent SHOT_DIR = ROOT / "docs" / "ppt-screenshots" OUT_PPT = ROOT / "docs" / "XAVIS-AI-Platform-메뉴안내.pptx" # 슬라이드 정의: (제목, 불릿 목록, 스크린샷 파일명 또는 None) SLIDES: list[tuple[str, list[str], str | None]] = [ ( "XAVIS AI Platform 메뉴 안내", [ "사내 AI 도구·학습·과제·활용 사례 통합 포털", "접속: https://ai.xavis.co.kr/", "최초 1회: @ncue.net 이메일 → 인증 메일 링크(15분 유효)", "좌측 메뉴: 회사규정 · WM · AI · 프롬프트 · 학습센터 · 과제신청 · AI 활용 사례 · 대시보드(허용자)", ], None, ), ( "1. 서비스 접속 (로그인)", [ "경로: /login — 미인증 시 자동 이동", "회사 이메일 입력 → [검증] → 메일 [인증 완료하기] 클릭", "인증 후 학습센터 등 원하는 화면으로 이동", "유의: @ncue.net 만 가능 · 링크 만료 시 재검증 · 로그아웃은 좌측 하단", ], "login.png", ), ( "2. 회사규정", [ "좌측 [회사규정] 클릭 → Google NotebookLM (새 탭, 회사 Google 계정 로그인)", "사내 규정·지침 AI 검색·요약·질의응답", "캡처: 좌측 메뉴 [회사규정] 위치 (학습센터 화면)", "AI 답변은 원문 규정·다우오피스 공식 문서와 반드시 대조", ], "company-policy.png", ), ( "3. WM", [ "좌측 [WM] 클릭 → NotebookLM WM 노트북 (새 탭)", "WM 프로세스·용어·가이드 질의", "캡처: 좌측 메뉴 [WM] 위치 (AI 화면)", "공식 매뉴얼·담당 부서 확인 병행", ], "wm.png", ), ( "4. AI (메인 허브)", [ "경로: /ai-explore — AI 서비스 카드 허브", "검색 + 타입 필터(전체/일반/XScan/FScan)", "회의록 AI · 업무 체크리스트 · 일반 채팅 · FSCAN 선정도우미", ], "ai-explore.png", ), ( "5. 회의록 AI", [ "텍스트 입력: 회의 원문 붙여넣기 → 회의록 생성 → 저장", "음성 파일: mp3·m4a·wav(최대 300MB) → 업로드→전사→회의록 정리", "저장 시 업무 체크리스트 AI와 자동 연동", "대안: Claude 음성 업로드 / 클로버노트 전사 → 텍스트 입력 탭 붙여넣기", "유의: 생성 결과 검토 필수 · 개인정보·대외비 주의", ], "meeting-minutes.png", ), ( "6. 업무 체크리스트 AI", [ "회의록 AI 저장분의 액션·체크리스트 통합 관리", "진행/완료 필터 · 회의별 필터 · 완료 처리 메모", "흐름: 회의록 AI 저장 → 체크리스트에서 추적", ], "task-checklist.png", ), ( "7. 일반 채팅", [ "ChatGPT 기반 사내 인앱 채팅 (로그인 필요)", "업무 질의·초안·아이디어 · (설정 시) 웹 검색", "반복 프롬프트는 [프롬프트] 메뉴 템플릿 활용", "유의: AI 답변은 실수할 수 있음 · 기밀 입력 자제", ], "chat.png", ), ( "8. FSCAN 조사각 선정도우미", [ "검사 대상물 H/W 치수 입력 → FSCAN 모델 1차 선정", "영업·기술 검토 시 빠른 선정용", "최종 스펙은 공식 카탈로그·기술팀 확인 필수", ], "fscan.png", ), ( "9. 프롬프트 라이브러리", [ "공식 템플릿: 회의 요약·이메일·보고·OKR·코드리뷰 등 → 복사", "워크플로: 4단계 입력 → 맞춤 프롬프트 초안", "공유하기: 팀 프롬프트·참고 파일 (기밀 제외)", ], "prompts.png", ), ( "10. 학습센터", [ "YouTube · PPT/PDF · 동영상 · 웹·뉴스 링크 강의", "카테고리: AX 사고 전환 · AI 툴 활용 · AI Agent · 바이브 코딩", "검색 예: claude, 클로드 → 도구별 강의 찾기", ], "learning.png", ), ( "11. AX 과제 신청", [ "온라인 신청 + Word 양식 다운로드", "Pain Point · AI 기대 · 데이터·효과 등 작성", "조회로 본인 신청 확인·수정 · AI 활용 사례 참고", ], "ax-apply.png", ), ( "12. AI 활용 사례", [ "부서별 도입·성과 사례 카드 열람", "글쓰기: STAR 형식(1.Situation~4.Result)", "AX 과제·팀 공유 레퍼런스", ], "ai-cases.png", ), ( "13. 대시보드 (허용 계정)", [ "허용 이메일만 좌측 메뉴 표시", "경영성과: 연도·분기 KPI 차트 + 매출일보 엑셀 업로드", ], "dashboard.png", ), ( "14. 경영성과 대시보드", [ "상단: Chart.js KPI·차트 조회", "하단: .xlsx 매출일보 업로드 → 스냅샷 저장", ], "dashboard-business-performance.png", ), ( "업무별 Quick Reference", [ "음성 회의록 → AI → 회의록 AI (또는 클로버노트 → 텍스트 입력)", "할 일 추적 → 업무 체크리스트 AI", "빠른 질문 → 일반 채팅 · 메일·보고 → 프롬프트", "규정 → 회사규정 · 학습 → 학습센터 · AI 과제 → 과제신청", "문의: AI혁신팀", ], None, ), ] ACCENT = RGBColor(0x25, 0x63, 0xEB) DARK = RGBColor(0x11, 0x18, 0x27) GRAY = RGBColor(0x4B, 0x55, 0x63) def add_title_slide(prs: Presentation, title: str, bullets: list[str]) -> None: layout = prs.slide_layouts[6] # blank slide = prs.slides.add_slide(layout) slide.background.fill.solid() slide.background.fill.fore_color.rgb = RGBColor(0xF0, 0xF4, 0xFF) box = slide.shapes.add_textbox(Inches(0.8), Inches(2.2), Inches(11.5), Inches(1.2)) tf = box.text_frame tf.text = title p = tf.paragraphs[0] p.font.size = Pt(40) p.font.bold = True p.font.color.rgb = DARK p.alignment = PP_ALIGN.CENTER sub = slide.shapes.add_textbox(Inches(1.2), Inches(3.6), Inches(10.8), Inches(2.5)) stf = sub.text_frame stf.word_wrap = True for i, line in enumerate(bullets[:4]): para = stf.paragraphs[0] if i == 0 else stf.add_paragraph() para.text = line para.font.size = Pt(18) para.font.color.rgb = GRAY para.space_after = Pt(8) para.alignment = PP_ALIGN.CENTER def add_content_slide( prs: Presentation, title: str, bullets: list[str], shot_name: str | None, ) -> None: layout = prs.slide_layouts[6] slide = prs.slides.add_slide(layout) # 제목 title_box = slide.shapes.add_textbox(Inches(0.5), Inches(0.25), Inches(12.3), Inches(0.6)) ttf = title_box.text_frame ttf.text = title tp = ttf.paragraphs[0] tp.font.size = Pt(26) tp.font.bold = True tp.font.color.rgb = ACCENT has_shot = shot_name and (SHOT_DIR / shot_name).is_file() text_left = Inches(0.5) text_top = Inches(0.95) text_w = Inches(5.8) if has_shot else Inches(12.3) text_h = Inches(6.2) body = slide.shapes.add_textbox(text_left, text_top, text_w, text_h) btf = body.text_frame btf.word_wrap = True for i, line in enumerate(bullets): para = btf.paragraphs[0] if i == 0 else btf.add_paragraph() para.text = f"• {line}" para.font.size = Pt(14) para.font.color.rgb = DARK para.space_after = Pt(6) para.level = 0 if has_shot: shot_path = str(SHOT_DIR / shot_name) slide.shapes.add_picture( shot_path, Inches(6.6), Inches(0.85), width=Inches(6.2), ) elif shot_name: note = slide.shapes.add_textbox(Inches(6.6), Inches(2.5), Inches(6.0), Inches(1.0)) ntf = note.text_frame ntf.text = f"(캡처 없음: {shot_name})" ntf.paragraphs[0].font.size = Pt(12) ntf.paragraphs[0].font.color.rgb = GRAY # 슬라이드 번호 num = len(prs.slides) footer = slide.shapes.add_textbox(Inches(12.0), Inches(7.05), Inches(0.8), Inches(0.3)) ftf = footer.text_frame ftf.text = str(num) ftf.paragraphs[0].font.size = Pt(10) ftf.paragraphs[0].font.color.rgb = GRAY ftf.paragraphs[0].alignment = PP_ALIGN.RIGHT def build() -> Path: prs = Presentation() prs.slide_width = Inches(13.333) prs.slide_height = Inches(7.5) for idx, (title, bullets, shot) in enumerate(SLIDES): if idx == 0: add_title_slide(prs, title, bullets) else: add_content_slide(prs, title, bullets, shot) OUT_PPT.parent.mkdir(parents=True, exist_ok=True) prs.save(str(OUT_PPT)) return OUT_PPT if __name__ == "__main__": out = build() print(f"PPT saved: {out}")