송용우
Committed by GitHub

Merge pull request #18 from FacerAin/feature/rest_api

Add /api/challenge/list /api/challenge/participate
1 const Challenge = require("../../models/challenge"); 1 const Challenge = require("../../models/challenge");
2 +const Session = require("../../models/session");
3 +const Participation = require("../../models/participation");
4 +const Group = require("../../models/group");
5 +const User = require('../../models/user');
6 +
2 const Joi = require("joi"); 7 const Joi = require("joi");
3 /*POST /api/challenge/getChallenge 8 /*POST /api/challenge/getChallenge
4 { 9 {
...@@ -8,7 +13,7 @@ const Joi = require("joi"); ...@@ -8,7 +13,7 @@ const Joi = require("joi");
8 exports.getChallenge = async (ctx) => { 13 exports.getChallenge = async (ctx) => {
9 try { 14 try {
10 const { challengeName } = ctx.request.body; 15 const { challengeName } = ctx.request.body;
11 - const challenge = await Challenge.findByChallengeName(challengeName); 16 + const challenge = await Challenge.findByChallengeName(challengeName).select('-_id');
12 if (!challenge) { 17 if (!challenge) {
13 ctx.status = 401; 18 ctx.status = 401;
14 return; 19 return;
...@@ -25,7 +30,6 @@ exports.getChallenge = async (ctx) => { ...@@ -25,7 +30,6 @@ exports.getChallenge = async (ctx) => {
25 endDate: Date Object, 30 endDate: Date Object,
26 durationPerSession: "2w", // '1d' means one day per session, '2w' means 2 weeks per session, '3m' means 3 months per session. 31 durationPerSession: "2w", // '1d' means one day per session, '2w' means 2 weeks per session, '3m' means 3 months per session.
27 goalPerSession: 3, 32 goalPerSession: 3,
28 - groups: [{'name1', 'name2'}]
29 } 33 }
30 */ 34 */
31 exports.addChallenge = async (ctx) => { 35 exports.addChallenge = async (ctx) => {
...@@ -35,8 +39,7 @@ exports.addChallenge = async (ctx) => { ...@@ -35,8 +39,7 @@ exports.addChallenge = async (ctx) => {
35 startDate: Joi.date(), 39 startDate: Joi.date(),
36 endDate: Joi.date(), 40 endDate: Joi.date(),
37 durationPerSession: Joi.string(), 41 durationPerSession: Joi.string(),
38 - goalPerSession: Joi.number(), 42 + goalPerSession: Joi.number()
39 - groups: Joi.array().items(Joi.string()),
40 }) 43 })
41 .unknown(); 44 .unknown();
42 const result = Joi.validate(ctx.request.body, schema); 45 const result = Joi.validate(ctx.request.body, schema);
...@@ -46,7 +49,7 @@ exports.addChallenge = async (ctx) => { ...@@ -46,7 +49,7 @@ exports.addChallenge = async (ctx) => {
46 ctx.body = result.error; 49 ctx.body = result.error;
47 return; 50 return;
48 } 51 }
49 - const { 52 + let {
50 challengeName, 53 challengeName,
51 startDate, 54 startDate,
52 endDate, 55 endDate,
...@@ -55,7 +58,7 @@ exports.addChallenge = async (ctx) => { ...@@ -55,7 +58,7 @@ exports.addChallenge = async (ctx) => {
55 } = ctx.request.body; 58 } = ctx.request.body;
56 59
57 try { 60 try {
58 - const isChallengeExist = await Challenge.findByChallengeName(challengeName); 61 + const isChallengeExist = await Challenge.findByChallengeName(challengeName).select('-_id');
59 62
60 if (isChallengeExist) { 63 if (isChallengeExist) {
61 ctx.status = 409; 64 ctx.status = 409;
...@@ -70,11 +73,123 @@ exports.addChallenge = async (ctx) => { ...@@ -70,11 +73,123 @@ exports.addChallenge = async (ctx) => {
70 }); 73 });
71 74
72 await challenge.save(); 75 await challenge.save();
73 - ctx.body = challenge(); 76 +
77 + const newChallenge=await Challenge.findByChallengeName(challengeName);
78 + const newChallenge_id=newChallenge._id;
79 + const timeStep=Number(durationPerSession.slice(0,-1))
80 + if(typeof(startDate)=='string'){
81 + startDate=new Date(startDate);
82 + }
83 + if(typeof(endDate)=='string'){
84 + endDate=new Date(endDate);
85 + }
86 + for(let s_date=new Date(startDate);s_date<endDate;){
87 + let e_date=new Date(s_date);
88 + if(durationPerSession[durationPerSession.length-1]==='d'){
89 + console.log('day');
90 + e_date.setDate(s_date.getDate()+timeStep);
91 + }
92 + else if(durationPerSession[durationPerSession.length-1]==='w'){
93 + console.log('week');
94 + e_date.setDate(s_date.getDate()+timeStep*7);
95 + }
96 + else if(durationPerSession[durationPerSession.length-1]==='m'){
97 + console.log('month');
98 + e_date.setMonth(s_date.getMonth()+timeStep);
99 + }
100 + e_date.setMinutes(e_date.getMinutes()-1);
101 + if(e_date>endDate){
102 + break;
103 + }
104 + let status="";
105 + if (s_date>new Date()){
106 + status="enrolled";
107 + }
108 + else if (s_date<=new Date() && new Date() <= e_date){
109 + status="progress";
110 + }
111 + else{
112 + status="end";
113 + }
114 + console.log(`start:${s_date}\nend:${e_date}`);
115 + const session=new Session({
116 + challengeId:newChallenge_id,
117 + sessionStartDate:s_date,
118 + sessionEndDate:e_date,
119 + status:status,
120 + });
121 + await session.save();
122 + s_date=new Date(e_date);
123 + s_date.setMinutes(s_date.getMinutes()+1);
124 + }
125 + ctx.body = challenge;
74 } catch (e) { 126 } catch (e) {
75 ctx.throw(500, e); 127 ctx.throw(500, e);
76 } 128 }
129 +};
130 +
131 +
132 +/* GET /api/challenge/list?status
133 +query string status can be in ['all','enrolled','progress','end']
134 +*/
135 +exports.list = async (ctx) => {
136 + try{
137 + const status = ctx.query.status;
138 + if (status!=='all'){
139 + const challenges = await Challenge.find({status:status}).select('-_id');
140 + ctx.body = challenges;
141 + }
142 + else {
143 + const challenges = await Challenge.find({}).select('-_id');
144 + ctx.body = challenges;
145 + }
146 + }
147 + catch(e){
148 + ctx.throw(500,e);
149 + }
150 +};
151 +
152 +/* POST /api/challenge/participate
153 +{
154 + username: 'username',
155 + challengeName: 'challengename'
156 +}
157 +*/
158 +
159 +exports.participate=async (ctx)=>{
160 + try{
77 /* 161 /*
78 - TODO: How to handle group? 162 + TODO: access token validation,
163 + recommend:get username from access_token
79 */ 164 */
80 -}; 165 + console.log(ctx.request.body);
166 + const {username,challengeName}=ctx.request.body;
167 + const challenge=await Challenge.findByChallengeName(challengeName);
168 + const challenge_id=challenge._id;
169 + const user=await User.findByUsername(username);
170 + const user_id=user._id;
171 + const newGroup=new Group({
172 + members:[user_id],
173 + });
174 + let newGroup_id=""
175 + await newGroup.save(async (err,product)=>{
176 + if(err){
177 + throw err;
178 + }
179 + newGroup_id=product._id;
180 + const sessions=await Session.findByChallengeId(challenge_id);
181 + sessions.forEach(async (elem) => {
182 + const newParticipation=new Participation({
183 + sessionId:elem._id,
184 + groupId:newGroup_id,
185 + problems:[],
186 + });
187 + await newParticipation.save();
188 + });
189 + });
190 + }
191 + catch(e){
192 + console.error(e);
193 + ctx.throw(500,e);
194 + }
195 +};
...\ No newline at end of file ...\ No newline at end of file
......
1 +const Router = require('koa-router');
2 +const challenge = new Router();
3 +const challengeCtrl = require('./challege.ctrl');
4 +
5 +challenge.post("/getchallenge",challengeCtrl.getChallenge);
6 +challenge.post("/addchallenge",challengeCtrl.addChallenge);
7 +challenge.get("/list",challengeCtrl.list);
8 +challenge.post("/participate",challengeCtrl.participate);
9 +
10 +module.exports = challenge;
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -6,11 +6,13 @@ const friend = require("./friend"); ...@@ -6,11 +6,13 @@ const friend = require("./friend");
6 const notify = require("./notify"); 6 const notify = require("./notify");
7 const user = require("./user"); 7 const user = require("./user");
8 const profile = require("./profile"); 8 const profile = require("./profile");
9 +const challenge = require("./challenge");
9 10
10 api.use("/auth", auth.routes()); 11 api.use("/auth", auth.routes());
11 api.use("/friend", friend.routes()); 12 api.use("/friend", friend.routes());
12 api.use("/notify", notify.routes()); 13 api.use("/notify", notify.routes());
13 api.use("/user", user.routes()); 14 api.use("/user", user.routes());
14 api.use("/profile", profile.routes()); 15 api.use("/profile", profile.routes());
16 +api.use("/challenge",challenge.routes());
15 17
16 module.exports = api; 18 module.exports = api;
......