from flask import Flask, request, jsonify, render_template, send_from_directory import base64 from pydub import AudioSegment # 変換用にpydubをインポート import os import shutil from process import AudioProcessor from transcription import TranscriptionMaker from analyze import TextAnalyzer import json process=AudioProcessor() transcripter = TranscriptionMaker() app = Flask(__name__) users = [] transcription_text="" harassment_keywords = [ "バカ", "馬鹿", "アホ", "死ね", "クソ", "うざい", "きもい", "キモい", "ブス", "デブ", "ハゲ", "セクハラ", "パワハラ", "モラハラ" ] total_audio = "" # トップページ(テンプレート: index.html) @app.route('/') @app.route('/index', methods=['GET', 'POST']) def index(): return render_template('index.html', users = users) # フィードバック画面(テンプレート: feedback.html) @app.route('/feedback', methods=['GET', 'POST']) def feedback(): return render_template('feedback.html') # 会話詳細画面(テンプレート: talkDetail.html) @app.route('/talk_detail', methods=['GET', 'POST']) def talk_detail(): return render_template('talkDetail.html') # 音声登録画面(テンプレート: userRegister.html) @app.route('/userregister', methods=['GET', 'POST']) def userregister(): return render_template('userRegister.html') #人数確認 @app.route('/confirm', methods=['GET']) # 基本的にGETで取得する想定なので、GETのみに変更 def confirm(): return jsonify({'members': users}), 200 #リセット画面(テンプレート: reset.html) @app.route('/reset_html', methods=['GET', 'POST']) def reset_html(): return render_template('reset.html') #メンバー削除&累積音声削除 @app.route('/reset_member', methods=['GET', 'POST']) def reset_member(): global users # ←これを追加! #data = request.get_json() #name = data['name'] # 名前を取得 global total_audio print(total_audio) process.delete_files_in_directory(total_audio) base_audio_dir = "/tmp/data/base_audio" for name in users: file_path = os.path.join(base_audio_dir, f"{name}.wav") if os.path.exists(file_path): try: os.remove(file_path) print(f"{file_path} を削除しました。") except Exception as e: print(f"削除中にエラーが発生しました: {e}") else: print(f"ファイルが存在しません: {file_path}") users.clear() return render_template('index.html', users = users) # 書き起こし作成エンドポイント @app.route('/transcription',methods =['GET','POST']) def transcription(): global transcription_text global total_audio print(total_audio) try: transcription_text = transcripter.create_transcription(total_audio) print(transcription_text) with open(transcription_text,'r',encoding='utf-8') as file: file_content = file.read() print(file_content) return jsonify({'transcription': file_content}),200 except Exception as e: return jsonify({"error": str(e)}),500 # AI分析エンドポイント @app.route('/analyze',methods =['GET','POST']) def analyze(): global transcription_text analyzer = TextAnalyzer(transcription_text, harassment_keywords) api_key = os.environ.get("DEEPSEEK") if api_key is None: raise ValueError("DEEPSEEK_API_KEY が設定されていません。") results = analyzer.analyze(api_key=api_key) print(json.dumps(results, ensure_ascii=False, indent=2)) if "deepseek_analysis" in results and results["deepseek_analysis"]: deepseek_data = results["deepseek_analysis"] conversation_level = deepseek_data.get("conversationLevel") harassment_present = deepseek_data.get("harassmentPresent") harassment_type = deepseek_data.get("harassmentType") repetition = deepseek_data.get("repetition") pleasantConversation = deepseek_data.get("pleasantConversation") blameOrHarassment = deepseek_data.get("blameOrHarassment") print("\n--- DeepSeek 分析結果 ---") print(f"会話レベル: {conversation_level}") print(f"ハラスメントの有無: {harassment_present}") print(f"ハラスメントの種類: {harassment_type}") print(f"繰り返しの程度: {repetition}") print(f"会話の心地よさ: {pleasantConversation}") print(f"非難またはハラスメントの程度: {blameOrHarassment}") return jsonify({"results": results}),200 # 音声アップロード&解析エンドポイント @app.route('/upload_audio', methods=['POST']) def upload_audio(): global total_audio try: data = request.get_json() # name か users のいずれかが必須。どちらも無い場合はエラー if not data or 'audio_data' not in data or ('name' not in data and 'users' not in data): return jsonify({"error": "音声データまたは名前がありません"}), 400 # Base64デコードして音声バイナリを取得 audio_binary = base64.b64decode(data['audio_data']) upload_name = 'tmp' audio_dir = "/tmp/data" os.makedirs(audio_dir, exist_ok=True) audio_path = os.path.join(audio_dir, f"{upload_name}.wav") with open(audio_path, 'wb') as f: f.write(audio_binary) print(users) # 各ユーザーの参照音声ファイルのパスをリストに格納 reference_paths = [] base_audio_dir = "/tmp/data/base_audio" for user in users: ref_path = os.path.abspath(os.path.join(base_audio_dir, f"{user}.wav")) if not os.path.exists(ref_path): return jsonify({"error": "参照音声ファイルが見つかりません", "details": ref_path}), 500 reference_paths.append(ref_path) # 複数人の場合は参照パスのリストを、1人の場合は単一のパスを渡す if len(users) > 1: print("複数人の場合の処理") matched_times, segments_dir = process.process_multi_audio(reference_paths, audio_path, threshold=0.05) total_audio = transcripter.merge_segments(segments_dir) # 各メンバーのrateを計算 total_time = sum(matched_times) rates = [(time / total_time) * 100 if total_time > 0 else 0 for time in matched_times] return jsonify({"rates": rates}), 200 else: matched_time, unmatched_time, segments_dir = process.process_audio(reference_paths[0], audio_path, threshold=0.05) total_audio = transcripter.merge_segments(segments_dir) total_time = matched_time + unmatched_time rate = (matched_time / total_time) * 100 if total_time > 0 else 0 return jsonify({"rate": rate}), 200 except Exception as e: print("Error in /upload_audio:", str(e)) return jsonify({"error": "サーバーエラー", "details": str(e)}), 500 @app.route('/reset', methods=['GET']) def reset(): global users users=[] return 200 @app.route('/upload_base_audio', methods=['POST']) def upload_base_audio(): global users#グローバル変数を編集できるようにする try: data = request.get_json() if not data or 'audio_data' not in data or 'name' not in data: return jsonify({"error": "音声データまたは名前がありません"}), 400 name = data['name'] # 名前を取得 print(name) users.append(name) users=list(set(users))#重複排除 print(users) audio_path=process.save_audio_from_base64( base64_audio=data['audio_data'], # 音声データ output_dir= "/tmp/data/base_audio", #保存先 output_filename=f"{name}.wav" # 固定ファイル名(必要に応じて generate_filename() で一意のファイル名に変更可能) ) return jsonify({"state": "Registration Success!", "path": audio_path}), 200 except Exception as e: print("Error in /upload_base_audio:", str(e)) return jsonify({"error": "サーバーエラー", "details": str(e)}), 500 if __name__ == '__main__': port = int(os.environ.get("PORT", 7860)) app.run(debug=True, host="0.0.0.0", port=port)