Ejemplo n.º 1
0
    def process_solution(course_name, course_year):
        user = User(session['user'])

        try:
            course = Courses().find_one(name=course_name,
                                        year=course_year,
                                        only_active=False)
            problem = course.problem_db[request.form['prob-id']]
            lang = Languages.db()[request.form['lang-id']]
            solution = request.form['src']
            use_docker = request.form.get('use-docker', 'off') == 'on'

            test_result = crates.TestResult(
                user=user.id,
                problem=problem.id,
                lang=lang.id,
                course=course.id,
                docker=use_docker,
                solution=solution,
                action='solve',
            )
            # save to the db and redirect with _id
            insert_result = Mongo().save_result(test_result.peek())

            return redirect(
                url_for('view_result',
                        course_name=course.name,
                        course_year=course.year,
                        problem_id=problem.id,
                        _id=str(insert_result.inserted_id)))

        except:
            logger.exception('Could not parse data')
Ejemplo n.º 2
0
    def view_course(course_name, course_year):
        user = User(session['user'])
        course = Courses().find_one(name=course_name,
                                    year=course_year,
                                    only_active=False)
        problems: List[Problem] = sorted(list(
            course.problem_db.find(disabled=(None, False))),
                                         key=problem_cat_getter)

        languages = Languages.db().find(disabled=(None, False))

        if not user.is_admin():
            problems = [p for p in problems if p.is_visible()]

        cat_problems = OrderedDict()
        for cat, items in groupby(problems, key=problem_cat_getter):
            cat_problems[cat] = list(items)

        return render_template_ext(
            'view_course.njk',
            user=user,
            notifications=Mongo().load_notifications(user.id),
            course=course,
            languages=languages,
            has_categories=len(cat_problems) > 1,
            problems=problems,
            cat_problems=cat_problems,
            title=course.name,
            subtitle=course.year,
            breadcrumbs=Breadcrumbs.new(Link.CoursesBtn(), ),
            js_no_cache=['solution.js'])
Ejemplo n.º 3
0
def write_config(reference: pathlib = None):
    (Env.courses / _course_name / '2019' / 'config.yaml').write_text(
        _course_config.read_text())

    if reference:
        course = Courses()[request_base['course']]
        problem = course.problem_db[request_base['problem']]
        problem.reference.path.write_text(reference.read_text())
Ejemplo n.º 4
0
    def view_courses():
        user = User(session['user'])

        courses = list(Courses().find(only_active=not user.is_admin()))

        return render_template_ext('view_courses.njk',
                                   title='Course list',
                                   user=user,
                                   notifications=Mongo().load_notifications(
                                       user.id),
                                   courses=courses)
Ejemplo n.º 5
0
    def view_result(course_name, course_year, problem_id, _id=None):
        user = User(session['user'])

        if user.is_admin():
            return redirect(
                url_for('admin_problem',
                        course_name=course_name,
                        course_year=course_year,
                        problem_id=problem_id))

        course = Courses().find_one(name=course_name,
                                    year=course_year,
                                    only_active=False)
        problem = course.problem_db[problem_id]
        results = list()
        result = None
        breadcrumbs = [Link.CoursesBtn(), Link.CourseBtn(course)]

        # TODO check access
        if _id:
            document = Mongo().result_by_id(_id)
            if document:
                # add to previous solution if already executed
                if document.result:
                    results.append(document.peek())
                else:
                    result = document.peek()
                    breadcrumbs.append(Link.ProblemBtn(course, problem))

        if Env.use_database:
            for prev in Mongo().peek_last_n_results(20, user.id, course.id,
                                                    problem.id):
                # push only valid result
                if prev.get('result') and str(prev['_id']) != str(_id):
                    results.append(prev)

        if _id:
            for r in results:
                if str(r['_id']) == str(_id):
                    r['active'] = 'active'

        results = sorted(results, reverse=True, key=lambda x: x.get('attempt'))

        return render_template_ext(
            'results.njk',
            user=user,
            notifications=Mongo().read_notifications(user.id),
            results=results,
            result=result,
            requestReview=True,
            title='Problem %s' % problem.name,
            breadcrumbs=Breadcrumbs.new(*breadcrumbs),
        )
Ejemplo n.º 6
0
    def view_course(course_name, course_year):
        user = User(session['user'])
        course = Courses().find_one(name=course_name,
                                    year=course_year,
                                    only_active=False)
        problems = list(course.problem_db.find(disabled=(None, False)))
        languages = Languages.db().find(disabled=(None, False))

        return render_template_ext(
            'submit.njk',
            user=user,
            notifications=Mongo().read_notifications(user.id),
            course=course,
            languages=languages,
            problems=problems,
            title=course.name,
            subtitle=course.year,
            breadcrumbs=Breadcrumbs.new(Link.CoursesBtn(), ),
        )
Ejemplo n.º 7
0
    def admin_problem(course_name, course_year, problem_id):
        user = User(session['user'])
        course = Courses().find_one(name=course_name,
                                    year=course_year,
                                    only_active=False)
        problems_ids = ','.join([x.id for x in list(course.problem_db.find())])
        problem = course.problem_db[problem_id]
        languages = Languages.db().find(disabled=(None, False))

        return render_template_ext(
            'problem.njk',
            user=user,
            notifications=Mongo().read_notifications(user.id),
            course=course,
            languages=languages,
            problem=problem,
            problems_ids=problems_ids,
            title='Manage problem %s' % problem.name,
            breadcrumbs=Breadcrumbs.new(Link.CoursesBtn(),
                                        Link.CourseBtn(course)),
        )
Ejemplo n.º 8
0
 def ref_course(self):
     """
     :rtype: database.objects.Course
     """
     from database.objects import Courses
     return Courses()[self.course]
