뉴스피드가 포험 되어있는 서비스
뉴스피드란?
내 게시물을 포함한 모든 게시물을 볼 수 있는 공간
📦What-should-i-eat-today
┣ 📂static
┃ ┣ 📂image
┃ ┃ ┗ 📜favicon_pizza.ico
┃ ┣ 📂js
┃ ┃ ┣ 📜edit.js
┃ ┃ ┣ 📜find_id.js
┃ ┃ ┣ 📜find_pw.js
┃ ┃ ┣ 📜log.js
┃ ┃ ┣ 📜login.js
┃ ┃ ┣ 📜mypage.js
┃ ┃ ┣ 📜my_like_post.js
┃ ┃ ┣ 📜my_post.js
┃ ┃ ┣ 📜post.js
┃ ┃ ┣ 📜postlist.js
┃ ┃ ┣ 📜register.js
┃ ┃ ┣ 📜update_pw.js
┃ ┃ ┗ 📜write.js
┃ ┗ 📂styles
┃ ┃ ┣ 📜common.css
┃ ┃ ┣ 📜edit.css
┃ ┃ ┣ 📜find_id.css
┃ ┃ ┣ 📜find_pw.css
┃ ┃ ┣ 📜header.css
┃ ┃ ┣ 📜log.css
┃ ┃ ┣ 📜login.css
┃ ┃ ┣ 📜mypage.css
┃ ┃ ┣ 📜my_like_post.css
┃ ┃ ┣ 📜my_post.css
┃ ┃ ┣ 📜post.css
┃ ┃ ┣ 📜postlist.css
┃ ┃ ┣ 📜register.css
┃ ┃ ┣ 📜reset.css
┃ ┃ ┣ 📜update_pw.css
┃ ┃ ┗ 📜write.css
┣ 📂templates
┃ ┣ 📂components
┃ ┃ ┣ 📜edit.html
┃ ┃ ┣ 📜find_id.html
┃ ┃ ┣ 📜find_pw.html
┃ ┃ ┣ 📜header.html
┃ ┃ ┣ 📜log.html
┃ ┃ ┣ 📜login.html
┃ ┃ ┣ 📜mypage.html
┃ ┃ ┣ 📜my_like_post.html
┃ ┃ ┣ 📜my_post.html
┃ ┃ ┣ 📜post.html
┃ ┃ ┣ 📜postlist.html
┃ ┃ ┣ 📜register.html
┃ ┃ ┣ 📜update_pw.html
┃ ┃ ┗ 📜write.html
┃ ┗ 📜index.html
┣ 📜app.py
┗ 📜config.py
https://www.notion.so/544626a1335d4a9189573caea30ea4d0?v=e9650d6cb19e4230b7101a62245e4fd8
https://github.com/ParkAsher/what-should-i-eat-today
기본적인 커뮤니티 서비스의 동작 순서에 맞게 기능 우선순위를 두고, 각자 담당한 기능을 구현 시작.
sql = "SELECT * FROM Users WHERE user_nickname = %s"
rows = app.database.execute(sql, userNickname)
sql = "SELECT user_id FROM Users WHERE user_id = %s"
rows = app.database.execute(sql, userId)
let nickname = userNickname.search(/[ㄱ-ㅎ|ㅏ-ㅣ]/g);
let idKorean = userId.search(/[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/g);
let idSpace = userId.search(/[`~!@@#$%^&*|₩₩₩'₩";:₩/?]/gi);
let pwNumber = userPw.search(/[0-9]/g);
let pwEnglish = userPw.search(/[a-z]/gi);
let pwSpece = userPw.search(/[`~!@@#$%^&*|₩₩₩'₩";:₩/?]/gi);
let nameNumber = userName.search(/[0-9]/g);
let nameSpace = userName.search(/[`~!@@#$%^&*|₩₩₩'₩";:₩/?]/gi);
// RFC 5322 이메일 형식 강화형
let emailCheck = userEmail.search(/^[-0-9A-Za-z!#$%&'*+/=?^_`{|}~.]+@[-0-9A-Za-z!#$%&'*+/=?^_`{|}~]+[.]{1}[0-9A-Za-z]/i);
hashed_pw = bcrypt.hashpw(userPw, bcrypt.gensalt(rounds=10))
user_data = []
for record in rows:
temp = {
"id": record[0],
"user_id": record[1],
"user_pw": record[2].encode('utf-8'),
"user_name": record[3],
"user_nickname": record[4],
"user_email": record[5],
"signup_at": record[6].strftime("%Y-%m-%d %H:%M:%S"),
}
user_data.append(temp)
session['user-info'] = user_data[0]
if sort == "recommend":
# 추천순
sql = """
SELECT p.id, p.title, u.user_id, u.user_nickname, p.content, p.thumbnail, p.created_at, p.recommend
FROM Posts as p
LEFT JOIN Users as u
ON p.author = u.id
ORDER BY recommend DESC, created_at DESC
LIMIT %s, 8
"""
rows = app.database.execute(sql, (post_count))
else:
# 최신순
sql = """
SELECT p.id, p.title, u.user_id, u.user_nickname, p.content, p.thumbnail, p.created_at, p.recommend
FROM Posts as p
LEFT JOIN Users as u
ON p.author = u.id
ORDER BY created_at DESC
LIMIT %s, 8
"""
rows = app.database.execute(sql, (post_count))
# 댓글 갯수 카운트
sql = """
SELECT COUNT(*) FROM Comments
WHERE c_post_id = %s
"""
rows = app.database.execute(sql, post_id)
for record in rows:
comment_list_count = record[0]
if comment_list_count == 0:
comment_page = 0
elif comment_list_count % 5 == 0:
comment_page = comment_list_count // 5
else:
comment_page = math.ceil(comment_list_count / 5)
<div class="post-pagination-wrap">
{% if post_page != 0 %} {% if sort == "recommend" %} {% for i in range(post_page) %}
<button
data-index="{{i+1}}"
type="button"
class="post-pagination"
onclick="get_post_list('{{i+1}}' , 'recommend')"
>
{{i+1}}
</button>
{% endfor %} {% else %} {% for i in range(post_page) %}
<button
data-index="{{i+1}}"
type="button"
class="post-pagination"
onclick="get_post_list('{{i+1}}' , 'newest')"
>
{{i+1}}
</button>
{% endfor %} {% endif %} {% endif %}
</div>
@app.route("/api/post-recommend", methods=['POST'])
def post_recommend():
post_id = request.form['post_id']
user_num = request.form['user_num']
sql = """
UPDATE Posts SET recommend = Posts.recommend + 1
WHERE Posts.id = %s
"""
app.database.execute(sql, post_id)
sql2 = """
INSERT INTO Recommends(r_user, p_id)
VALUES(%s, %s)
"""
app.database.execute(sql2, (user_num, post_id))
return ({'msg': "추천하였습니다!"})
function imageHandler() {
const input = document.createElement("input");
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
input.click();
input.onchange = function () {
const formData = new FormData();
const file = $(this)[0].files[0];
formData.append('file', file);
$.ajax({
type: "POST",
url: "/api/file-upload",
cache: false,
contentType: false,
processData: false,
data: formData,
success: function (response) {
let img_url = response['img_url'];
const range = quill.getSelection();
quill.insertEmbed(range.index, 'image', img_url)
}
})
}
}
// quill init function
function quillInit() {
let options = {
modules: {
imageResize: {
displaySize: true
},
toolbar: {
container: [
[{ 'font': [] }, { 'size': [] }],
[{ 'header': 1 }, { 'header': 2 }],
['bold', 'underline', 'strike', 'blockquote', 'code-block'],
[{ 'list': 'bullet' }, { 'indent': '-1' }, { 'indent': '+1' },],
[{ 'color': [] }, { 'background': [] }],
[{ align: '' }, { align: 'center' }, { align: 'right' }, { align: 'justify' }],
['link', 'image'],
],
handlers: {
image: imageHandler(),
},
}
},
theme: 'snow',
};
quill = new Quill('#editor', options);
quill.getModule('toolbar').addHandler('image', function () {
imageHandler();
});
quill.on('text-change', function () {
document.getElementById("post-content").value = quill.root.innerHTML;
})
}
###############
# file upload #
###############
@app.route('/api/file-upload', methods=['POST'])
def file_upload():
file = request.files['file']
filename = file.filename.split('.')[0]
ext = file.filename.split('.')[-1]
img_name = datetime.datetime.now().strftime(f"{filename}-%Y-%m-%d-%H-%M-%S.{ext}")
# s3에 이미지파일 업로드
s3_put_object(s3, 'what-should-i-eat-today', file, img_name)
# 올라간 이미지의 url
image_url = f'https://what-should-i-eat-today.s3.ap-northeast-2.amazonaws.com/{img_name}'
return jsonify({'img_url': image_url})
##########################
# image insert to aws s3 #
##########################
def s3_put_object(s3, bucket, file, filename):
try:
s3.put_object(
Body=file,
Bucket=bucket,
Key=f'{filename}',
ContentType="image/*",
ACL='public-read'
)
except Exception as e:
print(e)
return False
return True