]> git.ipfire.org Git - collecty.git/blobdiff - src/collecty/plugins/base.py
Refectoring of the main classes
[collecty.git] / src / collecty / plugins / base.py
index b6eabd0bfc2f10ba953a7d838ad604978390dfd0..5b130444324f5c530efdad3b97e3155888d35c4e 100644 (file)
@@ -31,6 +31,7 @@ import time
 import unicodedata
 
 from .. import locales
+from .. import util
 from ..constants import *
 from ..i18n import _
 
@@ -302,6 +303,9 @@ class Object(object):
        def __repr__(self):
                return "<%s>" % self.__class__.__name__
 
+       def __lt__(self, other):
+               return self.id < other.id
+
        @property
        def collecty(self):
                return self.plugin.collecty
@@ -440,12 +444,20 @@ class Object(object):
 
                return schema
 
-       def make_rrd_defs(self, prefix=None):
-               defs = []
+       @property
+       def rrd_schema_names(self):
+               ret = []
 
                for line in self.rrd_schema:
-                       (def_type, name, type, lower_limit, upper_limit) = line.split(":")
+                       (prefix, name, type, lower_limit, upper_limit) = line.split(":")
+                       ret.append(name)
+
+               return ret
+
+       def make_rrd_defs(self, prefix=None):
+               defs = []
 
+               for name in self.rrd_schema_names:
                        if prefix:
                                p = "%s_%s" % (prefix, name)
                        else:
@@ -457,6 +469,21 @@ class Object(object):
 
                return defs
 
+       def get_stddev(self, interval=None):
+               args = self.make_rrd_defs()
+
+               # Add the correct interval
+               args += ["--start", util.make_interval(interval)]
+
+               for name in self.rrd_schema_names:
+                       args += [
+                               "VDEF:%s_stddev=%s,STDEV" % (name, name),
+                               "PRINT:%s_stddev:%%lf" % name,
+                       ]
+
+               x, y, vals = rrdtool.graph("/dev/null", *args)
+               return dict(zip(self.rrd_schema_names, vals))
+
        def execute(self):
                if self.collected:
                        raise RuntimeError("This object has already collected its data")
@@ -498,15 +525,6 @@ class GraphTemplate(object):
        # Extra arguments passed to rrdgraph.
        rrd_graph_args = []
 
-       intervals = {
-               None   : "-3h",
-               "hour" : "-1h",
-               "day"  : "-25h",
-               "month": "-30d",
-               "week" : "-360h",
-               "year" : "-365d",
-       }
-
        # Default dimensions for this graph
        height = GRAPH_DEFAULT_HEIGHT
        width  = GRAPH_DEFAULT_WIDTH
@@ -522,7 +540,8 @@ class GraphTemplate(object):
                self.object_id = object_id
 
                # Get the main object
-               self.object = self.get_object(self.object_id)
+               self.objects = self.get_objects(self.object_id)
+               self.objects.sort()
 
        def __repr__(self):
                return "<%s>" % self.__class__.__name__
@@ -535,6 +554,14 @@ class GraphTemplate(object):
        def log(self):
                return self.plugin.log
 
+       @property
+       def object(self):
+               """
+                       Shortcut to the main object
+               """
+               if len(self.objects) == 1:
+                       return self.objects[0]
+
        def _make_command_line(self, interval, format=DEFAULT_IMAGE_FORMAT,
                        width=None, height=None, with_title=True, thumbnail=False):
                args = [e for e in GRAPH_DEFAULT_ARGUMENTS]
@@ -575,13 +602,20 @@ class GraphTemplate(object):
                        if self.upper_limit is not None:
                                args += ["--upper-limit", self.upper_limit]
 
-               try:
-                       interval = self.intervals[interval]
-               except KeyError:
-                       interval = "end-%s" % interval
-
                # Add interval
-               args += ["--start", interval]
+               args += ["--start", util.make_interval(interval)]
+
+               return args
+
+       def _add_defs(self):
+               use_prefix = len(self.objects) >= 2
+
+               args = []
+               for object in self.objects:
+                       if use_prefix:
+                               args += object.make_rrd_defs(object.id)
+                       else:
+                               args += object.make_rrd_defs()
 
                return args
 
@@ -606,45 +640,33 @@ class GraphTemplate(object):
 
                return ret
 
-       def get_object(self, *args, **kwargs):
-               return self.plugin.get_object(*args, **kwargs)
+       def get_objects(self, *args, **kwargs):
+               object = self.plugin.get_object(*args, **kwargs)
 
-       def get_object_table(self):
-               return {
-                       "file" : self.object,
-               }
-
-       @property
-       def object_table(self):
-               if not hasattr(self, "_object_table"):
-                       self._object_table = self.get_object_table()
-
-               return self._object_table
+               if object:
+                       return [object,]
 
-       def get_object_files(self):
-               files = {}
-
-               for id, obj in self.object_table.items():
-                       files[id] = obj.file
-
-               return files
+               return []
 
        def generate_graph(self, interval=None, **kwargs):
+               assert self.objects, "Cannot render graph without any objects"
+
                # Make sure that all collected data is in the database
                # to get a recent graph image
-               if self.object:
-                       self.object.commit()
+               for object in self.objects:
+                       object.commit()
 
                args = self._make_command_line(interval, **kwargs)
 
                self.log.info(_("Generating graph %s") % self)
 
-               #object_files = self.get_object_files()
+               rrd_graph = self.rrd_graph
 
-               if self.object:
-                       args += self.object.make_rrd_defs()
+               # Add DEFs for all objects
+               if not any((e.startswith("DEF:") for e in rrd_graph)):
+                       args += self._add_defs()
 
-               args += self.rrd_graph
+               args += rrd_graph
                args = self._add_vdefs(args)
 
                # Convert arguments to string