Ejemplo n.º 9
0
    def stats():
        data = request.json
        filters = {}

        def add_filter(n, v=None, l=None):
            r = data
            if n.find('.') != -1:
                r, n = data['filters'], n.split('.')[1]

            if r.get(n, None):
                val = l(r.get(n)) if l else r.get(n)
                if val is not SKIP:
                    filters[v or n] = val

        def dummy_object_id(period):
            if period == 'day':
                gen_time = datetime.datetime.today() - datetime.timedelta(
                    days=1)
            elif period == 'week':
                gen_time = datetime.datetime.today() - datetime.timedelta(
                    days=7)
            elif period == 'two weeks':
                gen_time = datetime.datetime.today() - datetime.timedelta(
                    days=14)
            elif period == 'month':
                gen_time = datetime.datetime.today() - datetime.timedelta(
                    days=31)
            else:
                gen_time = datetime.datetime.today() - datetime.timedelta(
                    days=365 * 5)
            return ObjectId.from_datetime(gen_time)

        # {'course': 'TST-2019', 'problem': 'problem-1', 'filters':
        #   {'daterange': 'week', 'status': 'all', 'limit-per-user': '******', 'has-review-flag': 'no', 'search': 'a'}}
        limit_per_user = data['filters']['limit-per-user']
        if limit_per_user == 'all':
            limit_per_user = 1000
        else:
            limit_per_user = int(limit_per_user)

        has_review_flag = data['filters']['has-review-flag']
        if has_review_flag == 'yes':
            filters['review_request'] = {'$ne': None}
        if has_review_flag == 'no':
            filters['review_request'] = {'$exists': False}

        sort_by_inner = data['filters']['sort-by-inner']
        sort_by_outer = data['filters']['sort-by-outer']
        search = str(data['filters']['search']).strip()

        if search:
            filters['user'] = {'$regex': f".*{search}.*"}

        add_filter('course')
        add_filter('filters.problem', 'problem', skip_if_all)
        # add_filter('filters.course', 'course', skip_if_all)

        add_filter('filters.status', 'result.status', skip_if_all)
        add_filter('filters.daterange', '_id',
                   lambda x: {'$gte': dummy_object_id(x)})
        base_properties = {x: 1 for x in Mongo().base_properties}

        pipeline = [
            {
                '$match': filters
            },
            {
                '$project': {
                    'review': 1,
                    **base_properties
                }
            },
            {
                '$sort': {
                    sort_by_inner: -1
                }
            },
            {
                '$group': {
                    '_id': '$user',
                    'results': {
                        '$push': '$$ROOT'
                    }  # $$ROOT
                }
            },
        ]
        # print(pipeline, limit_per_user)
        items = list(Mongo().data.aggregate(pipeline))
        try:
            course = Courses()[data['course']]
        except:
            course = None

        if course:
            for key in data['filters'].keys():
                if key.startswith('tag-'):
                    tag = key[4:]
                    value = data['filters'][key]
                    if value == 'all':
                        continue

                    items = [
                        x for x in items
                        if course.student_has_tag(x['_id'], tag, value)
                    ]

        # tags = .get('tag-group', None)

        def add_fields(x):
            x['firstname'] = str(x['_id']).split('.')[0]
            x['lastname'] = str(x['_id']).split('.')[-1]
            return x

        items = map(add_fields, items)
        items = sorted(items, key=lambda x: x[sort_by_outer])

        result = list()
        for item in items:
            item_copy = deepcopy(item)
            item_copy['results'] = item_copy['results'][0:limit_per_user]
            for attempt in item_copy['results']:
                attempt['time'] = datetime.datetime.timestamp(
                    attempt['_id'].generation_time)
            # item_copy['results'] = sorted(item_copy['results'], key=lambda x: x['time'], reverse=True)

            if 'results' in item_copy:
                item_copy['results'] = [
                    r for r in item_copy['results'] if 'result' in r
                ]
                result.append(item_copy)

        return flask.json.dumps(result)
Ejemplo n.º 10
0
    def view_result(course_name, course_year, problem_id, _id=None):
        user = User(session['user'])

        if user.is_admin():
            return redirect(
                url_for('admin_problem',
                        course_name=course_name,
                        course_year=course_year,
                        problem_id=problem_id))

        course = Courses().find_one(name=course_name,
                                    year=course_year,
                                    only_active=False)
        problem = course.problem_db[problem_id]
        results = list()
        result = None
        breadcrumbs = [Link.CoursesBtn(), Link.CourseBtn(course)]

        # TODO check access
        if _id:
            document = Mongo().result_by_id(_id)
            if document:
                # add to previous solution if already executed
                if document.result:
                    results.append(document)
                else:
                    result = document
                    breadcrumbs.append(Link.ProblemBtn(course, problem))

        if Env.use_database:
            for prev in Mongo().peek_last_n_results(10, user.id, course.id,
                                                    problem.id):
                # push only valid result
                if prev.result and str(prev._id) != str(_id):
                    results.append(prev)

        if _id:
            for r in results:
                if str(r._id) == str(_id):
                    r.active = 'active'

        def get_attempt(obj):
            try:
                return int(obj.attempt)
            except:
                return 0

        results = sorted(results, reverse=True, key=get_attempt)

        return render_template_ext(
            'view_result.njk',
            user=user,
            notifications=Mongo().load_notifications(user.id),
            results=results,
            result=result,
            requestReview=True,
            title='Problem %s' % problem.name,
            breadcrumbs=Breadcrumbs.new(*breadcrumbs),
            js=[
                '//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/highlight.min.js',
                '/static/js/lib/highlightjs-line-numbers.js'
            ],
            js_no_cache=['sockets.js', 'process.js'])