File size: 9,531 Bytes
77591a2
 
 
 
 
 
c14545d
77901a2
 
77591a2
 
4f6a6c3
77591a2
 
 
77901a2
 
 
 
 
 
3fbb133
77591a2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4f6a6c3
77591a2
 
 
 
 
a776d5a
 
 
 
ac884fd
a49984b
a776d5a
ba81acb
8b37533
a49984b
 
 
8b37533
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a776d5a
dda9dff
 
 
77901a2
3fbb133
a49984b
ac884fd
3fbb133
ac884fd
 
 
 
 
 
 
77901a2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
611943f
77591a2
 
 
 
3fbb133
77591a2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1804233
3fbb133
611943f
 
 
 
77591a2
1804233
3fbb133
611943f
 
 
77591a2
 
 
a49984b
77591a2
 
 
 
 
a49984b
77591a2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48f9750
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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
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
    global total_audio
    print(total_audio)
    process.delete_files_in_directory(total_audio)
    try:
        data = request.get_json()
        if not data or "names" not in data:
            return jsonify({"status": "error", "message": "Invalid request body"}), 400  # 400 Bad Request

        names = data.get("names", [])
        base_audio_dir = "/tmp/data/base_audio"

        for name in names:
            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}")
                    # ファイル削除に失敗した場合も、エラーを返す
                    return jsonify({"status": "error", "message": f"Failed to delete {name}: {e}"}), 500

            else:
                print(f"ファイルが存在しません: {file_path}")

        # usersリストを更新
        users = [u for u in users if u not in names]

        # 成功した場合のレスポンス
        return jsonify({"status": "success", "message": "Members deleted successfully", "users": users}), 200 # 200 OK

    except Exception as e:
        print(f"An unexpected error occurred: {e}")
        return jsonify({"status": "error", "message": f"Internal server error: {e}"}), 500  # 500 Internal Server Error

# 書き起こし作成エンドポイント
@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)