chiark / gitweb /
Put plugin code into a different file, split from profile. Also use a nice class...
authordaid <daid303@gmail.com>
Wed, 12 Feb 2014 13:51:32 +0000 (14:51 +0100)
committerdaid <daid303@gmail.com>
Wed, 12 Feb 2014 13:51:32 +0000 (14:51 +0100)
Cura/gui/pluginPanel.py
Cura/gui/printWindow2.py
Cura/util/plugin.py [new file with mode: 0644]
Cura/util/profile.py

index 330fcb2632e3e45ab89fd5559724e322fb1d13b3..3478f037e60cf86c26fb8daa84efe6f92ed329fe 100644 (file)
@@ -6,23 +6,24 @@ import webbrowser
 from wx.lib import scrolledpanel
 
 from Cura.util import profile
+from Cura.util import plugin
 from Cura.util import explorer
 
 class pluginPanel(wx.Panel):
        def __init__(self, parent, callback):
                wx.Panel.__init__(self, parent,-1)
                #Plugin page
-               self.pluginList = profile.getPluginList()
+               self.pluginList = plugin.getPluginList("postprocess")
                self.callback = callback
 
                sizer = wx.GridBagSizer(2, 2)
                self.SetSizer(sizer)
 
-               effectStringList = []
-               for effect in self.pluginList:
-                       effectStringList.append(effect['name'])
+               pluginStringList = []
+               for p in self.pluginList:
+                       pluginStringList.append(p.getName())
 
-               self.listbox = wx.ListBox(self, -1, choices=effectStringList)
+               self.listbox = wx.ListBox(self, -1, choices=pluginStringList)
                title = wx.StaticText(self, -1, _("Plugins:"))
                title.SetFont(wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD))
                helpButton = wx.Button(self, -1, '?', style=wx.BU_EXACTFIT)
@@ -58,7 +59,7 @@ class pluginPanel(wx.Panel):
                self.updateProfileToControls()
 
        def updateProfileToControls(self):
-               self.pluginConfig = profile.getPluginConfig()
+               self.pluginConfig = plugin.getPostProcessPluginConfig()
                for p in self.panelList:
                        p.Show(False)
                        self.pluginEnabledPanel.GetSizer().Detach(p)
@@ -69,7 +70,7 @@ class pluginPanel(wx.Panel):
        def _buildPluginPanel(self, pluginConfig):
                plugin = None
                for pluginTest in self.pluginList:
-                       if pluginTest['filename'] == pluginConfig['filename']:
+                       if pluginTest.getFilename() == pluginConfig['filename']:
                                plugin = pluginTest
                if plugin is None:
                        return False
@@ -77,7 +78,7 @@ class pluginPanel(wx.Panel):
                pluginPanel = wx.Panel(self.pluginEnabledPanel)
                s = wx.GridBagSizer(2, 2)
                pluginPanel.SetSizer(s)
-               title = wx.StaticText(pluginPanel, -1, plugin['name'])
+               title = wx.StaticText(pluginPanel, -1, plugin.getName())
                title.SetFont(wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD))
                remButton = wx.Button(pluginPanel, -1, 'X', style=wx.BU_EXACTFIT)
                helpButton = wx.Button(pluginPanel, -1, '?', style=wx.BU_EXACTFIT)
@@ -85,13 +86,13 @@ class pluginPanel(wx.Panel):
                s.Add(helpButton, pos=(0,0), span=(1,1), flag=wx.TOP|wx.LEFT|wx.ALIGN_RIGHT, border=5)
                s.Add(remButton, pos=(0,3), span=(1,1), flag=wx.TOP|wx.RIGHT|wx.ALIGN_RIGHT, border=5)
                s.Add(wx.StaticLine(pluginPanel), pos=(1,0), span=(1,4), flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=3)
-               info = wx.StaticText(pluginPanel, -1, plugin['info'])
+               info = wx.StaticText(pluginPanel, -1, plugin.getInfo())
                info.Wrap(300)
                s.Add(info, pos=(2,0), span=(1,4), flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=3)
 
                pluginPanel.paramCtrls = {}
                i = 0
-               for param in plugin['params']:
+               for param in plugin.getParams():
                        value = param['default']
                        if param['name'] in pluginConfig['params']:
                                value = pluginConfig['params'][param['name']]
