Skip to content

Commit 33abb67

Browse files
committed
fixes #632
1 parent 78522fa commit 33abb67

13 files changed

Lines changed: 140 additions & 60 deletions

File tree

fixture/openCourse.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
const mongoose = require('mongoose');
2+
3+
var Course = require('courses').Course;
4+
var CourseGroup = require('courses').CourseGroup;
5+
var CourseInvite = require('courses').CourseInvite;
6+
var VideoKey = require('videokey').VideoKey;
7+
8+
exports.Course = [
9+
{
10+
"_id": "5569b7fc097bf243c1d54e5b",
11+
slug: "js",
12+
videoKeyTag: "js",
13+
title: "Курс JavaScript/DOM/интерфейсы",
14+
shortDescription: `"Правильный" курс по профессиональному JavaScript, цель которого – научить думать на JavaScript, писать просто, быстро и красиво.`,
15+
isListed: true,
16+
weight: 1
17+
}
18+
];
19+
20+
exports.CourseInvite = [];
21+
exports.CourseParticipant = [];
22+
exports.CourseFeedback = [];
23+
24+
exports.CourseGroup = [
25+
{
26+
course: '5569b7fc097bf243c1d54e5b',
27+
dateStart: new Date(2015, 4, 14),
28+
dateEnd: new Date(2016, 6, 16),
29+
timeDesc: "пн/чт 19:30 - 21:00 GMT+3",
30+
slug: 'js-1',
31+
price: 99999,
32+
participantsLimit: 40,
33+
webinarId: '116500571',
34+
isListed: true,
35+
isOpenForSignup: true,
36+
title: "Курс JavaScript/DOM/интерфейсы (14.05)"
37+
}
38+
];
39+
40+
exports.VideoKey = [];
41+
for(var i=0; i<50; i++) exports.VideoKey.push({key: "см. в старом кабинете-" + i.toString(36), tag: 'js'});

handlers/courses/controller/coursesByUser.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const CourseInvite = require('../models/courseInvite');
44
const CourseParticipant = require('../models/courseParticipant');
55
const CourseGroup = require('../models/courseGroup');
66
const CourseFeedback = require('../models/courseFeedback');
7+
const _ = require('lodash');
78

