]> git.ipfire.org Git - people/ms/python-rrdtool.git/blame - RRDtool.py
* Added support for Python 2.7 (other 2.x versions might also work, but its not tested)
[people/ms/python-rrdtool.git] / RRDtool.py
CommitLineData
225c0910 1#!/usr/bin/env python
b4570f2a
CJ
2# -*- coding: utf-8 -*-
3#
225c0910 4# python-rrdtool, rrdtool bindings for Python.
b4570f2a
CJ
5# Based on the rrdtool Python bindings for Python 2 from
6# Hye-Shik Chang <perky@fallin.lv>.
7#
8# Copyright 2012 Christian Jurk <commx@commx.ws>
9#
10# This program is free software; you can redistribute it and/or modify
275aa95d
CJ
11# it under the terms of the GNU Lesser General Public License as
12# published by the Free Software Foundation; either version 3 of the
13# License, or (at your option) any later version.
b4570f2a
CJ
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
275aa95d 20# You should have received a copy of the GNU Lesser General Public License
b4570f2a
CJ
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23# MA 02110-1301, USA.
24#
25#
26
b4570f2a
CJ
27import os
28import rrdtool
225c0910
CJ
29
30from datetime import datetime
31from io import BytesIO
b4570f2a
CJ
32from time import mktime
33
34def create(filename, *args):
35 "Create a Round Robin Database and return a RRD object on success."
36 rrdtool.create(filename, *args)
37
38 if not os.access(filename, os.F_OK):
39 raise rrdtool.OperationalError('RRD file was not created')
40
41 return RRD(filename)
42
43class RRD:
44 """An object-based interface to the rrdtool module."""
45
46 def __init__(self, filename, check_type=True):
47 "Initialize the class instance with a filename."
48
49 if not os.access(filename, os.F_OK | os.R_OK):
50 raise rrdtool.OperationalError('RRD {!s} cannot be opened.' \
51 .format(filename))
52
53 # Use rrdinfo to test whether the file is a valid RRD file
54 if check_type is True:
55 rrdtool.info(filename)
56
57 self.readonly = not os.access(filename, os.W_OK)
58 self.filename = filename
59
60 def graph(self, output_file, *args):
225c0910
CJ
61 """
62 Generate a graph based on the arguments passed to this function.
63
64 If output_file is None, "-" will be used as the output filename.
65 In that case, rrdtool returns the image bytes within its info dict.
66 """
67 outfile = '-' if output_file is None else output_file
b4570f2a 68
225c0910
CJ
69 # when writing to a file-like object, use output buffering
70 if isinstance(output_file, os.IOBase):
71 outfile = '-'
b4570f2a 72
225c0910 73 info = rrdtool.graphv(outfile, *args)
b4570f2a 74
225c0910
CJ
75 if isinstance(info, dict) and 'image' in info:
76 if isinstance(output_file, os.IOBase):
77 output_file.write(info['image'])
78 elif output_file is None:
79 return info['image']
b4570f2a 80
225c0910 81 return info
b4570f2a
CJ
82
83 def info(self):
84 return rrdtool.info(self.filename)
85
86 def update(self, values, *args):
87 vl = []
88
89 if self.readonly:
90 raise rrdtool.OperationalError('RRD file is read-only: {!s}' \
91 .format(self.filename))
92 elif not isinstance(values, (list, tuple)):
93 raise rrdtool.ProgrammingError('The values parameter must be a ' \
94 'list or tuple')
95 else:
96 for row in values:
97 if isinstance(row, str):
98 vl.append(row)
99 elif isinstance(row, (list, tuple)):
100 if len(row) < 2:
101 raise rrdtool.ProgrammingError('Value {!r} has too ' \
102 'few elements in sequence object'.format(row))
103 else:
104 ts = row[0]
105 if ts is None:
106 ts = 'N'
107 elif isinstance(ts, datetime):
108 ts = int(mktime(ts.timetuple()))
109 elif isinstance(ts, str):
110 ts = int(ts)
111 elif not isinstance(ts, int):
112 raise ValueError('Unsupported type')
113
114 v = '{}:{}'.format(ts, ':'.join([str(x) for x in row[1:]]))
115 vl.append(v)
116
117 arglist = tuple(vl + list(args))
118 return rrdtool.update(self.filename, *arglist)
119
120 def __repr__(self):
121 return '<RRD {!r}>'.format(self.filename)