コード例 #1
0
ファイル: user_status.py プロジェクト: royxue/Codejam
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))
コード例 #2
0
ファイル: contest_manager.py プロジェクト: veltzerdoron/GCJ
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))
コード例 #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))
コード例 #4
0
ファイル: contest_manager.py プロジェクト: veltzerdoron/GCJ
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))
コード例 #5
0
ファイル: user_status.py プロジェクト: veltzerdoron/GCJ
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))
コード例 #6
0
    def Submit(self,
               input_id,
               output_name,
               source_patterns,
               io_set_public,
               gzip_body=True,
               zip_sources=False,
               add_ignored_zips=False):
        """Submit the specified output and sources file to the problem.

    Args:
      input_id: Identifier of the output to submit ('0' for the small output,
        '1' for the large output).
      output_name: Name of the file with the output data.
      source_patterns: Name patterns of the source files to be included with the
        output. These patterns will be expanded using Python's glob module.
      io_set_public: Boolean indicating whether the answer is public or not.
      gzip_body: Boolean indicating whether the body has to be gzipped or not.
      zip_sources: Boolean indicating whether all sources should be put inside a
        zip file or not.
      add_ignored_zips: Boolean indicating whether zip files that are not
        included directly but are inside a included directory should be
        submitted or not.

    Raises:
      error.InternalError: If an error occurs while copying ignored zip files
        to the final location.
      error.NetworkError: If a network error occurs while communicating with the
        server.
      error.ServerError: If the server answers code distinct than 200.
    """
        # Prepare the source files (zipping all directories). After this,
        # source_files will only contain text files and zip files specified directly
        # or by compressing a directory.
        source_files, ignored_zips = self._PrepareSourceFiles(
            set(source_patterns))

        # Check if the user requested to zip source files.
        if zip_sources:
            # Extract all files to zip into a list and remove them from the
            # source files list.
            sources_to_zip = [
                filename for filename, file_data in source_files
                if file_data is None
            ]
            source_files = [(filename, file_data)
                            for filename, file_data in source_files
                            if file_data is not None]

            # Generate a zip file with all the flat source files.
            sys.stdout.write('Compressing files "{0}"...\n'.format(
                ', '.join(sources_to_zip)))
            zipped_sources, _ = zip_utils.MakeZipFileInMemory(
                sources_to_zip, ignore_exts=['.zip'])

            # Generate a random name for the zipped source files and add it to the
            # source files to send.
            zip_filename = '__plain_files_{0}.zip'.format(
                random.randrange(0, 2**31 - 1))
            source_files.append((zip_filename, zipped_sources))

        # Check if the user requested to add the ignored zip files inside included
        # directories.
        if add_ignored_zips:
            # Copy and add each ignored file to the source list.
            for ignored_zip in ignored_zips:
                # Read the contents of the ignored zip file.
                try:
                    zip_file = open(ignored_zip, 'rb')
                    zip_file_contents = zip_file.read()
                    zip_file.close()
                except IOError as e:
                    raise error.InternalError(
                        'I/O error happened while read zip file '
                        '"{0}": {1}.\n'.format(ignored_zip, e))

                # Generate the zip flat filename by substituting path with underscores
                # and adding a random number to prevent collisions. Then use it to add
                # the zip file and its contents into the source files to send.
                path, ext = os.path.splitext(ignored_zip)
                zip_flat_filename = '{1}_{0}{2}'.format(
                    random.randrange(0, 2**31 - 1),
                    path.replace('\\', '_').replace('/', '_'), ext)
                source_files.append((zip_flat_filename, zip_file_contents))

        # Print message and check that at least one source file was included.
        if source_files:
            sources_str = ', '.join('"{0}"'.format(filename)
                                    for filename, _ in source_files)
            sys.stdout.write(
                'Sending output file "{0}" and source(s) {1} to "{2}"'
                '...\n'.format(output_name, sources_str, self.host))
        else:
            # Print warning saying that no source file is being included, this might
            # cause disqualification in a real contest.
            sys.stdout.write(
                'Warning, no source files are being sent for output '
                'file "{0}"!\n'.format(output_name))
            sys.stdout.write('Sending output file "{0}" to "{1}"...\n'.format(
                output_name, self.host))

        # Generate a random boundary string to separate multipart data and
        # create a multipart data object with it. Then fill it with the necessary
        # arguments.
        multipart_boundary = '----gcjMultipartBoundary{0}'.format(
            random.randrange(0, 2**31 - 1))
        body_data = multipart_data.MultipartData(multipart_boundary)
        body_data.AddString('csrfmiddlewaretoken', self.middleware_token)
        body_data.AddFile('answer', output_name)
        for i, (filename, file_data) in enumerate(source_files):
            body_data.AddFile('source-file{0}'.format(i), filename, file_data)
            body_data.AddString('source-file-name{0}'.format(i), filename)
        body_data.AddString('cmd', 'SubmitAnswer')
        body_data.AddString('contest', self.contest_id)
        body_data.AddString('problem', self.problem_id)
        body_data.AddString('input_id', input_id)
        body_data.AddString('num_source_files', str(len(source_files)))
        body_data.AddString('agent', constants.CODEJAM_AGENT_NAME)

        # Get the message body and check if compression was requested.
        request_body = str(body_data)
        if gzip_body:
            compressed_body = zip_utils.ZipData(request_body)
            sys.stdout.write('Sending {0} bytes to server ({1} uncompressed)'
                             '...\n'.format(len(compressed_body),
                                            len(request_body)))
            request_body = compressed_body
        else:
            sys.stdout.write('Sending {0} bytes to server...\n'.format(
                len(request_body)))

        # Send an HTTP request with the output file and the source files.
        request_url = '/codejam/contest/dashboard/do'
        request_referer = 'http://{0}/codejam/contest/dashboard?c={1}'.format(
            self.host, self.contest_id)
        request_arguments = {}
        request_headers = {
            'Content-Encoding':
            'gzip' if gzip_body else 'text/plain',
            'Content-Type':
            'multipart/form-data; boundary={0}'.format(multipart_boundary),
            'Referer':
            request_referer,
            'Cookie':
            self.cookie,
        }
        try:
            status, reason, response = http_interface.Post(
                self.host, request_url, request_arguments, request_headers,
                request_body)
        except httplib.HTTPException as e:
            raise error.NetworkError(
                'HTTP exception while sending solution to 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 submit solution. Check that the host, '
                'username and contest id are valid.\n')

        # Check if the server accepted the input or just ignored it. If it
        # accepted it, parse the response and print the submission result.
        if response:
            submit_result = self._ParseResult(response, io_set_public)
            sys.stdout.write('{0}\n'.format(submit_result))
        else:
            raise error.ServerError(
                'No response received from the server. This generally happens if '
                'you try to submit the large output before solving the small '
                'input.\n')
