def GetUserStatus(host, cookie, middleware_token, contest_id, problems): """Get the current user's status from the server. Args: host: Domain name of the server where the contest is running. cookie: Cookie for the current user. middleware_token: Middleware authentication token for the current user. contest_id: Id of the contest where the user is participating. problems: List with all problems in the contest. Returns: An UserStatus object with the current user's status. Raises: error.NetworkError: If a network error occurs while communicating with the server. error.ServerError: If the server answers code distinct than 200 or the response is a malformed JSON. """ # Send an HTTP request to get the user status. sys.stdout.write( 'Getting user status at contest {0} from "{1}"...\n'.format( contest_id, host)) request_referer = 'http://{0}/codejam/contest/dashboard?c={1}'.format( host, contest_id) request_arguments = { 'cmd': 'GetUserStatus', 'contest': contest_id, 'zx': str(int(time.time())), 'csrfmiddlewaretoken': str(middleware_token), } request_headers = { 'Referer': request_referer, 'Cookie': cookie, } try: status, reason, response = http_interface.Get( host, '/codejam/contest/dashboard/do', request_arguments, request_headers) except httplib.HTTPException as e: raise error.NetworkError( 'HTTP exception while user status from the Google ' 'Code Jam server: {0}.\n'.format(e)) # Check if the status is not good. if status != 200 or reason != 'OK': raise error.ServerError( 'Error while communicating with the server, cannot ' 'get user status. Check that the host, username ' 'and contest id are valid.\n') # Parse the JSON response and return an object with the user status. try: json_response = json.loads(response) return UserStatus.FromJsonResponse(json_response, problems) except ValueError as e: raise error.ServerError( 'Invalid response received from the server, cannot ' 'get user status. Check that the contest id is ' 'valid: {0}.\n'.format(e))
def GetContestStatus(host, cookie, get_initial_values_token, contest_id): """Get the contest status of the specified contest. Args: host: Host where the contest is running. cookie: Cookie that the user received when authenticating. get_initial_values_token: Middleware token used to make the request. contest_id: ID of the contest whose problems must be read. Returns: The contest status. Raises: error.NetworkError: If a network error occurs while communicating with the server. error.ServerError: If the server answers code distinct than 200 or the response is a malformed JSON. """ # Send an HTTP request to get the problem list from the server. sys.stdout.write('Getting status of contest {0} from "{1}"...\n'.format( contest_id, host)) request_referer = 'http://{0}/codejam/contest/dashboard?c={1}'.format( host, contest_id) request_arguments = { 'cmd': 'GetInitialValues', 'contest': contest_id, 'zx': str(int(time.time())), 'csrfmiddlewaretoken': str(get_initial_values_token), } request_headers = { 'Referer': request_referer, 'Cookie': cookie, } try: status, reason, response = http_interface.Get( host, '/codejam/contest/dashboard/do', request_arguments, request_headers) except httplib.HTTPException as e: raise error.NetworkError( 'HTTP exception while retrieving contest status ' 'from the Google Code Jam server: ' '{0}.\n'.format(e)) # Check if the status is not good. if status != 200 or reason != 'OK': raise error.ServerError( 'Error while communicating with the server, cannot ' 'get contest status. Check that the host, username ' 'and contest id are valid.\n') # Parse the JSON response and extract the contest status from it. try: json_response = json.loads(response) return json_response['cs'] except (KeyError, ValueError) as e: raise error.ServerError( 'Invalid response received from the server, cannot ' 'get contest status. Check that the contest id is ' 'valid: {0}.\n'.format(e))
def _GetMiddlewareTokens(host, cookie): """Get needed middleware tokens for the specified host. Args: host: Host where the contest is running. cookie: Cookie that the user received when authenticating. Returns: A tuple two elements: a dictionary containing all the middleware tokens, and the tokens expiration date. Raises: error.NetworkError: If a network error occurs while communicating with the server. error.ServerError: If the server answers code distinct than 200 or the response is a malformed JSON. """ # Send an HTTP request to get the problem list from the server. sys.stdout.write('Getting middleware tokens from "{0}"...\n'.format(host)) request_referer = 'http://{0}/codejam'.format(host) request_arguments = { 'cmd': 'GetMiddlewareTokens', 'actions': 'GetInitialValues,GetInputFile,GetUserStatus,SubmitAnswer', } request_headers = { 'Referer': request_referer, 'Cookie': cookie, } try: status, reason, response = http_interface.Get(host, '/codejam/middleware', request_arguments, request_headers) except httplib.HTTPException as e: raise error.NetworkError('HTTP exception while retrieving middleware ' 'tokens from the Google Code Jam server: ' '{0}\n'.format(e)) # Check if the status is not good. if status != 200 or reason != 'OK': raise error.ServerError( 'Error while communicating with the server, cannot ' 'get middleware tokens. Check that the host, ' 'username and contest id are valid.\n') # Extract token information from server response. try: tokens_info = json.loads(response) return tokens_info['tokens'], tokens_info['expire'] except (KeyError, ValueError) as e: raise error.ServerError( 'Invalid response received from the server, cannot ' 'initialize contest. Check that the contest id is ' 'valid: {0}.\n'.format(e))
def GetCurrentContestId(host, cookie, tournament_id): # Send an HTTP request to get the problem list from the server. sys.stdout.write('Getting current contest of tournament {0} from ' '"{1}"...\n'.format(tournament_id, host)) request_arguments = { 't': tournament_id, 'zx': str(int(time.time())), } request_headers = { 'Referer': 'http://{0}/codejam', 'Cookie': cookie, } try: status, reason, response = http_interface.Get( host, '/codejam/contest/microsite-info', request_arguments, request_headers) except httplib.HTTPException as e: raise error.NetworkError( 'HTTP exception while retrieving current contest ' 'from the Google Code Jam server: ' '{0}.\n'.format(e)) # Check if the status is not good. if status != 200 or reason != 'OK': raise error.ServerError( 'Error while communicating with the server, cannot ' 'get current contest. Check that the host and ' 'username are valid.\n') # Parse the JSON response and extract the contest status from it. try: json_response = json.loads(response) return json_response.get('contestId', None) except ValueError as e: raise error.ServerError( 'Invalid response received from the server, cannot ' 'get current contest. Check that the tournament id ' 'is valid: {0}.\n'.format(e))
def GetUserStatus(host, cookie, middleware_token, contest_id, input_spec): """Get the current user's status from the server. Args: host: Domain name of the server where the contest is running. cookie: Cookie for the current user. middleware_token: Middleware authentication token for the current user. contest_id: Id of the contest where the user is participating. input_spec: Dictionary with the input specification, mapping from input name to another dictionary with a 'time_limit' key. Returns: An UserStatus object with the current user's status. Raises: error.ConfigurationError: If there is an input specification without time limit. error.NetworkError: If a network error occurs while communicating with the server. error.ServerError: If the server answers code distinct than 200 or the response is a malformed JSON. """ # Send an HTTP request to get the user status. sys.stdout.write( 'Getting user status at contest {0} from "{1}"...\n'.format( contest_id, host)) request_referer = 'http://{0}/codejam/contest/dashboard?c={1}'.format( host, contest_id) request_arguments = { 'cmd': 'GetUserStatus', 'contest': contest_id, 'zx': str(int(time.time())), 'csrfmiddlewaretoken': str(middleware_token), } request_headers = { 'Referer': request_referer, 'Cookie': cookie, } try: status, reason, response = http_interface.Get( host, '/codejam/contest/dashboard/do', request_arguments, request_headers) except httplib.HTTPException as e: raise error.NetworkError( 'HTTP exception while user status from the Google ' 'Code Jam server: {0}.\n'.format(e)) # Check if the status is not good. if status != 200 or reason != 'OK': raise error.ServerError( 'Error while communicating with the server, cannot ' 'get user status. Check that the host, username ' 'and contest id are valid.\n') # Sort and extract information from the input specification. try: parsed_input_spec = [ (input_data['input_id'], input_name, input_data['time_limit']) for input_name, input_data in input_spec.iteritems() ] parsed_input_spec.sort() input_spec = [input_data[1:] for input_data in parsed_input_spec] except KeyError: raise error.ConfigurationError( 'Wrong input specification, "time_limit" ' 'key not found.\n') # Parse the JSON response and return an object with the user status. try: json_response = json.loads(response) return UserStatus.FromJsonResponse(json_response, input_spec) except ValueError as e: raise error.ServerError( 'Invalid response received from the server, cannot ' 'get user status. Check that the contest id is ' 'valid: {0}.\n'.format(e))
def Download(self, input_id, filename): """Download the specified input and store it in the specified file. Args: input_id: Identifier of the input to download ('0' for the small input and '1' for the large input). filename: Name of the file where the input data must be stored. """ # Send an HTTP request to get the input file from the server. sys.stdout.write('Getting input file "{0}" from "{1}"...\n'.format( filename, self.host)) request_url = '/codejam/contest/dashboard/do/{0}'.format(filename) request_referer = 'http://{0}/codejam/contest/dashboard?c={1}'.format( self.host, self.contest_id) request_arguments = { 'cmd': 'GetInputFile', 'contest': self.contest_id, 'problem': str(self.problem_id), 'input_id': input_id, 'filename': filename, 'input_file_type': '0', 'csrfmiddlewaretoken': self.middleware_token, 'agent': constants.CODEJAM_AGENT_NAME, } request_headers = { 'Referer': request_referer, 'Cookie': self.cookie, } try: status, reason, response = http_interface.Get( self.host, request_url, request_arguments, request_headers) except httplib.HTTPException as e: raise error.NetworkError( 'HTTP exception while getting input file: ' '{0}.\n'.format(e)) # Check if the status is not good. if status != 200 or reason != 'OK': raise error.ServerError( 'Error while communicating with the server, ' 'cannot download input. Check that the host, ' 'username and contest id are valid.\n') # No response from the server, output warning. if not response: raise error.ServerError( 'No response received from the server. This generally happens when:\n' ' - You try to download a small input but it is already solved.\n' ' - You try to download the large input before solving the small ' 'input.\n' ' - You try to redownload the large but its timer already ' 'expired.\n') # Write response to the desired file. try: input_file = open(filename, 'wt') input_file.write(response) input_file.close() sys.stdout.write( 'File "{0}" downloaded successfully.\n'.format(filename)) except IOError as e: raise error.InternalError('I/O error while writing file "{0}": ' '{1}.\n'.format(filename, e))
def GetUserSubmissions(host, cookie, contest_id, problems): """Get the current user's submissions for the current contest. Args: host: Domain name of the server where the contest is running. cookie: Cookie for the current user. contest_id: Id of the contest where the user is participating. problems: Iterable with all problems in the current contest. Returns: A list of UserSubmission objects with the user submissions for the current contest. Raises: error.NetworkError: If a network error occurs while communicating with the server. error.ServerError: If the server answers code distinct than 200 or the response is a malformed JSON. """ # Send an HTTP request to get the contest events. sys.stdout.write('Getting events of contest {0} from "{1}"...\n'.format( contest_id, host)) request_referer = 'http://{0}/codejam/contest/dashboard?c={1}'.format( host, contest_id) request_arguments = { 'cmd': 'GetEvents', 'contest': contest_id, 'zx': str(int(time.time())), } request_headers = { 'Referer': request_referer, 'Cookie': cookie, } try: status, reason, response = http_interface.Get( host, '/codejam/contest/dashboard/do', request_arguments, request_headers) except httplib.HTTPException as e: raise error.NetworkError( 'HTTP exception while retrieving user submissions from the Google Code ' 'Jam server: {0}.\n'.format(e)) # Check if the status is not good. if status != 200 or reason != 'OK': raise error.ServerError( 'Error while communicating with the server, cannot ' 'get contest events. Check that the host, username ' 'and contest id are valid.\n') # Parse the JSON response and extract the user submissions (or attempts). try: json_response = json.loads(response) submissions = json_response.get('a') if submissions is None: return None except ValueError as e: raise error.ServerError('Cannot parse JSON from server response: ' '{0}.\n'.format(e)) # Process each user submission and return them in a list. return [ UserSubmission.FromJsonResponse(submission, problems) for submission in submissions ]
def CheckToolVersion(host, tool_version): """Check if the specified tool_version is accepted by the host. Args: host: Host where the contest is running. tool_version: String with this tool's version. Raises: error.InternalError: If the tool's version is not accepted by the host. error.NetworkError: If a network error occurs while communicating with the server. error.ServerError: If the server answers code distinct than 200 or the response is a malformed JSON. """ # Send an HTTP request to get the problem list from the server. sys.stdout.write('Checking tool version for "{0}"...\n'.format(host)) request_referer = 'http://{0}/codejam'.format(host) request_arguments = { 'cmd': 'CheckVersion', 'version': tool_version, } request_headers = { 'Referer': request_referer, } try: status, reason, response = http_interface.Get(host, '/codejam/cmdline', request_arguments, request_headers) except httplib.HTTPException as e: raise error.NetworkError( 'HTTP exception while checking tool version with ' 'the Google Code Jam server: {0}\n'.format(e)) # The current server version might not support this yet. Print a warning # message and skip validation. if status == 404: print 'WARNING: Cannot check commandline version with the server.' return # Check if the status is not good. if status != 200 or reason != 'OK': raise error.ServerError( 'Error while communicating with the server, cannot ' 'check tool version. Check that the host is ' 'valid.\n') # Extract token information from server response. try: validation_info = json.loads(response) if validation_info['msg']: print validation_info['msg'] if not validation_info['valid']: raise error.InternalError( 'This tool\'s version is not accepted by host ' '{0}, please update to the latest ' 'version.\n'.format(host, tool_version)) except (KeyError, ValueError) as e: raise error.ServerError( 'Invalid response received from the server, cannot ' 'initialize contest. Check that the contest id is ' 'valid: {0}.\n'.format(e))
def _GetProblems(host, cookie, contest_id): """Read the problems of the specified contest. Args: host: Host where the contest is running. cookie: Cookie that the user received when authenticating. contest_id: ID of the contest whose problems must be read. Returns: A tuple with two lists, the first with the problem IDs and the second with the problem names. Raises: error.NetworkError: If a network error occurs while communicating with the server. error.ServerError: If the server answers code distinct than 200 or the response is a malformed JSON. """ # Send an HTTP request to get the problem list from the server. sys.stdout.write( 'Getting problem list of contest {0} from "{1}"...\n'.format( contest_id, host)) request_referer = 'http://{0}/codejam/contest/dashboard?c={1}'.format( host, contest_id) request_arguments = { 'cmd': 'GetProblems', 'contest': contest_id, } request_headers = { 'Referer': request_referer, 'Cookie': cookie, } try: status, reason, response = http_interface.Get( host, '/codejam/contest/dashboard/do', request_arguments, request_headers) except httplib.HTTPException as e: raise error.NetworkError( 'HTTP exception while retrieving problem ' 'information from the Google Code Jam server: ' '{0}.\n'.format(e)) # Check if the status is not good. if status != 200 or reason != 'OK': raise error.ServerError( 'Error while communicating with the server, cannot ' 'get problem information. Check that the host, ' 'username and contest id are valid.\n') # Parse the JSON response and extract each problem from it. try: problems = [] json_response = json.loads(response) for problem in json_response: problems.append({ 'key': problem['key'], 'id': problem['id'], 'name': problem['name'] }) return problems except (KeyError, ValueError) as e: raise error.ServerError( 'Invalid response received from the server, cannot ' 'initialize contest. Check that the contest id is ' 'valid: {0}.\n'.format(e))