jeongsoo commited on
Commit
ece728f
Β·
1 Parent(s): 1681cd4
app/app_revised.py CHANGED
@@ -3,17 +3,22 @@ RAG 검색 챗봇 μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜ (μž₯치 관리 κΈ°λŠ₯ 톡합)
3
  """
4
 
5
  import os
 
6
  import logging
 
7
  import threading
8
- from datetime import datetime, timedelta
9
- from flask import Flask, send_from_directory
 
 
10
  from dotenv import load_dotenv
11
  from functools import wraps
 
12
 
13
  # 둜거 μ„€μ •
14
  logging.basicConfig(
15
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
16
- level=logging.DEBUG
17
  )
18
  logger = logging.getLogger(__name__)
19
 
@@ -57,6 +62,9 @@ except ImportError as e:
57
  # Flask μ•± μ΄ˆκΈ°ν™”
58
  app = Flask(__name__)
59
 
 
 
 
60
  # μ„Έμ…˜ μ„€μ •
61
  app.secret_key = os.getenv('FLASK_SECRET_KEY', 'rag_chatbot_fixed_secret_key_12345')
62
 
@@ -226,6 +234,16 @@ def initialize_app():
226
  # 라우트 등둝
227
  register_all_routes()
228
 
 
 
 
 
 
 
 
 
 
 
229
  logger.info("μ•± μ΄ˆκΈ°ν™” μ™„λ£Œ")
230
 
231
 
 
3
  """
4
 
5
  import os
6
+ import json
7
  import logging
8
+ import tempfile
9
  import threading
10
+ import datetime
11
+ from flask import Flask, request, jsonify, render_template, send_from_directory, session, redirect, url_for
12
+ from flask_cors import CORS
13
+ from werkzeug.utils import secure_filename
14
  from dotenv import load_dotenv
15
  from functools import wraps
16
+ from datetime import timedelta
17
 
18
  # 둜거 μ„€μ •
19
  logging.basicConfig(
20
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
21
+ level=logging.DEBUG # INFOμ—μ„œ DEBUG둜 λ³€κ²½ν•˜μ—¬ 더 μƒμ„Έν•œ 둜그 확인
22
  )
23
  logger = logging.getLogger(__name__)
24
 
 
62
  # Flask μ•± μ΄ˆκΈ°ν™”
63
  app = Flask(__name__)
64
 
65
+ # CORS μ„€μ • μΆ”κ°€
66
+ CORS(app, supports_credentials=True, resources={r"/api/*": {"origins": "*"}})
67
+
68
  # μ„Έμ…˜ μ„€μ •
69
  app.secret_key = os.getenv('FLASK_SECRET_KEY', 'rag_chatbot_fixed_secret_key_12345')
70
 
 
234
  # 라우트 등둝
235
  register_all_routes()
236
 
237
+ # 404 였λ₯˜ ν•Έλ“€λŸ¬ μΆ”κ°€
238
+ @app.errorhandler(404)
239
+ def not_found(e):
240
+ # JSON ν˜•μ‹μœΌλ‘œ 404 였λ₯˜ 응닡
241
+ return jsonify({
242
+ "success": False,
243
+ "error": "Endpoint not found",
244
+ "message": str(e)
245
+ }), 404
246
+
247
  logger.info("μ•± μ΄ˆκΈ°ν™” μ™„λ£Œ")
248
 
249
 
app/static/js/app-device.js CHANGED
@@ -257,7 +257,16 @@ const DeviceControl = {
257
  method: 'GET'
258
  });
259
 
260
- const data = await response.json();
 
 
 
 
 
 
 
 
 
261
 
262
  if (response.ok && data.success) {
263
  // μƒνƒœ 확인 성곡
@@ -310,7 +319,19 @@ const DeviceControl = {
310
  method: 'GET'
311
  });
312
 
313
- const data = await response.json();
 
 
 
 
 
 
 
 
 
 
 
 
314
 
315
  if (response.ok && data.success) {
316
  // λͺ©λ‘ 쑰회 성곡
@@ -458,7 +479,19 @@ const DeviceControl = {
458
  body: JSON.stringify({})
459
  }, 15000); // 15초 νƒ€μž„μ•„μ›ƒ (싀행에 μ‹œκ°„μ΄ 더 걸릴 수 있음)
460
 
461
- const data = await response.json();
 
 
 
 
 
 
 
 
 
 
 
 
462
 
