session.ctrl.js
6.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
const axios = require("axios");
const Participation = require("../../models/participation");
const Session = require("../../models/session");
const Group = require("../../models/group");
const User = require("../../models/user");
const Challenge = require("../../models/challenge");
const Problem = require("../../models/problem");
const mongoose = require("mongoose");
require('dotenv').config();
const {ObjectId} = mongoose.Types;
/* POST /api/session/createproblem/:how
{
sessionId: ObjectId or String,
groupId: ObjectId or String,
problemList:[Number], (optional)
}
*/
exports.createProblem = async (ctx)=>{
try{
let {sessionId,groupId,problemList} = ctx.request.body;
if(typeof(sessionId)==='string'){
sessionId=new ObjectId(sessionId);
}
if(typeof(groupId)==='string'){
groupId=new ObjectId(groupId);
}
if(typeof(problemList)==='string'){
problemList=JSON.parse(problemList);
}
const session = await Session.findById(sessionId);
const challengeId = session['challengeId'];
const challenge = await Challenge.findById(challengeId);
const goalPerSession = challenge['goalPerSession'];
const participation = await Participation.findOne({sessionId:sessionId,groupId:groupId});
const group = await Group.findById(groupId);
const how=ctx.params.how;
if(how==='self'){
if(problemList.length!==goalPerSession){
ctx.throw(400,'문제 수가 맞지 않습니다.');
}
let check = true;
for(let i=0;i<group.members.length;i++){
const user = await User.findById(group.members[i]);
let userProblemList = [];
for(let key in user.solvedBJ_date.solvedBJbyDATE){
userProblemList.push(user.solvedBJ_date.solvedBJbyDATE[key]);
}
userProblemList=userProblemList.flat().map(elem=>elem.problem_number);
for(let j=0;j<problemList.length;j++){
if(userProblemList.includes(problemList[j])){
check = false;
break;
}
}
}
if(!check){
ctx.throw(400,'그룹원이 이미 푼 문제는 등록할 수 없습니다.');
return;
}
else{
problemList.map(async problemNum=>await participation.addProblem({problemNum:problemNum,isSolved:false}));
ctx.body=participation.serialize();
}
}
else if(how==='recommend'){
let groupProblemList=[];
let selectedProblemList=[];
for(let i=0;i<group.members.length;i++){
const user = await User.findById(group.members[i]);
for(let key in user.solvedBJ_date.solvedBJbyDATE){
groupProblemList.push(user.solvedBJ_date.solvedBJbyDATE[key]);
}
}
groupProblemList=groupProblemList.flat().sort((a,b)=>new Date(b.solvedDate)-new Date(a.solvedDate)).map(elem=>elem.problem_number);
groupProblemList=groupProblemList.filter((x,i)=>groupProblemList.indexOf(x)===i);
console.log(groupProblemList);
const problems=await Problem.find({}).sort({count:-1});
console.log(problems);
console.log(goalPerSession);
for(let i=0;i<problems.length;i++){
if(!groupProblemList.includes(String(problems[i].problemNum))){
selectedProblemList.push(String(problems[i].problemNum));
}
if(selectedProblemList.length===goalPerSession || i/problems.length >= 0.75){
break;
}
}
for(let i=0; i<groupProblemList.length && selectedProblemList.length < goalPerSession; i++){
const p = await Problem.findOne({problemNum:groupProblemList[i]});
if( Number(p.solvedacLevel)< 1 || Number(p.solvedacLevel)>30 ){
continue;
}
const body = await axios.get(`https://api.solved.ac/v2/search/problems.json?query=solvable:true+tier:${p.solvedacLevel}&page=1&sort=solved&sort_direction=desc`);
let data = body.data;
if(typeof(data)==='string'){
data=JSON.parse(data);
}
for(let j=0;j<data.result.problems.length;j++){
if(!groupProblemList.includes(data.result.problems[j].id)){
selectedProblemList.push(data.result.problems[j].id.toString());
break;
}
}
}
selectedProblemList.map(async problemNum=>await participation.addProblem({problemNum:problemNum,isSolved:false}));
ctx.body=participation.serialize();
}
}
catch(e){
console.error(e);
ctx.throw(500,e);
}
};
// GET /api/session/status?sessionId&groupId
exports.status=async (ctx)=>{
try{
let {sessionId,groupId}=ctx.request.query;
if(typeof(sessionId)==='string'){
sessionId=new ObjectId(sessionId);
}
if(typeof(groupId)==='string'){
groupId=new ObjectId(groupId);
}
const participation=await Participation.findOne({sessionId:sessionId,groupId:groupId});
const group = await Group.findById(groupId);
for(let i=0;i<group.members.length;i++){
const user=await User.findById(group.members[i]);
await axios.patch(`http://localhost:${process.env.SERVER_PORT}/api/profile/syncBJ`,{username:user.username});
}
for(let i=0;i<group.members.length;i++){
const user=await User.findById(group.members[i]);
let userProblemList = [];
for(let key in user.solvedBJ_date.solvedBJbyDATE){
userProblemList.push(user.solvedBJ_date.solvedBJbyDATE[key]);
}
userProblemList=userProblemList.flat().map(elem=>elem.problem_number);
for(let j=0;j<participation.problems.length;j++){
if(userProblemList.includes(String(participation.problems[i].problemNum))){
participation.problems[i].isSolved=true;
await participation.save();
}
}
}
ctx.body=participation.serialize();
}
catch(e){
ctx.throw(500,e);
}
}