2 The plugin module contains information about the plugins found for Cura.
3 It keeps track of a list of installed plugins and the information contained within.
5 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
14 import cPickle as pickle
16 from Cura.util import profile
17 from Cura.util import resources
21 class pluginInfo(object):
23 Plugin information object. Used to keep track of information about the available plugins in this installation of Cura.
24 Each plugin as meta-data associated with it which can be retrieved from this class.
26 def __init__(self, dirname, filename):
27 self._dirname = dirname
28 self._filename = filename
29 self._name = os.path.splitext(os.path.basename(filename))[0]
30 self._type = 'unknown'
33 with open(os.path.join(dirname, filename), "r") as f:
36 if not line.startswith('#'):
38 line = line[1:].split(':', 1)
41 if line[0].upper() == 'NAME':
42 self._name = line[1].strip()
43 elif line[0].upper() == 'INFO':
44 self._info = line[1].strip()
45 elif line[0].upper() == 'TYPE':
46 self._type = line[1].strip()
47 elif line[0].upper() == 'DEPEND':
49 elif line[0].upper() == 'PARAM':
50 m = re.match('([a-zA-Z][a-zA-Z0-9_]*)\(([a-zA-Z_]*)(?::([^\)]*))?\) +(.*)', line[1].strip())
52 self._params.append({'name': m.group(1), 'type': m.group(2), 'default': m.group(3), 'description': m.group(4)})
54 # print "Unknown item in plugin meta data: %s %s" % (line[0], line[1])
56 self._readSettings(os.path.join(profile.getBasePath()))
57 for plugindir in getPluginBasePaths():
58 self._readSettings(plugindir)
60 def _readSettings(self, indir):
61 settings_file = os.path.join(indir, 'plugin_defaults.ini')
62 plugin_basename = re.sub(r'\.pyc?','',os.path.basename(self._filename))
63 if not os.path.exists(settings_file):
65 cfg = ConfigParser.ConfigParser()
67 cfg.read(settings_file)
70 if not cfg.has_section(plugin_basename):
72 for param in self._params:
74 if cfg.has_option(plugin_basename, name):
75 param['default'] = cfg.get(plugin_basename, name)
77 def getFilename(self):
80 def getFullFilename(self):
81 return os.path.join(self._dirname, self._filename)
95 def getPostProcessPluginConfig():
97 return pickle.loads(str(profile.getProfileSetting('plugin_config')))
101 def setPostProcessPluginConfig(config):
102 profile.putProfileSetting('plugin_config', pickle.dumps(config))
104 def overridePostProcessPluginConfig(config):
105 profile.setTempOverride('plugin_config', pickle.dumps(config))
107 def getPluginBasePaths():
109 if platform.system() != "Windows":
110 ret.append(os.path.expanduser('~/.cura/plugins/'))
111 if platform.system() == "Darwin" and hasattr(sys, 'frozen'):
112 ret.append(os.path.normpath(os.path.join(resources.resourceBasePath, "plugins")))
114 ret.append(os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'plugins')))
117 def getPluginList(pluginType):
119 if _pluginList is None:
121 for basePath in getPluginBasePaths():
122 if os.path.isdir(basePath):
123 for filename in os.listdir(basePath):
124 if filename.startswith('.'):
126 if filename.startswith('_'):
128 if os.path.isdir(os.path.join(basePath, filename)):
129 if os.path.exists(os.path.join(basePath, filename, 'script.py')):
130 _pluginList.append(pluginInfo(basePath, os.path.join(filename, 'script.py')))
131 elif filename.endswith('.py'):
132 _pluginList.append(pluginInfo(basePath, filename))
134 for plugin in _pluginList:
135 if plugin.getType() == pluginType:
139 def runPostProcessingPlugins(engineResult, pluginConfigList):
140 pluginList = getPluginList('postprocess')
143 for pluginConfig in pluginConfigList:
145 for pluginTest in pluginList:
146 if pluginTest.getFilename() == pluginConfig['filename']:
151 pythonFile = plugin.getFullFilename()
153 if tempfilename is None:
154 f = tempfile.NamedTemporaryFile(prefix='CuraPluginTemp', delete=False)
155 tempfilename = f.name
156 gcode = engineResult.getGCode()
158 data = gcode.read(16 * 1024)
165 locals = {'filename': tempfilename}
166 for param in plugin.getParams():
167 value = param['default']
168 if param['name'] in pluginConfig['params']:
169 value = pluginConfig['params'][param['name']]
171 if param['type'] == 'float':
175 value = float(param['default'])
177 locals[param['name']] = value
179 execfile(pythonFile, locals)
181 traceback.print_exc()
182 locationInfo = traceback.extract_tb(sys.exc_info()[2])[-1]
183 return "%s: '%s' @ %s:%s:%d" % (str(sys.exc_info()[0].__name__), str(sys.exc_info()[1]), os.path.basename(locationInfo[0]), locationInfo[2], locationInfo[1])
184 if tempfilename is not None:
185 f = open(tempfilename, "r")
186 engineResult.setGCode("")
191 engineResult._gcodeData.write(data)
194 os.unlink(tempfilename)