# __init__.py

#

Copyright (C) 2011 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Subprogram for GoogleCL which handles all requests

#

using the Discovery service

This program uses the Discovery API to take interact with other APIs. It is called when GoogleCL cannot identify a requested service as using gdata. Syntax is generally similar to using gdata services.

General usage (omitting initial 'google'):

> help format

Examples: # Creating a new shortened goo.gl URL urlshortener insert --body {"longUrl":""}

# Getting data for a shortened goo.gl URL urlshortener url get

    import httplib2
    import logging

    import googlecl

    from apiclient.discovery import build_from_document
    from googlecl.discovery import authentication
    from googlecl.discovery import output
    from googlecl.discovery import data
    from googlecl.discovery import docs
    import simplejson as json

    LOG = logging.getLogger(googlecl.LOGGER_NAME)
    DISCOVERY_URI = '%s/discovery/v1/apis/{api}/{apiVersion}/rest'

#

    class DiscoveryManager():

#

      def __init__(self, email):
        self.dataManager = data.DefaultManager(email)
        self.docManager = docs.DocManager(self.dataManager.local_apis, self.dataManager.base_url)

#

Primary function for the program

      def run(self, argv):
       try:

#

Executes methods, displays help, and organizes formatting for services using Discovery

Args: cache: A cache, which may already contain objects to be used argv: The arguments, parsed into a list as from the command line

Determines if the help, format, or default is being called

        LOG.debug('Running Discovery...')
        isHelp = argv[0]=='help'
        verbose = False
        if isHelp:
          argv = argv[1:]
          if argv[-1] == '--verbose' or argv[-1] == '-v':
            verbose = True
            argv = argv[:-1]

        http = httplib2.Http()

        LOG.debug('Parsing service...')

#

Fetches service, version, docs, etc.

        try:
          servicename, version, doc, args = self.docManager.run(argv, isHelp,
                                                                verbose)
        except TypeError:
          return

        LOG.debug('Managing auth...')

#

Checks if credentials are needed and, if so, whether they are possessed. If not, gets appropriate credentials.

        if 'auth' in doc:
          if '--force-auth' in args:
            args.remove('--force-auth')
            force_auth = True
          else:
            force_auth = False
          http = authentication.authenticate(self.dataManager.email, servicename, doc, http,
            self.dataManager.client_id, self.dataManager.client_secret, force_auth)

#

Builds the service and finds the method

          service = build_from_document(json.dumps(doc), DISCOVERY_URI % self.dataManager.base_url, http=http)
        else:
          service = build_from_document(json.dumps(doc), DISCOVERY_URI % self.dataManager.base_url,
                          developerKey=self.dataManager.devkey2, http=http)
        LOG.debug('Determining task...')
        try:
          metinfo, method, args = getMethod(service, doc, args)
        except:

#

LOG.error('Did not recognize task.')

          return

        LOG.debug('Parsing parameters...')
        try:
          kwargs = self.dataManager.fill_out_options(metinfo, doc, args)
        except TypeError, err:
          raise
          return

        LOG.debug('Executing method...')
        try:
          resp = method(**kwargs).execute()
        except Exception, err:
          LOG.error(err)
          return

        LOG.debug('Displaying output...')

#

Displays formatted output

        output.output(resp, self.dataManager.formatting)
       except Exception, err:
        print 'Uncaught error'
        raise

#

      def apis_list(self):

#

Returns a list of the APIs that may be used

        return [str(d['name']) for d in self.docManager.directory['items']]

#

Locates the method to be executed

    def getMethod(service, doc, args):

#

apable of finding some methods implicitly isplays assistance if method isn't identified

rgs: service: The service object being used doc: Documentation describing the service args: List containing the method path to be followed

eturns: A tuple of the meta-info describing the method, the method itself, and the parameters for the method

      obj = doc
      attr = service
      i = 0
      while 'resources' in obj or 'methods' in obj:
        if i < len(args) and 'resources' in obj and args[i] in obj['resources']:
          attr = getattr(attr, args[i])
          obj = obj['resources'][args[i]]
          i=i+1
        elif i < len(args) and 'methods' in obj and args[i] in obj['methods']:
          attr = getattr(attr, args[i])
          obj = obj['methods'][args[i]]
          i=i+1
        elif ('resources' in obj and not 'methods' in obj and
            len(obj['resources'])==1):
          attr = getattr(attr, obj['resources'].keys()[0])
          obj = obj['resources'][obj['resources'].keys()[0]]
        elif 'methods' in obj and not 'resources' in obj and len(obj['methods'])==1:
          attr = getattr(attr, obj['methods'].keys()[0])
          obj = obj['methods'][obj['methods'].keys()[0]]
        else:
          print 'Did not recognize task.'
          if 'methods' in obj:
            LOG.error('Possible methods: ' + ', '.join(obj['methods']))
          if 'resources' in obj:
            LOG.error('Possible resources: ' + ', '.join(obj['resources']))
          return
        if not 'id' in obj:
          attr = attr()
      return obj, attr, args[i:]