web.pluginmanager.plugins.pluginbase

Package web :: Package pluginmanager :: Package plugins :: Module pluginbase |
[hide private]
[frames] | no frames]

# Source Code for Module web.pluginmanager.plugins.pluginbase

      1  '''
      2  Plugin base module
      3  '''
      4
      5  import os
      6  import sys
      7  import re
      8  import web
      9  import codecs
     10  import config
     11  import ConfigParser
     12  from action import Action
     13  from dependency import Dependency, Version
     14
     15  DEP = re.compile(r'^(?P<pname>\w+)\s*\((?P<operator>\>=|\>|=|\<=|\<)(?P<major>.*)\.(?P<minor>.*)\.(?P<release>.*)\)\s*$')
     16
     17
     18 -class PluginBase(object):
     19      '''
     20      Plugin base class. Each plugin should inherit from this class.
     21
     22      Variables documentation:
     23
     24      urls: This variable is a tuple of pairs in the form "url-regexp, view" as in web.py
     25      applications, but for this plugin only.
     26      '''
     27
     28      ################################
     29      ### FIXME Parse errors are not captured
     30      ###############################
     31 -    def __init__(self):
     32          self.name = 'nonamed'
     33          self.human_name = 'nonamed'
     34          self.author = 'anonymous'
     35          self.description = 'nodescription'
     36          self._version = 'noversion'
     37          self.enabled = False
     38          self.urls = []
     39          self._dependencies = []
     40          self.actions = {}
     41
     42 -    def get_dependencies(self):
     43          '''
     44          Returns the depencies list.
     45          '''
     46          return self._dependencies
     47
     48 -    def set_dependencies(self, depstr):
     49          '''
     50          Generates the dependencies given a string.
     51          It's necesary for parsing the configuration file.
     52          '''
     53          deps = map(str.strip, depstr.split(','))
     54          for dep in deps:
     55              match = DEP.match(dep)
     56              print dep
     57              print match
     58              pname, operator, major, minor, release = match.groups()
     59              dep = Dependency(pname, operator, major, minor, release)
     60              self._dependencies.append(dep)
     61
     62      depend = property(get_dependencies, set_dependencies)
     63
     64 -    def get_version(self):
     65          '''
     66          Returns the version.
     67          '''
     68          return self._version
     69
     70 -    def set_version(self, verstr):
     71          '''
     72          Generates the version given a string.
     73          It's necesary for parsing the configuration file.
     74          '''
     75          major, minor, release = verstr.split('.')
     76          self._version = Version(major, minor, release)
     77
     78      version = property(get_version, set_version)
     79
     80 -    def is_enabled(self):
     81          '''
     82          Returns if the plugin is enabled in exection time.
     83          '''
     84          return self.enabled
     85
     86 -    def read_config(self, name):
     87          '''
     88          Parses plugin conf file and sets all values as object
     89          attributes.
     90          '''
     91
     92          path = os.path.join(config.pluginsdir, name, 'plugin.conf')
     93          self.read_config_path(path)
     94
     95 -    def read_config_path(self, path):
     96          '''
     97          Given a path, it generates the initial configuration of a plugin.
     98          '''
     99          parser = ConfigParser.ConfigParser()
    100          parser.readfp(codecs.open(path, 'r', sys.getfilesystemencoding(), errors="ignore"))
    101
    102          # reading plugin config
    103          for k, v in  parser.items('plugin'):
    104              setattr(self, k, v)
    105
    106          # reading actions config
    107          actions = [i for i in parser.sections() if i.startswith('action/')]
    108          for a in actions:
    109              action = Action(self)
    110              for k, v in parser.items(a):
    111                  if k == "appear_in_main_panel":
    112                      v = parser.getboolean(a, k)
    113
    114                  setattr(action, k, v)
    115
    116              self.actions[action.name] = action
    117
    118 -    def get_actions(self):
    119          '''
    120          Returns the actions.
    121          '''
    122          return self.actions.values()
    123
    124 -    def get_main_panel_actions(self):
    125          '''
    126          Returns the actions which appears in the main panel
    127          '''
    128          return (a for a in self.actions.values() if a.appear_in_main_panel)
    129
    130
    131 -    def enable(self):
    132          '''
    133          This function initialize the plugin in such a way that it can used.
    134          It will be called in two cases:
    135          1.  When the plugin is disabled and it's going to be enabled by the
    136              admins of the aplication. In this case the install function will
    137              also be called if the plugin has not previously been
    138              installed.
    139          2.  Once the plugin is already enabled and installed the pluginmanager
    140              will instanciate the plugin and then will call this enable
    141              function. This is because the enable function will always before
    142              the plugin can be used.
    143
    144          You can reimplement this function if you want to execute custom
    145          actions when your plugin is going to be used.
    146          '''
    147          pass
    148
    149 -    def disable(self):
    150          '''
    151          This function will be called when the plugin is enabled and it's
    152          going to be disabled by the admins of the aplication. It is called only
    153          by the pluginmanager. WARNING: Note that disable will NOT be called
    154          when the application shutdowns. Use __del__ for that.
    155
    156          You can reimplement this function if you want to execute custom
    157          actions when your plugin is going to be disabled.
    158          '''
    159          pass
    160
    161 -    def install(self):
    162          '''
    163          This function will be called when the plugin is enabled the first
    164          time.
    165
    166          You can reimplement this function if you want to install some tables
    167          in the data base, or to do something only once.
    168          '''
    169          pass
    170
    171 -    def uninstall(self):
    172          '''
    173          This function will be called when the user wants to delete the plugin
    174          from the system.
    175
    176          You can reimplement this function like a cleanup function. You MUST
    177          erase all data that plugin generated when it's not goint to be used
    178          ever. For example all tables in the data base or data generated in
    179          install function.
    180          '''
    181          pass
    182
    183 -    def _request(self, args, method):
    184          '''
    185          Request a GET or a POST petition to the plugin. Redirects a url to a view inside
    186          the plugin and returns the data that the appropiate view returns. The "method"
    187          argument can be either "GET" or "POST".
    188
    189          This function is ONLY called by PluginView. When a request of type
    190          /plugin/<plugin_name>/<args> is received, PluginView deals with it and acts as a
    191          proxy, calling to this _request function of the plugin called "plugin_name", with
    192          args= "args".
    193
    194          Each plugin deals with GET and POST requests by configuring the self.url tuple of
    195          pairs url-regexp, view, as webpy applications do.
    196          '''
    197
    198          for i in xrange(0, len(self.urls), 2):
    199              path = self.urls[i]
    200              view = self.urls[i+1]
    201              view_instance = view()
    202              match = re.match(path, args)
    203              if not match:
    204                  continue
    205
    206              # Found the match!
    207
    208              if method == "GET":
    209                  return view_instance.GET(*match.groups(), **match.groupdict())
    210              else:
    211                  return view_instance.POST(*match.groups(), **match.groupdict())
    212
    213 -    def get_options(self):
    214          '''
    215          This function has to return a form. This form contains the options
    216          of the plugin that the user can change. If you want options
    217          in your plugin you have to reimplement this function.
    218          Also you will want to reimplement save_options function which is
    219          called when the user submits.
    220
    221          In the other hand if you don't need any options you haven't to do
    222          anything.
    223          '''
    224          return None
    225
    226 -    def save_options(self, inputs):
    227          '''
    228          This function is called when the user filles the form returned
    229          by get_options, which is passed like argument.
    230          It's useful to save the user preferences.
    231          You can reimplement this function.
    232          '''
    233          pass
    234
    235 -    def get_actions_for_ou(self, ou):
    236          '''
    237          When the user navigates the organizative units tree structure it will
    238          a panel with plugins' actions. The navigator view will call this
    239          function for each plugin. You can reimplement this function to
    240          return the actions that you want the user see.
    241
    242          The ou argument is the Organizative Unit that the user is seing.
    243          '''
    244          return []
    245
    246 -    def get_actions_for_computer(self, computer):
    247          '''
    248          The same that get_actions_for_ou but when the user is seing only
    249          a computer.
    250
    251          The computer argument is the Computer that the user is seing.
    252          '''
    253          return []
    254