Пример #1
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'])
Пример #2
0
def insert_test_values():
    from database import Session
    from database.objects import User, Address, BlogPost, Keyword
    from random import randint

    letters = "abcdefghijklmnopqrstuvwxyz"

    s = Session()

    keyword = Keyword("firstpost")

    for n in range(100):
        name = ""
        for l in range(randint(4, 10)):
            letter = letters[randint(0, len(letters) - 1)]
            name += letter
        user = User(name=name, fullname=name, password="******")
        user.addresses = [
            Address(email_address=("*****@*****.**" % name)),
            Address(email_address=("*****@*****.**" % name)),
        ]
        post = BlogPost(("%ss Blog Post" % name), "This is a test", user)
        post.keywords.append(Keyword(name))
        post.keywords.append(keyword)
        s.add(post)

    s.commit()
    s.close()
Пример #3
0
    def decorated_function(*args, **kwargs):
        from database.objects import User
        try:
            user = User(session['user'])
            if not user.is_admin():
                raise Exception('Access denied')
        except:
            return redirect(Env.url_login)

        return f(*args, **kwargs)
Пример #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)
Пример #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),
        )
Пример #6
0
    def login(data):
        crypto = SimpleCrypto(Env.secret_key())
        json_data = crypto.decrypt_json(data)
        user = User.from_json(json_data)

        try:
            registered = User.db()[user.id]
            if registered:
                user.role = registered.role
        except: pass

        session['user'] = user.peek()

        return redirect('courses')
Пример #7
0
    def get_db_result(_id):
        user = User(session['user'])
        result = Mongo().result_by_id(_id)
        output_dir = result.output_dir
        review = result.review

        if output_dir:
            for case in result.results:
                try:
                    case_config = result.ref_problem[case.id]
                    if case_config:
                        case.attachments = case_config.get_attachments(
                            user_dir=Env.root.joinpath(output_dir))
                except AttributeError:
                    logger.exception('attachments')
                    pass
        if review:
            for line, comments in review.items():
                for i, c in enumerate(comments):
                    comments[i]['text'] = markdown.markdown(c['text'])

        mark_as_read = Mongo().mark_as_read(to=user.id,
                                            _id=_id,
                                            event='new-comment')
        logger.info('mark-as-read: {}', mark_as_read)

        return flask.json.dumps(result)
Пример #8
0
    def read_notifications():
        user = User(session['user'])
        data = request.json

        return flask.json.dumps(
            dict(notifications=Mongo().read_notifications(user.id,
                                                          n_id=data['_id'])))
Пример #9
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')
Пример #10
0
    def perma_result(_id):
        user = User(session['user'])
        document = Mongo().result_by_id(_id)
        course = document.ref_course
        problem = document.ref_problem
        breadcrumbs = [
            Link.CoursesBtn(),
            Link.CourseBtn(course),
            Link.ProblemBtn(course, problem)
        ]

        return render_template_ext(
            'view_result.njk',
            user=user,
            notifications=Mongo().load_notifications(user.id),
            results=[document],
            result=None,
            requestReview=False,
            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'])
Пример #11
0
    def request_review():
        user = User(session['user'])
        data = request.json
        _id = data['_id']
        document = Mongo().result_by_id(_id)
        from_user = document.user or user.id

        # request_dt = document.review_request  # type: datetime
        # if request_dt:
        #     return flask.json.dumps(
        #         dict(result='warning', message=f'Request was already sent on {request_dt:%Y-%m-%d %H:%M:%S}')
        #     )

        # notify all teachers
        reviewers = list()
        for reviewer_obj in document.ref_course.teachers:
            if type(reviewer_obj) is dict:
                reviewer = str(reviewer_obj.get('id', reviewer_obj))
            else:
                reviewer = reviewer_obj

            event_document = {
                'from':
                from_user,
                'to':
                reviewer,
                'course':
                document.course,
                'problem':
                document.problem,
                'document':
                _id,
                'event':
                'codereview',
                'title':
                f'Code review requested by {from_user}',
                'description':
                f'Student {from_user} has requested code review for the problem {document.ref_problem.id}'
            }

            if Mongo().add_notification(event_document):
                logger.info(f'add-notification: {event_document}')
                reviewers.append(reviewer)
            else:
                logger.warning(
                    f'notification already exists: {event_document}')

        Mongo().update_fields(_id, review_request=datetime.datetime.now())

        if reviewers:
            return flask.json.dumps(dict(result='ok', reviewers=reviewers))
        else:
            return flask.json.dumps(
                dict(result='warning', message='Request was already sent'))
Пример #12
0
def _process_solution_by_id(_id, rerun=False):
    document = Mongo().result_by_id(_id)

    if document.result is None or rerun:
        _process_solution(
            User(dict(id=document.user)),
            document.action,
            not document.docker,
            document.problem,
            document.course,
            document.lang,
            document.solution,
            document._id
        )
Пример #13
0
 def student_process_solution(data):
     print(data)
     user = User(session['user'])
     try:
         document = Mongo().result_by_id(data['_id'])
         _process_solution(
             user=user,
             action=document.action,
             skip_docker=not document.docker,
             problem_id=document.problem,
             course_id=document.course,
             lang_id=document.lang,
             src=document.solution,
             _id=data['_id'],
         )
     except:
         logger.exception('Error while processing solution')
Пример #14
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(), ),
        )
