applications/luci-statistics: avoid global vars, avoid nil indexing, get rid of count...
[project/luci.git] / applications / luci-statistics / luasrc / statistics / datatree.lua
index 82e7a28..850b83a 100644 (file)
@@ -1,10 +1,25 @@
+--[[
+
+Luci statistics - rrd data tree builder
+(c) 2008 Freifunk Leipzig / Jo-Philipp Wich <xm@leipzig.freifunk.net>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+               http://www.apache.org/licenses/LICENSE-2.0
+
+$Id$
+
+]]--
+
 module("luci.statistics.datatree", package.seeall)
 
 local util = require("luci.util")
 local sys  = require("luci.sys")
-local fs   = require("luci.fs")
-local uci  = require("luci.model.uci").Session()
-local sections, names = uci:sections( "luci_statistics" )
+local fs   = require("nixio.fs")
+local uci  = require("luci.model.uci").cursor()
+local sections = uci:get_all("luci_statistics")
 
 
 Instance = util.class()
@@ -12,7 +27,7 @@ Instance = util.class()
 function Instance.__init__( self, host )
        self._host    = host or sections.collectd.Hostname or sys.hostname()
        self._libdir  = sections.collectd.PluginDir        or "/usr/lib/collectd"
-       self._rrddir  = sections.collectd_rrdtool.DataDir  or "/tmp"
+       self._rrddir  = sections.collectd_rrdtool.DataDir  or "/tmp/rrd"
 
        self._libdir  = self._libdir:gsub("/$","")
        self._rrddir  = self._rrddir:gsub("/$","")
@@ -35,6 +50,19 @@ function Instance._mkpath( self, plugin, pinstance )
        return dir
 end
 
+function Instance._ls( self, ... )
+       local ditr = fs.dir(self:_mkpath(...))
+       if ditr then
+               local dirs = { }
+               while true do
+                       local d = ditr()
+                       if not d then break end
+                       dirs[#dirs+1] = d
+               end
+               return dirs
+       end
+end
+
 function Instance._notzero( self, table )
        for k in pairs(table) do
                return true
@@ -44,45 +72,71 @@ function Instance._notzero( self, table )
 end
 
 function Instance._scan( self )
-       for i, plugin in ipairs( fs.dir( self._libdir ) ) do
-               if plugin:match("%w+.so") then
-                       self._plugins[ plugin:gsub(".so", "") ] = { }
+       local dirs = self:_ls()
+       if not dirs then
+               return
+       end
+
+--     for i, plugin in ipairs( dirs ) do
+--             if plugin:match("%w+.so") then
+--                     self._plugins[ plugin:gsub("%.so$", "") ] = { }
+--             end
+--     end
+
+       for _, dir in ipairs(dirs) do
+               if dir ~= "." and dir ~= ".." and
+                  fs.stat(self:_mkpath(dir)).type == "dir"
+               then
+                       local plugin = dir:gsub("%-.+$", "")
+                       if not self._plugins[plugin] then
+                               self._plugins[plugin] = { }
+                       end
                end
        end
 
        for plugin, instances in pairs( self._plugins ) do
-               for i, dir in ipairs( fs.dir( self:_mkpath() ) ) do
-                       if dir:find( plugin .. "%-" ) or dir == plugin then
-                               local instance = ""
 
-                               if dir ~= plugin then
-                                       instance = dir:gsub( plugin .. "%-", "", 1 )
-                               end
+               local dirs = self:_ls()
 
-                               instances[instance] = { }
+               if type(dirs) == "table" then
+                       for i, dir in ipairs(dirs) do
+                               if dir:find( plugin .. "%-" ) or dir == plugin then
+                                       local instance = ""
+
+                                       if dir ~= plugin then
+                                               instance = dir:gsub( plugin .. "%-", "", 1 )
+                                       end
+
+                                       instances[instance] = { }
+                               end
                        end
                end
 
                for instance, data_instances in pairs( instances ) do
-                       for i, file in ipairs( fs.dir( self:_mkpath( plugin, instance ) ) ) do
-                               if file:find("%.rrd") then
-                                       file = file:gsub("%.rrd","")
-
-                                       local data_type
-                                       local data_instance
-
-                                       if file:find("%-") then
-                                               data_type     = file:gsub( "%-.+","" )
-                                               data_instance = file:gsub( "[^%-]-%-", "", 1 )
-                                       else
-                                               data_type     = file
-                                               data_instance = ""
-                                       end
 
-                                       if not data_instances[data_type] then
-                                               data_instances[data_type] = { data_instance }
-                                       else
-                                               table.insert( data_instances[data_type], data_instance )
+                       dirs = self:_ls(plugin, instance)
+
+                       if type(dirs) == "table" then
+                               for i, file in ipairs(dirs) do
+                                       if file:find("%.rrd") then
+                                               file = file:gsub("%.rrd","")
+
+                                               local data_type
+                                               local data_instance
+
+                                               if file:find("%-") then
+                                                       data_type     = file:gsub( "%-.+","" )
+                                                       data_instance = file:gsub( "[^%-]-%-", "", 1 )
+                                               else
+                                                       data_type     = file
+                                                       data_instance = ""
+                                               end
+
+                                               if not data_instances[data_type] then
+                                                       data_instances[data_type] = { data_instance }
+                                               else
+                                                       table.insert( data_instances[data_type], data_instance )
+                                               end
                                        end
                                end
                        end
@@ -115,9 +169,12 @@ end
 
 function Instance.data_types( self, plugin, instance )
        local rv = { }
+       local p  = self._plugins[plugin]
 
-       for type, val in pairs( self._plugins[plugin][instance] ) do
-               table.insert( rv, type )
+       if type(p) == "table" and type(p[instance]) == "table" then
+               for type, val in pairs(p[instance]) do
+                       table.insert( rv, type )
+               end
        end
 
        return rv
@@ -125,12 +182,28 @@ end
 
 function Instance.data_instances( self, plugin, instance, dtype )
        local rv = { }
+       local p  = self._plugins[plugin]
 
-       if type(self._plugins[plugin][instance][dtype]) == "table" then
-               for i, instance in ipairs( self._plugins[plugin][instance][dtype] ) do
+       if type(p) == "table" and type(p[instance]) == "table" and type(p[instance][dtype]) == "table" then
+               for i, instance in ipairs(p[instance][dtype]) do
                        table.insert( rv, instance )
                end
        end
 
        return rv
 end
+
+function Instance.host_instances( self )
+       local hosts_path = fs.glob(self._rrddir..'/*')
+       local hosts = { }
+
+       if hosts_path then
+               local path
+               for path in hosts_path do
+                       hosts[#hosts+1] = fs.basename(path)
+               end
+       end
+
+       return hosts
+end
+