본 코드리뷰는 <정글에서의 첫 프로젝트> 글에 이어지는 게시글입니다.
위 링크글에서 프로젝트 기획의도, 구현 기능, 구현 과정을 간단하게 담아뒀습니다.
정글 처음 들어가서 3일간 진행한 프로젝트였는데 가장 핵심적인 부분만 짚고 넘어가고자 합니다.
깃허브 코드
주요 기능
backend
는 크게 3부분으로 나뉜다.
관련 함수들은 functions/cron.py
, functions/login_models.py
, functions/shuttle.py
파일별로 분류하여 flask
서버를 실행하는 app.py
로 import
하였다.
app.py
#import cron
from functions.cron import * # cron 관련 import
@app.route('/')
def home():
return User().render_homepage()
@app.route('/addtodayshuttle', methods=['GET'])
def add_today():
return Shuttle().new_today_shuttle()
@app.route('/additem', methods=['POST'])
def post_additem():
return Shuttle().post_additem()
@app.route('/deleteitem', methods=['POST'])
def delete_item():
return Shuttle().delete_item()
@app.route('/login/')
def login_window():
return render_template('login.html')
@app.route('/user/signup', methods=['GET', 'POST'])
def signup():
return User().signup()
@app.route('/user/signout')
def signout():
return User().signout()
@app.route('/user/login', methods=['POST'])
def login():
return User().login()
@app.route('/user/change_pw', methods=['POST'])
def change_pw():
return User().change_pw()
@app.route('/test')
def test():
return "TEST"
functions/cron.py
def do_cron_job():
Shuttle().get_winner() # 유저 두 명 추첨!
Shuttle().new_today_shuttle() # 다음 라운드 진행
scheduler = BackgroundScheduler()
scheduler.add_job(do_cron_job, 'cron', minute='*/3') # 3분마다 실행
scheduler.start()
cron에서는 정해진 시간에 그 동안 모아진 유저들을 대상으로 추첨을 하여 두 명을 선발하고 다음(날짜)의 셔틀을 추가해준다. 기존의 셔틀은 삭제하는 것이 아니라 새로운 셔틀을 추가하면서 내려가고, 내려가면서 댓글이 달리거나 수정되지 않도록 처리하였다.
기존 기획 의도는 하루에 한 번 그 날의 셔틀을 뽑는 것 인데 시연을 위해 3분마다 동작하게 설정하였다.
def get_winner(self): # 댓글 단 사람 중에 두 명을 선발하기
data = sorted(db.shuttles.find({}), key=lambda x: x['date'], reverse=True)
# get latest shuttle
info = data[0]['content']
date = data[0]['date']
player = set()
for i in info :
player.add(i['name'])
# 두 명 추출
if not player:
winner = ["사람이 없습니다", ""]
elif len(player) == 1:
winner = [list(player)[0], "혼자 가세요...ㅋ"]
else:
winner = random.sample(player, 2)
db.shuttles.update_one({"date": date}, {"$set": {"winner": winner}})
이 프로젝트를 개선한다면 가장 빠르게 수정해줘야 할 부분이다.
이 부분은 처음 db모델을 구상하면서 많이 고민되었던 부분이다. 매일 혹은 일정시간마다 새로운 shuttle이 들어오고, 지난 shuttle이 쌓이는데 CRUD가 발생하는건 가장 상단의 새로운 shuttle밖에 없었다.
db에 collection을 만들 때 가장 최근 collection만 별도로 만들어주고 CRUD를 진행시켜주다가 새로운 shuttle이 만들어지면 보관되는 보관용 collection을 만들어 줄지, 지금처럼 전부 하나의 collection에 몰아주되, 가장 최근의 shuttle만 불러와서 처리할 지 고민했었다.
허나 우리가 아직 mongo 문법이 익숙치 않아서 가장 최근의 shuttle을 수정하기 위해서 모든 shuttle(data)을 다 불러와 준 후 이를 한번 뒤집고(reverse=True) 가장 상단에 위치한 데이터에 접근하였다(data[0])ㅠㅠ 시간이 워낙 촉박해서 일단 구현부터 해놓고 수정해야지 하고 넘어갔는데 수정할 수 있는 여력은 없었다..
아래는 cron이 돌며 새로운 셔틀을 생성해주는 코드다. 생각보다 간단:) db에 초기화해서 셔틀을 넣어주기만 하면 된다.
class Shuttle():
def new_today_shuttle(self):
now = datetime.datetime.now()
nowDate = now.strftime('%Y-%m-%d %H:%M')
today_shuttle = {
'date': nowDate,
'content': [],
'winner': []
}
db.shuttles.insert_one(today_shuttle)
return None