PageRenderTime 124ms CodeModel.GetById 41ms app.highlight 43ms RepoModel.GetById 37ms app.codeStats 0ms

/src/googlecl/discovery/data.py

http://googlecl.googlecode.com/
Python | 203 lines | 180 code | 4 blank | 19 comment | 6 complexity | 3fa3bf141e963335f313e5a2a0e2b2f2 MD5 | raw file
  1# Copyright (C) 2011 Google Inc.
  2#
  3# Licensed under the Apache License, Version 2.0 (the "License");
  4# you may not use this file except in compliance with the License.
  5# You may obtain a copy of the License at
  6#
  7#      http://www.apache.org/licenses/LICENSE-2.0
  8#
  9# Unless required by applicable law or agreed to in writing, software
 10# distributed under the License is distributed on an "AS IS" BASIS,
 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12# See the License for the specific language governing permissions and
 13# limitations under the License.
 14
 15""" Subclass which manages data for Discovery
 16
 17Manages defaults, config values, parsing the arguments,
 18and prompting for missing parameters
 19Defaults may be viewed/edited by calling 'edit defaults'
 20TODO: Integrate ConfigParser
 21"""
 22
 23import logging
 24
 25import simplejson as json
 26import googlecl
 27import googlecl.config
 28import optparse
 29
 30LOG = logging.getLogger(googlecl.LOGGER_NAME)
 31DEFAULT_FILENAME_FORMAT = 'dcd_%s'
 32# Args governing prompting
 33META_ARGS = ['prompt', 'editor', 'editmode']
 34# Args that aren't in method parameters
 35EXTRA_ARGS = ['fields']
 36
 37class DefaultManager:
 38
 39  def __init__(self, email):
 40    self.email = email
 41    # Loads config options
 42    config = googlecl.config.load_configuration(None)
 43    self.client_id = config.lazy_get(None, 'client_id',
 44         default='20958643459.apps.googleusercontent.com', option_type=str)
 45    self.client_secret = config.lazy_get(None, 'client_secret',
 46         default='3D1TrF0sgq52J7zH80jdfbit', option_type=str)
 47    self.devkey2 = config.lazy_get(None, 'devkey2',
 48         default='AIzaSyAmK-fJLcJ0jS2mMIX5EXgU6M6UPT39e50', option_type=str)
 49    # Should make ^ required
 50    self.prompt = config.lazy_get(None, 'prompt', 
 51         default='required', option_type=str)
 52    self.editmode = config.lazy_get(None, 'editmode',
 53         default='cl', option_type=str)
 54    self.formatting = config.lazy_get(None, 'formatting',
 55         default='pprint', option_type=str)
 56    self.local_apis = config.lazy_get(None, 'local_apis', default='', option_type=str)
 57    if '[' in self.local_apis or '(' in self.local_apis:
 58      self.local_apis = json.loads(self.local_apis)
 59    self.base_url = config.lazy_get(None, 'base_url', default='https://www.googleapis.com', option_type=str)
 60    editor = config.safe_get('DOCS', 'document_editor')
 61    if not editor:
 62      editor = config.safe_get(None, 'editor')
 63    if not editor:
 64      import os
 65      editor = os.getenv('EDITOR')
 66    if not editor:
 67      editor = 'vim'
 68    self.editor = editor
 69
 70  def fill_out_options(self, metinfo, doc, args):
 71    """ Turns a list of arguments into a map of keys/values
 72    Starts by doing basic parse, then loads defaults, 
 73    and finally prompts for missing values
 74
 75    Args:
 76      metinfo: The meta-info for the method, 
 77        such as the required/optional parameters
 78      args: The arguments which are passed in
 79    """
 80    parser = optparse.OptionParser()
 81    # Set up options
 82    for arg in META_ARGS:
 83      parser.add_option('--'+arg, default=getattr(self, arg))
 84    for arg in EXTRA_ARGS:
 85      parser.add_option('--'+arg)
 86    if 'parameters' in metinfo:
 87      for arg in metinfo['parameters']:
 88        parser.add_option("--"+arg)
 89    if 'request' in metinfo:
 90      parser.add_option("--body")
 91      for arg in doc['schemas'][metinfo['request']['$ref']]['properties']:
 92        try:
 93          parser.add_option('--'+arg)
 94        except optparse.OptionConflictError:
 95          pass
 96
 97    # Parse args
 98    (options, args) = parser.parse_args(args)
 99    kwargs = vars(options)