コード例 #7
0
ファイル: input_downloader.py プロジェクト: veltzerdoron/GCJ
    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))
コード例 #8
0
def _MakeLogin(host, user, password):
  """Retrieve the authentication token and cookie from the code jam server,
  using the given user and password to authenticate.

  Args:
    host: Name of the host that runs the competition.
    user: User to authenticate in the Code Jam servers.
    password: Password of the user.

  Returns:
    A tuple with the authentication token and the login cookie.

  Raises:
    error.AuthenticationError: If the server answers with an authentication
      error, as specified in the GoogleLogin protocol.
    error.NetworkError: If there was a problem while communicating with the
      server.
  """
  try:
    # Get the authentication token and gae cookie using the GoogleLogin module.
    sys.stdout.write('Logging into "{0}" with user "{1}"...\n'.format(
        host, user))
    application_name = 'gcj_commandline-{0}'.format(constants.VERSION)
    auth_token, cookie = google_login.Login(
        host, 'HOSTED_OR_GOOGLE', user, password, 'ah', application_name, False)
    sys.stdout.write('Successfully logged into "{0}" with user "{1}".\n'.format(
        host, user))
    return auth_token, cookie

  except google_login.AuthenticationError as e:
    # Return a exception with a human-readable error based on the error and exit
    # with an error code.
    if e.reason == 'BadAuthentication':
      raise error.AuthenticationError('Invalid username or password.\n')
    elif e.reason == 'CaptchaRequired':
      raise error.AuthenticationError(
          'Please go to https://www.google.com/accounts/DisplayUnlockCaptcha '
          'and verify you are a human. Then try again.\n')
    elif e.reason == 'NotVerified':
      raise error.AuthenticationError('Account not verified.')
    elif e.reason == 'TermsNotAgreed':
      raise error.AuthenticationError('User has not agreed to TOS.')
    elif e.reason == 'AccountDeleted':
      raise error.AuthenticationError('The user account has been deleted.')
    elif e.reason == 'AccountDisabled':
      raise error.AuthenticationError('The user account has been disabled.')
    elif e.reason == 'ServiceDisabled':
      raise error.AuthenticationError('The user\'s access to the service has '
                                      'been disabled.')
    elif e.reason == 'ServiceUnavailable':
      raise error.AuthenticationError('The service is not available, try again '
                                      'later.')
    else:
      raise error.AuthenticationError('Unrecognized authentication error. '
                                      'Reason: %s' % e.reason)

  except urllib2.HTTPError as e:
    explanation = BaseHTTPServer.BaseHTTPRequestHandler.responses[e.code][0]
    raise error.NetworkError('HTTP error while logging into the Google Code '
                             'Jam server ({0}): {1}\n'.format(e.code,
                                                              explanation))
コード例 #9
0
ファイル: user_submissions.py プロジェクト: royxue/Codejam
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
    ]
コード例 #10
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))
コード例 #11
0
ファイル: contest_manager.py プロジェクト: veltzerdoron/GCJ
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))