kootaeng2
Feat: Implement user login and registration system
fd1e3ee
raw
history blame
5.85 kB
# src/app.py (์ตœ์ข… ํ†ตํ•ฉ ๋ฒ„์ „)
# ---------------------------------
# 1. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฐ ๋ชจ๋“ˆ ์ž„ํฌํŠธ
# ---------------------------------
import os
import random
from flask import Flask, render_template, request, jsonify, session, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
# 'ํ˜„์žฌ ํด๋”์— ์žˆ๋Š”' ๋ชจ๋“ˆ๋“ค์„ ์ƒ๋Œ€ ๊ฒฝ๋กœ๋กœ ์ž„ํฌํŠธ
from .emotion_engine import load_emotion_classifier, predict_emotion
from .recommender import Recommender
# ---------------------------------
# 2. Flask ์•ฑ ์ดˆ๊ธฐํ™” ๋ฐ ๊ธฐ๋ณธ ์„ค์ •
# ---------------------------------
app = Flask(__name__)
# ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํŒŒ์ผ ๊ฒฝ๋กœ ์„ค์ •
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'database.db')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# ์„ธ์…˜ ๋ฐ์ดํ„ฐ๋ฅผ ์•”ํ˜ธํ™”ํ•˜๊ธฐ ์œ„ํ•œ ์‹œํฌ๋ฆฟ ํ‚ค (โš ๏ธ ์‹ค์ œ ๋ฐฐํฌ ์‹œ์—๋Š” ๋” ๋ณต์žกํ•œ ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝํ•˜์„ธ์š”!)
app.config['SECRET_KEY'] = 'dev-secret-key-for-flask-session'
# ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ์ฒด ์ƒ์„ฑ
db = SQLAlchemy(app)
# ---------------------------------
# 3. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ชจ๋ธ ์ •์˜
# ---------------------------------
class User(db.Model):
"""์‚ฌ์šฉ์ž ์ •๋ณด ์ €์žฅ์„ ์œ„ํ•œ ๋ชจ๋ธ"""
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
password_hash = db.Column(db.String(128), nullable=False)
def set_password(self, password):
"""๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ•ด์‹ฑํ•˜์—ฌ ์ €์žฅ"""
self.password_hash = generate_password_hash(password)
def check_password(self, password):
"""ํ•ด์‹œ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ์ž…๋ ฅ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋น„๊ต"""
return check_password_hash(self.password_hash, password)
# ---------------------------------
# 4. AI ์—”์ง„ ๋ฐ ์ถ”์ฒœ๊ธฐ ์ดˆ๊ธฐ ๋กœ๋”ฉ
# ---------------------------------
print("AI ์ฑ—๋ด‡ ์„œ๋ฒ„๋ฅผ ์ค€๋น„ ์ค‘์ž…๋‹ˆ๋‹ค...")
emotion_classifier = load_emotion_classifier()
recommender = Recommender()
emotion_emoji_map = {
'๊ธฐ์จ': '๐Ÿ˜„', 'ํ–‰๋ณต': '๐Ÿ˜Š', '์‚ฌ๋ž‘': 'โค๏ธ',
'๋ถˆ์•ˆ': '๐Ÿ˜Ÿ', '์Šฌํ””': '๐Ÿ˜ข', '์ƒ์ฒ˜': '๐Ÿ’”',
'๋ถ„๋…ธ': '๐Ÿ˜ ', 'ํ˜์˜ค': '๐Ÿคข', '์งœ์ฆ': '๐Ÿ˜ค',
'๋†€๋žŒ': '๐Ÿ˜ฎ',
'์ค‘๋ฆฝ': '๐Ÿ˜',
}
print("โœ… AI ์ฑ—๋ด‡ ์„œ๋ฒ„๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ค€๋น„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
# ---------------------------------
# 5. ๋ผ์šฐํŠธ(Routes) ์ •์˜
# ---------------------------------
# --- ์‚ฌ์šฉ์ž ์ธ์ฆ ๊ด€๋ จ ๋ผ์šฐํŠธ ---
@app.route('/signup', methods=['GET', 'POST'])
def signup():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
if User.query.filter_by(username=username).first():
return "์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์‚ฌ์šฉ์ž ์ด๋ฆ„์ž…๋‹ˆ๋‹ค."
new_user = User(username=username)
new_user.set_password(password)
db.session.add(new_user)
db.session.commit()
return redirect(url_for('login'))
return render_template('signup.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
user = User.query.filter_by(username=username).first()
if user and user.check_password(password):
session['user_id'] = user.id
session['username'] = user.username
return redirect(url_for('home'))
else:
return "๋กœ๊ทธ์ธ ์ •๋ณด๊ฐ€ ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค."
return render_template('login.html')
@app.route('/logout')
def logout():
session.pop('user_id', None)
session.pop('username', None)
return redirect(url_for('login'))
# --- ๋ฉ”์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ผ์šฐํŠธ ---
@app.route("/")
def home():
"""๋ฉ”์ธ ํŽ˜์ด์ง€. ๋กœ๊ทธ์ธํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ์ด๋™."""
if 'user_id' not in session:
return redirect(url_for('login'))
# ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž์˜ ์ด๋ฆ„์„ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์ „๋‹ฌ
return render_template("emotion_homepage.html", username=session.get('username'))
@app.route("/api/recommend", methods=["POST"])
def api_recommend():
"""์ผ๊ธฐ ๋ถ„์„ ๋ฐ ์ฝ˜ํ…์ธ  ์ถ”์ฒœ API."""
# API ์š”์ฒญ๋„ ๋กœ๊ทธ์ธ๋œ ์‚ฌ์šฉ์ž๋งŒ ๊ฐ€๋Šฅํ•˜๋„๋ก ์ฒดํฌ
if 'user_id' not in session:
return jsonify({"error": "๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค."}), 401
user_diary = request.json.get("diary")
if not user_diary:
return jsonify({"error": "์ผ๊ธฐ ๋‚ด์šฉ์ด ์—†์Šต๋‹ˆ๋‹ค."}), 400
predicted_emotion = predict_emotion(emotion_classifier, user_diary)
accept_recs = recommender.recommend(predicted_emotion, "์ˆ˜์šฉ")
change_recs = recommender.recommend(predicted_emotion, "์ „ํ™˜")
accept_choice = random.choice(accept_recs) if accept_recs else "์ถ”์ฒœ ์—†์Œ"
change_choice = random.choice(change_recs) if change_recs else "์ถ”์ฒœ ์—†์Œ"
recommendation_text = (
f"<b>[ ์ด ๊ฐ์ •์„ ๋” ๊นŠ์ด ๋А๋ผ๊ณ  ์‹ถ๋‹ค๋ฉด... (์ˆ˜์šฉ) ]</b><br>"
f"โ€ข {accept_choice}<br><br>"
f"<b>[ ์ด ๊ฐ์ •์—์„œ ๋ฒ—์–ด๋‚˜๊ณ  ์‹ถ๋‹ค๋ฉด... (์ „ํ™˜) ]</b><br>"
f"โ€ข {change_choice}"
)
response_data = {
"emotion": predicted_emotion,
"emoji": emotion_emoji_map.get(predicted_emotion, '๐Ÿค”'),
"recommendation": recommendation_text
}
return jsonify(response_data)
# ---------------------------------
# 6. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰
# ---------------------------------
if __name__ == "__main__":
with app.app_context():
db.create_all() # (์„ ํƒ์‚ฌํ•ญ) ์•ฑ ์‹คํ–‰ ์‹œ DB๊ฐ€ ์—†์œผ๋ฉด ์ž๋™์œผ๋กœ ์ƒ์„ฑ.
app.run(debug=True)