100    for arg in kwargs.keys():
101      if kwargs[arg] == None or kwargs[arg] == '':
102        del kwargs[arg]
103
104    # Loads defaults
105    config = googlecl.config.load_configuration()
106    if config.parser.has_section(metinfo['id']):
107      for arg in config.parser.options(metinfo['id']):
108        if arg not in kwargs:
109          kwargs[arg] = config.get(metinfo['id'], arg)
110
111    # Attaches unmatched values to appropriate keys
112    if args:
113      if not 'parameterOrder' in metinfo:
114        LOG.error('Received unexpected parameter.')
115        return
116      args = dict(zip([i for i in metinfo['parameterOrder']
117               if i not in kwargs.keys() or kwargs[i] == None],args))
118      kwargs = dict(kwargs.items() + args.items())
119
120    # Prompts for missing values
121    if not kwargs['prompt'] == 'none' and 'parameterOrder' in metinfo:
122      for a in metinfo['parameterOrder']: # Required parameters
123        if a not in kwargs:
124          value = raw_input('Please specify ' + a + ': ')
125          if not value:
126            return
127          kwargs[a] = value
128    if kwargs['prompt'] == 'all' and 'parameters' in metinfo:
129      for a in metinfo['parameters']: # Optional parameters
130        if a not in kwargs:
131          value = raw_input('Please specify ' + a + ': ')
132          if value:
133            kwargs[a] = value
134    if kwargs:
135      for arg in kwargs.keys():
136        if '{' == kwargs[arg][0] or '[' == kwargs[arg][0] or '(' == kwargs[arg][0]:
137          kwargs[arg] = json.loads(kwargs[arg])
138
139    if 'parameters' in metinfo:
140      pars = set(metinfo['parameters'])
141    else:
142      pars = {}
143    # Assumes that unknown keys are part of body
144    if 'body' not in kwargs and 'request' in metinfo and not set(kwargs.keys()) - set(META_ARGS) - set(EXTRA_ARGS) <= set(pars):
145      body = {}
146      for a in set(kwargs.keys()) - set(pars) - set(META_ARGS) - set(EXTRA_ARGS):
147        body[a] = kwargs[a]
148        del kwargs[a]
149      kwargs['body'] = body
150      
151    # Prompts for missing body
152    if not kwargs['prompt'] == 'none' and 'body' not in kwargs and 'request' in metinfo:
153      schemaname = metinfo['request']['$ref']
154      schema = doc['schemas'][schemaname]
155      if kwargs['editmode'] == 'editor':
156        import subprocess
157        import tempfile
158        import os
159
160        fd, filename = tempfile.mkstemp(text=True)
161        f = open(filename, 'w')
162        body = {}
163        # Assembles the outline of the body
164        # Will modify to use required/mutable args if/when it is available
165        for p in schema['properties']:
166          if 'default' in schema['properties'][p]:
167            body[p] = schema['properties'][p]['default']
168          elif 'type' in schema['properties'][p]:
169            body[p] = "<"+schema['properties'][p]['type']+">"
170        json.dump(body, f, indent=2)
171        f.close()
172        cmd = '%s %s' % (kwargs['editor'], filename)
173        raw_input('Missing body...')
174        subprocess.call(cmd, shell=True)
175        f = open(filename)
176        value = json.load(f)
177        f.close()
178        os.remove(filename)
179      else:
180        print 'Missing body - Schema: ' + schemaname
181        sargs = ', '.join(schema['properties'])
182        print '  Args: ' + sargs
183        bodyparser = optparse.OptionParser() 
184        for arg in doc['schemas'][metinfo['request']['$ref']]['properties']:
185          bodyparser.add_option('--'+arg)
186        (options, args) = bodyparser.parse_args(raw_input('Please specify body: ').split())
187        value = vars(options)
188        for arg in value.keys():
189          if value[arg] == None or value[arg] == '':
190            del value[arg]
191        if not value:
192          return
193      kwargs['body'] = value
194    # Get rid of meta-args
195    for arg in META_ARGS:
196      del kwargs[arg]
197    # Can't have '-'s in keys
198    for k in kwargs:
199      if '-' in k:
200        kwargs[k.replace('-','_')] = kwargs[k]
201        del kwargs[k]
202
203    return kwargs