From ff40cfc06ecc82b5adbaed11d9c00c6f761b444d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Avil=C3=A9s?= Date: Mon, 27 Oct 2014 11:33:16 +0100 Subject: [PATCH] Add converter-related code --- importer/indico_importer/converter.py | 91 +++++++++++++++++++++++++++ importer/indico_importer/utils.py | 8 +++ 2 files changed, 99 insertions(+) create mode 100644 importer/indico_importer/converter.py create mode 100644 importer/indico_importer/utils.py diff --git a/importer/indico_importer/converter.py b/importer/indico_importer/converter.py new file mode 100644 index 0000000..ab9a520 --- /dev/null +++ b/importer/indico_importer/converter.py @@ -0,0 +1,91 @@ +class RecordConverter(object): + """ + Converts a dictionary or list of dictionaries into another list of dictionaries. The goal + is to alter data fetched from connector class into a format that can be easily read by importer + plugin. The way dictionaries are converted depends on the 'conversion' variable. + + conversion = [ (sourceKey, destinationKey, conversionFuncion(optional), converter(optional))... ] + + It's a list tuples in which a single element represents a translation that will be made. Every + element of the list is a tuple that consists of from 1 to 4 entries. + + *** IMPORTANT syntax for a tuple containing a single element is (element, ) NOT (element) !. *** + + The first one is the key name in the source dictionary, the value that applies to this key will + be the subject of the translation. The second is the key in the destination dictionary at which + translated value will be put. If not specified its value will be equal the value of the first + element. If the second element is equal *append* and the converted element is a dictionary or a + list of dictionaries, destination dictionary will be updated by the converted element.Third, + optional, element is the function that will take the value from the source dictionary and return + the value which will be inserted into result dictionary. If the third element is empty + defaultConversionMethod will be called. Fourth, optional, element is a RecordConverter class + which will be executed with converted value as an argument. + """ + + conversion = [] + + @staticmethod + def defaultConversionMethod(attr): + """ + Method that will be used to convert an entry in dictionary unless other method is specified. + """ + return attr + + @classmethod + def convert(cls, record): + """ + Converts a single dictionary or list of dictionaries into converted list of dictionaries. + """ + if isinstance(record, list): + return [cls._convert(r) for r in record] + else: + return [cls._convert(record)] + + @classmethod + def _convertInternal(cls, record): + """ + Converts a single dictionary into converted dictionary or list of dictionaries into converted + list of dictionaries. Used while passing dictionaries to another converter. + """ + if isinstance(record, list): + return [cls._convert(r) for r in record] + else: + return cls._convert(record) + + @classmethod + def _convert(cls, record): + """ + Core method of the converter. Converts a single dictionary into another dictionary. + """ + if record: + convertedDict = {} + for field in cls.conversion: + key = field[0] + if len(field) >= 2 and field[1]: + convertedKey = field[1] + else: + convertedKey = key + if len(field) >= 3 and field[2]: + conversionMethod = field[2] + else: + conversionMethod = cls.defaultConversionMethod + if len(field) >= 4: + converter = field[3] + else: + converter = None + try: + value = conversionMethod(record[key]) + except KeyError: + continue + if converter: + value = converter._convertInternal(value) + if convertedKey == "*append*": + if isinstance(value, list): + for v in value: + convertedDict.update(v) + else: + convertedDict.update(value) + else: + convertedDict[convertedKey] = value + return convertedDict + return {} diff --git a/importer/indico_importer/utils.py b/importer/indico_importer/utils.py new file mode 100644 index 0000000..20ca701 --- /dev/null +++ b/importer/indico_importer/utils.py @@ -0,0 +1,8 @@ +def parse_datetime(string): + split_datetime = string[0].split('T') + if len(split_datetime) > 1: + return {'date': string[0].split('T')[0], + 'time': string[0].split('T')[1]} + else: + return {'date': string[0].split('T')[0], + 'time': '00:00'}