|
|
import gradio as gr |
|
|
import json |
|
|
from pathlib import Path |
|
|
import re |
|
|
|
|
|
|
|
|
current_dir = Path(__file__).parent |
|
|
|
|
|
def create_quiz_app(): |
|
|
"""Gradio 앱 생성""" |
|
|
|
|
|
|
|
|
html_file = current_dir / "simple_quiz.html" |
|
|
if html_file.exists(): |
|
|
with open(html_file, 'r', encoding='utf-8') as f: |
|
|
full_html = f.read() |
|
|
else: |
|
|
full_html = """ |
|
|
<!DOCTYPE html> |
|
|
<html lang=\"ko\"> |
|
|
<head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>퀴즈</title></head> |
|
|
<body><h1>퀴즈 파일을 찾을 수 없습니다.</h1></body> |
|
|
</html> |
|
|
""" |
|
|
|
|
|
|
|
|
questions_file = current_dir / "webquiz" / "questions.json" |
|
|
if not questions_file.exists(): |
|
|
fallback = current_dir / "questions.json" |
|
|
if fallback.exists(): |
|
|
questions_file = fallback |
|
|
|
|
|
if questions_file.exists(): |
|
|
with open(questions_file, 'r', encoding='utf-8') as f: |
|
|
questions_data = json.load(f) |
|
|
|
|
|
questions_js = json.dumps(questions_data, ensure_ascii=False) |
|
|
|
|
|
|
|
|
if 'const questions = [' in full_html: |
|
|
full_html = full_html.replace( |
|
|
'const questions = [', |
|
|
f'const questions = {questions_js}; const _old_questions = [' |
|
|
) |
|
|
else: |
|
|
|
|
|
full_html = re.sub( |
|
|
r"<body[^>]*>", |
|
|
lambda m: f"{m.group(0)}\n<script>const questions = {questions_js};</script>", |
|
|
full_html, |
|
|
flags=re.IGNORECASE |
|
|
) |
|
|
|
|
|
|
|
|
srcdoc_html = full_html.replace("'", "'") |
|
|
|
|
|
|
|
|
iframe_html = f""" |
|
|
<div class=\"iframe-wrap\"> |
|
|
<iframe id=\"quiz_iframe\" class=\"iframe\" srcdoc='{srcdoc_html}'></iframe> |
|
|
</div> |
|
|
""" |
|
|
|
|
|
with gr.Blocks( |
|
|
title="인적자원관리 퀴즈", |
|
|
theme=gr.themes.Soft(), |
|
|
css=""" |
|
|
.gradio-container { max-width: none !important; padding: 0 !important; } |
|
|
.main { padding: 0 !important; } |
|
|
.block { border: none !important; box-shadow: none !important; margin: 0 !important; } |
|
|
|
|
|
/* Responsive iframe sizing */ |
|
|
.iframe-wrap { width: 100%; height: 100vh; } |
|
|
.iframe { width: 100%; height: 100%; border: none; } |
|
|
|
|
|
@media (max-width: 480px) { |
|
|
.iframe-wrap { height: 92vh; } |
|
|
.iframe { height: 100%; } |
|
|
} |
|
|
""" |
|
|
) as app: |
|
|
|
|
|
|
|
|
gr.HTML( |
|
|
value=iframe_html, |
|
|
elem_id="quiz_interface" |
|
|
) |
|
|
|
|
|
return app |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
app = create_quiz_app() |
|
|
app.launch( |
|
|
server_name="0.0.0.0", |
|
|
server_port=7860, |
|
|
share=False, |
|
|
show_error=True |
|
|
) |