463
  if (response.ok && data.success) {
464
  // μ‹€ν–‰ 성곡
@@ -466,11 +499,14 @@ const DeviceControl = {
466
  this.showExecuteResult('success', `μ‹€ν–‰ 성곡: ${data.message || 'ν”„λ‘œκ·Έλž¨μ΄ μ„±κ³΅μ μœΌλ‘œ μ‹€ν–‰λ˜μ—ˆμŠ΅λ‹ˆλ‹€.'}`);
467
 
468
  // μ‹œμŠ€ν…œ μ•Œλ¦Ό
469
- AppUtils.addSystemNotification(`ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ 성곡: ${this.getSelectedProgramName()}`);
470
  } else {
471
  // μ‹€ν–‰ μ‹€νŒ¨
472
  console.error('ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ μ‹€νŒ¨:', data);
473
  this.showExecuteResult('error', `μ‹€ν–‰ μ‹€νŒ¨: ${data.error || 'μ•Œ 수 μ—†λŠ” 였λ₯˜'}`);
 
 
 
474
  }
475
  } catch (error) {
476
  // μ˜ˆμ™Έ λ°œμƒ
@@ -481,37 +517,15 @@ const DeviceControl = {
481
  } else {
482
  this.showExecuteResult('error', `ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ 쀑 였λ₯˜ λ°œμƒ: ${error.message}`);
483
  }
 
 
 
484
  } finally {
485
  // λ²„νŠΌ λ‹€μ‹œ ν™œμ„±ν™”
486
  this.elements.executeProgramBtn.disabled = false;
487
  }
488
  },
489
 
490
- // μ„ νƒλœ ν”„λ‘œκ·Έλž¨ 이름 κ°€μ Έμ˜€κΈ°
491
- getSelectedProgramName: function() {
492
- const dropdown = this.elements.programSelectDropdown;
493
- const selectedOption = dropdown.options[dropdown.selectedIndex];
494
- return selectedOption ? selectedOption.textContent : 'μ•Œ 수 μ—†λŠ” ν”„λ‘œκ·Έλž¨';
495
- },
496
-
497
- // ν”„λ‘œκ·Έλž¨ λͺ©λ‘ 였λ₯˜ ν‘œμ‹œ
498
- showProgramsError: function(errorMessage) {
499
- this.elements.programsList.innerHTML = `
500
- <div class="error-message">
501
- <i class="fas fa-exclamation-circle"></i> ${errorMessage}
502
- <button class="retry-button" id="retryLoadProgramsBtn">
503
- <i class="fas fa-sync"></i> λ‹€μ‹œ μ‹œλ„
504
- </button>
505
- </div>
506
- `;
507
-
508
- // μž¬μ‹œλ„ λ²„νŠΌ 이벀트 λ¦¬μŠ€λ„ˆ
509
- document.getElementById('retryLoadProgramsBtn').addEventListener('click', () => {
510
- console.log('ν”„λ‘œκ·Έλž¨ λͺ©λ‘ μž¬μ‹œλ„ λ²„νŠΌ 클릭');
511
- this.loadProgramsList();
512
- });
513
- },
514
-
515
  // μ‹€ν–‰ κ²°κ³Ό ν‘œμ‹œ
516
  showExecuteResult: function(status, message) {
517
  const resultElement = this.elements.executeResult;
@@ -542,6 +556,24 @@ const DeviceControl = {
542
  default:
543
  resultElement.textContent = message;
544
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
545
  }
546
  };
547
 
 
257
  method: 'GET'
258
  });
259
 
260
+ // 응닡 μƒνƒœ μ½”λ“œ λ‘œκΉ…
261
+ console.log(`μž₯치 μƒνƒœ 확인 응닡 μƒνƒœ: ${response.status}`);
262
+
263
+ let data;
264
+ try {
265
+ data = await response.json();
266
+ } catch (jsonError) {
267
+ console.error('JSON νŒŒμ‹± 였λ₯˜:', jsonError, await response.text());
268
+ throw new Error(`μ„œλ²„ 응닡을 μ²˜λ¦¬ν•  수 μ—†μŠ΅λ‹ˆλ‹€: ${jsonError.message}`);
269
+ }
270
 
271
  if (response.ok && data.success) {
272
  // μƒνƒœ 확인 성곡
 
319
  method: 'GET'
320
  });
321
 
322
+ // 응닡 μƒνƒœ μ½”λ“œ λ‘œκΉ…
323
+ console.log(`ν”„λ‘œκ·Έλž¨ λͺ©λ‘ 쑰회 응닡 μƒνƒœ: ${response.status}`);
324
+
325
+ let data;
326
+ try {
327
+ data = await response.json();
328
+ } catch (jsonError) {
329
+ console.error('JSON νŒŒμ‹± 였λ₯˜:', jsonError);
330
+ // 응닡 λ‚΄μš©μ„ ν…μŠ€νŠΈλ‘œ 확인
331
+ const responseText = await response.text();
332
+ console.error('응닡 ν…μŠ€νŠΈ:', responseText);
333
+ throw new Error(`μ„œλ²„ 응닡을 μ²˜λ¦¬ν•  수 μ—†μŠ΅λ‹ˆλ‹€: ${jsonError.message}`);
334
+ }
335
 