89
/**
910
* The order form is sent to checkout when it's 100% valid (client-side code validated it)
@@ -26,16 +27,15 @@ exports.get = function*(next) {
2627
}).populate('group').exec();
2728

2829
// plus groups where participates
29-
var participant = yield CourseParticipant.findOne({
30-
user: user._id
31-
}).exec();
30+
var participantWithGroups = yield CourseParticipant.find({
31+
user: user._id,
32+
isActive: true
33+
}).populate('group').exec();
3234

3335
var groups;
34-
if (participant) {
36+
if (participantWithGroups) {
3537
// plus groups where participates
36-
groups = yield CourseGroup.find({
37-
participants: participant._id
38-
}).exec();
38+
groups = _.pluck(participantWithGroups, 'group');
3939
} else {
4040
groups = [];
4141
}
@@ -60,7 +60,7 @@ exports.get = function*(next) {
6060

6161
let hasFeedback = yield CourseFeedback.findOne({
6262
courseGroup: group._id,
63-
participant: participant._id
63+
participant: participantWithGroups._id
6464
}).exec();
6565

6666
let groupInfo = formatGroup(group);

handlers/courses/controller/feedback.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,22 @@ exports.get = function*() {
88

99
var number = +this.params.feedbackNumber;
1010

11-
var courseFeedback = this.locals.courseFeedback = yield CourseFeedback.findOne({number: number}).populate('courseGroup participant').exec();
11+
var courseFeedback = this.locals.courseFeedback = yield CourseFeedback.findOne({number: number}).populate('group participant').exec();
1212

1313
if (!courseFeedback) {
1414
this.throw(404);
1515
}
1616

17-
var authorOrAdmin = this.locals.authorOrAdmin = this.user.isAdmin || String(this.user._id) == String(courseFeedback.participant.user);
17+
var authorOrAdmin = this.user.isAdmin || String(this.user._id) == String(courseFeedback.participant.user);
18+
this.locals.authorOrAdmin = authorOrAdmin;
19+
1820
if (!courseFeedback.isPublic && !authorOrAdmin) {
1921
this.throw(403, "Отзыв не публичный");
2022
}
2123

2224
this.locals.participantUser = yield User.findById(courseFeedback.participant.user).exec();
2325

24-
var group = this.locals.group = courseFeedback.courseGroup;
26+
var group = this.locals.group = courseFeedback.group;
2527

2628
this.locals.title = "Отзыв\n" + group.title;
2729

handlers/courses/controller/groupFeedback.js

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const countries = require('countries');
22
const ImgurImage = require('imgur').ImgurImage;
3-
const CourseFeedback = require('../models/courseFeedback')
3+
const CourseFeedback = require('../models/courseFeedback');
4+
const CourseParticipant = require('../models/courseParticipant');
45
const _ = require('lodash');
56

67
exports.all = function*() {
@@ -9,22 +10,23 @@ exports.all = function*() {
910

1011
this.locals.title = "Отзыв\n" + group.title;
1112

12-
var participant = this.locals.participant = group.getParticipantByUserId(this.user._id);
13+
this.locals.participant = this.participant;
14+
1315
this.locals.countries = countries.all;
1416

1517
var courseFeedback = yield CourseFeedback.findOne({
16-
participant: participant._id
18+
participant: this.participant._id
1719
}).exec();
1820

1921
if (!courseFeedback) {
2022
courseFeedback = new CourseFeedback({
2123
recommend: true,
2224
isPublic: true,
23-
country: participant.country,
24-
photo: participant.photo,
25-
aboutLink: participant.aboutLink,
26-
city: participant.city,
27-
occupation: participant.occupation
25+
country: this.participant.country,
26+
photo: this.participant.photo,
27+
aboutLink: this.participant.aboutLink,
28+
city: this.participant.city,
29+
occupation: this.participant.occupation
2830
});
2931
}
3032

@@ -33,8 +35,8 @@ exports.all = function*() {
3335
'stars content country city isPublic recommend aboutLink occupation'.split(' ')
3436
);
3537

36-
feedbackData.participant = participant._id;
37-
feedbackData.courseGroup = group._id;
38+
feedbackData.participant = this.participant._id;
39+
feedbackData.group = group._id;
3840
feedbackData.recommend = Boolean(+feedbackData.recommend);
3941
feedbackData.isPublic = Boolean(+feedbackData.isPublic);
4042

handlers/courses/controller/groupMaterials.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
var bytes = require('bytes');
22
var Course = require('../models/course');
33
var CourseGroup = require('../models/courseGroup');
4+
var CourseParticipant = require('../models/courseParticipant');
45
var _ = require('lodash');
56

67
// Group info for a participant, with user instructions on how to login
@@ -14,11 +15,7 @@ exports.get = function*() {
1415

1516
this.locals.title = "Материалы для обучения\n" + group.title;
1617

17-
var participant = group.participants.filter(function(p) {
18-
return String(p.user) == String(this.user._id);
19-
}.bind(this))[0];
20-
21-
this.locals.participant = participant;
18+
this.locals.participant = this.participant;
2219

2320
var materials = this.locals.materials = [];
2421
for (var i = 0; i < group.materials.length; i++) {
@@ -32,6 +29,6 @@ exports.get = function*() {
3229
}
3330

3431
this.body = this.render('groupMaterials', {
35-
videoKey: participant.videoKey
32+
videoKey: this.participant.videoKey
3633
});
3734
};

handlers/courses/controller/groupMaterialsDownload.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ exports.get = function*() {
1111

1212
var material = _.where(group.materials, {filename: this.params.filename})[0];
1313

14-
console.log(material);
1514
// ensure the path to material is valid
1615
if (!material) {
1716
this.throw(404);

handlers/courses/controller/invite.js

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,22 @@ exports.all = function*() {
4848
}
4949

5050
//yield CourseGroup.populate(invite.group, {path: 'participants'});
51-
yield CourseGroup.populate(invite.group, 'participants course');
52-
yield User.populate(invite.group, 'participants.user');
51+
yield CourseGroup.populate(invite.group, 'course');
52+
53+
var userByEmail = yield User.findOne({
54+
email: invite.email
55+
}).exec();
56+
57+
var participantByEmail = yield CourseParticipant.findOne({
58+
isActive: true,
59+
group: invite.group._id,
60+
user: userByEmail._id
61+
}).exec();
62+
5363

54-
var participantsByEmail = _.indexBy(_.pluck(invite.group.participants, 'user'), 'email');
5564
// invite was NOT accepted, but this guy is a participant (added manually?),
5665
// so show the same as accepted
57-
if (participantsByEmail[invite.email]) {
66+
if (participantByEmail) {
5867
this.addFlashMessage("success", "Вы уже участник курса. Ниже, рядом с курсом, вы найдёте инструкцию.");
5968
this.redirect(this.user.getProfileUrl() + '/courses');
6069
return;
@@ -109,7 +118,8 @@ function* askParticipantDetails(invite) {
109118
var participantData = _.pick(this.request.body,
110119
'photoId firstName surname country city aboutLink occupation purpose wishes'.split(' ')
111120
);
112-
participantData.user = this.user;
121+
participantData.user = this.user._id;
122+
participantData.group = invite.group._id;
113123

114124
if (participantData.photoId) {
115125
var photo = yield ImgurImage.findOne({imgurId: this.request.body.photoId}).exec();
@@ -122,6 +132,7 @@ function* askParticipantDetails(invite) {
122132
participantData.photo = this.user.photo;
123133
}
124134

135+
125136
var participant = new CourseParticipant(participantData);
126137

127138
try {
@@ -161,9 +172,7 @@ function* askParticipantDetails(invite) {
161172

162173
}
163174

164-
function* acceptParticipant(invite, participant) {
165-
166-
invite.group.participants.push(participant._id);
175+
function* acceptParticipant(invite) {
167176

168177
this.user.profileTabsEnabled.addToSet('courses');
169178
yield this.user.persist();
@@ -174,16 +183,21 @@ function* acceptParticipant(invite, participant) {
174183

175184
yield invite.group.persist();
176185

186+
yield CourseGroup.populate(invite.group, 'course');
187+
188+
189+
var participants = yield CourseParticipant.find({
190+
group: invite.group._id,
191+
isActive: true
192+
}).populate('user').exec();
177193

178-
yield CourseGroup.populate(invite.group, 'participants course');
179-
yield User.populate(invite.group, 'participants.user');
180194

181195
if (process.env.NODE_ENV != 'development') {
182-
yield* grantXmppChatMemberships(invite.group);
196+
yield* grantXmppChatMemberships(invite.group, participants);
183197
}
184198

185199
if (invite.group.course.videoKeyTag) {
186-
yield *grantVideoKeys(invite.group);
200+
yield *grantVideoKeys(invite.group, participants);
187201
}
188202

189203

@@ -262,7 +276,7 @@ function* loginByInvite(invite) {
262276
}
263277

264278

265-
function* grantXmppChatMemberships(group) {
279+
function* grantXmppChatMemberships(group, participants) {
266280
log.debug("Grant xmpp chat membership");
267281
// grant membership in chat
268282
var client = new xmppClient({
@@ -277,14 +291,13 @@ function* grantXmppChatMemberships(group) {
277291
membersOnly: 1
278292
});
279293

280-
281294
var jobs = [];
282-
for (var i = 0; i < group.participants.length; i++) {
283-
var participant = group.participants[i];
295+
for (var i = 0; i < participants.length; i++) {
296+
var participant = participants[i];
284297

285298
log.debug("grant " + roomJid + " to", participant.user.profileName, participant.firstName, participant.surname);
286299

287-
jobs.push(client.grantMember(roomJid, participant.user.profileName, participant.firstName + ' ' + participant.surname));
300+
jobs.push(client.grantMember(roomJid, participant.user.profileName, participant.fullName));
288301
}
289302

290303
// grant all in parallel
@@ -293,25 +306,25 @@ function* grantXmppChatMemberships(group) {
293306
client.disconnect();
294307
}
295308

296-
function* grantVideoKeys(group) {
309+
function* grantVideoKeys(group, participants) {
297310

298-
var participants = group.participants.filter(function(participant) {
311+
var participantsWithoutKeys = participants.filter(function(participant) {
299312
return !participant.videoKey;
300313
});
301314

302315
var videoKeys = yield VideoKey.find({
303316
tag: group.course.videoKeyTag,
304317
used: false
305-
}).limit(participants.length).exec();
318+
}).limit(participantsWithoutKeys.length).exec();
306319

307320
log.debug("Keys selected", videoKeys && videoKeys.toArray());
308321

309-
if (!videoKeys || videoKeys.length != participants.length) {
310-
throw new Error("Недостаточно серийных номеров " + participants.length);
322+
if (!videoKeys || videoKeys.length != participantsWithoutKeys.length) {
323+
throw new Error("Недостаточно серийных номеров " + participantsWithoutKeys.length);
311324
}
312325

313-
for (var i = 0; i < participants.length; i++) {
314-
var participant = participants[i];
326+
for (var i = 0; i < participantsWithoutKeys.length; i++) {
327+
var participant = participantsWithoutKeys[i];
315328
participant.videoKey = videoKeys[i].key;
316329
videoKeys[i].used = true;
317330
}
Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
var _ = require('lodash');
1+
const _ = require('lodash');
2+
const CourseParticipant = require('../models/courseParticipant');
23

34
module.exports = function*(next) {
45

@@ -8,11 +9,17 @@ module.exports = function*(next) {
89
this.throw(401);
910
}
1011

11-
var participantIds = _.pluck(group.participants, 'user').map(String);
12+
var participant = yield CourseParticipant.findOne({
13+
isActive: true,
14+
group: group._id,
15+
user: this.user._id
16+
}).exec();
1217

13-
if (!~participantIds.indexOf(String(this.user._id))) {
18+
if (!participant) {
1419
this.throw(403, "Вы не являетесь участником этой группы.");
1520
}
1621

22+
this.participant = participant;
23+
1724
yield* next;
1825
};

handlers/courses/lib/routeGroupBySlug.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
const CourseGroup = require('../models/courseGroup');
2+
const CourseParticipant = require('../models/courseGroup');
23

34
module.exports = function*(slug, next) {
45

56
var group = yield CourseGroup.findOne({
67
slug: slug
7-
}).populate('course participants').exec();
8+
}).populate('course').exec();
89

910
if (!group) {
1011
this.throw(404, "Нет такой группы.");

handlers/courses/models/courseFeedback.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ var countries = require('countries');
55

66
var schema = new Schema({
77

8-
courseGroup: {
8+
group: {
99
type: Schema.Types.ObjectId,
1010
ref: 'CourseGroup',
1111
required: true

0 commit comments

Comments
 (0)