コード例 #1
0
ファイル: utils.py プロジェクト: GeographicaGS/moocng
def change_user_group(id_user, id_group, new_id_group, pos_lat=0.0, pos_lon=0.0):
    groupCollection = mongodb.get_db().get_collection('groups')
    group = groupCollection.find_one({'_id': ObjectId(id_group)})

    for m in group["members"]:
        if m["id_user"] == id_user:
            member = m
            group["members"].remove(m)
            if "size" in group:
                group["size"] -= 1
            else:
                group["size"] = len(group["members"])

    groupCollection.update({'_id': ObjectId(id_group)}, {"$set": {"members": group["members"], "size": group["size"]}})
    group = groupCollection.find_one({'_id': ObjectId(new_id_group)})
    group["members"].append(member)
    if "size" in group:
        group["size"] += 1
    else:
        group["size"] = len(group["members"])
    groupCollection.update({'_id': ObjectId(new_id_group)}, {"$set": {"members": group["members"], "size": group["size"]}})

    groupsActivityCollection = mongodb.get_db().get_collection('groups_activity')
    timestamp = int(round(time.time() * 1000))
    activity_entry = {"id_course": group["id_course"], "id_user": id_user, "former_id_group": ObjectId(id_group), "new_id_group": ObjectId(new_id_group), "timestamp": timestamp, "lat": pos_lat, "lon": pos_lon}
    groupsActivityCollection.insert(activity_entry)
コード例 #2
0
ファイル: views.py プロジェクト: GeographicaGS/moocng
def profile_badge(request, badgeid, id=None):

	if (badgeid):
		if(not id):
			if(not request.user.id):
				return HttpResponseRedirect("/auth/login")
			user = request.user
			id = request.user.id
		else:
			user = User.objects.get(username=id)
			id = user.id

		badge = get_db().get_collection('badge').find({"id_user": id, "id_badge": int(badgeid)})[0]
		hashed_email = hashlib.sha256(user.email + settings.BADGES_HASH_SALT).hexdigest()
		badge['id'] = badge['_id']

		return render_to_response('profile/badge.html', {
			"id":id,
			'request': request,
			"user_view_profile": user,
			"badges_count": get_db().get_collection('badge').find({"id_user": id}).count(),
			"hashed_email": hashed_email,
			"badge": badge,
			"openbadges_service_url": settings.BADGES_SERVICE_URL,
			}, context_instance=RequestContext(request))
	else:
		return HttpResponseBadRequest()
コード例 #3
0
ファイル: resources.py プロジェクト: HengeSense/moocng
 def obj_delete(self, request, **kwargs):
     obj = self.obj_get(request, **kwargs)
     #submissions and reviews must be deleted too
     submissions = get_db().get_collection('peer_review_submissions')
     submissions.remove({'kq': obj.kq_id})
     reviews = get_db().get_collection('peer_review_reviews')
     reviews.remove({'kq': obj.kq_id})
     super(PrivatePeerReviewAssignmentResource, self).obj_delete(request, **kwargs)
コード例 #4
0
ファイル: models.py プロジェクト: GeographicaGS/moocng
	def update_following_blog_user(self, id, following, extra=None):
		get_db().get_collection(self.col_user).update({"id_user": id}, {"$set": {"following": following}})

		# xAPI
		if extra:
			user = User.objects.get(pk=id)
			course = None
			resource = {
				'type': 'microblogfollow',
				'user_id': extra['user_id']
			}
			geolocation = extra.get('geolocation')
			x_api.learnerInteracts(user, resource, course, geolocation)
コード例 #5
0
ファイル: methods.py プロジェクト: GeographicaGS/moocng
def unenroll_student(course, student):
    from moocng import mongodb
    from bson.objectid import ObjectId
    from moocng.x_api import utils as x_api

    if course.has_groups:
        groupCollection = mongodb.get_db().get_collection('groups')
        group = groupCollection.find_one( { 'id_course': course.id, 'members.id_user':student.id } )
        if(group):
            for m in group["members"]:
                if(m["id_user"] == student.id):
                    group["members"].remove(m)
                    if "size" in group:
                        group["size"] -= 1
                    else:
                        group["size"] = len(group["members"])

            groupCollection.update({'_id': ObjectId(group["_id"])}, {"$set": {"members": group["members"], "size": group["size"]}})

    course.students.through.objects.get(student=student,
                                        course=course).delete()

    geolocation = {
        'lat': 0.0,
        'lon': 0.0
    }

    x_api.learnerUnenrollsInMooc(student, course, geolocation)
コード例 #6
0
ファイル: tasks.py プロジェクト: NoriVicJr/moocng
def on_activity_created_task(activity_created, unit_activity, course_activity):
    db = get_db()
    kq = KnowledgeQuantum.objects.get(id=activity_created["kq_id"])
    kq_type = kq.kq_type()

    # KQ
    data = {"viewed": 1}
    if kq_type == "Video":
        data["passed"] = 1
    stats_kq = db.get_collection("stats_kq")
    stats_kq.update({"kq_id": activity_created["kq_id"]}, {"$inc": data}, safe=True)

    # UNIT
    data = {}
    if unit_activity == 1:  # First activity of the unit
        data["started"] = 1
    elif kq.unit.knowledgequantum_set.count() == unit_activity:
        data["completed"] = 1
    # TODO passed
    if data.keys():
        stats_unit = db.get_collection("stats_unit")
        stats_unit.update({"unit_id": kq.unit.id}, {"$inc": data}, safe=True)

    # COURSE
    course_kqs = KnowledgeQuantum.objects.filter(unit__course__id=activity_created["course_id"]).count()
    data = {}
    if course_activity == 1:  # First activity of the course
        data["started"] = 1
    elif course_kqs == course_activity:
        data["completed"] = 1
    # TODO passed
    if data.keys():
        stats_course = db.get_collection("stats_course")
        stats_course.update({"course_id": activity_created["course_id"]}, {"$inc": data}, safe=True)
コード例 #7
0
    def forwards(self, orm):
        from moocng.mongodb import get_db

        db = get_db()
        activity = db.get_collection("groups")

        activity.create_index([("id_course", pymongo.ASCENDING)])
コード例 #8
0
ファイル: views.py プロジェクト: Yangff/moocng
def teacheradmin_stats(request, course_slug):
    course = get_object_or_404(Course, slug=course_slug)
    is_enrolled = course.students.filter(id=request.user.id).exists()

    stats_course = get_db().get_collection('stats_course')
    stats = stats_course.find_one({'course_id': course.id})

    if stats is not None:
        data = {
            'enrolled': course.students.count(),
            'started': stats.get('started', -1),
            'completed': stats.get('completed', -1),
        }

        if course.threshold is not None:
            #if the course doesn't support certification, then don't return the
            #'passed' stat since it doesn't apply
            data['passed'] = stats.get('passed', -1)

        return render_to_response('teacheradmin/stats.html', {
            'course': course,
            'is_enrolled': is_enrolled,
            'initial_data': simplejson.dumps(data),
        }, context_instance=RequestContext(request))
    else:
        messages.error(request, _(u"There are no statistics for this course."))
        return HttpResponseRedirect(reverse('teacheradmin_info',
                                            args=[course_slug]))
