블로그 기능 구현
> 글쓰기, 수정, 삭제 구현 > 목록 페이지 벽돌 레이아웃 구성 > 로그인 기능 추가 > 컨텐츠 공개/숨김 기능 추가
This commit is contained in:
115
app.py
115
app.py
@@ -6,6 +6,8 @@ from bs4 import BeautifulSoup
|
||||
from werkzeug.utils import secure_filename
|
||||
import os
|
||||
import uuid
|
||||
from markupsafe import Markup
|
||||
from jinja2 import filters
|
||||
|
||||
UPLOAD_FOLDER = 'static/upload/img' # 경로를 Flask 앱 루트 기준으로 수정
|
||||
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
|
||||
@@ -66,7 +68,7 @@ def connnect_db():
|
||||
host='wxnasso.synology.me',
|
||||
user='wixon5',
|
||||
password='Wixon2022@!',
|
||||
database='wixon',
|
||||
database='test',
|
||||
charset="utf8mb4",
|
||||
cursorclass=pymysql.cursors.DictCursor, # DictCursor를 사용하여 딕셔너리 형태로 결과를 반환
|
||||
init_command='SET SQL_SAFE_UPDATES = 0;',
|
||||
@@ -92,8 +94,13 @@ def sql_execute(q, d, is_data=False, is_last_id=False):
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
# MySQL에서 모든 블로그 포스트를 가져옵니다.
|
||||
query = "SELECT `title`, `thumbnail_img`, `contents` FROM `blog` WHERE `use_yn` = 'Y' ORDER BY `add_date` DESC;"
|
||||
if 'user_info' in session: # 로그인된 사용자가 있을 경우
|
||||
# 외부 공개 안된 글도 포함하여 모든 블로그 포스트를 가져옵니다.
|
||||
query = "SELECT `id`, `title`, `thumbnail_img`, `contents` FROM `blog` WHERE `use_yn` = 'Y' ORDER BY `add_date` DESC;"
|
||||
else: # 로그인된 사용자가 없을 경우
|
||||
# 외부 공개된 블로그 포스트만 가져옵니다.
|
||||
query = "SELECT `id`, `title`, `thumbnail_img`, `contents` FROM `blog` WHERE `use_yn` = 'Y' and `public_yn` = 'Y' ORDER BY `add_date` DESC;"
|
||||
|
||||
r, posts = sql_execute(query, (), is_data=True)
|
||||
|
||||
# `index.html` 템플릿으로 데이터를 전달합니다.
|
||||
@@ -126,34 +133,122 @@ def logout():
|
||||
return redirect(url_for('index'))
|
||||
|
||||
|
||||
@app.route('/post/<int:post_id>')
|
||||
def post(post_id):
|
||||
# SQL 쿼리와 삽입할 데이터 설정
|
||||
query = "SELECT blog.*, member.mb_name, member.mb_id FROM blog INNER JOIN member ON blog.user_id = member.mb_idx WHERE blog.id = %s"
|
||||
data = (post_id,)
|
||||
|
||||
# Post를 데이터베이스에서 검색
|
||||
result, fetched_data = sql_execute(query, data, is_data=True)
|
||||
|
||||
if result:
|
||||
# 검색 성공시, 포스트 상세 페이지로 이동
|
||||
post = fetched_data[0]
|
||||
|
||||
# 이전과 다음 포스트를 찾기
|
||||
if 'user_info' in session: # 로그인된 사용자가 있을 경우
|
||||
# 외부 공개 안된 글도 포함하여 모든 블로그 포스트를 가져옵니다.
|
||||
prev_query = "SELECT blog.*, member.mb_name, member.mb_id FROM blog INNER JOIN member ON blog.user_id = member.mb_idx WHERE blog.add_date < %s AND blog.use_yn = 'Y' ORDER BY blog.add_date DESC LIMIT 1"
|
||||
next_query = "SELECT blog.*, member.mb_name, member.mb_id FROM blog INNER JOIN member ON blog.user_id = member.mb_idx WHERE blog.add_date > %s AND blog.use_yn = 'Y' ORDER BY blog.add_date ASC LIMIT 1"
|
||||
else: # 로그인된 사용자가 없을 경우
|
||||
# 외부 공개된 블로그 포스트만 가져옵니다.
|
||||
prev_query = "SELECT blog.*, member.mb_name, member.mb_id FROM blog INNER JOIN member ON blog.user_id = member.mb_idx WHERE blog.add_date < %s AND blog.public_yn = 'Y' AND blog.use_yn = 'Y' ORDER BY blog.add_date DESC LIMIT 1"
|
||||
next_query = "SELECT blog.*, member.mb_name, member.mb_id FROM blog INNER JOIN member ON blog.user_id = member.mb_idx WHERE blog.add_date > %s AND blog.public_yn = 'Y' AND blog.use_yn = 'Y' ORDER BY blog.add_date ASC LIMIT 1"
|
||||
|
||||
prev_post = None
|
||||
next_post = None
|
||||
|
||||
prev_result, prev_fetched_data = sql_execute(prev_query, (post['add_date'],), is_data=True)
|
||||
next_result, next_fetched_data = sql_execute(next_query, (post['add_date'],), is_data=True)
|
||||
|
||||
if prev_result and prev_fetched_data:
|
||||
prev_post = prev_fetched_data[0]
|
||||
if next_result and next_fetched_data:
|
||||
next_post = next_fetched_data[0]
|
||||
|
||||
return render_template('post.html', post=post, prev_post=prev_post, next_post=next_post)
|
||||
else:
|
||||
# 검색 실패시, 에러 메시지 반환
|
||||
return "Failed to fetch the post", 500
|
||||
|
||||
|
||||
@app.route('/edit_post/<int:post_id>', methods=['GET', 'POST'])
|
||||
def edit_post(post_id):
|
||||
if 'username' not in session or ('username' in session and session['username'] not in ['admin', 'wixon']):
|
||||
flash('You are not allowed to edit this post.')
|
||||
return redirect(url_for('index'))
|
||||
|
||||
if request.method == 'POST':
|
||||
# 포스트 업데이트 로직
|
||||
title = request.form.get('title')
|
||||
category = request.form.get('category')
|
||||
public_yn = 'Y' if request.form.get('public') == 'on' else 'N'
|
||||
contents = request.form.get('contents')
|
||||
|
||||
query = "UPDATE blog SET title = %s, category = %s, public_yn = %s, contents = %s WHERE id = %s"
|
||||
data = (title, category, public_yn, contents, post_id)
|
||||
|
||||
res = sql_execute(query, data)
|
||||
if res:
|
||||
flash('Post updated successfully.')
|
||||
return redirect(url_for('post', post_id=post_id))
|
||||
else:
|
||||
flash('Failed to update the post.')
|
||||
return redirect(url_for('edit_post', post_id=post_id))
|
||||
|
||||
else:
|
||||
# 포스트 가져오기 로직
|
||||
query = "SELECT * FROM blog WHERE id = %s"
|
||||
data = (post_id,)
|
||||
|
||||
res, fetched_data = sql_execute(query, data, is_data=True)
|
||||
if res and fetched_data:
|
||||
return render_template('edit_post.html', post=fetched_data[0])
|
||||
else:
|
||||
flash('Failed to fetch the post.')
|
||||
return redirect(url_for('index'))
|
||||
|
||||
|
||||
@app.route('/write', methods=['GET', 'POST'])
|
||||
def write():
|
||||
if 'user_info' not in session:
|
||||
flash("You need to login first.")
|
||||
return redirect(url_for('login'))
|
||||
|
||||
if request.method == 'POST':
|
||||
user_id = session['user_info']['mb_idx']
|
||||
title = request.form['title']
|
||||
category = request.form['category']
|
||||
contents = request.form['contents']
|
||||
is_public = 'Y' if request.form.get('public') == 'on' else 'N'
|
||||
|
||||
# 본문에서 첫 번째 이미지 추출
|
||||
soup = BeautifulSoup(contents, 'html.parser')
|
||||
first_image = soup.find('img')
|
||||
thumbnail_img = first_image['src'] if first_image else None
|
||||
|
||||
# SQL 쿼리와 삽입할 데이터 설정
|
||||
query = "INSERT INTO blog (title, category, contents, thumbnail_img, use_yn) VALUES (%s, %s, %s, %s, 'Y')"
|
||||
data = (title, category, contents, thumbnail_img)
|
||||
query = "INSERT INTO blog (user_id, title, category, contents, thumbnail_img, public_yn) VALUES (%s, %s, %s, %s, %s, %s)"
|
||||
data = (user_id, title, category, contents, thumbnail_img, is_public)
|
||||
|
||||
# 새로운 글 저장
|
||||
result, last_id = sql_execute(query, data, is_last_id=True)
|
||||
|
||||
if result:
|
||||
# 저장 성공시, 인덱스 페이지로 리다이렉트
|
||||
return redirect(url_for('index'))
|
||||
else:
|
||||
# 저장 실패시, 에러 메시지 반환
|
||||
return "Failed to write post", 500
|
||||
else:
|
||||
return render_template('write.html')
|
||||
|
||||
|
||||
@app.route('/blog/<int:id>', methods=['DELETE'])
|
||||
def delete_post(id):
|
||||
query = "UPDATE `blog` SET `use_yn` = 'N' WHERE `id` = %s;"
|
||||
res = sql_execute(query, (id,))
|
||||
if res:
|
||||
return jsonify(success=True, message='Post deleted successfully'), 200
|
||||
else:
|
||||
return jsonify(success=False, message='Could not delete the post'), 500
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=8899)
|
||||
|
||||
Reference in New Issue
Block a user