def put(self, run_id: int): """ View for updating run """ data = request.get_json(force=True, silent=False) run = db.session.query(Run).get(run_id) if run is None: raise NotFound(f'Run with id #{run_id} is not found') only_fields = ['ejudge_status', 'ejudge_test_num', 'ejudge_score'] load_run_schema = RunSchema(only=only_fields, context={'instance': run}) _, errors = load_run_schema.load(data) if errors: raise BadRequest(errors) invalidate_monitor_cache_by_run(run) # Avoid excess DB queries excludes = ['user', 'problem'] dump_run_schema = RunSchema(exclude=excludes) data, _ = dump_run_schema.dump(run) db.session.add(run) db.session.commit() return jsonify(data)
def get(self, run_id: int): args = parser.parse(self.get_args, request) is_admin = args.get('is_admin') user_id = args.get('user_id') run_q = db.session.query(Run) if not is_admin: run_q = run_q.filter(Run.user_id == user_id) run = run_q.filter(Run.id == run_id).one_or_none() if run is None: raise NotFound(f'Run with id #{run_id} is not found') language_id = run.ejudge_language_id source = run.source or b'' for encoding in POSSIBLE_SOURCE_ENCODINGS: try: source = source.decode(encoding) break except UnicodeDecodeError: pass return jsonify({'source': source, 'language_id': language_id})
def post(self, run_id: int): """ View for rejudge run""" run = db.session.query(Run).get(run_id) if run is None: raise NotFound(f'Run with id #{run_id} is not found') # If ejudge_url is None submission failed by error inside workers # And we shouldn't really rejudge the solution if run.ejudge_url is None: run.ejudge_url = current_app.config['EJUDGE_NEW_CLIENT_URL'] db.session.add(run) else: rejudge = Rejudge(run_id=run.id, ejudge_contest_id=run.ejudge_contest_id, ejudge_url=run.ejudge_url or 'rmatics_failed_submission') db.session.add(rejudge) db.session.flush([rejudge]) run.move_protocol_to_rejudge_collection(rejudge.id) queue_submit(run.id, run.ejudge_url) run.ejudge_status = 377 run.ejudge_test_num = None run.ejudge_score = None db.session.add(run) db.session.commit() return jsonify({})
def get(self, run_id: int): args = parser.parse(self.get_args, request) is_admin = args.get('is_admin') user_id = args.get('user_id') # if user_id == 399362 and not is_admin: # import random as rdm # return jsonify({'source': rdm.choice(['Нет', 'Отстань', 'Сори', 'Кончились', 'Попробуйте в другой раз', 'Ваш запрос очень важен для нас, оставайтесь на линии']), 'language_id': 2}) run_q = db.session.query(Run) if not is_admin: run_q = run_q.filter(Run.user_id == user_id) run = run_q.filter(Run.id == run_id).one_or_none() if run is None: raise NotFound(f'Run with id #{run_id} is not found') language_id = run.ejudge_language_id source = run.source or b'' for encoding in POSSIBLE_SOURCE_ENCODINGS: try: source = source.decode(encoding) break except UnicodeDecodeError: pass return jsonify({'source': source, 'language_id': language_id})
def post(self, problem_id: int): args = parser.parse(self.post_args) language_id = args['lang_id'] statement_id = args.get('statement_id') user_id = args.get('user_id') file = parser.parse_files(request, 'file', 'file') # Здесь НЕЛЬЗЯ использовать .get(problem_id), см EjudgeProblem.__doc__ problem = db.session.query(EjudgeProblem) \ .filter_by(id=problem_id) \ .one_or_none() if not problem: raise NotFound('Problem with this id is not found') try: text = self.check_file_restriction(file) except ValueError as e: raise BadRequest(e.args[0]) source_hash = Run.generate_source_hash(text) duplicate = db.session.query(Run).filter(Run.user_id == user_id) \ .filter(Run.problem_id == problem_id) \ .order_by(Run.id.desc()).first() if duplicate is not None and duplicate.source_hash == source_hash: raise BadRequest('Source file is duplicate of your previous submission') # TODO: разобраться, есть ли там constraint на statement_id run = Run( user_id=user_id, problem_id=problem_id, statement_id=statement_id, ejudge_contest_id=problem.ejudge_contest_id, ejudge_language_id=language_id, ejudge_status=377, # In queue source_hash=source_hash, ) db.session.add(run) db.session.flush() run.update_source(text) run_id = run.id ejudge_url = current_app.config['EJUDGE_NEW_CLIENT_URL'] # Коммит должен быть до отправки в очередь иначе это гонка db.session.commit() queue_submit(run_id, ejudge_url) return jsonify({ 'run_id': run_id })
def get(self, problem_id: int): problem = db.session.query(EjudgeProblem).get(problem_id) if not problem: raise NotFound('Problem with this id is not found') if not problem.sample_tests: schema = ProblemSchema(exclude=['sample_tests_json']) else: schema = ProblemSchema() data = schema.dump(problem) return jsonify(data.data)
def post(self): data = request.get_json(force=True) ejudge_run_id = data['run_id'] ejudge_contest_id = data['contest_id'] mongo_protocol_id = data.get('mongo_protocol_id', None) run = db.session.query(Run) \ .filter_by(ejudge_run_id=ejudge_run_id, ejudge_contest_id=ejudge_contest_id) \ .one_or_none() if run is None: msg = f'Cannot find Run with \ ejudge_contest_id={ejudge_contest_id}, \ ejudge_run_id={ejudge_run_id}' raise BadRequest(msg) run_schema = FromEjudgeRunSchema(context={'instance': run}) received_run, errors = run_schema.load(data) if errors: raise BadRequest(errors) if mongo_protocol_id: # If it is we should invalidate cache invalidate_monitor_cache_by_run(run) current_app.logger.debug('Cache invalidated') try: result = mongo.db.protocol.update_one( {'_id': ObjectId(mongo_protocol_id)}, {'$set': { 'run_id': received_run.id }}) if not result.modified_count: raise BadRequest( f'Cannot find protocol by _id {mongo_protocol_id}') except DuplicateKeyError: current_app.logger.exception('Found duplicate key for run_id') except PyMongoError: current_app.logger.exception('Looks like mongo is shutdown') raise InternalServerError(f'Looks like mongo is shutdown') db.session.add(received_run) db.session.commit() return jsonify({}, 200)
def get(self): args = parser.parse(contest_based_get_args, request) course_module_ids = args['contest_id'] group_id = args['group_id'] time_before = args['time_before'] time_after = args['time_after'] contest_ids = [] for cm_id in course_module_ids: monitor_group_id, statement_ids = self._get_contests(cm_id) contest_ids += statement_ids group_id = group_id or monitor_group_id if group_id: users = db.session.query(SimpleUser)\ .join(UserGroup, UserGroup.user_id == SimpleUser.id)\ .filter(UserGroup.group_id == group_id) user_ids = [user.id for user in users] else: user_ids = None contest_problems = OrderedDict() for contest_id in contest_ids: contest_problems[contest_id] = get_problems_by_statement_id( contest_id) contest_problems_runs = [] for contest_id, problems in contest_problems.items(): for problem in problems: runs = get_runs(problem_id=problem.id, user_ids=user_ids, time_before=time_before, time_after=time_after) monitor_data = ContestBasedMonitorData(contest_id, problem, runs) contest_problems_runs.append(monitor_data) schema = ContestBasedMonitorSchema(many=True) response = schema.dump(contest_problems_runs) # We have to commit session because we may created cache_meta db.session.commit() return jsonify(response.data)
def get(self, run_id: int): args = parser.parse(self.get_args, request) is_admin = args.get('is_admin') user_id = args.get('user_id') run_q = db.session.query(Run) if not is_admin: run_q = run_q.filter(Run.user_id == user_id) run = run_q.filter(Run.id == run_id).one_or_none() if run is None: raise NotFound(f'Run with id #{run_id} is not found') protocol = run.protocol if not protocol: raise NotFound(f'Protocol for run_id: {run_id} not found') return jsonify(protocol)
def _process(self, args, user_ids): course_module_ids = args['contest_id'] group_id = args['group_id'] time_before = args['time_before'] time_after = args['time_after'] # Context arguments context_source = args.get('context_source') show_hidden = args.get('show_hidden') contest_ids = [] for cm_id in course_module_ids: monitor_group_id, statement_ids = self._get_contests(cm_id) contest_ids += statement_ids group_id = group_id or monitor_group_id contest_problems = OrderedDict() for contest_id in contest_ids: contest_problems[contest_id] = get_problems_by_statement_id( contest_id) contest_problems_runs = [] for contest_id, problems in contest_problems.items(): for problem in problems: runs = get_runs(problem_id=problem.id, user_ids=user_ids, time_before=time_before, time_after=time_after, context_source=context_source, show_hidden=show_hidden) monitor_data = ContestBasedMonitorData(contest_id, problem, runs) contest_problems_runs.append(monitor_data) schema = ContestBasedMonitorSchema(many=True) response = schema.dump(contest_problems_runs) # We have to commit session because we may created cache_meta db.session.commit() return jsonify(response.data)
def get(self): # TODO: Приделать контекст посылки (NFRMTCS-192) args = parser.parse(problem_based_get_args, request) user_ids = args['user_id'] problem_ids = args['problem_id'] time_before = args['time_before'] time_after = args['time_after'] problem_runs = [] for problem_id in problem_ids: runs = get_runs(problem_id=problem_id, user_ids=user_ids, time_before=time_before, time_after=time_after) problem_runs.append(ProblemBasedMonitorData(problem_id, runs)) schema = ProblemBasedMonitorSchema(many=True) problem_runs = schema.dump(problem_runs) # We have to commit session because we may created cache_meta db.session.commit() return jsonify(problem_runs.data)
def get(self): args = parser.parse(problem_based_get_args, request) user_ids = args['user_id'] if not user_ids: user_ids = args['uid'] problem_ids = args['problem_id'] if not problem_ids: problem_ids = args['pid'] time_before = args['time_before'] time_after = args['time_after'] # Context arguments context_id = args.get('context_id') context_source = args.get('context_source') show_hidden = args.get('show_hidden') problem_runs = [] for problem_id in problem_ids: runs = get_runs( problem_id=problem_id, user_ids=user_ids, time_before=time_before, time_after=time_after, context_id=context_id, context_source=context_source, show_hidden=show_hidden, ) problem_runs.append(ProblemBasedMonitorData(problem_id, runs)) schema = ProblemBasedMonitorSchema(many=True) problem_runs = schema.dump(problem_runs) # We have to commit session because we may created cache_meta db.session.commit() return jsonify(problem_runs.data)
def post(self, problem_id: int): args = parser.parse(self.post_args) language_id = args['lang_id'] statement_id = args.get('statement_id') user_id = args.get('user_id') file = parser.parse_files(request, 'file', 'file') # If context parameters are unavialable, # consider it as Moodle submission and set defaults context_id = args.get('context_id') context_source = args.get('context_source', DEFAULT_MOODLE_CONTEXT_SOURCE) is_visible = args.get('is_visible', True) # Здесь НЕЛЬЗЯ использовать .get(problem_id), см EjudgeProblem.__doc__ problem = db.session.query(EjudgeProblem) \ .filter_by(id=problem_id) \ .one_or_none() if not problem: raise NotFound('Problem with this id is not found') if int(user_id) <= 0: raise BadRequest('Wrong user status') try: limit = 64 if problem.output_only: limit = 1024 * 16 text = self.check_file_restriction(file, limit) except ValueError as e: raise BadRequest(e.args[0]) source_hash = Run.generate_source_hash(text) duplicate: Run = db.session.query(Run).filter(Run.user_id == user_id) \ .filter(Run.problem_id == problem_id) \ .order_by(Run.id.desc()).first() if duplicate is not None and \ duplicate.source_hash == source_hash and \ duplicate.ejudge_language_id == language_id: raise BadRequest( 'Source file is duplicate of your previous submission') # There is not constraint on statement_id run = Run( user_id=user_id, problem_id=problem_id, statement_id=statement_id, ejudge_contest_id=problem.ejudge_contest_id, ejudge_language_id=language_id, ejudge_status=377, # In queue source_hash=source_hash, # Context related properties context_source=context_source, is_visible=is_visible, ) # If it's context aware submission, # overwrite statement_id with context if context_id: run.statement_id = context_id db.session.add(run) db.session.flush() run.update_source(text) run_id = run.id ejudge_url = current_app.config['EJUDGE_NEW_CLIENT_URL'] # Коммит должен быть до отправки в очередь иначе это гонка db.session.commit() queue_submit(run_id, ejudge_url) return jsonify({'run_id': run_id})