コード例 #9
0
ファイル: tasks.py プロジェクト: Macro-Bin/moocng
def update_stats(submitted, data_kq=None, data_unit=None, data_course=None):
    db = get_db()
    data_kq = data_kq or {}
    data_unit = data_unit or {}
    data_course = data_course or {}
    # KQ
    # TODO passed
    if data_kq.keys():
        stats_kq = db.get_collection('stats_kq')
        stats_kq.update(
            {'kq_id': submitted['kq_id']},
            {'$inc': data_kq},
            safe=True
        )

    # UNIT
    # TODO passed
    if data_unit.keys():
        stats_unit = db.get_collection('stats_unit')
        stats_unit.update(
            {'unit_id': submitted['unit_id']},
            {'$inc': data_unit},
            safe=True
        )

    # COURSE
    # TODO passed
    if data_course.keys():
        stats_course = db.get_collection('stats_course')
        stats_course.update(
            {'course_id': submitted['course_id']},
            {'$inc': data_course},
            safe=True
        )
コード例 #10
0
ファイル: utils.py プロジェクト: Macro-Bin/moocng
def clone_activity_user_course(user, copy_course, original_course=None, force_email=False):
    if not original_course:
        original_course = copy_course.created_from
        if not original_course:
            raise ValueError("This course needs a original course")
    try:
        course_student_relation = user.coursestudent_set.get(course=copy_course)
    except CourseStudent.DoesNotExist:
        return ([], [], [])

    file_name = get_trace_clone_file_name(original_course, copy_course)
    file_path = get_trace_clone_file_path(file_name)
    f = open(file_path)
    trace_ids = json.loads(f.read())
    f.close()
    if not copy_course.pk == trace_ids['Course'][str(original_course.pk)]:
        raise ValueError

    mongo_db = mongodb.get_db()

    new_act_docs = _clone_activity_user_course(mongo_db, trace_ids, user,
                                               copy_course, original_course)

    insert_answer_docs, update_answer_docs = _clone_answer_user_course(
        mongo_db, trace_ids, user,
        copy_course, original_course)

    if (new_act_docs or insert_answer_docs or update_answer_docs or
       course_student_relation.old_course_status != 'c' or force_email):
        if course_student_relation.old_course_status != 'c':
            course_student_relation.old_course_status = 'c'
            course_student_relation.save()
        if not settings.DEBUG:
            send_cloned_activity_email(original_course, copy_course, user)
    return (new_act_docs, insert_answer_docs, update_answer_docs)
コード例 #11
0
ファイル: resources.py プロジェクト: HengeSense/moocng
 def dispatch(self, request_type, request, **kwargs):
     db = get_db()
     self.user_answers = get_user(request, db.get_collection('answers'))
     self.user_activity = get_user(request, db.get_collection('activity'))
     return super(KnowledgeQuantumResource, self).dispatch(request_type,
                                                           request,
                                                           **kwargs)
コード例 #12
0
ファイル: views.py プロジェクト: tao12345666333/moocng
def teacheradmin_stats(request, course_slug):
    course = get_object_or_404(Course, slug=course_slug)
    is_enrolled = course.students.filter(id=request.user.id).exists()

    stats_course = get_db().get_collection('stats_course')
    stats = stats_course.find_one({'course_id': course.id})

    if stats is not None:
        data = {
            'enrolled': course.students.count(),
            'started': stats.get('started', -1),
            'completed': stats.get('completed', -1),
        }

        if course.threshold is not None:
            #if the course doesn't support certification, then don't return the
            #'passed' stat since it doesn't apply
            data['passed'] = stats.get('passed', -1)

        return render_to_response('teacheradmin/stats.html', {
            'course': course,
            'is_enrolled': is_enrolled,
            'initial_data': simplejson.dumps(data),
        },
                                  context_instance=RequestContext(request))
    else:
        messages.error(request, _(u"There are no statistics for this course."))
        return HttpResponseRedirect(
            reverse('teacheradmin_info', args=[course_slug]))
コード例 #13
0
def save_review(kq, reviewer, user_reviewed, criteria, comment):

    parsed_criteria = [[int(a), int(b)] for (a, b) in criteria]

    db = get_db()
    submissions = db.get_collection("peer_review_submissions")
    reviews = db.get_collection("peer_review_reviews")

    submission = submissions.find_one({
        "author": user_reviewed.id,
        "kq": kq.id
    })

    peer_review_review = {
        "submission_id": submission.get("_id"),
        "author": user_reviewed.id,
        "comment": comment,
        "created": datetime.utcnow(),
        "reviewer": reviewer.id,
        "criteria": parsed_criteria,
        "kq": kq.id,
        "unit": kq.unit.id,
        "course": kq.unit.course.id
    }

    review_exists = (reviews.find({
        "submission_id": submission.get("_id"),
        "reviewer": reviewer.id,
    }).count() > 0)

    if review_exists:
        raise IntegrityError("Already exist one review for this submission and"
                             " reviewer")

    reviews.insert(peer_review_review)

    submissions.update({
        "author": user_reviewed.id,
        "kq": kq.id,
    }, {
        "$inc": {
            "reviews": 1,
        },
        "$unset": {
            "assigned_to": 1,
            "assigned_when": 1,
        },
        "$push": {
            "reviewers": reviewer.id,
        }
    })

    submissions.update({
        "author": reviewer.id,
        "kq": kq.id,
    }, {"$inc": {
        "author_reviews": 1,
    }})

    return peer_review_review
コード例 #14
0
ファイル: migrate_marks.py プロジェクト: Macro-Bin/moocng
 def handle(self, *args, **options):
     users = User.objects.all()
     if options["user"]:
         users = users.filter(pk=options["user"])
         if not users:
             raise CommandError(u"User %s does not exist" % options["user"])
         self.message("Migrating the user: %s" % users[0].username)
     elif settings.NUM_MIGRATE_MARK_DAILY is not None:
         email_list = options["email_list"]
         if not email_list:
             raise CommandError(u"Please you have to pass the email list")
         first_day = datetime.strptime(settings.FIRST_DAY_MIGRATE_MARK, '%Y-%m-%d')
         today = datetime.today()
         num_days = (today - first_day).days
         start_pk = num_days * settings.NUM_MIGRATE_MARK_DAILY + 1
         end_pk = (num_days + 1) * settings.NUM_MIGRATE_MARK_DAILY
         self.message("Migrating the users from pk=%s to pk=%s " % (start_pk, end_pk))
         users = users.filter(pk__gte=start_pk, pk__lte=end_pk)
         max_pk = User.objects.aggregate(Max('pk'))['pk__max']
         if not users and end_pk >= max_pk:
             send_mail('The mark migration is finished',
                       'The mark migration is finished',
                       settings.DEFAULT_FROM_EMAIL,
                       email_list.split(','))
     db = get_db()
     for user in users:
         for course in user.courses_as_student.all():
             for unit in course.unit_set.scorables():
                 for kq in unit.knowledgequantum_set.all():
                     updated_kq, passed_kq_now = update_kq_mark(db, kq, user, course.threshold)
                     self.update_passed(db, 'stats_kq', passed_kq_now, {'kq_id': kq.pk})
                 updated_unit, passed_unit_now = update_unit_mark(db, unit, user, course.threshold)
                 self.update_passed(db, 'stats_unit', passed_unit_now, {'unit_id': unit.pk})
             updated_course, passed_course_now = update_course_mark(db, course, user)
             self.update_passed(db, 'stats_course', passed_course_now, {'course_id': course.pk})
