Source code for core.project.serialization
# -*- coding: utf-8 -*-
# -*- python -*-
#
#
# OpenAlea.OALab: Multi-Paradigm GUI
#
# Copyright 2014 INRIA - CIRAD - INRA
#
# File author(s): Guillaume Baty <guillaume.baty@inria.fr>
#
# File contributor(s):
#
# Distributed under the Cecill-C License.
# See accompanying file LICENSE.txt or copy at
# http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html
#
# OpenAlea WebSite : http://openalea.gforge.inria.fr
#
###############################################################################
from openalea.core.serialization import AbstractSaver
from openalea.core.path import path as Path
from configobj import ConfigObj
from openalea.core.service.interface import interface_name
from openalea.core.project import Project
from openalea.core.customexception import ErrorInvalidItem
[docs]class ProjectLoader(object):
dtype = ['IProject']
protocols = ['inode/directory']
options = ['config_filename=oaproject.cfg', 'default_metadata']
[docs] def load(self, path, protocol=None, **kwds):
project = Project(path)
return self.update(project, path, protocol=protocol, **kwds)
[docs] def update(self, obj, path, protocol=None, **kwds):
project = obj
default_metadata = kwds.pop('default_metadata', project.DEFAULT_METADATA)
default_categories = kwds.pop('default_categories', project.categories)
config_filename = kwds.pop('config_filename', 'oaproject.cfg')
config = ConfigObj(path / config_filename)
if 'metadata' in config:
for info in config["metadata"].keys():
if info == 'name':
info = 'alias'
value = config['metadata']['name']
elif info == 'author':
info = 'authors'
value = config['metadata']['author']
elif info == 'author_email':
continue
else:
value = config['metadata'][info]
if interface_name(default_metadata[info].interface) == 'ISequence':
if isinstance(value, basestring):
value = value.split(',')
setattr(project, info, value)
if 'manifest' in config:
# Load file names in right place (dict.keys()) but don't load entire object:
# ie. load keys but not values
for category in config["manifest"].keys():
# Backward compatibility
if category == 'src':
category = 'model'
old_category = 'src'
else:
old_category = category
if category in default_categories:
filenames = config["manifest"][old_category]
if not isinstance(filenames, list):
filenames = [filenames]
for filename in filenames:
section = '%s.path' % category
try:
if section in config:
if filename in config[section]:
project._add_item(category, path=config[section][filename], mode=project.MODE_LINK)
else:
project._add_item(category, filename=filename, mode=project.MODE_COPY)
else:
project._add_item(category, filename=filename, mode=project.MODE_COPY)
except ErrorInvalidItem:
pass
return project
[docs]class ProjectSaver(AbstractSaver):
dtype = ['IProject']
protocols = ['inode/directory']
options = [
{'name': 'mode', 'interface': 'IStr', 'value': 'all', 'values': ['all', 'metadata']}
]
[docs] def save(self, obj, path, protocol=None, **kwds):
mode = kwds.pop('mode', 'all')
path = Path(path)
config_filename = kwds.get('config_filename', 'oaproject.cfg')
config_path = path / config_filename
if mode == 'all':
if not path.exists():
path.makedirs()
self._save_metadata(obj, config_path)
lines = self._save_controls(obj)
with open(path / 'control.py', 'w') as f:
for line in lines:
f.write(line)
elif mode == 'metadata':
if path.exists():
self._save_metadata(obj, config_path)
else:
raise NotImplementedError('mode=%s' % mode)
def _save_metadata(self, obj, path):
path.touch()
from configobj import ConfigObj
config = ConfigObj()
if not path.isfile():
return
config.filename = path
config['manifest'] = dict()
config['metadata'] = obj.metadata
for category in obj.categories:
filenames_dict = getattr(obj, category)
if filenames_dict:
category_path = obj.path / category
if not category_path.exists():
category_path.makedirs()
config['manifest'][category] = []
for filename in sorted(filenames_dict.keys()):
data = filenames_dict[filename]
if hasattr(data, 'save'):
data.save()
config['manifest'][category].append(data.name)
# If data is stored outside project, register data.path in section category.path
if data.path.parent != category_path:
section = category + ".path"
config.setdefault(section, {})[data.name] = data.path
config.write()
def _save_controls(self, obj):
from openalea.core.control.serialization import ControlSerializer
from openalea.core.control.manager import ControlManager
cm = ControlManager()
controls = cm.controls()
if controls:
serializer = ControlSerializer()
lines = serializer.serialize(controls)
else:
lines = []
return lines