File size: 7,212 Bytes
baa0ef1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# app.pyの一部

from flask import Flask, render_template, request, jsonify, url_for
from gtts import gTTS
import os
import logging
import hashlib
from translation_data import (
    translation_dict_A,
    translation_dict_B,
    translation_dict_C,
    translation_dict_D,
    translation_dict_F
    # Include translation_dict_E, translation_dict_G if they exist
)

# Initialize Flask app
app = Flask(__name__)

# Configure logging
logging.basicConfig(level=logging.DEBUG)

# Directory to save audio files
AUDIO_DIR = os.path.join('static', 'audio')

# Ensure the audio directory exists
os.makedirs(AUDIO_DIR, exist_ok=True)

# Flashcards data organized by categories
flashcards = {
    'A': {
        'chinese_sentences': list(translation_dict_A.keys()),
        'japanese_translations': list(translation_dict_A.values())
    },
    'B': {
        'chinese_sentences': list(translation_dict_B.keys()),
        'japanese_translations': list(translation_dict_B.values())
    },
    'C': {
        'chinese_sentences': list(translation_dict_C.keys()),
        'japanese_translations': list(translation_dict_C.values())
    },
    'D': {
        'chinese_sentences': list(translation_dict_D.keys()),
        'japanese_translations': list(translation_dict_D.values())
    },
    'F': {
        'chinese_sentences': list(translation_dict_F.keys()),
        'japanese_translations': list(translation_dict_F.values())
    },
    # Add 'E' and 'G' similarly if needed
}

# Helper function to generate a truncated hash
def generate_truncated_hash(text, length=8):
    """

    Generate a truncated SHA-256 hash for the given text.



    Args:

        text (str): The input text to hash.

        length (int): The length of the truncated hash.



    Returns:

        str: Truncated hash string.

    """
    hash_object = hashlib.sha256(text.encode('utf-8'))
    hex_dig = hash_object.hexdigest()
    return hex_dig[:length]

# Helper function to generate gTTS audio
def generate_audio_def(text, set_name, index):
    """

    Generate a gTTS audio file for the given text.



    Args:

        text (str): The text to convert to speech.

        set_name (str): The set identifier.

        index (int): The index of the flashcard.



    Returns:

        str: URL to the saved audio file.

    """
    sentence_hash = generate_truncated_hash(text)
    folder_path = os.path.join(AUDIO_DIR, sentence_hash)
    os.makedirs(folder_path, exist_ok=True)

    filename = f"{set_name}_{index}_def.mp3"
    filepath = os.path.join(folder_path, filename)

    if not os.path.exists(filepath):
        logging.info(f"Generating gTTS audio file: {filepath}")
        try:
            tts = gTTS(text=text, lang='ja')  # Japanese TTS
            tts.save(filepath)
        except Exception as e:
            logging.error(f"Error generating gTTS audio: {e}")
            return None
    else:
        logging.info(f"Using existing gTTS audio file: {filepath}")

    return url_for('static', filename=f"audio/{sentence_hash}/{filename}")

# Route for the portal page
@app.route('/')
def portal():
    """Render the portal page with links to different categories."""
    return render_template('portal.html')

# Route to render the flashcards page
@app.route('/flashcards')
def flashcards_page():
    """Render the flashcards page for a specific set and index."""
    set_name = request.args.get('set', 'A')
    try:
        index = int(request.args.get('index', 0))
    except ValueError:
        return "Invalid index parameter", 400

    if set_name not in flashcards:
        return "Set not found", 404

    total = len(flashcards[set_name]['chinese_sentences'])
    if not (0 <= index < total):
        return "Index out of range", 404

    chinese = flashcards[set_name]['chinese_sentences'][index]
    japanese = flashcards[set_name]['japanese_translations'][index]
    audio_def_url = generate_audio_def(japanese, set_name, index)

    # Predefined variant filenames (assuming they are pre-generated)
    sentence_hash = generate_truncated_hash(japanese)
    variant_urls = {}
    for variant_num in range(1, 4):  # Variants 1 to 4
        variant_filename = f"variant_{variant_num}.mp3"
        variant_filepath = os.path.join(AUDIO_DIR, sentence_hash, variant_filename)
        if os.path.exists(variant_filepath):
            variant_urls[f"variant_{variant_num}"] = url_for('static', filename=f"audio/{sentence_hash}/{variant_filename}")
        else:
            variant_urls[f"variant_{variant_num}"] = None  # Handle missing files

    return render_template(
        'flashcards.html',
        set_name=set_name,
        index=index,
        total=total,
        japanese=japanese,      # Japanese text
        chinese=chinese,        # Chinese text
        audio_def_url=audio_def_url,  # gTTS audio URL
        variant_urls=variant_urls      # Other variant audio URLs
    )

# API endpoint to fetch flashcard data
@app.route('/api/flashcards')
def api_flashcards():
    """API endpoint to fetch flashcard data with multiple audio variants."""
    set_name = request.args.get('set', 'A')
    try:
        index = int(request.args.get('index', 0))
    except ValueError:
        return jsonify({'error': 'Invalid index parameter'}), 400

    if set_name in flashcards:
        chinese_sentences = flashcards[set_name]['chinese_sentences']
        japanese_translations = flashcards[set_name]['japanese_translations']
        total = len(chinese_sentences)

        if 0 <= index < total:
            chinese = chinese_sentences[index]
            japanese = japanese_translations[index]

            # gTTSによるお手本音声
            audio_def_url = generate_audio_def(japanese, set_name, index)

            # 他のバリアント音声のURLを取得
            sentence_hash = generate_truncated_hash(japanese)
            variant_urls = {}
            for variant_num in range(1, 5):  # Variants 1 to 4
                variant_filename = f"variant_{variant_num}.mp3"
                variant_filepath = os.path.join(AUDIO_DIR, sentence_hash, variant_filename)
                if os.path.exists(variant_filepath):
                    variant_urls[f"variant_{variant_num}"] = url_for('static', filename=f"audio/{sentence_hash}/{variant_filename}")
                else:
                    variant_urls[f"variant_{variant_num}"] = None  # Handle missing files

            return jsonify({
                'set_name': set_name,
                'index': index,
                'total': total,
                'japanese': japanese,
                'chinese': chinese,
                'audio_def_url': audio_def_url,      # gTTS音声
                'variant_urls': variant_urls         # 他のバリアント音声
            })
        else:
            return jsonify({'error': 'Index out of range'}), 404
    else:
        return jsonify({'error': 'Set not found'}), 404

if __name__ == '__main__':
    # Run the Flask app on all available IPs on port 7860
    app.run(debug=True, host="0.0.0.0", port=7860)