import gradio as gr import pathlib import json import hashlib import random import os def load_content(file_path): if not file_path.exists(): raise FileNotFoundError(f"Content file not found: {file_path}") with open(file_path, 'r') as file: content = [json.loads(line) for line in file if line.strip()] for item in content: item["id"] = hashlib.md5((item["question"] + item["answer"]).encode()).hexdigest() item["views"] = item.get("views", 0) return content def select_next_question(content, seen_questions): unseen_questions = [item for item in content if item["id"] not in seen_questions] if unseen_questions: return random.choice(unseen_questions) else: min_views = min(item["views"] for item in content) least_viewed = [item for item in content if item["views"] == min_views] return random.choice(least_viewed) class InterfaceCreator: def __init__(self, content, audio_dir): self.content = content self.seen_questions = set() self.audio_dir = audio_dir def get_audio_path(self, item_id, audio_type): return os.path.join(self.audio_dir, f"{item_id}_{audio_type}.mp3") def update_interface(self, current_item=None): if current_item is None or current_item.get('state') == 'answer': new_item = select_next_question(self.content, self.seen_questions) new_item['state'] = 'question' new_item['views'] += 1 self.seen_questions.add(new_item["id"]) question_audio = self.get_audio_path(new_item['id'], 'question') if not os.path.exists(question_audio): print(f"Warning: Audio file not found: {question_audio}") question_audio = None else: print(f"Audio file found: {question_audio}") return ("Show Answer ⏎", new_item['question'], "", question_audio, new_item) elif current_item.get('state') == 'question': current_item['state'] = 'answer' answer_audio = self.get_audio_path(current_item['id'], 'answer') if not os.path.exists(answer_audio): print(f"Warning: Audio file not found: {answer_audio}") answer_audio = None else: print(f"Audio file found: {answer_audio}") return ("Next Question ⏎", current_item['question'], current_item['answer'], answer_audio, current_item) def create_interface(self): custom_css = """ .center-text { text-align: center; } #question-text, #answer-text { border: none; background: transparent; font-size: 20px; } #question-text textarea, #answer-text textarea { border: none; background: transparent; font-size: 20px; resize: none; overflow: hidden; min-height: 100px; max-height: 400px; } #audio-output { display: none !important; } #audio-output audio { display: none !important; } footer { display: none !important; } """ shortcut_js = """ """ with gr.Blocks(css=custom_css, head=shortcut_js) as demo: current_item = gr.State(None) primary_button = gr.Button("Show Answer ⏎", variant="primary", elem_id="primary-button") question_text = gr.Textbox(elem_id="question-text", show_label=False, label="Question", lines=5, max_lines=20, interactive=False) answer_text = gr.Textbox(elem_id="answer-text", show_label=False, label="Answer", lines=5, max_lines=20, interactive=False) audio_output = gr.Audio(elem_id="audio-output", visible=True, autoplay=True) primary_button.click(self.update_interface, inputs=[current_item], outputs=[primary_button, question_text, answer_text, audio_output, current_item]) demo.load(self.update_interface, outputs=[primary_button, question_text, answer_text, audio_output, current_item]) return demo if __name__ == "__main__": BASE_DIR = pathlib.Path(os.getcwd()) CONTENT_FILE = BASE_DIR / "content.jsonl" AUDIO_DIR = BASE_DIR / "audio" content = load_content(CONTENT_FILE) interface_creator = InterfaceCreator(content, AUDIO_DIR) demo = interface_creator.create_interface() demo.launch()