def challenge_by_name(challenge_name): """ Page to display a challenge given a problem name. """ challenge = mongodb.challenges.find_one({'name': challenge_name}) if not challenge or ( not is_active_user_in('Dev') and challenge['dev_only'] ): abort(404) submissions = mongodb.submissions.find({ 'cid': challenge['cid'] }).sort([ ('rating', -1) ]).limit(10) challenge_solutions = [] i = 0 for submission in submissions: i += 1 # TODO: Batch request user_from_submission = mongodb.users.find_one({ 'uid': submission['uid'] }) if not user_from_submission: raise Exception("Could not find user " + submission['uid'] + " in the database") submission['sequence'] = i submission['username'] = user_from_submission['username'] submission['RD'] = int(round(submission['RD'])) challenge_solutions.append(submission) matches = latest_matches( cid = challenge['cid'] ) return render_template('challenge.html', challenge = challenge, challenge_solutions = challenge_solutions, matches = matches, custom_title = challenge_name)
def challenge(): """ Page to display a challenge given an id. """ challenge_id = request.args.get('cid') if not challenge_id: abort(404) challenge = mongodb.challenges.find_one({'cid': challenge_id}) if challenge and ( is_active_user_in('Dev') or not challenge['dev_only'] ): return render_template('challenge.html', challenge=challenge) else: abort(404)
def submitsolution(challenge_name): """ Allows a user to submit/update (override) a solution to an existing challenge. """ challenge = mongodb.challenges.find_one({'name': challenge_name}) if not challenge or ( not is_active_user_in('Dev') and challenge['dev_only'] ): abort(404) if request.method == 'GET': return render_template('submitsolution.html', challenge = challenge) if 'language' not in request.form: return render_template('submit.solution.html', challenge = challenge, error = "Please select a language"), 400 language = request.form['language'] if language not in ACCEPTED_LANGUAGES.keys(): return render_template('submitsolution.html', challenge = challenge, error = "Invalid language"), 403 file = request.files['sourcefile'] if not file: return render_template('submitsolution.html', challenge = challenge, error = "Please select a Source File"), 400 # Source/Solution/Submission (you choose!) Instance ID siid = str(uuid4()) # Upload the source file to the 'mjollnir-solutions' S3 bucket using the siid as the key upload_solution(siid, language, file) # Update/Create a database entry for this submission query_existing_solution = { 'uid': user.custom_data['uid'], 'cid': challenge['cid'] } existing_solution = mongodb.submissions.find_one(query_existing_solution) if existing_solution: # For an existing solution, we have to set the 'build_' attributes and notify # the compiler service. The service is responsible for updating the database entries # when it finishes compiling. update_document = { '$set': { 'build_siid': siid, 'build_status': "Waiting", 'build_description': "" } } mongodb.submissions.update(query_existing_solution, update_document) document = existing_solution else: # For new solutions, we just add the document blueprint document = { 'siid': '', 'build_siid': siid, 'build_status': "Waiting", 'build_description': "", 'cid': challenge['cid'], 'uid': user.custom_data['uid'], 'sid': str(uuid4()), 'rating': 1500, 'RD': 300.0, 'previous_submissions': [] } mongodb.submissions.insert(document) error = '' try: r = requests.post('http://' + app.config['YGG_URL'] + '/build', data={'sid': document['sid'], 'cid': document['cid'], 'password': app.config['YGG_PASSWORD']}) if r.status_code != 200: error = 'Could not send solution to build. Please notify system administrators.' logger.warn('[%s] Error %d in /build: %s' % (time.strftime('%Y-%m-%d %H:%M:%S'), r.status_code, r.text)) except requests.exceptions.ConnectionError as e: error = 'Connection refused. Yggdrasil may be down. Please notify system administrators.' logger.warn('[%s] Exception in /build: %s' % (time.strftime('%Y-%m-%d %H:%M:%S'), e.message)) if error: return render_template('submitsolution.html', challenge = challenge, error = error), 400 return redirect(url_for('dashboard'))
def groups_dashboard(): """ Renders a list of groups the user can see """ username = user.username if not username: abort(400) user_in_db = mongodb.users.find_one({ 'username': username }) if not user_in_db: abort(404) groups = filter(lambda group: not group['admin_only'] or username in group['admins'] or is_active_user_in('Dev'), mongodb.groups.find()) return render_template('groups.html', username = username, groups = groups)
def challenges(): """ Page to display all challenges """ challenges = sorted_by_name( [challenge for challenge in mongodb.challenges.find() if ( not challenge['dev_only'] or is_active_user_in('Dev') )] ) return render_template('challenges.html', challenges=challenges)