--- a/pvl/verkko/rrd.py Sun Jan 20 19:52:41 2013 +0200
+++ b/pvl/verkko/rrd.py Sun Jan 20 22:46:17 2013 +0200
@@ -3,7 +3,7 @@
http://verkko.paivola.fi/rrd
"""
-import pvl.web.application as web
+from pvl import web
from pvl.web import urls
from pvl.web.html import tags as html
@@ -11,186 +11,6 @@
import logging; log = logging.getLogger('pvl.verkko.rrd')
-# Model
-import os, os.path, errno
-
-class RRDDatabase (object) :
- """
- A filesystem directory containing .rrd files.
- """
-
- def __init__ (self, graph, path, cache=None) :
- """
- graph - pvl.rrd.graph.InterfaceGraph type
- path - path to rrd dirs
- cache - path to cache dirs
- """
-
- if not path :
- raise ValueError("RRDDatabase: no path given")
-
- log.info("%s: type=%s, cache=%s", path, graph, cache)
-
- self._graph = graph
- self._path = path
- self._cache = cache
-
- def path (self, node=None, *subnodes) :
- """
- Lookup and full filesystem path to the given relative RRD/dir path.
-
- Raises ValueError if invalid path.
- """
-
- if node :
- # relative dir (no leading slash) -> absolute path
- path = os.path.normpath(os.path.join(self._path, node, *subnodes))
- else :
- path = self._path
-
- log.debug("%s: %s -> %s", self, node, path)
-
- # check inside base path
- if not path.startswith(self._path) :
- # mask
- raise ValueError("%s: Invalid path: %s" % (self, node))
-
- # ok
- return path
-
- def tree (self, node=None) :
- """
- Lookup and return RRDTree for given node, or root tree.
-
- Raises ValueError if invalid path, or no such tree.
- """
-
- # lookup fs path
- path = self.path(node)
-
- # found?
- if not os.path.isdir(path) :
- raise ValueError("%s: Invalid tree: %s: %s" % (self, node, path))
-
- return node
-
- def rrd (self, node, tree=None) :
- """
- Lookup and return RRD for given node.
- """
-
- if tree :
- node = os.path.join(tree, node)
-
- path = self.path(node) + '.rrd'
-
- if not os.path.isfile(path) :
- raise ValueError("%: Invalid rrd: %s: %s" % (self, node, path))
-
- return node
-
- def list (self, tree) :
- """
- List (trees, rrds) under given tree.
- """
-
- dirs = []
- rrds = []
-
- for name in os.listdir(self.path(tree)) :
- if name.startswith('.') :
- continue
-
- log.debug("%s: %s: %s", self, tree, name)
-
- path = self.path(tree, name)
- basename, extname = os.path.splitext(name)
-
- if os.path.isdir(path) :
- dirs.append(name)
-
- elif extname == '.rrd' :
- # without the .rrd
- rrds.append(basename)
-
- # return sorted lists
- return sorted(dirs), sorted(rrds)
-
- def _stat (self, path) :
- """
- os.stat or None.
- """
-
- try :
- return os.stat(path)
-
- except OSError as ex :
- if ex.errno == errno.ENOENT :
- return None
- else :
- raise
-
- def cache (self, source, *key) :
- """
- Lookup given key from cache, returning (hit, file).
- """
-
- # output
- if not self._cache :
- return None, None
-
- # cache path
- path = os.path.join(self._cache, *key)
-
- # create
- dir = os.path.dirname(path)
- if not os.path.isdir(dir) :
- log.warn("makedirs %s", dir)
- os.makedirs(dir)
-
- # stats's
- src = self._stat(source)
- dst = self._stat(path)
-
- if not dst:
- log.debug("%s: %s: %s: miss", self._cache, source, path)
- return None, path
-
- elif dst and src.st_mtime < dst.st_mtime :
- log.debug("%s: %s: %s: hit", self._cache, source, path)
-
- return True, path
-
- else :
- log.debug("%s: %s: %s: update", self._cache, source, path)
- return False, path
-
- def graph (self, rrd, style, interval) :
- """
- Graph given rrd using given style/interval, returning the opened png data file.
- """
-
- title = str(rrd) # " / ".join(rrd.split('/'))
-
- path = self.path(rrd) + '.rrd'
-
- cached, out = self.cache(path, style, interval, rrd + '.png')
-
- log.debug("%s: %s: %s", self, rrd, out)
-
- if cached :
- # from cache
- outfile = open(out)
-
- else :
- # to cache
- dimensions, lines, outfile = self._graph.build(title, path, style, interval).graph(out)
-
- return outfile
-
- def __str__ (self) :
- return str(self._path)
-
# View/Controller
class Handler (web.Handler) :
CSS = (
@@ -211,7 +31,7 @@
tree = ''
for part in _tree.split('/') :
- tree = os.path.join(tree, part)
+ tree = urls.join(tree, part)
yield part, self.url(Index, tree=tree)
@@ -245,7 +65,7 @@
"""
if self.tree :
- path = os.path.join(self.tree, node)
+ path = urls.join(self.tree, node)
else :
path = node
@@ -260,6 +80,7 @@
try :
# XXX: unicode?
self.tree = self.app.rrd.tree(tree)
+
except ValueError as ex :
# mask
raise web.NotFound(tree)
@@ -368,7 +189,7 @@
self.rrd = self.app.rrd.rrd(target, self.tree)
except ValueError as ex :
- raise web.NotFound(tree, target)
+ raise web.NotFound(tree + '/' + target)
self.style = style
self.interval = interval
@@ -401,6 +222,7 @@
# WSGI
class Application (web.Application) :
+ # dispatch
urls = urls.Map((
urls.rule('/', Index),
urls.rule('/<target>', Target),
@@ -411,7 +233,7 @@
def __init__ (self, rrd) :
"""
- Initialize app with given RRDDatabase
+ rrd - pvl.rrd.RRDDatabase
"""
self.rrd = rrd