text: #!/usr/bin/env python
  """
  Simple script, for NodeMeister enc data dumps, to translate a JSON dump
  into object creation statements. We *need* some sort of testing (simple
  fixture-driven high-level integration testing) before we can start to
  hack on it (like breaking down the methods enough to write real unit
  tests). So we need a simple way to grab the data we've manually entered
  into the database. We want this data to remain useful, so this script
  translates a JSON "manage.py dumpdata enc" file into object creation
  and save statements for use in tests.
  """
  
  import anyjson
  import optparse
  import sys
  import re
  from subprocess import Popen, PIPE
  from getpass import getuser
  from platform import node
  from datetime import datetime
  
  models = {}
  models['group'] = {'modelname': 'Group', 'fieldname': 'group', 'fk': {}}
  models['group']['manytomany'] = {'parents': 'group'}
  models['node'] = {'modelname': 'Node', 'fieldname': 'node', 'fk': {}}
  models['node']['manytomany'] = {'excluded_groups': 'group', 'groups': 'group'}
  models['groupclass'] = {'modelname': 'GroupClass', 'fieldname': 'groupclass'}
  models['groupclass']['manytomany'] = {}
  models['groupclass']['fk'] = {'group': 'group'}
  models['nodeclass'] = {'modelname': 'NodeClass', 'fieldname': 'nodeclass', 'fk': {'node': 'node'}, 'manytomany': {}}
  models['nodeparameter'] = {'modelname': 'NodeParameter', 'fieldname': 'nodeparameter', 'fk': {'node': 'node'}, 'manytomany': {}}
  models['groupparameter'] = {'modelname': 'GroupParameter', 'fieldname': 'groupparameter', 'fk': {'group': 'group'}, 'manytomany': {}}
  models['paramexclusion'] = {'modelname': 'ParamExclusion', 'fieldname': 'paramexclusion', 'fk': {'node': 'node'}, 'manytomany': {}}
  models['classexclusion'] = {'modelname': 'ClassExclusion', 'fieldname': 'classexclusion', 'fk': {'node': 'node'}, 'manytomany': {}}
  
  FUNC_BODY = """    def test_functional_dump2yaml_%s(self, client):
          \"""
          High-level functional object dump-to-yaml tests
  
          generated from enc/fixtures/%s.json as of rev %s
          generated by enc/fixtures/dump_to_creates.py by %s (%s on %s) at %s
          \"""
          to_save = []
  %s
          for o in to_save:
              o.save()
  
          with open('enc/fixtures/%s.yaml', 'r') as fh:
              yaml = fh.read()
  
          response = client.get('/enc/puppet/testnode', CONTENT_TYPE='application/json')
          assert response.status_code == 200
          assert response.content == yaml
  """
  
  
  def to_s(s):
      """
      write value as a string suitable for use in python code...
      """
      try:
          des = anyjson.deserialize(s)
          return des
      except ValueError:
          pass
      except TypeError:
          pass
      if isinstance(s, basestring):
          return "'" + s + "'"
      return str(s)
  
  
  def to_fkey_list(name, title, l, model=None):
      """
      take a title/object name and a list (l),
      make an object relation list
      """
      if model is None:
          model = title
      s = ""
      for g in l:
          s += "        %s.%s.add(%s%s)\n" % (name, title, model, g)
      return s
  
  
  def to_fkey(name, title, f, model=None):
      if model is None:
          model = title
      s = "%s=%s%s, " % (title, model, f)
      return s
  
  
  def make_statement(o_type, o):
      """
      make an object creation statement for a node
      """
      if o_type not in models:
          print "ERROR: no model info for type '%s'" % o_type
          return ""
      name = "%s%s" % (o_type, o['pk'])
      s = "        %s = enc.models.%s.objects.create(" % (name, models[o_type]['modelname'])
      deferred = ""
      for f in o['fields']:
          if f in models[o_type]['manytomany']:
              deferred += to_fkey_list(name, f, o['fields'][f], model=models[o_type]['manytomany'][f])
          elif f in models[o_type]['fk']:
              s += to_fkey(name, f, o['fields'][f], model=models[o_type]['fk'][f])
          else:
              s += "%s=%s, " % (f, to_s(o['fields'][f]))
      s = s.strip(', ')
      s += ")\n"
      s += deferred
      s += "        to_save.append(%s)\n" % name
      return s
  
  
  def do_object_list(l):
      """
      iterate over a list of objects, return a string of statements
      """
      s = ""
      for i in l:
          o_type = i['model'].split('.')[1]
          foo = make_statement(o_type, i)
          s += "        " + foo
      return s
  
  
  def get_git_rev():
      """
      Gets the current git revision for the current directory
      """
      output = Popen(["git", "rev-parse", "--short", "HEAD"], stdout=PIPE).communicate()[0]
      return output.strip()
  
  
  def get_git_user():
      """
      Gets the current git revision for the current directory
      """
      output = Popen(["git", "config", "--get", "user.email"], stdout=PIPE).communicate()[0]
      return output.strip()
  
  
  def do_file(fname):
      """
      Handle a file.
      """
      with open(fname, 'r') as fh:
          contents = fh.read()
      data = anyjson.deserialize(contents)
  
      fixture_name = re.sub(r'\.json$', '', fname)
      safe_fixture_name = re.sub(r'[^A-Za-z0-9_]', '', fixture_name)
      ds = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  
      output = do_object_list(data)
  
      print(FUNC_BODY % (safe_fixture_name, fixture_name, get_git_rev(), ds, get_git_user(), getuser(), node(), output, fixture_name))
  
  
  if __name__ == "__main__":
      usage = "usage: %prog [options]"
      parser = optparse.OptionParser(usage=usage)
  
      parser.add_option('-i', '--infile', dest='infile', action="store", type="string",
                        help='input file')
  
      options, args = parser.parse_args()
  
      if not options.infile:
          print("ERROR: input file must be specified.")
          sys.exit(1)
  
      do_file(options.infile)
  