336
  if (response.ok && data.success) {
337
  // λͺ©λ‘ 쑰회 성곡
 
479
  body: JSON.stringify({})
480
  }, 15000); // 15초 νƒ€μž„μ•„μ›ƒ (싀행에 μ‹œκ°„μ΄ 더 걸릴 수 있음)
481
 
482
+ // 응닡 μƒνƒœ μ½”λ“œ λ‘œκΉ…
483
+ console.log(`ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ 응닡 μƒνƒœ: ${response.status}`);
484
+
485
+ let data;
486
+ try {
487
+ data = await response.json();
488
+ } catch (jsonError) {
489
+ console.error('JSON νŒŒμ‹± 였λ₯˜:', jsonError);
490
+ // 응닡 λ‚΄μš©μ„ ν…μŠ€νŠΈλ‘œ 확인
491
+ const responseText = await response.text();
492
+ console.error('응닡 ν…μŠ€νŠΈ:', responseText);
493
+ throw new Error(`μ„œλ²„ 응닡을 μ²˜λ¦¬ν•  수 μ—†μŠ΅λ‹ˆλ‹€: ${jsonError.message}`);
494
+ }
495
 
496
  if (response.ok && data.success) {
497
  // μ‹€ν–‰ 성곡
 
499
  this.showExecuteResult('success', `μ‹€ν–‰ 성곡: ${data.message || 'ν”„λ‘œκ·Έλž¨μ΄ μ„±κ³΅μ μœΌλ‘œ μ‹€ν–‰λ˜μ—ˆμŠ΅λ‹ˆλ‹€.'}`);
500
 
501
  // μ‹œμŠ€ν…œ μ•Œλ¦Ό
502
+ AppUtils.addSystemNotification(`ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ 성곡: ${data.message || 'ν”„λ‘œκ·Έλž¨μ΄ μ„±κ³΅μ μœΌλ‘œ μ‹€ν–‰λ˜μ—ˆμŠ΅λ‹ˆλ‹€.'}`);
503
  } else {
504
  // μ‹€ν–‰ μ‹€νŒ¨
505
  console.error('ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ μ‹€νŒ¨:', data);
506
  this.showExecuteResult('error', `μ‹€ν–‰ μ‹€νŒ¨: ${data.error || 'μ•Œ 수 μ—†λŠ” 였λ₯˜'}`);
507
+
508
+ // μ—λŸ¬ λ©”μ‹œμ§€
509
+ AppUtils.addErrorMessage(`ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ μ‹€νŒ¨: ${data.error || 'μ•Œ 수 μ—†λŠ” 였λ₯˜'}`);
510
  }
511
  } catch (error) {
512
  // μ˜ˆμ™Έ λ°œμƒ
 
517
  } else {
518
  this.showExecuteResult('error', `ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ 쀑 였λ₯˜ λ°œμƒ: ${error.message}`);
519
  }
520
+
521
+ // μ—λŸ¬ λ©”μ‹œμ§€
522
+ AppUtils.addErrorMessage(`ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ 쀑 였λ₯˜ λ°œμƒ: ${error.message}`);
523
  } finally {
524
  // λ²„νŠΌ λ‹€μ‹œ ν™œμ„±ν™”
525
  this.elements.executeProgramBtn.disabled = false;
526
  }
527
  },
528
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
529
  // μ‹€ν–‰ κ²°κ³Ό ν‘œμ‹œ
530
  showExecuteResult: function(status, message) {
531
  const resultElement = this.elements.executeResult;
 
556
  default:
557
  resultElement.textContent = message;
558
  }
559
+ },
560
+
561
+ // ν”„λ‘œκ·Έλž¨ λͺ©λ‘ 였λ₯˜ ν‘œμ‹œ
562
+ showProgramsError: function(errorMessage) {
563
+ this.elements.programsList.innerHTML = `
564
+ <div class="error-message">
565
+ <i class="fas fa-exclamation-circle"></i> ${errorMessage}
566
+ <button class="retry-button" id="retryLoadProgramsBtn">
567
+ <i class="fas fa-sync"></i> λ‹€μ‹œ μ‹œλ„
568
+ </button>
569
+ </div>
570
+ `;
571
+
572
+ // μž¬μ‹œλ„ λ²„νŠΌ 이벀트 λ¦¬μŠ€λ„ˆ
573
+ document.getElementById('retryLoadProgramsBtn').addEventListener('click', () => {
574
+ console.log('ν”„λ‘œκ·Έλž¨ λͺ©λ‘ μž¬μ‹œλ„ λ²„νŠΌ 클릭');
575
+ this.loadProgramsList();
576
+ });
577
  }
578
  };
579
 
requirements.txt CHANGED
@@ -9,3 +9,4 @@ nltk>=3.6.5
9
  sentence-transformers>=2.2.2
10
  gradio>=3.50.0,<4.0.0
11
  openai>=1.0.0
 
 
9
  sentence-transformers>=2.2.2
10
  gradio>=3.50.0,<4.0.0
11
  openai>=1.0.0
12
+ flask-cors>=3.0.10