コード例 #15
0
ファイル: validation.py プロジェクト: MCHacker/moocng
    def is_valid(self, bundle, request):
        if not bundle.data or not ("kq" in bundle.data):
            return {'__all__': 'Expected kq id'}

        errors = {}

        db = get_db()
        collection = db.get_collection("peer_review_submissions")

        exists = collection.find({
            "kq": bundle.data["kq"],
            "author": unicode(request.user.id)
        })

        if exists.count() > 0:
            msg = "Already exists a submission for kq=%s and user=%s" % (
                bundle.data["kq"],
                request.user.id)
            logger.error(msg)
            errors["kq"] = [msg]
            errors["author"] = [msg]

        text = bundle.data.get("text", "")
        max_text_leng = getattr(settings, "PEER_REVIEW_TEXT_MAX_SIZE", 5000)

        if len(text) > max_text_leng:
            errors["text"] = "Text is longer than %s chars" % max_text_leng

        return errors
コード例 #16
0
    def handle(self, *args, **options):
        activity = get_db().get_collection('activity')
        to_fix = activity.find({'$where': 'function() { return this.unit_id == null; }'})
        fixed_counter = 0
        removed_counter = 0
        total = to_fix.count()

        if total > 0:
            for act in to_fix:
                try:
                    kq = KnowledgeQuantum.objects.get(id=int(act['kq_id']))
                    activity.update(
                        {'kq_id': act['kq_id']},
                        {'$set': {'unit_id': kq.unit.id}},
                    )
                    fixed_counter += 1
                except KnowledgeQuantum.DoesNotExist:
                    activity.remove({'kq_id': act['kq_id']})
                    removed_counter += 1

                if ((total / 100) % (fixed_counter + removed_counter)) == 0:
                    percent = int(total / (fixed_counter + removed_counter))
                    print 'Progress: %d%% of %d' % (percent, total)

        print 'Fixed %d activities, removed %d' % (fixed_counter, removed_counter)
コード例 #17
0
ファイル: fix_activities_ids.py プロジェクト: jespino/moocng
    def handle(self, *args, **options):
        activity = get_db().get_collection('activity')
        to_fix = activity.find({'$where': 'function() { return this.unit_id == null; }'})
        fixed_counter = 0
        removed_counter = 0
        total = to_fix.count()

        if total > 0:
            for act in to_fix:
                try:
                    kq = KnowledgeQuantum.objects.get(id=int(act['kq_id']))
                    activity.update(
                        {'kq_id': act['kq_id']},
                        {'$set': {'unit_id': kq.unit.id}},
                    )
                    fixed_counter += 1
                except KnowledgeQuantum.DoesNotExist:
                    activity.remove({'kq_id': act['kq_id']})
                    removed_counter += 1

                if ((total / 100) % (fixed_counter + removed_counter)) == 0:
                    percent = int(total / (fixed_counter + removed_counter))
                    print 'Progress: %d%% of %d' % (percent, total)

        print 'Fixed %d activities, removed %d' % (fixed_counter, removed_counter)
コード例 #18
0
ファイル: validation.py プロジェクト: NorthStar/moocng
    def is_valid(self, bundle, request):
        if not bundle.data or not ("kq" in bundle.data):
            return {'__all__': 'Expected kq id'}

        errors = {}

        db = get_db()
        collection = db.get_collection("peer_review_submissions")

        exists = collection.find({
            "kq": bundle.data["kq"],
            "author": unicode(request.user.id)
        })

        if exists.count() > 0:
            msg = "Already exists a submission for kq=%s and user=%s" % (
                bundle.data["kq"], request.user.id)
            logger.error(msg)
            errors["kq"] = [msg]
            errors["author"] = [msg]

        text = bundle.data.get("text", "")
        max_text_leng = getattr(settings, "PEER_REVIEW_TEXT_MAX_SIZE", 5000)

        if len(text) > max_text_leng:
            errors["text"] = "Text is longer than %s chars" % max_text_leng

        return errors
コード例 #19
0
ファイル: models.py プロジェクト: GeographicaGS/moocng
	def search_posts(self, query, page):
	    postCollection = get_db().get_collection(self.col_post)
	    mongoQuery = {'$regex': '.*%s.*' % (query)}

	    posts = postCollection.find({'text': mongoQuery})[page:page+10].sort("date",pymongo.DESCENDING)

	    return self._process_post_list(posts)
コード例 #20
0
ファイル: tasks.py プロジェクト: fid-jose/moocng
def update_mark(submitted):
    from moocng.courses.marks import calculate_kq_mark, calculate_unit_mark, calculate_course_mark
    updated_kq_mark = updated_unit_mark = updated_course_mark = False
    passed_kq = passed_unit = passed_course = False
    kq = KnowledgeQuantum.objects.get(pk=submitted['kq_id'])
    unit = kq.unit
    course = kq.unit.course
    user = User.objects.get(pk=submitted['user_id'])
    mark_kq, mark_normalized_kq = calculate_kq_mark(kq, user)

    db = get_db()

    # KQ
    updated_kq_mark, passed_kq = update_kq_mark(db, kq, user, course.threshold,
                                                new_mark_kq=mark_kq,
                                                new_mark_normalized_kq=mark_normalized_kq)

    # UNIT
    if not updated_kq_mark:
        return (updated_kq_mark, updated_unit_mark, updated_course_mark,
                passed_kq, passed_unit, passed_course)

    mark_unit, mark_normalized_unit = calculate_unit_mark(kq.unit, user)
    updated_unit_mark, passed_unit = update_unit_mark(db, unit, user, course.threshold,
                                                      new_mark_unit=mark_unit,
                                                      new_mark_normalized_unit=mark_normalized_unit)

    # COURSE
    if not updated_unit_mark:
        return (updated_kq_mark, updated_unit_mark, updated_course_mark,
                passed_kq, passed_unit, passed_course)
    mark_course, units_info = calculate_course_mark(unit.course, user)
    updated_course_mark, passed_course = update_course_mark(db, course, user, mark_course)
    return (updated_kq_mark, updated_unit_mark, updated_course_mark,
            passed_kq, passed_unit, passed_course)
コード例 #21
0
ファイル: models.py プロジェクト: GeographicaGS/moocng
	def _process_post_children(self, post, id_user=None):
		postCollection = get_db().get_collection(self.col_post)
		from_zone = tz.tzutc()
		to_zone = tz.tzlocal()
		post['replies'] = []
		for child in post['children']:
			try:
				post_child = postCollection.find({
					'$and': [
						{'_id': child},
						{'$or': [ {'deleted': {'$exists': False} }, {'deleted': False} ] }
					]
				}).limit(1)[0]
				if post_child and len(post_child['children']) > 0:
					self._process_post_children(post_child, id_user)

				post_child["date"] = datetime.strptime(post_child.get("date"), "%Y-%m-%dT%H:%M:%S.%f").replace(tzinfo=from_zone).astimezone(to_zone).strftime('%d %b %Y').upper()
				if("original_date" in post_child):
					post_child["original_date"] = datetime.strptime(post_child.get("original_date"), "%Y-%m-%dT%H:%M:%S.%f").replace(tzinfo=from_zone).astimezone(to_zone).strftime('%d %b %Y').upper()
				post_child["id"] = post_child.pop("_id")
				post_child["text"] = self._process_urls(post_child["text"])
				post_child["text"] = self._process_hashtags(post_child["text"])
				if id_user:
					user_voted = [x for x in post_child["voters"] if id_user == x["id_user"]]
					post_child["user_vote"] = 0
					for user_vote in user_voted:
						post_child["user_vote"] += user_vote["vote"]

				post['replies'].append(post_child)
			except:
				pass
