OzoneAsai commited on
Commit
baa0ef1
1 Parent(s): 97a02fd

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +201 -148
app.py CHANGED
@@ -1,148 +1,201 @@
1
- from flask import Flask, render_template, request, jsonify, url_for
2
- from gtts import gTTS
3
- import os
4
- import logging
5
- from translation_data import (
6
- translation_dict_A,
7
- translation_dict_B,
8
- translation_dict_C,
9
- translation_dict_D,
10
- translation_dict_F
11
- # Include translation_dict_E, translation_dict_G if they exist
12
- )
13
-
14
- # Initialize Flask app
15
- app = Flask(__name__)
16
-
17
- # Configure logging
18
- logging.basicConfig(level=logging.DEBUG)
19
-
20
- # Directory to save audio files
21
- AUDIO_DIR = os.path.join('static', 'audio')
22
-
23
- # Ensure the audio directory exists
24
- os.makedirs(AUDIO_DIR, exist_ok=True)
25
-
26
- # Flashcards data organized by categories
27
- flashcards = {
28
- 'A': {
29
- 'chinese_sentences': list(translation_dict_A.keys()),
30
- 'japanese_translations': list(translation_dict_A.values())
31
- },
32
- 'B': {
33
- 'chinese_sentences': list(translation_dict_B.keys()),
34
- 'japanese_translations': list(translation_dict_B.values())
35
- },
36
- 'C': {
37
- 'chinese_sentences': list(translation_dict_C.keys()),
38
- 'japanese_translations': list(translation_dict_C.values())
39
- },
40
- 'D': {
41
- 'chinese_sentences': list(translation_dict_D.keys()),
42
- 'japanese_translations': list(translation_dict_D.values())
43
- },
44
- 'F': {
45
- 'chinese_sentences': list(translation_dict_F.keys()),
46
- 'japanese_translations': list(translation_dict_F.values())
47
- },
48
- # Add 'E' and 'G' similarly if needed
49
- }
50
-
51
- # Helper function to generate audio
52
- def generate_audio(text, set_name, index):
53
- """Generate an audio file from Japanese text using gTTS."""
54
- filename = f"{set_name}_{index}.mp3"
55
- filepath = os.path.join(AUDIO_DIR, filename)
56
-
57
- if not os.path.exists(filepath):
58
- logging.info(f"Generating audio file: {filepath}")
59
- try:
60
- tts = gTTS(text=text, lang='ja') # Japanese TTS
61
- tts.save(filepath)
62
- except Exception as e:
63
- logging.error(f"Error generating audio: {e}")
64
- return None
65
- else:
66
- logging.info(f"Using existing audio file: {filepath}")
67
-
68
- return filepath
69
-
70
- # Route for the portal page
71
- @app.route('/')
72
- def portal():
73
- """Render the portal page with links to different categories."""
74
- return render_template('portal.html')
75
-
76
- # Route to render the flashcards page
77
- @app.route('/flashcards')
78
- def flashcards_page():
79
- """Render the flashcards page for a specific set and index."""
80
- set_name = request.args.get('set', 'A')
81
- try:
82
- index = int(request.args.get('index', 0))
83
- except ValueError:
84
- return "Invalid index parameter", 400
85
-
86
- if set_name not in flashcards:
87
- return "Set not found", 404
88
-
89
- total = len(flashcards[set_name]['chinese_sentences'])
90
- if not (0 <= index < total):
91
- return "Index out of range", 404
92
-
93
- chinese = flashcards[set_name]['chinese_sentences'][index]
94
- japanese = flashcards[set_name]['japanese_translations'][index]
95
- audio_url = url_for('static', filename=f"audio/{set_name}_{index}.mp3")
96
-
97
- return render_template(
98
- 'flashcards.html',
99
- set_name=set_name,
100
- index=index,
101
- total=total,
102
- japanese=japanese, # Changed from 'english' to 'japanese'
103
- chinese=chinese, # Added 'chinese'
104
- audio_url=audio_url
105
- )
106
-
107
- # API endpoint to fetch flashcard data
108
- @app.route('/api/flashcards')
109
- def api_flashcards():
110
- """API endpoint to fetch flashcard data."""
111
- set_name = request.args.get('set', 'A')
112
- try:
113
- index = int(request.args.get('index', 0))
114
- except ValueError:
115
- return jsonify({'error': 'Invalid index parameter'}), 400
116
-
117
- if set_name in flashcards:
118
- chinese_sentences = flashcards[set_name]['chinese_sentences']
119
- japanese_translations = flashcards[set_name]['japanese_translations']
120
- total = len(chinese_sentences)
121
-
122
- if 0 <= index < total:
123
- chinese = chinese_sentences[index]
124
- japanese = japanese_translations[index]
125
-
126
- # Generate audio from Japanese text
127
- audio_path = generate_audio(japanese, set_name, index)
128
- if audio_path:
129
- audio_url = url_for('static', filename=f"audio/{set_name}_{index}.mp3")
130
- else:
131
- audio_url = None # Handle audio generation failure
132
-
133
- return jsonify({
134
- 'set_name': set_name,
135
- 'index': index,
136
- 'total': total,
137
- 'japanese': japanese, # Changed from 'english' to 'japanese'
138
- 'chinese': chinese, # Added 'chinese'
139
- 'audio_url': audio_url
140
- })
141
- else:
142
- return jsonify({'error': 'Index out of range'}), 404
143
- else:
144
- return jsonify({'error': 'Set not found'}), 404
145
-
146
- if __name__ == '__main__':
147
- # Run the Flask app on all available IPs on port 7860
148
- app.run(debug=True, host="0.0.0.0", port=7860)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.pyの一部
2
+
3
+ from flask import Flask, render_template, request, jsonify, url_for
4
+ from gtts import gTTS
5
+ import os
6
+ import logging
7
+ import hashlib
8
+ from translation_data import (
9
+ translation_dict_A,
10
+ translation_dict_B,
11
+ translation_dict_C,
12
+ translation_dict_D,
13
+ translation_dict_F
14
+ # Include translation_dict_E, translation_dict_G if they exist
15
+ )
16
+
17
+ # Initialize Flask app
18
+ app = Flask(__name__)
19
+
20
+ # Configure logging
21
+ logging.basicConfig(level=logging.DEBUG)
22
+
23
+ # Directory to save audio files
24
+ AUDIO_DIR = os.path.join('static', 'audio')
25
+
26
+ # Ensure the audio directory exists
27
+ os.makedirs(AUDIO_DIR, exist_ok=True)
28
+
29
+ # Flashcards data organized by categories
30
+ flashcards = {
31
+ 'A': {
32
+ 'chinese_sentences': list(translation_dict_A.keys()),
33
+ 'japanese_translations': list(translation_dict_A.values())
34
+ },
35
+ 'B': {
36
+ 'chinese_sentences': list(translation_dict_B.keys()),
37
+ 'japanese_translations': list(translation_dict_B.values())
38
+ },
39
+ 'C': {
40
+ 'chinese_sentences': list(translation_dict_C.keys()),
41
+ 'japanese_translations': list(translation_dict_C.values())
42
+ },
43
+ 'D': {
44
+ 'chinese_sentences': list(translation_dict_D.keys()),
45
+ 'japanese_translations': list(translation_dict_D.values())
46
+ },
47
+ 'F': {
48
+ 'chinese_sentences': list(translation_dict_F.keys()),
49
+ 'japanese_translations': list(translation_dict_F.values())
50
+ },
51
+ # Add 'E' and 'G' similarly if needed
52
+ }
53
+
54
+ # Helper function to generate a truncated hash
55
+ def generate_truncated_hash(text, length=8):
56
+ """
57
+ Generate a truncated SHA-256 hash for the given text.
58
+
59
+ Args:
60
+ text (str): The input text to hash.
61
+ length (int): The length of the truncated hash.
62
+
63
+ Returns:
64
+ str: Truncated hash string.
65
+ """
66
+ hash_object = hashlib.sha256(text.encode('utf-8'))
67
+ hex_dig = hash_object.hexdigest()
68
+ return hex_dig[:length]
69
+
70
+ # Helper function to generate gTTS audio
71
+ def generate_audio_def(text, set_name, index):
72
+ """
73
+ Generate a gTTS audio file for the given text.
74
+
75
+ Args:
76
+ text (str): The text to convert to speech.
77
+ set_name (str): The set identifier.
78
+ index (int): The index of the flashcard.
79
+
80
+ Returns:
81
+ str: URL to the saved audio file.
82
+ """
83
+ sentence_hash = generate_truncated_hash(text)
84
+ folder_path = os.path.join(AUDIO_DIR, sentence_hash)
85
+ os.makedirs(folder_path, exist_ok=True)
86
+
87
+ filename = f"{set_name}_{index}_def.mp3"
88
+ filepath = os.path.join(folder_path, filename)
89
+
90
+ if not os.path.exists(filepath):
91
+ logging.info(f"Generating gTTS audio file: {filepath}")
92
+ try:
93
+ tts = gTTS(text=text, lang='ja') # Japanese TTS
94
+ tts.save(filepath)
95
+ except Exception as e:
96
+ logging.error(f"Error generating gTTS audio: {e}")
97
+ return None
98
+ else:
99
+ logging.info(f"Using existing gTTS audio file: {filepath}")
100
+
101
+ return url_for('static', filename=f"audio/{sentence_hash}/{filename}")
102
+
103
+ # Route for the portal page
104
+ @app.route('/')
105
+ def portal():
106
+ """Render the portal page with links to different categories."""
107
+ return render_template('portal.html')
108
+
109
+ # Route to render the flashcards page
110
+ @app.route('/flashcards')
111
+ def flashcards_page():
112
+ """Render the flashcards page for a specific set and index."""
113
+ set_name = request.args.get('set', 'A')
114
+ try:
115
+ index = int(request.args.get('index', 0))
116
+ except ValueError:
117
+ return "Invalid index parameter", 400
118
+
119
+ if set_name not in flashcards:
120
+ return "Set not found", 404
121
+
122
+ total = len(flashcards[set_name]['chinese_sentences'])
123
+ if not (0 <= index < total):
124
+ return "Index out of range", 404
125
+
126
+ chinese = flashcards[set_name]['chinese_sentences'][index]
127
+ japanese = flashcards[set_name]['japanese_translations'][index]
128
+ audio_def_url = generate_audio_def(japanese, set_name, index)
129
+
130
+ # Predefined variant filenames (assuming they are pre-generated)
131
+ sentence_hash = generate_truncated_hash(japanese)
132
+ variant_urls = {}
133
+ for variant_num in range(1, 4): # Variants 1 to 4
134
+ variant_filename = f"variant_{variant_num}.mp3"
135
+ variant_filepath = os.path.join(AUDIO_DIR, sentence_hash, variant_filename)
136
+ if os.path.exists(variant_filepath):
137
+ variant_urls[f"variant_{variant_num}"] = url_for('static', filename=f"audio/{sentence_hash}/{variant_filename}")
138
+ else:
139
+ variant_urls[f"variant_{variant_num}"] = None # Handle missing files
140
+
141
+ return render_template(
142
+ 'flashcards.html',
143
+ set_name=set_name,
144
+ index=index,
145
+ total=total,
146
+ japanese=japanese, # Japanese text
147
+ chinese=chinese, # Chinese text
148
+ audio_def_url=audio_def_url, # gTTS audio URL
149
+ variant_urls=variant_urls # Other variant audio URLs
150
+ )
151
+
152
+ # API endpoint to fetch flashcard data
153
+ @app.route('/api/flashcards')
154
+ def api_flashcards():
155
+ """API endpoint to fetch flashcard data with multiple audio variants."""
156
+ set_name = request.args.get('set', 'A')
157
+ try:
158
+ index = int(request.args.get('index', 0))
159
+ except ValueError:
160
+ return jsonify({'error': 'Invalid index parameter'}), 400
161
+
162
+ if set_name in flashcards:
163
+ chinese_sentences = flashcards[set_name]['chinese_sentences']
164
+ japanese_translations = flashcards[set_name]['japanese_translations']
165
+ total = len(chinese_sentences)
166
+
167
+ if 0 <= index < total:
168
+ chinese = chinese_sentences[index]
169
+ japanese = japanese_translations[index]
170
+
171
+ # gTTSによるお手本音声
172
+ audio_def_url = generate_audio_def(japanese, set_name, index)
173
+
174
+ # 他のバリアント音声のURLを取得
175
+ sentence_hash = generate_truncated_hash(japanese)
176
+ variant_urls = {}
177
+ for variant_num in range(1, 5): # Variants 1 to 4
178
+ variant_filename = f"variant_{variant_num}.mp3"
179
+ variant_filepath = os.path.join(AUDIO_DIR, sentence_hash, variant_filename)
180
+ if os.path.exists(variant_filepath):
181
+ variant_urls[f"variant_{variant_num}"] = url_for('static', filename=f"audio/{sentence_hash}/{variant_filename}")
182
+ else:
183
+ variant_urls[f"variant_{variant_num}"] = None # Handle missing files
184
+
185
+ return jsonify({
186
+ 'set_name': set_name,
187
+ 'index': index,
188
+ 'total': total,
189
+ 'japanese': japanese,
190
+ 'chinese': chinese,
191
+ 'audio_def_url': audio_def_url, # gTTS音声
192
+ 'variant_urls': variant_urls # 他のバリアント音声
193
+ })
194
+ else:
195
+ return jsonify({'error': 'Index out of range'}), 404
196
+ else:
197
+ return jsonify({'error': 'Set not found'}), 404
198
+
199
+ if __name__ == '__main__':
200
+ # Run the Flask app on all available IPs on port 7860
201
+ app.run(debug=True, host="0.0.0.0", port=7860)