@@ -125,19 +126,19 @@ class pluginPanel(wx.Panel):
                        idx = self.panelList.index(panel)
                        for k in panel.paramCtrls.keys():
                                self.pluginConfig[idx]['params'][k] = panel.paramCtrls[k].GetValue()
-               profile.setPluginConfig(self.pluginConfig)
+               plugin.setPostProcessPluginConfig(self.pluginConfig)
                self.callback()
 
        def OnAdd(self, e):
                if self.listbox.GetSelection() < 0:
                        wx.MessageBox(_("You need to select a plugin before you can add anything."), _("Error: no plugin selected"), wx.OK | wx.ICON_INFORMATION)
                        return
-               plugin = self.pluginList[self.listbox.GetSelection()]
-               newConfig = {'filename': plugin['filename'], 'params': {}}
+               p = self.pluginList[self.listbox.GetSelection()]
+               newConfig = {'filename': p.getFilename(), 'params': {}}
                if not self._buildPluginPanel(newConfig):
                        return
                self.pluginConfig.append(newConfig)
-               profile.setPluginConfig(self.pluginConfig)
+               plugin.setPostProcessPluginConfig(self.pluginConfig)
                self.callback()
 
        def OnRem(self, e):
@@ -157,12 +158,11 @@ class pluginPanel(wx.Panel):
                self.Layout()
 
                self.pluginConfig.pop(idx)
-               profile.setPluginConfig(self.pluginConfig)
+               plugin.setPostProcessPluginConfig(self.pluginConfig)
                self.callback()
 
        def OnHelp(self, e):
                panel = e.GetEventObject().GetParent()
-               sizer = self.pluginEnabledPanel.GetSizer()
                idx = self.panelList.index(panel)
 
                fname = self.pluginConfig[idx]['filename'].lower()
@@ -174,6 +174,6 @@ class pluginPanel(wx.Panel):
                webbrowser.open('http://wiki.ultimaker.com/Category:CuraPlugin')
 
        def OnOpenPluginLocation(self, e):
-               if not os.path.exists(profile.getPluginBasePaths()[0]):
-                       os.mkdir(profile.getPluginBasePaths()[0])
-               explorer.openExplorerPath(profile.getPluginBasePaths()[0])
+               if not os.path.exists(plugin.getPluginBasePaths()[0]):
+                       os.mkdir(plugin.getPluginBasePaths()[0])
+               explorer.openExplorerPath(plugin.getPluginBasePaths()[0])
index b5ce553d3c2fbebcf150f875d32a642c266bbc97..df8a7e3cb3ce941358497c5e17add5ebfe5f1103 100644 (file)
@@ -78,7 +78,7 @@ class printWindowPlugin(wx.Frame):
        def script_setImage(self, guiImage, mapImage):
                self._backgroundImage = wx.BitmapFromImage(wx.Image(os.path.join(self._basePath, guiImage)))
                self._mapImage = wx.Image(os.path.join(self._basePath, mapImage))
-               self.SetClientSize(self._backgroundImage.GetSize())
+               self.SetClientSize(self._mapImage.GetSize())
 
        def script_addColorCommand(self, r, g, b, command, data = None):
                self._colorCommandMap[(r, g, b)] = (command, data)