コード例 #22
0
ファイル: views.py プロジェクト: GeographicaGS/moocng
def profile_user(request, id, byid=False):

	if(not id):
		case = None
		if(not request.user.id):
			return HttpResponseRedirect('/auth/login')
		id = request.user.id
		user =  request.user
	else:
		case = _getCase(request,id)
		if byid:
			user = User.objects.get(pk=id)
		else:
			user = User.objects.get(username=id)
			id = user.id

	courses = get_courses_user_is_enrolled(user)

	return render_to_response('profile/user.html', {
		'id': id,
		'case': case,
		'badges_count': get_db().get_collection('badge').find({'id_user': id}).count(),
		'request': request,
		'courses': courses,
		'is_user': True,
		'user_view_profile': user,
		}, context_instance=RequestContext(request))
コード例 #23
0
ファイル: utils.py プロジェクト: fid-jose/moocng
def insert_p2p_if_does_not_exists_or_raise(p2p_submission, submissions=None):
    if submissions is None:
        db = get_db()
        submissions = db.get_collection("peer_review_submissions")
    if submissions.find({'kq': p2p_submission['kq'], 'author': p2p_submission['author']}).count() > 0:
        raise BadRequest(_('You have already sent a submission. Please reload the page'))
    return submissions.insert(p2p_submission)
コード例 #24
0
ファイル: models.py プロジェクト: GeographicaGS/moocng
	def save_retweet(self, post_id, user_id, username, extra=None):
		postCollection = get_db().get_collection(self.col_post)
		post = postCollection.find_one({"$and": [{"id_user":user_id},{"id_original_post":ObjectId(post_id)}]})

		if(not post):
			postCollection.update({"$or": [{"_id": ObjectId(post_id)}, {"id_original_post": ObjectId(post_id)}]}, {"$inc": {"shared":  1}}, multi=True)
			post = postCollection.find_one({"_id": ObjectId(post_id)})
			post["id_author"] = post["id_user"]
			post["id_user"] = user_id
			post["id_original_post"] = post["_id"]
			post["original_date"] = post["date"]
			post["date"] = datetime.utcnow().isoformat()
			post["shared_by"] = "@%s" % (username)
			del post["_id"]
			rtpost_id = super(Microblog,self).insert_post(post)

			# xAPI
			if extra:
				user = User.objects.get(pk=user_id)
				course = None
				resource = {
					'type': 'microblogshare',
					'url': 'https://%s%s#%s' % (settings.API_URI, reverse('profile_posts_byid', kwargs={'id': user_id}), rtpost_id),
					'name': 'Microblog post',
					'description': 'This is a blog post'
				}
				geolocation = extra.get('geolocation')
				x_api.learnerSubmitsAResource(user, resource, course, geolocation)
			return True
		else:
			return False
コード例 #25
0
ファイル: views.py プロジェクト: HengeSense/moocng
def teacheradmin_stats_kqs(request, course_slug):
    course = get_object_or_404(Course, slug=course_slug)
    if not 'unit' in request.GET:
        return HttpResponse(status=400)
    unit = get_object_or_404(Unit, id=request.GET['unit'])
    if not unit in course.unit_set.all():
        return HttpResponse(status=400)
    data = []
    activity = get_db().get_collection('activity')
    answers = get_db().get_collection('answers')

    kq_list = unit.knowledgequantum_set.all()
    for kq in kq_list:
        kq_data = {
            'id': kq.id,
            'title': kq.title,
            'viewed': 0
        }

        question = None
        if kq.question_set.count() > 0:
            question = kq.question_set.all()[0]
            kq_data['answered'] = 0

            # if course.threshold is not None:
            #     # if the course doesn't support certification, then don't
            #     # return the 'passed' stat since it doesn't apply
            #     kq_data['passed'] = 0
            #     for student in course.students.all():
            #         if calculate_kq_mark(kq, student) >= float(course.threshold):
            #             kq_data['passed'] += 1

        kq_data["viewed"] = activity.find({
            "courses.%s.kqs" % course.id: str(kq.id)
        }).count()

        for question in kq.question_set.all():
            kq_data["answered"] = answers.find({
                "questions.%s" % question.id: {
                    "$exists": True
                }
            }).count()

        data.append(kq_data)

    return HttpResponse(simplejson.dumps(data),
                        mimetype='application/json')
コード例 #26
0
ファイル: tasks.py プロジェクト: GeographicaGS/moocng
def update_unit_mark(db, unit, user, threshold, new_mark_unit=None, new_mark_normalized_unit=None):
    from moocng.courses.marks import calculate_unit_mark
    if not new_mark_unit or not new_mark_normalized_unit:
        new_mark_unit, new_mark_normalized_unit = calculate_unit_mark(unit, user)
    data_unit = {}
    data_unit['user_id'] = user.pk
    data_unit['course_id'] = unit.course_id
    data_unit['unit_id'] = unit.pk

    marks_unit = db.get_collection('marks_unit')
    mark_unit_item = marks_unit.find_one(data_unit)
    if mark_unit_item:
        updated_unit_mark = (new_mark_unit != mark_unit_item['mark'] or
                             new_mark_normalized_unit != mark_unit_item['relative_mark'])
        if updated_unit_mark:
            marks_unit.update(
                data_unit,
                {'$set': {'mark': new_mark_unit,
                          'relative_mark': new_mark_normalized_unit}},
                safe=True
            )
    else:
        updated_unit_mark = True
        data_unit['mark'] = new_mark_unit
        data_unit['relative_mark'] = new_mark_normalized_unit
        marks_unit.insert(data_unit)

    # check if user completed this unit
    unit_kqs = unit.knowledgequantum_set.all()
    completed = True
    for kq in unit_kqs:
        if not kq.is_completed(user):
            completed = False

    today = date.today()

    if completed:
        # badge unique unit
        badges = BadgeByCourse.objects.filter(course_id=unit.course_id, criteria_type=2, criteria=unit.id)
        for badge in badges:
            win = False
            if(badge.note <= new_mark_unit):
                gotBadge = get_db().get_collection('badge').find_one({'id_badge': badge.id, "id_user": user.pk})
                if(not gotBadge):
                    get_db().get_collection('badge').insert({"id_badge":badge.id, "id_user":user.pk, "title":badge.title, "description":badge.description, "color":badge.color, "date": today.isoformat()})

    return updated_unit_mark, has_passed_now(new_mark_unit, mark_unit_item, threshold)
コード例 #27
0
def kq_get_peer_review_score(kq, author, pra=None):
    """ppr_collection is peer_review_reviews mongo collection

        Return a tuple with (score, scorable)
        * If this kq isn't peer_review type:
            return (None, false)
        * If there is no submission:
            return (0, True)
        * If I haven't reviewed enough submissions of other students:
            return (0, True)
        * If nobody reviewed my submission:
            return (None, False)
        * If there are some reviews from other students to my submission but
          less than the minimum the teacher wants:
            return (Average, False)
        * If I got enough reviews of my submission and I have reviewed enough
          reviews of other students' submissions:
            rerturn (Average, True)
    """

    if not pra:
        try:
            pra = kq.peerreviewassignment
        except PeerReviewAssignment.DoesNotExist:
            return (None, False)

    db = get_db()

    prs_collection = db.get_collection("peer_review_submissions")

    submission = prs_collection.find_one({"kq": kq.id, "author": author.id})

    if not submission:
        return (0, True)

    if (submission.get("author_reviews", 0) < pra.minimum_reviewers):
        return (0, True)

    if (submission["reviews"] == 0):
        return (None, False)

    ppr_collection = db.get_collection("peer_review_reviews")

    reviews = ppr_collection.find({"kq": kq.id, "author": author.id})

    reviews_count = reviews.count()

    sum_average = 0
    for review in reviews:
        sum_average += float(get_peer_review_review_score(review))

    average = sum_average / reviews_count

    if (submission["reviews"] > 0
            and submission.get("author_reviews", 0) < pra.minimum_reviewers):
        return (average, False)

    else:
        return (average, True)
