buletomato25 commited on
Commit
43a0845
·
2 Parent(s): f1b89be d181b92
__pycache__/analyze.cpython-310.pyc CHANGED
Binary files a/__pycache__/analyze.cpython-310.pyc and b/__pycache__/analyze.cpython-310.pyc differ
 
__pycache__/transcription.cpython-310.pyc CHANGED
Binary files a/__pycache__/transcription.cpython-310.pyc and b/__pycache__/transcription.cpython-310.pyc differ
 
app.py CHANGED
@@ -1,223 +1,224 @@
1
- from flask import Flask, request, jsonify, render_template, send_from_directory
2
- import base64
3
- from pydub import AudioSegment # 変換用にpydubをインポート
4
- import os
5
- import shutil
6
- from process import AudioProcessor
7
- from transcription import TranscriptionMaker
8
- from analyze import TextAnalyzer
9
- import json
10
-
11
- process=AudioProcessor()
12
- transcripter = TranscriptionMaker()
13
- app = Flask(__name__)
14
-
15
- users = []
16
- transcription_text=""
17
- harassment_keywords = [
18
- "バカ", "馬鹿", "アホ", "死ね", "クソ", "うざい",
19
- "きもい", "キモい", "ブス", "デブ", "ハゲ",
20
- "セクハラ", "パワハラ", "モラハラ"
21
- ]
22
- total_audio = ""
23
-
24
- # トップページ(テンプレート: index.html)
25
- @app.route('/')
26
- @app.route('/index', methods=['GET', 'POST'])
27
- def index():
28
- return render_template('index.html', users = users)
29
-
30
- # フィードバック画面(テンプレート: feedback.html)
31
- @app.route('/feedback', methods=['GET', 'POST'])
32
- def feedback():
33
- return render_template('feedback.html')
34
-
35
- # 会話詳細画面(テンプレート: talkDetail.html)
36
- @app.route('/talk_detail', methods=['GET', 'POST'])
37
- def talk_detail():
38
- return render_template('talkDetail.html')
39
-
40
- # 音声登録画面(テンプレート: userRegister.html)
41
- @app.route('/userregister', methods=['GET', 'POST'])
42
- def userregister():
43
- return render_template('userRegister.html')
44
-
45
- #人数確認
46
- @app.route('/confirm', methods=['GET']) # 基本的にGETで取得する想定なので、GETのみに変更
47
- def confirm():
48
- return jsonify({'members': users}), 200
49
-
50
- #リセット画面(テンプレート: reset.html)
51
- @app.route('/reset_html', methods=['GET', 'POST'])
52
- def reset_html():
53
- return render_template('reset.html')
54
-
55
- #メンバー削除&累積音声削除
56
- @app.route('/reset_member', methods=['GET', 'POST'])
57
- def reset_member():
58
- global users
59
- global total_audio
60
- print(total_audio)
61
- process.delete_files_in_directory(total_audio)
62
- try:
63
- data = request.get_json()
64
- if not data or "names" not in data:
65
- return jsonify({"status": "error", "message": "Invalid request body"}), 400 # 400 Bad Request
66
-
67
- names = data.get("names", [])
68
- base_audio_dir = "/tmp/data/base_audio"
69
-
70
- for name in names:
71
- file_path = os.path.join(base_audio_dir, f"{name}.wav")
72
- if os.path.exists(file_path):
73
- try:
74
- os.remove(file_path)
75
- print(f"{file_path} を削除しました。")
76
- except Exception as e:
77
- print(f"削除中にエラーが発生しました: {e}")
78
- # ファイル削除に失敗した場合も、エラーを返す
79
- return jsonify({"status": "error", "message": f"Failed to delete {name}: {e}"}), 500
80
-
81
- else:
82
- print(f"ファイルが存在しません: {file_path}")
83
-
84
- # usersリストを更新
85
- users = [u for u in users if u not in names]
86
-
87
- # 成功した場合のレスポンス
88
- return jsonify({"status": "success", "message": "Members deleted successfully", "users": users}), 200 # 200 OK
89
-
90
- except Exception as e:
91
- print(f"An unexpected error occurred: {e}")
92
- return jsonify({"status": "error", "message": f"Internal server error: {e}"}), 500 # 500 Internal Server Error
93
-
94
- # 書き起こし作成エンドポイント
95
- @app.route('/transcription',methods =['GET','POST'])
96
- def transcription():
97
- global transcription_text
98
- global total_audio
99
- try:
100
- audio_directory = transcripter.merge_segments(total_audio)
101
- transcription_text = transcripter.create_transcription(audio_directory)
102
- with open(transcription_text,'r',encoding='utf-8') as file:
103
- file_content = file.read()
104
- print(file_content)
105
- return jsonify({'transcription': file_content}),200
106
- except Exception as e:
107
- return jsonify({"error": str(e)}),500
108
-
109
- # AI分析エンドポイント
110
- @app.route('/analyze',methods =['GET','POST'])
111
- def analyze():
112
- global transcription_text
113
- analyzer = TextAnalyzer(transcription_text, harassment_keywords)
114
- api_key = os.environ.get("DEEPSEEK")
115
- if api_key is None:
116
- raise ValueError("DEEPSEEK_API_KEY が設定されていません。")
117
-
118
- results = analyzer.analyze(api_key=api_key)
119
-
120
- print(json.dumps(results, ensure_ascii=False, indent=2))
121
-
122
- if "deepseek_analysis" in results and results["deepseek_analysis"]:
123
- deepseek_data = results["deepseek_analysis"]
124
- conversation_level = deepseek_data.get("conversationLevel")
125
- harassment_present = deepseek_data.get("harassmentPresent")
126
- harassment_type = deepseek_data.get("harassmentType")
127
- repetition = deepseek_data.get("repetition")
128
- pleasantConversation = deepseek_data.get("pleasantConversation")
129
- blameOrHarassment = deepseek_data.get("blameOrHarassment")
130
-
131
- print("\n--- DeepSeek 分析結果 ---")
132
- print(f"会話レベル: {conversation_level}")
133
- print(f"ハラスメントの有無: {harassment_present}")
134
- print(f"ハラスメントの種類: {harassment_type}")
135
- print(f"繰り返しの程度: {repetition}")
136
- print(f"会話の心地よさ: {pleasantConversation}")
137
- print(f"非難またはハラスメントの程度: {blameOrHarassment}")
138
- return jsonify({"results": results}),200
139
-
140
-
141
- # 音声アップロード&解析エンドポイント
142
- @app.route('/upload_audio', methods=['POST'])
143
- def upload_audio():
144
- global total_audio
145
- try:
146
- data = request.get_json()
147
- # name か users のいずれかが必須。どちらも無い場合はエラー
148
- if not data or 'audio_data' not in data or ('name' not in data and 'users' not in data):
149
- return jsonify({"error": "音声データまたは名前がありません"}), 400
150
-
151
- # Base64デコードして音声バイナリを取得
152
- audio_binary = base64.b64decode(data['audio_data'])
153
-
154
- upload_name = 'tmp'
155
- audio_dir = "/tmp/data"
156
- os.makedirs(audio_dir, exist_ok=True)
157
- audio_path = os.path.join(audio_dir, f"{upload_name}.wav")
158
- with open(audio_path, 'wb') as f:
159
- f.write(audio_binary)
160
- print(users)
161
- # 各ユーザーの参照音声ファイルのパスをリストに格納
162
- reference_paths = []
163
- base_audio_dir = "/tmp/data/base_audio"
164
- for user in users:
165
- ref_path = os.path.abspath(os.path.join(base_audio_dir, f"{user}.wav"))
166
- if not os.path.exists(ref_path):
167
- return jsonify({"error": "参照音声ファイルが見つかりません", "details": ref_path}), 500
168
- reference_paths.append(ref_path)
169
-
170
- # 複数人の場合は参照パスのリストを、1人の場合は単一のパスを渡す
171
- if len(users) > 1:
172
- print("複数人の場合の処理")
173
- matched_times, segments_dir = process.process_multi_audio(reference_paths, audio_path, threshold=0.05)
174
- total_audio = transcripter.merge_segments(segments_dir)
175
- # 各メンバーのrateを計算
176
- total_time = sum(matched_times)
177
- rates = [(time / total_time) * 100 if total_time > 0 else 0 for time in matched_times]
178
- return jsonify({"rates": rates}), 200
179
- else:
180
- matched_time, unmatched_time, segments_dir = process.process_audio(reference_paths[0], audio_path, threshold=0.05)
181
- total_audio = transcripter.merge_segments(segments_dir)
182
- total_time = matched_time + unmatched_time
183
- rate = (matched_time / total_time) * 100 if total_time > 0 else 0
184
- return jsonify({"rate": rate}), 200
185
- except Exception as e:
186
- print("Error in /upload_audio:", str(e))
187
- return jsonify({"error": "サーバーエラー", "details": str(e)}), 500
188
-
189
- @app.route('/reset', methods=['GET'])
190
- def reset():
191
- global users
192
- users=[]
193
- return 200
194
-
195
- @app.route('/upload_base_audio', methods=['POST'])
196
- def upload_base_audio():
197
- global users#グローバル変数を編集できるようにする
198
- try:
199
- data = request.get_json()
200
- if not data or 'audio_data' not in data or 'name' not in data:
201
- return jsonify({"error": "音声データまたは名前がありません"}), 400
202
- name = data['name'] # 名前を取得
203
- print(name)
204
-
205
-
206
- users.append(name)
207
- users=list(set(users))#重複排除
208
- print(users)
209
-
210
-
211
- audio_path=process.save_audio_from_base64(
212
- base64_audio=data['audio_data'], # 音声データ
213
- output_dir= "/tmp/data/base_audio", #保存先
214
- output_filename=f"{name}.wav" # 固定ファイル名(必要に応じて generate_filename() で一意のファイル名に変更可能)
215
- )
216
- return jsonify({"state": "Registration Success!", "path": audio_path}), 200
217
- except Exception as e:
218
- print("Error in /upload_base_audio:", str(e))
219
- return jsonify({"error": "サーバーエラー", "details": str(e)}), 500
220
-
221
- if __name__ == '__main__':
222
- port = int(os.environ.get("PORT", 7860))
 