diff --git a/Cura/util/plugin.py b/Cura/util/plugin.py
new file mode 100644 (file)
index 0000000..382c62e
--- /dev/null
@@ -0,0 +1,147 @@
+"""
+The plugin module contains information about the plugins found for Cura.
+It keeps track of a list of installed plugins and the information contained within.
+"""
+__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
+
+import os
+import sys
+import traceback
+import platform
+import glob
+import re
+import cPickle as pickle
+
+from Cura.util import profile
+from Cura.util import resources
+
+_pluginList = None
+
+class pluginInfo(object):
+       def __init__(self, dirname, filename):
+               self._dirname = dirname
+               self._filename = filename
+               self._name = os.path.splitext(os.path.basename(filename))[0]
+               self._type = 'unknown'
+               self._info = ''
+               self._params = []
+               with open(os.path.join(dirname, filename), "r") as f:
+                       for line in f:
+                               line = line.strip()
+                               if not line.startswith('#'):
+                                       break
+                               line = line[1:].split(':', 1)
+                               if len(line) != 2:
+                                       continue
+                               if line[0].upper() == 'NAME':
+                                       self._name = line[1].strip()
+                               elif line[0].upper() == 'INFO':
+                                       self._info = line[1].strip()
+                               elif line[0].upper() == 'TYPE':
+                                       self._type = line[1].strip()
+                               elif line[0].upper() == 'DEPEND':
+                                       pass
+                               elif line[0].upper() == 'PARAM':
+                                       m = re.match('([a-zA-Z][a-zA-Z0-9_]*)\(([a-zA-Z_]*)(?::([^\)]*))?\) +(.*)', line[1].strip())
+                                       if m is not None:
+                                               self._params.append({'name': m.group(1), 'type': m.group(2), 'default': m.group(3), 'description': m.group(4)})
+                               # else:
+                               #       print "Unknown item in plugin meta data: %s %s" % (line[0], line[1])
+
+       def getFilename(self):
+               return self._filename
+
+       def getFullFilename(self):
+               return os.path.join(self._dirname, self._filename)
+
+       def getType(self):
+               return self._type
+
+       def getName(self):
+               return self._name
+
+       def getInfo(self):
+               return self._info
+
+       def getParams(self):
+               return self._params
+
+def getPostProcessPluginConfig():
+       try:
+               return pickle.loads(str(profile.getProfileSetting('plugin_config')))
+       except:
+               return []
+
+def setPostProcessPluginConfig(config):
+       profile.putProfileSetting('plugin_config', pickle.dumps(config))
+
+def getPluginBasePaths():
+       ret = []
+       if platform.system() != "Windows":
+               ret.append(os.path.expanduser('~/.cura/plugins/'))
+       if platform.system() == "Darwin" and hasattr(sys, 'frozen'):
+               ret.append(os.path.normpath(os.path.join(resources.resourceBasePath, "plugins")))
+       else:
+               ret.append(os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'plugins')))
+       return ret
+
+def getPluginList(pluginType):
+       global _pluginList
+       if _pluginList is None:
+               _pluginList = []
+               for basePath in getPluginBasePaths():
+                       for filename in os.listdir(basePath):
+                               if filename.startswith('.'):
+                                       continue
+                               if filename.startswith('_'):
+                                       continue
+                               if os.path.isdir(os.path.join(basePath, filename)):
+                                       if os.path.exists(os.path.join(basePath, filename, 'script.py')):
+                                               _pluginList.append(pluginInfo(basePath, os.path.join(filename, 'script.py')))
+                               elif filename.endswith('.py'):
+                                       _pluginList.append(pluginInfo(basePath, filename))
+       ret = []
+       for plugin in _pluginList:
+               if plugin.getType() == pluginType:
+                       ret.append(plugin)
+       return ret
+
+def runPostProcessingPlugins(engineResult):
+       pluginConfigList = getPostProcessPluginConfig()
+       pluginList = getPluginList()
+
+       for pluginConfig in pluginConfigList:
+               plugin = None
+               for pluginTest in pluginList:
+                       if pluginTest['filename'] == pluginConfig['filename']:
+                               plugin = pluginTest
+               if plugin is None:
+                       continue
+
+               pythonFile = None
+               for basePath in getPluginBasePaths():
+                       testFilename = os.path.join(basePath, pluginConfig['filename'])
+                       if os.path.isfile(testFilename):
+                               pythonFile = testFilename
+               if pythonFile is None:
+                       continue
+
+               locals = {'filename': gcodefilename}
+               for param in plugin['params']:
+                       value = param['default']
+                       if param['name'] in pluginConfig['params']:
+                               value = pluginConfig['params'][param['name']]
+
+                       if param['type'] == 'float':
+                               try:
+                                       value = float(value)
+                               except:
+                                       value = float(param['default'])
+
+                       locals[param['name']] = value
+               try:
+                       execfile(pythonFile, locals)
+               except:
+                       locationInfo = traceback.extract_tb(sys.exc_info()[2])[-1]
+                       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])
+       return None
index dbc8b7aabc4b2bf4f03a951d73f89723739e2b68..b63a04eba3efab4542b8954ed626cd163471259f 100644 (file)
@@ -5,7 +5,19 @@ These settings can be globally accessed and modified.
 from __future__ import division
 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
 
-import os, traceback, math, re, zlib, base64, time, sys, platform, glob, string, stat, types
+import os
+import traceback
+import math
+import re
+import zlib
+import base64
+import time
+import sys
+import platform
+import glob
+import string
+import stat
+import types
 import cPickle as pickle
 import numpy
 if sys.version_info[0] < 3:
