주석 완료 하여 깃허브에 올림
깃허브 주소 : https://github.com/stravinest/sparta_kcal_1.git
우리조는 로그인 인증 방식을 JWT로 구현하였고 손쉽게 사용할수 있었다.
payload = jwt.decode(token_receive, SECRET_KEY, algorithms=['HS256'])
다만 로그아웃을 한후에 뒤로가기를 눌렀을 때 다시 로그인이 되는 상황이 나왔고 이를 아래의 코드로 해결하였다.
def after_request(response):
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
return response
클라이언트가 서버에 요청하는 API 구성을 프로젝트 전에 와이어 프로그램 으로 짰다. 그 중 내가 맡은 부분 을 정리하자면
profile 마이페이지
@app.route('/profile')
token_receive = request.cookies.get('mytoken')
payload = jwt.decode(token_receive, SECRET_KEY, algorithms=['HS256'])
return render_template("profile.html", status=status_receive, userid=payload['id'])
프로필 페이지 띄움
로그인 된 아이디 값을 받아와서 render 페이지에 보내준다.
status 값은 index(메인 오늘의 칼로리페이지) 에서 받아오는데
status값이 old 이면 프로필을 입력 한상태 new이면 프로필이 미입력된상태이다.
@app.route('/api/send', methods=['GET'])
profiles = list(db.todayKcal.find({"myid": payload['id']}, {'_id': False}))
if (profiles == []):
status = 'new'
else:
status = 'old'
return jsonify({'status': status})
메인페이지에서 mypage를 눌렀을때 status 값을 판별해서 보내주게 된다.
status 값이 new 일때
프로필 입력기 창이 나타나고
status 값이 old 일때
프로필을 뿌려주며 프로필 수정기 창이 나타난다.
@app.route('/api/profile_post', methods=['POST'])
bmiscore = math.trunc(w / (h * h) * 10000)
bmi = ""
if (bmiscore > 30):
bmi = "비만"
elif (bmiscore >= 25):
bmi = "과체중"
elif (bmiscore >= 19):
bmi = "정상"
else:
bmi = "저체중"
프로필 입력시에 키 몸무게 목표칼로리를 입력 해야 하고 빈칸으로 입력시에 alert창을 띄운다. 등록 할때 bmi 지수도 계산되어서 같이 DB에 들어가게 된다.
@app.route('/api/profile', methods=['GET'])
profiles = list(db.todayKcal.find({"myid": myid_receive}, {'_id': False}))
그 아이디값에 맞는 프로필 리스팅
@app.route('/api/profile_cal', methods=['GET'])
agg_result = db.foodInfo.aggregate(
[
{
"$match": {'user_info': myid_receive}
},
{
"$group":
{
"_id":{"user_id":"$user_info",
"date":"$food_date"},
"total": {"$sum": "$food_kcal"}
}},
{
"$sort": {"date": -1}
},
])
프로필 칼로리 계산 과 목표칼로리와 차이를 계산해서 뿌려준다.(가장 힘들었던 부분)
@app.route('/api/profile_adjust', methods=['POST'])
db.todayKcal.update_one({'myid': myid_receive}, {'$set': {'height': int(height_receive)}})
db.todayKcal.update_one({'myid': myid_receive}, {'$set': {'weight': int(weight_receive)}})
db.todayKcal.update_one({'myid': myid_receive}, {'$set': {'goal_cal': int(goal_cal_receive)}})
db.todayKcal.update_one({'myid': myid_receive}, {'$set': {'bmi': bmi}})
db.todayKcal.update_one({'myid': myid_receive}, {'$set': {'bmiscore': int(bmiscore)}})
status 값이 old라면 수정기가 나오고 프로필을 수정할수 있다.
@app.route('/api/profile_food', methods=['GET'])
foodInfos = list(db.foodInfo.find({"user_info":myid_receive}, {'_id': False}).sort("now", -1))
음식사진 출력 로그인된 아이디의 음식사진만 출력
1.git, github사용의 문제
git branch 를 너무 남발했고 최신화와 기존 branch 간의 충돌이 너무 잦았다. 이에 계속해서 백업하고 초기화 clone으로 진행하다가 각자 스터디를 하여 서로 공유하면서 git을 이해했다.
결론: 프로젝트 초반에 룰을 정하여 git backup과 git upload를 차근차근 진행하자!
2.프로필 페이지에 칼로리 합산 문제
db에서 아이디 와 날짜별로 칼로리를 더한 값을 출력해야하는데 find문으로는 쉽지가 않았다.
처음에 find로 아이디를 찾고 다시 날짜 별로 칼로리를 합산하려는데 자바스크립트 쪽에서는 알고리즘적으로 해결이 쉽지 않았다. 결국에는 몽고디비의 aggregate툴로 구현을 할수 있었다.
여기서 이어진 문제 두번째
날짜 값 문자열로 받았는데 sort가 먹히지 않는 현상이 발생했다. 그래서 새로운 날짜 데이터 int형으로 db에 저장하여 그값 today 값으로 sort를 했다. 그런데 도 먹히지 않는 sort
한참을 씨름하다가 total 값에 sort하니 되는 걸 발견 total의 위치에다 today 값으로 sort해야 함을 알았고 avg 함수를 써서 today값을 뽑아냈다 ( 어차피 몇개가있건 평균은 today 값이기 때문에) 뽑아낸 avg(today값 평균) 갑을 sort 먹이니 성공!(내림차순) limit 도 3으로 줘서 최대 3번째 까지만 뽑히도록 만듬
> agg_result = db.foodInfo.aggregate(
[
{
"$match": {'user_info': myid_receive}
},
{
"$group":
{
"_id": {"user_id": "$user_info",
"date": "$food_date",
},
"total": {"$sum": "$food_kcal"},
"avg": {"$avg": "$today"}
}},
{
"$sort": {"avg": -1}
},
{
"$limit": 3
},
])
if name == 'main':
app.run(port=500,debug=True_)
app.run('0.0.0.0', port=5000, debug=True)
app.run('0.0.0.0') 이부분 모든 호스트가 접속가능으로 해줘야 함을 발견 위에 app.run(port 이부분은 삭제 해야 함!!
4.staus 값을 받아오는 부분 에서의 문제
로그인 해서 각자의 아이디 값에 맞는 프로필 페이지를 띄워야 한다. 그리고 그 아이디 가 프로필을 작성했을 경우와 미작성했을 경우를 나눠서 창을 띄워줬어야 했는데 이부분에서 status의 상태를 받아와야 했다. 이 status의 상태는 주소창으로 넘어오는데 처음 프로필 페이지에가 업로드 될때 바로 받아와야 했다. 그런데 프로필 페이지가 띄워질때 그 status 값을 받아오는게 쉽지가 않았다. 지금생각해서 보면 바로 띄울때 서버에 요청에서 받아오면 되지 않을까 생각하는데 그때 당시에는 전 페이지에서 (메인) 값을 넘길대 주소창으로 status값을 받게끔 만들고 그 값으로 status상태를 진단할수 있었다.
서로의 페이지간의 협업이 매우 중요했고, 프로젝트 전에 어떻게 협업을 계획할지가 진짜 중요한것을 깨달았다. 나혼자만이 아닌 팀으로서 내 역할을 어떻게 충분히 100퍼센트로 할 수 있는지 가 중요한 것 같다.
프로젝트를 하면서 수많은 자질구레한 오류들을 접하면서 어떻게든 이게 맞게 한지는 모르겠지만 결국은 원하던 기능을 구현한 것에 만족감을 느낀다.