SOY NV AI
๋ฉํ๋ฐ์ดํฐ ์์ฑ ๊ธฐ๋ฅ ๊ฐ์ : ๊ธฐ์กด ๋ฉํ๋ฐ์ดํฐ ๋ณํฉ ๋ฐ ํ์ฐจ ์ ๋ณด ์ ์ง
d234e06
| """ | |
| Flask ์ ํ๋ฆฌ์ผ์ด์ ์ด๊ธฐํ | |
| """ | |
| from flask import Flask | |
| from flask_login import LoginManager | |
| import sqlite3 | |
| from pathlib import Path | |
| from typing import Optional | |
| from app.database import db, User | |
| from app.core.config import Config, get_config | |
| from app.core.logger import get_logger | |
| logger = get_logger(__name__) | |
| login_manager = LoginManager() | |
| login_manager.login_view = 'main.login' | |
| login_manager.login_message = '๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค.' | |
| login_manager.login_message_category = 'info' | |
| def load_user(user_id: str) -> Optional[User]: | |
| """ | |
| ์ฌ์ฉ์ ๋ก๋ ํจ์ (Flask-Login์ฉ) | |
| Args: | |
| user_id: ์ฌ์ฉ์ ID (๋ฌธ์์ด) | |
| Returns: | |
| User ๊ฐ์ฒด ๋๋ None | |
| """ | |
| try: | |
| return User.query.get(int(user_id)) | |
| except (ValueError, TypeError): | |
| return None | |
| def create_app() -> Flask: | |
| """ | |
| Flask ์ ํ๋ฆฌ์ผ์ด์ ํฉํ ๋ฆฌ ํจ์ | |
| Returns: | |
| ์ค์ ๋ Flask ์ ํ๋ฆฌ์ผ์ด์ ์ธ์คํด์ค | |
| """ | |
| config = get_config() | |
| # ํ์ ๋๋ ํ ๋ฆฌ ์์ฑ | |
| config.ensure_directories() | |
| # ํ ํ๋ฆฟ ํด๋ ๋ฐ static ํด๋ ๊ฒฝ๋ก ์ค์ | |
| template_folder = str(config.TEMPLATES_FOLDER) | |
| static_folder = str(config.STATIC_FOLDER) | |
| app = Flask(__name__, template_folder=template_folder, static_folder=static_folder) | |
| # Flask ์ค์ ์ ์ฉ | |
| app.config['SECRET_KEY'] = config.SECRET_KEY | |
| app.config['SQLALCHEMY_DATABASE_URI'] = config.SQLALCHEMY_DATABASE_URI | |
| app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = config.SQLALCHEMY_TRACK_MODIFICATIONS | |
| app.config['MAX_CONTENT_LENGTH'] = config.MAX_CONTENT_LENGTH | |
| # ํ์ฅ ์ด๊ธฐํ | |
| db.init_app(app) | |
| login_manager.init_app(app) | |
| # Blueprint ๋ฑ๋ก | |
| from app.routes import main_bp | |
| app.register_blueprint(main_bp) | |
| # ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ด๊ธฐํ ๋ฐ ๋ง์ด๊ทธ๋ ์ด์ | |
| with app.app_context(): | |
| db.create_all() | |
| migrate_database(app) | |
| create_admin_user() | |
| logger.info("Flask ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ด๊ธฐํ๋์์ต๋๋ค.") | |
| return app | |
| def migrate_database(app: Flask) -> None: | |
| """ | |
| ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ง์ด๊ทธ๋ ์ด์ ์คํ | |
| Args: | |
| app: Flask ์ ํ๋ฆฌ์ผ์ด์ ์ธ์คํด์ค | |
| """ | |
| try: | |
| db_uri = app.config['SQLALCHEMY_DATABASE_URI'] | |
| if not db_uri.startswith('sqlite:///'): | |
| logger.warning(f"SQLite๊ฐ ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์๋ ๋ง์ด๊ทธ๋ ์ด์ ์ด ์ง์๋์ง ์์ต๋๋ค: {db_uri}") | |
| return | |
| db_path_str = db_uri.replace('sqlite:///', '') | |
| db_path = Path(db_path_str) | |
| # ์๋ ๊ฒฝ๋ก์ธ ๊ฒฝ์ฐ instance ํด๋ ๊ธฐ์ค์ผ๋ก ์ฒ๋ฆฌ | |
| if not db_path.is_absolute(): | |
| db_path = Path(app.instance_path) / db_path | |
| if not db_path.exists(): | |
| logger.info(f"๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์ผ์ด ์์ต๋๋ค (์๋ก ์์ฑ๋จ): {db_path}") | |
| return | |
| logger.info(f"๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ง์ด๊ทธ๋ ์ด์ ์์: {db_path}") | |
| conn = sqlite3.connect(str(db_path)) | |
| cursor = conn.cursor() | |
| # user ํ ์ด๋ธ์ nickname ์ปฌ๋ผ์ด ์๋์ง ํ์ธ | |
| cursor.execute("PRAGMA table_info(user)") | |
| user_columns = [column[1] for column in cursor.fetchall()] | |
| if 'nickname' not in user_columns: | |
| logger.info("user ํ ์ด๋ธ์ nickname ์ปฌ๋ผ ์ถ๊ฐ ์ค...") | |
| cursor.execute("ALTER TABLE user ADD COLUMN nickname VARCHAR(80)") | |
| conn.commit() | |
| logger.info("user.nickname ์ปฌ๋ผ ์ถ๊ฐ ์๋ฃ") | |
| # uploaded_file ํ ์ด๋ธ์ด ์กด์ฌํ๋์ง ํ์ธ | |
| cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='uploaded_file'") | |
| if cursor.fetchone(): | |
| cursor.execute("PRAGMA table_info(uploaded_file)") | |
| uploaded_file_columns = [column[1] for column in cursor.fetchall()] | |
| if 'uploaded_by' not in uploaded_file_columns: | |
| logger.info("uploaded_file ํ ์ด๋ธ์ uploaded_by ์ปฌ๋ผ ์ถ๊ฐ ์ค...") | |
| cursor.execute("ALTER TABLE uploaded_file ADD COLUMN uploaded_by INTEGER") | |
| conn.commit() | |
| logger.info("uploaded_file.uploaded_by ์ปฌ๋ผ ์ถ๊ฐ ์๋ฃ") | |
| if 'parent_file_id' not in uploaded_file_columns: | |
| logger.info("uploaded_file ํ ์ด๋ธ์ parent_file_id ์ปฌ๋ผ ์ถ๊ฐ ์ค...") | |
| cursor.execute("ALTER TABLE uploaded_file ADD COLUMN parent_file_id INTEGER") | |
| conn.commit() | |
| logger.info("uploaded_file.parent_file_id ์ปฌ๋ผ ์ถ๊ฐ ์๋ฃ") | |
| # document_chunk ํ ์ด๋ธ์ด ์กด์ฌํ๋์ง ํ์ธ | |
| cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='document_chunk'") | |
| if cursor.fetchone(): | |
| cursor.execute("PRAGMA table_info(document_chunk)") | |
| document_chunk_columns = [column[1] for column in cursor.fetchall()] | |
| if 'chunk_metadata' not in document_chunk_columns: | |
| logger.info("document_chunk ํ ์ด๋ธ์ chunk_metadata ์ปฌ๋ผ ์ถ๊ฐ ์ค...") | |
| cursor.execute("ALTER TABLE document_chunk ADD COLUMN chunk_metadata TEXT") | |
| conn.commit() | |
| logger.info("document_chunk.chunk_metadata ์ปฌ๋ผ ์ถ๊ฐ ์๋ฃ") | |
| conn.close() | |
| logger.info("๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ง์ด๊ทธ๋ ์ด์ ์๋ฃ") | |
| except sqlite3.Error as e: | |
| logger.error(f"๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ง์ด๊ทธ๋ ์ด์ ์ค SQLite ์ค๋ฅ ๋ฐ์: {e}", exc_info=True) | |
| except Exception as e: | |
| logger.error(f"๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ง์ด๊ทธ๋ ์ด์ ์ค ์ค๋ฅ ๋ฐ์: {e}", exc_info=True) | |
| def create_admin_user() -> None: | |
| """ | |
| ์ด๊ธฐ ๊ด๋ฆฌ์ ๊ณ์ ์์ฑ | |
| """ | |
| admin_username = 'soymedia' | |
| admin_password = 's0ymedi@1@34' | |
| try: | |
| admin = User.query.filter_by(username=admin_username).first() | |
| if not admin: | |
| admin = User(username=admin_username, is_admin=True, is_active=True) | |
| admin.set_password(admin_password) | |
| db.session.add(admin) | |
| db.session.commit() | |
| logger.info(f'๊ด๋ฆฌ์ ๊ณ์ ์ด ์์ฑ๋์์ต๋๋ค: {admin_username}') | |
| else: | |
| logger.debug(f'๊ด๋ฆฌ์ ๊ณ์ ์ด ์ด๋ฏธ ์กด์ฌํฉ๋๋ค: {admin_username}') | |
| except Exception as e: | |
| logger.error(f'๊ด๋ฆฌ์ ๊ณ์ ์์ฑ ์ค ์ค๋ฅ ๋ฐ์: {e}', exc_info=True) | |
| db.session.rollback() | |