コード例 #28
0
ファイル: tasks.py プロジェクト: GeographicaGS/moocng
def on_activity_created_task(activity_created, unit_activity, course_activity):
    db = get_db()
    kq = KnowledgeQuantum.objects.get(id=activity_created['kq_id'])
    kq_type = kq.kq_type()
    course = Course.objects.get(id=activity_created['course_id'])
    logger.info(course.end_date)
    if date.today() < course.end_date:
        up_kq, up_u, up_c, passed_kq, passed_unit, passed_course = update_mark(activity_created)
    else:
        passed_kq = passed_unit = passed_course = False
    # KQ
    data = {
        'viewed': 1
    }
    if kq_type == 'Video' or passed_kq:
        data['passed'] = 1
    stats_kq = db.get_collection('stats_kq')
    stats_kq.update(
        {'kq_id': activity_created['kq_id']},
        {'$inc': data},
        safe=True
    )

    # UNIT
    data = {}
    if unit_activity == 1:  # First activity of the unit
        data['started'] = 1
    elif kq.unit.knowledgequantum_set.count() == unit_activity:
        data['completed'] = 1

    if passed_unit:
        data['passed'] = 1

    if data.keys():
        stats_unit = db.get_collection('stats_unit')
        stats_unit.update(
            {'unit_id': kq.unit.id},
            {'$inc': data},
            safe=True
        )

    # COURSE
    course_kqs = KnowledgeQuantum.objects.filter(unit__course__id=activity_created['course_id']).count()
    data = {}
    if course_activity == 1:  # First activity of the course
        data['started'] = 1
    elif course_kqs == course_activity:
        data['completed'] = 1

    if passed_course:
        data['passed'] = 1

    if data.keys():
        stats_course = db.get_collection('stats_course')
        stats_course.update(
            {'course_id': activity_created['course_id']},
            {'$inc': data},
            safe=True
        )
コード例 #29
0
ファイル: models.py プロジェクト: GeographicaGS/moocng
	def insert_blog_user(self, user_id, following, extra=None):
		user = {
			"id_user": user_id,
			"following": following
		}
		get_db().get_collection(self.col_user).insert(user)

		# xAPI
		if extra:
			user = User.objects.get(pk=user_id)
			course = None
			resource = {
				'type': 'microblogfollow',
				'user_id': extra['user_id']
			}
			geolocation = extra.get('geolocation')
			x_api.learnerInteracts(user, resource, course, geolocation)
コード例 #30
0
    def handle(self, *args, **options):

        if not options["course_pk"]:
            raise CommandError("-c course_pk is required")

        groups = list(get_groups_by_course(options["course_pk"]))
        print "Groups: " + str(len(groups))
        for group in groups:
            if "forum_slug" in group and group["forum_slug"] is not None:
                print "\nGroup " + str(group["name"]) + " already has forum topic"
            else:
                print "\nGroup " + str(group["name"]) + " has NO forum topic"

                course = Course.objects.filter(id=int(options["course_pk"]))[:1].get()
                split_result = re.split(r'([0-9]+)', course.forum_slug)
                cid = split_result[1]

                content = _(u"This is the topic for ") + group["name"] + _(u" where you can comment and help other team members")
                data = {
                    "uid": 1,
                    "title": group["name"],
                    "content": content,
                    "cid": cid
                }
                timestamp = int(round(time.time() * 1000))
                authhash = hashlib.md5(settings.FORUM_API_SECRET + str(timestamp)).hexdigest()
                headers = {
                    "Content-Type": "application/json",
                    "auth-hash": authhash,
                    "auth-timestamp": timestamp
                }
                
                if settings.FEATURE_FORUM:
                    try:
                        r = requests.post(settings.FORUM_URL + "/api2/topics", data=json.dumps(data), headers=headers)
                        if r.status_code == requests.codes.ok:
                            group["forum_slug"] = r.json()["slug"]
                            mongodb.get_db().get_collection('groups').update({"_id": group["_id"]}, {"$set": {"forum_slug": group["forum_slug"]}})
                            print "  --> Topic for Group '" + group["name"] + "' created succesfully."
                        else:
                            print "  --> Could no create a topic for Group '" + group["name"] + "'. Server returns error code " + r.status_code + "."
                            print r.text

                    except:
                        print "  !!! Error creating course forum topic"
                        print "      Unexpected error:", sys.exc_info()
コード例 #31
0
ファイル: models.py プロジェクト: GeographicaGS/moocng
	def post_edit(self, post_id, id_user, course_slug, postText):
		postCollection = get_db().get_collection(self.col_post)

		if self._can_edit(id_user, course_slug, post_id):
			postCollection.update({"_id": ObjectId(post_id)}, {"$set": {"text": escape(postText)}})
			return True
		else:
			return False
コード例 #32
0
ファイル: statistics.py プロジェクト: tao12345666333/moocng
    def handle(self, *args, **options):
        all_courses_objs = Course.objects.only('id').all()
        all_courses_ids = [c.id for c in all_courses_objs]

        if options['all_courses']:
            courses = all_courses_objs
        elif not options['courses']:
            # FIXME this crashes, there are problems with the dates
            courses = Course.objects.only('id').filter(status='p').filter(
                # exclude courses that haven't started
                Q(start_date__is_null=True)
                | Q(start_date__is_null=False, start_date__lte=datetime.now))
            if not options['finished_courses']:
                # exclude finished courses
                courses = courses.filter(
                    Q(end_date__is_null=True)
                    | Q(end_date__is_null=False, end_date__gte=datetime.now))
        else:
            user_courses = options['courses'].split(',')
            courses = []
            for id_or_slug in user_courses:
                try:
                    if id_or_slug.isdigit():
                        c = Course.objects.only('id').get(id=id_or_slug)
                    else:
                        c = Course.objects.only('id').get(slug=id_or_slug)
                    courses.append(c)
                except Course.DoesNotExist:
                    print '"%s" does not exist' % id_or_slug
                    pass

        courses = [c.id for c in courses]
        blacklist = [cid for cid in all_courses_ids if cid not in courses]

        print 'Calculating stats for these courses (ids): %s' % ', '.join(
            [str(cid) for cid in courses])

        # Drop existing stats for selected courses
        db = get_db()
        stats_course = db.get_collection('stats_course')
        stats_unit = db.get_collection('stats_unit')
        stats_kq = db.get_collection('stats_kq')
        for cid in courses:
            stats_course.remove({'course_id': cid}, safe=True)
            stats_unit.remove({'course_id': cid}, safe=True)
            stats_kq.remove({'course_id': cid}, safe=True)

        # Callback to show some progress information
        def callback(step='', counter=0, total=0):
            step = max(1, int(total / 100))
            if counter % step == 0:
                if step == 'calculating':
                    print 'Processed %d of %d users' % (counter, total)
                elif step == 'storing':
                    print 'Saved %d of %d statistics entries' % (counter,
                                                                 total)

        calculate_all_stats(callback=callback, course_blacklist=blacklist)