Пример #15
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)),
        )
Пример #16
0
    def perma_result(_id):
        user = User(session['user'])
        document = Mongo().result_by_id(_id)
        course = document.ref_course
        problem = document.ref_problem
        breadcrumbs = [
            Link.CoursesBtn(),
            Link.CourseBtn(course),
            Link.ProblemBtn(course, problem)
        ]

        return render_template_ext(
            'results.njk',
            user=user,
            notifications=Mongo().read_notifications(user.id),
            results=[document],
            result=None,
            requestReview=False,
            title='Problem %s' % problem.name,
            breadcrumbs=Breadcrumbs.new(*breadcrumbs),
        )
Пример #17
0
]

root = pathlib.Path(__file__).resolve()
files = root.parent.parent / 'files'

_course_name = 'course-template'
_course_config = files / 'TST.config.yaml'
_solution = dict(
    solution_correct=files / 'problem-1-correct.py',
    solution_wrong=files / 'problem-1-wrong.py',
    solution_timeout=files / 'problem-1-timeout.py',
    solution_fatal=files / 'problem-1-fatal.py',
)

user_root = User(dict(
    id='root',
    role='test',
))

request_base = dict(
    user=user_root,
    lang='PY-367',
    course='TST-2019',
    problem='problem-1',
)

solve_request_base = dict(type=ProcessRequestType.SOLVE, **request_base)
generate_input_request_base = dict(type=ProcessRequestType.GENERATE_INPUT,
                                   **request_base)
generate_output_request_base = dict(type=ProcessRequestType.GENERATE_OUTPUT,
                                    **request_base)
Пример #18
0
 def backdoor_login(role, id=None):
     session['user'] = User(dict(id=id, role=role, affi='debug'))
     return redirect(url_for('view_courses'))
Пример #19
0
def create_user_if_not_exist(session, user):
    ex = session.query(exists().where(User.name == user)).scalar()
    if not ex:
        new_user = User(name=user, password='')
        session.add(new_user)
        session.commit()
Пример #20
0
                                                  config.db_password)
print(connection_string)
engine = create_engine(connection_string, echo=True)
DBObjectBase.metadata.create_all(engine)
Session = sessionmaker(bind=engine)

session = Session()

for replay in glob.glob(os.path.join('replays', '*.gz')):
    base = os.path.basename(replay)
    uuid = base.split('_')[-1].split('.')[0]
    ip = base.split('_')[0]
    user = -1
    print(uuid, ip, user)
    if not session.query(exists().where(User.id == -1)).scalar():
        u = User(id=-1, name='Undefined', password='')
        session.add(u)
        session.commit()

    if not session.query(exists().where(Model.model_hash == '0')).scalar():
        u = Model(model_hash='0')
        session.add(u)
        session.commit()
    if not session.query(exists().where(Replay.uuid == uuid)).scalar():
        r = Replay(uuid=uuid,
                   ip=ip,
                   user=user,
                   model_hash='0',
                   num_team0=1,
                   num_players=1,
                   is_eval=False)
