Source code for nxsrecconfig.Converter

#!/usr/bin/env python
#   This file is part of nxsrecconfig - NeXus Sardana Recorder Settings
#
#    Copyright (C) 2014-2017 DESY, Jan Kotanski <jkotan@mail.desy.de>
#
#    nexdatas is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    nexdatas is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with nexdatas.  If not, see <http://www.gnu.org/licenses/>.
#

"""  Selection version converter """

import json


[docs]class ConverterXtoY(object): """ virtual selection version converter """ def __init__(self): """ constructor """ #: (:obj:`dict` <:obj:`str`, :obj:`str`>) names to convert self.names = {}
[docs] def convert(self, selection): """ converts selection to the current selector version :param selection: selection dictionary object :type selection: :obj:`dict` <:obj:`str`, `any`> """ for old, new in self.names.items(): if old in list(selection.keys()): selection[new] = selection.pop(old)
[docs]class Converter2to3(ConverterXtoY): """ Selection converter from version 2 to 3 """ def __init__(self): """ converter """ super(Converter2to3, self).__init__() #: (:obj:`dict` <:obj:`str`, :obj:`str`>) names to convert self.names = { "PreselectedDataSources": "PreselectingDataSources", "InitDataSources": "DataSourcePreselection", }
[docs] def seltoint(self, jselelem): """ converters list/dict of elements to dictionary with logical values :param jselelem: json list or dict selection element :type jselelem: :obj:`str` :returns: json dictionary :rtype: :obj:`str` """ sel = json.loads(jselelem) if isinstance(sel, dict): return json.dumps( dict((key, True if vl else None) for key, vl in sel.items())) elif isinstance(sel, (list, tuple)): return json.dumps(dict((key, True) for key in sel))
[docs] def convert(self, selection): """ converts selection from version 2 to 3 :param selection: selection dictionary object :type selection: :obj:`dict` <:obj:`str`, `any`> """ super(Converter2to3, self).convert(selection) if 'ComponentPreselection' in selection.keys(): selection["ComponentPreselection"] = self.seltoint( selection["ComponentPreselection"]) if 'DataSourcePreselection' in selection.keys(): selection["DataSourcePreselection"] = self.seltoint( selection["DataSourcePreselection"]) if 'MntGrpConfiguration' not in selection.keys(): selection['MntGrpConfiguration'] = ''
[docs]class Converter3to2(ConverterXtoY): """ Selection converter from version 3 to 2 """ def __init__(self): """ constructor """ super(Converter3to2, self).__init__() #: (:obj:`dict` <:obj:`str`, :obj:`str`>) names to convert self.names = { "PreselectingDataSources": "PreselectedDataSources", "DataSourcePreselection": "InitDataSources", }
[docs] def seltobool(self, jselelem): """ converters dictioanry with None/True/False values to dictionary with True/False values :param jselelem: json dictionary selection element :type jselelem: :obj:`str` :returns: converter json dictionary :rtype: :obj:`str` """ sel = json.loads(jselelem) return json.dumps( dict((key, vl is not None) for key, vl in sel.items()))
[docs] def seltolist(self, jselelem): """ converters dictioanry with None/True/False values to list of elementes with walue True :param jselelem: json dictionary selection element :type jselelem: :obj:`str` :returns: converter json dictionary :rtype: :obj:`str` """ sel = json.loads(jselelem) return json.dumps([key for key, vl in sel.items() if vl])
[docs] def convert(self, selection): """ converts selection from version 3 to 2 :param selection: selection dictionary object :type selection: :obj:`dict` <:obj:`str`, `any`> """ super(Converter3to2, self).convert(selection) if 'ComponentPreselection' in selection.keys(): selection["ComponentPreselection"] = self.seltobool( selection["ComponentPreselection"]) if 'InitDataSources' in selection.keys(): selection['InitDataSources'] = self.seltolist( selection['InitDataSources']) if 'MntGrpConfiguration' in selection.keys(): selection.pop('MntGrpConfiguration')
[docs]class Converter1to2(ConverterXtoY): """ Selection converter from version 1 to 2 """ def __init__(self): """ constructor """ super(Converter1to2, self).__init__() #: (:obj:`dict` <:obj:`str`, :obj:`str`>) names to convert self.names = { "AutomaticComponentGroup": "ComponentPreselection", "AutomaticDataSources": "PreselectedDataSources", "ComponentGroup": "ComponentSelection", "DataSourceGroup": "DataSourceSelection", "DataRecord": "UserData", "HiddenElements": "UnplottedComponents", "DynamicLinks": "DefaultDynamicLinks", "DynamicPath": "DefaultDynamicPath" } #: (:obj:`dict` <:obj:`str`, :obj:`str`>) names of properties self.pnames = { "Labels": "label", "LabelPaths": "nexus_path", "LabelLinks": "link", "LabelTypes": "data_type", "LabelShapes": "shape", }
[docs] def convert(self, selection): """ converts selection from version 1 to 2 :param selection: selection dictionary object :type selection: :obj:`dict` <:obj:`str`, `any`> """ super(Converter1to2, self).convert(selection) props = {} for var, pn in self.pnames.items(): if var in list(selection.keys()): props[pn] = json.loads(selection.pop(var)) selection["ChannelProperties"] = json.dumps(props)
[docs]class Converter2to1(ConverterXtoY): """ Selection converter from version 2 to 1 """ def __init__(self): """ constructor """ super(Converter2to1, self).__init__() #: (:obj:`dict` <:obj:`str`, :obj:`str`>) names of properties self.pnames = { "Labels": "label", "LabelPaths": "nexus_path", "LabelLinks": "link", "LabelTypes": "data_type", "LabelShapes": "shape", } #: (:obj:`dict` <:obj:`str`, :obj:`str`>) names to convert self.names = { "ComponentSelection": "ComponentGroup", "ComponentPreselection": "AutomaticComponentGroup", "PreselectedDataSources": "AutomaticDataSources", "DataSourceSelection": "DataSourceGroup", "UserData": "DataRecord", "UnplottedComponents": "HiddenElements", "DefaultDynamicLinks": "DynamicLinks", "DefaultDynamicPath": "DynamicPath" }
[docs] def convert(self, selection): """ converts selection from version 2 to 1 :param selection: selection dictionary object :type selection: :obj:`dict` <:obj:`str`, `any`> """ super(Converter2to1, self).convert(selection) if "ChannelProperties" in selection: props = json.loads(selection["ChannelProperties"]) for var, pn in self.pnames.items(): if pn in props: selection[var] = json.dumps(props.pop(pn)) selection.pop("ChannelProperties") if "Version" in selection: selection.pop("Version")
[docs]class Converter(object): """ selection version converter """ def __init__(self, ver): """ contstructor :param ver: the required selection version :type ver: :obj:`str` """ sver = ver.split(".") #: (:obj:`int`) major selection version self.majorversion = int(sver[0]) #: (:obj:`int`) minor selection version self.minorversion = int(sver[1]) #: (:obj:`int`) patch selection version self.patchversion = int(sver[2]) #: (:obj:`list` <:class:`ConverterXtoY`>) converter up sequence self.up = [Converter1to2(), Converter2to3()] #: (:obj:`list` <:class:`ConverterXtoY`>) converter down sequence self.down = [Converter2to1(), Converter3to2()]
[docs] def allkeys(self, selection): """ :param selection: selection dictionary object :type selection: nxsrecconfig.Selection.Selection :returns: selection keys :rtype: :obj:`set` """ lkeys = set() for cv in self.up: lkeys.update(set(cv.names.keys())) lkeys.update(set(cv.names.values())) ak = set(selection.keys()) ak.update(lkeys) return ak
[docs] def convert(self, selection): """ converts selection from any version to any other :param selection: selection dictionary object :type selection: :obj:`dict` <:obj:`str`, `any`> """ major, _, _ = self.version(selection) if major == self.majorversion: return if major < self.majorversion: for i in range(major - 1, self.majorversion - 1): self.up[i].convert(selection) elif major > self.majorversion: for i in range(major - 2, self.majorversion - 2, -1): self.down[i].convert(selection) selection["Version"] = "%s.%s.%s" % ( self.majorversion, self.minorversion, self.patchversion)
[docs] @classmethod def version(cls, selection): """ fetches selection version and converts it into (major, minor, patch) :param selection: selection dictionary object :type selection: nxsrecconfig.Selection.Selection :returns: (major, minor, patch) tuple with integers :rtype: (:obj:`int` , :obj:`int` , :obj:`int`) """ major = 1 minor = 0 patch = 0 if 'Version' in selection: ver = selection['Version'] sver = ver.split(".") major = int(sver[0]) minor = int(sver[1]) patch = int(sver[2]) return major, minor, patch