Exemple #1
0
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))
Exemple #2
0
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))
Exemple #3
0
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))
Exemple #4
0
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))
Exemple #5
0
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))
Exemple #6
0
    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))
Exemple #7
0
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
    ]
Exemple #8
0
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))
Exemple #9
0
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))