@@ -13,7 +25,6 @@ if sys.version_info[0] < 3:
 else:
        import configparser as ConfigParser
 
-from Cura.util import resources
 from Cura.util import version
 from Cura.util import validators
 
@@ -1042,98 +1053,3 @@ def getAlterationFileContents(filename, extruderCount = 1):
                #Append the profile string to the end of the GCode, so we can load it from the GCode file later.
                postfix = ';CURA_PROFILE_STRING:%s\n' % (getProfileString())
        return unicode(prefix + re.sub("(.)\{([^\}]*)\}", replaceTagMatch, alterationContents).rstrip() + '\n' + postfix).strip().encode('utf-8') + '\n'
-
-###### PLUGIN #####
-
-def getPluginConfig():
-       try:
-               return pickle.loads(str(getProfileSetting('plugin_config')))
-       except:
-               return []
-
-def setPluginConfig(config):
-       putProfileSetting('plugin_config', pickle.dumps(config))
-
-def getPluginBasePaths():
-       ret = []
-       if platform.system() != "Windows":
-               ret.append(os.path.expanduser('~/.cura/plugins/'))
-       if platform.system() == "Darwin" and hasattr(sys, 'frozen'):
-               ret.append(os.path.normpath(os.path.join(resources.resourceBasePath, "plugins")))
-       else:
-               ret.append(os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'plugins')))
-       return ret
-
-def getPluginList():
-       ret = []
-       for basePath in getPluginBasePaths():
-               for filename in glob.glob(os.path.join(basePath, '*.py')):
-                       filename = os.path.basename(filename)
-                       if filename.startswith('_'):
-                               continue
-                       with open(os.path.join(basePath, filename), "r") as f:
-                               item = {'filename': filename, 'name': None, 'info': None, 'type': None, 'params': []}
-                               for line in f:
-                                       line = line.strip()
-                                       if not line.startswith('#'):
-                                               break
-                                       line = line[1:].split(':', 1)
-                                       if len(line) != 2:
-                                               continue
-                                       if line[0].upper() == 'NAME':
-                                               item['name'] = line[1].strip()
-                                       elif line[0].upper() == 'INFO':
-                                               item['info'] = line[1].strip()
-                                       elif line[0].upper() == 'TYPE':
-                                               item['type'] = line[1].strip()
-                                       elif line[0].upper() == 'DEPEND':
-                                               pass
-                                       elif line[0].upper() == 'PARAM':
-                                               m = re.match('([a-zA-Z][a-zA-Z0-9_]*)\(([a-zA-Z_]*)(?::([^\)]*))?\) +(.*)', line[1].strip())
-                                               if m is not None:
-                                                       item['params'].append({'name': m.group(1), 'type': m.group(2), 'default': m.group(3), 'description': m.group(4)})
-                                       else:
-                                               print "Unknown item in effect meta data: %s %s" % (line[0], line[1])
-                               if item['name'] is not None and item['type'] == 'postprocess':
-                                       ret.append(item)
-       return ret
-
-def runPostProcessingPlugins(gcodefilename):
-       pluginConfigList = getPluginConfig()
-       pluginList = getPluginList()
-
-       for pluginConfig in pluginConfigList:
-               plugin = None
-               for pluginTest in pluginList:
-                       if pluginTest['filename'] == pluginConfig['filename']:
-                               plugin = pluginTest
-               if plugin is None:
-                       continue
-
-               pythonFile = None
-               for basePath in getPluginBasePaths():
-                       testFilename = os.path.join(basePath, pluginConfig['filename'])
-                       if os.path.isfile(testFilename):
-                               pythonFile = testFilename
-               if pythonFile is None:
-                       continue
-
-               locals = {'filename': gcodefilename}
-               for param in plugin['params']:
-                       value = param['default']
-                       if param['name'] in pluginConfig['params']:
-                               value = pluginConfig['params'][param['name']]
-
-                       if param['type'] == 'float':
-                               try:
-                                       value = float(value)
-                               except:
-                                       value = float(param['default'])
-
-                       locals[param['name']] = value
-               try:
-                       execfile(pythonFile, locals)
-               except:
-                       locationInfo = traceback.extract_tb(sys.exc_info()[2])[-1]
-                       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])
-       return None