]> git.ipfire.org Git - collecty.git/blobdiff - src/collecty/plugins/base.py
Create the object table only once and cache it
[collecty.git] / src / collecty / plugins / base.py
index 1a03105eeabbcd97af4ba744a7d19ea13ee356c3..61a4682564e9855ac745ed410fea33562e234a84 100644 (file)
@@ -155,6 +155,9 @@ class Plugin(threading.Thread):
                        now = datetime.datetime.utcnow()
                        try:
                                result = o.collect()
+
+                               if isinstance(result, tuple) or isinstance(result, list):
+                                       result = ":".join(("%s" % e for e in result))
                        except:
                                self.log.warning(_("Unhandled exception in %s.collect()") % o, exc_info=True)
                                continue
@@ -204,21 +207,21 @@ class Plugin(threading.Thread):
 
                        return object
 
-       def get_template(self, template_name):
+       def get_template(self, template_name, object_id):
                for template in self.templates:
                        if not template.name == template_name:
                                continue
 
-                       return template(self)
+                       return template(self, object_id)
 
        def generate_graph(self, template_name, object_id="default", **kwargs):
-               template = self.get_template(template_name)
+               template = self.get_template(template_name, object_id=object_id)
                if not template:
                        raise RuntimeError("Could not find template %s" % template_name)
 
                time_start = time.time()
 
-               graph = template.generate_graph(object_id=object_id, **kwargs)
+               graph = template.generate_graph(**kwargs)
 
                duration = time.time() - time_start
                self.log.debug(_("Generated graph %s in %.1fms") \
@@ -272,7 +275,19 @@ class Object(object):
                """
                        The absolute path to the RRD file of this plugin.
                """
-               return os.path.join(DATABASE_DIR, self.plugin.path, "%s.rrd" % self.id)
+               filename = self._normalise_filename("%s.rrd" % self.id)
+
+               return os.path.join(DATABASE_DIR, self.plugin.path, filename)
+
+       @staticmethod
+       def _normalise_filename(filename):
+               # Convert the filename into ASCII characters only
+               filename = filename.encode("ascii", "ignore")
+
+               # Replace any spaces by dashes
+               filename = filename.replace(" ", "-")
+
+               return filename
 
        ### Basic methods
 
@@ -378,6 +393,16 @@ class GraphTemplate(object):
        # A unique name to identify this graph template.
        name = None
 
+       # Headline of the graph image
+       graph_title = None
+
+       # Vertical label of the graph
+       graph_vertical_label = None
+
+       # Limits
+       lower_limit = None
+       upper_limit = None
+
        # Instructions how to create the graph.
        rrd_graph = None
 
@@ -396,9 +421,15 @@ class GraphTemplate(object):
        height = GRAPH_DEFAULT_HEIGHT
        width  = GRAPH_DEFAULT_WIDTH
 
-       def __init__(self, plugin):
+       def __init__(self, plugin, object_id):
                self.plugin = plugin
 
+               # Get all required RRD objects
+               self.object_id = object_id
+
+               # Get the main object
+               self.object = self.get_object(self.object_id)
+
        def __repr__(self):
                return "<%s>" % self.__class__.__name__
 
@@ -424,6 +455,24 @@ class GraphTemplate(object):
 
                args += self.rrd_graph_args
 
+               # Graph title
+               if self.graph_title:
+                       args += ["--title", self.graph_title]
+
+               # Vertical label
+               if self.graph_vertical_label:
+                       args += ["--vertical-label", self.graph_vertical_label]
+
+               if self.lower_limit is not None or self.upper_limit is not None:
+                       # Force to honour the set limits
+                       args.append("--rigid")
+
+                       if self.lower_limit is not None:
+                               args += ["--lower-limit", self.lower_limit]
+
+                       if self.upper_limit is not None:
+                               args += ["--upper-limit", self.upper_limit]
+
                # Add interval
                args.append("--start")
 
@@ -434,26 +483,36 @@ class GraphTemplate(object):
 
                return args
 
-       def get_object_table(self, object_id):
+       def get_object(self, *args, **kwargs):
+               return self.plugin.get_object(*args, **kwargs)
+
+       def get_object_table(self):
                return {
-                       "file" : self.plugin.get_object(object_id),
+                       "file" : self.object,
                }
 
-       def get_object_files(self, object_id):
+       @property
+       def object_table(self):
+               if not hasattr(self, "_object_table"):
+                       self._object_table = self.get_object_table()
+
+               return self._object_table
+
+       def get_object_files(self):
                files = {}
 
-               for id, obj in self.get_object_table(object_id).items():
+               for id, obj in self.object_table.items():
                        files[id] = obj.file
 
                return files
 
-       def generate_graph(self, object_id, interval=None, **kwargs):
+       def generate_graph(self, interval=None, **kwargs):
                args = self._make_command_line(interval, **kwargs)
 
                self.log.info(_("Generating graph %s") % self)
                self.log.debug("  args: %s" % args)
 
-               object_files = self.get_object_files(object_id)
+               object_files = self.get_object_files()
 
                for item in self.rrd_graph:
                        try:
@@ -461,6 +520,8 @@ class GraphTemplate(object):
                        except TypeError:
                                args.append(item)
 
+                       self.log.debug("  %s" % args[-1])
+
                return self.write_graph(*args)
 
        def write_graph(self, *args):