コード例 #33
0
ファイル: statistics.py プロジェクト: Macro-Bin/moocng
    def handle(self, *args, **options):
        all_courses_objs = Course.objects.only('id').all()
        all_courses_ids = [c.id for c in all_courses_objs]

        if options['all_courses']:
            courses = all_courses_objs
        elif not options['courses']:
            # FIXME this crashes, there are problems with the dates
            courses = Course.objects.only('id').filter(status='p').filter(
                # exclude courses that haven't started
                Q(start_date__is_null=True) |
                Q(start_date__is_null=False, start_date__lte=datetime.now)
            )
            if not options['finished_courses']:
                # exclude finished courses
                courses = courses.filter(
                    Q(end_date__is_null=True) |
                    Q(end_date__is_null=False, end_date__gte=datetime.now)
                )
        else:
            user_courses = options['courses'].split(',')
            courses = []
            for id_or_slug in user_courses:
                try:
                    if id_or_slug.isdigit():
                        c = Course.objects.only('id').get(id=id_or_slug)
                    else:
                        c = Course.objects.only('id').get(slug=id_or_slug)
                    courses.append(c)
                except Course.DoesNotExist:
                    print '"%s" does not exist' % id_or_slug
                    pass

        courses = [c.id for c in courses]
        blacklist = [cid for cid in all_courses_ids if cid not in courses]

        print 'Calculating stats for these courses (ids): %s' % ', '.join([str(cid) for cid in courses])

        # Drop existing stats for selected courses
        db = get_db()
        stats_course = db.get_collection('stats_course')
        stats_unit = db.get_collection('stats_unit')
        stats_kq = db.get_collection('stats_kq')
        for cid in courses:
            stats_course.remove({'course_id': cid}, safe=True)
            stats_unit.remove({'course_id': cid}, safe=True)
            stats_kq.remove({'course_id': cid}, safe=True)

        # Callback to show some progress information
        def callback(step='', counter=0, total=0):
            step = max(1, int(total / 100))
            if counter % step == 0:
                if step == 'calculating':
                    print 'Processed %d of %d users' % (counter, total)
                elif step == 'storing':
                    print 'Saved %d of %d statistics entries' % (counter, total)

        calculate_all_stats(callback=callback, course_blacklist=blacklist)
コード例 #34
0
ファイル: models.py プロジェクト: ntwuxc/moocng
def course_stats(sender, instance, created, **kwargs):
    if created:
        stats_course = get_db().get_collection('stats_course')
        stats_course.insert({
            'course_id': instance.id,
            'started': 0,
            'completed': 0,
            'passed': 0,
        }, data=True)
コード例 #35
0
ファイル: models.py プロジェクト: GeographicaGS/moocng
	def post_delete(self, post_id, id_user, course_slug, avoidCascade=None):
		postCollection = get_db().get_collection(self.col_post)
		if self._can_edit(id_user, course_slug, post_id):
			if avoidCascade and len(postCollection.find({"_id": ObjectId(post_id)})[0]['children']) > 0:
				return False
			postCollection.update({"_id": ObjectId(post_id)}, {"$set": {"deleted": True}})
			return True
		else:
			return False
コード例 #36
0
ファイル: resources.py プロジェクト: NorthStar/moocng
 def dispatch(self, request_type, request, **kwargs):
     # We need the request to dehydrate some fields
     try:
         question_id = int(request.GET.get("question", None))
     except ValueError:
         raise BadRequest("question filter isn't a integer value")
     collection = get_db().get_collection("answers")
     self.answer = collection.find_one({"user_id": request.user.id, "question_id": question_id})
     return super(OptionResource, self).dispatch(request_type, request, **kwargs)
コード例 #37
0
def get_course_mark(course, user, db=None):
    data_course = {'user_id': user.pk, 'course_id': course.pk}
    db = db or get_db()
    marks_course = db.get_collection('marks_course')
    mark_course_item = marks_course.find_one(data_course)
    if mark_course_item:
        total_mark = mark_course_item['mark']
    else:
        total_mark = 0
    return (total_mark, get_units_info_from_course(course, user, db=db))
コード例 #38
0
ファイル: models.py プロジェクト: ntwuxc/moocng
    def kq_visited_by(self, user):
        db = get_db()

        activity = db.get_collection("activity")
        # Verify if user has watch the video from kq
        user_activity_exists = activity.find({
            "user_id": user.id,
            "kq_id": self.id,
        })

        return user_activity_exists.count() > 0
コード例 #39
0
ファイル: utils.py プロジェクト: ntwuxc/moocng
def insert_p2p_if_does_not_exists_or_raise(p2p_submission, submissions=None):
    if submissions is None:
        db = get_db()
        submissions = db.get_collection("peer_review_submissions")
    if submissions.find({
            'kq': p2p_submission['kq'],
            'author': p2p_submission['author']
    }).count() > 0:
        raise BadRequest(
            _('You have already sent a submission. Please reload the page'))
    return submissions.insert(p2p_submission)
コード例 #40
0
ファイル: utils.py プロジェクト: ntwuxc/moocng
def update_course_mark_by_user(course, user):
    db = mongodb.get_db()
    for unit in course.unit_set.scorables():
        for kq in unit.knowledgequantum_set.all():
            updated_kq, passed_kq_now = update_kq_mark(db, kq, user,
                                                       course.threshold)
            update_passed(db, 'stats_kq', passed_kq_now, {'kq_id': kq.pk})
        updated_unit, passed_unit_now = update_unit_mark(
            db, unit, user, course.threshold)
        update_passed(db, 'stats_unit', passed_unit_now, {'unit_id': unit.pk})
    updated_course, passed_course_now = update_course_mark(db, course, user)
    update_passed(db, 'stats_course', passed_course_now,
                  {'course_id': course.pk})
コード例 #41
0
 def forwards(self, orm):
     "Write your forwards methods here."
     from moocng.mongodb import get_db
     db = get_db()
     marks_course = db.get_collection('marks_course')
     marks_unit = db.get_collection('marks_unit')
     marks_kq = db.get_collection('marks_kq')
     marks_course.create_index([('course_id', pymongo.ASCENDING),
                                ('user_id', pymongo.ASCENDING)])
     marks_unit.create_index([('course_id', pymongo.ASCENDING),
                              ('user_id', pymongo.ASCENDING)])
     marks_kq.create_index([('unit_id', pymongo.ASCENDING),
                            ('user_id', pymongo.ASCENDING)])
コード例 #42
0
 def dispatch(self, request_type, request, **kwargs):
     # We need the request to dehydrate some fields
     try:
         question_id = int(request.GET.get("question", None))
     except ValueError:
         raise BadRequest("question filter isn't a integer value")
     collection = get_db().get_collection('answers')
     self.answer = collection.find_one({
         "user_id": request.user.id,
         "question_id": question_id
     })
     return super(OptionResource, self).dispatch(request_type, request,
                                                 **kwargs)
コード例 #43
0
ファイル: utils.py プロジェクト: tao12345666333/moocng
    def create_activity(self, user, kq):
        key = 'courses'
        course_id = str(kq.unit.course.id)
        activity_collection = get_db().get_collection('activity')
        user_data = activity_collection.find_one({'user': user.id}, safe=True)
        if user_data is None or not (key in user_data or course_id in user_data[key]):
            initial = {course_id: {'kqs': []}}
            user_data = {'user': user.id, key: initial}
            user_data['_id'] = activity_collection.insert(user_data)
            user_data[key][course_id]['kqs'] = [str(kq.id)]
        else:
            user_data[key][course_id]['kqs'].append(str(kq.id))

        activity_collection.update({'_id': user_data['_id']}, user_data)
コード例 #44
0
def calculate_question_mark(kq, question, user):
    db = get_db()
    answers = db.get_collection('answers')
    user_answer = answers.find_one({
        'user_id': user.id,
        'question_id': question.id
    })
    if user_answer:
        if user_answer and question.is_correct(user_answer):
            return (10.0, True)
        else:
            return (0.0, True)

    return (0.0, True)