Пример #21
0
def student_submit_solution(data):
    print(data)
    user = User(session['user'])

    try:
        type = str(data['type'])
        action = ProcessRequestType(type)
        skip_docker = not data.get('docker', True)
    except:
        Emittor.error('Unsupported action', [
            'Given action is not supported:',
            '    %s' % data['type'], '', 'Please contact [email protected]',
            'if you think this is a mistake.'
        ])
        return

    if not user.is_admin() and (skip_docker or action
                                in (ProcessRequestType.GENERATE_INPUT,
                                    ProcessRequestType.GENERATE_OUTPUT)):
        Emittor.error('Operation not permitted', [
            'You do not have sufficient privileges to perform action:',
            '    %s (skip docker: %s)' %
            (action, skip_docker), '', 'Please contact [email protected]',
            'if you want to gain the privileges.'
        ])
        return

    request = processing.request.ProcessRequest(
        user=user,
        lang=data['lang'],
        problem=data['prob'],
        course=data['course'],
        solution=data['src'],
        type=action,
        docker=False if (skip_docker and user.is_admin()) else True,
    )

    mongo.save_log(request.get_log_dict())

    # ignore problems which are past due
    if request.problem.time_left < 0:
        return

    Emittor.register_events(request)
    Emittor.queue_status(queue_status())

    time.sleep(0.1)
    queue.append(request)
    Emittor.queue_push(request)

    time.sleep(0.1)

    # put a barrier here so only certain amount fo users can process code at once
    # while other will see queue list
    with thread_lock:
        try:
            request.process()
        except ConfigurationException as e:
            if user.is_admin():
                logger.exception('[visible to admin only] invalid yaml config')
                Emittor.exception(e)
        except Exception as e:
            logger.exception('process error:')
            Emittor.exception(e)
        finally:
            mongo.save_result(request.get_result_dict())
            request.save_result()
            request.destroy()

    queue.remove(request)
    Emittor.queue_pop(request)
Пример #22
0
    def add_comment():
        data = request.json
        user = User(session['user'])
        # course = Courses()[data['course']]
        # problem = course.problem_db[data['problem']]
        # attempt = data['attempt']

        _id = data['_id']
        document = Mongo().result_by_id(_id)
        review = document.review or dict()
        now = time.time()

        from_user = user.id
        author_user = document.user

        for comment in data['comments']:
            line, text = str(comment['line']), comment['comment']
            review_line = review[line] if line in review else list()
            review_line.append(dict(
                user=user.id,
                time=now,
                text=text,
            ))
            review[line] = review_line
        recipients = {from_user, author_user}
        for cmts in review.values():
            for cmt in cmts:
                recipients.add(cmt['user'])

        for recipient in recipients:
            if recipient == from_user:
                logger.info('Not creating notification for self')
            else:
                event_document = {
                    'from':
                    from_user,
                    'to':
                    recipient,
                    'course':
                    document.course,
                    'problem':
                    document.problem,
                    'document':
                    _id,
                    'event':
                    'new-comment',
                    'title':
                    f'New comment from {from_user}',
                    'description':
                    f'{document.ref_problem.id} User {from_user} commented your code in problem '
                }

                if Mongo().add_notification(event_document):
                    logger.info('add-notification: {}', event_document)
                else:
                    logger.warning('notification already exists: {}',
                                   event_document)

        mark_as_read = Mongo().mark_as_read(_id=_id,
                                            event='codereview',
                                            to=None)
        logger.info('mark-as-read: {}', mark_as_read)

        update_one = Mongo().update_fields(_id, review=review)
        logger.info('document-updated: {}', update_one)

        return flask.json.dumps(dict(result='ok'))
Пример #23
0
 def load_notifications():
     user = User(session['user'])
     return flask.json.dumps(
         dict(notifications=Mongo().load_notifications(user.id).peek(), ))
Пример #24
0
 def admin_switch_role(role, id=None):
     user = User(session['user'])
     session['user'] = User(dict(id=id or user.id, role=role, affi='debug'))
     return redirect('courses')
Пример #25
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'])