223
  app.run(debug=True, host="0.0.0.0", port=port)
 
1
+ from flask import Flask, request, jsonify, render_template, send_from_directory
2
+ import base64
3
+ from pydub import AudioSegment # 変換用にpydubをインポート
4
+ import os
5
+ import shutil
6
+ from process import AudioProcessor
7
+ from transcription import TranscriptionMaker
8
+ from analyze import TextAnalyzer
9
+ import json
10
+
11
+ process=AudioProcessor()
12
+ transcripter = TranscriptionMaker()
13
+ app = Flask(__name__)
14
+
15
+ users = []
16
+ transcription_text=""
17
+ harassment_keywords = [
18
+ "バカ", "馬鹿", "���ホ", "死ね", "クソ", "うざい",
19
+ "きもい", "キモい", "ブス", "デブ", "ハゲ",
20
+ "セクハラ", "パワハラ", "モラハラ"
21
+ ]
22
+ total_audio = ""
23
+
24
+ # トップページ(テンプレート: index.html)
25
+ @app.route('/index', methods=['GET', 'POST'])
26
+ def index():
27
+ return render_template('index.html', users = users)
28
+
29
+ # フィードバック画面(テンプレート: feedback.html)
30
+ @app.route('/feedback', methods=['GET', 'POST'])
31
+ def feedback():
32
+ return render_template('feedback.html')
33
+
34
+ # 会話詳細画面(テンプレート: talkDetail.html)
35
+ @app.route('/talk_detail', methods=['GET', 'POST'])
36
+ def talk_detail():
37
+ return render_template('talkDetail.html')
38
+
39
+ # 音声登録画面(テンプレート: userRegister.html)
40
+ @app.route('/')
41
+ @app.route('/userregister', methods=['GET', 'POST'])
42
+ def userregister():
43
+ return render_template('userRegister.html')
44
+
45
+ #人数確認
46
+ @app.route('/confirm', methods=['GET']) # 基本的にGETで取得する想定なので、GETのみに変更
47
+ def confirm():
48
+ return jsonify({'members': users}), 200
49
+
50
+ #リセット画面(テンプレート: reset.html)
51
+ @app.route('/reset_html', methods=['GET', 'POST'])
52
+ def reset_html():
53
+ return render_template('reset.html')
54
+
55
+ #メンバー削除&累積音声削除
56
+ @app.route('/reset_member', methods=['GET', 'POST'])
57
+ def reset_member():
58
+ global users
59
+ global total_audio
60
+ print(total_audio)
61
+ process.delete_files_in_directory(total_audio)
62
+ try:
63
+ data = request.get_json()
64
+ if not data or "names" not in data:
65
+ return jsonify({"status": "error", "message": "Invalid request body"}), 400 # 400 Bad Request
66
+
67
+ names = data.get("names", [])
68
+ base_audio_dir = "/tmp/data/base_audio"
69
+
70
+ for name in names:
71
+ file_path = os.path.join(base_audio_dir, f"{name}.wav")
72
+ if os.path.exists(file_path):
73
+ try:
74
+ os.remove(file_path)
75
+ print(f"{file_path} を削除しました。")
76
+ except Exception as e:
77
+ print(f"削除中にエラーが発生しました: {e}")
78
+ # ファイル削除に失敗した場合も、エラーを返す
79
+ return jsonify({"status": "error", "message": f"Failed to delete {name}: {e}"}), 500
80
+
81
+ else:
82
+ print(f"ファイルが存在しません: {file_path}")
83
+
84
+ # usersリストを更新
85
+ users = [u for u in users if u not in names]
86
+
87
+ # 成功した場合のレスポンス
88
+ return jsonify({"status": "success", "message": "Members deleted successfully", "users": users}), 200 # 200 OK
89
+
90
+ except Exception as e:
91
+ print(f"An unexpected error occurred: {e}")
92
+ return jsonify({"status": "error", "message": f"Internal server error: {e}"}), 500 # 500 Internal Server Error
93
+
94
+ # 書き起こし作成エンドポイント
95
+ @app.route('/transcription',methods =['GET','POST'])
96
+ def transcription():
97
+ global transcription_text
98
+ global total_audio
99
+ try:
100
+ audio_directory = transcripter.merge_segments(total_audio)
101
+ transcription_text = transcripter.create_transcription(audio_directory)
102
+ with open(transcription_text,'r',encoding='utf-8') as file:
103
+ file_content = file.read()
104
+ print(file_content)
105
+ return jsonify({'transcription': file_content}),200
106
+ except Exception as e:
107
+ return jsonify({"error": str(e)}),500
108
+
109
+ # AI分析エンドポイント
110
+ @app.route('/analyze',methods =['GET','POST'])
111
+ def analyze():
112
+ global transcription_text
113
+ analyzer = TextAnalyzer(transcription_text, harassment_keywords)
114
+ api_key = os.environ.get("DEEPSEEK")
115
+ if api_key is None:
116
+ raise ValueError("DEEPSEEK_API_KEY が設定されていません。")
117
+
118
+ results = analyzer.analyze(api_key=api_key)
119
+
120
+ print(json.dumps(results, ensure_ascii=False, indent=2))
121
+
122
+ if "deepseek_analysis" in results and results["deepseek_analysis"]:
123
+ deepseek_data = results["deepseek_analysis"]
124
+ conversation_level = deepseek_data.get("conversationLevel")
125
+ harassment_present = deepseek_data.get("harassmentPresent")
126
+ harassment_type = deepseek_data.get("harassmentType")
127
+ repetition = deepseek_data.get("repetition")
128
+ pleasantConversation = deepseek_data.get("pleasantConversation")
129
+ blameOrHarassment = deepseek_data.get("blameOrHarassment")
130
+
131
+ print("\n--- DeepSeek 分析結果 ---")
132
+ print(f"会話レベル: {conversation_level}")
133
+ print(f"ハラスメントの有無: {harassment_present}")
134
+ print(f"ハラスメントの種類: {harassment_type}")
135
+ print(f"繰り返しの程度: {repetition}")
136
+ print(f"会話の心地よさ: {pleasantConversation}")
137
+ print(f"非難またはハラスメントの程度: {blameOrHarassment}")
138
+ return jsonify({"results": results}),200
139
+
140
+
141
+ # 音声アップロード&解析エ��ドポイント
142
+ @app.route('/upload_audio', methods=['POST'])
143
+ def upload_audio():
144
+ global total_audio
145
+ try:
146
+ data = request.get_json()
147
+ # name か users のいずれかが必須。どちらも無い場合はエラー
148
+ if not data or 'audio_data' not in data or ('name' not in data and 'users' not in data):
149
+ return jsonify({"error": "音声データまたは名前がありません"}), 400
150
+
151
+ # Base64デコードして音声バイナリを取得
152
+ audio_binary = base64.b64decode(data['audio_data'])
153
+
154
+ upload_name = 'tmp'
155
+ audio_dir = "/tmp/data"
156
+ os.makedirs(audio_dir, exist_ok=True)
157
+ audio_path = os.path.join(audio_dir, f"{upload_name}.wav")
158
+ with open(audio_path, 'wb') as f:
159
+ f.write(audio_binary)
160
+ print(users)
161
+ # 各ユーザーの参照音声ファイルのパスをリストに格納
162
+ reference_paths = []
163
+ base_audio_dir = "/tmp/data/base_audio"
164
+ for user in users:
165
+ ref_path = os.path.abspath(os.path.join(base_audio_dir, f"{user}.wav"))
166
+ if not os.path.exists(ref_path):
167
+ return jsonify({"error": "参照音声ファイルが見つかりません", "details": ref_path}), 500
168
+ reference_paths.append(ref_path)
169
+
170
+ # 複数人の場合は参照パスのリストを、1人の場合は単一のパスを渡す
171
+ if len(users) > 1:
172
+ print("複数人の場合の処理")
173
+ matched_times, segments_dir = process.process_multi_audio(reference_paths, audio_path, threshold=0.05)
174
+ total_audio = transcripter.merge_segments(segments_dir)
175
+ # 各メンバーのrateを計算
176
+ total_time = sum(matched_times)
177
+ rates = [(time / total_time) * 100 if total_time > 0 else 0 for time in matched_times]
178
+ return jsonify({"rates": rates}), 200
179
+ else:
180
+ matched_time, unmatched_time, segments_dir = process.process_audio(reference_paths[0], audio_path, threshold=0.05)
181
+ total_audio = transcripter.merge_segments(segments_dir)
182
+ total_time = matched_time + unmatched_time
183
+ rate = (matched_time / total_time) * 100 if total_time > 0 else 0
184
+ return jsonify({"rate": rate}), 200
185
+ except Exception as e:
186
+ print("Error in /upload_audio:", str(e))
187
+ return jsonify({"error": "サーバーエラー", "details": str(e)}), 500
188
+
189
+ @app.route('/reset', methods=['GET'])
190
+ def reset():
191
+ global users
192
+ users = []
193
+ return jsonify({"status": "success", "message": "Users reset"}), 200
194
+
195
+
196
+ @app.route('/upload_base_audio', methods=['POST'])
197
+ def upload_base_audio():
198
+ global users#グローバル変数を編集できるようにする
199
+ try:
200
+ data = request.get_json()
201
+ if not data or 'audio_data' not in data or 'name' not in data:
202
+ return jsonify({"error": "音声データまたは名前がありません"}), 400
203
+ name = data['name'] # 名前を取得
204
+ print(name)
205
+
206
+
207
+ users.append(name)
208
+ users=list(set(users))#重複排除
209
+ print(users)
210
+
211
+
212
+ audio_path=process.save_audio_from_base64(
213
+ base64_audio=data['audio_data'], # 音声データ
214
+ output_dir= "/tmp/data/base_audio", #保存先
215
+ output_filename=f"{name}.wav" # 固定ファイル名(必要に応じて generate_filename() で一意のファイル名に変更可能)
216
+ )
217
+ return jsonify({"state": "Registration Success!", "path": audio_path}), 200
218
+ except Exception as e:
219
+ print("Error in /upload_base_audio:", str(e))
220
+ return jsonify({"error": "サーバーエラー", "details": str(e)}), 500
221
+
222
+ if __name__ == '__main__':
223
+ port = int(os.environ.get("PORT", 7860))
224
  app.run(debug=True, host="0.0.0.0", port=port)