########################################
# The contents of this file are subject to the MLX PUBLIC LICENSE version
# 1.0 (the "License"); you may not use this file except in
# compliance with the License.
# 
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
# the License for the specific language governing rights and limitations
# under the License.
# 
# The Original Source Code is "compClust", released 2003 September 03.
# 
# The Original Source Code was developed by the California Institute of
# Technology (Caltech).  Portions created by Caltech are Copyright (C)
# 2002-2003 California Institute of Technology. All Rights Reserved.
########################################

"""
This is a simple module to save you current python intereptor state
"""
import types
import sys
import cPickle
import copy


def isPickleable(object):

  """
  isPickable(object)

  returns 1 if the object is pickleable 0 otherwise
  """
  
  # this might be slow
  testStream = open('/dev/null', 'w')
  try:
    cPickle.dump(object, testStream)
    return(1)
  except:
    return(0)
  

def save(stream):
  """
  saveSession(stream)

  save your current python session.  stream can also be a string in which
  case it is assumed to be a filename.

  """

  if type(stream) == types.StringType:
    outstream = open(stream, 'w')
  else:
    outstream = stream
    
  globalObjects = copy.copy(sys._getframe(1).f_globals)
  loadedModules = sys.modules.keys()
  loadedModules.pop(loadedModules.index('__main__'))
  for object in globalObjects.keys():
    if not isPickleable(sys._getframe(1).f_globals[object]):
      print "can't save: %s"%(object)
      del(globalObjects[object])

  globalObjects['__+loadedMods']=loadedModules
  cPickle.dump(globalObjects, outstream, 1)

  if type(stream) == types.StringType:
    outstream.close()

  return(globalObjects)

def restore(stream):

  """
  restoreSession (stream)

  restors a previously pickled session
  """

  if type(stream) == types.StringType:
    instream = open(stream, 'r')
  else:
    instream = stream

  
  globalObjects = cPickle.load(instream)
  for mod in globalObjects['__+loadedMods']:
    try:
      exec('import %s'%(mod))
    except:
      print "can't load %s "%(mod)

      
  del(globalObjects['__+loadedMods'])
  
  g = sys._getframe(1).f_globals
  for key in globalObjects.keys():
    g[key] = globalObjects[key]
  

  if type(stream) == types.StringType:
    instream.close()
  
