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')
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'])
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())
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)
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), )
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(), ), )
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)), )
def ref_course(self): """ :rtype: database.objects.Course """ from database.objects import Courses return Courses()[self.course]
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)
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'])