# data.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. Subclass which manages data for Discovery

#

anages defaults, config values, parsing the arguments, nd prompting for missing parameters efaults may be viewed/edited by calling 'edit defaults' ODO: Integrate ConfigParser

    import logging

    import simplejson as json
    import googlecl
    import googlecl.config
    import optparse

    LOG = logging.getLogger(googlecl.LOGGER_NAME)
    DEFAULT_FILENAME_FORMAT = 'dcd_%s'

#

Args governing prompting

    META_ARGS = ['prompt', 'editor', 'editmode']

#

Args that aren't in method parameters

    EXTRA_ARGS = ['fields']

#

    class DefaultManager:

#

      def __init__(self, email):
        self.email = email

#

Loads config options

        config = googlecl.config.load_configuration(None)
        self.client_id = config.lazy_get(None, 'client_id',
             default='20958643459.apps.googleusercontent.com', option_type=str)
        self.client_secret = config.lazy_get(None, 'client_secret',
             default='3D1TrF0sgq52J7zH80jdfbit', option_type=str)
        self.devkey2 = config.lazy_get(None, 'devkey2',
             default='AIzaSyAmK-fJLcJ0jS2mMIX5EXgU6M6UPT39e50', option_type=str)

#

Should make ^ required

        self.prompt = config.lazy_get(None, 'prompt',
             default='required', option_type=str)
        self.editmode = config.lazy_get(None, 'editmode',
             default='cl', option_type=str)
        self.formatting = config.lazy_get(None, 'formatting',
             default='pprint', option_type=str)
        self.local_apis = config.lazy_get(None, 'local_apis', default='', option_type=str)
        if '[' in self.local_apis or '(' in self.local_apis:
          self.local_apis = json.loads(self.local_apis)
        self.base_url = config.lazy_get(None, 'base_url', default='https://www.googleapis.com', option_type=str)
        editor = config.safe_get('DOCS', 'document_editor')
        if not editor:
          editor = config.safe_get(None, 'editor')
        if not editor:
          import os
          editor = os.getenv('EDITOR')
        if not editor:
          editor = 'vim'
        self.editor = editor

#

Turns a list of arguments into a map of keys/values

      def fill_out_options(self, metinfo, doc, args):

#

tarts by doing basic parse, then loads defaults, nd finally prompts for missing values

rgs: metinfo: The meta-info for the method, such as the required/optional parameters args: The arguments which are passed in

        parser = optparse.OptionParser()

#

Set up options

        for arg in META_ARGS:
          parser.add_option('--'+arg, default=getattr(self, arg))
        for arg in EXTRA_ARGS:
          parser.add_option('--'+arg)
        if 'parameters' in metinfo:
          for arg in metinfo['parameters']:
            parser.add_option("--"+arg)
        if 'request' in metinfo:
          parser.add_option("--body")
          for arg in doc['schemas'][metinfo['request']['$ref']]['properties']:
            try:
              parser.add_option('--'+arg)
            except optparse.OptionConflictError:
              pass

#

Parse args

        (options, args) = parser.parse_args(args)
        kwargs = vars(options)
        for arg in kwargs.keys():
          if kwargs[arg] == None or kwargs[arg] == '':
            del kwargs[arg]

#

Loads defaults

        config = googlecl.config.load_configuration()
        if config.parser.has_section(metinfo['id']):
          for arg in config.parser.options(metinfo['id']):
            if arg not in kwargs:
              kwargs[arg] = config.get(metinfo['id'], arg)

#

Attaches unmatched values to appropriate keys

        if args:
          if not 'parameterOrder' in metinfo:
            LOG.error('Received unexpected parameter.')
            return
          args = dict(zip([i for i in metinfo['parameterOrder']
                   if i not in kwargs.keys() or kwargs[i] == None],args))
          kwargs = dict(kwargs.items() + args.items())

#

Prompts for missing values

        if not kwargs['prompt'] == 'none' and 'parameterOrder' in metinfo:
          for a in metinfo['parameterOrder']: # Required parameters
            if a not in kwargs:
              value = raw_input('Please specify ' + a + ': ')
              if not value:
                return
              kwargs[a] = value
        if kwargs['prompt'] == 'all' and 'parameters' in metinfo:
          for a in metinfo['parameters']: # Optional parameters
            if a not in kwargs:
              value = raw_input('Please specify ' + a + ': ')
              if value:
                kwargs[a] = value
        if kwargs:
          for arg in kwargs.keys():
            if '{' == kwargs[arg][0] or '[' == kwargs[arg][0] or '(' == kwargs[arg][0]:
              kwargs[arg] = json.loads(kwargs[arg])

        if 'parameters' in metinfo:
          pars = set(metinfo['parameters'])
        else:
          pars = {}

#

Assumes that unknown keys are part of body

        if 'body' not in kwargs and 'request' in metinfo and not set(kwargs.keys()) - set(META_ARGS) - set(EXTRA_ARGS) <= set(pars):
          body = {}
          for a in set(kwargs.keys()) - set(pars) - set(META_ARGS) - set(EXTRA_ARGS):
            body[a] = kwargs[a]
            del kwargs[a]
          kwargs['body'] = body

#

Prompts for missing body

        if not kwargs['prompt'] == 'none' and 'body' not in kwargs and 'request' in metinfo:
          schemaname = metinfo['request']['$ref']
          schema = doc['schemas'][schemaname]
          if kwargs['editmode'] == 'editor':
            import subprocess
            import tempfile
            import os

            fd, filename = tempfile.mkstemp(text=True)
            f = open(filename, 'w')
            body = {}

#

Assembles the outline of the body Will modify to use required/mutable args if/when it is available

            for p in schema['properties']:
              if 'default' in schema['properties'][p]:
                body[p] = schema['properties'][p]['default']
              elif 'type' in schema['properties'][p]:
                body[p] = "<"+schema['properties'][p]['type']+">"
            json.dump(body, f, indent=2)
            f.close()
            cmd = '%s %s' % (kwargs['editor'], filename)
            raw_input('Missing body...')
            subprocess.call(cmd, shell=True)
            f = open(filename)
            value = json.load(f)
            f.close()
            os.remove(filename)
          else:
            print 'Missing body - Schema: ' + schemaname
            sargs = ', '.join(schema['properties'])
            print '  Args: ' + sargs
            bodyparser = optparse.OptionParser()
            for arg in doc['schemas'][metinfo['request']['$ref']]['properties']:
              bodyparser.add_option('--'+arg)
            (options, args) = bodyparser.parse_args(raw_input('Please specify body: ').split())
            value = vars(options)
            for arg in value.keys():
              if value[arg] == None or value[arg] == '':
                del value[arg]
            if not value:
              return
          kwargs['body'] = value

#

Get rid of meta-args

        for arg in META_ARGS:
          del kwargs[arg]

#

Can't have '-'s in keys

        for k in kwargs:
          if '-' in k:
            kwargs[k.replace('-','_')] = kwargs[k]
            del kwargs[k]

        return kwargs