PageRenderTime 33ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/src/googlecl/discovery/data.py

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