コード例 #45
0
    def forwards(self, orm):
        kq_unit = {}

        for course in orm['courses.course'].objects.all():
            for unit in course.unit_set.all():
                for kq in unit.knowledgequantum_set.all():
                    kq_unit[str(kq.id)] = unit.id

        js_migration = """
var kq_unit = %s;

db.activity_tmp.drop();

db.activity.find().forEach(function (activity) {
    var internal_counter = 0, course;
    for (cp in activity.courses) {
        course = activity.courses[cp];
        internal_counter += course.kqs.length;
        course.kqs.forEach(function (kq) {
            db.activity_tmp.insert({
                user_id: parseInt(activity.user, 10),
                course_id: parseInt(cp, 10),
                kq_id: parseInt(kq, 10),
                unit_id: kq_unit[kq]
            });
        });
    }
});
        """ % simplejson.dumps(kq_unit)

        connector = get_db()
        db = connector.get_database()
        db.eval(Code(js_migration))

        db.activity.drop()
        try:
            db.activity_tmp.rename('activity')
        except OperationFailure:
            # if the activity collection was empty, then there is no new
            # collection to rename, but that is okay
            pass

        print "Activity collection migrated, old collection dropped. Creating indexes..."

        db.activity.create_index([("user_id", pymongo.ASCENDING),
                                  ("unit_id", pymongo.ASCENDING),
                                  ("kq_id", pymongo.ASCENDING)])
        db.activity.create_index([("kq_id", pymongo.ASCENDING)])
コード例 #46
0
ファイル: models.py プロジェクト: ntwuxc/moocng
    def is_completed(self, user, visited=None):
        db = get_db()

        if visited is None:
            visited = self.kq.kq_visited_by(user)
            if not visited:
                return False

        # Verify if user has answered the question
        answers = db.get_collection("answers")
        answer_exists = answers.find_one({
            "user_id": user.id,
            "question_id": self.id,
        })

        return not (answer_exists is None)
コード例 #47
0
ファイル: models.py プロジェクト: ntwuxc/moocng
def unit_stats(sender, instance, created, **kwargs):
    stats_unit = get_db().get_collection('stats_unit')
    if created:
        stats_unit.insert({
            'course_id': instance.course.id,
            'unit_id': instance.id,
            'started': 0,
            'completed': 0,
            'passed': 0,
        }, safe=True)
    else:
        stats_unit.update(
            {'unit_id': instance.id},
            {'$set': {'course_id': instance.course.id}},
            safe=True
        )
コード例 #48
0
def calculate_question_mark(kq, question, user):
    """
    Calculate if the user answer is the correct one, and punctuate accordingly.
    If the user did the task right the platform gives a 10, if not, a 0.

    .. versionadded:: 0.1
    """
    db = get_db()
    answers = db.get_collection('answers')
    user_answer = answers.find_one({
        'user_id': user.id,
        'question_id': question.id
    })
    if user_answer:
        if user_answer and question.is_correct(user_answer):
            return 10.0
    return 0.0
コード例 #49
0
ファイル: utils.py プロジェクト: NorthStar/moocng
def calculate_kq_mark(kq, user):
    # TODO Optimize per student
    from moocng.courses.models import Question
    from moocng.peerreview.models import PeerReviewAssignment
    from moocng.peerreview.utils import kq_get_peer_review_score
    try:
        db = get_db()
        question = Question.objects.filter(kq=kq)
        if question:
            answers = db.get_collection('answers')
            user_answer_list = answers.find_one({'user': user.id}, safe=True)
            if user_answer_list is not None:
                answer = user_answer_list.get('questions',
                                              {}).get(unicode(question[0].id))
                if answer and question[0].is_correct(answer):
                    return (10.0, True)
                else:
                    if kq.unit.deadline is not None and kq.unit.deadline > datetime.now(
                            kq.unit.deadline.tzinfo):
                        return (0.0, True)
        else:
            peer_review_assignment = PeerReviewAssignment.objects.filter(kq=kq)
            if peer_review_assignment:
                mark, use_in_total = kq_get_peer_review_score(
                    kq, user, peer_review_assignment[0])
                if mark is not None:
                    return (mark * 2.0, use_in_total
                            )  # * 2 due peer_review range is 1-5
                else:
                    return (None, False)
            else:
                activity = db.get_collection('activity')
                user_activity_list = activity.find_one({'user': user.id},
                                                       safe=True)
                if user_activity_list is not None:
                    visited_kqs = user_activity_list.get('courses', {}).get(
                        unicode(kq.unit.course.id), {}).get('kqs', [])
                    if unicode(kq.id) in visited_kqs:
                        return (10.0, True)
                    else:
                        if kq.unit.deadline is not None and kq.unit.deadline > datetime.now(
                                kq.unit.deadline.tzinfo):
                            return (0, True)
    except AttributeError:
        pass
    return (0, True)
コード例 #50
0
ファイル: tasks.py プロジェクト: ntwuxc/moocng
def on_activity_created_task(activity_created, unit_activity, course_activity):
    db = get_db()
    kq = KnowledgeQuantum.objects.get(id=activity_created['kq_id'])
    kq_type = kq.kq_type()
    up_kq, up_u, up_c, passed_kq, passed_unit, passed_course = update_mark(
        activity_created)
    # KQ
    data = {'viewed': 1}
    if kq_type == 'Video' or passed_kq:
        data['passed'] = 1
    stats_kq = db.get_collection('stats_kq')
    stats_kq.update({'kq_id': activity_created['kq_id']}, {'$inc': data},
                    safe=True)

    # UNIT
    data = {}
    if unit_activity == 1:  # First activity of the unit
        data['started'] = 1
    elif kq.unit.knowledgequantum_set.count() == unit_activity:
        data['completed'] = 1

    if passed_unit:
        data['passed'] = 1

    if data.keys():
        stats_unit = db.get_collection('stats_unit')
        stats_unit.update({'unit_id': kq.unit.id}, {'$inc': data}, safe=True)

    # COURSE
    course_kqs = KnowledgeQuantum.objects.filter(
        unit__course__id=activity_created['course_id']).count()
    data = {}
    if course_activity == 1:  # First activity of the course
        data['started'] = 1
    elif course_kqs == course_activity:
        data['completed'] = 1

    if passed_course:
        data['passed'] = 1

    if data.keys():
        stats_course = db.get_collection('stats_course')
        stats_course.update({'course_id': activity_created['course_id']},
                            {'$inc': data},
                            safe=True)
コード例 #51
0
ファイル: stats.py プロジェクト: NorthStar/moocng
def course_completed_started(course):
    activity = get_db().get_collection('activity')

    total_kqs = KnowledgeQuantum.objects.filter(unit__course=course).count()
    kqs_by_user = activity.group(condition={"course_id": course.id},
                                 key={"user_id": 1},
                                 initial={"kqs": 0},
                                 reduce=Code("""function (curr, result) {
            result.kqs += 1
        }"""))

    def is_completed(e):
        return e.get("kqs", 0) == total_kqs

    completed = len(filter(is_completed, kqs_by_user))
    started = len(kqs_by_user)

    return (completed, started)
コード例 #52
0
ファイル: stats.py プロジェクト: NorthStar/moocng
def unit_completed_started(unit):
    activity = get_db().get_collection('activity')

    total_kqs = unit.knowledgequantum_set.count()
    kqs_by_user = activity.group(condition={"unit_id": unit.id},
                                 key={"user_id": 1},
                                 initial={"kqs": 0},
                                 reduce=Code("""function (curr, result) {
            result.kqs += 1
        }"""))

    def is_completed(e):
        return e.get("kqs", 0) == total_kqs

    completed = len(filter(is_completed, kqs_by_user))
    started = len(kqs_by_user)

    return (completed, started)
