1"""
2Core Module for Web Base Data Generation
3"""
4
5import sys, os, json
6
7from vtk.web import iteritems
8
9class DataHandler(object):
10    def __init__(self, basePath):
11        self.__root = basePath
12        self.types = ["tonic-query-data-model"]
13        self.metadata = {}
14        self.data = {}
15        self.arguments = {}
16        self.current = {}
17        self.sections = {}
18        self.basePattern = None
19        self.priority = []
20        self.argOrder = []
21        self.realValues = {}
22        self.can_write = True
23
24    def getBasePath(self):
25        return self.__root
26
27    def updateBasePattern(self):
28        self.priority.sort(key=lambda item: item[1])
29        self.basePattern = ''
30        patternSeparator = ''
31        currentPriority = -1
32
33        for item in self.priority:
34            if currentPriority != -1:
35                if currentPriority == item[1]:
36                    patternSeparator = '_'
37                else:
38                    patternSeparator = '/'
39            currentPriority = item[1]
40            self.basePattern = '{%s}%s%s' % (item[0], patternSeparator, self.basePattern)
41
42    def registerArgument(self, **kwargs):
43        """
44        We expect the following set of arguments
45         - priority
46         - name
47         - label (optional)
48         - values
49         - uiType
50         - defaultIdx
51        """
52        newArgument = {}
53        argName = kwargs['name']
54        self.argOrder.append(argName)
55        for key, value in iteritems(kwargs):
56            if key == 'priority':
57                self.priority.append([argName, value])
58            elif key == 'values':
59                self.realValues[argName] = value
60                newArgument[key] = [ "{value}".format(value=x) for x in value ]
61            else:
62                newArgument[key] = value
63
64        self.arguments[argName] = newArgument
65
66    def updatePriority(self, argumentName, newPriority):
67        for item in self.priority:
68            if item[0] == argumentName:
69                item[1] = newPriority
70
71    def setArguments(self, **kwargs):
72        """
73        Update the arguments index
74        """
75        for key, value in iteritems(kwargs):
76            self.current[key] = value
77
78    def removeData(self, name):
79        del self.data[name]
80
81    def registerData(self, **kwargs):
82        """
83        name, type, mimeType, fileName, dependencies
84        """
85        newData = { 'metadata': {} }
86        argName = kwargs['name']
87        for key, value in iteritems(kwargs):
88            if key == 'fileName':
89                if 'rootFile' in kwargs and kwargs['rootFile']:
90                    newData['pattern'] = '{pattern}/%s' % value
91                else:
92                    newData['pattern'] = '{pattern}%s' % value
93            else:
94                newData[key] = value
95
96        self.data[argName] = newData
97
98    def addDataMetaData(self, name, key, value):
99        self.data[name]['metadata'][key] = value
100
101    def getDataAbsoluteFilePath(self, name, createDirectories=True):
102        dataPattern = self.data[name]['pattern']
103        if '{pattern}' in dataPattern:
104            if len(self.basePattern) == 0:
105                dataPattern = dataPattern.replace('{pattern}/', self.basePattern).replace('{pattern}', self.basePattern)
106                self.data[name]['pattern'] = dataPattern
107            else:
108                dataPattern = dataPattern.replace('{pattern}', self.basePattern)
109                self.data[name]['pattern'] = dataPattern
110
111        keyValuePair = {}
112        for key, value in iteritems(self.current):
113            keyValuePair[key] = self.arguments[key]['values'][value]
114
115        fullpath = os.path.join(self.__root, dataPattern.format(**keyValuePair))
116
117        if createDirectories and self.can_write:
118            if not os.path.exists(os.path.dirname(fullpath)):
119                os.makedirs(os.path.dirname(fullpath))
120
121        return fullpath
122
123    def addTypes(self, *args):
124        for arg in args:
125            self.types.append(arg)
126
127    def addMetaData(self, key, value):
128        self.metadata[key] = value
129
130    def addSection(self, key, value):
131        self.sections[key] = value
132
133    def computeDataPatterns(self):
134        if self.basePattern == None:
135            self.updateBasePattern()
136
137        for name in self.data:
138            dataPattern = self.data[name]['pattern']
139            if '{pattern}' in dataPattern:
140                dataPattern = dataPattern.replace('{pattern}', self.basePattern)
141                self.data[name]['pattern'] = dataPattern
142
143    def __getattr__(self, name):
144        if self.basePattern == None:
145            self.updateBasePattern()
146
147        for i in range(len(self.arguments[name]['values'])):
148            self.current[name] = i
149            yield self.realValues[name][i]
150
151    def writeDataDescriptor(self):
152        if not self.can_write:
153            return
154
155        self.computeDataPatterns()
156
157        jsonData = {
158            "arguments_order" : self.argOrder,
159            "type"            : self.types,
160            "arguments"       : self.arguments,
161            "metadata"        : self.metadata,
162            "data"            : []
163        }
164
165        # Add sections
166        for key, value in iteritems(self.sections):
167            jsonData[key] = value
168
169        # Add data
170        for key, value in iteritems(self.data):
171            jsonData['data'].append(value)
172
173        filePathToWrite = os.path.join(self.__root, "index.json")
174        with open(filePathToWrite, "w") as fileToWrite:
175            fileToWrite.write(json.dumps(jsonData))
176