chiark / gitweb /
95886edefcc315693580eec6c3cb4708e57a7319
[cura.git] / Cura / fabmetheus_utilities / fabmetheus_tools / interpret_plugins / csv.py
1 """
2 This page is in the table of contents.
3 The csv.py script is an import translator plugin to get a carving from an csv file.
4
5 An import plugin is a script in the interpret_plugins folder which has the function getCarving.  It is meant to be run from the interpret tool.  To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.
6
7 The getCarving function takes the file name of an csv file and returns the carving.
8
9 """
10
11
12 from __future__ import absolute_import
13 #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module.
14 import __init__
15
16 from fabmetheus_utilities import archive
17 from fabmetheus_utilities import gcodec
18 from fabmetheus_utilities import xml_simple_reader
19 import sys
20
21
22 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
23 __credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
24 __date__ = '$Date: 2008/21/04 $'
25 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
26
27
28 def getCarving(fileName=''):
29         "Get the carving for the csv file."
30         csvText = archive.getFileText(fileName)
31         if csvText == '':
32                 return None
33         csvParser = CSVSimpleParser( fileName, None, csvText )
34         lowerLocalName = csvParser.getDocumentElement().getNodeName().lower()
35         pluginModule = archive.getModuleWithDirectoryPath( getPluginsDirectoryPath(), lowerLocalName )
36         if pluginModule == None:
37                 return None
38         return pluginModule.getCarvingFromParser( csvParser )
39
40 def getLineDictionary(line):
41         "Get the line dictionary."
42         lineDictionary = {}
43         splitLine = line.split('\t')
44         for splitLineIndex in xrange( len(splitLine) ):
45                 word = splitLine[ splitLineIndex ]
46                 if word != '':
47                         lineDictionary[ splitLineIndex ] = word
48         return lineDictionary
49
50 def getPluginsDirectoryPath():
51         "Get the plugins directory path."
52         return archive.getInterpretPluginsPath('xml_plugins')
53
54
55 class CSVElement( xml_simple_reader.XMLElement ):
56         "A csv element."
57         def continueParsingObject( self, line, lineStripped ):
58                 "Parse replaced line."
59                 splitLineStripped = lineStripped.split('\t')
60                 key = splitLineStripped[0]
61                 value = splitLineStripped[1]
62                 self.attributes[key] = value
63                 self.addToIdentifierDictionaries()
64
65         def continueParsingTable( self, line, lineStripped ):
66                 "Parse replaced line."
67                 if self.headingDictionary == None:
68                         self.headingDictionary = getLineDictionary(line)
69                         return
70                 csvElement = self
71                 oldAttributesLength = len( self.attributes )
72                 if oldAttributesLength > 0:
73                         csvElement = CSVElement()
74                 csvElement.parentNode = self.parentNode
75                 csvElement.localName = self.localName
76                 lineDictionary = getLineDictionary(line)
77                 for columnIndex in lineDictionary.keys():
78                         if columnIndex in self.headingDictionary:
79                                 key = self.headingDictionary[ columnIndex ]
80                                 value = lineDictionary[ columnIndex ]
81                                 csvElement.attributes[key] = value
82                 csvElement.addToIdentifierDictionaries()
83                 if len( csvElement.attributes ) == 0 or oldAttributesLength == 0 or self.parentNode == None:
84                         return
85                 self.parentNode.childNodes.append( csvElement )
86
87         def getElementFromObject( self, leadingTabCount, lineStripped, oldElement ):
88                 "Parse replaced line."
89                 splitLine = lineStripped.split('\t')
90                 self.localName = splitLine[1]
91                 if leadingTabCount == 0:
92                         return self
93                 self.parentNode = oldElement
94                 while leadingTabCount <= self.parentNode.getNumberOfParents():
95                         self.parentNode = self.parentNode.parentNode
96                 self.parentNode.childNodes.append(self)
97                 return self
98
99         def getElementFromTable( self, leadingTabCount, lineStripped, oldElement ):
100                 "Parse replaced line."
101                 self.headingDictionary = None
102                 return self.getElementFromObject( leadingTabCount, lineStripped, oldElement )
103
104         def getNumberOfParents(self):
105                 "Get the number of parent nodes."
106                 if self.parentNode == None:
107                         return 0
108                 return self.parentNode.getNumberOfParents() + 1
109
110
111 class CSVSimpleParser( xml_simple_reader.DocumentNode ):
112         "A simple csv parser."
113         def __init__( self, parentNode, csvText ):
114                 "Add empty lists."
115                 self.continueFunction = None
116                 self.extraLeadingTabCount = None
117                 self.lines = archive.getTextLines( csvText )
118                 self.oldCSVElement = None
119                 self.documentElement = None
120                 for line in self.lines:
121                         self.parseLine(line)
122
123         def getNewCSVElement( self, leadingTabCount, lineStripped ):
124                 "Get a new csv element."
125                 if self.documentElement != None and self.extraLeadingTabCount == None:
126                         self.extraLeadingTabCount = 1 - leadingTabCount
127                 if self.extraLeadingTabCount != None:
128                         leadingTabCount += self.extraLeadingTabCount
129                 if lineStripped[ : len('_table') ] == '_table' or lineStripped[ : len('_t') ] == '_t':
130                         self.oldCSVElement = CSVElement().getElementFromTable( leadingTabCount, lineStripped, self.oldCSVElement )
131                         self.continueFunction = self.oldCSVElement.continueParsingTable
132                         return
133                 self.oldCSVElement = CSVElement().getElementFromObject( leadingTabCount, lineStripped, self.oldCSVElement )
134                 self.continueFunction = self.oldCSVElement.continueParsingObject
135
136         def parseLine(self, line):
137                 "Parse a gcode line and add it to the inset skein."
138                 lineStripped = line.lstrip()
139                 if len( lineStripped ) < 1:
140                         return
141                 leadingPart = line[ : line.find( lineStripped ) ]
142                 leadingTabCount = leadingPart.count('\t')
143                 if lineStripped[ : len('_') ] == '_':
144                         self.getNewCSVElement( leadingTabCount, lineStripped )
145                         if self.documentElement == None:
146                                 self.documentElement = self.oldCSVElement
147                                 self.documentElement.document = self
148                         return
149                 if self.continueFunction != None:
150                         self.continueFunction( line, lineStripped )
151
152
153 def main():
154         "Display the inset dialog."
155         if len(sys.argv) > 1:
156                 getCarving(' '.join(sys.argv[1 :]))
157
158 if __name__ == "__main__":
159         main()