コード例 #53
0
def on_activity_created(sender, user_id, mongo_object, **kwargs):
    api_task_logger.debug("activity created")

    data = mongo_object.to_dict()
    activity = get_db().get_collection('activity')
    unit_activity = activity.find({
        'user_id': data['user_id'],
        'unit_id': data['unit_id'],
    }).count()
    course_activity = activity.find({
        'user_id': data['user_id'],
        'course_id': data['course_id']
    }).count()

    on_activity_created_task.apply_async(
        args=[data, unit_activity, course_activity],
        queue='stats',
    )
コード例 #54
0
ファイル: tasks.py プロジェクト: ntwuxc/moocng
def update_mark(submitted):
    from moocng.courses.marks import calculate_kq_mark, calculate_unit_mark, calculate_course_mark
    updated_kq_mark = updated_unit_mark = updated_course_mark = False
    passed_kq = passed_unit = passed_course = False
    kq = KnowledgeQuantum.objects.get(pk=submitted['kq_id'])
    unit = kq.unit
    course = kq.unit.course
    user = User.objects.get(pk=submitted['user_id'])
    mark_kq, mark_normalized_kq = calculate_kq_mark(kq, user)

    db = get_db()

    # KQ
    updated_kq_mark, passed_kq = update_kq_mark(
        db,
        kq,
        user,
        course.threshold,
        new_mark_kq=mark_kq,
        new_mark_normalized_kq=mark_normalized_kq)

    # UNIT
    if not updated_kq_mark:
        return (updated_kq_mark, updated_unit_mark, updated_course_mark,
                passed_kq, passed_unit, passed_course)

    mark_unit, mark_normalized_unit = calculate_unit_mark(kq.unit, user)
    updated_unit_mark, passed_unit = update_unit_mark(
        db,
        unit,
        user,
        course.threshold,
        new_mark_unit=mark_unit,
        new_mark_normalized_unit=mark_normalized_unit)

    # COURSE
    if not updated_unit_mark:
        return (updated_kq_mark, updated_unit_mark, updated_course_mark,
                passed_kq, passed_unit, passed_course)
    mark_course, units_info = calculate_course_mark(unit.course, user)
    updated_course_mark, passed_course = update_course_mark(
        db, course, user, mark_course)
    return (updated_kq_mark, updated_unit_mark, updated_course_mark, passed_kq,
            passed_unit, passed_course)
コード例 #55
0
ファイル: utils.py プロジェクト: ntwuxc/moocng
def kq_get_peer_review_score(kq, author, pra=None):
    """ppr_collection is peer_review_reviews mongo collection

        Return a tuple with (score, scorable)
        * If this kq isn't peer_review type:
            return None
        * If there is no submission:
            return 0
        * If I haven't reviewed enough submissions of other students:
            return 0
        * If nobody reviewed my submission:
            return None
        * If I got enough reviews of my submission and I have reviewed enough
          reviews of other students' submissions:
            rerturn Average
    """

    if not pra:
        try:
            pra = kq.peerreviewassignment
        except PeerReviewAssignment.DoesNotExist:
            return None

    db = get_db()

    prs_collection = db.get_collection("peer_review_submissions")

    submission = prs_collection.find_one({"kq": kq.id, "author": author.id})

    if (not submission
            or submission.get("author_reviews", 0) < pra.minimum_reviewers):
        return 0
    elif submission["reviews"] == 0:
        return None

    ppr_collection = db.get_collection("peer_review_reviews")
    reviews = ppr_collection.find({"kq": kq.id, "author": author.id})
    reviews_count = reviews.count()
    sum_average = 0
    for review in reviews:
        sum_average += float(get_peer_review_review_score(review))

    return (sum_average /
            reviews_count) * 2  # * 2 due peer_review range is 1-5
コード例 #56
0
ファイル: utils.py プロジェクト: ntwuxc/moocng
def clone_activity_user_course(user,
                               copy_course,
                               original_course=None,
                               force_email=False):
    if not original_course:
        original_course = copy_course.created_from
        if not original_course:
            raise ValueError("This course needs a original course")
    try:
        course_student_relation = user.coursestudent_set.get(
            course=copy_course)
    except CourseStudent.DoesNotExist:
        return ([], [], [])

    file_name = get_trace_clone_file_name(original_course, copy_course)
    file_path = get_trace_clone_file_path(file_name)
    f = open(file_path)
    trace_ids = json.loads(f.read())
    f.close()
    if not copy_course.pk == trace_ids['Course'][str(original_course.pk)]:
        raise ValueError

    mongo_db = mongodb.get_db()

    new_act_docs = _clone_activity_user_course(mongo_db, trace_ids, user,
                                               copy_course, original_course)

    insert_answer_docs, update_answer_docs = _clone_answer_user_course(
        mongo_db, trace_ids, user, copy_course, original_course)

    if (new_act_docs or insert_answer_docs or update_answer_docs
            or course_student_relation.old_course_status != 'c'
            or force_email):
        if course_student_relation.old_course_status != 'c':
            course_student_relation.old_course_status = 'c'
            course_student_relation.save()
        if not settings.DEBUG:
            send_cloned_activity_email(original_course, copy_course, user)
        update_course_mark_by_user(copy_course, user)
    return (new_act_docs, insert_answer_docs, update_answer_docs)
コード例 #57
0
def pending_reviews(peer_review_assignment, user, course, user_submissions):
    db = get_db()
    peer_review_reviews = db.get_collection('peer_review_reviews')
    reviewed = peer_review_reviews.find({
        'reviewer': user.id,
        'kq': peer_review_assignment.kq.id,
    })
    peer_review_submissions = db.get_collection('peer_review_submissions')
    assigned = peer_review_submissions.find({
        'assigned_to': user.id,
        'kq': peer_review_assignment.kq.id,
    })
    pending = peer_review_assignment.minimum_reviewers - reviewed.count()
    has_sent_submission = peer_review_assignment.id in user_submissions
    return {
        'reviewed': reviewed,
        'assigned': assigned,
        'pending': pending,
        'has_sent_submission': has_sent_submission,
        'peer_review_assignment_id': peer_review_assignment.id,
        'course_slug': course.slug
    }
コード例 #58
0
ファイル: models.py プロジェクト: tao12345666333/moocng
    def is_completed(self, user, visited=None):

        db = get_db()

        if visited is None:
            visited = self.kq.kq_visited_by(user)
            if not visited:
                return False

        # Verify if user has sent a submission
        submissions = db.get_collection("peer_review_submissions")
        user_submission = submissions.find_one({
            "kq": self.kq.id,
            "author": user.id
        })

        if not user_submission:
            return False

        if user_submission.get("author_reviews", 0) < self.minimum_reviewers:
            return False

        return True
コード例 #59
0
ファイル: models.py プロジェクト: ntwuxc/moocng
def kq_stats(sender, instance, created, **kwargs):
    stats_kq = get_db().get_collection('stats_kq')
    if created:
        stats_kq.insert({
            'course_id': instance.unit.course.id,
            'unit_id': instance.unit.id,
            'kq_id': instance.id,
            'viewed': 0,
            'submitted': 0,
            'reviews': 0,
            'reviewers': 0,
            'passed': 0,
        }, safe=True)
        # It doesn't matter if it has all the fields because the teacheradmin
        # view only returns the proper fields depending on the kq type
    else:
        stats_kq.update(
            {'kq_id': instance.id},
            {'$set': {
                'course_id': instance.unit.course.id,
                'unit_id': instance.unit.id,
            }},
            safe=True
        )